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
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 *
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. '''
31 test
= TestManager(self
, self
.options
.tmpdir
)
32 test
.add_all_connections(self
.nodes
)
34 self
.block_time
= None
35 NetworkThread().start() # Start up network handling in another thread
40 self
.tip
= int("0x" + self
.nodes
[0].getbestblockhash(), 0)
41 self
.block_time
= int(time
.time())+1
44 Create a new block with an anyone-can-spend coinbase
47 block
= create_block(self
.tip
, create_coinbase(height
), self
.block_time
)
50 # Save the coinbase for later
52 self
.tip
= block
.sha256
54 yield TestInstance([[block
, True]])
57 Now we need that block to mature so we can spend the coinbase.
59 test
= TestInstance(sync_every_block
=False)
61 block
= create_block(self
.tip
, create_coinbase(height
), self
.block_time
)
63 self
.tip
= block
.sha256
65 test
.blocks_and_transactions
.append([block
, True])
70 Now we use merkle-root malleability to generate an invalid block with
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.
76 block2
= create_block(self
.tip
, create_coinbase(height
), self
.block_time
)
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()
87 orig_hash
= block2
.sha256
88 block2_orig
= copy
.deepcopy(block2
)
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]])
101 Make sure that a totally screwed up block is not valid.
103 block3
= create_block(self
.tip
, create_coinbase(height
), self
.block_time
)
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()
112 yield TestInstance([[block3
, RejectResult(16, b
'bad-cb-amount')]])
115 if __name__
== '__main__':
116 InvalidBlockRequestTest().main()