mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-09 10:43:19 -05:00
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.
This commit is contained in:
parent
7b4d3249ce
commit
dda0b0834f
3 changed files with 17 additions and 9 deletions
|
@ -5,6 +5,7 @@
|
||||||
#ifndef BITCOIN_INTERFACES_MINING_H
|
#ifndef BITCOIN_INTERFACES_MINING_H
|
||||||
#define BITCOIN_INTERFACES_MINING_H
|
#define BITCOIN_INTERFACES_MINING_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
|
||||||
namespace node {
|
namespace node {
|
||||||
|
@ -29,8 +30,8 @@ public:
|
||||||
//! If this chain is exclusively used for testing
|
//! If this chain is exclusively used for testing
|
||||||
virtual bool isTestChain() = 0;
|
virtual bool isTestChain() = 0;
|
||||||
|
|
||||||
//! Returns the hash for the tip of this chain, 0 if none
|
//! Returns the hash for the tip of this chain
|
||||||
virtual uint256 getTipHash() = 0;
|
virtual std::optional<uint256> getTipHash() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new block template
|
* Construct a new block template
|
||||||
|
|
|
@ -847,11 +847,11 @@ public:
|
||||||
return chainman().GetParams().IsTestChain();
|
return chainman().GetParams().IsTestChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 getTipHash() override
|
std::optional<uint256> getTipHash() override
|
||||||
{
|
{
|
||||||
LOCK(::cs_main);
|
LOCK(::cs_main);
|
||||||
CBlockIndex* tip{chainman().ActiveChain().Tip()};
|
CBlockIndex* tip{chainman().ActiveChain().Tip()};
|
||||||
if (!tip) return uint256{0};
|
if (!tip) return {};
|
||||||
return tip->GetBlockHash();
|
return tip->GetBlockHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -667,6 +667,9 @@ static RPCHelpMan getblocktemplate()
|
||||||
ChainstateManager& chainman = EnsureChainman(node);
|
ChainstateManager& chainman = EnsureChainman(node);
|
||||||
Mining& miner = EnsureMining(node);
|
Mining& miner = EnsureMining(node);
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
std::optional<uint256> maybe_tip{miner.getTipHash()};
|
||||||
|
CHECK_NONFATAL(maybe_tip);
|
||||||
|
uint256 tip{maybe_tip.value()};
|
||||||
|
|
||||||
std::string strMode = "template";
|
std::string strMode = "template";
|
||||||
UniValue lpval = NullUniValue;
|
UniValue lpval = NullUniValue;
|
||||||
|
@ -706,7 +709,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// testBlockValidity only supports blocks built on the current Tip
|
// testBlockValidity only supports blocks built on the current Tip
|
||||||
if (block.hashPrevBlock != miner.getTipHash()) {
|
if (block.hashPrevBlock != tip) {
|
||||||
return "inconclusive-not-best-prevblk";
|
return "inconclusive-not-best-prevblk";
|
||||||
}
|
}
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
|
@ -757,7 +760,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
|
// NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
|
||||||
hashWatchedChain = miner.getTipHash();
|
hashWatchedChain = tip;
|
||||||
nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
|
nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,6 +784,10 @@ static RPCHelpMan getblocktemplate()
|
||||||
}
|
}
|
||||||
ENTER_CRITICAL_SECTION(cs_main);
|
ENTER_CRITICAL_SECTION(cs_main);
|
||||||
|
|
||||||
|
std::optional<uint256> maybe_tip{miner.getTipHash()};
|
||||||
|
CHECK_NONFATAL(maybe_tip);
|
||||||
|
tip = maybe_tip.value();
|
||||||
|
|
||||||
if (!IsRPCRunning())
|
if (!IsRPCRunning())
|
||||||
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
|
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
|
||||||
// TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
|
// TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
|
||||||
|
@ -802,7 +809,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
static CBlockIndex* pindexPrev;
|
static CBlockIndex* pindexPrev;
|
||||||
static int64_t time_start;
|
static int64_t time_start;
|
||||||
static std::unique_ptr<CBlockTemplate> pblocktemplate;
|
static std::unique_ptr<CBlockTemplate> pblocktemplate;
|
||||||
if (!pindexPrev || pindexPrev->GetBlockHash() != miner.getTipHash() ||
|
if (!pindexPrev || pindexPrev->GetBlockHash() != tip ||
|
||||||
(miner.getTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5))
|
(miner.getTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5))
|
||||||
{
|
{
|
||||||
// Clear pindexPrev so future calls make a new block, despite any failures from here on
|
// Clear pindexPrev so future calls make a new block, despite any failures from here on
|
||||||
|
@ -810,7 +817,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
|
|
||||||
// Store the pindexBest used before createNewBlock, to avoid races
|
// Store the pindexBest used before createNewBlock, to avoid races
|
||||||
nTransactionsUpdatedLast = miner.getTransactionsUpdated();
|
nTransactionsUpdatedLast = miner.getTransactionsUpdated();
|
||||||
CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(miner.getTipHash());
|
CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(tip);
|
||||||
time_start = GetTime();
|
time_start = GetTime();
|
||||||
|
|
||||||
// Create new block
|
// Create new block
|
||||||
|
@ -943,7 +950,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
result.pushKV("transactions", std::move(transactions));
|
result.pushKV("transactions", std::move(transactions));
|
||||||
result.pushKV("coinbaseaux", std::move(aux));
|
result.pushKV("coinbaseaux", std::move(aux));
|
||||||
result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue);
|
result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue);
|
||||||
result.pushKV("longpollid", miner.getTipHash().GetHex() + ToString(nTransactionsUpdatedLast));
|
result.pushKV("longpollid", tip.GetHex() + ToString(nTransactionsUpdatedLast));
|
||||||
result.pushKV("target", hashTarget.GetHex());
|
result.pushKV("target", hashTarget.GetHex());
|
||||||
result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1);
|
result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1);
|
||||||
result.pushKV("mutable", std::move(aMutable));
|
result.pushKV("mutable", std::move(aMutable));
|
||||||
|
|
Loading…
Add table
Reference in a new issue