mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-13 07:28:59 +01:00
CValidationState framework
This commit is contained in:
committed by
Pieter Wuille
parent
2835080e16
commit
ef3988ca36
84
src/main.h
84
src/main.h
@@ -112,9 +112,11 @@ class CTxUndo;
|
||||
class CCoinsView;
|
||||
class CCoinsViewCache;
|
||||
class CScriptCheck;
|
||||
class CValidationState;
|
||||
|
||||
struct CBlockTemplate;
|
||||
|
||||
|
||||
/** Register a wallet to receive updates from core */
|
||||
void RegisterWallet(CWallet* pwalletIn);
|
||||
/** Unregister a wallet from core */
|
||||
@@ -122,7 +124,7 @@ void UnregisterWallet(CWallet* pwalletIn);
|
||||
/** Push an updated transaction to all registered wallets */
|
||||
void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false);
|
||||
/** Process an incoming block */
|
||||
bool ProcessBlock(CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
|
||||
bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
|
||||
/** Check whether enough disk space is available for an incoming block */
|
||||
bool CheckDiskSpace(uint64 nAdditionalBytes = 0);
|
||||
/** Open a block file (blk?????.dat) */
|
||||
@@ -172,9 +174,9 @@ std::string GetWarnings(std::string strFor);
|
||||
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
|
||||
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false);
|
||||
/** Connect/disconnect blocks until pindexNew is the new tip of the active block chain */
|
||||
bool SetBestChain(CBlockIndex* pindexNew);
|
||||
bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew);
|
||||
/** Find the best known block, and make it the tip of the block chain */
|
||||
bool ConnectBestBlock();
|
||||
bool ConnectBestBlock(CValidationState &state);
|
||||
/** Create a new block index entry for a given block hash */
|
||||
CBlockIndex * InsertBlockIndex(uint256 hash);
|
||||
/** Verify a signature */
|
||||
@@ -454,7 +456,6 @@ public:
|
||||
|
||||
|
||||
|
||||
|
||||
enum GetMinFee_mode
|
||||
{
|
||||
GMF_BLOCK,
|
||||
@@ -474,10 +475,6 @@ public:
|
||||
std::vector<CTxOut> vout;
|
||||
unsigned int nLockTime;
|
||||
|
||||
// Denial-of-service detection:
|
||||
mutable int nDoS;
|
||||
bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
|
||||
|
||||
CTransaction()
|
||||
{
|
||||
SetNull();
|
||||
@@ -498,7 +495,6 @@ public:
|
||||
vin.clear();
|
||||
vout.clear();
|
||||
nLockTime = 0;
|
||||
nDoS = 0; // Denial-of-service prevention
|
||||
}
|
||||
|
||||
bool IsNull() const
|
||||
@@ -654,27 +650,24 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// Do all possible client-mode checks
|
||||
bool ClientCheckInputs() const;
|
||||
|
||||
// Check whether all prevouts of this transaction are present in the UTXO set represented by view
|
||||
bool HaveInputs(CCoinsViewCache &view) const;
|
||||
|
||||
// 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(CCoinsViewCache &view, bool fScriptChecks = true,
|
||||
bool CheckInputs(CValidationState &state, CCoinsViewCache &view, bool fScriptChecks = true,
|
||||
unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC,
|
||||
std::vector<CScriptCheck> *pvChecks = NULL) const;
|
||||
|
||||
// Apply the effects of this transaction on the UTXO set represented by view
|
||||
bool UpdateCoins(CCoinsViewCache &view, CTxUndo &txundo, int nHeight, const uint256 &txhash) const;
|
||||
bool UpdateCoins(CValidationState &state, CCoinsViewCache &view, CTxUndo &txundo, int nHeight, const uint256 &txhash) const;
|
||||
|
||||
// Context-independent validity checks
|
||||
bool CheckTransaction() const;
|
||||
bool CheckTransaction(CValidationState &state) const;
|
||||
|
||||
// Try to accept this transaction into the memory pool
|
||||
bool AcceptToMemoryPool(bool fCheckInputs=true, bool fLimitFree = true, bool* pfMissingInputs=NULL);
|
||||
bool AcceptToMemoryPool(CValidationState &state, bool fCheckInputs=true, bool fLimitFree = true, bool* pfMissingInputs=NULL);
|
||||
|
||||
protected:
|
||||
static const CTxOut &GetOutputFor(const CTxIn& input, CCoinsViewCache& mapInputs);
|
||||
@@ -1320,10 +1313,6 @@ public:
|
||||
// memory only
|
||||
mutable std::vector<uint256> vMerkleTree;
|
||||
|
||||
// Denial-of-service detection:
|
||||
mutable int nDoS;
|
||||
bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
|
||||
|
||||
CBlock()
|
||||
{
|
||||
SetNull();
|
||||
@@ -1346,7 +1335,6 @@ public:
|
||||
CBlockHeader::SetNull();
|
||||
vtx.clear();
|
||||
vMerkleTree.clear();
|
||||
nDoS = 0;
|
||||
}
|
||||
|
||||
CBlockHeader GetBlockHeader() const
|
||||
@@ -1494,23 +1482,23 @@ public:
|
||||
* In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean
|
||||
* will be true if no problems were found. Otherwise, the return value will be false in case
|
||||
* of problems. Note that in any case, coins may be modified. */
|
||||
bool DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool *pfClean = NULL);
|
||||
bool DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &coins, bool *pfClean = NULL);
|
||||
|
||||
// Apply the effects of this block (with given index) on the UTXO set represented by coins
|
||||
bool ConnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool fJustCheck=false);
|
||||
bool ConnectBlock(CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &coins, bool fJustCheck=false);
|
||||
|
||||
// Read a block from disk
|
||||
bool ReadFromDisk(const CBlockIndex* pindex);
|
||||
|
||||
// Add this block to the block index, and if necessary, switch the active block chain to this
|
||||
bool AddToBlockIndex(const CDiskBlockPos &pos);
|
||||
bool AddToBlockIndex(CValidationState &state, const CDiskBlockPos &pos);
|
||||
|
||||
// Context-independent validity checks
|
||||
bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true) const;
|
||||
bool CheckBlock(CValidationState &state, bool fCheckPOW=true, bool fCheckMerkleRoot=true) const;
|
||||
|
||||
// Store block on disk
|
||||
// if dbp is provided, the file is known to already reside on disk
|
||||
bool AcceptBlock(CDiskBlockPos *dbp = NULL);
|
||||
bool AcceptBlock(CValidationState &state, CDiskBlockPos *dbp = NULL);
|
||||
};
|
||||
|
||||
|
||||
@@ -1877,6 +1865,48 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** Capture information about block/transaction validation */
|
||||
class CValidationState {
|
||||
private:
|
||||
enum mode_state {
|
||||
MODE_VALID, // everything ok
|
||||
MODE_INVALID, // network rule violation (DoS value may be set)
|
||||
MODE_ERROR, // run-time error
|
||||
} mode;
|
||||
int nDoS;
|
||||
public:
|
||||
CValidationState() : mode(MODE_VALID), nDoS(0) {}
|
||||
bool DoS(int level, bool ret = false) {
|
||||
if (mode == MODE_ERROR)
|
||||
return ret;
|
||||
nDoS += level;
|
||||
mode = MODE_INVALID;
|
||||
return ret;
|
||||
}
|
||||
bool Invalid(bool ret = false) {
|
||||
return DoS(0, ret);
|
||||
}
|
||||
bool Error(bool ret = false) {
|
||||
mode = MODE_ERROR;
|
||||
return ret;
|
||||
}
|
||||
bool IsValid() {
|
||||
return mode == MODE_VALID;
|
||||
}
|
||||
bool IsInvalid() {
|
||||
return mode == MODE_INVALID;
|
||||
}
|
||||
bool IsError() {
|
||||
return mode == MODE_ERROR;
|
||||
}
|
||||
bool IsInvalid(int &nDoSOut) {
|
||||
if (IsInvalid()) {
|
||||
nDoSOut = nDoS;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -2025,7 +2055,7 @@ public:
|
||||
std::map<uint256, CTransaction> mapTx;
|
||||
std::map<COutPoint, CInPoint> mapNextTx;
|
||||
|
||||
bool accept(CTransaction &tx, bool fCheckInputs, bool fLimitFree, bool* pfMissingInputs);
|
||||
bool accept(CValidationState &state, CTransaction &tx, bool fCheckInputs, bool fLimitFree, bool* pfMissingInputs);
|
||||
bool addUnchecked(const uint256& hash, CTransaction &tx);
|
||||
bool remove(const CTransaction &tx, bool fRecursive = false);
|
||||
bool removeConflicts(const CTransaction &tx);
|
||||
|
||||
Reference in New Issue
Block a user