11#!/usr/bin/env python3
2- # Copyright (c) 2016 The Bitcoin Core developers
2+ # Copyright (c) 2016-2025 The Dash Core developers
33# Distributed under the MIT software license, see the accompanying
44# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55"""
1515from test_framework .util import (
1616 assert_equal ,
1717 assert_raises_rpc_error ,
18+ get_mnemonic ,
1819)
1920
2021
@@ -29,15 +30,17 @@ def skip_test_if_missing_module(self):
2930 def setup_network (self ):
3031 self .add_nodes (self .num_nodes , self .extra_args )
3132 self .start_nodes ()
32- self .import_deterministic_coinbase_privkeys ()
33+ self .nodes [0 ].createwallet (self .default_wallet_name , blank = True , load_on_startup = True )
34+ self .nodes [0 ].importprivkey (privkey = self .nodes [0 ].get_deterministic_priv_key ().key , label = 'coinbase' , rescan = True )
3335
3436 def recover_non_hd (self ):
3537 self .log .info ("Recover non-HD wallet to check different upgrade paths" )
3638 node = self .nodes [0 ]
3739 self .stop_node (0 )
3840 shutil .copyfile (os .path .join (node .datadir , "non_hd.bak" ), os .path .join (node .datadir , self .chain , self .default_wallet_name , self .wallet_data_filename ))
3941 self .start_node (0 )
40- assert 'hdchainid' not in node .getwalletinfo ()
42+ if not self .options .descriptors :
43+ assert 'hdchainid' not in node .getwalletinfo ()
4144
4245 def run_test (self ):
4346 node = self .nodes [0 ]
@@ -47,9 +50,10 @@ def run_test(self):
4750 assert 'hdchainid' not in node .getwalletinfo ()
4851 balance_before = node .getbalance ()
4952 assert node .upgradetohd ()
50- mnemonic = node .dumphdinfo ()['mnemonic' ]
51- chainid = node .getwalletinfo ()['hdchainid' ]
52- assert_equal (len (chainid ), 64 )
53+ mnemonic = get_mnemonic (node )
54+ if not self .options .descriptors :
55+ chainid = node .getwalletinfo ()['hdchainid' ]
56+ assert_equal (len (chainid ), 64 )
5357 assert_equal (balance_before , node .getbalance ())
5458
5559 self .log .info ("Should be spendable and should use correct paths" )
@@ -82,8 +86,9 @@ def run_test(self):
8286
8387 self .log .info ("No mnemonic, no mnemonic passphrase, no wallet passphrase, should result in completely different keys" )
8488 assert node .upgradetohd ()
85- assert mnemonic != node .dumphdinfo ()['mnemonic' ]
86- assert chainid != node .getwalletinfo ()['hdchainid' ]
89+ assert mnemonic != get_mnemonic (node )
90+ if not self .options .descriptors :
91+ assert chainid != node .getwalletinfo ()['hdchainid' ]
8792 assert_equal (balance_non_HD , node .getbalance ())
8893 node .keypoolrefill (5 )
8994 node .rescanblockchain ()
@@ -96,18 +101,20 @@ def run_test(self):
96101 self .restart_node (0 , extra_args = ['-keypool=10' ])
97102 assert node .upgradetohd ("" , "" , "" , True )
98103 # Completely different keys, no HD coins should be recovered
99- assert mnemonic != node .dumphdinfo ()['mnemonic' ]
100- assert chainid != node .getwalletinfo ()['hdchainid' ]
104+ assert mnemonic != get_mnemonic (node )
105+ if not self .options .descriptors :
106+ assert chainid != node .getwalletinfo ()['hdchainid' ]
101107 assert_equal (balance_non_HD , node .getbalance ())
102108
103109 self .recover_non_hd ()
104110
105111 self .log .info ("Same mnemonic, another mnemonic passphrase, no wallet passphrase, should result in a different set of keys" )
106112 new_mnemonic_passphrase = "somewords"
107113 assert node .upgradetohd (mnemonic , new_mnemonic_passphrase )
108- assert_equal (mnemonic , node .dumphdinfo ()['mnemonic' ])
109- new_chainid = node .getwalletinfo ()['hdchainid' ]
110- assert chainid != new_chainid
114+ assert_equal (mnemonic , get_mnemonic (node ))
115+ if not self .options .descriptors :
116+ new_chainid = node .getwalletinfo ()['hdchainid' ]
117+ assert chainid != new_chainid
111118 assert_equal (balance_non_HD , node .getbalance ())
112119 node .keypoolrefill (5 )
113120 node .rescanblockchain ()
@@ -119,8 +126,9 @@ def run_test(self):
119126
120127 self .log .info ("Same mnemonic, another mnemonic passphrase, no wallet passphrase, should result in a different set of keys (again)" )
121128 assert node .upgradetohd (mnemonic , new_mnemonic_passphrase )
122- assert_equal (mnemonic , node .dumphdinfo ()['mnemonic' ])
123- assert_equal (new_chainid , node .getwalletinfo ()['hdchainid' ])
129+ assert_equal (mnemonic , get_mnemonic (node ))
130+ if not self .options .descriptors :
131+ assert_equal (new_chainid , node .getwalletinfo ()['hdchainid' ])
124132 assert_equal (balance_non_HD , node .getbalance ())
125133 node .keypoolrefill (5 )
126134 node .rescanblockchain ()
@@ -132,8 +140,9 @@ def run_test(self):
132140
133141 self .log .info ("Same mnemonic, no mnemonic passphrase, no wallet passphrase, should recover all coins after rescan" )
134142 assert node .upgradetohd (mnemonic )
135- assert_equal (mnemonic , node .dumphdinfo ()['mnemonic' ])
136- assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
143+ assert_equal (mnemonic , get_mnemonic (node ))
144+ if not self .options .descriptors :
145+ assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
137146 node .keypoolrefill (5 )
138147 assert balance_after != node .getbalance ()
139148 node .rescanblockchain ()
@@ -144,8 +153,9 @@ def run_test(self):
144153 self .log .info ("Same mnemonic, no mnemonic passphrase, no wallet passphrase, large enough keepool, should recover all coins with no extra rescan" )
145154 self .restart_node (0 , extra_args = ['-keypool=10' ])
146155 assert node .upgradetohd (mnemonic )
147- assert_equal (mnemonic , node .dumphdinfo ()['mnemonic' ])
148- assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
156+ assert_equal (mnemonic , get_mnemonic (node ))
157+ if not self .options .descriptors :
158+ assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
149159 # All coins should be recovered
150160 assert_equal (balance_after , node .getbalance ())
151161
@@ -154,8 +164,9 @@ def run_test(self):
154164 self .log .info ("Same mnemonic, no mnemonic passphrase, no wallet passphrase, large enough keepool, rescan is skipped initially, should recover all coins after rescanblockchain" )
155165 self .restart_node (0 , extra_args = ['-keypool=10' ])
156166 assert node .upgradetohd (mnemonic , "" , "" , False )
157- assert_equal (mnemonic , node .dumphdinfo ()['mnemonic' ])
158- assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
167+ assert_equal (mnemonic , get_mnemonic (node ))
168+ if not self .options .descriptors :
169+ assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
159170 assert balance_after != node .getbalance ()
160171 node .rescanblockchain ()
161172 # All coins should be recovered
@@ -171,8 +182,9 @@ def run_test(self):
171182 self .start_node (0 , extra_args = ['-rescan' ])
172183 assert_raises_rpc_error (- 13 , "Error: Please enter the wallet passphrase with walletpassphrase first." , node .dumphdinfo )
173184 node .walletpassphrase (walletpass , 100 )
174- assert_equal (mnemonic , node .dumphdinfo ()['mnemonic' ])
175- assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
185+ assert_equal (mnemonic , get_mnemonic (node ))
186+ if not self .options .descriptors :
187+ assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
176188 # Note: wallet encryption results in additional keypool topup,
177189 # so we can't compare new balance to balance_non_HD here,
178190 # assert_equal(balance_non_HD, node.getbalance()) # won't work
@@ -191,12 +203,25 @@ def run_test(self):
191203 node .wait_until_stopped ()
192204 self .start_node (0 , extra_args = ['-rescan' ])
193205 assert_raises_rpc_error (- 13 , "Error: Wallet encrypted but passphrase not supplied to RPC." , node .upgradetohd , mnemonic )
194- assert_raises_rpc_error (- 1 , "Error: The wallet passphrase entered was incorrect" , node .upgradetohd , mnemonic , "" , "wrongpass" )
206+ if not self .options .descriptors :
207+ assert_raises_rpc_error (- 1 , "Error: The wallet passphrase entered was incorrect" , node .upgradetohd , mnemonic , "" , "wrongpass" )
208+ else :
209+ assert_raises_rpc_error (- 1 , "SetupDescriptorScriptPubKeyMans: Wallet is locked, cannot setup new descriptors" , node .upgradetohd , mnemonic , "" , "wrongpass" )
210+ if self .options .descriptors :
211+ # TODO - implement auto-unlock descriptor wallet
212+ node .walletpassphrase (walletpass , 100 )
195213 assert node .upgradetohd (mnemonic , "" , walletpass )
196- assert_raises_rpc_error (- 13 , "Error: Please enter the wallet passphrase with walletpassphrase first." , node .dumphdinfo )
214+ # TODO - drop it too!
215+ if self .options .descriptors :
216+ node .walletlock ()
217+ if not self .options .descriptors :
218+ assert_raises_rpc_error (- 13 , "Error: Please enter the wallet passphrase with walletpassphrase first." , node .dumphdinfo )
219+ else :
220+ assert_raises_rpc_error (- 13 , "Error: Please enter the wallet passphrase with walletpassphrase first." , node .listdescriptors , True )
197221 node .walletpassphrase (walletpass , 100 )
198- assert_equal (mnemonic , node .dumphdinfo ()['mnemonic' ])
199- assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
222+ assert_equal (mnemonic , get_mnemonic (node ))
223+ if not self .options .descriptors :
224+ assert_equal (chainid , node .getwalletinfo ()['hdchainid' ])
200225 # Note: wallet encryption results in additional keypool topup,
201226 # so we can't compare new balance to balance_non_HD here,
202227 # assert_equal(balance_non_HD, node.getbalance()) # won't work
@@ -206,6 +231,28 @@ def run_test(self):
206231 # All coins should be recovered
207232 assert_equal (balance_after , node .getbalance ())
208233
234+ self .log .info ("Test upgradetohd with user defined mnemonic" )
235+ custom_mnemonic = "similar behave slot swim scissors throw planet view ghost laugh drift calm"
236+ # this address belongs to custom mnemonic with no passphrase
237+ custom_address_1 = "yLpq97zZUsFQ2rdMqhcPKkYT36MoPK4Hob"
238+ # this address belongs to custom mnemonic with passphrase "custom-passphrase"
239+ custom_address_2 = "yYBPeZQcqgQHu9dxA5pKBWtYbK2hwfFHxf"
240+ node .sendtoaddress (custom_address_1 , 11 )
241+ node .sendtoaddress (custom_address_2 , 12 )
242+ self .generate (node , 1 )
243+
244+ node .createwallet ("wallet-11" , blank = True )
245+ w11 = node .get_wallet_rpc ("wallet-11" )
246+ w11 .upgradetohd (custom_mnemonic )
247+ assert_equal (11 , w11 .getbalance ())
248+ w11 .unloadwallet ()
249+
250+ node .createwallet ("wallet-12" , blank = True )
251+ w12 = node .get_wallet_rpc ("wallet-12" )
252+ w12 .upgradetohd (custom_mnemonic , "custom-passphrase" )
253+ assert_equal (12 , w12 .getbalance ())
254+ w12 .unloadwallet ()
255+
209256
210257if __name__ == '__main__' :
211258 WalletUpgradeToHDTest ().main ()
0 commit comments