2 # Copyright (c) 2015-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 the preciousblock RPC."""
7 from test_framework
.test_framework
import BitcoinTestFramework
8 from test_framework
.util
import (
15 def unidirectional_node_sync_via_rpc(node_src
, node_dest
):
17 blockhash
= node_src
.getbestblockhash()
20 assert(len(node_dest
.getblock(blockhash
, False)) > 0)
23 blocks_to_copy
.append(blockhash
)
24 blockhash
= node_src
.getblockheader(blockhash
, True)['previousblockhash']
25 blocks_to_copy
.reverse()
26 for blockhash
in blocks_to_copy
:
27 blockdata
= node_src
.getblock(blockhash
, False)
28 assert(node_dest
.submitblock(blockdata
) in (None, 'inconclusive'))
30 def node_sync_via_rpc(nodes
):
31 for node_src
in nodes
:
32 for node_dest
in nodes
:
33 if node_src
is node_dest
:
35 unidirectional_node_sync_via_rpc(node_src
, node_dest
)
37 class PreciousTest(BitcoinTestFramework
):
38 def set_test_params(self
):
39 self
.setup_clean_chain
= True
42 def setup_network(self
):
46 self
.log
.info("Ensure submitblock can in principle reorg to a competing chain")
47 self
.nodes
[0].generate(1)
48 assert_equal(self
.nodes
[0].getblockcount(), 1)
49 (hashY
, hashZ
) = self
.nodes
[1].generate(2)
50 assert_equal(self
.nodes
[1].getblockcount(), 2)
51 node_sync_via_rpc(self
.nodes
[0:3])
52 assert_equal(self
.nodes
[0].getbestblockhash(), hashZ
)
54 self
.log
.info("Mine blocks A-B-C on Node 0")
55 (hashA
, hashB
, hashC
) = self
.nodes
[0].generate(3)
56 assert_equal(self
.nodes
[0].getblockcount(), 5)
57 self
.log
.info("Mine competing blocks E-F-G on Node 1")
58 (hashE
, hashF
, hashG
) = self
.nodes
[1].generate(3)
59 assert_equal(self
.nodes
[1].getblockcount(), 5)
60 assert(hashC
!= hashG
)
61 self
.log
.info("Connect nodes and check no reorg occurs")
62 # Submit competing blocks via RPC so any reorg should occur before we proceed (no way to wait on inaction for p2p sync)
63 node_sync_via_rpc(self
.nodes
[0:2])
64 connect_nodes_bi(self
.nodes
,0,1)
65 assert_equal(self
.nodes
[0].getbestblockhash(), hashC
)
66 assert_equal(self
.nodes
[1].getbestblockhash(), hashG
)
67 self
.log
.info("Make Node0 prefer block G")
68 self
.nodes
[0].preciousblock(hashG
)
69 assert_equal(self
.nodes
[0].getbestblockhash(), hashG
)
70 self
.log
.info("Make Node0 prefer block C again")
71 self
.nodes
[0].preciousblock(hashC
)
72 assert_equal(self
.nodes
[0].getbestblockhash(), hashC
)
73 self
.log
.info("Make Node1 prefer block C")
74 self
.nodes
[1].preciousblock(hashC
)
75 sync_chain(self
.nodes
[0:2]) # wait because node 1 may not have downloaded hashC
76 assert_equal(self
.nodes
[1].getbestblockhash(), hashC
)
77 self
.log
.info("Make Node1 prefer block G again")
78 self
.nodes
[1].preciousblock(hashG
)
79 assert_equal(self
.nodes
[1].getbestblockhash(), hashG
)
80 self
.log
.info("Make Node0 prefer block G again")
81 self
.nodes
[0].preciousblock(hashG
)
82 assert_equal(self
.nodes
[0].getbestblockhash(), hashG
)
83 self
.log
.info("Make Node1 prefer block C again")
84 self
.nodes
[1].preciousblock(hashC
)
85 assert_equal(self
.nodes
[1].getbestblockhash(), hashC
)
86 self
.log
.info("Mine another block (E-F-G-)H on Node 0 and reorg Node 1")
87 self
.nodes
[0].generate(1)
88 assert_equal(self
.nodes
[0].getblockcount(), 6)
89 sync_blocks(self
.nodes
[0:2])
90 hashH
= self
.nodes
[0].getbestblockhash()
91 assert_equal(self
.nodes
[1].getbestblockhash(), hashH
)
92 self
.log
.info("Node1 should not be able to prefer block C anymore")
93 self
.nodes
[1].preciousblock(hashC
)
94 assert_equal(self
.nodes
[1].getbestblockhash(), hashH
)
95 self
.log
.info("Mine competing blocks I-J-K-L on Node 2")
96 self
.nodes
[2].generate(4)
97 assert_equal(self
.nodes
[2].getblockcount(), 6)
98 hashL
= self
.nodes
[2].getbestblockhash()
99 self
.log
.info("Connect nodes and check no reorg occurs")
100 node_sync_via_rpc(self
.nodes
[1:3])
101 connect_nodes_bi(self
.nodes
,1,2)
102 connect_nodes_bi(self
.nodes
,0,2)
103 assert_equal(self
.nodes
[0].getbestblockhash(), hashH
)
104 assert_equal(self
.nodes
[1].getbestblockhash(), hashH
)
105 assert_equal(self
.nodes
[2].getbestblockhash(), hashL
)
106 self
.log
.info("Make Node1 prefer block L")
107 self
.nodes
[1].preciousblock(hashL
)
108 assert_equal(self
.nodes
[1].getbestblockhash(), hashL
)
109 self
.log
.info("Make Node2 prefer block H")
110 self
.nodes
[2].preciousblock(hashH
)
111 assert_equal(self
.nodes
[2].getbestblockhash(), hashH
)
113 if __name__
== '__main__':
114 PreciousTest().main()