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

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