1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef BITCOIN_PRIMITIVES_BLOCK_H
7 #define BITCOIN_PRIMITIVES_BLOCK_H
8 
9 #include <auxpow.h>
10 #include <primitives/transaction.h>
11 #include <primitives/pureheader.h>
12 #include <serialize.h>
13 #include <uint256.h>
14 
15 #include <memory>
16 
17 /** Nodes collect new transactions into a block, hash them into a hash tree,
18  * and scan through nonce values to make the block's hash satisfy proof-of-work
19  * requirements.  When they solve the proof-of-work, they broadcast the block
20  * to everyone and the block is added to the block chain.  The first transaction
21  * in the block is a special one that creates a new coin owned by the creator
22  * of the block.
23  */
24 class CBlockHeader : public CPureBlockHeader
25 {
26 public:
27 
28     // auxpow (if this is a merge-minded block)
29     std::shared_ptr<CAuxPow> auxpow;
30 
CBlockHeader()31     CBlockHeader()
32     {
33         SetNull();
34     }
35 
SERIALIZE_METHODS(CBlockHeader,obj)36     SERIALIZE_METHODS(CBlockHeader, obj)
37     {
38         READWRITEAS(CPureBlockHeader, obj);
39 
40         if (obj.IsAuxpow())
41         {
42             SER_READ(obj, obj.auxpow = std::make_shared<CAuxPow>());
43             assert(obj.auxpow != nullptr);
44             READWRITE(*obj.auxpow);
45         } else
46         {
47             SER_READ(obj, obj.auxpow.reset());
48         }
49     }
50 
SetNull()51     void SetNull()
52     {
53         CPureBlockHeader::SetNull();
54         auxpow.reset();
55     }
56 
57     /**
58      * Set the block's auxpow (or unset it).  This takes care of updating
59      * the version accordingly.
60      */
61     void SetAuxpow (std::unique_ptr<CAuxPow> apow);
62 };
63 
64 
65 class CBlock : public CBlockHeader
66 {
67 public:
68     // network and disk
69     std::vector<CTransactionRef> vtx;
70 
71     // memory only
72     mutable bool fChecked;
73 
CBlock()74     CBlock()
75     {
76         SetNull();
77     }
78 
CBlock(const CBlockHeader & header)79     CBlock(const CBlockHeader &header)
80     {
81         SetNull();
82         *(static_cast<CBlockHeader*>(this)) = header;
83     }
84 
SERIALIZE_METHODS(CBlock,obj)85     SERIALIZE_METHODS(CBlock, obj)
86     {
87         READWRITEAS(CBlockHeader, obj);
88         READWRITE(obj.vtx);
89     }
90 
SetNull()91     void SetNull()
92     {
93         CBlockHeader::SetNull();
94         vtx.clear();
95         fChecked = false;
96     }
97 
GetBlockHeader()98     CBlockHeader GetBlockHeader() const
99     {
100         CBlockHeader block;
101         block.nVersion       = nVersion;
102         block.hashPrevBlock  = hashPrevBlock;
103         block.hashMerkleRoot = hashMerkleRoot;
104         block.nTime          = nTime;
105         block.nBits          = nBits;
106         block.nNonce         = nNonce;
107         block.auxpow         = auxpow;
108         return block;
109     }
110 
111     std::string ToString() const;
112 };
113 
114 /** Describes a place in the block chain to another node such that if the
115  * other node doesn't have the same branch, it can find a recent common trunk.
116  * The further back it is, the further before the fork it may be.
117  */
118 struct CBlockLocator
119 {
120     std::vector<uint256> vHave;
121 
CBlockLocatorCBlockLocator122     CBlockLocator() {}
123 
CBlockLocatorCBlockLocator124     explicit CBlockLocator(const std::vector<uint256>& vHaveIn) : vHave(vHaveIn) {}
125 
SERIALIZE_METHODSCBlockLocator126     SERIALIZE_METHODS(CBlockLocator, obj)
127     {
128         int nVersion = s.GetVersion();
129         if (!(s.GetType() & SER_GETHASH))
130             READWRITE(nVersion);
131         READWRITE(obj.vHave);
132     }
133 
SetNullCBlockLocator134     void SetNull()
135     {
136         vHave.clear();
137     }
138 
IsNullCBlockLocator139     bool IsNull() const
140     {
141         return vHave.empty();
142     }
143 };
144 
145 #endif // BITCOIN_PRIMITIVES_BLOCK_H
146