aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Dong <contact@carldong.me>2021-08-18 14:36:28 -0400
committerCarl Dong <contact@carldong.me>2021-12-07 14:48:06 -0500
commit2414ebc18b8bebf79c47e58a4293d0fc6420a811 (patch)
tree2f12fa9c8c90fda63b430dcd0ad3860ab87675cf /src
parent8d466a8504bfb81ce8699d650aa72ec9cc8b0a54 (diff)
init: Delay RPC block notif until warmup finished
See added code comment for more details.
Diffstat (limited to 'src')
-rw-r--r--src/init.cpp10
-rw-r--r--src/node/chainstate.cpp2
2 files changed, 10 insertions, 2 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 0c5baeee3b..9c8963d10d 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1777,7 +1777,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 13: finished
+ // At this point, the RPC is "started", but still in warmup, which means it
+ // cannot yet be called. Before we make it callable, we need to make sure
+ // that the RPC's view of the best block is valid and consistent with
+ // ChainstateManager's ActiveTip.
+ //
+ // If we do not do this, RPC's view of the best block will be height=0 and
+ // hash=0x0. This will lead to erroroneous responses for things like
+ // waitforblockheight.
+ RPCNotifyBlockChange(chainman.ActiveTip());
SetRPCWarmupFinished();
+
uiInterface.InitMessage(_("Done loading").translated);
for (const auto& client : node.chain_clients) {
diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp
index c795c740e4..56d1073bab 100644
--- a/src/node/chainstate.cpp
+++ b/src/node/chainstate.cpp
@@ -5,7 +5,6 @@
#include <node/chainstate.h>
#include <chainparams.h> // for CChainParams
-#include <rpc/blockchain.h> // for RPCNotifyBlockChange
#include <util/time.h> // for GetTime
#include <node/blockstorage.h> // for CleanupBlockRevFiles, fHavePruned, fReindex
#include <shutdown.h> // for ShutdownRequested
@@ -144,7 +143,6 @@ std::optional<ChainstateLoadVerifyError> VerifyLoadedChainstate(ChainstateManage
for (CChainState* chainstate : chainman.GetAll()) {
if (!is_coinsview_empty(chainstate)) {
const CBlockIndex* tip = chainstate->m_chain.Tip();
- RPCNotifyBlockChange(tip);
if (tip && tip->nTime > GetTime() + MAX_FUTURE_BLOCK_TIME) {
return ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE;
}