MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / MaybeValidateSnapshot

Method MaybeValidateSnapshot

src/validation.cpp:5986–6096  ·  view source on GitHub ↗

Currently, this function holds cs_main for its duration, which could be for multiple minutes due to the ComputeUTXOStats call. Holding cs_main used to be necessary (before d43a1f1a2fa3) to avoid advancing validated_cs farther than its target block. Now it should be possible to avoid this, but simply releasing cs_main here would not be possible because this function is invoked by ConnectTip within

Source from the content-addressed store, hash-verified

5984// hash, because the UTXO set is only hashed after the historical chainstate
5985// reaches its target block and is no longer changing.
5986SnapshotCompletionResult ChainstateManager::MaybeValidateSnapshot(Chainstate& validated_cs, Chainstate& unvalidated_cs)
5987{
5988 AssertLockHeld(cs_main);
5989
5990 // If the snapshot does not need to be validated...
5991 if (unvalidated_cs.m_assumeutxo != Assumeutxo::UNVALIDATED ||
5992 // Or if either chainstate is unusable...
5993 !unvalidated_cs.m_from_snapshot_blockhash ||
5994 validated_cs.m_assumeutxo != Assumeutxo::VALIDATED ||
5995 !validated_cs.m_chain.Tip() ||
5996 // Or the validated chainstate is not targeting the snapshot block...
5997 !validated_cs.m_target_blockhash ||
5998 *validated_cs.m_target_blockhash != *unvalidated_cs.m_from_snapshot_blockhash ||
5999 // Or the validated chainstate has not reached the snapshot block yet...
6000 !validated_cs.ReachedTarget()) {
6001 // Then the snapshot cannot be validated and there is nothing to do.
6002 return SnapshotCompletionResult::SKIPPED;
6003 }
6004 assert(validated_cs.TargetBlock() == validated_cs.m_chain.Tip());
6005
6006 auto handle_invalid_snapshot = [&]() EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
6007 bilingual_str user_error = strprintf(_(
6008 "%s failed to validate the -assumeutxo snapshot state. "
6009 "This indicates a hardware problem, or a bug in the software, or a "
6010 "bad software modification that allowed an invalid snapshot to be "
6011 "loaded. As a result of this, the node will shut down and stop using any "
6012 "state that was built on the snapshot, resetting the chain height "
6013 "from %d to %d. On the next "
6014 "restart, the node will resume syncing from %d "
6015 "without using any snapshot data. "
6016 "Please report this incident to %s, including how you obtained the snapshot. "
6017 "The invalid snapshot chainstate will be left on disk in case it is "
6018 "helpful in diagnosing the issue that caused this error."),
6019 CLIENT_NAME, unvalidated_cs.m_chain.Height(),
6020 validated_cs.m_chain.Height(),
6021 validated_cs.m_chain.Height(), CLIENT_BUGREPORT);
6022
6023 LogError("[snapshot] !!! %s\n", user_error.original);
6024 LogError("[snapshot] deleting snapshot, reverting to validated chain, and stopping node\n");
6025
6026 // Reset chainstate target to network tip instead of snapshot block.
6027 validated_cs.SetTargetBlock(nullptr);
6028
6029 unvalidated_cs.m_assumeutxo = Assumeutxo::INVALID;
6030
6031 auto rename_result = unvalidated_cs.InvalidateCoinsDBOnDisk();
6032 if (!rename_result) {
6033 user_error += Untranslated("\n") + util::ErrorString(rename_result);
6034 }
6035
6036 GetNotifications().fatalError(user_error);
6037 };
6038
6039 CCoinsViewDB& validated_coins_db = validated_cs.CoinsDB();
6040 validated_cs.ForceFlushStateToDisk();
6041
6042 const auto& maybe_au_data = m_options.chainparams.AssumeutxoForHeight(validated_cs.m_chain.Height());
6043 if (!maybe_au_data) {

Callers 3

ConnectTipMethod · 0.80
BOOST_FIXTURE_TEST_CASEFunction · 0.80
LoadChainstateFunction · 0.80

Calls 15

MaybeRebalanceCachesMethod · 0.95
_Function · 0.85
UntranslatedFunction · 0.85
ErrorStringFunction · 0.85
ComputeUTXOStatsFunction · 0.85
TargetBlockMethod · 0.80
HeightMethod · 0.80
SetTargetBlockMethod · 0.80
ForceFlushStateToDiskMethod · 0.80
AssumeutxoForHeightMethod · 0.80

Tested by 1

BOOST_FIXTURE_TEST_CASEFunction · 0.64