You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

preciousblock.py 5.0KB

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