6
6
7
7
import random
8
8
import shutil
9
+ from test_framework .address import script_to_p2sh
9
10
from test_framework .descriptors import descsum_create
10
11
from test_framework .test_framework import BitcoinTestFramework
11
12
from test_framework .messages import COIN , CTransaction , CTxOut
@@ -674,6 +675,21 @@ def send_to_script(script, amount):
674
675
wallet .rpc .importaddress (address = script_wsh_pkh .hex (), label = "raw_spk2" , rescan = True , p2sh = False )
675
676
assert_equal (wallet .getbalances ()['watchonly' ]['trusted' ], 5 )
676
677
678
+ # Import sh(pkh()) script, by using importaddress(), with the p2sh flag enabled.
679
+ # This will wrap the script under another sh level, which is invalid!, and store it inside the wallet.
680
+ # The migration process must skip the invalid scripts and the addressbook records linked to them.
681
+ # They are not being watched by the current wallet, nor should be watched by the migrated one.
682
+ label_sh_pkh = "raw_sh_pkh"
683
+ script_pkh = key_to_p2pkh_script (df_wallet .getaddressinfo (df_wallet .getnewaddress ())["pubkey" ])
684
+ script_sh_pkh = script_to_p2sh_script (script_pkh )
685
+ addy_script_sh_pkh = script_to_p2sh (script_pkh ) # valid script address
686
+ addy_script_double_sh_pkh = script_to_p2sh (script_sh_pkh ) # invalid script address
687
+
688
+ # Note: 'importaddress()' will add two scripts, a valid one sh(pkh()) and an invalid one 'sh(sh(pkh()))'.
689
+ # Both of them will be stored with the same addressbook label. And only the latter one should
690
+ # be discarded during migration. The first one must be migrated.
691
+ wallet .rpc .importaddress (address = script_sh_pkh .hex (), label = label_sh_pkh , rescan = False , p2sh = True )
692
+
677
693
# Migrate wallet and re-check balance
678
694
info_migration = wallet .migratewallet ()
679
695
wallet_wo = self .nodes [0 ].get_wallet_rpc (info_migration ["watchonly_name" ])
@@ -683,6 +699,20 @@ def send_to_script(script, amount):
683
699
# The watch-only scripts are no longer part of the main wallet
684
700
assert_equal (wallet .getbalances ()['mine' ]['trusted' ], 0 )
685
701
702
+ # The invalid sh(sh(pk())) script label must not be part of the main wallet anymore
703
+ assert label_sh_pkh not in wallet .listlabels ()
704
+ # But, the standard sh(pkh()) script should be part of the watch-only wallet.
705
+ addrs_by_label = wallet_wo .getaddressesbylabel (label_sh_pkh )
706
+ assert addy_script_sh_pkh in addrs_by_label
707
+ assert addy_script_double_sh_pkh not in addrs_by_label
708
+
709
+ # Also, the watch-only wallet should have the descriptor for the standard sh(pkh())
710
+ desc = descsum_create (f"addr({ addy_script_sh_pkh } )" )
711
+ assert next (it ['desc' ] for it in wallet_wo .listdescriptors ()['descriptors' ] if it ['desc' ] == desc )
712
+ # And doesn't have a descriptor for the invalid one
713
+ desc_invalid = descsum_create (f"addr({ addy_script_double_sh_pkh } )" )
714
+ assert_equal (next ((it ['desc' ] for it in wallet_wo .listdescriptors ()['descriptors' ] if it ['desc' ] == desc_invalid ), None ), None )
715
+
686
716
# Just in case, also verify wallet restart
687
717
self .nodes [0 ].unloadwallet (info_migration ["watchonly_name" ])
688
718
self .nodes [0 ].loadwallet (info_migration ["watchonly_name" ])
0 commit comments