Skip to content

Commit e413b2e

Browse files
committed
Merge ca97d29 into merged_master (Bitcoin PR #16551)
2 parents bc7f2f6 + ca97d29 commit e413b2e

File tree

6 files changed

+643
-2
lines changed

6 files changed

+643
-2
lines changed

test/functional/data/blockheader_testnet3.hex

Lines changed: 548 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2019 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 that we reject low difficulty headers to prevent our block tree from filling up with useless bloat"""
6+
7+
from test_framework.messages import (
8+
CBlockHeader,
9+
FromHex,
10+
)
11+
from test_framework.mininode import (
12+
P2PInterface,
13+
msg_headers,
14+
)
15+
from test_framework.test_framework import BitcoinTestFramework
16+
17+
import os
18+
19+
20+
class RejectLowDifficultyHeadersTest(BitcoinTestFramework):
21+
def set_test_params(self):
22+
self.setup_clean_chain = True
23+
self.chain = 'testnet3' # Use testnet chain because it has an early checkpoint
24+
self.num_nodes = 2
25+
26+
def add_options(self, parser):
27+
parser.add_argument(
28+
'--datafile',
29+
default='data/blockheader_testnet3.hex',
30+
help='Test data file (default: %(default)s)',
31+
)
32+
33+
def run_test(self):
34+
self.log.info("Read headers data")
35+
self.headers_file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), self.options.datafile)
36+
with open(self.headers_file_path, encoding='utf-8') as headers_data:
37+
h_lines = [l.strip() for l in headers_data.readlines()]
38+
39+
# The headers data is taken from testnet3 for early blocks from genesis until the first checkpoint. There are
40+
# two headers with valid POW at height 1 and 2, forking off from genesis. They are indicated by the FORK_PREFIX.
41+
FORK_PREFIX = 'fork:'
42+
self.headers = [l for l in h_lines if not l.startswith(FORK_PREFIX)]
43+
self.headers_fork = [l[len(FORK_PREFIX):] for l in h_lines if l.startswith(FORK_PREFIX)]
44+
45+
self.headers = [FromHex(CBlockHeader(), h) for h in self.headers]
46+
self.headers_fork = [FromHex(CBlockHeader(), h) for h in self.headers_fork]
47+
48+
self.log.info("Feed all non-fork headers, including and up to the first checkpoint")
49+
self.nodes[0].add_p2p_connection(P2PInterface())
50+
self.nodes[0].p2p.send_message(msg_headers(self.headers))
51+
self.nodes[0].p2p.sync_with_ping()
52+
assert {
53+
'height': 546,
54+
'hash': '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70',
55+
'branchlen': 546,
56+
'status': 'headers-only',
57+
} in self.nodes[0].getchaintips()
58+
59+
self.log.info("Feed all fork headers (fails due to checkpoint)")
60+
with self.nodes[0].assert_debug_log(['bad-fork-prior-to-checkpoint (code 67)']):
61+
self.nodes[0].p2p.send_message(msg_headers(self.headers_fork))
62+
self.nodes[0].p2p.wait_for_disconnect()
63+
64+
self.log.info("Feed all fork headers (succeeds without checkpoint)")
65+
# On node 0 it succeeds because checkpoints are disabled
66+
self.restart_node(0, extra_args=['-nocheckpoints'])
67+
self.nodes[0].add_p2p_connection(P2PInterface())
68+
self.nodes[0].p2p.send_message(msg_headers(self.headers_fork))
69+
self.nodes[0].p2p.sync_with_ping()
70+
assert {
71+
"height": 2,
72+
"hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39",
73+
"branchlen": 2,
74+
"status": "headers-only",
75+
} in self.nodes[0].getchaintips()
76+
77+
# On node 1 it succeeds because no checkpoint has been reached yet by a chain tip
78+
self.nodes[1].add_p2p_connection(P2PInterface())
79+
self.nodes[1].p2p.send_message(msg_headers(self.headers_fork))
80+
self.nodes[1].p2p.sync_with_ping()
81+
assert {
82+
"height": 2,
83+
"hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39",
84+
"branchlen": 2,
85+
"status": "headers-only",
86+
} in self.nodes[1].getchaintips()
87+
88+
89+
if __name__ == '__main__':
90+
RejectLowDifficultyHeadersTest().main()

test/functional/test_framework/mininode.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"mainnet": b"\xf9\xbe\xb4\xd9", # mainnet
8787
"testnet3": b"\x0b\x11\x09\x07", # testnet3
8888
"regtest": b"\xfa\xbf\xb5\xda", # regtest
89+
"elementsregtest": b"\xfa\xbf\xb5\xda",
8990
}
9091

9192

@@ -111,7 +112,7 @@ def __init__(self):
111112
def is_connected(self):
112113
return self._transport is not None
113114

114-
def peer_connect(self, dstaddr, dstport, net="regtest"):
115+
def peer_connect(self, dstaddr, dstport, *, net):
115116
assert not self.is_connected
116117
self.dstaddr = dstaddr
117118
self.dstport = dstport

test/functional/test_framework/test_node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
504504
if 'dstaddr' not in kwargs:
505505
kwargs['dstaddr'] = '127.0.0.1'
506506

507-
p2p_conn.peer_connect(**kwargs)()
507+
p2p_conn.peer_connect(**kwargs, net=self.chain)()
508508
self.p2ps.append(p2p_conn)
509509
if wait_for_verack:
510510
p2p_conn.wait_for_verack()

test/functional/test_framework/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ def initialize_datadir(dirname, n, chain):
310310
f.write("server=1\n")
311311
f.write("keypool=1\n")
312312
f.write("discover=0\n")
313+
f.write("dnsseed=0\n")
313314
f.write("listenonion=0\n")
314315
f.write("printtoconsole=0\n")
315316
f.write("upnp=0\n")

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@
221221
'feature_uacomment.py',
222222
'wallet_coinbase_category.py',
223223
'feature_filelock.py',
224+
#'p2p_dos_header_tree.py', # ELEMENTS: this test requires connecting to testnet3
224225
'p2p_unrequested_blocks.py',
225226
'feature_includeconf.py',
226227
'rpc_deriveaddresses.py',

0 commit comments

Comments
 (0)