diff options
author | James O'Beirne <james.obeirne@pm.me> | 2021-08-17 16:23:02 -0400 |
---|---|---|
committer | James O'Beirne <james.obeirne@pm.me> | 2022-09-13 13:30:25 -0400 |
commit | ad67ff377c2b271cb4683da2fb25fd295557f731 (patch) | |
tree | 43dfea6b6b3550913d61ace0c7ebb2be8cd4c55c | |
parent | 34d159033106cc595cfa852695610bfe419c989c (diff) |
validation: remove snapshot datadirs upon validation failure
If a UTXO snapshot fails to validate, don't leave the resulting datadir
on disk as this will confuse initialization on next startup and we'll
get an assertion error.
-rw-r--r-- | src/validation.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index 7e9c6b891e..b94950d1b4 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4876,7 +4876,22 @@ bool ChainstateManager::ActivateSnapshot( } } if (!snapshot_ok) { - WITH_LOCK(::cs_main, this->MaybeRebalanceCaches()); + LOCK(::cs_main); + this->MaybeRebalanceCaches(); + + // PopulateAndValidateSnapshot can return (in error) before the leveldb datadir + // has been created, so only attempt removal if we got that far. + if (auto snapshot_datadir = node::FindSnapshotChainstateDir()) { + // We have to destruct leveldb::DB in order to release the db lock, otherwise + // DestroyDB() (in DeleteCoinsDBFromDisk()) will fail. See `leveldb::~DBImpl()`. + // Destructing the chainstate (and so resetting the coinsviews object) does this. + snapshot_chainstate.reset(); + bool removed = DeleteCoinsDBFromDisk(*snapshot_datadir, /*is_snapshot=*/true); + if (!removed) { + AbortNode(strprintf("Failed to remove snapshot chainstate dir (%s). " + "Manually remove it before restarting.\n", fs::PathToString(*snapshot_datadir))); + } + } return false; } |