diff options
author | Sjors Provoost <sjors@sprovoost.nl> | 2024-06-26 13:42:55 +0200 |
---|---|---|
committer | Sjors Provoost <sjors@sprovoost.nl> | 2024-06-27 08:58:25 +0200 |
commit | a74b0f93efa1d9eaf5abc2f6591c44a632aec6ed (patch) | |
tree | fdba4752f6cec737b715d7a226a41a65dfdc885e /src/node/interfaces.cpp | |
parent | f6dc6db44ddc22ade96a69a02908f14cfb279a37 (diff) |
Have testBlockValidity hold cs_main instead of caller
The goal of interfaces is to eventually run in their own process,
so we can't use EXCLUSIVE_LOCKS_REQUIRED in their declaration.
However TestBlockValidaty will crash (in its call to ConnectBlock)
if the tip changes from under the proposed block.
Have the testBlockValidity implementation hold the lock instead,
and non-fatally check for this condition.
Diffstat (limited to 'src/node/interfaces.cpp')
-rw-r--r-- | src/node/interfaces.cpp | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 5e87bf234a..fa151407fa 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -872,8 +872,15 @@ public: bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) override { - LOCK(::cs_main); - return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, chainman().ActiveChain().Tip(), /*fCheckPOW=*/false, check_merkle_root); + LOCK(cs_main); + CBlockIndex* tip{chainman().ActiveChain().Tip()}; + // Fail if the tip updated before the lock was taken + if (block.hashPrevBlock != tip->GetBlockHash()) { + state.Error("Block does not connect to current chain tip."); + return false; + } + + return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, tip, /*fCheckPOW=*/false, check_merkle_root); } std::unique_ptr<CBlockTemplate> createNewBlock(const CScript& script_pub_key, bool use_mempool) override |