Skip to content

Commit

Permalink
test: add coverage for re-opening a downgraded encrypted wallet on ma…
Browse files Browse the repository at this point in the history
…ster

The test creates a wallet on master, downgrades and encrypts the wallet.
Then, it tries to open it again on master.
  • Loading branch information
furszy authored and achow101 committed Dec 11, 2023
1 parent cb79d9a commit 522894b
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions test/functional/wallet_backwards_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,66 @@ def test_v19_addmultisigaddress(self):
wallet = node_v19.get_wallet_rpc("w1_v19")
assert wallet.getaddressinfo(address_18075)["solvable"]

def test_downgrade_encryption(self, node_master, descriptors_nodes, legacy_nodes):
self.log.info("Test downgrade encryption + re-open on master")

# Create wallet on master, downgrade and encrypt the wallet. Then, try to open it again on master.
name_wallet_on_master = "new_wallet"
node_master.createwallet(name_wallet_on_master, descriptors=self.options.descriptors)
wallet_on_master = node_master.get_wallet_rpc(name_wallet_on_master)

# Retrieve the wallet's xpub
xpub = wallet_on_master.gethdkey()["xpub"]

# Make a backup of the wallet file
backup_path = os.path.join(self.options.tmpdir, f"{name_wallet_on_master}.dat")
wallet_on_master.backupwallet(backup_path)

# Downgrade and encrypt the wallet.
for node in descriptors_nodes if self.options.descriptors else legacy_nodes:
if self.major_version_less_than(node, 22):
continue # cannot downgrade further than v22, tr() descriptors aren't supported.

# Load wallet in the prev node
target_dir = node.wallets_path / name_wallet_on_master
os.makedirs(target_dir, exist_ok=True)
shutil.copyfile(backup_path, target_dir / "wallet.dat")
node.loadwallet(name_wallet_on_master)
wallet_prev = node.get_wallet_rpc(name_wallet_on_master)

# Encrypt wallet in the prev node
wallet_prev.encryptwallet("pass")
wallet_info = wallet_prev.getwalletinfo()

# Restart prev node and verify it can reopen the wallet
self.restart_node(node.index, extra_args=[f"-wallet={name_wallet_on_master}"])
wallet_prev = node.get_wallet_rpc(name_wallet_on_master)
assert_equal(wallet_info, wallet_prev.getwalletinfo())
# And also it can decrypt the wallet
wallet_prev.walletpassphrase("pass", 999999)

# Finally, export the encrypted prev node wallet, and re-open it on master
exported_name = f'{name_wallet_on_master}_{node.index}'
prev_backup_path = os.path.join(self.options.tmpdir, f"{exported_name}.dat")
wallet_prev.backupwallet(prev_backup_path)

# Re-open it on master and decrypt the wallet
node_master.restorewallet(exported_name, prev_backup_path)
enc_wallet = node_master.get_wallet_rpc(exported_name)
enc_wallet.walletpassphrase("pass", 999999)
assert 'unlocked_until' in enc_wallet.getwalletinfo()

# Check that the xpub is different
assert xpub != enc_wallet.gethdkey()["xpub"]

# remove backup file
os.remove(prev_backup_path)
wallet_prev.unloadwallet()
enc_wallet.unloadwallet()

# Clean wallet
wallet_on_master.unloadwallet()

def run_test(self):
node_miner = self.nodes[0]
node_master = self.nodes[1]
Expand Down Expand Up @@ -305,6 +365,9 @@ def run_test(self):
self.log.info("Test that 0.21 cannot open wallet containing tr() descriptors")
assert_raises_rpc_error(-1, "map::at", node_v21.loadwallet, "w1")

# Test encryption on a previous version + reopen on master
self.test_downgrade_encryption(node_master, descriptors_nodes, legacy_nodes)

self.log.info("Test that a wallet can upgrade to and downgrade from master, from:")
for node in descriptors_nodes if self.options.descriptors else legacy_nodes:
# Run twice for each node to also test encrypted wallets
Expand Down

0 comments on commit 522894b

Please sign in to comment.