diff --git a/src/Makefile.am b/src/Makefile.am --- a/src/Makefile.am +++ b/src/Makefile.am @@ -106,6 +106,7 @@ bloom.h \ blockencodings.h \ blockfileinfo.h \ + blockindex.h \ blockindexworkcomparator.h \ blockstatus.h \ blockvalidity.h \ diff --git a/src/chain.h b/src/blockindex.h copy from src/chain.h copy to src/blockindex.h --- a/src/chain.h +++ b/src/blockindex.h @@ -1,37 +1,19 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2016 The Bitcoin Core developers +// Copyright (c) 2018 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_CHAIN_H -#define BITCOIN_CHAIN_H +#ifndef BITCOIN_BLOCKINDEX_H +#define BITCOIN_BLOCKINDEX_H #include "arith_uint256.h" #include "blockstatus.h" #include "blockvalidity.h" -#include "consensus/params.h" #include "diskblockpos.h" -#include "pow.h" #include "primitives/block.h" #include "tinyformat.h" #include "uint256.h" -#include -#include - -/** - * Maximum amount of time that a block timestamp is allowed to exceed the - * current network-adjusted time before the block will be accepted. - */ -static const int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; - -/** - * Timestamp window used as a grace period by code that compares external - * timestamps (such as timestamps passed to RPCs, or wallet key creation times) - * to block timestamps. This should be set at least as high as - * MAX_FUTURE_BLOCK_TIME. - */ -static const int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; +#include /** * The block chain is a tree shaped structure starting with the genesis block at @@ -235,176 +217,4 @@ const CBlockIndex *GetAncestor(int height) const; }; -/** - * Maintain a map of CBlockIndex for all known headers. - */ -struct BlockHasher { - size_t operator()(const uint256 &hash) const { return hash.GetCheapHash(); } -}; - -typedef std::unordered_map BlockMap; -extern BlockMap mapBlockIndex; - -arith_uint256 GetBlockProof(const CBlockIndex &block); - -/** - * Return the time it would take to redo the work difference between from and - * to, assuming the current hashrate corresponds to the difficulty at tip, in - * seconds. - */ -int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, - const CBlockIndex &from, - const CBlockIndex &tip, - const Consensus::Params &); -/** - * Find the forking point between two chain tips. - */ -const CBlockIndex *LastCommonAncestor(const CBlockIndex *pa, - const CBlockIndex *pb); - -/** Used to marshal pointers into hashes for db storage. */ -class CDiskBlockIndex : public CBlockIndex { -public: - uint256 hashPrev; - - CDiskBlockIndex() { hashPrev = uint256(); } - - explicit CDiskBlockIndex(const CBlockIndex *pindex) : CBlockIndex(*pindex) { - hashPrev = (pprev ? pprev->GetBlockHash() : uint256()); - } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream &s, Operation ser_action) { - int _nVersion = s.GetVersion(); - if (!(s.GetType() & SER_GETHASH)) { - READWRITE(VARINT(_nVersion)); - } - - READWRITE(VARINT(nHeight)); - READWRITE(nStatus); - READWRITE(VARINT(nTx)); - if (nStatus.hasData() || nStatus.hasUndo()) { - READWRITE(VARINT(nFile)); - } - if (nStatus.hasData()) { - READWRITE(VARINT(nDataPos)); - } - if (nStatus.hasUndo()) { - READWRITE(VARINT(nUndoPos)); - } - - // block header - READWRITE(this->nVersion); - READWRITE(hashPrev); - READWRITE(hashMerkleRoot); - READWRITE(nTime); - READWRITE(nBits); - READWRITE(nNonce); - } - - uint256 GetBlockHash() const { - CBlockHeader block; - block.nVersion = nVersion; - block.hashPrevBlock = hashPrev; - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block.GetHash(); - } - - std::string ToString() const { - std::string str = "CDiskBlockIndex("; - str += CBlockIndex::ToString(); - str += strprintf("\n hashBlock=%s, hashPrev=%s)", - GetBlockHash().ToString(), hashPrev.ToString()); - return str; - } -}; - -/** - * An in-memory indexed chain of blocks. - */ -class CChain { -private: - std::vector vChain; - -public: - /** - * Returns the index entry for the genesis block of this chain, or nullptr - * if none. - */ - CBlockIndex *Genesis() const { - return vChain.size() > 0 ? vChain[0] : nullptr; - } - - /** - * Returns the index entry for the tip of this chain, or nullptr if none. - */ - CBlockIndex *Tip() const { - return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr; - } - - /** - * Returns the index entry at a particular height in this chain, or nullptr - * if no such height exists. - */ - CBlockIndex *operator[](int nHeight) const { - if (nHeight < 0 || nHeight >= (int)vChain.size()) { - return nullptr; - } - return vChain[nHeight]; - } - - /** Compare two chains efficiently. */ - friend bool operator==(const CChain &a, const CChain &b) { - return a.vChain.size() == b.vChain.size() && - a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1]; - } - - /** Efficiently check whether a block is present in this chain. */ - bool Contains(const CBlockIndex *pindex) const { - return (*this)[pindex->nHeight] == pindex; - } - - /** - * Find the successor of a block in this chain, or nullptr if the given - * index is not found or is the tip. - */ - CBlockIndex *Next(const CBlockIndex *pindex) const { - if (!Contains(pindex)) { - return nullptr; - } - - return (*this)[pindex->nHeight + 1]; - } - - /** - * Return the maximal height in the chain. Is equal to chain.Tip() ? - * chain.Tip()->nHeight : -1. - */ - int Height() const { return vChain.size() - 1; } - - /** Set/initialize a chain with a given tip. */ - void SetTip(CBlockIndex *pindex); - - /** - * Return a CBlockLocator that refers to a block in this chain (by default - * the tip). - */ - CBlockLocator GetLocator(const CBlockIndex *pindex = nullptr) const; - - /** - * Find the last common block between this chain and a block index entry. - */ - const CBlockIndex *FindFork(const CBlockIndex *pindex) const; - - /** - * Find the earliest block with timestamp equal or greater than the given. - */ - CBlockIndex *FindEarliestAtLeast(int64_t nTime) const; -}; - -#endif // BITCOIN_CHAIN_H +#endif // BITCOIN_BLOCKINDEX_H diff --git a/src/blockindexworkcomparator.h b/src/blockindexworkcomparator.h --- a/src/blockindexworkcomparator.h +++ b/src/blockindexworkcomparator.h @@ -5,8 +5,7 @@ #ifndef BITCOIN_BLOCK_INDEX_WORK_COMPARATOR_H #define BITCOIN_BLOCK_INDEX_WORK_COMPARATOR_H -// TODO: Split chain.h apart and only include CBlockIndex -#include "chain.h" +#include "blockindex.h" struct CBlockIndexWorkComparator { bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const { diff --git a/src/chain.h b/src/chain.h --- a/src/chain.h +++ b/src/chain.h @@ -7,8 +7,7 @@ #define BITCOIN_CHAIN_H #include "arith_uint256.h" -#include "blockstatus.h" -#include "blockvalidity.h" +#include "blockindex.h" #include "consensus/params.h" #include "diskblockpos.h" #include "pow.h" @@ -33,208 +32,6 @@ */ static const int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; -/** - * The block chain is a tree shaped structure starting with the genesis block at - * the root, with each block potentially having multiple candidates to be the - * next block. A blockindex may have multiple pprev pointing to it, but at most - * one of them can be part of the currently active branch. - */ -class CBlockIndex { -public: - //! pointer to the hash of the block, if any. Memory is owned by this - //! CBlockIndex - const uint256 *phashBlock; - - //! pointer to the index of the predecessor of this block - CBlockIndex *pprev; - - //! pointer to the index of some further predecessor of this block - CBlockIndex *pskip; - - //! height of the entry in the chain. The genesis block has height 0 - int nHeight; - - //! Which # file this block is stored in (blk?????.dat) - int nFile; - - //! Byte offset within blk?????.dat where this block's data is stored - unsigned int nDataPos; - - //! Byte offset within rev?????.dat where this block's undo data is stored - unsigned int nUndoPos; - - //! (memory only) Total amount of work (expected number of hashes) in the - //! chain up to and including this block - arith_uint256 nChainWork; - - //! Number of transactions in this block. - //! Note: in a potential headers-first mode, this number cannot be relied - //! upon - unsigned int nTx; - - //! (memory only) Number of transactions in the chain up to and including - //! this block. - //! This value will be non-zero only if and only if transactions for this - //! block and all its parents are available. Change to 64-bit type when - //! necessary; won't happen before 2030 - unsigned int nChainTx; - - //! Verification status of this block. See enum BlockStatus - BlockStatus nStatus; - - //! block header - int32_t nVersion; - uint256 hashMerkleRoot; - uint32_t nTime; - uint32_t nBits; - uint32_t nNonce; - - //! (memory only) Sequential id assigned to distinguish order in which - //! blocks are received. - int32_t nSequenceId; - - //! (memory only) block header metadata - uint64_t nTimeReceived; - - //! (memory only) Maximum nTime in the chain upto and including this block. - unsigned int nTimeMax; - - void SetNull() { - phashBlock = nullptr; - pprev = nullptr; - pskip = nullptr; - nHeight = 0; - nFile = 0; - nDataPos = 0; - nUndoPos = 0; - nChainWork = arith_uint256(); - nTx = 0; - nChainTx = 0; - nStatus = BlockStatus(); - nSequenceId = 0; - nTimeMax = 0; - - nVersion = 0; - hashMerkleRoot = uint256(); - nTime = 0; - nTimeReceived = 0; - nBits = 0; - nNonce = 0; - } - - CBlockIndex() { SetNull(); } - - CBlockIndex(const CBlockHeader &block) { - SetNull(); - - nVersion = block.nVersion; - hashMerkleRoot = block.hashMerkleRoot; - nTime = block.nTime; - // Default to block time if nTimeReceived is never set, which - // in effect assumes that this block is honestly mined. - // Note that nTimeReceived isn't written to disk, so blocks read from - // disk will be assumed to be honestly mined. - nTimeReceived = block.nTime; - nBits = block.nBits; - nNonce = block.nNonce; - } - - CDiskBlockPos GetBlockPos() const { - CDiskBlockPos ret; - if (nStatus.hasData()) { - ret.nFile = nFile; - ret.nPos = nDataPos; - } - return ret; - } - - CDiskBlockPos GetUndoPos() const { - CDiskBlockPos ret; - if (nStatus.hasUndo()) { - ret.nFile = nFile; - ret.nPos = nUndoPos; - } - return ret; - } - - CBlockHeader GetBlockHeader() const { - CBlockHeader block; - block.nVersion = nVersion; - if (pprev) { - block.hashPrevBlock = pprev->GetBlockHash(); - } - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block; - } - - uint256 GetBlockHash() const { return *phashBlock; } - - int64_t GetBlockTime() const { return int64_t(nTime); } - - int64_t GetBlockTimeMax() const { return int64_t(nTimeMax); } - - int64_t GetHeaderReceivedTime() const { return nTimeReceived; } - - int64_t GetReceivedTimeDiff() const { - return GetHeaderReceivedTime() - GetBlockTime(); - } - - enum { nMedianTimeSpan = 11 }; - - int64_t GetMedianTimePast() const { - int64_t pmedian[nMedianTimeSpan]; - int64_t *pbegin = &pmedian[nMedianTimeSpan]; - int64_t *pend = &pmedian[nMedianTimeSpan]; - - const CBlockIndex *pindex = this; - for (int i = 0; i < nMedianTimeSpan && pindex; - i++, pindex = pindex->pprev) { - *(--pbegin) = pindex->GetBlockTime(); - } - - std::sort(pbegin, pend); - return pbegin[(pend - pbegin) / 2]; - } - - std::string ToString() const { - return strprintf( - "CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", pprev, - nHeight, hashMerkleRoot.ToString(), GetBlockHash().ToString()); - } - - //! Check whether this block index entry is valid up to the passed validity - //! level. - bool IsValid(enum BlockValidity nUpTo = BlockValidity::TRANSACTIONS) const { - return nStatus.isValid(nUpTo); - } - - //! Raise the validity level of this block index entry. - //! Returns true if the validity was changed. - bool RaiseValidity(enum BlockValidity nUpTo) { - // Only validity flags allowed. - if (nStatus.isInvalid()) { - return false; - } - - if (nStatus.getValidity() >= nUpTo) { - return false; - } - - nStatus = nStatus.withValidity(nUpTo); - return true; - } - - //! Build the skiplist pointer for this entry. - void BuildSkip(); - - //! Efficiently find an ancestor of this block. - CBlockIndex *GetAncestor(int height); - const CBlockIndex *GetAncestor(int height) const; -}; - /** * Maintain a map of CBlockIndex for all known headers. */ @@ -262,7 +59,11 @@ const CBlockIndex *LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb); -/** Used to marshal pointers into hashes for db storage. */ +/** + * Used to marshal pointers into hashes for db storage. + * TODO: Once CDiskBlockIndex is removed chain.h should + * use a forward declaration for CBlockIndex. +*/ class CDiskBlockIndex : public CBlockIndex { public: uint256 hashPrev; diff --git a/src/miner.cpp b/src/miner.cpp --- a/src/miner.cpp +++ b/src/miner.cpp @@ -6,7 +6,7 @@ #include "miner.h" #include "amount.h" -#include "chain.h" +#include "blockindex.h" #include "chainparams.h" #include "coins.h" #include "config.h" diff --git a/src/pow.cpp b/src/pow.cpp --- a/src/pow.cpp +++ b/src/pow.cpp @@ -7,7 +7,7 @@ #include "pow.h" #include "arith_uint256.h" -#include "chain.h" +#include "blockindex.h" #include "chainparams.h" #include "config.h" #include "consensus/activation.h" diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -6,6 +6,7 @@ #include "rpc/blockchain.h" #include "amount.h" +#include "blockindex.h" #include "chain.h" #include "chainparams.h" #include "checkpoints.h" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -5,6 +5,7 @@ #include "rpc/mining.h" #include "amount.h" +#include "blockindex.h" #include "blockvalidity.h" #include "chain.h" #include "chainparams.h" diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -6,6 +6,7 @@ #include "chainparams.h" #include "config.h" #include "consensus/merkle.h" +#include "pow.h" #include "random.h" #include "test/test_bitcoin.h" diff --git a/src/test/blockindex_tests.cpp b/src/test/blockindex_tests.cpp --- a/src/test/blockindex_tests.cpp +++ b/src/test/blockindex_tests.cpp @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "blockindex.h" #include "blockvalidity.h" -#include "chain.h" #include "diskblockpos.h" #include "uint256.h" diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "blockindex.h" #include "chain.h" #include "chainparams.h" #include "config.h" diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "blockindex.h" #include "chain.h" #include "test/test_bitcoin.h" #include "util.h" diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "chain.h" +#include "blockindex.h" #include "chainparams.h" #include "consensus/params.h" #include "test/test_bitcoin.h" diff --git a/src/txdb.h b/src/txdb.h --- a/src/txdb.h +++ b/src/txdb.h @@ -7,7 +7,6 @@ #define BITCOIN_TXDB_H #include "blockfileinfo.h" -#include "chain.h" #include "coins.h" #include "dbwrapper.h" #include "diskblockpos.h" diff --git a/src/txdb.cpp b/src/txdb.cpp --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -5,6 +5,7 @@ #include "txdb.h" +#include "chain.h" #include "chainparams.h" #include "hash.h" #include "init.h" diff --git a/src/validation.h b/src/validation.h --- a/src/validation.h +++ b/src/validation.h @@ -12,7 +12,9 @@ #endif #include "amount.h" +#include "arith_uint256.h" #include "blockfileinfo.h" +#include "chain.h" #include "coins.h" #include "consensus/consensus.h" #include "diskblockpos.h" diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -7,6 +7,7 @@ #include "validation.h" #include "arith_uint256.h" +#include "blockindex.h" #include "blockindexworkcomparator.h" #include "blockvalidity.h" #include "chainparams.h" diff --git a/src/versionbits.h b/src/versionbits.h --- a/src/versionbits.h +++ b/src/versionbits.h @@ -5,9 +5,11 @@ #ifndef BITCOIN_CONSENSUS_VERSIONBITS #define BITCOIN_CONSENSUS_VERSIONBITS -#include "chain.h" +#include "consensus/params.h" #include +class CBlockIndex; + /** What block version to use for new blocks (pre versionbits) */ static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4; /** What bits to set in version for versionbits blocks */ diff --git a/src/versionbits.cpp b/src/versionbits.cpp --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -4,6 +4,7 @@ #include "versionbits.h" +#include "blockindex.h" #include "consensus/params.h" const struct BIP9DeploymentInfo diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" +#include "blockindex.h" #include "chain.h" #include "config.h" #include "core_io.h" diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "amount.h" +#include "blockindex.h" #include "chain.h" #include "chainparams.h" // for GetConsensus. #include "config.h" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5,6 +5,7 @@ #include "wallet/wallet.h" +#include "blockindex.h" #include "chain.h" #include "checkpoints.h" #include "config.h"