Skip to content

Commit 6efcdf6

Browse files
committed
tests: Use new wallets for each test in wallet_taproot.py
To avoid a wallet potentially being able to sign a transaction using keys from descriptors imported in previous tests, make new wallets for each test case rather than sharing them.
1 parent 8781a1b commit 6efcdf6

File tree

1 file changed

+70
-47
lines changed

1 file changed

+70
-47
lines changed

test/functional/wallet_taproot.py

Lines changed: 70 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""Test generation and spending of P2TR addresses."""
66

77
import random
8+
import uuid
89

910
from decimal import Decimal
1011
from 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-
476499
if __name__ == '__main__':
477500
WalletTaprootTest().main()

0 commit comments

Comments
 (0)