diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index 20e92dbef73..0610f109665 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -60,6 +60,18 @@ class WalletMigrationTest(BitcoinTestFramework): assert_equal(info["format"], "bdb") return wallet + def migrate_wallet(self, wallet_rpc, *args, **kwargs): + # Helper to ensure that only migration happens + # Since we may rescan on loading of a wallet, make sure that the best block + # is written before beginning migration + # Reload to force write that record + wallet_name = wallet_rpc.getwalletinfo()["walletname"] + wallet_rpc.unloadwallet() + self.nodes[0].loadwallet(wallet_name) + # Migrate, checking that rescan does not occur + with self.nodes[0].assert_debug_log(expected_msgs=[], unexpected_msgs=["Rescanning"]): + return wallet_rpc.migratewallet(*args, **kwargs) + def assert_addr_info_equal(self, addr_info, addr_info_old): assert_equal(addr_info["address"], addr_info_old["address"]) assert_equal(addr_info["scriptPubKey"], addr_info_old["scriptPubKey"]) @@ -104,7 +116,7 @@ class WalletMigrationTest(BitcoinTestFramework): assert_equal(old_change_addr_info["hdkeypath"], "m/0'/1'/0'") # Note: migration could take a while. - basic0.migratewallet() + self.migrate_wallet(basic0) # Verify created descriptors assert_equal(basic0.getwalletinfo()["descriptors"], True) @@ -145,7 +157,7 @@ class WalletMigrationTest(BitcoinTestFramework): txs = basic1.listtransactions() addr_gps = basic1.listaddressgroupings() - basic1_migrate = basic1.migratewallet() + basic1_migrate = self.migrate_wallet(basic1) assert_equal(basic1.getwalletinfo()["descriptors"], True) self.assert_is_sqlite("basic1") assert_equal(basic1.getbalance(), bal) @@ -186,7 +198,7 @@ class WalletMigrationTest(BitcoinTestFramework): basic2_txs = basic2.listtransactions() # Now migrate and test that we still see have the same balance/transactions - basic2.migratewallet() + self.migrate_wallet(basic2) assert_equal(basic2.getwalletinfo()["descriptors"], True) self.assert_is_sqlite("basic2") assert_equal(basic2.getbalance(), basic2_balance) @@ -208,7 +220,7 @@ class WalletMigrationTest(BitcoinTestFramework): ms_info = multisig0.addmultisigaddress(2, [addr1, addr2, addr3]) - multisig0.migratewallet() + self.migrate_wallet(multisig0) assert_equal(multisig0.getwalletinfo()["descriptors"], True) self.assert_is_sqlite("multisig0") ms_addr_info = multisig0.getaddressinfo(ms_info["address"]) @@ -243,7 +255,7 @@ class WalletMigrationTest(BitcoinTestFramework): # Migrating multisig1 should see the multisig is no longer part of multisig1 # A new wallet multisig1_watchonly is created which has the multisig address # Transaction to multisig is in multisig1_watchonly and not multisig1 - multisig1.migratewallet() + self.migrate_wallet(multisig1) assert_equal(multisig1.getwalletinfo()["descriptors"], True) self.assert_is_sqlite("multisig1") assert_equal(multisig1.getaddressinfo(addr1)["ismine"], False) @@ -326,7 +338,7 @@ class WalletMigrationTest(BitcoinTestFramework): self.nodes[0].setmocktime(int(time.time()) + 100) # Migrate - imports0.migratewallet() + self.migrate_wallet(imports0) assert_equal(imports0.getwalletinfo()["descriptors"], True) self.assert_is_sqlite("imports0") assert_raises_rpc_error(-5, "Invalid or non-wallet transaction id", imports0.gettransaction, received_watchonly_txid) @@ -379,7 +391,7 @@ class WalletMigrationTest(BitcoinTestFramework): default.sendtoaddress(addr, 10) self.generate(self.nodes[0], 1) - watchonly0.migratewallet() + self.migrate_wallet(watchonly0) assert_equal("watchonly0_watchonly" in self.nodes[0].listwallets(), False) info = watchonly0.getwalletinfo() assert_equal(info["descriptors"], True) @@ -411,7 +423,7 @@ class WalletMigrationTest(BitcoinTestFramework): # Before migrating, we can fetch addr1 from the keypool assert_equal(watchonly1.getnewaddress(address_type="bech32"), addr1) - watchonly1.migratewallet() + self.migrate_wallet(watchonly1) info = watchonly1.getwalletinfo() assert_equal(info["descriptors"], True) assert_equal(info["private_keys_enabled"], False) @@ -431,7 +443,7 @@ class WalletMigrationTest(BitcoinTestFramework): bals = wallet.getbalances() - wallet.migratewallet() + self.migrate_wallet(wallet) assert_equal(bals, wallet.getbalances()) @@ -450,7 +462,7 @@ class WalletMigrationTest(BitcoinTestFramework): assert_raises_rpc_error(-4, "Error: Wallet decryption failed, the wallet passphrase was not provided or was incorrect", wallet.migratewallet, None, "badpass") assert_raises_rpc_error(-4, "The passphrase contains a null character", wallet.migratewallet, None, "pass\0with\0null") - wallet.migratewallet(passphrase="pass") + self.migrate_wallet(wallet, passphrase="pass") info = wallet.getwalletinfo() assert_equal(info["descriptors"], True) @@ -512,7 +524,7 @@ class WalletMigrationTest(BitcoinTestFramework): self.log.info("Test migration of the wallet named as the empty string") wallet = self.create_legacy_wallet("") - wallet.migratewallet() + self.migrate_wallet(wallet) info = wallet.getwalletinfo() assert_equal(info["descriptors"], True) assert_equal(info["format"], "sqlite") @@ -534,7 +546,7 @@ class WalletMigrationTest(BitcoinTestFramework): assert_equal(info["descriptors"], False) assert_equal(info["format"], "bdb") - wallet.migratewallet() + self.migrate_wallet(wallet) info = wallet.getwalletinfo() assert_equal(info["descriptors"], True) assert_equal(info["format"], "sqlite") @@ -622,7 +634,7 @@ class WalletMigrationTest(BitcoinTestFramework): check(addr_info, wallet) # Migrate wallet - info_migration = wallet.migratewallet() + info_migration = self.migrate_wallet(wallet) wallet_wo = self.nodes[0].get_wallet_rpc(info_migration["watchonly_name"]) wallet_solvables = self.nodes[0].get_wallet_rpc(info_migration["solvables_name"]) @@ -717,7 +729,7 @@ class WalletMigrationTest(BitcoinTestFramework): wallet.rpc.importaddress(address=script_sh_pkh.hex(), label=label_sh_pkh, rescan=False, p2sh=True) # Migrate wallet and re-check balance - info_migration = wallet.migratewallet() + info_migration = self.migrate_wallet(wallet) wallet_wo = self.nodes[0].get_wallet_rpc(info_migration["watchonly_name"]) # Watch-only balance is under "mine". @@ -780,7 +792,7 @@ class WalletMigrationTest(BitcoinTestFramework): assert_equal(wallet.gettransaction(txid=child_txid)["confirmations"], -1) assert_equal(wallet.gettransaction(txid=conflict_txid)["confirmations"], 1) - wallet.migratewallet() + self.migrate_wallet(wallet) assert_equal(wallet.gettransaction(txid=parent_txid)["confirmations"], -1) assert_equal(wallet.gettransaction(txid=child_txid)["confirmations"], -1) assert_equal(wallet.gettransaction(txid=conflict_txid)["confirmations"], 1) @@ -813,7 +825,7 @@ class WalletMigrationTest(BitcoinTestFramework): p2wpkh_addr = key_to_p2wpkh(hybrid_pubkey) wallet.importaddress(p2wpkh_addr) - migrate_info = wallet.migratewallet() + migrate_info = self.migrate_wallet(wallet) # Both addresses should only appear in the watchonly wallet p2pkh_addr_info = wallet.getaddressinfo(p2pkh_addr)