|
13 | 13 | MAX_HEADERS_RESULTS,
|
14 | 14 | MAX_INV_SIZE,
|
15 | 15 | MAX_PROTOCOL_MESSAGE_LENGTH,
|
| 16 | + MSG_TX, |
| 17 | + from_hex, |
16 | 18 | msg_getdata,
|
17 | 19 | msg_headers,
|
18 | 20 | msg_inv,
|
19 | 21 | msg_ping,
|
20 |
| - MSG_TX, |
21 | 22 | msg_version,
|
22 | 23 | ser_string,
|
23 | 24 | )
|
@@ -73,6 +74,7 @@ def run_test(self):
|
73 | 74 | self.test_oversized_inv_msg()
|
74 | 75 | self.test_oversized_getdata_msg()
|
75 | 76 | self.test_oversized_headers_msg()
|
| 77 | + self.test_invalid_pow_headers_msg() |
76 | 78 | self.test_resource_exhaustion()
|
77 | 79 |
|
78 | 80 | def test_buffer(self):
|
@@ -248,6 +250,36 @@ def test_oversized_headers_msg(self):
|
248 | 250 | size = MAX_HEADERS_RESULTS + 1
|
249 | 251 | self.test_oversized_msg(msg_headers([CBlockHeader()] * size), size)
|
250 | 252 |
|
| 253 | + def test_invalid_pow_headers_msg(self): |
| 254 | + self.log.info("Test headers message with invalid proof-of-work is logged as misbehaving and disconnects peer") |
| 255 | + blockheader_tip_hash = self.nodes[0].getbestblockhash() |
| 256 | + blockheader_tip = from_hex(CBlockHeader(), self.nodes[0].getblockheader(blockheader_tip_hash, False)) |
| 257 | + |
| 258 | + # send valid headers message first |
| 259 | + assert_equal(self.nodes[0].getblockchaininfo()['headers'], 0) |
| 260 | + blockheader = CBlockHeader() |
| 261 | + blockheader.hashPrevBlock = int(blockheader_tip_hash, 16) |
| 262 | + blockheader.nTime = int(time.time()) |
| 263 | + blockheader.nBits = blockheader_tip.nBits |
| 264 | + blockheader.rehash() |
| 265 | + while not blockheader.hash.startswith('0'): |
| 266 | + blockheader.nNonce += 1 |
| 267 | + blockheader.rehash() |
| 268 | + peer = self.nodes[0].add_p2p_connection(P2PInterface()) |
| 269 | + peer.send_and_ping(msg_headers([blockheader])) |
| 270 | + assert_equal(self.nodes[0].getblockchaininfo()['headers'], 1) |
| 271 | + chaintips = self.nodes[0].getchaintips() |
| 272 | + assert_equal(chaintips[0]['status'], 'headers-only') |
| 273 | + assert_equal(chaintips[0]['hash'], blockheader.hash) |
| 274 | + |
| 275 | + # invalidate PoW |
| 276 | + while not blockheader.hash.startswith('f'): |
| 277 | + blockheader.nNonce += 1 |
| 278 | + blockheader.rehash() |
| 279 | + with self.nodes[0].assert_debug_log(['Misbehaving', 'header with invalid proof of work']): |
| 280 | + peer.send_message(msg_headers([blockheader])) |
| 281 | + peer.wait_for_disconnect() |
| 282 | + |
251 | 283 | def test_resource_exhaustion(self):
|
252 | 284 | self.log.info("Test node stays up despite many large junk messages")
|
253 | 285 | conn = self.nodes[0].add_p2p_connection(P2PDataStore())
|
|
0 commit comments