6
6
7
7
import random
8
8
import shutil
9
+ import struct
10
+
9
11
from test_framework .address import (
10
12
script_to_p2sh ,
11
13
key_to_p2pkh ,
12
14
key_to_p2wpkh ,
13
15
)
16
+ from test_framework .bdb import BTREE_MAGIC
14
17
from test_framework .descriptors import descsum_create
15
18
from test_framework .key import ECPubKey
16
19
from test_framework .test_framework import BitcoinTestFramework
20
23
assert_equal ,
21
24
assert_raises_rpc_error ,
22
25
find_vout_for_address ,
26
+ sha256sum_file ,
23
27
)
24
28
from test_framework .wallet_util import (
25
29
get_generate_key ,
@@ -827,6 +831,43 @@ def test_hybrid_pubkey(self):
827
831
828
832
wallet .unloadwallet ()
829
833
834
+ def test_failed_migration_cleanup (self ):
835
+ self .log .info ("Test that a failed migration is cleaned up" )
836
+ wallet = self .create_legacy_wallet ("failed" )
837
+
838
+ # Make a copy of the wallet with the solvables wallet name so that we are unable
839
+ # to create the solvables wallet when migrating, thus failing to migrate
840
+ wallet .unloadwallet ()
841
+ solvables_path = self .nodes [0 ].wallets_path / "failed_solvables"
842
+ shutil .copytree (self .nodes [0 ].wallets_path / "failed" , solvables_path )
843
+ original_shasum = sha256sum_file (solvables_path / "wallet.dat" )
844
+
845
+ self .nodes [0 ].loadwallet ("failed" )
846
+
847
+ # Add a multisig so that a solvables wallet is created
848
+ wallet .addmultisigaddress (2 , [wallet .getnewaddress (), get_generate_key ().pubkey ])
849
+ wallet .importaddress (get_generate_key ().p2pkh_addr )
850
+
851
+ assert_raises_rpc_error (- 4 , "Failed to create new watchonly wallet" , wallet .migratewallet )
852
+
853
+ assert "failed" in self .nodes [0 ].listwallets ()
854
+ assert "failed_watchonly" not in self .nodes [0 ].listwallets ()
855
+ assert "failed_solvables" not in self .nodes [0 ].listwallets ()
856
+
857
+ assert not (self .nodes [0 ].wallets_path / "failed_watchonly" ).exists ()
858
+ # Since the file in failed_solvables is one that we put there, migration shouldn't touch it
859
+ assert solvables_path .exists ()
860
+ new_shasum = sha256sum_file (solvables_path / "wallet.dat" )
861
+ assert_equal (original_shasum , new_shasum )
862
+
863
+ wallet .unloadwallet ()
864
+ # Check the wallet we tried to migrate is still BDB
865
+ with open (self .nodes [0 ].wallets_path / "failed" / "wallet.dat" , "rb" ) as f :
866
+ data = f .read (16 )
867
+ _ , _ , magic = struct .unpack ("QII" , data )
868
+ assert_equal (magic , BTREE_MAGIC )
869
+
870
+
830
871
def run_test (self ):
831
872
self .generate (self .nodes [0 ], 101 )
832
873
@@ -845,6 +886,7 @@ def run_test(self):
845
886
self .test_migrate_raw_p2sh ()
846
887
self .test_conflict_txs ()
847
888
self .test_hybrid_pubkey ()
889
+ self .test_failed_migration_cleanup ()
848
890
849
891
if __name__ == '__main__' :
850
892
WalletMigrationTest ().main ()
0 commit comments