diff options
author | Sjors Provoost <sjors@sprovoost.nl> | 2024-06-10 17:03:33 +0200 |
---|---|---|
committer | Sjors Provoost <sjors@sprovoost.nl> | 2024-06-18 18:47:51 +0200 |
commit | 4bf2e361da1964f7c278b4939967a0e5afde20b0 (patch) | |
tree | ea724943b5c9af260bd631da0bacaa5755c862ef /src | |
parent | 404b01c436122b951e9e06ed26d79dba4651685e (diff) |
rpc: call CreateNewBlock via miner interface
Diffstat (limited to 'src')
-rw-r--r-- | src/interfaces/mining.h | 11 | ||||
-rw-r--r-- | src/node/interfaces.cpp | 7 | ||||
-rw-r--r-- | src/rpc/mining.cpp | 24 |
3 files changed, 30 insertions, 12 deletions
diff --git a/src/interfaces/mining.h b/src/interfaces/mining.h index 8ed273252b..9494fd75bf 100644 --- a/src/interfaces/mining.h +++ b/src/interfaces/mining.h @@ -8,11 +8,13 @@ #include <uint256.h> namespace node { +struct CBlockTemplate; struct NodeContext; } // namespace node class BlockValidationState; class CBlock; +class CScript; namespace interfaces { @@ -30,6 +32,15 @@ public: //! Returns the hash for the tip of this chain, 0 if none virtual uint256 getTipHash() = 0; + /** + * Construct a new block template + * + * @param[in] script_pub_key the coinbase output + * @param[in] use_mempool set false to omit mempool transactions + * @returns a block template + */ + virtual std::unique_ptr<node::CBlockTemplate> createNewBlock(const CScript& script_pub_key, bool use_mempool = true) = 0; + /** * Check a block is completely valid from start to finish. * Only works on top of our current best block. diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index bd200e8d29..215dbf5e17 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -32,6 +32,7 @@ #include <node/context.h> #include <node/interface_ui.h> #include <node/mini_miner.h> +#include <node/miner.h> #include <node/transaction.h> #include <node/types.h> #include <node/warnings.h> @@ -859,6 +860,12 @@ public: return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, chainman().ActiveChain().Tip(), /*fCheckPOW=*/false, check_merkle_root); } + std::unique_ptr<CBlockTemplate> createNewBlock(const CScript& script_pub_key, bool use_mempool) override + { + LOCK(::cs_main); + return BlockAssembler{chainman().ActiveChainstate(), use_mempool ? context()->mempool.get() : nullptr}.CreateNewBlock(script_pub_key); + } + NodeContext* context() override { return &m_node; } ChainstateManager& chainman() { return *Assert(m_node.chainman); } NodeContext& m_node; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 9762d7648d..a65413de1e 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -156,11 +156,11 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& return true; } -static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& mempool, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries) +static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries) { UniValue blockHashes(UniValue::VARR); while (nGenerate > 0 && !chainman.m_interrupt) { - std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler{chainman.ActiveChainstate(), &mempool}.CreateNewBlock(coinbase_script)); + std::unique_ptr<CBlockTemplate> pblocktemplate(miner.createNewBlock(coinbase_script)); if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); @@ -241,10 +241,10 @@ static RPCHelpMan generatetodescriptor() } NodeContext& node = EnsureAnyNodeContext(request.context); - const CTxMemPool& mempool = EnsureMemPool(node); + Mining& miner = EnsureMining(node); ChainstateManager& chainman = EnsureChainman(node); - return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries); + return generateBlocks(chainman, miner, coinbase_script, num_blocks, max_tries); }, }; } @@ -287,12 +287,12 @@ static RPCHelpMan generatetoaddress() } NodeContext& node = EnsureAnyNodeContext(request.context); - const CTxMemPool& mempool = EnsureMemPool(node); + Mining& miner = EnsureMining(node); ChainstateManager& chainman = EnsureChainman(node); CScript coinbase_script = GetScriptForDestination(destination); - return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries); + return generateBlocks(chainman, miner, coinbase_script, num_blocks, max_tries); }, }; } @@ -373,7 +373,7 @@ static RPCHelpMan generateblock() { LOCK(cs_main); - std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler{chainman.ActiveChainstate(), nullptr}.CreateNewBlock(coinbase_script)); + std::unique_ptr<CBlockTemplate> blocktemplate{miner.createNewBlock(coinbase_script, /*use_mempool=*/false)}; if (!blocktemplate) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); } @@ -671,7 +671,6 @@ static RPCHelpMan getblocktemplate() std::string strMode = "template"; UniValue lpval = NullUniValue; std::set<std::string> setClientRules; - Chainstate& active_chainstate = chainman.ActiveChainstate(); if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); @@ -810,18 +809,19 @@ static RPCHelpMan getblocktemplate() // Clear pindexPrev so future calls make a new block, despite any failures from here on pindexPrev = nullptr; - // Store the pindexBest used before CreateNewBlock, to avoid races + // Store the pindexBest used before createNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(miner.getTipHash()); time_start = GetTime(); // Create new block CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = BlockAssembler{active_chainstate, &mempool}.CreateNewBlock(scriptDummy); - if (!pblocktemplate) + pblocktemplate = miner.createNewBlock(scriptDummy); + if (!pblocktemplate) { throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); + } - // Need to update only after we know CreateNewBlock succeeded + // Need to update only after we know createNewBlock succeeded pindexPrev = pindexPrevNew; } CHECK_NONFATAL(pindexPrev); |