aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/mining.h2
-rw-r--r--src/node/interfaces.cpp11
-rw-r--r--src/rpc/mining.cpp4
3 files changed, 10 insertions, 7 deletions
diff --git a/src/interfaces/mining.h b/src/interfaces/mining.h
index bc98448833..7d71a01450 100644
--- a/src/interfaces/mining.h
+++ b/src/interfaces/mining.h
@@ -67,7 +67,7 @@ public:
* @param[in] block the block to validate
* @param[in] check_merkle_root call CheckMerkleRoot()
* @param[out] state details of why a block failed to validate
- * @returns false if any of the checks fail
+ * @returns false if it does not build on the current tip, or any of the checks fail
*/
virtual bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) = 0;
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
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index d9fd82d708..7e420dcd9b 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -371,8 +371,6 @@ static RPCHelpMan generateblock()
ChainstateManager& chainman = EnsureChainman(node);
{
- LOCK(cs_main);
-
std::unique_ptr<CBlockTemplate> blocktemplate{miner.createNewBlock(coinbase_script, /*use_mempool=*/false)};
if (!blocktemplate) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
@@ -387,8 +385,6 @@ static RPCHelpMan generateblock()
RegenerateCommitments(block, chainman);
{
- LOCK(cs_main);
-
BlockValidationState state;
if (!miner.testBlockValidity(block, /*check_merkle_root=*/false, state)) {
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("testBlockValidity failed: %s", state.ToString()));