text: // Copyright (c) 2009-2010 Satoshi Nakamoto
  // Copyright (c) 2009-2018 The Bitcoin Core developers
  // Distributed under the MIT software license, see the accompanying
  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  
  #ifndef BITCOIN_PRIMITIVES_BLOCK_H
  #define BITCOIN_PRIMITIVES_BLOCK_H
  
  #include <powdata.h>
  #include <primitives/transaction.h>
  #include <primitives/pureheader.h>
  #include <serialize.h>
  #include <uint256.h>
  
  #include <memory>
  
  /** Nodes collect new transactions into a block, hash them into a hash tree,
   * and scan through nonce values to make the block's hash satisfy proof-of-work
   * requirements.  When they solve the proof-of-work, they broadcast the block
   * to everyone and the block is added to the block chain.  The first transaction
   * in the block is a special one that creates a new coin owned by the creator
   * of the block.
   */
  class CBlockHeader : public CPureBlockHeader
  {
  public:
  
    /** The PoW data for this block.  */
    PowData pow;
  
    SERIALIZE_METHODS(CBlockHeader, obj)
    {
        READWRITEAS(CPureBlockHeader, obj);
        READWRITE (obj.pow);
    }
  
    /**
     * Returns a hash based on the PoW of this block, which can be used for
     * the generation of random numbers in games.  Note that there is some
     * potential for miners to manipulate this:  Namely, they can withhold
     * a block if they do not like the resulting effect in some game they
     * are involved in; this costs them the CHI block reward, but may be
     * worth it for high stakes in a game.
     */
    uint256 GetRngSeed() const;
  
  };
  
  class CBlock : public CBlockHeader
  {
  public:
      // network and disk
      std::vector<CTransactionRef> vtx;
  
      // memory only
      mutable bool fChecked;
  
      CBlock()
      {
          SetNull();
      }
  
      CBlock(const CBlockHeader &header)
      {
          SetNull();
          *(static_cast<CBlockHeader*>(this)) = header;
      }
  
      SERIALIZE_METHODS(CBlock, obj)
      {
          READWRITEAS(CBlockHeader, obj);
          READWRITE(obj.vtx);
      }
  
      void SetNull()
      {
          CBlockHeader::SetNull();
          vtx.clear();
          fChecked = false;
      }
  
      CBlockHeader GetBlockHeader() const
      {
          CBlockHeader block;
          block.nVersion       = nVersion;
          block.hashPrevBlock  = hashPrevBlock;
          block.hashMerkleRoot = hashMerkleRoot;
          block.nTime          = nTime;
          block.nBits          = nBits;
          block.nNonce         = nNonce;
          block.pow            = pow;
          return block;
      }
  
      std::string ToString() const;
  };
  
  /** Describes a place in the block chain to another node such that if the
   * other node doesn't have the same branch, it can find a recent common trunk.
   * The further back it is, the further before the fork it may be.
   */
  struct CBlockLocator
  {
      std::vector<uint256> vHave;
  
      CBlockLocator() {}
  
      explicit CBlockLocator(const std::vector<uint256>& vHaveIn) : vHave(vHaveIn) {}
  
      SERIALIZE_METHODS(CBlockLocator, obj)
      {
          int nVersion = s.GetVersion();
          if (!(s.GetType() & SER_GETHASH))
              READWRITE(nVersion);
          READWRITE(obj.vHave);
      }
  
      void SetNull()
      {
          vHave.clear();
      }
  
      bool IsNull() const
      {
          return vHave.empty();
      }
  };
  
  #endif // BITCOIN_PRIMITIVES_BLOCK_H
  