@@ -112,7 +112,10 @@ def migrate_and_get_rpc(self, wallet_name, **kwargs):
112112 if wallet_name == "" :
113113 shutil .copyfile (self .old_node .wallets_path / "wallet.dat" , self .master_node .wallets_path / "wallet.dat" )
114114 else :
115- shutil .copytree (self .old_node .wallets_path / wallet_name , self .master_node .wallets_path / wallet_name )
115+ src = os .path .abspath (self .old_node .wallets_path / wallet_name )
116+ dst = os .path .abspath (self .master_node .wallets_path / wallet_name )
117+ if src != dst :
118+ shutil .copytree (self .old_node .wallets_path / wallet_name , self .master_node .wallets_path / wallet_name , dirs_exist_ok = True )
116119 # Check that the wallet shows up in listwalletdir with a warning about migration
117120 wallets = self .master_node .listwalletdir ()
118121 for w in wallets ["wallets" ]:
@@ -560,6 +563,60 @@ def test_unloaded_by_path(self):
560563
561564 assert_equal (bals , wallet .getbalances ())
562565
566+ def test_wallet_with_relative_path (self ):
567+ self .log .info ("Test migration of a wallet that isn't loaded, specified by a relative path" )
568+
569+ # Get the nearest common path of both nodes' wallet paths.
570+ common_parent = os .path .commonpath ([self .master_node .wallets_path , self .old_node .wallets_path ])
571+
572+ # This test assumes that the relative path from each wallet directory to the common path is identical.
573+ assert_equal (os .path .relpath (common_parent , start = self .master_node .wallets_path ), os .path .relpath (common_parent , start = self .old_node .wallets_path ))
574+
575+ wallet_name = "relative"
576+ absolute_path = os .path .abspath (os .path .join (common_parent , wallet_name ))
577+ relative_name = os .path .relpath (absolute_path , start = self .master_node .wallets_path )
578+
579+ wallet = self .create_legacy_wallet (relative_name )
580+ # listwalletdirs only returns wallets in the wallet directory
581+ assert {"name" : relative_name } not in wallet .listwalletdir ()["wallets" ]
582+ assert relative_name in wallet .listwallets ()
583+
584+ default = self .master_node .get_wallet_rpc (self .default_wallet_name )
585+ addr = wallet .getnewaddress ()
586+ txid = default .sendtoaddress (addr , 1 )
587+ self .generate (self .master_node , 1 )
588+ bals = wallet .getbalances ()
589+
590+ # migratewallet uses current time in naming the backup file, set a mock time
591+ # to check that this works correctly.
592+ curr_time = int (time .time ())
593+ self .master_node .setmocktime (curr_time )
594+ migrate_res , wallet = self .migrate_and_get_rpc (relative_name )
595+ self .master_node .setmocktime (0 )
596+
597+ # Check that the wallet was migrated, knows the right txid, and has the right balance.
598+ assert wallet .gettransaction (txid )
599+ assert_equal (bals , wallet .getbalances ())
600+
601+ # The migrated wallet should not be in the wallet dir, but should be in the list of wallets.
602+ info = wallet .getwalletinfo ()
603+
604+ walletdirlist = wallet .listwalletdir ()
605+ assert {"name" : info ["walletname" ]} not in walletdirlist ["wallets" ]
606+
607+ walletlist = wallet .listwallets ()
608+ assert info ["walletname" ] in walletlist
609+
610+ # Check that old node can restore from the backup.
611+ self .old_node .restorewallet ("relative_restored" , migrate_res ['backup_path' ])
612+ wallet = self .old_node .get_wallet_rpc ("relative_restored" )
613+ assert wallet .gettransaction (txid )
614+ assert_equal (bals , wallet .getbalances ())
615+
616+ info = wallet .getwalletinfo ()
617+ assert_equal (info ["descriptors" ], False )
618+ assert_equal (info ["format" ], "bdb" )
619+
563620 def test_default_wallet (self ):
564621 self .log .info ("Test migration of the wallet named as the empty string" )
565622 wallet = self .create_legacy_wallet ("" )
@@ -1403,6 +1460,7 @@ def run_test(self):
14031460 self .test_encrypted ()
14041461 self .test_nonexistent ()
14051462 self .test_unloaded_by_path ()
1463+ self .test_wallet_with_relative_path ()
14061464 self .test_default_wallet ()
14071465 self .test_direct_file ()
14081466 self .test_addressbook ()
0 commit comments