diff options
Diffstat (limited to 'src/main.h')
-rw-r--r-- | src/main.h | 407 |
1 files changed, 15 insertions, 392 deletions
diff --git a/src/main.h b/src/main.h index 5acc551793..cad7eebfb7 100644 --- a/src/main.h +++ b/src/main.h @@ -10,12 +10,14 @@ #include "config/bitcoin-config.h" #endif +#include "chain.h" #include "chainparams.h" #include "coins.h" #include "core.h" #include "net.h" #include "pow.h" #include "script/script.h" +#include "script/sigcache.h" #include "script/standard.h" #include "sync.h" #include "txmempool.h" @@ -113,7 +115,6 @@ static const uint64_t nMinDiskSpace = 52428800; class CBlockTreeDB; -struct CDiskBlockPos; class CTxUndo; class CScriptCheck; class CValidationState; @@ -172,12 +173,12 @@ std::string GetWarnings(std::string strFor); bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL); -int64_t GetBlockValue(int nHeight, int64_t nFees); +CAmount GetBlockValue(int nHeight, const CAmount& nFees); /** Create a new block index entry for a given block hash */ CBlockIndex * InsertBlockIndex(uint256 hash); /** Abort with a message */ -bool AbortNode(const std::string &msg); +bool AbortNode(const std::string &msg, const std::string &userMessage=""); /** Get statistics from node state */ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); /** Increase a node's misbehavior score. */ @@ -189,51 +190,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 @@ -260,7 +221,7 @@ struct CDiskTxPos : public CDiskBlockPos }; -int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); +CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); // // Check transaction inputs, and make sure any @@ -298,9 +259,8 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& ma // Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) // This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it // instead of being performed inline. -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks = true, - unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS, - std::vector<CScriptCheck> *pvChecks = NULL); +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks, + unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL); // Apply the effects of this transaction on the UTXO set represented by view void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight); @@ -342,12 +302,13 @@ private: const CTransaction *ptxTo; unsigned int nIn; unsigned int nFlags; + bool cacheStore; public: - CScriptCheck(): ptxTo(0), nIn(0), nFlags(0) {} - CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn) : + CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false) {} + CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) : scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), - ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn) { } + ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn) { } bool operator()() const; @@ -356,6 +317,7 @@ public: std::swap(ptxTo, check.ptxTo); std::swap(nIn, check.nIn); std::swap(nFlags, check.nFlags); + std::swap(cacheStore, check.cacheStore); } }; @@ -545,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: @@ -898,65 +578,8 @@ 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 locator. */ - CBlockIndex *FindFork(const CBlockLocator &locator) 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); /** The currently-connected chain of blocks. */ extern CChain chainActive; @@ -970,7 +593,7 @@ extern CBlockTreeDB *pblocktree; struct CBlockTemplate { CBlock block; - std::vector<int64_t> vTxFees; + std::vector<CAmount> vTxFees; std::vector<int64_t> vTxSigOps; }; |