]>
Commit | Line | Data |
---|---|---|
e8b5f0d5 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
7bec6dd2 | 3 | // Distributed under the MIT software license, see the accompanying |
e8b5f0d5 | 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
5 | ||
84738627 PJ |
6 | #ifndef BITCOIN_CHAIN_H |
7 | #define BITCOIN_CHAIN_H | |
e8b5f0d5 | 8 | |
734f85c4 | 9 | #include "arith_uint256.h" |
d2270111 | 10 | #include "primitives/block.h" |
e8b5f0d5 | 11 | #include "pow.h" |
85c579e3 | 12 | #include "tinyformat.h" |
e8b5f0d5 | 13 | #include "uint256.h" |
14 | ||
15 | #include <vector> | |
16 | ||
17 | #include <boost/foreach.hpp> | |
18 | ||
19 | struct CDiskBlockPos | |
20 | { | |
21 | int nFile; | |
22 | unsigned int nPos; | |
23 | ||
24 | ADD_SERIALIZE_METHODS; | |
25 | ||
26 | template <typename Stream, typename Operation> | |
27 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
28 | READWRITE(VARINT(nFile)); | |
29 | READWRITE(VARINT(nPos)); | |
30 | } | |
31 | ||
32 | CDiskBlockPos() { | |
33 | SetNull(); | |
34 | } | |
35 | ||
36 | CDiskBlockPos(int nFileIn, unsigned int nPosIn) { | |
37 | nFile = nFileIn; | |
38 | nPos = nPosIn; | |
39 | } | |
40 | ||
41 | friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) { | |
42 | return (a.nFile == b.nFile && a.nPos == b.nPos); | |
43 | } | |
44 | ||
45 | friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) { | |
46 | return !(a == b); | |
47 | } | |
48 | ||
49 | void SetNull() { nFile = -1; nPos = 0; } | |
50 | bool IsNull() const { return (nFile == -1); } | |
f5791c6a WL |
51 | |
52 | std::string ToString() const | |
53 | { | |
54 | return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos); | |
55 | } | |
56 | ||
e8b5f0d5 | 57 | }; |
58 | ||
59 | enum BlockStatus { | |
2fdc3351 | 60 | //! Unused. |
e8b5f0d5 | 61 | BLOCK_VALID_UNKNOWN = 0, |
341735eb | 62 | |
2fdc3351 | 63 | //! Parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future |
341735eb PW |
64 | BLOCK_VALID_HEADER = 1, |
65 | ||
2fdc3351 MF |
66 | //! All parent headers found, difficulty matches, timestamp >= median previous, checkpoint. Implies all parents |
67 | //! are also at least TREE. | |
341735eb PW |
68 | BLOCK_VALID_TREE = 2, |
69 | ||
2fdc3351 MF |
70 | /** |
71 | * Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, | |
72 | * sigops, size, merkle root. Implies all parents are at least TREE but not necessarily TRANSACTIONS. When all | |
73 | * parent blocks also have TRANSACTIONS, CBlockIndex::nChainTx will be set. | |
74 | */ | |
341735eb PW |
75 | BLOCK_VALID_TRANSACTIONS = 3, |
76 | ||
b05a89b2 | 77 | //! Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends, BIP30. |
2fdc3351 | 78 | //! Implies all parents are also at least CHAIN. |
341735eb PW |
79 | BLOCK_VALID_CHAIN = 4, |
80 | ||
2fdc3351 | 81 | //! Scripts & signatures ok. Implies all parents are also at least SCRIPTS. |
341735eb PW |
82 | BLOCK_VALID_SCRIPTS = 5, |
83 | ||
2fdc3351 | 84 | //! All validity bits. |
e8b5f0d5 | 85 | BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS | |
86 | BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS, | |
87 | ||
2fdc3351 MF |
88 | BLOCK_HAVE_DATA = 8, //! full block available in blk*.dat |
89 | BLOCK_HAVE_UNDO = 16, //! undo data available in rev*.dat | |
e8b5f0d5 | 90 | BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, |
91 | ||
2fdc3351 MF |
92 | BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed |
93 | BLOCK_FAILED_CHILD = 64, //! descends from failed block | |
e8b5f0d5 | 94 | BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, |
95 | }; | |
96 | ||
97 | /** The block chain is a tree shaped structure starting with the | |
98 | * genesis block at the root, with each block potentially having multiple | |
99 | * candidates to be the next block. A blockindex may have multiple pprev pointing | |
100 | * to it, but at most one of them can be part of the currently active branch. | |
101 | */ | |
102 | class CBlockIndex | |
103 | { | |
104 | public: | |
bf7835c2 | 105 | //! pointer to the hash of the block, if any. Memory is owned by this CBlockIndex |
e8b5f0d5 | 106 | const uint256* phashBlock; |
107 | ||
2fdc3351 | 108 | //! pointer to the index of the predecessor of this block |
e8b5f0d5 | 109 | CBlockIndex* pprev; |
110 | ||
2fdc3351 | 111 | //! pointer to the index of some further predecessor of this block |
e8b5f0d5 | 112 | CBlockIndex* pskip; |
113 | ||
2fdc3351 | 114 | //! height of the entry in the chain. The genesis block has height 0 |
e8b5f0d5 | 115 | int nHeight; |
116 | ||
2fdc3351 | 117 | //! Which # file this block is stored in (blk?????.dat) |
e8b5f0d5 | 118 | int nFile; |
119 | ||
2fdc3351 | 120 | //! Byte offset within blk?????.dat where this block's data is stored |
e8b5f0d5 | 121 | unsigned int nDataPos; |
122 | ||
2fdc3351 | 123 | //! Byte offset within rev?????.dat where this block's undo data is stored |
e8b5f0d5 | 124 | unsigned int nUndoPos; |
125 | ||
2fdc3351 | 126 | //! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block |
734f85c4 | 127 | arith_uint256 nChainWork; |
e8b5f0d5 | 128 | |
2fdc3351 MF |
129 | //! Number of transactions in this block. |
130 | //! Note: in a potential headers-first mode, this number cannot be relied upon | |
e8b5f0d5 | 131 | unsigned int nTx; |
132 | ||
2fdc3351 MF |
133 | //! (memory only) Number of transactions in the chain up to and including this block. |
134 | //! This value will be non-zero only if and only if transactions for this block and all its parents are available. | |
135 | //! Change to 64-bit type when necessary; won't happen before 2030 | |
136 | unsigned int nChainTx; | |
e8b5f0d5 | 137 | |
2fdc3351 | 138 | //! Verification status of this block. See enum BlockStatus |
e8b5f0d5 | 139 | unsigned int nStatus; |
140 | ||
2fdc3351 | 141 | //! block header |
e8b5f0d5 | 142 | int nVersion; |
143 | uint256 hashMerkleRoot; | |
144 | unsigned int nTime; | |
145 | unsigned int nBits; | |
146 | unsigned int nNonce; | |
147 | ||
2fdc3351 | 148 | //! (memory only) Sequential id assigned to distinguish order in which blocks are received. |
e8b5f0d5 | 149 | uint32_t nSequenceId; |
150 | ||
151 | void SetNull() | |
152 | { | |
153 | phashBlock = NULL; | |
154 | pprev = NULL; | |
155 | pskip = NULL; | |
156 | nHeight = 0; | |
157 | nFile = 0; | |
158 | nDataPos = 0; | |
159 | nUndoPos = 0; | |
734f85c4 | 160 | nChainWork = arith_uint256(); |
e8b5f0d5 | 161 | nTx = 0; |
162 | nChainTx = 0; | |
163 | nStatus = 0; | |
164 | nSequenceId = 0; | |
165 | ||
166 | nVersion = 0; | |
4f152496 | 167 | hashMerkleRoot = uint256(); |
e8b5f0d5 | 168 | nTime = 0; |
169 | nBits = 0; | |
170 | nNonce = 0; | |
171 | } | |
172 | ||
173 | CBlockIndex() | |
174 | { | |
175 | SetNull(); | |
176 | } | |
177 | ||
341735eb | 178 | CBlockIndex(const CBlockHeader& block) |
e8b5f0d5 | 179 | { |
180 | SetNull(); | |
181 | ||
182 | nVersion = block.nVersion; | |
183 | hashMerkleRoot = block.hashMerkleRoot; | |
184 | nTime = block.nTime; | |
185 | nBits = block.nBits; | |
186 | nNonce = block.nNonce; | |
187 | } | |
188 | ||
189 | CDiskBlockPos GetBlockPos() const { | |
190 | CDiskBlockPos ret; | |
191 | if (nStatus & BLOCK_HAVE_DATA) { | |
192 | ret.nFile = nFile; | |
193 | ret.nPos = nDataPos; | |
194 | } | |
195 | return ret; | |
196 | } | |
197 | ||
198 | CDiskBlockPos GetUndoPos() const { | |
199 | CDiskBlockPos ret; | |
200 | if (nStatus & BLOCK_HAVE_UNDO) { | |
201 | ret.nFile = nFile; | |
202 | ret.nPos = nUndoPos; | |
203 | } | |
204 | return ret; | |
205 | } | |
206 | ||
207 | CBlockHeader GetBlockHeader() const | |
208 | { | |
209 | CBlockHeader block; | |
210 | block.nVersion = nVersion; | |
211 | if (pprev) | |
212 | block.hashPrevBlock = pprev->GetBlockHash(); | |
213 | block.hashMerkleRoot = hashMerkleRoot; | |
214 | block.nTime = nTime; | |
215 | block.nBits = nBits; | |
216 | block.nNonce = nNonce; | |
217 | return block; | |
218 | } | |
219 | ||
220 | uint256 GetBlockHash() const | |
221 | { | |
222 | return *phashBlock; | |
223 | } | |
224 | ||
225 | int64_t GetBlockTime() const | |
226 | { | |
227 | return (int64_t)nTime; | |
228 | } | |
229 | ||
e8b5f0d5 | 230 | enum { nMedianTimeSpan=11 }; |
231 | ||
232 | int64_t GetMedianTimePast() const | |
233 | { | |
234 | int64_t pmedian[nMedianTimeSpan]; | |
235 | int64_t* pbegin = &pmedian[nMedianTimeSpan]; | |
236 | int64_t* pend = &pmedian[nMedianTimeSpan]; | |
237 | ||
238 | const CBlockIndex* pindex = this; | |
239 | for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) | |
240 | *(--pbegin) = pindex->GetBlockTime(); | |
241 | ||
242 | std::sort(pbegin, pend); | |
243 | return pbegin[(pend - pbegin)/2]; | |
244 | } | |
245 | ||
e8b5f0d5 | 246 | std::string ToString() const |
247 | { | |
248 | return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", | |
249 | pprev, nHeight, | |
250 | hashMerkleRoot.ToString(), | |
251 | GetBlockHash().ToString()); | |
252 | } | |
253 | ||
2fdc3351 | 254 | //! Check whether this block index entry is valid up to the passed validity level. |
e8b5f0d5 | 255 | bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const |
256 | { | |
257 | assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. | |
258 | if (nStatus & BLOCK_FAILED_MASK) | |
259 | return false; | |
260 | return ((nStatus & BLOCK_VALID_MASK) >= nUpTo); | |
261 | } | |
262 | ||
2fdc3351 MF |
263 | //! Raise the validity level of this block index entry. |
264 | //! Returns true if the validity was changed. | |
e8b5f0d5 | 265 | bool RaiseValidity(enum BlockStatus nUpTo) |
266 | { | |
267 | assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. | |
268 | if (nStatus & BLOCK_FAILED_MASK) | |
269 | return false; | |
270 | if ((nStatus & BLOCK_VALID_MASK) < nUpTo) { | |
271 | nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo; | |
272 | return true; | |
273 | } | |
274 | return false; | |
275 | } | |
276 | ||
2fdc3351 | 277 | //! Build the skiplist pointer for this entry. |
e8b5f0d5 | 278 | void BuildSkip(); |
279 | ||
2fdc3351 | 280 | //! Efficiently find an ancestor of this block. |
e8b5f0d5 | 281 | CBlockIndex* GetAncestor(int height); |
282 | const CBlockIndex* GetAncestor(int height) const; | |
283 | }; | |
284 | ||
285 | /** Used to marshal pointers into hashes for db storage. */ | |
286 | class CDiskBlockIndex : public CBlockIndex | |
287 | { | |
288 | public: | |
289 | uint256 hashPrev; | |
290 | ||
291 | CDiskBlockIndex() { | |
4f152496 | 292 | hashPrev = uint256(); |
e8b5f0d5 | 293 | } |
294 | ||
63d1ae55 | 295 | explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { |
4f152496 | 296 | hashPrev = (pprev ? pprev->GetBlockHash() : uint256()); |
e8b5f0d5 | 297 | } |
298 | ||
299 | ADD_SERIALIZE_METHODS; | |
300 | ||
301 | template <typename Stream, typename Operation> | |
302 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { | |
303 | if (!(nType & SER_GETHASH)) | |
304 | READWRITE(VARINT(nVersion)); | |
305 | ||
306 | READWRITE(VARINT(nHeight)); | |
307 | READWRITE(VARINT(nStatus)); | |
308 | READWRITE(VARINT(nTx)); | |
309 | if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) | |
310 | READWRITE(VARINT(nFile)); | |
311 | if (nStatus & BLOCK_HAVE_DATA) | |
312 | READWRITE(VARINT(nDataPos)); | |
313 | if (nStatus & BLOCK_HAVE_UNDO) | |
314 | READWRITE(VARINT(nUndoPos)); | |
315 | ||
316 | // block header | |
317 | READWRITE(this->nVersion); | |
318 | READWRITE(hashPrev); | |
319 | READWRITE(hashMerkleRoot); | |
320 | READWRITE(nTime); | |
321 | READWRITE(nBits); | |
322 | READWRITE(nNonce); | |
323 | } | |
324 | ||
325 | uint256 GetBlockHash() const | |
326 | { | |
327 | CBlockHeader block; | |
328 | block.nVersion = nVersion; | |
329 | block.hashPrevBlock = hashPrev; | |
330 | block.hashMerkleRoot = hashMerkleRoot; | |
331 | block.nTime = nTime; | |
332 | block.nBits = nBits; | |
333 | block.nNonce = nNonce; | |
334 | return block.GetHash(); | |
335 | } | |
336 | ||
337 | ||
338 | std::string ToString() const | |
339 | { | |
340 | std::string str = "CDiskBlockIndex("; | |
341 | str += CBlockIndex::ToString(); | |
342 | str += strprintf("\n hashBlock=%s, hashPrev=%s)", | |
343 | GetBlockHash().ToString(), | |
344 | hashPrev.ToString()); | |
345 | return str; | |
346 | } | |
347 | }; | |
348 | ||
349 | /** An in-memory indexed chain of blocks. */ | |
350 | class CChain { | |
351 | private: | |
352 | std::vector<CBlockIndex*> vChain; | |
353 | ||
354 | public: | |
355 | /** Returns the index entry for the genesis block of this chain, or NULL if none. */ | |
356 | CBlockIndex *Genesis() const { | |
357 | return vChain.size() > 0 ? vChain[0] : NULL; | |
358 | } | |
359 | ||
360 | /** Returns the index entry for the tip of this chain, or NULL if none. */ | |
361 | CBlockIndex *Tip() const { | |
362 | return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; | |
363 | } | |
364 | ||
365 | /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ | |
366 | CBlockIndex *operator[](int nHeight) const { | |
367 | if (nHeight < 0 || nHeight >= (int)vChain.size()) | |
368 | return NULL; | |
369 | return vChain[nHeight]; | |
370 | } | |
371 | ||
372 | /** Compare two chains efficiently. */ | |
373 | friend bool operator==(const CChain &a, const CChain &b) { | |
374 | return a.vChain.size() == b.vChain.size() && | |
375 | a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1]; | |
376 | } | |
377 | ||
378 | /** Efficiently check whether a block is present in this chain. */ | |
379 | bool Contains(const CBlockIndex *pindex) const { | |
380 | return (*this)[pindex->nHeight] == pindex; | |
381 | } | |
382 | ||
383 | /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ | |
384 | CBlockIndex *Next(const CBlockIndex *pindex) const { | |
385 | if (Contains(pindex)) | |
386 | return (*this)[pindex->nHeight + 1]; | |
387 | else | |
388 | return NULL; | |
389 | } | |
390 | ||
391 | /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ | |
392 | int Height() const { | |
393 | return vChain.size() - 1; | |
394 | } | |
395 | ||
b7ae2c17 | 396 | /** Set/initialize a chain with a given tip. */ |
397 | void SetTip(CBlockIndex *pindex); | |
e8b5f0d5 | 398 | |
399 | /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ | |
400 | CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; | |
401 | ||
402 | /** Find the last common block between this chain and a block index entry. */ | |
403 | const CBlockIndex *FindFork(const CBlockIndex *pindex) const; | |
404 | }; | |
405 | ||
84738627 | 406 | #endif // BITCOIN_CHAIN_H |