Skip to content

Commit 913411e

Browse files
committed
Split off VerifyLoadedChainstate
1 parent 53231ca commit 913411e

File tree

3 files changed

+67
-31
lines changed

3 files changed

+67
-31
lines changed

src/init.cpp

+29-16
Original file line numberDiff line numberDiff line change
@@ -1892,9 +1892,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
18921892
fReindexChainState,
18931893
nBlockTreeDBCache,
18941894
nCoinDBCache,
1895-
nCoinCacheUsage,
1896-
args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS),
1897-
args.GetArg("-checklevel", DEFAULT_CHECKLEVEL));
1895+
nCoinCacheUsage);
18981896
if (rv.has_value()) {
18991897
switch (rv.value()) {
19001898
case ChainstateLoadingError::ERROR_LOADING_BLOCK_DB:
@@ -1932,20 +1930,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
19321930
case ChainstateLoadingError::ERROR_LOADCHAINTIP_FAILED:
19331931
strLoadError = _("Error initializing block database");
19341932
break;
1935-
case ChainstateLoadingError::ERROR_EVO_DB_SANITY_FAILED:
1936-
strLoadError = _("Error initializing block database");
1937-
break;
19381933
case ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED:
19391934
strLoadError = _("Error opening block database");
19401935
break;
1941-
case ChainstateLoadingError::ERROR_BLOCK_FROM_FUTURE:
1942-
strLoadError = _("The block database contains a block which appears to be from the future. "
1943-
"This may be due to your computer's date and time being set incorrectly. "
1944-
"Only rebuild the block database if you are sure that your computer's date and time are correct");
1945-
break;
1946-
case ChainstateLoadingError::ERROR_CORRUPTED_BLOCK_DB:
1947-
strLoadError = _("Corrupted block database detected");
1948-
break;
19491936
case ChainstateLoadingError::ERROR_COMMITING_EVO_DB:
19501937
strLoadError = _("Failed to commit Evo database");
19511938
break;
@@ -1959,8 +1946,34 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
19591946
break;
19601947
}
19611948
} else {
1962-
fLoaded = true;
1963-
LogPrintf(" block index %15dms\n", Ticks<std::chrono::milliseconds>(SteadyClock::now() - load_block_index_start_time));
1949+
auto rv2 = VerifyLoadedChainstate(chainman,
1950+
*Assert(node.evodb.get()),
1951+
fReset,
1952+
fReindexChainState,
1953+
chainparams,
1954+
args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS),
1955+
args.GetArg("-checklevel", DEFAULT_CHECKLEVEL));
1956+
if (rv2.has_value()) {
1957+
switch (rv2.value()) {
1958+
case ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE:
1959+
strLoadError = _("The block database contains a block which appears to be from the future. "
1960+
"This may be due to your computer's date and time being set incorrectly. "
1961+
"Only rebuild the block database if you are sure that your computer's date and time are correct");
1962+
break;
1963+
case ChainstateLoadVerifyError::ERROR_CORRUPTED_BLOCK_DB:
1964+
strLoadError = _("Corrupted block database detected");
1965+
break;
1966+
case ChainstateLoadVerifyError::ERROR_EVO_DB_SANITY_FAILED:
1967+
strLoadError = _("Error initializing block database");
1968+
break;
1969+
case ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE:
1970+
strLoadError = _("Error opening block database");
1971+
break;
1972+
}
1973+
} else {
1974+
fLoaded = true;
1975+
LogPrintf(" block index %15dms\n", Ticks<std::chrono::milliseconds>(SteadyClock::now() - load_block_index_start_time));
1976+
}
19641977
}
19651978

19661979
if (!fLoaded && !ShutdownRequested()) {

src/node/chainstate.cpp

+22-9
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
5050
bool fReindexChainState,
5151
int64_t nBlockTreeDBCache,
5252
int64_t nCoinDBCache,
53-
int64_t nCoinCacheUsage,
54-
unsigned int check_blocks,
55-
unsigned int check_level)
53+
int64_t nCoinCacheUsage)
5654
{
5755
auto is_coinsview_empty = [&](CChainState* chainstate) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
5856
return fReset || fReindexChainState || chainstate->CoinsTip().GetBestBlock().IsNull();
@@ -232,6 +230,21 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
232230
return ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED;
233231
}
234232

