Dash Core  0.12.2.1
P2P Digital Currency
invalidblockrequest.py
Go to the documentation of this file.
1 #!/usr/bin/env python2
2 #
3 # Distributed under the MIT/X11 software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #
6 
7 from test_framework.test_framework import ComparisonTestFramework
8 from test_framework.util import *
9 from test_framework.comptool import TestManager, TestInstance, RejectResult
10 from test_framework.blocktools import *
11 import copy
12 import time
13 
14 
15 '''
16 In this test we connect to one node over p2p, and test block requests:
17 1) Valid blocks should be requested and become chain tip.
18 2) Invalid block with duplicated transaction should be re-requested.
19 3) Invalid block with bad coinbase value should be rejected and not
20 re-requested.
21 '''
22 
23 # Use the ComparisonTestFramework with 1 node: only use --testbinary.
25 
26  ''' Can either run this test as 1 node with expected answers, or two and compare them.
27  Change the "outcome" variable from each TestInstance object to only do the comparison. '''
28  def __init__(self):
29  self.num_nodes = 1
30 
31  def run_test(self):
32  test = TestManager(self, self.options.tmpdir)
33  test.add_all_connections(self.nodes)
34  self.tip = None
35  self.block_time = None
36  NetworkThread().start() # Start up network handling in another thread
38  test.run()
39 
40  def get_tests(self):
41  if self.tip is None:
42  self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
43  self.block_time = int(time.time())+1
44 
45  '''
46  Create a new block with an anyone-can-spend coinbase
47  '''
48  height = 1
49  block = create_block(self.tip, create_coinbase(height), self.block_time)
50  self.block_time += 1
51  block.solve()
52  # Save the coinbase for later
53  self.block1 = block
54  self.tip = block.sha256
55  height += 1
56  yield TestInstance([[block, True]])
57 
58  '''
59  Now we need that block to mature so we can spend the coinbase.
60  '''
61  test = TestInstance(sync_every_block=False)
62  for i in xrange(100):
63  block = create_block(self.tip, create_coinbase(height), self.block_time)
64  block.solve()
65  self.tip = block.sha256
66  self.block_time += 1
67  test.blocks_and_transactions.append([block, True])
68  height += 1
69  yield test
70 
71  '''
72  Now we use merkle-root malleability to generate an invalid block with
73  same blockheader.
74  Manufacture a block with 3 transactions (coinbase, spend of prior
75  coinbase, spend of that spend). Duplicate the 3rd transaction to
76  leave merkle root and blockheader unchanged but invalidate the block.
77  '''
78  block2 = create_block(self.tip, create_coinbase(height), self.block_time)
79  self.block_time += 1
80 
81  # b'0x51' is OP_TRUE
82  tx1 = create_transaction(self.block1.vtx[0], 0, b'\x51', 50 * COIN)
83  tx2 = create_transaction(tx1, 0, b'\x51', 50 * COIN)
84 
85  block2.vtx.extend([tx1, tx2])
86  block2.hashMerkleRoot = block2.calc_merkle_root()
87  block2.rehash()
88  block2.solve()
89  orig_hash = block2.sha256
90  block2_orig = copy.deepcopy(block2)
91 
92  # Mutate block 2
93  block2.vtx.append(tx2)
94  assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root())
95  assert_equal(orig_hash, block2.rehash())
96  assert(block2_orig.vtx != block2.vtx)
97 
98  self.tip = block2.sha256
99  yield TestInstance([[block2, RejectResult(16, b'bad-txns-duplicate')], [block2_orig, True]])
100  height += 1
101 
102  '''
103  Make sure that a totally screwed up block is not valid.
104  '''
105  block3 = create_block(self.tip, create_coinbase(height), self.block_time)
106  self.block_time += 1
107  block3.vtx[0].vout[0].nValue = 1000 * COIN # Too high!
108  block3.vtx[0].sha256=None
109  block3.vtx[0].calc_sha256()
110  block3.hashMerkleRoot = block3.calc_merkle_root()
111  block3.rehash()
112  block3.solve()
113 
114  yield TestInstance([[block3, RejectResult(16, b'bad-cb-amount')]])
115 
116 
117 if __name__ == '__main__':
def create_block(hashprev, coinbase, nTime=None)
Definition: blocktools.py:11
def sync_masternodes(rpc_connections)
Definition: util.py:142
def create_coinbase(height, pubkey=None)
Definition: blocktools.py:43
def create_transaction(prevtx, n, sig, value)
Definition: blocktools.py:61
UniValue getbestblockhash(const UniValue &params, bool fHelp)
Definition: blockchain.cpp:148
def assert_equal(thing1, thing2)
Definition: util.py:461