rpc/rest: Take and reuse local Chain/ChainState obj

In all rest/rpc-related modules, if there are multiple calls to
ActiveChain{,State}(), and the calls fall under the same ::cs_main lock,
we can simply take a local reference and use/reuse it instead of calling
ActiveChain{,State}() again and again.
This commit is contained in:
Carl Dong
2021-04-12 21:34:42 -04:00
parent bc3bd36902
commit 586190f0b4
4 changed files with 39 additions and 29 deletions

View File

@@ -608,6 +608,8 @@ static RPCHelpMan getblocktemplate()
UniValue lpval = NullUniValue;
std::set<std::string> setClientRules;
int64_t nMaxVersionPreVB = -1;
CChainState& active_chainstate = chainman.ActiveChainstate();
CChain& active_chain = active_chainstate.m_chain;
if (!request.params[0].isNull())
{
const UniValue& oparam = request.params[0].get_obj();
@@ -642,12 +644,12 @@ static RPCHelpMan getblocktemplate()
return "duplicate-inconclusive";
}
CBlockIndex* const pindexPrev = chainman.ActiveChain().Tip();
CBlockIndex* const pindexPrev = active_chain.Tip();
// TestBlockValidity only supports blocks built on the current Tip
if (block.hashPrevBlock != pindexPrev->GetBlockHash())
return "inconclusive-not-best-prevblk";
BlockValidationState state;
TestBlockValidity(state, Params(), chainman.ActiveChainstate(), block, pindexPrev, false, true);
TestBlockValidity(state, Params(), active_chainstate, block, pindexPrev, false, true);
return BIP22ValidationResult(state);
}
@@ -677,7 +679,7 @@ static RPCHelpMan getblocktemplate()
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!");
}
if (chainman.ActiveChainstate().IsInitialBlockDownload()) {
if (active_chainstate.IsInitialBlockDownload()) {
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks...");
}
}
@@ -703,7 +705,7 @@ static RPCHelpMan getblocktemplate()
else
{
// NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
hashWatchedChain = chainman.ActiveChain().Tip()->GetBlockHash();
hashWatchedChain = active_chain.Tip()->GetBlockHash();
nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
}
@@ -748,7 +750,7 @@ static RPCHelpMan getblocktemplate()
static CBlockIndex* pindexPrev;
static int64_t nStart;
static std::unique_ptr<CBlockTemplate> pblocktemplate;
if (pindexPrev != chainman.ActiveChain().Tip() ||
if (pindexPrev != active_chain.Tip() ||
(mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
{
// Clear pindexPrev so future calls make a new block, despite any failures from here on
@@ -756,12 +758,12 @@ static RPCHelpMan getblocktemplate()
// Store the pindexBest used before CreateNewBlock, to avoid races
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrevNew = chainman.ActiveChain().Tip();
CBlockIndex* pindexPrevNew = active_chain.Tip();
nStart = GetTime();
// Create new block
CScript scriptDummy = CScript() << OP_TRUE;
pblocktemplate = BlockAssembler(chainman.ActiveChainstate(), mempool, Params()).CreateNewBlock(scriptDummy);
pblocktemplate = BlockAssembler(active_chainstate, mempool, Params()).CreateNewBlock(scriptDummy);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
@@ -897,7 +899,7 @@ static RPCHelpMan getblocktemplate()
result.pushKV("transactions", transactions);
result.pushKV("coinbaseaux", aux);
result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue);
result.pushKV("longpollid", chainman.ActiveChain().Tip()->GetBlockHash().GetHex() + ToString(nTransactionsUpdatedLast));
result.pushKV("longpollid", active_chain.Tip()->GetBlockHash().GetHex() + ToString(nTransactionsUpdatedLast));
result.pushKV("target", hashTarget.GetHex());
result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1);
result.pushKV("mutable", aMutable);