test: p2p: check v1 magic bytes only after the full header #36730

pull optout21 wants to merge 1 commits into bitcoin:master from optout21:2611-testpython-v2-peer-fix changing 1 files +2 −3
  1. optout21 commented at 12:39 PM on November 2, 2026: contributor

    The p2p_v2_encrypted.py test can fail in the -- improbable -- case when network reads happen to arrive in smaller chunks (when reading HTTP response from the socket).

    Related to #36726 .

    All networking code using sockets must not make assumption about the chunking of the incoming/outgoing data, and should be resilient against any chunking. Normally, the chunking of the sends of the writer dictate the chunking of the receives at the reader, but this is not guaranteed by IP/TCP, intermediate networking elements may change the packet structure. In test using sockets on the same host, this is not very likely, but still possible.

    The v1 message parser in P2PConnection rejected the stream as soon as the first 4 bytes did not match the network magic. bitcoind's V1Transport::readHeader waits for the full 24-byte header before checking the magic.

    The v2 to v1 downgrade relies on bitcoind's behaviour: an outbound v2 connection is only retried with v1 (V2Transport::ShouldReconnectV1) if at least a v1 header's worth of bytes had been sent before the peer disconnected. If the node's first send reaches the test peer in small pieces, the Python peer could disconnect after just 4 bytes, the node would not retry with v1, and p2p_v2_encrypted.py would time out waiting for the reconnection.

    This was found -- and can be reproduced -- by using a reproducer patch, that forces all socket sends to use smaller chunking. For the run with the reproducer see #36724 .

    The issue is test-code only, the non-test code is correct.

    The fix is to match bitcoind by checking the magic only once the full header has been received.

    This fix makes the test more robust, even though a failure due to this issue in CI is very unlikely, but not impossible.

  2. test: p2p: check v1 magic bytes only after the full header
    The v1 message parser in P2PConnection rejected the stream as soon as
    the first 4 bytes did not match the network magic. bitcoind's
    V1Transport::readHeader waits for the full 24-byte header before
    checking the magic.
    
    The v2 to v1 downgrade relies on bitcoind's behaviour: an outbound v2
    connection is only retried with v1 (V2Transport::ShouldReconnectV1)
    if at least a v1 header's worth of bytes had been sent before the
    peer disconnected. If the node's first send reaches the test peer in
    small pieces, the Python peer could disconnect after just 4 bytes, the
    node would not retry with v1, and p2p_v2_encrypted.py would time out
    waiting for the reconnection.
    
    Match bitcoind by checking the magic only once the full header has
    been received.
    b54ef805e8
  3. DrahtBot added the label Tests on Nov 2, 2026
  4. DrahtBot commented at 12:39 PM on November 2, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    External sites

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process. A summary of reviews will appear here.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  5. optout21 marked this as ready for review on Nov 2, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-11-03 23:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me