Skip to content

Commit 37d9cc6

Browse files
furszyfanquake
authored andcommitted
test: wallet, add coverage for addressbook migration
Github-Pull: bitcoin#28038 Rebased-From: 7ecc29a
1 parent 4b16650 commit 37d9cc6

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

test/functional/wallet_migration.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ def assert_list_txs_equal(self, received_list_txs, expected_list_txs):
6767
del d["parent_descs"]
6868
assert_equal(received_list_txs, expected_list_txs)
6969

70+
def check_address(self, wallet, addr, is_mine, is_change, label):
71+
addr_info = wallet.getaddressinfo(addr)
72+
assert_equal(addr_info['ismine'], is_mine)
73+
assert_equal(addr_info['ischange'], is_change)
74+
if label is not None:
75+
assert_equal(addr_info['labels'], [label]),
76+
else:
77+
assert_equal(addr_info['labels'], []),
78+
7079
def test_basic(self):
7180
default = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
7281

@@ -470,6 +479,132 @@ def test_unloaded_by_path(self):
470479

471480
assert_equal(bals, wallet.getbalances())
472481

482+
def test_addressbook(self):
483+
df_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
484+
485+
self.log.info("Test migration of address book data")
486+
wallet = self.create_legacy_wallet("legacy_addrbook")
487+
df_wallet.sendtoaddress(wallet.getnewaddress(), 3)
488+
489+
# Import watch-only script to create a watch-only wallet after migration
490+
watch_addr = df_wallet.getnewaddress()
491+
wallet.importaddress(watch_addr)
492+
df_wallet.sendtoaddress(watch_addr, 2)
493+
494+
# Import solvable script
495+
multi_addr1 = wallet.getnewaddress()
496+
multi_addr2 = wallet.getnewaddress()
497+
multi_addr3 = df_wallet.getnewaddress()
498+
wallet.importpubkey(df_wallet.getaddressinfo(multi_addr3)["pubkey"])
499+
ms_addr_info = wallet.addmultisigaddress(2, [multi_addr1, multi_addr2, multi_addr3])
500+
501+
self.generate(self.nodes[0], 1)
502+
503+
# Test vectors
504+
addr_external = {
505+
"addr": df_wallet.getnewaddress(),
506+
"is_mine": False,
507+
"is_change": False,
508+
"label": ""
509+
}
510+
addr_external_with_label = {
511+
"addr": df_wallet.getnewaddress(),
512+
"is_mine": False,
513+
"is_change": False,
514+
"label": "external"
515+
}
516+
addr_internal = {
517+
"addr": wallet.getnewaddress(),
518+
"is_mine": True,
519+
"is_change": False,
520+
"label": ""
521+
}
522+
addr_internal_with_label = {
523+
"addr": wallet.getnewaddress(),
524+
"is_mine": True,
525+
"is_change": False,
526+
"label": "internal"
527+
}
528+
change_address = {
529+
"addr": wallet.getrawchangeaddress(),
530+
"is_mine": True,
531+
"is_change": True,
532+
"label": None
533+
}
534+
watch_only_addr = {
535+
"addr": watch_addr,
536+
"is_mine": False,
537+
"is_change": False,
538+
"label": "imported"
539+
}
540+
ms_addr = {
541+
"addr": ms_addr_info['address'],
542+
"is_mine": False,
543+
"is_change": False,
544+
"label": "multisig"
545+
}
546+
547+
# To store the change address in the addressbook need to send coins to it
548+
wallet.send(outputs=[{wallet.getnewaddress(): 2}], options={"change_address": change_address['addr']})
549+
self.generate(self.nodes[0], 1)
550+
551+
# Util wrapper func for 'addr_info'
552+
def check(info, node):
553+
self.check_address(node, info['addr'], info['is_mine'], info['is_change'], info["label"])
554+
555+
# Pre-migration: set label and perform initial checks
556+
for addr_info in [addr_external, addr_external_with_label, addr_internal, addr_internal_with_label, change_address, watch_only_addr, ms_addr]:
557+
if not addr_info['is_change']:
558+
wallet.setlabel(addr_info['addr'], addr_info["label"])
559+
check(addr_info, wallet)
560+
561+
# Migrate wallet
562+
info_migration = wallet.migratewallet()
563+
wallet_wo = self.nodes[0].get_wallet_rpc(info_migration["watchonly_name"])
564+
wallet_solvables = self.nodes[0].get_wallet_rpc(info_migration["solvables_name"])
565+
566+
#########################
567+
# Post migration checks #
568+
#########################
569+
570+
# First check the main wallet
571+
for addr_info in [addr_external, addr_external_with_label, addr_internal, addr_internal_with_label, change_address, ms_addr]:
572+
check(addr_info, wallet)
573+
574+
# Watch-only wallet will contain the watch-only entry (with 'is_mine=True') and all external addresses ('send')
575+
self.check_address(wallet_wo, watch_only_addr['addr'], is_mine=True, is_change=watch_only_addr['is_change'], label=watch_only_addr["label"])
576+
for addr_info in [addr_external, addr_external_with_label, ms_addr]:
577+
check(addr_info, wallet_wo)
578+
579+
# Solvables wallet will contain the multisig entry (with 'is_mine=True') and all external addresses ('send')
580+
self.check_address(wallet_solvables, ms_addr['addr'], is_mine=True, is_change=ms_addr['is_change'], label=ms_addr["label"])
581+
for addr_info in [addr_external, addr_external_with_label]:
582+
check(addr_info, wallet_solvables)
583+
584+
########################################################################################
585+
# Now restart migrated wallets and verify that the addressbook entries are still there #
586+
########################################################################################
587+
588+
# First the main wallet
589+
self.nodes[0].unloadwallet("legacy_addrbook")
590+
self.nodes[0].loadwallet("legacy_addrbook")
591+
for addr_info in [addr_external, addr_external_with_label, addr_internal, addr_internal_with_label, change_address, ms_addr]:
592+
check(addr_info, wallet)
593+
594+
# Watch-only wallet
595+
self.nodes[0].unloadwallet(info_migration["watchonly_name"])
596+
self.nodes[0].loadwallet(info_migration["watchonly_name"])
597+
self.check_address(wallet_wo, watch_only_addr['addr'], is_mine=True, is_change=watch_only_addr['is_change'], label=watch_only_addr["label"])
598+
for addr_info in [addr_external, addr_external_with_label, ms_addr]:
599+
check(addr_info, wallet_wo)
600+
601+
# Solvables wallet
602+
self.nodes[0].unloadwallet(info_migration["solvables_name"])
603+
self.nodes[0].loadwallet(info_migration["solvables_name"])
604+
self.check_address(wallet_solvables, ms_addr['addr'], is_mine=True, is_change=ms_addr['is_change'], label=ms_addr["label"])
605+
for addr_info in [addr_external, addr_external_with_label]:
606+
check(addr_info, wallet_solvables)
607+
473608
def run_test(self):
474609
self.generate(self.nodes[0], 101)
475610

@@ -482,6 +617,7 @@ def run_test(self):
482617
self.test_encrypted()
483618
self.test_unloaded()
484619
self.test_unloaded_by_path()
620+
self.test_addressbook()
485621

486622
if __name__ == '__main__':
487623
WalletMigrationTest().main()

0 commit comments

Comments
 (0)