88import shutil
99from test_framework .descriptors import descsum_create
1010from test_framework .test_framework import BitcoinTestFramework
11+ from test_framework .messages import COIN , CTransaction , CTxOut
12+ from test_framework .script_util import key_to_p2pkh_script , script_to_p2sh_script , script_to_p2wsh_script
1113from test_framework .util import (
1214 assert_equal ,
1315 assert_raises_rpc_error ,
@@ -639,6 +641,53 @@ def check(info, node):
639641 for addr_info in [addr_external , addr_external_with_label ]:
640642 check (addr_info , wallet_solvables )
641643
644+ def test_migrate_raw_p2sh (self ):
645+ self .log .info ("Test migration of watch-only raw p2sh script" )
646+ df_wallet = self .nodes [0 ].get_wallet_rpc (self .default_wallet_name )
647+ wallet = self .create_legacy_wallet ("raw_p2sh" )
648+
649+ def send_to_script (script , amount ):
650+ tx = CTransaction ()
651+ tx .vout .append (CTxOut (nValue = amount * COIN , scriptPubKey = script ))
652+
653+ hex_tx = df_wallet .fundrawtransaction (tx .serialize ().hex ())['hex' ]
654+ signed_tx = df_wallet .signrawtransactionwithwallet (hex_tx )
655+ df_wallet .sendrawtransaction (signed_tx ['hex' ])
656+ self .generate (self .nodes [0 ], 1 )
657+
658+ # Craft sh(pkh(key)) script and send coins to it
659+ pubkey = df_wallet .getaddressinfo (df_wallet .getnewaddress ())["pubkey" ]
660+ script_pkh = key_to_p2pkh_script (pubkey )
661+ script_sh_pkh = script_to_p2sh_script (script_pkh )
662+ send_to_script (script = script_sh_pkh , amount = 2 )
663+
664+ # Import script and check balance
665+ wallet .rpc .importaddress (address = script_pkh .hex (), label = "raw_spk" , rescan = True , p2sh = True )
666+ assert_equal (wallet .getbalances ()['watchonly' ]['trusted' ], 2 )
667+
668+ # Craft wsh(pkh(key)) and send coins to it
669+ pubkey = df_wallet .getaddressinfo (df_wallet .getnewaddress ())["pubkey" ]
670+ script_wsh_pkh = script_to_p2wsh_script (key_to_p2pkh_script (pubkey ))
671+ send_to_script (script = script_wsh_pkh , amount = 3 )
672+
673+ # Import script and check balance
674+ wallet .rpc .importaddress (address = script_wsh_pkh .hex (), label = "raw_spk2" , rescan = True , p2sh = False )
675+ assert_equal (wallet .getbalances ()['watchonly' ]['trusted' ], 5 )
676+
677+ # Migrate wallet and re-check balance
678+ info_migration = wallet .migratewallet ()
679+ wallet_wo = self .nodes [0 ].get_wallet_rpc (info_migration ["watchonly_name" ])
680+
681+ # Watch-only balance is under "mine".
682+ assert_equal (wallet_wo .getbalances ()['mine' ]['trusted' ], 5 )
683+ # The watch-only scripts are no longer part of the main wallet
684+ assert_equal (wallet .getbalances ()['mine' ]['trusted' ], 0 )
685+
686+ # Just in case, also verify wallet restart
687+ self .nodes [0 ].unloadwallet (info_migration ["watchonly_name" ])
688+ self .nodes [0 ].loadwallet (info_migration ["watchonly_name" ])
689+ assert_equal (wallet_wo .getbalances ()['mine' ]['trusted' ], 5 )
690+
642691 def run_test (self ):
643692 self .generate (self .nodes [0 ], 101 )
644693
@@ -654,6 +703,7 @@ def run_test(self):
654703 self .test_default_wallet ()
655704 self .test_direct_file ()
656705 self .test_addressbook ()
706+ self .test_migrate_raw_p2sh ()
657707
658708if __name__ == '__main__' :
659709 WalletMigrationTest ().main ()
0 commit comments