Skip to content

Commit eb8bc83

Browse files
committed
validation: sync utxo state after block sync
1 parent 5bc9b64 commit eb8bc83

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

src/init.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ static constexpr bool DEFAULT_REST_ENABLE{false};
139139
static constexpr bool DEFAULT_I2P_ACCEPT_INCOMING{true};
140140
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
141141

142+
//! Check if initial sync is done with no change in block height or queued downloads every 30s
143+
static constexpr auto SYNC_CHECK_INTERVAL{30s};
144+
142145
#ifdef WIN32
143146
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
144147
// accessing block files don't count towards the fd_set size limit
@@ -1108,6 +1111,44 @@ bool AppInitLockDataDirectory()
11081111
return true;
11091112
}
11101113

1114+
/**
1115+
* Once initial block sync is finished and no change in block height or queued downloads,
1116+
* sync utxo state to protect against data loss
1117+
*/
1118+
static void SyncCoinsTipAfterChainSync(const NodeContext& node)
1119+
{
1120+
LOCK(node.chainman->GetMutex());
1121+
if (node.chainman->IsInitialBlockDownload()) {
1122+
LogDebug(BCLog::COINDB, "Node is still in IBD, rescheduling post-IBD chainstate disk sync...\n");
1123+
node.scheduler->scheduleFromNow([&node] {
1124+
SyncCoinsTipAfterChainSync(node);
1125+
}, SYNC_CHECK_INTERVAL);
1126+
return;
1127+
}
1128+
1129+
static auto last_chain_height{-1};
1130+
const auto current_height{node.chainman->ActiveHeight()};
1131+
if (last_chain_height != current_height) {
1132+
LogDebug(BCLog::COINDB, "Chain height updated since last check, rescheduling post-IBD chainstate disk sync...\n");
1133+
last_chain_height = current_height;
1134+
node.scheduler->scheduleFromNow([&node] {
1135+
SyncCoinsTipAfterChainSync(node);
1136+
}, SYNC_CHECK_INTERVAL);
1137+
return;
1138+
}
1139+
1140+
if (node.peerman->GetNumberOfPeersWithValidatedDownloads() > 0) {
1141+
LogDebug(BCLog::COINDB, "Still downloading blocks from peers, rescheduling post-IBD chainstate disk sync...\n");
1142+
node.scheduler->scheduleFromNow([&node] {
1143+
SyncCoinsTipAfterChainSync(node);
1144+
}, SYNC_CHECK_INTERVAL);
1145+
return;
1146+
}
1147+
1148+
LogDebug(BCLog::COINDB, "Finished syncing to tip, syncing chainstate to disk\n");
1149+
node.chainman->ActiveChainstate().CoinsTip().Sync();
1150+
}
1151+
11111152
bool AppInitInterfaces(NodeContext& node)
11121153
{
11131154
node.chain = node.init->makeChain();
@@ -1985,6 +2026,12 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
19852026
StartupNotify(args);
19862027
#endif
19872028

2029+
if (node.chainman->IsInitialBlockDownload()) {
2030+
node.scheduler->scheduleFromNow([&node] {
2031+
SyncCoinsTipAfterChainSync(node);
2032+
}, SYNC_CHECK_INTERVAL);
2033+
}
2034+
19882035
return true;
19892036
}
19902037

src/net_processing.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ class PeerManagerImpl final : public PeerManager
532532
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex, !m_headers_presync_mutex, g_msgproc_mutex);
533533
void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds) override;
534534
ServiceFlags GetDesirableServiceFlags(ServiceFlags services) const override;
535+
int GetNumberOfPeersWithValidatedDownloads() const override EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
535536

536537
private:
537538
/** Consider evicting an outbound peer based on the amount of time they've been behind our tip */
@@ -1881,6 +1882,12 @@ PeerManagerInfo PeerManagerImpl::GetInfo() const
18811882
};
18821883
}
18831884

1885+
int PeerManagerImpl::GetNumberOfPeersWithValidatedDownloads() const
1886+
{
1887+
AssertLockHeld(m_chainman.GetMutex());
1888+
return m_peers_downloading_from;
1889+
}
1890+
18841891
void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
18851892
{
18861893
if (m_opts.max_extra_txs <= 0)

src/net_processing.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ class PeerManager : public CValidationInterface, public NetEventsInterface
141141
* we do not have a confirmed set of service flags.
142142
*/
143143
virtual ServiceFlags GetDesirableServiceFlags(ServiceFlags services) const = 0;
144+
145+
/** Get number of peers from which we're downloading blocks */
146+
virtual int GetNumberOfPeersWithValidatedDownloads() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) = 0;
144147
};
145148

146149
#endif // BITCOIN_NET_PROCESSING_H

0 commit comments

Comments
 (0)