The keys and scripts created for the Legacy Wallet needed to be persisted in order for the migration to work properly.
Fixes #32277.
The keys and scripts created for the Legacy Wallet needed to be persisted in order for the migration to work properly.
Fixes #32277.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32281.
See the guideline for information on the review process.
Type | Reviewers |
---|---|
ACK | achow101, davidgumberg, furszy |
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
568@@ -569,6 +569,22 @@ bool HasLegacyRecords(CWallet& wallet, DatabaseBatch& batch)
569 return false;
570 }
571
572+bool HasAnyRecordWithKeyPrefix(CWallet& wallet, const std::string& dbkey_prefix)
41@@ -42,6 +42,11 @@ static void WalletMigration(benchmark::Bench& bench)
42 const CScript& script = scripts_watch_only.emplace_back(GetScriptForDestination(dest));
43 assert(legacy_spkm->LoadWatchOnly(script));
44 assert(wallet->SetAddressBook(dest, strprintf("watch_%d", w), /*purpose=*/std::nullopt));
45+ {
46+ WalletBatch batch(wallet->GetDatabase());
62@@ -58,6 +63,11 @@ static void WalletMigration(benchmark::Bench& bench)
63 mtx.vout.emplace_back(COIN, scripts_watch_only.at(j % NUM_WATCH_ONLY_ADDR));
64 mtx.vin.resize(2);
65 wallet->AddToWallet(MakeTransactionRef(mtx), TxStateInactive{}, /*update_wtx=*/nullptr, /*fFlushOnClose=*/false, /*rescanning_old_block=*/true);
66+ {
67+ WalletBatch batch(wallet->GetDatabase());
68+ batch.WriteKey(pubkey, key.GetPrivKey(), CKeyMetadata());
ApplyMigrationData
in for (auto& desc_spkm : data.desc_spkms) {
and the second at DoMigration
in for (const auto& [desc_str, creation_time] : data->watch_descs) {
).
The keys and scripts created for the Legacy Wallet
needed to be persisted in order for the migration to work
properly.
42@@ -42,6 +43,7 @@ static void WalletMigration(benchmark::Bench& bench)
43 const CScript& script = scripts_watch_only.emplace_back(GetScriptForDestination(dest));
44 assert(legacy_spkm->LoadWatchOnly(script));
45 assert(wallet->SetAddressBook(dest, strprintf("watch_%d", w), /*purpose=*/std::nullopt));
For context on my comment in #32277 (comment), SetAddressBook()
includes a write to the database, and so does AddToWallet(tx)
This is the reason why some records were persisted, but none that were strictly “legacy” records as mentioned in #32277 (comment).
(@furszy)
Tested ACK 7912cd41258d59e4
Either of the two DB writes added here seems to fix the issue in my testing, but it’s better to be consistent and write both.
I am no longer confident the change to success
introduced in #32149 makes sense:
Now, any wallet which fails the HasLegacyRecords()
check gets flagged as success = true
, before it was only wallets with the blank flag set which got success = true
for free. On second thought, should #32149 have explicitly handled the empty watchonly wallet case, rather than having to reason about the correctness/completeness of HasLegacyRecords()
This bug was an instance of a more general class of crash during migration: #32111. This would still be a bug if #32111 was fixed, but might not have resulted in a crash.