Skip to content

Commit c648bdb

Browse files
committed
test: create wallet specific for test_locked_wallet case
Other tests are also relying on the node1 default wallet, which thanks to 'test_locked_wallet' is encrypted. And can only be accessed within a specific timeframe (100ms) set internally by the same test. This make other tests susceptible to races. They can only perform their operations successfully within the specified time. This can be seen running the test in valgrind, where other test cases fail due the wallet re-locking itself after the 100ms.
1 parent d23fda0 commit c648bdb

File tree

1 file changed

+39
-22
lines changed

1 file changed

+39
-22
lines changed

test/functional/wallet_fundrawtransaction.py

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -581,11 +581,20 @@ def test_spend_2of2(self):
581581
def test_locked_wallet(self):
582582
self.log.info("Test fundrawtxn with locked wallet and hardened derivation")
583583

584-
self.nodes[1].encryptwallet("test")
584+
df_wallet = self.nodes[1].get_wallet_rpc(self.default_wallet_name)
585+
self.nodes[1].createwallet(wallet_name="locked_wallet", descriptors=self.options.descriptors)
586+
wallet = self.nodes[1].get_wallet_rpc("locked_wallet")
587+
588+
# Add some balance to the wallet (this will be reverted at the end of the test)
589+
df_wallet.sendall(recipients=[wallet.getnewaddress()])
590+
self.generate(self.nodes[1], 1)
591+
592+
# Encrypt wallet and import descriptors
593+
wallet.encryptwallet("test")
585594

586595
if self.options.descriptors:
587-
self.nodes[1].walletpassphrase('test', 10)
588-
self.nodes[1].importdescriptors([{
596+
wallet.walletpassphrase('test', 10)
597+
wallet.importdescriptors([{
589598
'desc': descsum_create('wpkh(tprv8ZgxMBicQKsPdYeeZbPSKd2KYLmeVKtcFA7kqCxDvDR13MQ6us8HopUR2wLcS2ZKPhLyKsqpDL2FtL73LMHcgoCL7DXsciA8eX8nbjCR2eG/0h/*h)'),
590599
'timestamp': 'now',
591600
'active': True
@@ -596,49 +605,57 @@ def test_locked_wallet(self):
596605
'active': True,
597606
'internal': True
598607
}])
599-
self.nodes[1].walletlock()
608+
wallet.walletlock()
600609

601610
# Drain the keypool.
602-
self.nodes[1].getnewaddress()
603-
self.nodes[1].getrawchangeaddress()
611+
wallet.getnewaddress()
612+
wallet.getrawchangeaddress()
604613

605-
# Choose 2 inputs
606-
inputs = self.nodes[1].listunspent()[0:2]
607-
value = sum(inp["amount"] for inp in inputs) - Decimal("0.00000500") # Pay a 500 sat fee
614+
# Choose input
615+
inputs = wallet.listunspent()
616+
# Deduce fee to produce a changeless transaction
617+
value = inputs[0]["amount"] - Decimal("0.00002200")
608618
outputs = {self.nodes[0].getnewaddress():value}
609-
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
619+
rawtx = wallet.createrawtransaction(inputs, outputs)
610620
# fund a transaction that does not require a new key for the change output
611-
self.nodes[1].fundrawtransaction(rawtx)
621+
funded_tx = wallet.fundrawtransaction(rawtx)
622+
assert_equal(funded_tx["changepos"], -1)
612623

613624
# fund a transaction that requires a new key for the change output
614625
# creating the key must be impossible because the wallet is locked
615626
outputs = {self.nodes[0].getnewaddress():value - Decimal("0.1")}
616-
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
617-
assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it.", self.nodes[1].fundrawtransaction, rawtx)
627+
rawtx = wallet.createrawtransaction(inputs, outputs)
628+
assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it.", wallet.fundrawtransaction, rawtx)
618629

619630
# Refill the keypool.
620-
self.nodes[1].walletpassphrase("test", 100)
621-
self.nodes[1].keypoolrefill(8) #need to refill the keypool to get an internal change address
622-
self.nodes[1].walletlock()
631+
wallet.walletpassphrase("test", 100)
632+
wallet.keypoolrefill(8) #need to refill the keypool to get an internal change address
633+
wallet.walletlock()
623634

624-
assert_raises_rpc_error(-13, "walletpassphrase", self.nodes[1].sendtoaddress, self.nodes[0].getnewaddress(), 1.2)
635+
assert_raises_rpc_error(-13, "walletpassphrase", wallet.sendtoaddress, self.nodes[0].getnewaddress(), 1.2)
625636

626637
oldBalance = self.nodes[0].getbalance()
627638

628639
inputs = []
629640
outputs = {self.nodes[0].getnewaddress():1.1}
630-
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
631-
fundedTx = self.nodes[1].fundrawtransaction(rawtx)
641+
rawtx = wallet.createrawtransaction(inputs, outputs)
642+
fundedTx = wallet.fundrawtransaction(rawtx)
643+
assert fundedTx["changepos"] != -1
632644

633645
# Now we need to unlock.
634-
self.nodes[1].walletpassphrase("test", 600)
635-
signedTx = self.nodes[1].signrawtransactionwithwallet(fundedTx['hex'])
636-
self.nodes[1].sendrawtransaction(signedTx['hex'])
646+
wallet.walletpassphrase("test", 600)
647+
signedTx = wallet.signrawtransactionwithwallet(fundedTx['hex'])
648+
wallet.sendrawtransaction(signedTx['hex'])
637649
self.generate(self.nodes[1], 1)
638650

639651
# Make sure funds are received at node1.
640652
assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance())
641653

654+
# Restore pre-test wallet state
655+
wallet.sendall(recipients=[df_wallet.getnewaddress(), df_wallet.getnewaddress(), df_wallet.getnewaddress()])
656+
wallet.unloadwallet()
657+
self.generate(self.nodes[1], 1)
658+
642659
def test_many_inputs_fee(self):
643660
"""Multiple (~19) inputs tx test | Compare fee."""
644661
self.log.info("Test fundrawtxn fee with many inputs")

0 commit comments

Comments
 (0)