Skip to content

Commit 621c634

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 Github-Pull: 31563 Rebased-From: fa62c8b
1 parent 6db7256 commit 621c634

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

src/rpc/mining.cpp

Lines changed: 12 additions & 11 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

@@ -370,20 +370,21 @@ static RPCHelpMan generateblock()
370370

371371
ChainstateManager& chainman = EnsureChainman(node);
372372
{
373-
std::unique_ptr<CBlockTemplate> blocktemplate{miner.createNewBlock(coinbase_script, {.use_mempool = false})};
374-
if (!blocktemplate) {
375-
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
373+
LOCK(chainman.GetMutex());
374+
{
375+
std::unique_ptr<CBlockTemplate> blocktemplate{miner.createNewBlock(coinbase_script, {.use_mempool = false})};
376+
if (!blocktemplate) {
377+
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
378+
}
379+
block = blocktemplate->block;
376380
}
377-
block = blocktemplate->block;
378-
}
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-
{
387388
BlockValidationState state;
388389
if (!miner.testBlockValidity(block, /*check_merkle_root=*/false, state)) {
389390
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("testBlockValidity failed: %s", state.ToString()));

0 commit comments

Comments
 (0)