Skip to content

Commit dda0b08

Browse files
committed
rpc: minize getTipHash() calls in gbt
Set tip at the start of the function and only update it for a long poll. Additionally have getTipHash return an optional, so the caller can explicitly check that a tip exists.
1 parent 7b4d324 commit dda0b08

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

src/interfaces/mining.h

Lines changed: 3 additions & 2 deletions
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 <optional>
89
#include <uint256.h>
910

1011
namespace node {
@@ -29,8 +30,8 @@ class Mining
2930
//! If this chain is exclusively used for testing
3031
virtual bool isTestChain() = 0;
3132

32-
//! Returns the hash for the tip of this chain, 0 if none
33-
virtual uint256 getTipHash() = 0;
33+
//! Returns the hash for the tip of this chain
34+
virtual std::optional<uint256> getTipHash() = 0;
3435

3536
/**
3637
* Construct a new block template

src/node/interfaces.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,11 +847,11 @@ class MinerImpl : public Mining
847847
return chainman().GetParams().IsTestChain();
848848
}
849849

850-
uint256 getTipHash() override
850+
std::optional<uint256> getTipHash() override
851851
{
852852
LOCK(::cs_main);
853853
CBlockIndex* tip{chainman().ActiveChain().Tip()};
854-
if (!tip) return uint256{0};
854+
if (!tip) return {};
855855
return tip->GetBlockHash();
856856
}
857857

src/rpc/mining.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,9 @@ static RPCHelpMan getblocktemplate()
667667
ChainstateManager& chainman = EnsureChainman(node);
668668
Mining& miner = EnsureMining(node);
669669
LOCK(cs_main);
670+
std::optional<uint256> maybe_tip{miner.getTipHash()};
671+
CHECK_NONFATAL(maybe_tip);
672+
uint256 tip{maybe_tip.value()};
670673

671674
std::string strMode = "template";
672675
UniValue lpval = NullUniValue;
@@ -706,7 +709,7 @@ static RPCHelpMan getblocktemplate()
706709
}
707710

708711
// testBlockValidity only supports blocks built on the current Tip
709-
if (block.hashPrevBlock != miner.getTipHash()) {
712+
if (block.hashPrevBlock != tip) {
710713
return "inconclusive-not-best-prevblk";
711714
}
712715
BlockValidationState state;
@@ -757,7 +760,7 @@ static RPCHelpMan getblocktemplate()
757760
else
758761
{
759762
// NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
760-
hashWatchedChain = miner.getTipHash();
763+
hashWatchedChain = tip;
761764
nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
762765
}
763766

@@ -781,6 +784,10 @@ static RPCHelpMan getblocktemplate()
781784
}
782785
ENTER_CRITICAL_SECTION(cs_main);
783786

787+
std::optional<uint256> maybe_tip{miner.getTipHash()};
788+
CHECK_NONFATAL(maybe_tip);
789+
tip = maybe_tip.value();
790+
784791
if (!IsRPCRunning())
785792
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
786793
// TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
@@ -802,15 +809,15 @@ static RPCHelpMan getblocktemplate()
802809
static CBlockIndex* pindexPrev;
803810
static int64_t time_start;
804811
static std::unique_ptr<CBlockTemplate> pblocktemplate;
805-
if (!pindexPrev || pindexPrev->GetBlockHash() != miner.getTipHash() ||
812+
if (!pindexPrev || pindexPrev->GetBlockHash() != tip ||
806813
(miner.getTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5))
807814
{
808815
// Clear pindexPrev so future calls make a new block, despite any failures from here on
809816
pindexPrev = nullptr;
810817

811818
// Store the pindexBest used before createNewBlock, to avoid races
812819
nTransactionsUpdatedLast = miner.getTransactionsUpdated();
813-
CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(miner.getTipHash());
820+
CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(tip);
814821
time_start = GetTime();
815822

816823
// Create new block
@@ -943,7 +950,7 @@ static RPCHelpMan getblocktemplate()
943950
result.pushKV("transactions", std::move(transactions));
944951
result.pushKV("coinbaseaux", std::move(aux));
945952
result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue);
946-
result.pushKV("longpollid", miner.getTipHash().GetHex() + ToString(nTransactionsUpdatedLast));
953+
result.pushKV("longpollid", tip.GetHex() + ToString(nTransactionsUpdatedLast));
947954
result.pushKV("target", hashTarget.GetHex());
948955
result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1);
949956
result.pushKV("mutable", std::move(aMutable));

0 commit comments

Comments
 (0)