@@ -44,139 +44,137 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
4444 return fReset || fReindexChainState || chainstate->CoinsTip ().GetBestBlock ().IsNull ();
4545 };
4646
47- {
48- LOCK (cs_main);
47+ LOCK (cs_main);
4948
50- int64_t nEvoDbCache{64 * 1024 * 1024 }; // TODO
51- node.evodb .reset ();
52- node.evodb = std::make_unique<CEvoDB>(nEvoDbCache, false , fReset || fReindexChainState );
49+ int64_t nEvoDbCache{64 * 1024 * 1024 }; // TODO
50+ node.evodb .reset ();
51+ node.evodb = std::make_unique<CEvoDB>(nEvoDbCache, false , fReset || fReindexChainState );
5352
54- node.mnhf_manager .reset ();
55- node.mnhf_manager = std::make_unique<CMNHFManager>(*node.evodb );
53+ node.mnhf_manager .reset ();
54+ node.mnhf_manager = std::make_unique<CMNHFManager>(*node.evodb );
5655
57- chainman.InitializeChainstate (Assert (node.mempool .get ()), *node.evodb , node.chain_helper , llmq::chainLocksHandler, llmq::quorumInstantSendManager);
58- chainman.m_total_coinstip_cache = nCoinCacheUsage;
59- chainman.m_total_coinsdb_cache = nCoinDBCache;
56+ chainman.InitializeChainstate (Assert (node.mempool .get ()), *node.evodb , node.chain_helper , llmq::chainLocksHandler, llmq::quorumInstantSendManager);
57+ chainman.m_total_coinstip_cache = nCoinCacheUsage;
58+ chainman.m_total_coinsdb_cache = nCoinDBCache;
6059
61- auto & pblocktree{chainman.m_blockman .m_block_tree_db };
62- // new CBlockTreeDB tries to delete the existing file, which
63- // fails if it's still open from the previous loop. Close it first:
64- pblocktree.reset ();
65- pblocktree.reset (new CBlockTreeDB (nBlockTreeDBCache, block_tree_db_in_memory, fReset ));
60+ auto & pblocktree{chainman.m_blockman .m_block_tree_db };
61+ // new CBlockTreeDB tries to delete the existing file, which
62+ // fails if it's still open from the previous loop. Close it first:
63+ pblocktree.reset ();
64+ pblocktree.reset (new CBlockTreeDB (nBlockTreeDBCache, block_tree_db_in_memory, fReset ));
6665
67- DashChainstateSetup (chainman, node, fReset , fReindexChainState , consensus_params);
66+ DashChainstateSetup (chainman, node, fReset , fReindexChainState , consensus_params);
6867
69- if (fReset ) {
70- pblocktree->WriteReindexing (true );
71- // If we're reindexing in prune mode, wipe away unusable block files and all undo data files
72- if (fPruneMode )
73- CleanupBlockRevFiles ();
74- }
68+ if (fReset ) {
69+ pblocktree->WriteReindexing (true );
70+ // If we're reindexing in prune mode, wipe away unusable block files and all undo data files
71+ if (fPruneMode )
72+ CleanupBlockRevFiles ();
73+ }
7574
76- if (shutdown_requested && shutdown_requested ()) return ChainstateLoadingError::SHUTDOWN_PROBED;
75+ if (shutdown_requested && shutdown_requested ()) return ChainstateLoadingError::SHUTDOWN_PROBED;
7776
78- // LoadBlockIndex will load m_have_pruned if we've ever removed a
79- // block file from disk.
80- // Note that it also sets fReindex based on the disk flag!
81- // From here on out fReindex and fReset mean something different!
82- if (!chainman.LoadBlockIndex ()) {
83- if (shutdown_requested && shutdown_requested ()) return ChainstateLoadingError::SHUTDOWN_PROBED;
84- return ChainstateLoadingError::ERROR_LOADING_BLOCK_DB;
85- }
77+ // LoadBlockIndex will load m_have_pruned if we've ever removed a
78+ // block file from disk.
79+ // Note that it also sets fReindex based on the disk flag!
80+ // From here on out fReindex and fReset mean something different!
81+ if (!chainman.LoadBlockIndex ()) {
82+ if (shutdown_requested && shutdown_requested ()) return ChainstateLoadingError::SHUTDOWN_PROBED;
83+ return ChainstateLoadingError::ERROR_LOADING_BLOCK_DB;
84+ }
8685
87- if (!chainman.BlockIndex ().empty () &&
88- !chainman.m_blockman .LookupBlockIndex (consensus_params.hashGenesisBlock )) {
89- return ChainstateLoadingError::ERROR_BAD_GENESIS_BLOCK;
90- }
86+ if (!chainman.BlockIndex ().empty () &&
87+ !chainman.m_blockman .LookupBlockIndex (consensus_params.hashGenesisBlock )) {
88+ return ChainstateLoadingError::ERROR_BAD_GENESIS_BLOCK;
89+ }
9190
92- if (!consensus_params.hashDevnetGenesisBlock .IsNull () && !chainman.BlockIndex ().empty () &&
93- !chainman.m_blockman .LookupBlockIndex (consensus_params.hashDevnetGenesisBlock )) {
94- return ChainstateLoadingError::ERROR_BAD_DEVNET_GENESIS_BLOCK;
95- }
91+ if (!consensus_params.hashDevnetGenesisBlock .IsNull () && !chainman.BlockIndex ().empty () &&
92+ !chainman.m_blockman .LookupBlockIndex (consensus_params.hashDevnetGenesisBlock )) {
93+ return ChainstateLoadingError::ERROR_BAD_DEVNET_GENESIS_BLOCK;
94+ }
9695
97- // TODO: Remove this when pruning is fixed.
98- // See https://github.com/dashpay/dash/pull/1817 and https://github.com/dashpay/dash/pull/1743
99- if (is_governance_enabled && !is_txindex_enabled && network_id != CBaseChainParams::REGTEST) {
100- return ChainstateLoadingError::ERROR_TXINDEX_DISABLED_WHEN_GOV_ENABLED;
101- }
96+ // TODO: Remove this when pruning is fixed.
97+ // See https://github.com/dashpay/dash/pull/1817 and https://github.com/dashpay/dash/pull/1743
98+ if (is_governance_enabled && !is_txindex_enabled && network_id != CBaseChainParams::REGTEST) {
99+ return ChainstateLoadingError::ERROR_TXINDEX_DISABLED_WHEN_GOV_ENABLED;
100+ }
102101
103- // Check for changed -addressindex state
104- if (fAddressIndex != is_addrindex_enabled) {
105- return ChainstateLoadingError::ERROR_ADDRIDX_NEEDS_REINDEX;
106- }
102+ // Check for changed -addressindex state
103+ if (fAddressIndex != is_addrindex_enabled) {
104+ return ChainstateLoadingError::ERROR_ADDRIDX_NEEDS_REINDEX;
105+ }
107106
108- // Check for changed -spentindex state
109- if (fSpentIndex != is_spentindex_enabled) {
110- return ChainstateLoadingError::ERROR_SPENTIDX_NEEDS_REINDEX;
111- }
107+ // Check for changed -spentindex state
108+ if (fSpentIndex != is_spentindex_enabled) {
109+ return ChainstateLoadingError::ERROR_SPENTIDX_NEEDS_REINDEX;
110+ }
112111
113- // Check for changed -timestampindex state
114- if (fTimestampIndex != is_timeindex_enabled) {
115- return ChainstateLoadingError::ERROR_TIMEIDX_NEEDS_REINDEX;
116- }
112+ // Check for changed -timestampindex state
113+ if (fTimestampIndex != is_timeindex_enabled) {
114+ return ChainstateLoadingError::ERROR_TIMEIDX_NEEDS_REINDEX;
115+ }
117116
118- // Check for changed -prune state. What we are concerned about is a user who has pruned blocks
119- // in the past, but is now trying to run unpruned.
120- if (chainman.m_blockman .m_have_pruned && !fPruneMode ) {
121- return ChainstateLoadingError::ERROR_PRUNED_NEEDS_REINDEX;
122- }
117+ // Check for changed -prune state. What we are concerned about is a user who has pruned blocks
118+ // in the past, but is now trying to run unpruned.
119+ if (chainman.m_blockman .m_have_pruned && !fPruneMode ) {
120+ return ChainstateLoadingError::ERROR_PRUNED_NEEDS_REINDEX;
121+ }
123122
124- // At this point blocktree args are consistent with what's on disk.
125- // If we're not mid-reindex (based on disk + args), add a genesis block on disk
126- // (otherwise we use the one already on disk).
127- // This is called again in ThreadImport after the reindex completes.
128- if (!fReindex && !chainman.ActiveChainstate ().LoadGenesisBlock ()) {
129- return ChainstateLoadingError::ERROR_LOAD_GENESIS_BLOCK_FAILED;
130- }
123+ // At this point blocktree args are consistent with what's on disk.
124+ // If we're not mid-reindex (based on disk + args), add a genesis block on disk
125+ // (otherwise we use the one already on disk).
126+ // This is called again in ThreadImport after the reindex completes.
127+ if (!fReindex && !chainman.ActiveChainstate ().LoadGenesisBlock ()) {
128+ return ChainstateLoadingError::ERROR_LOAD_GENESIS_BLOCK_FAILED;
129+ }
131130
132- // At this point we're either in reindex or we've loaded a useful
133- // block tree into BlockIndex()!
131+ // At this point we're either in reindex or we've loaded a useful
132+ // block tree into BlockIndex()!
134133
135- for (CChainState* chainstate : chainman.GetAll ()) {
136- chainstate->InitCoinsDB (
137- /* cache_size_bytes */ nCoinDBCache,
138- /* in_memory */ coins_db_in_memory,
139- /* should_wipe */ fReset || fReindexChainState );
134+ for (CChainState* chainstate : chainman.GetAll ()) {
135+ chainstate->InitCoinsDB (
136+ /* cache_size_bytes */ nCoinDBCache,
137+ /* in_memory */ coins_db_in_memory,
138+ /* should_wipe */ fReset || fReindexChainState );
140139
141- if (coins_error_cb) {
142- chainstate->CoinsErrorCatcher ().AddReadErrCallback (coins_error_cb);
143- }
140+ if (coins_error_cb) {
141+ chainstate->CoinsErrorCatcher ().AddReadErrCallback (coins_error_cb);
142+ }
144143
145- // If necessary, upgrade from older database format.
146- // This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
147- if (!chainstate->CoinsDB ().Upgrade ()) {
148- return ChainstateLoadingError::ERROR_CHAINSTATE_UPGRADE_FAILED;
149- }
144+ // If necessary, upgrade from older database format.
145+ // This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
146+ if (!chainstate->CoinsDB ().Upgrade ()) {
147+ return ChainstateLoadingError::ERROR_CHAINSTATE_UPGRADE_FAILED;
148+ }
150149
151- // ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
152- if (!chainstate->ReplayBlocks ()) {
153- return ChainstateLoadingError::ERROR_REPLAYBLOCKS_FAILED;
154- }
150+ // ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
151+ if (!chainstate->ReplayBlocks ()) {
152+ return ChainstateLoadingError::ERROR_REPLAYBLOCKS_FAILED;
153+ }
155154
156- // The on-disk coinsdb is now in a good state, create the cache
157- chainstate->InitCoinsCache (nCoinCacheUsage);
158- assert (chainstate->CanFlushToDisk ());
155+ // The on-disk coinsdb is now in a good state, create the cache
156+ chainstate->InitCoinsCache (nCoinCacheUsage);
157+ assert (chainstate->CanFlushToDisk ());
159158
160- // flush evodb
161- // TODO: CEvoDB instance should probably be a part of CChainState
162- // (for multiple chainstates to actually work in parallel)
163- // and not a global
164- if (&chainman.ActiveChainstate () == chainstate && !node.evodb ->CommitRootTransaction ()) {
165- return ChainstateLoadingError::ERROR_COMMITING_EVO_DB;
166- }
159+ // flush evodb
160+ // TODO: CEvoDB instance should probably be a part of CChainState
161+ // (for multiple chainstates to actually work in parallel)
162+ // and not a global
163+ if (&chainman.ActiveChainstate () == chainstate && !node.evodb ->CommitRootTransaction ()) {
164+ return ChainstateLoadingError::ERROR_COMMITING_EVO_DB;
165+ }
167166
168- if (!is_coinsview_empty (chainstate)) {
169- // LoadChainTip initializes the chain based on CoinsTip()'s best block
170- if (!chainstate->LoadChainTip ()) {
171- return ChainstateLoadingError::ERROR_LOADCHAINTIP_FAILED;
172- }
173- assert (chainstate->m_chain .Tip () != nullptr );
167+ if (!is_coinsview_empty (chainstate)) {
168+ // LoadChainTip initializes the chain based on CoinsTip()'s best block
169+ if (!chainstate->LoadChainTip ()) {
170+ return ChainstateLoadingError::ERROR_LOADCHAINTIP_FAILED;
174171 }
172+ assert (chainstate->m_chain .Tip () != nullptr );
175173 }
174+ }
176175
177- if (!node.dmnman ->MigrateDBIfNeeded () || !node.dmnman ->MigrateDBIfNeeded2 ()) {
178- return ChainstateLoadingError::ERROR_UPGRADING_EVO_DB;
179- }
176+ if (!node.dmnman ->MigrateDBIfNeeded () || !node.dmnman ->MigrateDBIfNeeded2 ()) {
177+ return ChainstateLoadingError::ERROR_UPGRADING_EVO_DB;
180178 }
181179
182180 return std::nullopt ;
@@ -244,48 +242,46 @@ std::optional<ChainstateLoadVerifyError> VerifyLoadedChainstate(ChainstateManage
244242 return fReset || fReindexChainState || chainstate->CoinsTip ().GetBestBlock ().IsNull ();
245243 };
246244
247- {
248- LOCK (cs_main);
249-
250- for (CChainState* chainstate : chainman.GetAll ()) {
251- if (!is_coinsview_empty (chainstate)) {
252- const CBlockIndex* tip = chainstate->m_chain .Tip ();
253- if (tip && tip->nTime > get_unix_time_seconds () + 2 * 60 * 60 ) {
254- return ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE;
255- }
256- const bool v19active{DeploymentActiveAfter (tip, consensus_params, Consensus::DEPLOYMENT_V19)};
257- if (v19active) {
258- bls::bls_legacy_scheme.store (false );
259- LogPrintf (" %s: bls_legacy_scheme=%d\n " , __func__, bls::bls_legacy_scheme.load ());
260- }
261-
262- if (!CVerifyDB ().VerifyDB (
263- *chainstate, consensus_params, chainstate->CoinsDB (),
264- evodb,
265- check_level,
266- check_blocks)) {
267- return ChainstateLoadVerifyError::ERROR_CORRUPTED_BLOCK_DB;
268- }
269-
270- // VerifyDB() disconnects blocks which might result in us switching back to legacy.
271- // Make sure we use the right scheme.
272- if (v19active && bls::bls_legacy_scheme.load ()) {
273- bls::bls_legacy_scheme.store (false );
274- LogPrintf (" %s: bls_legacy_scheme=%d\n " , __func__, bls::bls_legacy_scheme.load ());
275- }
276-
277- if (check_level >= 3 ) {
278- chainstate->ResetBlockFailureFlags (nullptr );
279- }
280-
281- } else {
282- // TODO: CEvoDB instance should probably be a part of CChainState
283- // (for multiple chainstates to actually work in parallel)
284- // and not a global
285- if (&chainman.ActiveChainstate () == chainstate && !evodb.IsEmpty ()) {
286- // EvoDB processed some blocks earlier but we have no blocks anymore, something is wrong
287- return ChainstateLoadVerifyError::ERROR_EVO_DB_SANITY_FAILED;
288- }
245+ LOCK (cs_main);
246+
247+ for (CChainState* chainstate : chainman.GetAll ()) {
248+ if (!is_coinsview_empty (chainstate)) {
249+ const CBlockIndex* tip = chainstate->m_chain .Tip ();
250+ if (tip && tip->nTime > get_unix_time_seconds () + 2 * 60 * 60 ) {
251+ return ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE;
252+ }
253+ const bool v19active{DeploymentActiveAfter (tip, consensus_params, Consensus::DEPLOYMENT_V19)};
254+ if (v19active) {
255+ bls::bls_legacy_scheme.store (false );
256+ LogPrintf (" %s: bls_legacy_scheme=%d\n " , __func__, bls::bls_legacy_scheme.load ());
257+ }
258+
259+ if (!CVerifyDB ().VerifyDB (
260+ *chainstate, consensus_params, chainstate->CoinsDB (),
261+ evodb,
262+ check_level,
263+ check_blocks)) {
264+ return ChainstateLoadVerifyError::ERROR_CORRUPTED_BLOCK_DB;
265+ }
266+
267+ // VerifyDB() disconnects blocks which might result in us switching back to legacy.
268+ // Make sure we use the right scheme.
269+ if (v19active && bls::bls_legacy_scheme.load ()) {
270+ bls::bls_legacy_scheme.store (false );
271+ LogPrintf (" %s: bls_legacy_scheme=%d\n " , __func__, bls::bls_legacy_scheme.load ());
272+ }
273+
274+ if (check_level >= 3 ) {
275+ chainstate->ResetBlockFailureFlags (nullptr );
276+ }
277+
278+ } else {
279+ // TODO: CEvoDB instance should probably be a part of CChainState
280+ // (for multiple chainstates to actually work in parallel)
281+ // and not a global
282+ if (&chainman.ActiveChainstate () == chainstate && !evodb.IsEmpty ()) {
283+ // EvoDB processed some blocks earlier but we have no blocks anymore, something is wrong
284+ return ChainstateLoadVerifyError::ERROR_EVO_DB_SANITY_FAILED;
289285 }
290286 }
291287 }
0 commit comments