Skip to content

Commit d8a3496

Browse files
committed
rpc: call TestBlockValidity via miner interface
1 parent 8ecb681 commit d8a3496

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

src/interfaces/mining.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ namespace node {
99
struct NodeContext;
1010
} // namespace node
1111

12+
class BlockValidationState;
13+
class CBlock;
14+
1215
namespace interfaces {
1316

1417
//! Interface giving clients (RPC, Stratum v2 Template Provider in the future)
@@ -22,6 +25,18 @@ class Mining
2225
//! If this chain is exclusively used for testing
2326
virtual bool isTestChain() = 0;
2427

28+
/**
29+
* Check a block is completely valid from start to finish.
30+
* Only works on top of our current best block.
31+
* Does not check proof-of-work.
32+
*
33+
* @param[out] state details of why a block failed to validate
34+
* @param[in] block the block to validate
35+
* @param[in] check_merkle_root call CheckMerkleRoot()
36+
* @returns false if any of the checks fail
37+
*/
38+
virtual bool testBlockValidity(BlockValidationState& state, const CBlock& block, bool check_merkle_root = true) = 0;
39+
2540
//! Get internal node context. Useful for RPC and testing,
2641
//! but not accessible across processes.
2742
virtual node::NodeContext* context() { return nullptr; }

src/node/interfaces.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <chain.h>
99
#include <chainparams.h>
1010
#include <common/args.h>
11+
#include <consensus/validation.h>
1112
#include <deploymentstatus.h>
1213
#include <external_signer.h>
1314
#include <index/blockfilterindex.h>
@@ -844,6 +845,12 @@ class MinerImpl : public Mining
844845
return chainman().GetParams().IsTestChain();
845846
}
846847

848+
bool testBlockValidity(BlockValidationState& state, const CBlock& block, bool check_merkle_root) override
849+
{
850+
LOCK(::cs_main);
851+
return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, chainman().ActiveChain().Tip(), /*fCheckPOW=*/false, check_merkle_root);
852+
}
853+
847854
NodeContext* context() override { return &m_node; }
848855
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
849856
NodeContext& m_node;

src/rpc/mining.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ static RPCHelpMan generateblock()
339339
}
340340

341341
NodeContext& node = EnsureAnyNodeContext(request.context);
342+
Mining& miner = EnsureMining(node);
342343
const CTxMemPool& mempool = EnsureMemPool(node);
343344

344345
std::vector<CTransactionRef> txs;
@@ -389,8 +390,8 @@ static RPCHelpMan generateblock()
389390
LOCK(cs_main);
390391

391392
BlockValidationState state;
392-
if (!TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), false, false)) {
393-
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));
393+
if (!miner.testBlockValidity(state, block, /*check_merkle_root=*/false)) {
394+
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("testBlockValidity failed: %s", state.ToString()));
394395
}
395396
}
396397

@@ -664,6 +665,7 @@ static RPCHelpMan getblocktemplate()
664665
{
665666
NodeContext& node = EnsureAnyNodeContext(request.context);
666667
ChainstateManager& chainman = EnsureChainman(node);
668+
Mining& miner = EnsureMining(node);
667669
LOCK(cs_main);
668670

669671
std::string strMode = "template";
@@ -706,11 +708,12 @@ static RPCHelpMan getblocktemplate()
706708
}
707709

708710
CBlockIndex* const pindexPrev = active_chain.Tip();
709-
// TestBlockValidity only supports blocks built on the current Tip
710-
if (block.hashPrevBlock != pindexPrev->GetBlockHash())
711+
// testBlockValidity only supports blocks built on the current Tip
712+
if (block.hashPrevBlock != pindexPrev->GetBlockHash()) {
711713
return "inconclusive-not-best-prevblk";
714+
}
712715
BlockValidationState state;
713-
TestBlockValidity(state, chainman.GetParams(), active_chainstate, block, pindexPrev, false, true);
716+
miner.testBlockValidity(state, block);
714717
return BIP22ValidationResult(state);
715718
}
716719

@@ -726,7 +729,6 @@ static RPCHelpMan getblocktemplate()
726729
if (strMode != "template")
727730
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
728731

729-
Mining& miner = EnsureMining(node);
730732
if (!miner.isTestChain()) {
731733
const CConnman& connman = EnsureConnman(node);
732734
if (connman.GetNodeCount(ConnectionDirection::Both) == 0) {

test/functional/rpc_generate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def test_generateblock(self):
8787
txid1 = miniwallet.send_self_transfer(from_node=node)['txid']
8888
utxo1 = miniwallet.get_utxo(txid=txid1)
8989
rawtx2 = miniwallet.create_self_transfer(utxo_to_spend=utxo1)['hex']
90-
assert_raises_rpc_error(-25, 'TestBlockValidity failed: bad-txns-inputs-missingorspent', self.generateblock, node, address, [rawtx2, txid1])
90+
assert_raises_rpc_error(-25, 'testBlockValidity failed: bad-txns-inputs-missingorspent', self.generateblock, node, address, [rawtx2, txid1])
9191

9292
self.log.info('Fail to generate block with txid not in mempool')
9393
missing_txid = '0000000000000000000000000000000000000000000000000000000000000000'

0 commit comments

Comments
 (0)