@@ -3192,6 +3192,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
3192
3192
3193
3193
CBlockIndex *pindexMostWork = nullptr ;
3194
3194
CBlockIndex *pindexNewTip = nullptr ;
3195
+ bool exited_ibd{false };
3195
3196
do {
3196
3197
// Block until the validation queue drains. This should largely
3197
3198
// never happen in normal operation, however may happen during
@@ -3205,6 +3206,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
3205
3206
LOCK (cs_main);
3206
3207
// Lock transaction pool for at least as long as it takes for connectTrace to be consumed
3207
3208
LOCK (MempoolMutex ());
3209
+ const bool was_in_ibd = m_chainman.IsInitialBlockDownload ();
3208
3210
CBlockIndex* starting_tip = m_chain.Tip ();
3209
3211
bool blocks_connected = false ;
3210
3212
do {
@@ -3252,16 +3254,21 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
3252
3254
if (!blocks_connected) return true ;
3253
3255
3254
3256
const CBlockIndex* pindexFork = m_chain.FindFork (starting_tip);
3255
- bool fInitialDownload = m_chainman.IsInitialBlockDownload ();
3257
+ bool still_in_ibd = m_chainman.IsInitialBlockDownload ();
3258
+
3259
+ if (was_in_ibd && !still_in_ibd) {
3260
+ // Active chainstate has exited IBD.
3261
+ exited_ibd = true ;
3262
+ }
3256
3263
3257
3264
// Notify external listeners about the new tip.
3258
3265
// Enqueue while holding cs_main to ensure that UpdatedBlockTip is called in the order in which blocks are connected
3259
3266
if (pindexFork != pindexNewTip) {
3260
3267
// Notify ValidationInterface subscribers
3261
- GetMainSignals ().UpdatedBlockTip (pindexNewTip, pindexFork, fInitialDownload );
3268
+ GetMainSignals ().UpdatedBlockTip (pindexNewTip, pindexFork, still_in_ibd );
3262
3269
3263
3270
// Always notify the UI if a new block tip was connected
3264
- if (kernel::IsInterrupted (m_chainman.GetNotifications ().blockTip (GetSynchronizationState (fInitialDownload ), *pindexNewTip))) {
3271
+ if (kernel::IsInterrupted (m_chainman.GetNotifications ().blockTip (GetSynchronizationState (still_in_ibd ), *pindexNewTip))) {
3265
3272
// Just breaking and returning success for now. This could
3266
3273
// be changed to bubble up the kernel::Interrupted value to
3267
3274
// the caller so the caller could distinguish between
@@ -3272,6 +3279,13 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
3272
3279
}
3273
3280
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
3274
3281
3282
+ if (exited_ibd) {
3283
+ // If a background chainstate is in use, we may need to rebalance our
3284
+ // allocation of caches once a chainstate exits initial block download.
3285
+ LOCK (::cs_main);
3286
+ m_chainman.MaybeRebalanceCaches ();
3287
+ }
3288
+
3275
3289
if (WITH_LOCK (::cs_main, return m_disabled)) {
3276
3290
// Background chainstate has reached the snapshot base block, so exit.
3277
3291
break ;
0 commit comments