55"""Test generation and spending of P2TR addresses."""
66
77import random
8+ import uuid
89
910from decimal import Decimal
1011from test_framework .address import output_key_to_p2tr
@@ -229,89 +230,127 @@ def make_addr(treefn, keys, i):
229230
230231 def do_test_addr (self , comment , pattern , privmap , treefn , keys ):
231232 self .log .info ("Testing %s address derivation" % comment )
233+
234+ # Create wallets
235+ wallet_uuid = uuid .uuid4 ().hex
236+ self .nodes [0 ].createwallet (wallet_name = f"privs_tr_enabled_{ wallet_uuid } " , descriptors = True , blank = True )
237+ self .nodes [0 ].createwallet (wallet_name = f"pubs_tr_enabled_{ wallet_uuid } " , descriptors = True , blank = True , disable_private_keys = True )
238+ self .nodes [0 ].createwallet (wallet_name = f"addr_gen_{ wallet_uuid } " , descriptors = True , disable_private_keys = True , blank = True )
239+ privs_tr_enabled = self .nodes [0 ].get_wallet_rpc (f"privs_tr_enabled_{ wallet_uuid } " )
240+ pubs_tr_enabled = self .nodes [0 ].get_wallet_rpc (f"pubs_tr_enabled_{ wallet_uuid } " )
241+ addr_gen = self .nodes [0 ].get_wallet_rpc (f"addr_gen_{ wallet_uuid } " )
242+
232243 desc = self .make_desc (pattern , privmap , keys , False )
233244 desc_pub = self .make_desc (pattern , privmap , keys , True )
234245 assert_equal (self .nodes [0 ].getdescriptorinfo (desc )['descriptor' ], desc_pub )
235- result = self . addr_gen .importdescriptors ([{"desc" : desc_pub , "active" : True , "timestamp" : "now" }])
246+ result = addr_gen .importdescriptors ([{"desc" : desc_pub , "active" : True , "timestamp" : "now" }])
236247 assert (result [0 ]['success' ])
248+ address_type = "bech32m" if "tr" in pattern else "bech32"
237249 for i in range (4 ):
238- addr_g = self . addr_gen .getnewaddress (address_type = 'bech32m' )
250+ addr_g = addr_gen .getnewaddress (address_type = address_type )
239251 if treefn is not None :
240252 addr_r = self .make_addr (treefn , keys , i )
241253 assert_equal (addr_g , addr_r )
242- desc_a = self . addr_gen .getaddressinfo (addr_g )['desc' ]
254+ desc_a = addr_gen .getaddressinfo (addr_g )['desc' ]
243255 if desc .startswith ("tr(" ):
244256 assert desc_a .startswith ("tr(" )
245257 rederive = self .nodes [1 ].deriveaddresses (desc_a )
246258 assert_equal (len (rederive ), 1 )
247259 assert_equal (rederive [0 ], addr_g )
248260
249261 # tr descriptors can be imported
250- result = self . privs_tr_enabled .importdescriptors ([{"desc" : desc , "timestamp" : "now" }])
262+ result = privs_tr_enabled .importdescriptors ([{"desc" : desc , "timestamp" : "now" }])
251263 assert (result [0 ]["success" ])
252- result = self . pubs_tr_enabled .importdescriptors ([{"desc" : desc_pub , "timestamp" : "now" }])
264+ result = pubs_tr_enabled .importdescriptors ([{"desc" : desc_pub , "timestamp" : "now" }])
253265 assert (result [0 ]["success" ])
254266
267+ # Cleanup
268+ privs_tr_enabled .unloadwallet ()
269+ pubs_tr_enabled .unloadwallet ()
270+ addr_gen .unloadwallet ()
271+
255272 def do_test_sendtoaddress (self , comment , pattern , privmap , treefn , keys_pay , keys_change ):
256273 self .log .info ("Testing %s through sendtoaddress" % comment )
274+
275+ # Create wallets
276+ wallet_uuid = uuid .uuid4 ().hex
277+ self .nodes [0 ].createwallet (wallet_name = f"rpc_online_{ wallet_uuid } " , descriptors = True , blank = True )
278+ rpc_online = self .nodes [0 ].get_wallet_rpc (f"rpc_online_{ wallet_uuid } " )
279+
257280 desc_pay = self .make_desc (pattern , privmap , keys_pay )
258281 desc_change = self .make_desc (pattern , privmap , keys_change )
259282 desc_pay_pub = self .make_desc (pattern , privmap , keys_pay , True )
260283 desc_change_pub = self .make_desc (pattern , privmap , keys_change , True )
261284 assert_equal (self .nodes [0 ].getdescriptorinfo (desc_pay )['descriptor' ], desc_pay_pub )
262285 assert_equal (self .nodes [0 ].getdescriptorinfo (desc_change )['descriptor' ], desc_change_pub )
263- result = self . rpc_online .importdescriptors ([{"desc" : desc_pay , "active" : True , "timestamp" : "now" }])
286+ result = rpc_online .importdescriptors ([{"desc" : desc_pay , "active" : True , "timestamp" : "now" }])
264287 assert (result [0 ]['success' ])
265- result = self . rpc_online .importdescriptors ([{"desc" : desc_change , "active" : True , "timestamp" : "now" , "internal" : True }])
288+ result = rpc_online .importdescriptors ([{"desc" : desc_change , "active" : True , "timestamp" : "now" , "internal" : True }])
266289 assert (result [0 ]['success' ])
290+ address_type = "bech32m" if "tr" in pattern else "bech32"
267291 for i in range (4 ):
268- addr_g = self . rpc_online .getnewaddress (address_type = 'bech32m' )
292+ addr_g = rpc_online .getnewaddress (address_type = address_type )
269293 if treefn is not None :
270294 addr_r = self .make_addr (treefn , keys_pay , i )
271295 assert_equal (addr_g , addr_r )
272296 boring_balance = int (self .boring .getbalance () * 100000000 )
273297 to_amnt = random .randrange (1000000 , boring_balance )
274298 self .boring .sendtoaddress (address = addr_g , amount = Decimal (to_amnt ) / 100000000 , subtractfeefromamount = True )
275299 self .generatetoaddress (self .nodes [0 ], 1 , self .boring .getnewaddress (), sync_fun = self .no_op )
276- test_balance = int (self . rpc_online .getbalance () * 100000000 )
300+ test_balance = int (rpc_online .getbalance () * 100000000 )
277301 ret_amnt = random .randrange (100000 , test_balance )
278302 # Increase fee_rate to compensate for the wallet's inability to estimate fees for script path spends.
279- res = self . rpc_online .sendtoaddress (address = self .boring .getnewaddress (), amount = Decimal (ret_amnt ) / 100000000 , subtractfeefromamount = True , fee_rate = 200 )
303+ res = rpc_online .sendtoaddress (address = self .boring .getnewaddress (), amount = Decimal (ret_amnt ) / 100000000 , subtractfeefromamount = True , fee_rate = 200 )
280304 self .generatetoaddress (self .nodes [0 ], 1 , self .boring .getnewaddress (), sync_fun = self .no_op )
281- assert (self .rpc_online .gettransaction (res )["confirmations" ] > 0 )
305+ assert (rpc_online .gettransaction (res )["confirmations" ] > 0 )
306+
307+ # Cleanup
308+ txid = rpc_online .sendall (recipients = [self .boring .getnewaddress ()])["txid" ]
309+ self .generatetoaddress (self .nodes [0 ], 1 , self .boring .getnewaddress (), sync_fun = self .no_op )
310+ assert (rpc_online .gettransaction (txid )["confirmations" ] > 0 )
311+ rpc_online .unloadwallet ()
282312
283313 def do_test_psbt (self , comment , pattern , privmap , treefn , keys_pay , keys_change ):
284314 self .log .info ("Testing %s through PSBT" % comment )
315+
316+ # Create wallets
317+ wallet_uuid = uuid .uuid4 ().hex
318+ self .nodes [0 ].createwallet (wallet_name = f"psbt_online_{ wallet_uuid } " , descriptors = True , disable_private_keys = True , blank = True )
319+ self .nodes [1 ].createwallet (wallet_name = f"psbt_offline_{ wallet_uuid } " , descriptors = True , blank = True )
320+ psbt_online = self .nodes [0 ].get_wallet_rpc (f"psbt_online_{ wallet_uuid } " )
321+ psbt_offline = self .nodes [1 ].get_wallet_rpc (f"psbt_offline_{ wallet_uuid } " )
322+
285323 desc_pay = self .make_desc (pattern , privmap , keys_pay , False )
286324 desc_change = self .make_desc (pattern , privmap , keys_change , False )
287325 desc_pay_pub = self .make_desc (pattern , privmap , keys_pay , True )
288326 desc_change_pub = self .make_desc (pattern , privmap , keys_change , True )
289327 assert_equal (self .nodes [0 ].getdescriptorinfo (desc_pay )['descriptor' ], desc_pay_pub )
290328 assert_equal (self .nodes [0 ].getdescriptorinfo (desc_change )['descriptor' ], desc_change_pub )
291- result = self . psbt_online .importdescriptors ([{"desc" : desc_pay_pub , "active" : True , "timestamp" : "now" }])
329+ result = psbt_online .importdescriptors ([{"desc" : desc_pay_pub , "active" : True , "timestamp" : "now" }])
292330 assert (result [0 ]['success' ])
293- result = self . psbt_online .importdescriptors ([{"desc" : desc_change_pub , "active" : True , "timestamp" : "now" , "internal" : True }])
331+ result = psbt_online .importdescriptors ([{"desc" : desc_change_pub , "active" : True , "timestamp" : "now" , "internal" : True }])
294332 assert (result [0 ]['success' ])
295- result = self . psbt_offline .importdescriptors ([{"desc" : desc_pay , "active" : True , "timestamp" : "now" }])
333+ result = psbt_offline .importdescriptors ([{"desc" : desc_pay , "active" : True , "timestamp" : "now" }])
296334 assert (result [0 ]['success' ])
297- result = self . psbt_offline .importdescriptors ([{"desc" : desc_change , "active" : True , "timestamp" : "now" , "internal" : True }])
335+ result = psbt_offline .importdescriptors ([{"desc" : desc_change , "active" : True , "timestamp" : "now" , "internal" : True }])
298336 assert (result [0 ]['success' ])
337+ address_type = "bech32m" if "tr" in pattern else "bech32"
299338 for i in range (4 ):
300- addr_g = self . psbt_online .getnewaddress (address_type = 'bech32m' )
339+ addr_g = psbt_online .getnewaddress (address_type = address_type )
301340 if treefn is not None :
302341 addr_r = self .make_addr (treefn , keys_pay , i )
303342 assert_equal (addr_g , addr_r )
304343 boring_balance = int (self .boring .getbalance () * 100000000 )
305344 to_amnt = random .randrange (1000000 , boring_balance )
306345 self .boring .sendtoaddress (address = addr_g , amount = Decimal (to_amnt ) / 100000000 , subtractfeefromamount = True )
307346 self .generatetoaddress (self .nodes [0 ], 1 , self .boring .getnewaddress (), sync_fun = self .no_op )
308- test_balance = int (self . psbt_online .getbalance () * 100000000 )
347+ test_balance = int (psbt_online .getbalance () * 100000000 )
309348 ret_amnt = random .randrange (100000 , test_balance )
310349 # Increase fee_rate to compensate for the wallet's inability to estimate fees for script path spends.
311- psbt = self . psbt_online .walletcreatefundedpsbt ([], [{self .boring .getnewaddress (): Decimal (ret_amnt ) / 100000000 }], None , {"subtractFeeFromOutputs" :[0 ], "fee_rate" : 200 , "change_type" : "bech32m" })['psbt' ]
312- res = self . psbt_offline .walletprocesspsbt (psbt = psbt , finalize = False )
350+ psbt = psbt_online .walletcreatefundedpsbt ([], [{self .boring .getnewaddress (): Decimal (ret_amnt ) / 100000000 }], None , {"subtractFeeFromOutputs" :[0 ], "fee_rate" : 200 , "change_type" : address_type })['psbt' ]
351+ res = psbt_offline .walletprocesspsbt (psbt = psbt , finalize = False )
313352
314- decoded = self . psbt_offline .decodepsbt (res ["psbt" ])
353+ decoded = psbt_offline .decodepsbt (res ["psbt" ])
315354 if pattern .startswith ("tr(" ):
316355 for psbtin in decoded ["inputs" ]:
317356 assert "non_witness_utxo" not in psbtin
@@ -326,7 +365,17 @@ def do_test_psbt(self, comment, pattern, privmap, treefn, keys_pay, keys_change)
326365 rawtx = self .nodes [0 ].finalizepsbt (res ['psbt' ])['hex' ]
327366 txid = self .nodes [0 ].sendrawtransaction (rawtx )
328367 self .generatetoaddress (self .nodes [0 ], 1 , self .boring .getnewaddress (), sync_fun = self .no_op )
329- assert (self .psbt_online .gettransaction (txid )['confirmations' ] > 0 )
368+ assert (psbt_online .gettransaction (txid )['confirmations' ] > 0 )
369+
370+ # Cleanup
371+ psbt = psbt_online .sendall (recipients = [self .boring .getnewaddress ()], options = {"psbt" : True })["psbt" ]
372+ res = psbt_offline .walletprocesspsbt (psbt = psbt , finalize = False )
373+ rawtx = self .nodes [0 ].finalizepsbt (res ['psbt' ])['hex' ]
374+ txid = self .nodes [0 ].sendrawtransaction (rawtx )
375+ self .generatetoaddress (self .nodes [0 ], 1 , self .boring .getnewaddress (), sync_fun = self .no_op )
376+ assert (psbt_online .gettransaction (txid )['confirmations' ] > 0 )
377+ psbt_online .unloadwallet ()
378+ psbt_offline .unloadwallet ()
330379
331380 def do_test (self , comment , pattern , privmap , treefn ):
332381 nkeys = len (privmap )
@@ -336,21 +385,8 @@ def do_test(self, comment, pattern, privmap, treefn):
336385 self .do_test_psbt (comment , pattern , privmap , treefn , keys [2 * nkeys :3 * nkeys ], keys [3 * nkeys :4 * nkeys ])
337386
338387 def run_test (self ):
339- self .log .info ("Creating wallets..." )
340- self .nodes [0 ].createwallet (wallet_name = "privs_tr_enabled" , descriptors = True , blank = True )
341- self .privs_tr_enabled = self .nodes [0 ].get_wallet_rpc ("privs_tr_enabled" )
342- self .nodes [0 ].createwallet (wallet_name = "pubs_tr_enabled" , descriptors = True , blank = True , disable_private_keys = True )
343- self .pubs_tr_enabled = self .nodes [0 ].get_wallet_rpc ("pubs_tr_enabled" )
344388 self .nodes [0 ].createwallet (wallet_name = "boring" )
345- self .nodes [0 ].createwallet (wallet_name = "addr_gen" , descriptors = True , disable_private_keys = True , blank = True )
346- self .nodes [0 ].createwallet (wallet_name = "rpc_online" , descriptors = True , blank = True )
347- self .nodes [0 ].createwallet (wallet_name = "psbt_online" , descriptors = True , disable_private_keys = True , blank = True )
348- self .nodes [1 ].createwallet (wallet_name = "psbt_offline" , descriptors = True , blank = True )
349389 self .boring = self .nodes [0 ].get_wallet_rpc ("boring" )
350- self .addr_gen = self .nodes [0 ].get_wallet_rpc ("addr_gen" )
351- self .rpc_online = self .nodes [0 ].get_wallet_rpc ("rpc_online" )
352- self .psbt_online = self .nodes [0 ].get_wallet_rpc ("psbt_online" )
353- self .psbt_offline = self .nodes [1 ].get_wallet_rpc ("psbt_offline" )
354390
355391 self .log .info ("Mining blocks..." )
356392 gen_addr = self .boring .getnewaddress ()
@@ -460,18 +496,5 @@ def run_test(self):
460496 lambda k1 : key (k1 )
461497 )
462498
463- self .log .info ("Sending everything back..." )
464-
465- txid = self .rpc_online .sendall (recipients = [self .boring .getnewaddress ()])["txid" ]
466- self .generatetoaddress (self .nodes [0 ], 1 , self .boring .getnewaddress (), sync_fun = self .no_op )
467- assert (self .rpc_online .gettransaction (txid )["confirmations" ] > 0 )
468-
469- psbt = self .psbt_online .sendall (recipients = [self .boring .getnewaddress ()], options = {"psbt" : True })["psbt" ]
470- res = self .psbt_offline .walletprocesspsbt (psbt = psbt , finalize = False )
471- rawtx = self .nodes [0 ].finalizepsbt (res ['psbt' ])['hex' ]
472- txid = self .nodes [0 ].sendrawtransaction (rawtx )
473- self .generatetoaddress (self .nodes [0 ], 1 , self .boring .getnewaddress (), sync_fun = self .no_op )
474- assert (self .psbt_online .gettransaction (txid )['confirmations' ] > 0 )
475-
476499if __name__ == '__main__' :
477500 WalletTaprootTest ().main ()
0 commit comments