1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #ifndef H_BITCOIN_CHAIN
7 #define H_BITCOIN_CHAIN
15 #include <boost/foreach.hpp>
22 ADD_SERIALIZE_METHODS;
24 template <typename Stream, typename Operation>
25 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
26 READWRITE(VARINT(nFile));
27 READWRITE(VARINT(nPos));
34 CDiskBlockPos(int nFileIn, unsigned int nPosIn) {
39 friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) {
40 return (a.nFile == b.nFile && a.nPos == b.nPos);
43 friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) {
47 void SetNull() { nFile = -1; nPos = 0; }
48 bool IsNull() const { return (nFile == -1); }
52 BLOCK_VALID_UNKNOWN = 0,
53 BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
54 BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint
55 BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root
56 BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30
57 BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok
58 BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS |
59 BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS,
61 BLOCK_HAVE_DATA = 8, // full block available in blk*.dat
62 BLOCK_HAVE_UNDO = 16, // undo data available in rev*.dat
63 BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO,
65 BLOCK_FAILED_VALID = 32, // stage after last reached validness failed
66 BLOCK_FAILED_CHILD = 64, // descends from failed block
67 BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,
70 /** The block chain is a tree shaped structure starting with the
71 * genesis block at the root, with each block potentially having multiple
72 * candidates to be the next block. A blockindex may have multiple pprev pointing
73 * to it, but at most one of them can be part of the currently active branch.
78 // pointer to the hash of the block, if any. memory is owned by this CBlockIndex
79 const uint256* phashBlock;
81 // pointer to the index of the predecessor of this block
84 // pointer to the index of some further predecessor of this block
87 // height of the entry in the chain. The genesis block has height 0
90 // Which # file this block is stored in (blk?????.dat)
93 // Byte offset within blk?????.dat where this block's data is stored
94 unsigned int nDataPos;
96 // Byte offset within rev?????.dat where this block's undo data is stored
97 unsigned int nUndoPos;
99 // (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
102 // Number of transactions in this block.
103 // Note: in a potential headers-first mode, this number cannot be relied upon
106 // (memory only) Number of transactions in the chain up to and including this block
107 unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030
109 // Verification status of this block. See enum BlockStatus
110 unsigned int nStatus;
114 uint256 hashMerkleRoot;
119 // (memory only) Sequencial id assigned to distinguish order in which blocks are received.
120 uint32_t nSequenceId;
149 CBlockIndex(CBlockHeader& block)
153 nVersion = block.nVersion;
154 hashMerkleRoot = block.hashMerkleRoot;
157 nNonce = block.nNonce;
160 CDiskBlockPos GetBlockPos() const {
162 if (nStatus & BLOCK_HAVE_DATA) {
169 CDiskBlockPos GetUndoPos() const {
171 if (nStatus & BLOCK_HAVE_UNDO) {
178 CBlockHeader GetBlockHeader() const
181 block.nVersion = nVersion;
183 block.hashPrevBlock = pprev->GetBlockHash();
184 block.hashMerkleRoot = hashMerkleRoot;
187 block.nNonce = nNonce;
191 uint256 GetBlockHash() const
196 int64_t GetBlockTime() const
198 return (int64_t)nTime;
201 uint256 GetBlockWork() const
203 return GetProofIncrement(nBits);
206 enum { nMedianTimeSpan=11 };
208 int64_t GetMedianTimePast() const
210 int64_t pmedian[nMedianTimeSpan];
211 int64_t* pbegin = &pmedian[nMedianTimeSpan];
212 int64_t* pend = &pmedian[nMedianTimeSpan];
214 const CBlockIndex* pindex = this;
215 for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
216 *(--pbegin) = pindex->GetBlockTime();
218 std::sort(pbegin, pend);
219 return pbegin[(pend - pbegin)/2];
223 * Returns true if there are nRequired or more blocks of minVersion or above
224 * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart
225 * and going backwards.
227 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart,
228 unsigned int nRequired);
230 std::string ToString() const
232 return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
234 hashMerkleRoot.ToString(),
235 GetBlockHash().ToString());
238 // Check whether this block index entry is valid up to the passed validity level.
239 bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const
241 assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
242 if (nStatus & BLOCK_FAILED_MASK)
244 return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
247 // Raise the validity level of this block index entry.
248 // Returns true if the validity was changed.
249 bool RaiseValidity(enum BlockStatus nUpTo)
251 assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
252 if (nStatus & BLOCK_FAILED_MASK)
254 if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
255 nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
261 // Build the skiplist pointer for this entry.
264 // Efficiently find an ancestor of this block.
265 CBlockIndex* GetAncestor(int height);
266 const CBlockIndex* GetAncestor(int height) const;
269 /** Used to marshal pointers into hashes for db storage. */
270 class CDiskBlockIndex : public CBlockIndex
279 explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) {
280 hashPrev = (pprev ? pprev->GetBlockHash() : 0);
283 ADD_SERIALIZE_METHODS;
285 template <typename Stream, typename Operation>
286 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
287 if (!(nType & SER_GETHASH))
288 READWRITE(VARINT(nVersion));
290 READWRITE(VARINT(nHeight));
291 READWRITE(VARINT(nStatus));
292 READWRITE(VARINT(nTx));
293 if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
294 READWRITE(VARINT(nFile));
295 if (nStatus & BLOCK_HAVE_DATA)
296 READWRITE(VARINT(nDataPos));
297 if (nStatus & BLOCK_HAVE_UNDO)
298 READWRITE(VARINT(nUndoPos));
301 READWRITE(this->nVersion);
303 READWRITE(hashMerkleRoot);
309 uint256 GetBlockHash() const
312 block.nVersion = nVersion;
313 block.hashPrevBlock = hashPrev;
314 block.hashMerkleRoot = hashMerkleRoot;
317 block.nNonce = nNonce;
318 return block.GetHash();
322 std::string ToString() const
324 std::string str = "CDiskBlockIndex(";
325 str += CBlockIndex::ToString();
326 str += strprintf("\n hashBlock=%s, hashPrev=%s)",
327 GetBlockHash().ToString(),
328 hashPrev.ToString());
333 /** An in-memory indexed chain of blocks. */
336 std::vector<CBlockIndex*> vChain;
339 /** Returns the index entry for the genesis block of this chain, or NULL if none. */
340 CBlockIndex *Genesis() const {
341 return vChain.size() > 0 ? vChain[0] : NULL;
344 /** Returns the index entry for the tip of this chain, or NULL if none. */
345 CBlockIndex *Tip() const {
346 return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL;
349 /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */
350 CBlockIndex *operator[](int nHeight) const {
351 if (nHeight < 0 || nHeight >= (int)vChain.size())
353 return vChain[nHeight];
356 /** Compare two chains efficiently. */
357 friend bool operator==(const CChain &a, const CChain &b) {
358 return a.vChain.size() == b.vChain.size() &&
359 a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1];
362 /** Efficiently check whether a block is present in this chain. */
363 bool Contains(const CBlockIndex *pindex) const {
364 return (*this)[pindex->nHeight] == pindex;
367 /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */
368 CBlockIndex *Next(const CBlockIndex *pindex) const {
369 if (Contains(pindex))
370 return (*this)[pindex->nHeight + 1];
375 /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
377 return vChain.size() - 1;
380 /** Set/initialize a chain with a given tip. Returns the forking point. */
381 CBlockIndex *SetTip(CBlockIndex *pindex);
383 /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
384 CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const;
386 /** Find the last common block between this chain and a block index entry. */
387 const CBlockIndex *FindFork(const CBlockIndex *pindex) const;