Merge 5a1473e2c0 into merged_master (Bitcoin PR bitcoin/bitcoin#28976)

This commit is contained in:
Byron Hambly 2025-11-29 14:11:23 +02:00
commit 9d50e4e1b4
No known key found for this signature in database
GPG key ID: DE8F6EA20A661697
2 changed files with 24 additions and 9 deletions

View file

@ -4676,7 +4676,11 @@ std::optional<MigrationData> CWallet::GetDescriptorsForLegacy(bilingual_str& err
AssertLockHeld(cs_wallet);
LegacyScriptPubKeyMan* legacy_spkm = GetLegacyScriptPubKeyMan();
assert(legacy_spkm);
if (!Assume(legacy_spkm)) {
// This shouldn't happen
error = Untranslated(STR_INTERNAL_BUG("Error: Legacy wallet data missing"));
return std::nullopt;
}
std::optional<MigrationData> res = legacy_spkm->MigrateToDescriptor();
if (res == std::nullopt) {
@ -4691,8 +4695,9 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
AssertLockHeld(cs_wallet);
LegacyScriptPubKeyMan* legacy_spkm = GetLegacyScriptPubKeyMan();
if (!legacy_spkm) {
error = _("Error: This wallet is already a descriptor wallet");
if (!Assume(legacy_spkm)) {
// This shouldn't happen
error = Untranslated(STR_INTERNAL_BUG("Error: Legacy wallet data missing"));
return false;
}
@ -5027,7 +5032,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
}
// Before anything else, check if there is something to migrate.
if (!local_wallet->GetLegacyScriptPubKeyMan()) {
if (local_wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
return util::Error{_("Error: This wallet is already a descriptor wallet")};
}
@ -5060,8 +5065,11 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
// First change to using SQLite
if (!local_wallet->MigrateToSQLite(error)) return util::Error{error};
// Do the migration, and cleanup if it fails
success = DoMigration(*local_wallet, context, error, res);
// Do the migration of keys and scripts for non-blank wallets, and cleanup if it fails
success = local_wallet->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET);
if (!success) {
success = DoMigration(*local_wallet, context, error, res);
}
}
// In case of reloading failure, we need to remember the wallet dirs to remove

View file

@ -53,13 +53,12 @@ class WalletMigrationTest(BitcoinTestFramework):
assert_equal(file_magic, b'SQLite format 3\x00')
assert_equal(self.nodes[0].get_wallet_rpc(wallet_name).getwalletinfo()["format"], "sqlite")
def create_legacy_wallet(self, wallet_name, disable_private_keys=False):
self.nodes[0].createwallet(wallet_name=wallet_name, descriptors=False, disable_private_keys=disable_private_keys)
def create_legacy_wallet(self, wallet_name, **kwargs):
self.nodes[0].createwallet(wallet_name=wallet_name, descriptors=False, **kwargs)
wallet = self.nodes[0].get_wallet_rpc(wallet_name)
info = wallet.getwalletinfo()
assert_equal(info["descriptors"], False)
assert_equal(info["format"], "bdb")
assert_equal(info["private_keys_enabled"], not disable_private_keys)
return wallet
def assert_addr_info_equal(self, addr_info, addr_info_old):
@ -885,6 +884,13 @@ class WalletMigrationTest(BitcoinTestFramework):
_, _, magic = struct.unpack("QII", data)
assert_equal(magic, BTREE_MAGIC)
def test_blank(self):
self.log.info("Test that a blank wallet is migrated")
wallet = self.create_legacy_wallet("blank", blank=True)
assert_equal(wallet.getwalletinfo()["blank"], True)
wallet.migratewallet()
assert_equal(wallet.getwalletinfo()["blank"], True)
def test_avoidreuse(self):
self.log.info("Test that avoidreuse persists after migration")
@ -996,6 +1002,7 @@ class WalletMigrationTest(BitcoinTestFramework):
self.test_failed_migration_cleanup()
self.test_avoidreuse()
self.test_preserve_tx_extra_info()
self.test_blank()
if __name__ == '__main__':
WalletMigrationTest().main()