aboutsummaryrefslogtreecommitdiff
path: root/src/main.h
diff options
context:
space:
mode:
authorjtimon <jtimon@blockstream.io>2014-09-03 02:20:09 +0200
committerjtimon <jtimon@blockstream.io>2014-09-08 22:17:19 +0200
commite8b5f0d549b1b76611c7374bed9ceec7d09fa847 (patch)
treea35ca887cbbe54978bf94943a5a250d6ec30540e /src/main.h
parent6db83db3eb96809da3e680464b152f82785e38e6 (diff)
Move CBlockIndex, CChain and related code out of main
Diffstat (limited to 'src/main.h')
-rw-r--r--src/main.h381
1 files changed, 1 insertions, 380 deletions
diff --git a/src/main.h b/src/main.h
index dbc20783bb..ff55a26cac 100644
--- a/src/main.h
+++ b/src/main.h
@@ -10,6 +10,7 @@
#include "config/bitcoin-config.h"
#endif
+#include "chain.h"
#include "chainparams.h"
#include "coins.h"
#include "core.h"
@@ -113,7 +114,6 @@ static const uint64_t nMinDiskSpace = 52428800;
class CBlockTreeDB;
-struct CDiskBlockPos;
class CTxUndo;
class CScriptCheck;
class CValidationState;
@@ -189,51 +189,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
bool* pfMissingInputs, bool fRejectInsaneFee=false);
-
-
-
-
-
-
struct CNodeStateStats {
int nMisbehavior;
int nSyncHeight;
};
-struct CDiskBlockPos
-{
- int nFile;
- unsigned int nPos;
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(VARINT(nFile));
- READWRITE(VARINT(nPos));
- }
-
- CDiskBlockPos() {
- SetNull();
- }
-
- CDiskBlockPos(int nFileIn, unsigned int nPosIn) {
- nFile = nFileIn;
- nPos = nPosIn;
- }
-
- friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) {
- return (a.nFile == b.nFile && a.nPos == b.nPos);
- }
-
- friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) {
- return !(a == b);
- }
-
- void SetNull() { nFile = -1; nPos = 0; }
- bool IsNull() const { return (nFile == -1); }
-};
-
struct CDiskTxPos : public CDiskBlockPos
{
unsigned int nTxOffset; // after header
@@ -547,288 +507,6 @@ public:
}
};
-enum BlockStatus {
- BLOCK_VALID_UNKNOWN = 0,
- BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
- BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint
- BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root
- BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30
- BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok
- BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS |
- BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS,
-
- BLOCK_HAVE_DATA = 8, // full block available in blk*.dat
- BLOCK_HAVE_UNDO = 16, // undo data available in rev*.dat
- BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO,
-
- BLOCK_FAILED_VALID = 32, // stage after last reached validness failed
- BLOCK_FAILED_CHILD = 64, // descends from failed block
- BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,
-};
-
-/** 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
- 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
- unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030
-
- // Verification status of this block. See enum BlockStatus
- unsigned int nStatus;
-
- // block header
- int nVersion;
- uint256 hashMerkleRoot;
- unsigned int nTime;
- unsigned int nBits;
- unsigned int nNonce;
-
- // (memory only) Sequencial id assigned to distinguish order in which blocks are received.
- uint32_t nSequenceId;
-
- void SetNull()
- {
- phashBlock = NULL;
- pprev = NULL;
- pskip = NULL;
- nHeight = 0;
- nFile = 0;
- nDataPos = 0;
- nUndoPos = 0;
- nChainWork = 0;
- nTx = 0;
- nChainTx = 0;
- nStatus = 0;
- nSequenceId = 0;
-
- nVersion = 0;
- hashMerkleRoot = 0;
- nTime = 0;
- nBits = 0;
- nNonce = 0;
- }
-
- CBlockIndex()
- {
- SetNull();
- }
-
- CBlockIndex(CBlockHeader& block)
- {
- SetNull();
-
- nVersion = block.nVersion;
- hashMerkleRoot = block.hashMerkleRoot;
- nTime = block.nTime;
- nBits = block.nBits;
- nNonce = block.nNonce;
- }
-
- CDiskBlockPos GetBlockPos() const {
- CDiskBlockPos ret;
- if (nStatus & BLOCK_HAVE_DATA) {
- ret.nFile = nFile;
- ret.nPos = nDataPos;
- }
- return ret;
- }
-
- CDiskBlockPos GetUndoPos() const {
- CDiskBlockPos ret;
- if (nStatus & BLOCK_HAVE_UNDO) {
- 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;
- }
-
- uint256 GetBlockWork() const
- {
- return GetProofIncrement(nBits);
- }
-
- 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];
- }
-
- /**
- * Returns true if there are nRequired or more blocks of minVersion or above
- * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart
- * and going backwards.
- */
- static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart,
- unsigned int nRequired);
-
- 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 BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const
- {
- assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
- if (nStatus & BLOCK_FAILED_MASK)
- return false;
- return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
- }
-
- // Raise the validity level of this block index entry.
- // Returns true if the validity was changed.
- bool RaiseValidity(enum BlockStatus nUpTo)
- {
- assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
- if (nStatus & BLOCK_FAILED_MASK)
- return false;
- if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
- nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
- return true;
- }
- return false;
- }
-
- // 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;
-};
-
-/** Used to marshal pointers into hashes for db storage. */
-class CDiskBlockIndex : public CBlockIndex
-{
-public:
- uint256 hashPrev;
-
- CDiskBlockIndex() {
- hashPrev = 0;
- }
-
- explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) {
- hashPrev = (pprev ? pprev->GetBlockHash() : 0);
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (!(nType & SER_GETHASH))
- READWRITE(VARINT(nVersion));
-
- READWRITE(VARINT(nHeight));
- READWRITE(VARINT(nStatus));
- READWRITE(VARINT(nTx));
- if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
- READWRITE(VARINT(nFile));
- if (nStatus & BLOCK_HAVE_DATA)
- READWRITE(VARINT(nDataPos));
- if (nStatus & BLOCK_HAVE_UNDO)
- 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;
- }
-};
-
/** Capture information about block/transaction validation */
class CValidationState {
private:
@@ -900,63 +578,6 @@ public:
bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth);
};
-/** An in-memory indexed chain of blocks. */
-class CChain {
-private:
- std::vector<CBlockIndex*> vChain;
-
-public:
- /** Returns the index entry for the genesis block of this chain, or NULL if none. */
- CBlockIndex *Genesis() const {
- return vChain.size() > 0 ? vChain[0] : NULL;
- }
-
- /** Returns the index entry for the tip of this chain, or NULL if none. */
- CBlockIndex *Tip() const {
- return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL;
- }
-
- /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */
- CBlockIndex *operator[](int nHeight) const {
- if (nHeight < 0 || nHeight >= (int)vChain.size())
- return NULL;
- 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 NULL if the given index is not found or is the tip. */
- CBlockIndex *Next(const CBlockIndex *pindex) const {
- if (Contains(pindex))
- return (*this)[pindex->nHeight + 1];
- else
- return NULL;
- }
-
- /** 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. Returns the forking point. */
- CBlockIndex *SetTip(CBlockIndex *pindex);
-
- /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
- CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const;
-
- /** Find the last common block between this chain and a block index entry. */
- const CBlockIndex *FindFork(const CBlockIndex *pindex) const;
-};
-
/** Find the last common block between the parameter chain and a locator. */
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator);