diff options
-rw-r--r-- | src/interfaces/mining.h | 5 | ||||
-rw-r--r-- | src/node/interfaces.cpp | 8 | ||||
-rw-r--r-- | src/rpc/mining.cpp | 12 |
3 files changed, 18 insertions, 7 deletions
diff --git a/src/interfaces/mining.h b/src/interfaces/mining.h index 603d8475d3..8ed273252b 100644 --- a/src/interfaces/mining.h +++ b/src/interfaces/mining.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_INTERFACES_MINING_H #define BITCOIN_INTERFACES_MINING_H +#include <uint256.h> + namespace node { struct NodeContext; } // namespace node @@ -25,6 +27,9 @@ public: //! If this chain is exclusively used for testing virtual bool isTestChain() = 0; + //! Returns the hash for the tip of this chain, 0 if none + virtual uint256 getTipHash() = 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 a528afcff0..bd200e8d29 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -845,6 +845,14 @@ public: return chainman().GetParams().IsTestChain(); } + uint256 getTipHash() override + { + LOCK(::cs_main); + CBlockIndex* tip{chainman().ActiveChain().Tip()}; + if (!tip) return uint256{0}; + return tip->GetBlockHash(); + } + bool testBlockValidity(BlockValidationState& state, const CBlock& block, bool check_merkle_root) override { LOCK(::cs_main); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index a9968b6e5f..9762d7648d 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -672,7 +672,6 @@ static RPCHelpMan getblocktemplate() UniValue lpval = NullUniValue; std::set<std::string> setClientRules; Chainstate& active_chainstate = chainman.ActiveChainstate(); - CChain& active_chain = active_chainstate.m_chain; if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); @@ -707,9 +706,8 @@ static RPCHelpMan getblocktemplate() return "duplicate-inconclusive"; } - CBlockIndex* const pindexPrev = active_chain.Tip(); // testBlockValidity only supports blocks built on the current Tip - if (block.hashPrevBlock != pindexPrev->GetBlockHash()) { + if (block.hashPrevBlock != miner.getTipHash()) { return "inconclusive-not-best-prevblk"; } BlockValidationState state; @@ -761,7 +759,7 @@ static RPCHelpMan getblocktemplate() else { // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier - hashWatchedChain = active_chain.Tip()->GetBlockHash(); + hashWatchedChain = miner.getTipHash(); nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } @@ -806,7 +804,7 @@ static RPCHelpMan getblocktemplate() static CBlockIndex* pindexPrev; static int64_t time_start; static std::unique_ptr<CBlockTemplate> pblocktemplate; - if (pindexPrev != active_chain.Tip() || + if (!pindexPrev || pindexPrev->GetBlockHash() != miner.getTipHash() || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5)) { // Clear pindexPrev so future calls make a new block, despite any failures from here on @@ -814,7 +812,7 @@ static RPCHelpMan getblocktemplate() // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrevNew = active_chain.Tip(); + CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(miner.getTipHash()); time_start = GetTime(); // Create new block @@ -946,7 +944,7 @@ static RPCHelpMan getblocktemplate() result.pushKV("transactions", std::move(transactions)); result.pushKV("coinbaseaux", std::move(aux)); result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue); - result.pushKV("longpollid", active_chain.Tip()->GetBlockHash().GetHex() + ToString(nTransactionsUpdatedLast)); + result.pushKV("longpollid", miner.getTipHash().GetHex() + ToString(nTransactionsUpdatedLast)); result.pushKV("target", hashTarget.GetHex()); result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1); result.pushKV("mutable", std::move(aMutable)); |