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
):
40 self
.setup_clean_chain
= True
43 def setup_network(self
):
47 self
.log
.info("Ensure submitblock can in principle reorg to a competing chain")
48 self
.nodes
[0].generate(1)
49 assert_equal(self
.nodes
[0].getblockcount(), 1)
50 (hashY
, hashZ
) = self
.nodes
[1].generate(2)
51 assert_equal(self
.nodes
[1].getblockcount(), 2)
52 node_sync_via_rpc(self
.nodes
[0:3])
53 assert_equal(self
.nodes
[0].getbestblockhash(), hashZ
)
55 self
.log
.info("Mine blocks A-B-C on Node 0")
56 (hashA
, hashB
, hashC
) = self
.nodes
[0].generate(3)
57 assert_equal(self
.nodes
[0].getblockcount(), 5)
58 self
.log
.info("Mine competing blocks E-F-G on Node 1")
59 (hashE
, hashF
, hashG
) = self
.nodes
[1].generate(3)
60 assert_equal(self
.nodes
[1].getblockcount(), 5)
61 assert(hashC
!= hashG
)
62 self
.log
.info("Connect nodes and check no reorg occurs")
63 # Submit competing blocks via RPC so any reorg should occur before we proceed (no way to wait on inaction for p2p sync)
64 node_sync_via_rpc(self
.nodes
[0:2])
65 connect_nodes_bi(self
.nodes
,0,1)
66 assert_equal(self
.nodes
[0].getbestblockhash(), hashC
)
67 assert_equal(self
.nodes
[1].getbestblockhash(), hashG
)
68 self
.log
.info("Make Node0 prefer block G")
69 self
.nodes
[0].preciousblock(hashG
)
70 assert_equal(self
.nodes
[0].getbestblockhash(), hashG
)
71 self
.log
.info("Make Node0 prefer block C again")
72 self
.nodes
[0].preciousblock(hashC
)
73 assert_equal(self
.nodes
[0].getbestblockhash(), hashC
)
74 self
.log
.info("Make Node1 prefer block C")
75 self
.nodes
[1].preciousblock(hashC
)
76 sync_chain(self
.nodes
[0:2]) # wait because node 1 may not have downloaded hashC
77 assert_equal(self
.nodes
[1].getbestblockhash(), hashC
)
78 self
.log
.info("Make Node1 prefer block G again")
79 self
.nodes
[1].preciousblock(hashG
)
80 assert_equal(self
.nodes
[1].getbestblockhash(), hashG
)
81 self
.log
.info("Make Node0 prefer block G again")
82 self
.nodes
[0].preciousblock(hashG
)
83 assert_equal(self
.nodes
[0].getbestblockhash(), hashG
)
84 self
.log
.info("Make Node1 prefer block C again")
85 self
.nodes
[1].preciousblock(hashC
)
86 assert_equal(self
.nodes
[1].getbestblockhash(), hashC
)
87 self
.log
.info("Mine another block (E-F-G-)H on Node 0 and reorg Node 1")
88 self
.nodes
[0].generate(1)
89 assert_equal(self
.nodes
[0].getblockcount(), 6)
90 sync_blocks(self
.nodes
[0:2])
91 hashH
= self
.nodes
[0].getbestblockhash()
92 assert_equal(self
.nodes
[1].getbestblockhash(), hashH
)
93 self
.log
.info("Node1 should not be able to prefer block C anymore")
94 self
.nodes
[1].preciousblock(hashC
)
95 assert_equal(self
.nodes
[1].getbestblockhash(), hashH
)
96 self
.log
.info("Mine competing blocks I-J-K-L on Node 2")
97 self
.nodes
[2].generate(4)
98 assert_equal(self
.nodes
[2].getblockcount(), 6)
99 hashL
= self
.nodes
[2].getbestblockhash()
100 self
.log
.info("Connect nodes and check no reorg occurs")
101 node_sync_via_rpc(self
.nodes
[1:3])
102 connect_nodes_bi(self
.nodes
,1,2)
103 connect_nodes_bi(self
.nodes
,0,2)
104 assert_equal(self
.nodes
[0].getbestblockhash(), hashH
)
105 assert_equal(self
.nodes
[1].getbestblockhash(), hashH
)
106 assert_equal(self
.nodes
[2].getbestblockhash(), hashL
)
107 self
.log
.info("Make Node1 prefer block L")
108 self
.nodes
[1].preciousblock(hashL
)
109 assert_equal(self
.nodes
[1].getbestblockhash(), hashL
)
110 self
.log
.info("Make Node2 prefer block H")
111 self
.nodes
[2].preciousblock(hashH
)
112 assert_equal(self
.nodes
[2].getbestblockhash(), hashH
)
114 if __name__
== '__main__':
115 PreciousTest().main()