Pulled CheckBlock out of CBlock.

This commit is contained in:
Eric Lombrozo 2013-06-23 19:14:11 -07:00
parent 1959997afb
commit 38991ffa8a
3 changed files with 21 additions and 21 deletions

View file

@ -1720,7 +1720,7 @@ void ThreadScriptCheck() {
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
{ {
// Check it again in case a previous version let a bad block in // Check it again in case a previous version let a bad block in
if (!block.CheckBlock(state, !fJustCheck, !fJustCheck)) if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
return false; return false;
// verify that the view's current state corresponds to the previous block // verify that the view's current state corresponds to the previous block
@ -2188,51 +2188,51 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
} }
bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerkleRoot) const bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
{ {
// These are checks that are independent of context // These are checks that are independent of context
// that can be verified before saving an orphan block. // that can be verified before saving an orphan block.
// Size limits // Size limits
if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
return state.DoS(100, error("CheckBlock() : size limits failed")); return state.DoS(100, error("CheckBlock() : size limits failed"));
// Check proof of work matches claimed amount // Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(GetHash(), nBits)) if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits))
return state.DoS(50, error("CheckBlock() : proof of work failed")); return state.DoS(50, error("CheckBlock() : proof of work failed"));
// Check timestamp // Check timestamp
if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
return state.Invalid(error("CheckBlock() : block timestamp too far in the future")); return state.Invalid(error("CheckBlock() : block timestamp too far in the future"));
// First transaction must be coinbase, the rest must not be // First transaction must be coinbase, the rest must not be
if (vtx.empty() || !vtx[0].IsCoinBase()) if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
return state.DoS(100, error("CheckBlock() : first tx is not coinbase")); return state.DoS(100, error("CheckBlock() : first tx is not coinbase"));
for (unsigned int i = 1; i < vtx.size(); i++) for (unsigned int i = 1; i < block.vtx.size(); i++)
if (vtx[i].IsCoinBase()) if (block.vtx[i].IsCoinBase())
return state.DoS(100, error("CheckBlock() : more than one coinbase")); return state.DoS(100, error("CheckBlock() : more than one coinbase"));
// Check transactions // Check transactions
BOOST_FOREACH(const CTransaction& tx, vtx) BOOST_FOREACH(const CTransaction& tx, block.vtx)
if (!CheckTransaction(tx, state)) if (!CheckTransaction(tx, state))
return error("CheckBlock() : CheckTransaction failed"); return error("CheckBlock() : CheckTransaction failed");
// Build the merkle tree already. We need it anyway later, and it makes the // Build the merkle tree already. We need it anyway later, and it makes the
// block cache the transaction hashes, which means they don't need to be // block cache the transaction hashes, which means they don't need to be
// recalculated many times during this block's validation. // recalculated many times during this block's validation.
BuildMerkleTree(); block.BuildMerkleTree();
// Check for duplicate txids. This is caught by ConnectInputs(), // Check for duplicate txids. This is caught by ConnectInputs(),
// but catching it earlier avoids a potential DoS attack: // but catching it earlier avoids a potential DoS attack:
set<uint256> uniqueTx; set<uint256> uniqueTx;
for (unsigned int i=0; i<vtx.size(); i++) { for (unsigned int i = 0; i < block.vtx.size(); i++) {
uniqueTx.insert(GetTxHash(i)); uniqueTx.insert(block.GetTxHash(i));
} }
if (uniqueTx.size() != vtx.size()) if (uniqueTx.size() != block.vtx.size())
return state.DoS(100, error("CheckBlock() : duplicate transaction")); return state.DoS(100, error("CheckBlock() : duplicate transaction"));
unsigned int nSigOps = 0; unsigned int nSigOps = 0;
BOOST_FOREACH(const CTransaction& tx, vtx) BOOST_FOREACH(const CTransaction& tx, block.vtx)
{ {
nSigOps += GetLegacySigOpCount(tx); nSigOps += GetLegacySigOpCount(tx);
} }
@ -2240,7 +2240,7 @@ bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerk
return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount")); return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"));
// Check merkle root // Check merkle root
if (fCheckMerkleRoot && hashMerkleRoot != BuildMerkleTree()) if (fCheckMerkleRoot && block.hashMerkleRoot != block.BuildMerkleTree())
return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch")); return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));
return true; return true;
@ -2366,7 +2366,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString().c_str())); return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString().c_str()));
// Preliminary checks // Preliminary checks
if (!pblock->CheckBlock(state)) if (!CheckBlock(*pblock, state))
return error("ProcessBlock() : CheckBlock FAILED"); return error("ProcessBlock() : CheckBlock FAILED");
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
@ -2763,7 +2763,7 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth)
if (!ReadBlockFromDisk(block, pindex)) if (!ReadBlockFromDisk(block, pindex))
return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
// check level 1: verify block validity // check level 1: verify block validity
if (nCheckLevel >= 1 && !block.CheckBlock(state)) if (nCheckLevel >= 1 && !CheckBlock(block, state))
return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
// check level 2: verify undo validity // check level 2: verify undo validity
if (nCheckLevel >= 2 && pindex) { if (nCheckLevel >= 2 && pindex) {

View file

@ -703,9 +703,6 @@ public:
} }
// Context-independent validity checks
bool CheckBlock(CValidationState &state, bool fCheckPOW=true, bool fCheckMerkleRoot=true) const;
// Store block on disk // Store block on disk
// if dbp is provided, the file is known to already reside on disk // if dbp is provided, the file is known to already reside on disk
bool AcceptBlock(CValidationState &state, CDiskBlockPos *dbp = NULL); bool AcceptBlock(CValidationState &state, CDiskBlockPos *dbp = NULL);
@ -732,6 +729,9 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
// Add this block to the block index, and if necessary, switch the active block chain to this // Add this block to the block index, and if necessary, switch the active block chain to this
bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos); bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos);
// Context-independent validity checks
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
class CBlockFileInfo class CBlockFileInfo

View file

@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(May15)
// After May 15'th, big blocks are OK: // After May 15'th, big blocks are OK:
forkingBlock.nTime = tMay15; // Invalidates PoW forkingBlock.nTime = tMay15; // Invalidates PoW
BOOST_CHECK(forkingBlock.CheckBlock(state, false, false)); BOOST_CHECK(CheckBlock(forkingBlock, state, false, false));
} }
SetMockTime(0); SetMockTime(0);