Skip to content

Commit df08a62

Browse files
committed
TestBlockValidity function for CBlock proposals (used by CreateNewBlock)
1 parent 4ea1be7 commit df08a62

File tree

3 files changed

+31
-17
lines changed

3 files changed

+31
-17
lines changed

src/main.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ static int64_t nTimeIndex = 0;
15931593
static int64_t nTimeCallbacks = 0;
15941594
static int64_t nTimeTotal = 0;
15951595

1596-
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
1596+
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
15971597
{
15981598
AssertLockHeld(cs_main);
15991599
// 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
25732573
return true;
25742574
}
25752575

2576+
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
2577+
{
2578+
AssertLockHeld(cs_main);
2579+
assert(pindexPrev == chainActive.Tip());
2580+
2581+
CCoinsViewCache viewNew(pcoinsTip);
2582+
CBlockIndex indexDummy(block);
2583+
indexDummy.pprev = pindexPrev;
2584+
indexDummy.nHeight = pindexPrev->nHeight + 1;
2585+
2586+
// NOTE: CheckBlockHeader is called by CheckBlock
2587+
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
2588+
return false;
2589+
if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot))
2590+
return false;
2591+
if (!ContextualCheckBlock(block, state, pindexPrev))
2592+
return false;
2593+
if (!ConnectBlock(block, state, &indexDummy, viewNew, true))
2594+
return false;
2595+
assert(state.IsValid());
2596+
2597+
return true;
2598+
}
2599+
25762600

25772601

25782602

src/main.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex);
457457
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL);
458458

459459
// Apply the effects of this block (with given index) on the UTXO set represented by coins
460-
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);
460+
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);
461461

462462
// Context-independent validity checks
463463
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true);
@@ -467,6 +467,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = t
467467
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev);
468468
bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev);
469469

470+
// Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held)
471+
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
472+
470473
// Store block on disk
471474
// if dbp is provided, the file is known to already reside on disk
472475
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL);

src/miner.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -321,22 +321,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
321321
pblock->nNonce = 0;
322322
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
323323

324-
CBlockIndex indexDummy(*pblock);
325-
indexDummy.pprev = pindexPrev;
326-
indexDummy.nHeight = pindexPrev->nHeight + 1;
327-
CCoinsViewCache viewNew(pcoinsTip);
328324
CValidationState state;
329-
// NOTE: CheckBlockHeader is called by CheckBlock
330-
if (!ContextualCheckBlockHeader(*pblock, state, pindexPrev))
331-
throw std::runtime_error("CreateNewBlock() : ContextualCheckBlockHeader failed");
332-
if (!CheckBlock(*pblock, state, false, false))
333-
throw std::runtime_error("CreateNewBlock() : CheckBlock failed");
334-
if (!ContextualCheckBlock(*pblock, state, pindexPrev))
335-
throw std::runtime_error("CreateNewBlock() : ContextualCheckBlock failed");
336-
if (!ConnectBlock(*pblock, state, &indexDummy, viewNew, true))
337-
throw std::runtime_error("CreateNewBlock() : ConnectBlock failed");
338-
if (!state.IsValid())
339-
throw std::runtime_error("CreateNewBlock() : State is not valid");
325+
if (!TestBlockValidity(state, *pblock, pindexPrev, false, false))
326+
throw std::runtime_error("CreateNewBlock() : TestBlockValidity failed");
340327
}
341328

342329
return pblocktemplate.release();

0 commit comments

Comments
 (0)