]>
Commit | Line | Data |
---|---|---|
effc2770 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2013 The Bitcoin Core developers |
78253fcb | 3 | // Distributed under the MIT software license, see the accompanying |
effc2770 | 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
51ed9ec9 | 5 | |
d2270111 LD |
6 | #ifndef BITCOIN_PRIMITIVES_BLOCK_H |
7 | #define BITCOIN_PRIMITIVES_BLOCK_H | |
effc2770 | 8 | |
d2270111 | 9 | #include "primitives/transaction.h" |
51ed9ec9 BD |
10 | #include "serialize.h" |
11 | #include "uint256.h" | |
12 | ||
aabdf9e8 EL |
13 | /** Nodes collect new transactions into a block, hash them into a hash tree, |
14 | * and scan through nonce values to make the block's hash satisfy proof-of-work | |
15 | * requirements. When they solve the proof-of-work, they broadcast the block | |
16 | * to everyone and the block is added to the block chain. The first transaction | |
17 | * in the block is a special one that creates a new coin owned by the creator | |
18 | * of the block. | |
19 | */ | |
20 | class CBlockHeader | |
21 | { | |
22 | public: | |
23 | // header | |
c6a7e897 | 24 | static const size_t HEADER_SIZE=4+32+32+32+4+4+32; // excluding Equihash solution |
5e82e1c8 | 25 | static const int32_t CURRENT_VERSION=4; |
42181656 | 26 | static uint256 (CBlockHeader::*hashFunction)() const; |
27 | ||
28 | static void SetHashAlgo(); | |
29 | ||
9f3d4767 | 30 | int32_t nVersion; |
aabdf9e8 EL |
31 | uint256 hashPrevBlock; |
32 | uint256 hashMerkleRoot; | |
a8d384ae | 33 | uint256 hashReserved; |
9f3d4767 KD |
34 | uint32_t nTime; |
35 | uint32_t nBits; | |
fdda3c50 | 36 | uint256 nNonce; |
5be6abbf | 37 | std::vector<unsigned char> nSolution; |
aabdf9e8 EL |
38 | |
39 | CBlockHeader() | |
40 | { | |
41 | SetNull(); | |
42 | } | |
43 | ||
3f6540ad | 44 | ADD_SERIALIZE_METHODS; |
3d796f89 | 45 | |
84881f8c | 46 | template <typename Stream, typename Operation> |
31e9a838 | 47 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
aabdf9e8 EL |
48 | READWRITE(this->nVersion); |
49 | nVersion = this->nVersion; | |
50 | READWRITE(hashPrevBlock); | |
51 | READWRITE(hashMerkleRoot); | |
a8d384ae | 52 | READWRITE(hashReserved); |
aabdf9e8 EL |
53 | READWRITE(nTime); |
54 | READWRITE(nBits); | |
55 | READWRITE(nNonce); | |
fdda3c50 | 56 | READWRITE(nSolution); |
3d796f89 | 57 | } |
aabdf9e8 EL |
58 | |
59 | void SetNull() | |
60 | { | |
61 | nVersion = CBlockHeader::CURRENT_VERSION; | |
4f152496 WL |
62 | hashPrevBlock.SetNull(); |
63 | hashMerkleRoot.SetNull(); | |
a8d384ae | 64 | hashReserved.SetNull(); |
aabdf9e8 EL |
65 | nTime = 0; |
66 | nBits = 0; | |
fdda3c50 JG |
67 | nNonce = uint256(); |
68 | nSolution.clear(); | |
aabdf9e8 EL |
69 | } |
70 | ||
71 | bool IsNull() const | |
72 | { | |
73 | return (nBits == 0); | |
74 | } | |
75 | ||
42181656 | 76 | uint256 GetHash() const |
77 | { | |
78 | return (this->*hashFunction)(); | |
79 | } | |
80 | ||
81 | uint256 GetSHA256DHash() const; | |
82 | static void SetSHA256DHash(); | |
83 | ||
84 | uint256 GetVerusHash() const; | |
85 | static void SetVerusHash(); | |
aabdf9e8 | 86 | |
51ed9ec9 | 87 | int64_t GetBlockTime() const |
aabdf9e8 | 88 | { |
51ed9ec9 | 89 | return (int64_t)nTime; |
aabdf9e8 EL |
90 | } |
91 | }; | |
92 | ||
33944573 EL |
93 | |
94 | class CBlock : public CBlockHeader | |
95 | { | |
96 | public: | |
97 | // network and disk | |
98 | std::vector<CTransaction> vtx; | |
99 | ||
100 | // memory only | |
101 | mutable std::vector<uint256> vMerkleTree; | |
102 | ||
103 | CBlock() | |
104 | { | |
105 | SetNull(); | |
106 | } | |
107 | ||
108 | CBlock(const CBlockHeader &header) | |
109 | { | |
110 | SetNull(); | |
111 | *((CBlockHeader*)this) = header; | |
112 | } | |
113 | ||
3f6540ad | 114 | ADD_SERIALIZE_METHODS; |
3d796f89 | 115 | |
84881f8c | 116 | template <typename Stream, typename Operation> |
31e9a838 | 117 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
33944573 EL |
118 | READWRITE(*(CBlockHeader*)this); |
119 | READWRITE(vtx); | |
3d796f89 | 120 | } |
33944573 EL |
121 | |
122 | void SetNull() | |
123 | { | |
124 | CBlockHeader::SetNull(); | |
125 | vtx.clear(); | |
126 | vMerkleTree.clear(); | |
127 | } | |
128 | ||
129 | CBlockHeader GetBlockHeader() const | |
130 | { | |
131 | CBlockHeader block; | |
132 | block.nVersion = nVersion; | |
133 | block.hashPrevBlock = hashPrevBlock; | |
134 | block.hashMerkleRoot = hashMerkleRoot; | |
a8d384ae | 135 | block.hashReserved = hashReserved; |
33944573 EL |
136 | block.nTime = nTime; |
137 | block.nBits = nBits; | |
138 | block.nNonce = nNonce; | |
fdda3c50 | 139 | block.nSolution = nSolution; |
33944573 EL |
140 | return block; |
141 | } | |
142 | ||
584a3589 PW |
143 | // Build the in-memory merkle tree for this block and return the merkle root. |
144 | // If non-NULL, *mutated is set to whether mutation was detected in the merkle | |
145 | // tree (a duplication of transactions in the block leading to an identical | |
146 | // merkle root). | |
147 | uint256 BuildMerkleTree(bool* mutated = NULL) const; | |
33944573 | 148 | |
f121db58 PW |
149 | std::vector<uint256> GetMerkleBranch(int nIndex) const; |
150 | static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); | |
81212588 | 151 | std::string ToString() const; |
33944573 EL |
152 | }; |
153 | ||
f9b15a4f | 154 | |
fdda3c50 JG |
155 | /** |
156 | * Custom serializer for CBlockHeader that omits the nonce and solution, for use | |
157 | * as input to Equihash. | |
158 | */ | |
159 | class CEquihashInput : private CBlockHeader | |
160 | { | |
161 | public: | |
162 | CEquihashInput(const CBlockHeader &header) | |
163 | { | |
164 | CBlockHeader::SetNull(); | |
165 | *((CBlockHeader*)this) = header; | |
166 | } | |
167 | ||
168 | ADD_SERIALIZE_METHODS; | |
169 | ||
170 | template <typename Stream, typename Operation> | |
171 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
172 | READWRITE(this->nVersion); | |
173 | nVersion = this->nVersion; | |
174 | READWRITE(hashPrevBlock); | |
175 | READWRITE(hashMerkleRoot); | |
a8d384ae | 176 | READWRITE(hashReserved); |
fdda3c50 JG |
177 | READWRITE(nTime); |
178 | READWRITE(nBits); | |
179 | } | |
180 | }; | |
181 | ||
182 | ||
f9b15a4f PW |
183 | /** Describes a place in the block chain to another node such that if the |
184 | * other node doesn't have the same branch, it can find a recent common trunk. | |
185 | * The further back it is, the further before the fork it may be. | |
186 | */ | |
187 | struct CBlockLocator | |
188 | { | |
189 | std::vector<uint256> vHave; | |
190 | ||
191 | CBlockLocator() {} | |
192 | ||
193 | CBlockLocator(const std::vector<uint256>& vHaveIn) | |
194 | { | |
195 | vHave = vHaveIn; | |
196 | } | |
197 | ||
3f6540ad | 198 | ADD_SERIALIZE_METHODS; |
3d796f89 | 199 | |
84881f8c | 200 | template <typename Stream, typename Operation> |
31e9a838 | 201 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
f9b15a4f PW |
202 | if (!(nType & SER_GETHASH)) |
203 | READWRITE(nVersion); | |
204 | READWRITE(vHave); | |
3d796f89 | 205 | } |
f9b15a4f PW |
206 | |
207 | void SetNull() | |
208 | { | |
209 | vHave.clear(); | |
210 | } | |
211 | ||
bdb6a71d | 212 | bool IsNull() const |
f9b15a4f PW |
213 | { |
214 | return vHave.empty(); | |
215 | } | |
03f83b9b JG |
216 | |
217 | friend bool operator==(const CBlockLocator& a, const CBlockLocator& b) { | |
218 | return (a.vHave == b.vHave); | |
219 | } | |
f9b15a4f PW |
220 | }; |
221 | ||
d2270111 | 222 | #endif // BITCOIN_PRIMITIVES_BLOCK_H |