@@ -1593,7 +1593,7 @@ static int64_t nTimeIndex = 0; | |||
static int64_t nTimeCallbacks = 0; | |||
static int64_t nTimeTotal = 0; | |||
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) | |||
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) | |||
{ | |||
AssertLockHeld(cs_main); | |||
// Check it again in case a previous version let a bad block in | |||
@@ -2573,6 +2573,30 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis | |||
return true; | |||
} | |||
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) | |||
{ | |||
AssertLockHeld(cs_main); | |||
assert(pindexPrev == chainActive.Tip()); | |||
CCoinsViewCache viewNew(pcoinsTip); | |||
CBlockIndex indexDummy(block); | |||
indexDummy.pprev = pindexPrev; | |||
indexDummy.nHeight = pindexPrev->nHeight + 1; | |||
// NOTE: CheckBlockHeader is called by CheckBlock | |||
if (!ContextualCheckBlockHeader(block, state, pindexPrev)) | |||
return false; | |||
if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot)) | |||
return false; | |||
if (!ContextualCheckBlock(block, state, pindexPrev)) | |||
return false; | |||
if (!ConnectBlock(block, state, &indexDummy, viewNew, true)) | |||
return false; | |||
assert(state.IsValid()); | |||
return true; | |||
} | |||
@@ -457,7 +457,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); | |||
bool DisconnectBlock(CBlock& block, 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(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); | |||
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); | |||
// Context-independent validity checks | |||
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); | |||
@@ -467,6 +467,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = t | |||
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); | |||
bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); | |||
// Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) | |||
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, 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, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL); |
@@ -321,22 +321,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) | |||
pblock->nNonce = 0; | |||
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); | |||
CBlockIndex indexDummy(*pblock); | |||
indexDummy.pprev = pindexPrev; | |||
indexDummy.nHeight = pindexPrev->nHeight + 1; | |||
CCoinsViewCache viewNew(pcoinsTip); | |||
CValidationState state; | |||
// NOTE: CheckBlockHeader is called by CheckBlock | |||
if (!ContextualCheckBlockHeader(*pblock, state, pindexPrev)) | |||
throw std::runtime_error("CreateNewBlock() : ContextualCheckBlockHeader failed"); | |||
if (!CheckBlock(*pblock, state, false, false)) | |||
throw std::runtime_error("CreateNewBlock() : CheckBlock failed"); | |||
if (!ContextualCheckBlock(*pblock, state, pindexPrev)) | |||
throw std::runtime_error("CreateNewBlock() : ContextualCheckBlock failed"); | |||
if (!ConnectBlock(*pblock, state, &indexDummy, viewNew, true)) | |||
throw std::runtime_error("CreateNewBlock() : ConnectBlock failed"); | |||
if (!state.IsValid()) | |||
throw std::runtime_error("CreateNewBlock() : State is not valid"); | |||
if (!TestBlockValidity(state, *pblock, pindexPrev, false, false)) | |||
throw std::runtime_error("CreateNewBlock() : TestBlockValidity failed"); | |||
} | |||
return pblocktemplate.release(); |