From 891beb0f8a09810b179e39a680b579c2f6516db7 Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Thu, 25 Jan 2018 19:03:05 +0900 Subject: [PATCH] [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. --- test/functional/rpc_fundrawtransaction.py | 20 +++++++++++++++++++- test/functional/test_framework/util.py | 11 +++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index 5f7a0586e0..38d7fd9252 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -4,8 +4,18 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the fundrawtransaction RPC.""" +from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import ( + assert_equal, + assert_fee_amount, + assert_greater_than, + assert_greater_than_or_equal, + assert_raises_rpc_error, + connect_nodes_bi, + count_bytes, + find_vout_for_address, +) def get_unspent(listunspent, amount): @@ -57,6 +67,11 @@ class RawTransactionsTest(BitcoinTestFramework): watchonly_amount = Decimal(200) self.nodes[3].importpubkey(watchonly_pubkey, "", True) watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount) + + # Lock UTXO so nodes[0] doesn't accidentally spend it + watchonly_vout = find_vout_for_address(self.nodes[0], watchonly_txid, watchonly_address) + self.nodes[0].lockunspent(False, [{"txid": watchonly_txid, "vout": watchonly_vout}]) + self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5) @@ -472,6 +487,9 @@ class RawTransactionsTest(BitcoinTestFramework): connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) connect_nodes_bi(self.nodes,0,3) + # Again lock the watchonly UTXO or nodes[0] may spend it, because + # lockunspent is memory-only and thus lost on restart + self.nodes[0].lockunspent(False, [{"txid": watchonly_txid, "vout": watchonly_vout}]) self.sync_all() # drain the keypool diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 7fdc171332..1320c8f029 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -569,3 +569,14 @@ def mine_large_block(node, utxos=None): fee = 100 * node.getnetworkinfo()["relayfee"] create_lots_of_big_transactions(node, txouts, utxos, num, fee=fee) node.generate(1) + +def find_vout_for_address(node, txid, addr): + """ + Locate the vout index of the given transaction sending to the + given address. Raises runtime error exception if not found. + """ + tx = node.getrawtransaction(txid, True) + for i in range(len(tx["vout"])): + if any([addr == a for a in tx["vout"][i]["scriptPubKey"]["addresses"]]): + return i + raise RuntimeError("Vout not found for address: txid=%s, addr=%s" % (txid, addr))