forked from namecoin/namecoin-core
-
Notifications
You must be signed in to change notification settings - Fork 1
/
auxpow_invalidpow.py
executable file
·101 lines (81 loc) · 3.25 KB
/
auxpow_invalidpow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env python3
# Copyright (c) 2019 Daniel Kraft
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Tests what happens if we submit a valid block with invalid auxpow. Obviously
# the block should not be accepted, but it should also not be marked as
# permanently invalid. So resubmitting the same block with a valid auxpow
# should then work fine.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.blocktools import (
create_block,
create_coinbase,
)
from test_framework.messages import (
CAuxPow,
uint256_from_compact,
)
from test_framework.mininode import P2PDataStore
from test_framework.util import (
assert_equal,
hex_str_to_bytes,
)
from test_framework.auxpow_testing import computeAuxpow
import codecs
from io import BytesIO
class AuxpowInvalidPoWTest (BitcoinTestFramework):
def set_test_params (self):
self.num_nodes = 1
self.setup_clean_chain = True
self.extra_args = [["-whitelist=127.0.0.1"]]
def run_test (self):
node = self.nodes[0]
node.add_p2p_connection (P2PDataStore ())
self.log.info ("Sending block with invalid auxpow over P2P...")
tip = node.getbestblockhash ()
blk, blkHash = self.createBlock ()
blk = self.addAuxpow (blk, blkHash, False)
node.p2p.send_blocks_and_test ([blk], node, force_send=True,
success=False, reject_reason="high-hash")
assert_equal (node.getbestblockhash (), tip)
self.log.info ("Sending the same block with valid auxpow...")
blk = self.addAuxpow (blk, blkHash, True)
node.p2p.send_blocks_and_test ([blk], node, success=True)
assert_equal (node.getbestblockhash (), blkHash)
self.log.info ("Submitting block with invalid auxpow...")
tip = node.getbestblockhash ()
blk, blkHash = self.createBlock ()
blk = self.addAuxpow (blk, blkHash, False)
assert_equal (node.submitblock (blk.serialize ().hex ()), "high-hash")
assert_equal (node.getbestblockhash (), tip)
self.log.info ("Submitting block with valid auxpow...")
blk = self.addAuxpow (blk, blkHash, True)
assert_equal (node.submitblock (blk.serialize ().hex ()), None)
assert_equal (node.getbestblockhash (), blkHash)
def createBlock (self):
"""
Creates a new block that is valid for the current tip. It is marked as
auxpow, but the auxpow is not yet filled in.
"""
bestHash = self.nodes[0].getbestblockhash ()
bestBlock = self.nodes[0].getblock (bestHash)
tip = int (bestHash, 16)
height = bestBlock["height"] + 1
time = bestBlock["time"] + 1
block = create_block (tip, create_coinbase (height), time)
block.mark_auxpow ()
block.rehash ()
newHash = "%064x" % block.sha256
return block, newHash
def addAuxpow (self, block, blkHash, ok):
"""
Fills in the auxpow for the given block message. It is either
chosen to be valid (ok = True) or invalid (ok = False).
"""
target = b"%064x" % uint256_from_compact (block.nBits)
auxpowHex = computeAuxpow (blkHash, target, ok)
block.auxpow = CAuxPow ()
block.auxpow.deserialize (BytesIO (hex_str_to_bytes (auxpowHex)))
return block
if __name__ == '__main__':
AuxpowInvalidPoWTest ().main ()