@@ -67,6 +67,15 @@ def assert_list_txs_equal(self, received_list_txs, expected_list_txs):
67
67
del d ["parent_descs" ]
68
68
assert_equal (received_list_txs , expected_list_txs )
69
69
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
+
70
79
def test_basic (self ):
71
80
default = self .nodes [0 ].get_wallet_rpc (self .default_wallet_name )
72
81
@@ -504,6 +513,132 @@ def test_direct_file(self):
504
513
assert wallet_path .is_dir ()
505
514
assert wallet_dat_path .is_file ()
506
515
516
+ def test_addressbook (self ):
517
+ df_wallet = self .nodes [0 ].get_wallet_rpc (self .default_wallet_name )
518
+
519
+ self .log .info ("Test migration of address book data" )
520
+ wallet = self .create_legacy_wallet ("legacy_addrbook" )
521
+ df_wallet .sendtoaddress (wallet .getnewaddress (), 3 )
522
+
523
+ # Import watch-only script to create a watch-only wallet after migration
524
+ watch_addr = df_wallet .getnewaddress ()
525
+ wallet .importaddress (watch_addr )
526
+ df_wallet .sendtoaddress (watch_addr , 2 )
527
+
528
+ # Import solvable script
529
+ multi_addr1 = wallet .getnewaddress ()
530
+ multi_addr2 = wallet .getnewaddress ()
531
+ multi_addr3 = df_wallet .getnewaddress ()
532
+ wallet .importpubkey (df_wallet .getaddressinfo (multi_addr3 )["pubkey" ])
533
+ ms_addr_info = wallet .addmultisigaddress (2 , [multi_addr1 , multi_addr2 , multi_addr3 ])
534
+
535
+ self .generate (self .nodes [0 ], 1 )
536
+
537
+ # Test vectors
538
+ addr_external = {
539
+ "addr" : df_wallet .getnewaddress (),
540
+ "is_mine" : False ,
541
+ "is_change" : False ,
542
+ "label" : ""
543
+ }
544
+ addr_external_with_label = {
545
+ "addr" : df_wallet .getnewaddress (),
546
+ "is_mine" : False ,
547
+ "is_change" : False ,
548
+ "label" : "external"
549
+ }
550
+ addr_internal = {
551
+ "addr" : wallet .getnewaddress (),
552
+ "is_mine" : True ,
553
+ "is_change" : False ,
554
+ "label" : ""
555
+ }
556
+ addr_internal_with_label = {
557
+ "addr" : wallet .getnewaddress (),
558
+ "is_mine" : True ,
559
+ "is_change" : False ,
560
+ "label" : "internal"
561
+ }
562
+ change_address = {
563
+ "addr" : wallet .getrawchangeaddress (),
564
+ "is_mine" : True ,
565
+ "is_change" : True ,
566
+ "label" : None
567
+ }
568
+ watch_only_addr = {
569
+ "addr" : watch_addr ,
570
+ "is_mine" : False ,
571
+ "is_change" : False ,
572
+ "label" : "imported"
573
+ }
574
+ ms_addr = {
575
+ "addr" : ms_addr_info ['address' ],
576
+ "is_mine" : False ,
577
+ "is_change" : False ,
578
+ "label" : "multisig"
579
+ }
580
+
581
+ # To store the change address in the addressbook need to send coins to it
582
+ wallet .send (outputs = [{wallet .getnewaddress (): 2 }], options = {"change_address" : change_address ['addr' ]})
583
+ self .generate (self .nodes [0 ], 1 )
584
+
585
+ # Util wrapper func for 'addr_info'
586
+ def check (info , node ):
587
+ self .check_address (node , info ['addr' ], info ['is_mine' ], info ['is_change' ], info ["label" ])
588
+
589
+ # Pre-migration: set label and perform initial checks
590
+ for addr_info in [addr_external , addr_external_with_label , addr_internal , addr_internal_with_label , change_address , watch_only_addr , ms_addr ]:
591
+ if not addr_info ['is_change' ]:
592
+ wallet .setlabel (addr_info ['addr' ], addr_info ["label" ])
593
+ check (addr_info , wallet )
594
+
595
+ # Migrate wallet
596
+ info_migration = wallet .migratewallet ()
597
+ wallet_wo = self .nodes [0 ].get_wallet_rpc (info_migration ["watchonly_name" ])
598
+ wallet_solvables = self .nodes [0 ].get_wallet_rpc (info_migration ["solvables_name" ])
599
+
600
+ #########################
601
+ # Post migration checks #
602
+ #########################
603
+
604
+ # First check the main wallet
605
+ for addr_info in [addr_external , addr_external_with_label , addr_internal , addr_internal_with_label , change_address , ms_addr ]:
606
+ check (addr_info , wallet )
607
+
608
+ # Watch-only wallet will contain the watch-only entry (with 'is_mine=True') and all external addresses ('send')
609
+ self .check_address (wallet_wo , watch_only_addr ['addr' ], is_mine = True , is_change = watch_only_addr ['is_change' ], label = watch_only_addr ["label" ])
610
+ for addr_info in [addr_external , addr_external_with_label , ms_addr ]:
611
+ check (addr_info , wallet_wo )
612
+
613
+ # Solvables wallet will contain the multisig entry (with 'is_mine=True') and all external addresses ('send')
614
+ self .check_address (wallet_solvables , ms_addr ['addr' ], is_mine = True , is_change = ms_addr ['is_change' ], label = ms_addr ["label" ])
615
+ for addr_info in [addr_external , addr_external_with_label ]:
616
+ check (addr_info , wallet_solvables )
617
+
618
+ ########################################################################################
619
+ # Now restart migrated wallets and verify that the addressbook entries are still there #
620
+ ########################################################################################
621
+
622
+ # First the main wallet
623
+ self .nodes [0 ].unloadwallet ("legacy_addrbook" )
624
+ self .nodes [0 ].loadwallet ("legacy_addrbook" )
625
+ for addr_info in [addr_external , addr_external_with_label , addr_internal , addr_internal_with_label , change_address , ms_addr ]:
626
+ check (addr_info , wallet )
627
+
628
+ # Watch-only wallet
629
+ self .nodes [0 ].unloadwallet (info_migration ["watchonly_name" ])
630
+ self .nodes [0 ].loadwallet (info_migration ["watchonly_name" ])
631
+ self .check_address (wallet_wo , watch_only_addr ['addr' ], is_mine = True , is_change = watch_only_addr ['is_change' ], label = watch_only_addr ["label" ])
632
+ for addr_info in [addr_external , addr_external_with_label , ms_addr ]:
633
+ check (addr_info , wallet_wo )
634
+
635
+ # Solvables wallet
636
+ self .nodes [0 ].unloadwallet (info_migration ["solvables_name" ])
637
+ self .nodes [0 ].loadwallet (info_migration ["solvables_name" ])
638
+ self .check_address (wallet_solvables , ms_addr ['addr' ], is_mine = True , is_change = ms_addr ['is_change' ], label = ms_addr ["label" ])
639
+ for addr_info in [addr_external , addr_external_with_label ]:
640
+ check (addr_info , wallet_solvables )
641
+
507
642
def run_test (self ):
508
643
self .generate (self .nodes [0 ], 101 )
509
644
@@ -518,6 +653,7 @@ def run_test(self):
518
653
self .test_unloaded_by_path ()
519
654
self .test_default_wallet ()
520
655
self .test_direct_file ()
656
+ self .test_addressbook ()
521
657
522
658
if __name__ == '__main__' :
523
659
WalletMigrationTest ().main ()
0 commit comments