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.
6 from test_framework
.test_framework
import ComparisonTestFramework
7 from test_framework
.util
import *
8 from test_framework
.comptool
import TestManager
, TestInstance
, RejectResult
9 from test_framework
.blocktools
import *
15 In this test we connect to one node over p2p, and test block requests:
16 1) Valid blocks should be requested and become chain tip.
17 2) Invalid block with duplicated transaction should be re-requested.
18 3) Invalid block with bad coinbase value should be rejected and not
22 # Use the ComparisonTestFramework with 1 node: only use --testbinary.
23 class InvalidBlockRequestTest(ComparisonTestFramework
):
25 ''' Can either run this test as 1 node with expected answers, or two and compare them.
26 Change the "outcome" variable from each TestInstance object to only do the comparison. '''
32 test
= TestManager(self
, self
.options
.tmpdir
)
33 test
.add_all_connections(self
.nodes
)
35 self
.block_time
= None
36 NetworkThread().start() # Start up network handling in another thread
41 self
.tip
= int("0x" + self
.nodes
[0].getbestblockhash(), 0)
42 self
.block_time
= int(time
.time())+1
45 Create a new block with an anyone-can-spend coinbase
48 block
= create_block(self
.tip
, create_coinbase(height
), self
.block_time
)
51 # Save the coinbase for later
53 self
.tip
= block
.sha256
55 yield TestInstance([[block
, True]])
58 Now we need that block to mature so we can spend the coinbase.
60 test
= TestInstance(sync_every_block
=False)
62 block
= create_block(self
.tip
, create_coinbase(height
), self
.block_time
)
64 self
.tip
= block
.sha256
66 test
.blocks_and_transactions
.append([block
, True])
71 Now we use merkle-root malleability to generate an invalid block with
73 Manufacture a block with 3 transactions (coinbase, spend of prior
74 coinbase, spend of that spend). Duplicate the 3rd transaction to
75 leave merkle root and blockheader unchanged but invalidate the block.
77 block2
= create_block(self
.tip
, create_coinbase(height
), self
.block_time
)
81 tx1
= create_transaction(self
.block1
.vtx
[0], 0, b
'\x51', 50 * COIN
)
82 tx2
= create_transaction(tx1
, 0, b
'\x51', 50 * COIN
)
84 block2
.vtx
.extend([tx1
, tx2
])
85 block2
.hashMerkleRoot
= block2
.calc_merkle_root()
88 orig_hash
= block2
.sha256
89 block2_orig
= copy
.deepcopy(block2
)
92 block2
.vtx
.append(tx2
)
93 assert_equal(block2
.hashMerkleRoot
, block2
.calc_merkle_root())
94 assert_equal(orig_hash
, block2
.rehash())
95 assert(block2_orig
.vtx
!= block2
.vtx
)
97 self
.tip
= block2
.sha256
98 yield TestInstance([[block2
, RejectResult(16, b
'bad-txns-duplicate')], [block2_orig
, True]])
102 Make sure that a totally screwed up block is not valid.
104 block3
= create_block(self
.tip
, create_coinbase(height
), self
.block_time
)
106 block3
.vtx
[0].vout
[0].nValue
= 100 * COIN
# Too high!
107 block3
.vtx
[0].sha256
=None
108 block3
.vtx
[0].calc_sha256()
109 block3
.hashMerkleRoot
= block3
.calc_merkle_root()
113 yield TestInstance([[block3
, RejectResult(16, b
'bad-cb-amount')]])
116 if __name__
== '__main__':
117 InvalidBlockRequestTest().main()