2 # Copyright (c) 2014-2016 The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 """Test gettxoutproof and verifytxoutproof RPCs."""
7 from test_framework
.test_framework
import BitcoinTestFramework
8 from test_framework
.util
import *
10 class MerkleBlockTest(BitcoinTestFramework
):
11 def set_test_params(self
):
12 self
.setup_clean_chain
= True
13 # Nodes 0/1 are "wallet" nodes, Nodes 2/3 are used for testing
14 self
.extra_args
= [[], [], [], ["-txindex"]]
16 def setup_network(self
):
18 connect_nodes(self
.nodes
[0], 1)
19 connect_nodes(self
.nodes
[0], 2)
20 connect_nodes(self
.nodes
[0], 3)
25 self
.log
.info("Mining blocks...")
26 self
.nodes
[0].generate(105)
29 chain_height
= self
.nodes
[1].getblockcount()
30 assert_equal(chain_height
, 105)
31 assert_equal(self
.nodes
[1].getbalance(), 0)
32 assert_equal(self
.nodes
[2].getbalance(), 0)
34 node0utxos
= self
.nodes
[0].listunspent(1)
35 tx1
= self
.nodes
[0].createrawtransaction([node0utxos
.pop()], {self
.nodes
[1].getnewaddress(): 49.99})
36 txid1
= self
.nodes
[0].sendrawtransaction(self
.nodes
[0].signrawtransaction(tx1
)["hex"])
37 tx2
= self
.nodes
[0].createrawtransaction([node0utxos
.pop()], {self
.nodes
[1].getnewaddress(): 49.99})
38 txid2
= self
.nodes
[0].sendrawtransaction(self
.nodes
[0].signrawtransaction(tx2
)["hex"])
39 # This will raise an exception because the transaction is not yet in a block
40 assert_raises_jsonrpc(-5, "Transaction not yet in block", self
.nodes
[0].gettxoutproof
, [txid1
])
42 self
.nodes
[0].generate(1)
43 blockhash
= self
.nodes
[0].getblockhash(chain_height
+ 1)
47 blocktxn
= self
.nodes
[0].getblock(blockhash
, True)["tx"]
48 txlist
.append(blocktxn
[1])
49 txlist
.append(blocktxn
[2])
51 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid1
])), [txid1
])
52 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid1
, txid2
])), txlist
)
53 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid1
, txid2
], blockhash
)), txlist
)
55 txin_spent
= self
.nodes
[1].listunspent(1).pop()
56 tx3
= self
.nodes
[1].createrawtransaction([txin_spent
], {self
.nodes
[0].getnewaddress(): 49.98})
57 txid3
= self
.nodes
[0].sendrawtransaction(self
.nodes
[1].signrawtransaction(tx3
)["hex"])
58 self
.nodes
[0].generate(1)
61 txid_spent
= txin_spent
["txid"]
62 txid_unspent
= txid1
if txin_spent
["txid"] != txid1
else txid2
64 # We can't find the block from a fully-spent tx
65 assert_raises_jsonrpc(-5, "Transaction not yet in block", self
.nodes
[2].gettxoutproof
, [txid_spent
])
66 # We can get the proof if we specify the block
67 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid_spent
], blockhash
)), [txid_spent
])
68 # We can't get the proof if we specify a non-existent block
69 assert_raises_jsonrpc(-5, "Block not found", self
.nodes
[2].gettxoutproof
, [txid_spent
], "00000000000000000000000000000000")
70 # We can get the proof if the transaction is unspent
71 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid_unspent
])), [txid_unspent
])
72 # We can get the proof if we provide a list of transactions and one of them is unspent. The ordering of the list should not matter.
73 assert_equal(sorted(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid1
, txid2
]))), sorted(txlist
))
74 assert_equal(sorted(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid2
, txid1
]))), sorted(txlist
))
75 # We can always get a proof if we have a -txindex
76 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[3].gettxoutproof([txid_spent
])), [txid_spent
])
77 # We can't get a proof if we specify transactions from different blocks
78 assert_raises_jsonrpc(-5, "Not all transactions found in specified or retrieved block", self
.nodes
[2].gettxoutproof
, [txid1
, txid3
])
81 if __name__
== '__main__':
82 MerkleBlockTest().main()