Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_backup.py
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | def setup_network(self): | ||||
self.setup_nodes() | self.setup_nodes() | ||||
self.connect_nodes(0, 3) | self.connect_nodes(0, 3) | ||||
self.connect_nodes(1, 3) | self.connect_nodes(1, 3) | ||||
self.connect_nodes(2, 3) | self.connect_nodes(2, 3) | ||||
self.connect_nodes(2, 0) | self.connect_nodes(2, 0) | ||||
self.sync_all() | self.sync_all() | ||||
def one_send(self, from_node, to_address): | def one_send(self, from_node, to_address): | ||||
if (randint(1, 2) == 1): | if randint(1, 2) == 1: | ||||
amount = Decimal(randint(1, 10)) * Decimal(100000) | amount = Decimal(randint(1, 10)) * Decimal(100000) | ||||
self.nodes[from_node].sendtoaddress(to_address, amount) | self.nodes[from_node].sendtoaddress(to_address, amount) | ||||
def do_one_round(self): | def do_one_round(self): | ||||
a0 = self.nodes[0].getnewaddress() | a0 = self.nodes[0].getnewaddress() | ||||
a1 = self.nodes[1].getnewaddress() | a1 = self.nodes[1].getnewaddress() | ||||
a2 = self.nodes[2].getnewaddress() | a2 = self.nodes[2].getnewaddress() | ||||
Show All 21 Lines | class WalletBackupTest(BitcoinTestFramework): | ||||
def stop_three(self): | def stop_three(self): | ||||
self.stop_node(0) | self.stop_node(0) | ||||
self.stop_node(1) | self.stop_node(1) | ||||
self.stop_node(2) | self.stop_node(2) | ||||
def erase_three(self): | def erase_three(self): | ||||
os.remove( | os.remove( | ||||
os.path.join(self.nodes[0].datadir, self.chain, 'wallets', | os.path.join( | ||||
self.default_wallet_name, self.wallet_data_filename)) | self.nodes[0].datadir, | ||||
self.chain, | |||||
"wallets", | |||||
self.default_wallet_name, | |||||
self.wallet_data_filename, | |||||
) | |||||
) | |||||
os.remove( | os.remove( | ||||
os.path.join(self.nodes[1].datadir, self.chain, 'wallets', | os.path.join( | ||||
self.default_wallet_name, self.wallet_data_filename)) | self.nodes[1].datadir, | ||||
self.chain, | |||||
"wallets", | |||||
self.default_wallet_name, | |||||
self.wallet_data_filename, | |||||
) | |||||
) | |||||
os.remove( | os.remove( | ||||
os.path.join(self.nodes[2].datadir, self.chain, 'wallets', | os.path.join( | ||||
self.default_wallet_name, self.wallet_data_filename)) | self.nodes[2].datadir, | ||||
self.chain, | |||||
"wallets", | |||||
self.default_wallet_name, | |||||
self.wallet_data_filename, | |||||
) | |||||
) | |||||
def restore_nonexistent_wallet(self): | def restore_nonexistent_wallet(self): | ||||
node = self.nodes[3] | node = self.nodes[3] | ||||
nonexistent_wallet_file = os.path.join( | nonexistent_wallet_file = os.path.join( | ||||
self.nodes[0].datadir, 'nonexistent_wallet.bak') | self.nodes[0].datadir, "nonexistent_wallet.bak" | ||||
) | |||||
wallet_name = "res0" | wallet_name = "res0" | ||||
assert_raises_rpc_error(-8, | assert_raises_rpc_error( | ||||
-8, | |||||
"Backup file does not exist", | "Backup file does not exist", | ||||
node.restorewallet, | node.restorewallet, | ||||
wallet_name, | wallet_name, | ||||
nonexistent_wallet_file) | nonexistent_wallet_file, | ||||
) | |||||
def restore_wallet_existent_name(self): | def restore_wallet_existent_name(self): | ||||
node = self.nodes[3] | node = self.nodes[3] | ||||
wallet_file = os.path.join(self.nodes[0].datadir, 'wallet.bak') | wallet_file = os.path.join(self.nodes[0].datadir, "wallet.bak") | ||||
wallet_name = "res0" | wallet_name = "res0" | ||||
assert_raises_rpc_error(-8, | assert_raises_rpc_error( | ||||
-8, | |||||
"Wallet name already exists.", | "Wallet name already exists.", | ||||
node.restorewallet, | node.restorewallet, | ||||
wallet_name, | wallet_name, | ||||
wallet_file) | wallet_file, | ||||
) | |||||
def run_test(self): | def run_test(self): | ||||
self.log.info("Generating initial blockchain") | self.log.info("Generating initial blockchain") | ||||
self.generate(self.nodes[0], 1) | self.generate(self.nodes[0], 1) | ||||
self.generate(self.nodes[1], 1) | self.generate(self.nodes[1], 1) | ||||
self.generate(self.nodes[2], 1) | self.generate(self.nodes[2], 1) | ||||
self.generate(self.nodes[3], 100) | self.generate(self.nodes[3], 100) | ||||
assert_equal(self.nodes[0].getbalance(), 50000000) | assert_equal(self.nodes[0].getbalance(), 50000000) | ||||
assert_equal(self.nodes[1].getbalance(), 50000000) | assert_equal(self.nodes[1].getbalance(), 50000000) | ||||
assert_equal(self.nodes[2].getbalance(), 50000000) | assert_equal(self.nodes[2].getbalance(), 50000000) | ||||
assert_equal(self.nodes[3].getbalance(), 0) | assert_equal(self.nodes[3].getbalance(), 0) | ||||
self.log.info("Creating transactions") | self.log.info("Creating transactions") | ||||
# Five rounds of sending each other transactions. | # Five rounds of sending each other transactions. | ||||
for _ in range(5): | for _ in range(5): | ||||
self.do_one_round() | self.do_one_round() | ||||
self.log.info("Backing up") | self.log.info("Backing up") | ||||
self.nodes[0].backupwallet(os.path.join( | self.nodes[0].backupwallet(os.path.join(self.nodes[0].datadir, "wallet.bak")) | ||||
self.nodes[0].datadir, 'wallet.bak')) | self.nodes[0].dumpwallet(os.path.join(self.nodes[0].datadir, "wallet.dump")) | ||||
self.nodes[0].dumpwallet(os.path.join( | self.nodes[1].backupwallet(os.path.join(self.nodes[1].datadir, "wallet.bak")) | ||||
self.nodes[0].datadir, 'wallet.dump')) | self.nodes[1].dumpwallet(os.path.join(self.nodes[1].datadir, "wallet.dump")) | ||||
self.nodes[1].backupwallet(os.path.join( | self.nodes[2].backupwallet(os.path.join(self.nodes[2].datadir, "wallet.bak")) | ||||
self.nodes[1].datadir, 'wallet.bak')) | self.nodes[2].dumpwallet(os.path.join(self.nodes[2].datadir, "wallet.dump")) | ||||
self.nodes[1].dumpwallet(os.path.join( | |||||
self.nodes[1].datadir, 'wallet.dump')) | |||||
self.nodes[2].backupwallet(os.path.join( | |||||
self.nodes[2].datadir, 'wallet.bak')) | |||||
self.nodes[2].dumpwallet(os.path.join( | |||||
self.nodes[2].datadir, 'wallet.dump')) | |||||
self.log.info("More transactions") | self.log.info("More transactions") | ||||
for _ in range(5): | for _ in range(5): | ||||
self.do_one_round() | self.do_one_round() | ||||
# Generate 101 more blocks, so any fees paid mature | # Generate 101 more blocks, so any fees paid mature | ||||
self.generate(self.nodes[3], 101) | self.generate(self.nodes[3], 101) | ||||
Show All 9 Lines | def run_test(self): | ||||
## | ## | ||||
# Test restoring spender wallets from backups | # Test restoring spender wallets from backups | ||||
## | ## | ||||
self.log.info("Restoring wallets on node 3 using backup files") | self.log.info("Restoring wallets on node 3 using backup files") | ||||
self.restore_nonexistent_wallet() | self.restore_nonexistent_wallet() | ||||
backup_file_0 = os.path.join(self.nodes[0].datadir, 'wallet.bak') | backup_file_0 = os.path.join(self.nodes[0].datadir, "wallet.bak") | ||||
backup_file_1 = os.path.join(self.nodes[1].datadir, 'wallet.bak') | backup_file_1 = os.path.join(self.nodes[1].datadir, "wallet.bak") | ||||
backup_file_2 = os.path.join(self.nodes[2].datadir, 'wallet.bak') | backup_file_2 = os.path.join(self.nodes[2].datadir, "wallet.bak") | ||||
self.nodes[3].restorewallet("res0", backup_file_0) | self.nodes[3].restorewallet("res0", backup_file_0) | ||||
self.nodes[3].restorewallet("res1", backup_file_1) | self.nodes[3].restorewallet("res1", backup_file_1) | ||||
self.nodes[3].restorewallet("res2", backup_file_2) | self.nodes[3].restorewallet("res2", backup_file_2) | ||||
res0_rpc = self.nodes[3].get_wallet_rpc("res0") | res0_rpc = self.nodes[3].get_wallet_rpc("res0") | ||||
res1_rpc = self.nodes[3].get_wallet_rpc("res1") | res1_rpc = self.nodes[3].get_wallet_rpc("res1") | ||||
res2_rpc = self.nodes[3].get_wallet_rpc("res2") | res2_rpc = self.nodes[3].get_wallet_rpc("res2") | ||||
assert_equal(res0_rpc.getbalance(), balance0) | assert_equal(res0_rpc.getbalance(), balance0) | ||||
assert_equal(res1_rpc.getbalance(), balance1) | assert_equal(res1_rpc.getbalance(), balance1) | ||||
assert_equal(res2_rpc.getbalance(), balance2) | assert_equal(res2_rpc.getbalance(), balance2) | ||||
self.restore_wallet_existent_name() | self.restore_wallet_existent_name() | ||||
self.log.info("Restoring using dumped wallet") | self.log.info("Restoring using dumped wallet") | ||||
self.stop_three() | self.stop_three() | ||||
self.erase_three() | self.erase_three() | ||||
# start node2 with no chain | # start node2 with no chain | ||||
shutil.rmtree( | shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, "blocks")) | ||||
os.path.join( | shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, "chainstate")) | ||||
self.nodes[2].datadir, | |||||
self.chain, | |||||
'blocks')) | |||||
shutil.rmtree(os.path.join( | |||||
self.nodes[2].datadir, self.chain, 'chainstate')) | |||||
self.start_three() | self.start_three() | ||||
assert_equal(self.nodes[0].getbalance(), 0) | assert_equal(self.nodes[0].getbalance(), 0) | ||||
assert_equal(self.nodes[1].getbalance(), 0) | assert_equal(self.nodes[1].getbalance(), 0) | ||||
assert_equal(self.nodes[2].getbalance(), 0) | assert_equal(self.nodes[2].getbalance(), 0) | ||||
self.nodes[0].importwallet(os.path.join( | self.nodes[0].importwallet(os.path.join(self.nodes[0].datadir, "wallet.dump")) | ||||
self.nodes[0].datadir, 'wallet.dump')) | self.nodes[1].importwallet(os.path.join(self.nodes[1].datadir, "wallet.dump")) | ||||
self.nodes[1].importwallet(os.path.join( | self.nodes[2].importwallet(os.path.join(self.nodes[2].datadir, "wallet.dump")) | ||||
self.nodes[1].datadir, 'wallet.dump')) | |||||
self.nodes[2].importwallet(os.path.join( | |||||
self.nodes[2].datadir, 'wallet.dump')) | |||||
self.sync_blocks() | self.sync_blocks() | ||||
assert_equal(self.nodes[0].getbalance(), balance0) | assert_equal(self.nodes[0].getbalance(), balance0) | ||||
assert_equal(self.nodes[1].getbalance(), balance1) | assert_equal(self.nodes[1].getbalance(), balance1) | ||||
assert_equal(self.nodes[2].getbalance(), balance2) | assert_equal(self.nodes[2].getbalance(), balance2) | ||||
# Backup to source wallet file must fail | # Backup to source wallet file must fail | ||||
sourcePaths = [ | sourcePaths = [ | ||||
os.path.join(self.nodes[0].datadir, self.chain, 'wallets', | os.path.join( | ||||
self.default_wallet_name, self.wallet_data_filename), | self.nodes[0].datadir, | ||||
os.path.join(self.nodes[0].datadir, self.chain, '.', 'wallets', | self.chain, | ||||
self.default_wallet_name, self.wallet_data_filename), | "wallets", | ||||
os.path.join(self.nodes[0].datadir, self.chain, 'wallets', | self.default_wallet_name, | ||||
self.default_wallet_name), | self.wallet_data_filename, | ||||
os.path.join(self.nodes[0].datadir, self.chain, 'wallets')] | ), | ||||
os.path.join( | |||||
self.nodes[0].datadir, | |||||
self.chain, | |||||
".", | |||||
"wallets", | |||||
self.default_wallet_name, | |||||
self.wallet_data_filename, | |||||
), | |||||
os.path.join( | |||||
self.nodes[0].datadir, self.chain, "wallets", self.default_wallet_name | |||||
), | |||||
os.path.join(self.nodes[0].datadir, self.chain, "wallets"), | |||||
] | |||||
for sourcePath in sourcePaths: | for sourcePath in sourcePaths: | ||||
assert_raises_rpc_error(-4, "backup failed", | assert_raises_rpc_error( | ||||
self.nodes[0].backupwallet, sourcePath) | -4, "backup failed", self.nodes[0].backupwallet, sourcePath | ||||
) | |||||
if __name__ == '__main__': | if __name__ == "__main__": | ||||
WalletBackupTest().main() | WalletBackupTest().main() |