|
10 | 10 | - verify that getchaintips now returns two chain tips.
|
11 | 11 | """
|
12 | 12 |
|
| 13 | +from test_framework.blocktools import ( |
| 14 | + create_block, |
| 15 | + create_coinbase, |
| 16 | +) |
13 | 17 | from test_framework.test_framework import BitcoinTestFramework
|
14 | 18 | from test_framework.util import assert_equal
|
15 | 19 |
|
@@ -58,5 +62,33 @@ def run_test(self):
|
58 | 62 | tips[1]['status'] = 'active'
|
59 | 63 | assert_equal(tips[1], shortTip)
|
60 | 64 |
|
| 65 | + self.log.info("Test getchaintips behavior with invalid blocks") |
| 66 | + self.disconnect_nodes(0, 1) |
| 67 | + n0 = self.nodes[0] |
| 68 | + tip = int(n0.getbestblockhash(), 16) |
| 69 | + start_height = self.nodes[0].getblockcount() |
| 70 | + # Create invalid block (too high coinbase) |
| 71 | + block_time = n0.getblock(n0.getbestblockhash())['time'] + 1 |
| 72 | + invalid_block = create_block(tip, create_coinbase(start_height+1, nValue=100), block_time) |
| 73 | + invalid_block.solve() |
| 74 | + |
| 75 | + block_time += 1 |
| 76 | + block2 = create_block(invalid_block.sha256, create_coinbase(2), block_time, version=4) |
| 77 | + block2.solve() |
| 78 | + |
| 79 | + self.log.info("Submit headers-only chain") |
| 80 | + n0.submitheader(invalid_block.serialize().hex()) |
| 81 | + n0.submitheader(block2.serialize().hex()) |
| 82 | + tips = n0.getchaintips() |
| 83 | + assert_equal(len(tips), 3) |
| 84 | + assert_equal(tips[0]['status'], 'headers-only') |
| 85 | + |
| 86 | + self.log.info("Submit invalid block that invalidates the headers-only chain") |
| 87 | + n0.submitblock(invalid_block.serialize().hex()) |
| 88 | + tips = n0.getchaintips() |
| 89 | + assert_equal(len(tips), 3) |
| 90 | + assert_equal(tips[0]['status'], 'invalid') |
| 91 | + |
| 92 | + |
61 | 93 | if __name__ == '__main__':
|
62 | 94 | GetChainTipsTest(__file__).main()
|
0 commit comments