Check gpg version before setting --weak-digest
[bitcoinplatinum.git] / qa / rpc-tests / invalidblockrequest.py
blobeabc0db8df58325aec01794fcf2af2f287ba4240
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 node responses to invalid blocks.
7 In this test we connect to one node over p2p, and test block requests:
8 1) Valid blocks should be requested and become chain tip.
9 2) Invalid block with duplicated transaction should be re-requested.
10 3) Invalid block with bad coinbase value should be rejected and not
11 re-requested.
12 """
14 from test_framework.test_framework import ComparisonTestFramework
15 from test_framework.util import *
16 from test_framework.comptool import TestManager, TestInstance, RejectResult
17 from test_framework.blocktools import *
18 import copy
19 import time
21 # Use the ComparisonTestFramework with 1 node: only use --testbinary.
22 class InvalidBlockRequestTest(ComparisonTestFramework):
24 ''' Can either run this test as 1 node with expected answers, or two and compare them.
25 Change the "outcome" variable from each TestInstance object to only do the comparison. '''
26 def __init__(self):
27 super().__init__()
28 self.num_nodes = 1
30 def run_test(self):
31 test = TestManager(self, self.options.tmpdir)
32 test.add_all_connections(self.nodes)
33 self.tip = None
34 self.block_time = None
35 NetworkThread().start() # Start up network handling in another thread
36 test.run()
38 def get_tests(self):
39 if self.tip is None:
40 self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
41 self.block_time = int(time.time())+1
43 '''
44 Create a new block with an anyone-can-spend coinbase
45 '''
46 height = 1
47 block = create_block(self.tip, create_coinbase(height), self.block_time)
48 self.block_time += 1
49 block.solve()
50 # Save the coinbase for later
51 self.block1 = block
52 self.tip = block.sha256
53 height += 1
54 yield TestInstance([[block, True]])
56 '''
57 Now we need that block to mature so we can spend the coinbase.
58 '''
59 test = TestInstance(sync_every_block=False)
60 for i in range(100):
61 block = create_block(self.tip, create_coinbase(height), self.block_time)
62 block.solve()
63 self.tip = block.sha256
64 self.block_time += 1
65 test.blocks_and_transactions.append([block, True])
66 height += 1
67 yield test
69 '''
70 Now we use merkle-root malleability to generate an invalid block with
71 same blockheader.
72 Manufacture a block with 3 transactions (coinbase, spend of prior
73 coinbase, spend of that spend). Duplicate the 3rd transaction to
74 leave merkle root and blockheader unchanged but invalidate the block.
75 '''
76 block2 = create_block(self.tip, create_coinbase(height), self.block_time)
77 self.block_time += 1
79 # b'0x51' is OP_TRUE
80 tx1 = create_transaction(self.block1.vtx[0], 0, b'\x51', 50 * COIN)
81 tx2 = create_transaction(tx1, 0, b'\x51', 50 * COIN)
83 block2.vtx.extend([tx1, tx2])
84 block2.hashMerkleRoot = block2.calc_merkle_root()
85 block2.rehash()
86 block2.solve()
87 orig_hash = block2.sha256
88 block2_orig = copy.deepcopy(block2)
90 # Mutate block 2
91 block2.vtx.append(tx2)
92 assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root())
93 assert_equal(orig_hash, block2.rehash())
94 assert(block2_orig.vtx != block2.vtx)
96 self.tip = block2.sha256
97 yield TestInstance([[block2, RejectResult(16, b'bad-txns-duplicate')], [block2_orig, True]])
98 height += 1
101 Make sure that a totally screwed up block is not valid.
103 block3 = create_block(self.tip, create_coinbase(height), self.block_time)
104 self.block_time += 1
105 block3.vtx[0].vout[0].nValue = 100 * COIN # Too high!
106 block3.vtx[0].sha256=None
107 block3.vtx[0].calc_sha256()
108 block3.hashMerkleRoot = block3.calc_merkle_root()
109 block3.rehash()
110 block3.solve()
112 yield TestInstance([[block3, RejectResult(16, b'bad-cb-amount')]])
115 if __name__ == '__main__':
116 InvalidBlockRequestTest().main()