net_processing: do not treat non-connecting headers as response

Since https://github.com/bitcoin/bitcoin/pull/25454 we keep track of the last
GETHEADERS request that was sent and wasn't responded to. So far, every incoming
HEADERS message is treated as a response to whatever GETHEADERS was last sent,
regardless of its contents.

This commit makes this tracking more accurate, by only treating HEADERS messages
which (1) are empty, (2) connect to our existing block header tree, or (3) are a
continuation of a low-work headers sync as responses that clear the "outstanding
GETHEADERS" state (m_last_getheaders_timestamp).

That means that HEADERS messages which do not satisfy any of the above criteria
will be ignored, not triggering a GETHEADERS, and potentially (for now, but see
later commit) increase misbehavior score.
This commit is contained in:
Pieter Wuille
2024-03-12 13:18:15 -04:00
parent 0a7c650fcd
commit 9f66ac7cf1
2 changed files with 24 additions and 17 deletions

View File

@@ -559,7 +559,13 @@ class SendHeadersTest(BitcoinTestFramework):
height += 1
for i in range(1, MAX_NUM_UNCONNECTING_HEADERS_MSGS):
# Send a header that doesn't connect, check that we get a getheaders.
with p2p_lock:
test_node.last_message.pop("getheaders", None)
# Send an empty header as a failed response to the received getheaders
# (from the previous iteration). Otherwise, the new headers will be
# treated as a response instead of as an announcement.
test_node.send_header_for_blocks([])
# Send the actual unconnecting header, which should trigger a new getheaders.
test_node.send_header_for_blocks([blocks[i]])
test_node.wait_for_getheaders(block_hash=expected_hash)
@@ -574,6 +580,7 @@ class SendHeadersTest(BitcoinTestFramework):
# before we get disconnected. Should be 5*MAX_NUM_UNCONNECTING_HEADERS_MSGS
for i in range(5 * MAX_NUM_UNCONNECTING_HEADERS_MSGS - 1):
# Send a header that doesn't connect, check that we get a getheaders.
test_node.send_header_for_blocks([])
test_node.send_header_for_blocks([blocks[i % len(blocks)]])
test_node.wait_for_getheaders(block_hash=expected_hash)