Skip to content

Commit 891beb0

Browse files
committed
[test] fundrawtransaction: lock watch-only shared address
self.nodes[0] creates an address which is watch-only-shared with self.nodes[3]. If nodes[0] spends the associated UTXO during any of its sends later, the watchonly test will fail, as nodes[3] now has insufficient funds. Note that this also adds a new find_vout_for_address function to the test framework.
1 parent 6970b30 commit 891beb0

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

test/functional/rpc_fundrawtransaction.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,18 @@
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test the fundrawtransaction RPC."""
66

7+
from decimal import Decimal
78
from test_framework.test_framework import BitcoinTestFramework
8-
from test_framework.util import *
9+
from test_framework.util import (
10+
assert_equal,
11+
assert_fee_amount,
12+
assert_greater_than,
13+
assert_greater_than_or_equal,
14+
assert_raises_rpc_error,
15+
connect_nodes_bi,
16+
count_bytes,
17+
find_vout_for_address,
18+
)
919

1020

1121
def get_unspent(listunspent, amount):
@@ -57,6 +67,11 @@ def run_test(self):
5767
watchonly_amount = Decimal(200)
5868
self.nodes[3].importpubkey(watchonly_pubkey, "", True)
5969
watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
70+
71+
# Lock UTXO so nodes[0] doesn't accidentally spend it
72+
watchonly_vout = find_vout_for_address(self.nodes[0], watchonly_txid, watchonly_address)
73+
self.nodes[0].lockunspent(False, [{"txid": watchonly_txid, "vout": watchonly_vout}])
74+
6075
self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10)
6176

6277
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5)
@@ -472,6 +487,9 @@ def run_test(self):
472487
connect_nodes_bi(self.nodes,1,2)
473488
connect_nodes_bi(self.nodes,0,2)
474489
connect_nodes_bi(self.nodes,0,3)
490+
# Again lock the watchonly UTXO or nodes[0] may spend it, because
491+
# lockunspent is memory-only and thus lost on restart
492+
self.nodes[0].lockunspent(False, [{"txid": watchonly_txid, "vout": watchonly_vout}])
475493
self.sync_all()
476494

477495
# drain the keypool

test/functional/test_framework/util.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,3 +569,14 @@ def mine_large_block(node, utxos=None):
569569
fee = 100 * node.getnetworkinfo()["relayfee"]
570570
create_lots_of_big_transactions(node, txouts, utxos, num, fee=fee)
571571
node.generate(1)
572+
573+
def find_vout_for_address(node, txid, addr):
574+
"""
575+
Locate the vout index of the given transaction sending to the
576+
given address. Raises runtime error exception if not found.
577+
"""
578+
tx = node.getrawtransaction(txid, True)
579+
for i in range(len(tx["vout"])):
580+
if any([addr == a for a in tx["vout"][i]["scriptPubKey"]["addresses"]]):
581+
return i
582+
raise RuntimeError("Vout not found for address: txid=%s, addr=%s" % (txid, addr))

0 commit comments

Comments
 (0)