4040from test_framework .util import (
4141 assert_equal ,
4242 assert_raises_rpc_error ,
43+ sha256sum_file ,
4344)
4445
4546
@@ -140,6 +141,67 @@ def restore_wallet_existent_name(self):
140141 assert_raises_rpc_error (- 36 , error_message , node .restorewallet , wallet_name , backup_file )
141142 assert wallet_file .exists ()
142143
144+ def test_restore_existent_dir (self ):
145+ self .log .info ("Test restore on an existent empty directory" )
146+ node = self .nodes [3 ]
147+ backup_file = self .nodes [0 ].datadir_path / 'wallet.bak'
148+ wallet_name = "restored_wallet"
149+ wallet_dir = node .wallets_path / wallet_name
150+ os .mkdir (wallet_dir )
151+ res = node .restorewallet (wallet_name , backup_file )
152+ assert_equal (res ['name' ], wallet_name )
153+ node .unloadwallet (wallet_name )
154+
155+ self .log .info ("Test restore succeeds when the target directory contains non-wallet files" )
156+ wallet_file = node .wallets_path / wallet_name / "wallet.dat"
157+ os .remove (wallet_file )
158+ extra_file = node .wallets_path / wallet_name / "not_a_wallet.txt"
159+ extra_file .touch ()
160+ res = node .restorewallet (wallet_name , backup_file )
161+ assert_equal (res ['name' ], wallet_name )
162+ assert extra_file .exists () # extra file was not removed by mistake
163+ node .unloadwallet (wallet_name )
164+
165+ self .log .info ("Test restore failure due to existing db file in the destination directory" )
166+ original_shasum = sha256sum_file (wallet_file )
167+ error_message = "Failed to restore wallet. Database file exists in '{}'." .format (wallet_dir / "wallet.dat" )
168+ assert_raises_rpc_error (- 36 , error_message , node .restorewallet , wallet_name , backup_file )
169+ # Ensure the wallet file remains untouched
170+ assert wallet_dir .exists ()
171+ assert_equal (original_shasum , sha256sum_file (wallet_file ))
172+
173+ self .log .info ("Test restore succeeds when the .dat file in the destination has a different name" )
174+ second_wallet = wallet_dir / "hidden_storage.dat"
175+ os .rename (wallet_dir / "wallet.dat" , second_wallet )
176+ original_shasum = sha256sum_file (second_wallet )
177+ res = node .restorewallet (wallet_name , backup_file )
178+ assert_equal (res ['name' ], wallet_name )
179+ assert (wallet_dir / "hidden_storage.dat" ).exists ()
180+ assert_equal (original_shasum , sha256sum_file (second_wallet ))
181+ node .unloadwallet (wallet_name )
182+
183+ # Clean for follow-up tests
184+ os .remove (wallet_file )
185+
186+ def test_restore_into_unnamed_wallet (self ):
187+ self .log .info ("Test restore into a default unnamed wallet" )
188+ # This is also useful to test the migration recovery after failure logic
189+ node = self .nodes [3 ]
190+ if not self .options .descriptors :
191+ node .unloadwallet ("" )
192+ os .rename (node .wallets_path / "wallet.dat" , node .wallets_path / "default.wallet.dat" )
193+ backup_file = self .nodes [0 ].datadir_path / 'wallet.bak'
194+ wallet_name = ""
195+ res = node .restorewallet (wallet_name , backup_file )
196+ assert_equal (res ['name' ], "" )
197+ assert (node .wallets_path / "wallet.dat" ).exists ()
198+ # Clean for follow-up tests
199+ node .unloadwallet ("" )
200+ os .remove (node .wallets_path / "wallet.dat" )
201+ if not self .options .descriptors :
202+ os .rename (node .wallets_path / "default.wallet.dat" , node .wallets_path / "wallet.dat" )
203+ node .loadwallet ("" )
204+
143205 def test_pruned_wallet_backup (self ):
144206 self .log .info ("Test loading backup on a pruned node when the backup was created close to the prune height of the restoring node" )
145207 node = self .nodes [3 ]
@@ -159,6 +221,19 @@ def test_pruned_wallet_backup(self):
159221 # the backup to load successfully this close to the prune height
160222 node .restorewallet ('pruned' , node .datadir_path / 'wallet_pruned.bak' )
161223
224+ self .log .info ("Test restore on a pruned node when the backup was beyond the pruning point" )
225+ if not self .options .descriptors :
226+ node .unloadwallet ("" )
227+ os .rename (node .wallets_path / "wallet.dat" , node .wallets_path / "default.wallet.dat" )
228+ backup_file = self .nodes [0 ].datadir_path / 'wallet.bak'
229+ wallet_name = ""
230+ 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 pruned node)"
231+ assert_raises_rpc_error (- 4 , error_message , node .restorewallet , wallet_name , backup_file )
232+ assert node .wallets_path .exists () # ensure the wallets dir exists
233+ if not self .options .descriptors :
234+ os .rename (node .wallets_path / "default.wallet.dat" , node .wallets_path / "wallet.dat" )
235+ node .loadwallet ("" )
236+
162237 def run_test (self ):
163238 self .log .info ("Generating initial blockchain" )
164239 self .generate (self .nodes [0 ], 1 )
@@ -227,6 +302,8 @@ def run_test(self):
227302 assert_equal (res2_rpc .getbalance (), balance2 )
228303
229304 self .restore_wallet_existent_name ()
305+ self .test_restore_existent_dir ()
306+ self .test_restore_into_unnamed_wallet ()
230307
231308 if not self .options .descriptors :
232309 self .log .info ("Restoring using dumped wallet" )
0 commit comments