Skip to content

Commit 2f6dca4

Browse files
committed
Merge bitcoin#30335: Mining interface followups, reduce cs_main locking, test rpc bug fix
a74b0f9 Have testBlockValidity hold cs_main instead of caller (Sjors Provoost) f6dc6db refactor: use CHECK_NONFATAL to avoid single-use symbol (Sjors Provoost) 5fb2b70 Drop unneeded lock from createNewBlock (Sjors Provoost) 75ce763 refactor: testBlockValidity make out argument last (Sjors Provoost) 83a9bef Add missing include for mining interface (Sjors Provoost) Pull request description: Followups from bitcoin#30200 Fixes: - `std::unique_ptr` needs `#include <memory>` (noticed while working on bitcoin#30332, which has fewer includes than its parent PR that I originally tested with) - Drop lock from createNewBlock that was spuriously added - Have testBlockValidity hold cs_main instead of caller (also fixes a race condition in test-only code) Refactor: - Use CHECK_NONFATAL to avoid single-use symbol (refactor) - move output argument `state` to the end of `testBlockValidity`, see bitcoin#30200 (comment) ACKs for top commit: AngusP: Code Review ACK a74b0f9 itornaza: Tested ACK a74b0f9 ryanofsky: Code review ACK a74b0f9. Just new error string is added since last review, and a commit message was updated Tree-SHA512: 805e133bb59303fcee107d6f02b3e2761396c290efb731a85e6a29ae56b4b1b9cd28ada9629e979704dcfd98cf35034e7e6b618e29923049eb1eca2f65630e41
2 parents d38dbaa + a74b0f9 commit 2f6dca4

File tree

3 files changed

+18
-16
lines changed

3 files changed

+18
-16
lines changed

Diff for: src/interfaces/mining.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef BITCOIN_INTERFACES_MINING_H
66
#define BITCOIN_INTERFACES_MINING_H
77

8+
#include <memory>
89
#include <optional>
910
#include <uint256.h>
1011

@@ -44,6 +45,7 @@ class Mining
4445
* @returns a block template
4546
*/
4647
virtual std::unique_ptr<node::CBlockTemplate> createNewBlock(const CScript& script_pub_key, bool use_mempool = true) = 0;
48+
4749
/**
4850
* Processes new block. A valid new block is automatically relayed to peers.
4951
*
@@ -62,12 +64,12 @@ class Mining
6264
* Only works on top of our current best block.
6365
* Does not check proof-of-work.
6466
*
65-
* @param[out] state details of why a block failed to validate
6667
* @param[in] block the block to validate
6768
* @param[in] check_merkle_root call CheckMerkleRoot()
68-
* @returns false if any of the checks fail
69+
* @param[out] state details of why a block failed to validate
70+
* @returns false if it does not build on the current tip, or any of the checks fail
6971
*/
70-
virtual bool testBlockValidity(BlockValidationState& state, const CBlock& block, bool check_merkle_root = true) = 0;
72+
virtual bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) = 0;
7173

7274
//! Get internal node context. Useful for RPC and testing,
7375
//! but not accessible across processes.

Diff for: src/node/interfaces.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -870,18 +870,24 @@ class MinerImpl : public Mining
870870
return context()->mempool->GetTransactionsUpdated();
871871
}
872872

873-
bool testBlockValidity(BlockValidationState& state, const CBlock& block, bool check_merkle_root) override
873+
bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) override
874874
{
875-
LOCK(::cs_main);
876-
return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, chainman().ActiveChain().Tip(), /*fCheckPOW=*/false, check_merkle_root);
875+
LOCK(cs_main);
876+
CBlockIndex* tip{chainman().ActiveChain().Tip()};
877+
// Fail if the tip updated before the lock was taken
878+
if (block.hashPrevBlock != tip->GetBlockHash()) {
879+
state.Error("Block does not connect to current chain tip.");
880+
return false;
881+
}
882+
883+
return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, tip, /*fCheckPOW=*/false, check_merkle_root);
877884
}
878885

879886
std::unique_ptr<CBlockTemplate> createNewBlock(const CScript& script_pub_key, bool use_mempool) override
880887
{
881888
BlockAssembler::Options options;
882889
ApplyArgsManOptions(gArgs, options);
883890

884-
LOCK(::cs_main);
885891
return BlockAssembler{chainman().ActiveChainstate(), use_mempool ? context()->mempool.get() : nullptr, options}.CreateNewBlock(script_pub_key);
886892
}
887893

Diff for: src/rpc/mining.cpp

+3-9
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,6 @@ static RPCHelpMan generateblock()
371371

372372
ChainstateManager& chainman = EnsureChainman(node);
373373
{
374-
LOCK(cs_main);
375-
376374
std::unique_ptr<CBlockTemplate> blocktemplate{miner.createNewBlock(coinbase_script, /*use_mempool=*/false)};
377375
if (!blocktemplate) {
378376
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
@@ -387,10 +385,8 @@ static RPCHelpMan generateblock()
387385
RegenerateCommitments(block, chainman);
388386

389387
{
390-
LOCK(cs_main);
391-
392388
BlockValidationState state;
393-
if (!miner.testBlockValidity(state, block, /*check_merkle_root=*/false)) {
389+
if (!miner.testBlockValidity(block, /*check_merkle_root=*/false, state)) {
394390
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("testBlockValidity failed: %s", state.ToString()));
395391
}
396392
}
@@ -667,9 +663,7 @@ static RPCHelpMan getblocktemplate()
667663
ChainstateManager& chainman = EnsureChainman(node);
668664
Mining& miner = EnsureMining(node);
669665
LOCK(cs_main);
670-
std::optional<uint256> maybe_tip{miner.getTipHash()};
671-
CHECK_NONFATAL(maybe_tip);
672-
uint256 tip{maybe_tip.value()};
666+
uint256 tip{CHECK_NONFATAL(miner.getTipHash()).value()};
673667

674668
std::string strMode = "template";
675669
UniValue lpval = NullUniValue;
@@ -713,7 +707,7 @@ static RPCHelpMan getblocktemplate()
713707
return "inconclusive-not-best-prevblk";
714708
}
715709
BlockValidationState state;
716-
miner.testBlockValidity(state, block);
710+
miner.testBlockValidity(block, /*check_merkle_root=*/true, state);
717711
return BIP22ValidationResult(state);
718712
}
719713

0 commit comments

Comments
 (0)