mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-18 22:35:39 +01:00
test: restorewallet, coverage for existing dirs, unnamed wallet and prune failure
The first test verifies that restoring into an existing empty directory
or a directory with no .dat db files succeeds, while restoring into a
dir with a .dat file fails.
The second test covers restoring into the default unnamed wallet
(wallet.dat), which also implicitly exercises the recovery path used
after a failed migration.
The third test covers failure during restore on a prune node. When
the wallet last sync was beyond the pruning height.
Github-Pull: #34156
Rebased-From: f011e0f068
This commit is contained in:
@@ -39,6 +39,7 @@ from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_rpc_error,
|
||||
sha256sum_file,
|
||||
)
|
||||
|
||||
|
||||
@@ -136,6 +137,61 @@ class WalletBackupTest(BitcoinTestFramework):
|
||||
assert_raises_rpc_error(-36, error_message, node.restorewallet, wallet_name, backup_file)
|
||||
assert wallet_file.exists()
|
||||
|
||||
def test_restore_existent_dir(self):
|
||||
self.log.info("Test restore on an existent empty directory")
|
||||
node = self.nodes[3]
|
||||
backup_file = self.nodes[0].datadir_path / 'wallet.bak'
|
||||
wallet_name = "restored_wallet"
|
||||
wallet_dir = node.wallets_path / wallet_name
|
||||
os.mkdir(wallet_dir)
|
||||
res = node.restorewallet(wallet_name, backup_file)
|
||||
assert_equal(res['name'], wallet_name)
|
||||
node.unloadwallet(wallet_name)
|
||||
|
||||
self.log.info("Test restore succeeds when the target directory contains non-wallet files")
|
||||
wallet_file = node.wallets_path / wallet_name / "wallet.dat"
|
||||
os.remove(wallet_file)
|
||||
extra_file = node.wallets_path / wallet_name / "not_a_wallet.txt"
|
||||
extra_file.touch()
|
||||
res = node.restorewallet(wallet_name, backup_file)
|
||||
assert_equal(res['name'], wallet_name)
|
||||
assert extra_file.exists() # extra file was not removed by mistake
|
||||
node.unloadwallet(wallet_name)
|
||||
|
||||
self.log.info("Test restore failure due to existing db file in the destination directory")
|
||||
original_shasum = sha256sum_file(wallet_file)
|
||||
error_message = "Failed to restore wallet. Database file exists in '{}'.".format(wallet_dir / "wallet.dat")
|
||||
assert_raises_rpc_error(-36, error_message, node.restorewallet, wallet_name, backup_file)
|
||||
# Ensure the wallet file remains untouched
|
||||
assert wallet_dir.exists()
|
||||
assert_equal(original_shasum, sha256sum_file(wallet_file))
|
||||
|
||||
self.log.info("Test restore succeeds when the .dat file in the destination has a different name")
|
||||
second_wallet = wallet_dir / "hidden_storage.dat"
|
||||
os.rename(wallet_dir / "wallet.dat", second_wallet)
|
||||
original_shasum = sha256sum_file(second_wallet)
|
||||
res = node.restorewallet(wallet_name, backup_file)
|
||||
assert_equal(res['name'], wallet_name)
|
||||
assert (wallet_dir / "hidden_storage.dat").exists()
|
||||
assert_equal(original_shasum, sha256sum_file(second_wallet))
|
||||
node.unloadwallet(wallet_name)
|
||||
|
||||
# Clean for follow-up tests
|
||||
os.remove(wallet_file)
|
||||
|
||||
def test_restore_into_unnamed_wallet(self):
|
||||
self.log.info("Test restore into a default unnamed wallet")
|
||||
# This is also useful to test the migration recovery after failure logic
|
||||
node = self.nodes[3]
|
||||
backup_file = self.nodes[0].datadir_path / 'wallet.bak'
|
||||
wallet_name = ""
|
||||
res = node.restorewallet(wallet_name, backup_file)
|
||||
assert_equal(res['name'], "")
|
||||
assert (node.wallets_path / "wallet.dat").exists()
|
||||
# Clean for follow-up tests
|
||||
node.unloadwallet("")
|
||||
os.remove(node.wallets_path / "wallet.dat")
|
||||
|
||||
def test_pruned_wallet_backup(self):
|
||||
self.log.info("Test loading backup on a pruned node when the backup was created close to the prune height of the restoring node")
|
||||
node = self.nodes[3]
|
||||
@@ -155,6 +211,13 @@ class WalletBackupTest(BitcoinTestFramework):
|
||||
# the backup to load successfully this close to the prune height
|
||||
node.restorewallet('pruned', node.datadir_path / 'wallet_pruned.bak')
|
||||
|
||||
self.log.info("Test restore on a pruned node when the backup was beyond the pruning point")
|
||||
backup_file = self.nodes[0].datadir_path / 'wallet.bak'
|
||||
wallet_name = ""
|
||||
error_message = "Wallet loading failed. Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of a pruned node)"
|
||||
assert_raises_rpc_error(-4, error_message, node.restorewallet, wallet_name, backup_file)
|
||||
assert node.wallets_path.exists() # ensure the wallets dir exists
|
||||
|
||||
def run_test(self):
|
||||
self.log.info("Generating initial blockchain")
|
||||
self.generate(self.nodes[0], 1)
|
||||
@@ -219,6 +282,8 @@ class WalletBackupTest(BitcoinTestFramework):
|
||||
assert_equal(res2_rpc.getbalance(), balance2)
|
||||
|
||||
self.restore_wallet_existent_name()
|
||||
self.test_restore_existent_dir()
|
||||
self.test_restore_into_unnamed_wallet()
|
||||
|
||||
# Backup to source wallet file must fail
|
||||
sourcePaths = [
|
||||
|
||||
Reference in New Issue
Block a user