diff options
Diffstat (limited to 'src/main.h')
-rw-r--r-- | src/main.h | 167 |
1 files changed, 90 insertions, 77 deletions
diff --git a/src/main.h b/src/main.h index 825e577d1e..f6bac889be 100644 --- a/src/main.h +++ b/src/main.h @@ -7,10 +7,9 @@ #define BITCOIN_MAIN_H #if defined(HAVE_CONFIG_H) -#include "bitcoin-config.h" +#include "config/bitcoin-config.h" #endif -#include "bignum.h" #include "chainparams.h" #include "coins.h" #include "core.h" @@ -44,10 +43,12 @@ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000; static const unsigned int MAX_STANDARD_TX_SIZE = 100000; /** The maximum allowed number of signature check operations in a block (network rule) */ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; +/** Maxiumum number of signature check operations in an IsStandard() P2SH script */ +static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of orphan transactions kept in memory */ static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100; -/** The maximum number of orphan blocks kept in memory */ -static const unsigned int MAX_ORPHAN_BLOCKS = 750; +/** Default for -maxorphanblocks, maximum number of orphan blocks kept in memory */ +static const unsigned int DEFAULT_MAX_ORPHAN_BLOCKS = 750; /** The maximum size of a blk?????.dat file (since 0.8) */ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ @@ -67,12 +68,6 @@ static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 128; /** Timeout in seconds before considering a block download peer unresponsive. */ static const unsigned int BLOCK_DOWNLOAD_TIMEOUT = 60; -#ifdef USE_UPNP -static const int fHaveUPnP = true; -#else -static const int fHaveUPnP = false; -#endif - /** "reject" message codes **/ static const unsigned char REJECT_MALFORMED = 0x01; static const unsigned char REJECT_INVALID = 0x10; @@ -98,12 +93,12 @@ extern bool fBenchmark; extern int nScriptCheckThreads; extern bool fTxIndex; extern unsigned int nCoinCacheSize; +extern CFeeRate minRelayTxFee; // Minimum disk space required - used in CheckDiskSpace() static const uint64_t nMinDiskSpace = 52428800; -class CCoinsDB; class CBlockTreeDB; struct CDiskBlockPos; class CTxUndo; @@ -114,6 +109,9 @@ struct CNodeStateStats; struct CBlockTemplate; +/** Initialize respend bloom filter **/ +void InitRespendFilter(); + /** Register a wallet to receive updates from core */ void RegisterWallet(CWalletInterface* pwalletIn); /** Unregister a wallet from core */ @@ -121,7 +119,7 @@ void UnregisterWallet(CWalletInterface* pwalletIn); /** Unregister all wallets from core */ void UnregisterAllWallets(); /** Push an updated transaction to all registered wallets */ -void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock = NULL); +void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); /** Register with a network node to receive its signals */ void RegisterNodeSignals(CNodeSignals& nodeSignals); @@ -146,8 +144,6 @@ bool InitBlockIndex(); bool LoadBlockIndex(); /** Unload database information */ void UnloadBlockIndex(); -/** Verify consistency of the block and coin databases */ -bool VerifyDB(int nCheckLevel, int nCheckDepth); /** Print the loaded block tree */ void PrintBlockTree(); /** Process protocol messages received from a given node */ @@ -156,12 +152,6 @@ bool ProcessMessages(CNode* pfrom); bool SendMessages(CNode* pto, bool fSendTrickle); /** Run an instance of the script checking thread */ void ThreadScriptCheck(); -/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ -bool CheckProofOfWork(uint256 hash, unsigned int nBits); -/** Calculate the minimum amount of work a received block needs, without knowing its direct parent */ -unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime); -/** Get the number of active peers */ -int GetNumBlocksOfPeers(); /** Check whether we are doing an initial block download (synchronizing from disk or network) */ bool IsInitialBlockDownload(); /** Format a string that describes several potential problems detected by the core */ @@ -171,7 +161,6 @@ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, b /** Find the best known block, and make it the tip of the block chain */ bool ActivateBestChain(CValidationState &state); int64_t GetBlockValue(int nHeight, int64_t nFees); -unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock); void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev); @@ -200,6 +189,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa struct CNodeStateStats { int nMisbehavior; + int nSyncHeight; }; struct CDiskBlockPos @@ -256,14 +246,7 @@ struct CDiskTxPos : public CDiskBlockPos }; - -enum GetMinFee_mode -{ - GMF_RELAY, - GMF_SEND, -}; - -int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode); +int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); // // Check transaction inputs, and make sure any @@ -298,22 +281,15 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx); unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& mapInputs); -inline bool AllowFree(double dPriority) -{ - // Large (in bytes) low-priority (new, small-coin) transactions - // need a fee. - return dPriority > COIN * 144 / 250; -} - // 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, CCoinsViewCache &view, bool fScriptChecks = true, - unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, + unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS, 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, const uint256 &txhash); +void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight); // Context-independent validity checks bool CheckTransaction(const CTransaction& tx, CValidationState& state); @@ -477,7 +453,7 @@ public: int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } bool IsInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; } int GetBlocksToMaturity() const; - bool AcceptToMemoryPool(bool fLimitFree=true); + bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectInsaneFee=true); }; @@ -603,11 +579,13 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos); // Context-independent validity checks +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); // Store block on disk // if dbp is provided, the file is known to already reside on disk -bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp = NULL); +bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL); +bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); @@ -696,6 +674,9 @@ public: // 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; @@ -731,10 +712,11 @@ public: // (memory only) Sequencial id assigned to distinguish order in which blocks are received. uint32_t nSequenceId; - CBlockIndex() + void SetNull() { phashBlock = NULL; pprev = NULL; + pskip = NULL; nHeight = 0; nFile = 0; nDataPos = 0; @@ -752,19 +734,14 @@ public: nNonce = 0; } + CBlockIndex() + { + SetNull(); + } + CBlockIndex(CBlockHeader& block) { - phashBlock = NULL; - pprev = NULL; - nHeight = 0; - nFile = 0; - nDataPos = 0; - nUndoPos = 0; - nChainWork = 0; - nTx = 0; - nChainTx = 0; - nStatus = 0; - nSequenceId = 0; + SetNull(); nVersion = block.nVersion; hashMerkleRoot = block.hashMerkleRoot; @@ -814,18 +791,19 @@ public: return (int64_t)nTime; } - CBigNum GetBlockWork() const + uint256 GetBlockWork() const { - CBigNum bnTarget; - bnTarget.SetCompact(nBits); - if (bnTarget <= 0) + uint256 bnTarget; + bool fNegative; + bool fOverflow; + bnTarget.SetCompact(nBits, &fNegative, &fOverflow); + if (fNegative || fOverflow || bnTarget == 0) return 0; - return (CBigNum(1)<<256) / (bnTarget+1); - } - - bool CheckIndex() const - { - return CheckProofOfWork(GetBlockHash(), nBits); + // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 + // as it's too large for a uint256. However, as 2**256 is at least as large + // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, + // or ~bnTarget / (nTarget+1) + 1. + return (~bnTarget / (bnTarget + 1)) + 1; } enum { nMedianTimeSpan=11 }; @@ -844,30 +822,57 @@ public: return pbegin[(pend - pbegin)/2]; } - int64_t GetMedianTime() const; - /** * Returns true if there are nRequired or more blocks of minVersion or above - * in the last nToCheck blocks, starting at pstart and going backwards. + * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart + * and going backwards. */ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, - unsigned int nRequired, unsigned int nToCheck); + unsigned int nRequired); std::string ToString() const { return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", pprev, nHeight, - hashMerkleRoot.ToString().c_str(), - GetBlockHash().ToString().c_str()); + hashMerkleRoot.ToString(), + GetBlockHash().ToString()); } void print() const { - LogPrintf("%s\n", ToString().c_str()); + LogPrintf("%s\n", 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 @@ -925,14 +930,14 @@ public: std::string str = "CDiskBlockIndex("; str += CBlockIndex::ToString(); str += strprintf("\n hashBlock=%s, hashPrev=%s)", - GetBlockHash().ToString().c_str(), - hashPrev.ToString().c_str()); + GetBlockHash().ToString(), + hashPrev.ToString()); return str; } void print() const { - LogPrintf("%s\n", ToString().c_str()); + LogPrintf("%s\n", ToString()); } }; @@ -999,6 +1004,14 @@ public: std::string GetRejectReason() const { return strRejectReason; } }; +/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ +class CVerifyDB { +public: + CVerifyDB(); + ~CVerifyDB(); + bool VerifyDB(int nCheckLevel, int nCheckDepth); +}; + /** An in-memory indexed chain of blocks. */ class CChain { private: @@ -1054,14 +1067,14 @@ public: /** 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. */ + CBlockIndex *FindFork(CBlockIndex *pindex) const; }; /** The currently-connected chain of blocks. */ extern CChain chainActive; -/** The currently best known chain of headers (some of which may be invalid). */ -extern CChain chainMostWork; - /** Global variable that points to the active CCoinsView (protected by cs_main) */ extern CCoinsViewCache *pcoinsTip; @@ -1110,7 +1123,7 @@ public: class CWalletInterface { protected: - virtual void SyncTransaction(const uint256 &hash, const CTransaction &tx, const CBlock *pblock) =0; + virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) =0; virtual void EraseFromWallet(const uint256 &hash) =0; virtual void SetBestChain(const CBlockLocator &locator) =0; virtual void UpdatedTransaction(const uint256 &hash) =0; |