Skip to content

Commit fa62c8b

Browse files
author
MarcoFalke
committed
rpc: Extend scope of validation mutex in generateblock
The mutex (required by TestBlockValidity) must be held after creating the block, until TestBlockValidity is called. Otherwise, it is possible that the chain advances in the meantime and leads to a crash in TestBlockValidity: Assertion failed: pindexPrev && pindexPrev == chainstate.m_chain.Tip() (validation.cpp: TestBlockValidity: 4338) The diff can be reviewed with the git options --ignore-all-space --function-context
1 parent fc7b214 commit fa62c8b

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

src/rpc/mining.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) 2010 Satoshi Nakamoto
2-
// Copyright (c) 2009-2022 The Bitcoin Core developers
2+
// Copyright (c) 2009-present The Bitcoin Core developers
33
// Distributed under the MIT software license, see the accompanying
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

@@ -371,22 +371,22 @@ static RPCHelpMan generateblock()
371371

372372
ChainstateManager& chainman = EnsureChainman(node);
373373
{
374-
std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock({.use_mempool = false, .coinbase_output_script = coinbase_output_script})};
375-
CHECK_NONFATAL(block_template);
374+
LOCK(chainman.GetMutex());
375+
{
376+
std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock({.use_mempool = false, .coinbase_output_script = coinbase_output_script})};
377+
CHECK_NONFATAL(block_template);
376378

377-
block = block_template->getBlock();
378-
}
379+
block = block_template->getBlock();
380+
}
379381

380-
CHECK_NONFATAL(block.vtx.size() == 1);
382+
CHECK_NONFATAL(block.vtx.size() == 1);
381383

382-
// Add transactions
383-
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
384-
RegenerateCommitments(block, chainman);
384+
// Add transactions
385+
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
386+
RegenerateCommitments(block, chainman);
385387

386-
{
387-
LOCK(::cs_main);
388388
BlockValidationState state;
389-
if (!TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), /*fCheckPOW=*/false, /*fCheckMerkleRoot=*/false)) {
389+
if (!TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), /*fCheckPOW=*/false, /*fCheckMerkleRoot=*/false)) {
390390
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));
391391
}
392392
}

0 commit comments

Comments
 (0)