aboutsummaryrefslogtreecommitdiff
path: root/src/main.h
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2013-01-27 00:14:11 +0100
committerPieter Wuille <pieterw@google.com>2013-01-30 03:56:44 +0100
commitef3988ca369900206b0cfc32cc1958aee0e43710 (patch)
tree9cd1ecf802bd159238ece0954200b98a45d01bf3 /src/main.h
parent2835080e164527ecc2db31e68d86ab8a8337c62b (diff)
downloadbitcoin-ef3988ca369900206b0cfc32cc1958aee0e43710.tar.xz
CValidationState framework
Diffstat (limited to 'src/main.h')
-rw-r--r--src/main.h84
1 files changed, 57 insertions, 27 deletions
diff --git a/src/main.h b/src/main.h
index 9dbcac0b5a..9c2029c9b7 100644
--- a/src/main.h
+++ b/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);