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
):
13 self
.setup_clean_chain
= True
14 # Nodes 0/1 are "wallet" nodes, Nodes 2/3 are used for testing
15 self
.extra_args
= [[], [], [], ["-txindex"]]
17 def setup_network(self
):
19 connect_nodes(self
.nodes
[0], 1)
20 connect_nodes(self
.nodes
[0], 2)
21 connect_nodes(self
.nodes
[0], 3)
26 self
.log
.info("Mining blocks...")
27 self
.nodes
[0].generate(105)
30 chain_height
= self
.nodes
[1].getblockcount()
31 assert_equal(chain_height
, 105)
32 assert_equal(self
.nodes
[1].getbalance(), 0)
33 assert_equal(self
.nodes
[2].getbalance(), 0)
35 node0utxos
= self
.nodes
[0].listunspent(1)
36 tx1
= self
.nodes
[0].createrawtransaction([node0utxos
.pop()], {self
.nodes
[1].getnewaddress(): 49.99})
37 txid1
= self
.nodes
[0].sendrawtransaction(self
.nodes
[0].signrawtransaction(tx1
)["hex"])
38 tx2
= self
.nodes
[0].createrawtransaction([node0utxos
.pop()], {self
.nodes
[1].getnewaddress(): 49.99})
39 txid2
= self
.nodes
[0].sendrawtransaction(self
.nodes
[0].signrawtransaction(tx2
)["hex"])
40 # This will raise an exception because the transaction is not yet in a block
41 assert_raises_rpc_error(-5, "Transaction not yet in block", self
.nodes
[0].gettxoutproof
, [txid1
])
43 self
.nodes
[0].generate(1)
44 blockhash
= self
.nodes
[0].getblockhash(chain_height
+ 1)
48 blocktxn
= self
.nodes
[0].getblock(blockhash
, True)["tx"]
49 txlist
.append(blocktxn
[1])
50 txlist
.append(blocktxn
[2])
52 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid1
])), [txid1
])
53 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid1
, txid2
])), txlist
)
54 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid1
, txid2
], blockhash
)), txlist
)
56 txin_spent
= self
.nodes
[1].listunspent(1).pop()
57 tx3
= self
.nodes
[1].createrawtransaction([txin_spent
], {self
.nodes
[0].getnewaddress(): 49.98})
58 txid3
= self
.nodes
[0].sendrawtransaction(self
.nodes
[1].signrawtransaction(tx3
)["hex"])
59 self
.nodes
[0].generate(1)
62 txid_spent
= txin_spent
["txid"]
63 txid_unspent
= txid1
if txin_spent
["txid"] != txid1
else txid2
65 # We can't find the block from a fully-spent tx
66 assert_raises_rpc_error(-5, "Transaction not yet in block", self
.nodes
[2].gettxoutproof
, [txid_spent
])
67 # We can get the proof if we specify the block
68 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid_spent
], blockhash
)), [txid_spent
])
69 # We can't get the proof if we specify a non-existent block
70 assert_raises_rpc_error(-5, "Block not found", self
.nodes
[2].gettxoutproof
, [txid_spent
], "00000000000000000000000000000000")
71 # We can get the proof if the transaction is unspent
72 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid_unspent
])), [txid_unspent
])
73 # 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.
74 assert_equal(sorted(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid1
, txid2
]))), sorted(txlist
))
75 assert_equal(sorted(self
.nodes
[2].verifytxoutproof(self
.nodes
[2].gettxoutproof([txid2
, txid1
]))), sorted(txlist
))
76 # We can always get a proof if we have a -txindex
77 assert_equal(self
.nodes
[2].verifytxoutproof(self
.nodes
[3].gettxoutproof([txid_spent
])), [txid_spent
])
78 # We can't get a proof if we specify transactions from different blocks
79 assert_raises_rpc_error(-5, "Not all transactions found in specified or retrieved block", self
.nodes
[2].gettxoutproof
, [txid1
, txid3
])
82 if __name__
== '__main__':
83 MerkleBlockTest().main()