233+
return std::nullopt;
234+
}
235+
236+
std::optional<ChainstateLoadVerifyError> VerifyLoadedChainstate(ChainstateManager& chainman,
237+
CEvoDB& evodb,
238+
bool fReset,
239+
bool fReindexChainState,
240+
const CChainParams& chainparams,
241+
unsigned int check_blocks,
242+
unsigned int check_level)
243+
{
244+
auto is_coinsview_empty = [&](CChainState* chainstate) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
245+
return fReset || fReindexChainState || chainstate->CoinsTip().GetBestBlock().IsNull();
246+
};
247+
235248
try {
236249
LOCK(cs_main);
237250

@@ -246,7 +259,7 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
246259
const CBlockIndex* tip = chainstate->m_chain.Tip();
247260
RPCNotifyBlockChange(tip);
248261
if (tip && tip->nTime > GetTime() + MAX_FUTURE_BLOCK_TIME) {
249-
return ChainstateLoadingError::ERROR_BLOCK_FROM_FUTURE;
262+
return ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE;
250263
}
251264
const bool v19active{DeploymentActiveAfter(tip, chainparams.GetConsensus(), Consensus::DEPLOYMENT_V19)};
252265
if (v19active) {
@@ -256,10 +269,10 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
256269

257270
if (!CVerifyDB().VerifyDB(
258271
*chainstate, chainparams, chainstate->CoinsDB(),
259-
*evodb,
272+
evodb,
260273
check_level,
261274
check_blocks)) {
262-
return ChainstateLoadingError::ERROR_CORRUPTED_BLOCK_DB;
275+
return ChainstateLoadVerifyError::ERROR_CORRUPTED_BLOCK_DB;
263276
}
264277

265278
// VerifyDB() disconnects blocks which might result in us switching back to legacy.
@@ -277,15 +290,15 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
277290
// TODO: CEvoDB instance should probably be a part of CChainState
278291
// (for multiple chainstates to actually work in parallel)
279292
// and not a global
280-
if (&chainman.ActiveChainstate() == chainstate && !evodb->IsEmpty()) {
293+
if (&chainman.ActiveChainstate() == chainstate && !evodb.IsEmpty()) {
281294
// EvoDB processed some blocks earlier but we have no blocks anymore, something is wrong
282-
return ChainstateLoadingError::ERROR_EVO_DB_SANITY_FAILED;
295+
return ChainstateLoadVerifyError::ERROR_EVO_DB_SANITY_FAILED;
283296
}
284297
}
285298
}
286299
} catch (const std::exception& e) {
287300
LogPrintf("%s\n", e.what());
288-
return ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED;
301+
return ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE;
289302
}
290303

291304
return std::nullopt;

src/node/chainstate.h

+16-6
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ enum class ChainstateLoadingError {
4343
ERROR_CHAINSTATE_UPGRADE_FAILED,
4444
ERROR_REPLAYBLOCKS_FAILED,
4545
ERROR_LOADCHAINTIP_FAILED,
46-
ERROR_EVO_DB_SANITY_FAILED,
4746
ERROR_GENERIC_BLOCKDB_OPEN_FAILED,
48-
ERROR_BLOCK_FROM_FUTURE,
49-
ERROR_CORRUPTED_BLOCK_DB,
5047
ERROR_COMMITING_EVO_DB,
5148
ERROR_UPGRADING_EVO_DB,
5249
ERROR_UPGRADING_SIGNALS_DB,
@@ -106,8 +103,21 @@ std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
106103
bool fReindexChainState,
107104
int64_t nBlockTreeDBCache,
108105
int64_t nCoinDBCache,
109-
int64_t nCoinCacheUsage,
110-
unsigned int check_blocks,
111-
unsigned int check_level);
106+
int64_t nCoinCacheUsage);
107+
108+
enum class ChainstateLoadVerifyError {
109+
ERROR_BLOCK_FROM_FUTURE,
110+
ERROR_CORRUPTED_BLOCK_DB,
111+
ERROR_EVO_DB_SANITY_FAILED,
112+
ERROR_GENERIC_FAILURE,
113+
};
114+
115+
std::optional<ChainstateLoadVerifyError> VerifyLoadedChainstate(ChainstateManager& chainman,
116+
CEvoDB& evodb,
117+
bool fReset,
118+
bool fReindexChainState,
119+
const CChainParams& chainparams,
120+
unsigned int check_blocks,
121+
unsigned int check_level);
112122

113123
#endif // BITCOIN_NODE_CHAINSTATE_H

0 commit comments

Comments
 (0)