Repository: bitcoin/bitcoin
File: test/functional/wallet_migration.py (Python)

Code before:

        # Check that old node can restore from the backup.
        self.old_node.restorewallet("relative_restored", migrate_res['backup_path'])
        wallet = self.old_node.get_wallet_rpc("relative_restored")
        assert wallet.gettransaction(txid)
        assert_equal(bals, wallet.getbalances())

        info = wallet.getwalletinfo()
        assert_equal(info["descriptors"], False)
        assert_equal(info["format"], "bdb")

    def test_default_wallet(self):
        self.log.info("Test migration of the wallet named as the empty string")
        wallet = self.create_legacy_wallet("")

        # Set time to verify backup existence later
        curr_time = int(time.time())
        self.master_node.setmocktime(curr_time)

        res, wallet = self.migrate_and_get_rpc("")
        self.master_node.setmocktime(0)
        info = wallet.getwalletinfo()
        assert_equal(info["descriptors"], True)
        assert_equal(info["format"], "sqlite")

        walletdir_list = wallet.listwalletdir()
        assert {"name": info["walletname"]} in walletdir_list["wallets"]

        # Check backup existence and its non-empty wallet filename
        backup_filename = f"default_wallet_{curr_time}.legacy.bak"
        backup_path = self.master_node.wallets_path / backup_filename
        assert backup_path.exists()
        assert_equal(str(backup_path), res['backup_path'])
        assert {"name": backup_filename} not in walletdir_list["wallets"]

        self.master_node.setmocktime(0)

    def test_direct_file(self):
        self.log.info("Test migration of a wallet that is not in a wallet directory")
        wallet = self.create_legacy_wallet("plainfile")
        wallet.unloadwallet()

        shutil.copyfile(
            self.old_node.wallets_path / "plainfile" / "wallet.dat" ,
            self.master_node.wallets_path / "plainfile"
        )
        assert (self.master_node.wallets_path / "plainfile").is_file()

        self.master_node.migratewallet("plainfile")
        wallet = self.master_node.get_wallet_rpc("plainfile")
        info = wallet.getwalletinfo()

Review comment (bug):
Can we add more stricter checks on the transaction received here.

For example:
```
tx = wallet.gettransaction(txid)
assert_equal(tx["amount"], 1)
assert_equal(tx["confirmations"], 1)
```
This gives you tighter guarantees and helps with debugging if the test fails.

Code after:
        bals = wallet.getbalances()

        # migratewallet uses current time in naming the backup file, set a mock time
        # to check that this works correctly.
        curr_time = int(time.time())
        self.master_node.setmocktime(curr_time)
        migrate_res, wallet = self.migrate_and_get_rpc(relative_name)
        self.master_node.setmocktime(0)

        # Check that the wallet was migrated, knows the right txid, and has the right balance.
        assert wallet.gettransaction(txid)
        assert_equal(bals, wallet.getbalances())

        # The migrated wallet should not be in the wallet dir, but should be in the list of wallets.
        info = wallet.getwalletinfo()

        walletdirlist = wallet.listwalletdir()
        assert {"name": info["walletname"]} not in walletdirlist["wallets"]

        walletlist = wallet.listwallets()
        assert info["walletname"] in walletlist

        # Check that old node can restore from the backup.
        self.old_node.restorewallet("relative_restored", migrate_res['backup_path'])
        wallet = self.old_node.get_wallet_rpc("relative_restored")
        assert wallet.gettransaction(txid)
        assert_equal(bals, wallet.getbalances())

        info = wallet.getwalletinfo()
        assert_equal(info["descriptors"], False)
        assert_equal(info["format"], "bdb")

    def test_wallet_with_path_ending_in_slash(self):
        self.log.info("Test migrating a wallet with a name/path ending in '/'")

        # The last directory in the wallet's path
        final_dir = "mywallet"
        wallet_name = f"path/to/{final_dir}/"
        wallet = self.create_legacy_wallet(wallet_name)
        default = self.master_node.get_wallet_rpc(self.default_wallet_name)

        addr = wallet.getnewaddress()
        txid = default.sendtoaddress(addr, 1)
        self.generate(self.master_node, 1)
        bals = wallet.getbalances()

        _, wallet = self.migrate_and_get_rpc(wallet_name)

        assert wallet.gettransaction(txid)

        assert_equal(bals, wallet.getbalances())