Skip to content

test: fix addr relay test silently passing and other improvements#34750

Merged
fanquake merged 3 commits intobitcoin:masterfrom
stratospher:2026_03_tests_addr_relay
Mar 12, 2026
Merged

test: fix addr relay test silently passing and other improvements#34750
fanquake merged 3 commits intobitcoin:masterfrom
stratospher:2026_03_tests_addr_relay

Conversation

@stratospher
Copy link
Contributor

couple of improvements in the addr relay test:

  TestFramework (INFO): Check that we answer getaddr messages only once per connection
  TestFramework.p2p (WARNING): Connection lost to 127.0.0.1:58829 due to [Errno 54] Connection reset by peer
  • remove a no longer applicable test comment since we don't need to send initial GETADDR for intial self announcement anymore

the test silently passes on master because SetupAddressRelay
isn't called by default for inbound connections.
since we're bumping mocktime more than CHAIN_SYNC_TIMEOUT = 20 * 60,
it's possible for disconnections like this to happen in the test:

$ test/functional/p2p_addr_relay.py --randomseed=7758649581790797022
...
TestFramework (INFO): Check that we answer getaddr messages only once per connection
TestFramework.p2p (WARNING): Connection lost to 127.0.0.1:58829 due to [Errno 54] Connection reset by peer
...
we don't need to send GETADDR for initial self announcement
anymore + can construct addr_receivers using
AddrReceiver(send_getaddr=False).

however we would need to send an empty ADDR message to each
of the addr_receivers to initialise addr relay for inbound
connections. so current code is simpler and we can just
clarify the comment.
@DrahtBot DrahtBot added the Tests label Mar 6, 2026
@DrahtBot
Copy link
Contributor

DrahtBot commented Mar 6, 2026

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

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK Bortlesboat, naiyoma, mzumsande

If your review is incorrectly listed, please copy-paste <!--meta-tag:bot-skip--> into the comment that the bot should ignore.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #34717 (p2p: remove m_getaddr_sent by naiyoma)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@stratospher
Copy link
Contributor Author

(CI failure is unrelated)

@fanquake fanquake added this to the 31.0 milestone Mar 6, 2026
@DrahtBot DrahtBot removed the CI failed label Mar 6, 2026
Copy link

@Bortlesboat Bortlesboat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 57bfa86

The move of msg_addr() before the relay check is the key fix — without it, the num_ipv4_received == 0 assertion was passing because address relay was never initialized, not because relay was actually suppressed.

The peerinfo index fix and header announcement to prevent eviction are straightforward.

Copy link

@Bortlesboat Bortlesboat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 57bfa86. Ran both p2p_addr_relay.py and p2p_addr_selfannouncement.py locally, both pass. Good catch on the stale peerinfo reference in inbound_blackhole_tests — that would silently check the wrong peer.

@fanquake
Copy link
Member

cc @Crypt-iQ @naiyoma

Copy link
Contributor

@naiyoma naiyoma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 57bfa86

I would suggest testing this flow, as it was previously an edge case but is now the default behaviour:

  1. self-announcement
  2. GETADDR
  3. ADDR.
diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py
index 65b21c0d50..af8a10e5c0 100755
--- a/test/functional/p2p_addr_relay.py
+++ b/test/functional/p2p_addr_relay.py

+        tip_header = from_hex(CBlockHeader(), self.nodes[0].getblockheader(self.nodes[0].getbestblockhash(), False))
+        full_outbound_peer.send_and_ping(msg_headers([tip_header]))
+
+        # Self-announcement is not relayed (m_getaddr_sent=true, set when node sent GETADDR)
+        self_announcement = self.setup_addr_msg(1)
+        self.send_addr_msg(full_outbound_peer, self_announcement, [inbound_peer])
+        self.log.info('Check that self-announcement from outbound peer is not relayed')
+        assert_equal(inbound_peer.num_ipv4_received, 0)
+
+        # GETADDR response is not relayed (vAddr.size() >= 1000)
+        getaddr_response = self.setup_addr_msg(1000)
+        self.send_addr_msg(full_outbound_peer, getaddr_response, [inbound_peer])
+        self.log.info('Check that GETADDR response from outbound peer is not relayed')
         assert_equal(inbound_peer.num_ipv4_received, 0)
 
-        self.log.info('Check that subsequent addr messages sent from an outbound peer are relayed')
+
+        self.log.info('Check that first subsequent addr messages sent from an outbound peer are relayed(m_getaddr_sent=false)')

@naiyoma
Copy link
Contributor

naiyoma commented Mar 12, 2026

An alternative would be to check that a small getaddr response would be relayed, but a larger response wouldn't. (Both this and the previous suggestion might be out of scope—feel free to ignore.)

+        self.log.info('Test that self-announcement resets m_getaddr_sent, causing small GETADDR responses to be relayed')
+        outbound_peer1 = self.nodes[0].add_outbound_p2p_connection(
+            AddrReceiver(), p2p_idx=0, connection_type="outbound-full-relay"
+        )
+        inbound_peer1 = self.nodes[0].add_p2p_connection(AddrReceiver(send_getaddr=False))
+        # Enable addr relay on inbound_peer1
+        inbound_peer1.send_and_ping(msg_addr())
+
+        # Outbound peer sends self-announcement -> resets m_getaddr_sent to False
+        self_announcement = self.setup_addr_msg(1)
+        outbound_peer1.send_and_ping(self_announcement)
+
+        # small GETADDR response (9 addrs) gets relayed
+        getaddr_response_small = self.setup_addr_msg(9)
+        self.send_addr_msg(outbound_peer1, getaddr_response_small, [inbound_peer1])
+        assert_equal(inbound_peer1.num_ipv4_received, 9)
+
+        # Large GETADDR response (1000 addrs) - not relayed, but only due to size check
+        getaddr_response_large = self.setup_addr_msg(1000)
+        self.send_addr_msg(outbound_peer1, getaddr_response_large, [inbound_peer1])
+        assert_equal(inbound_peer1.num_ipv4_received, 9)
+
+        self.nodes[0].disconnect_p2ps()

Copy link
Contributor

@mzumsande mzumsande left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review ACK 57bfa86

@fanquake fanquake merged commit 5608b8c into bitcoin:master Mar 12, 2026
51 of 52 checks passed
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Mar 12, 2026
the test silently passes on master because SetupAddressRelay
isn't called by default for inbound connections.

Github-Pull: bitcoin#34750
Rebased-From: ecb5ce6
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Mar 12, 2026
since we're bumping mocktime more than CHAIN_SYNC_TIMEOUT = 20 * 60,
it's possible for disconnections like this to happen in the test:

$ test/functional/p2p_addr_relay.py --randomseed=7758649581790797022
...
TestFramework (INFO): Check that we answer getaddr messages only once per connection
TestFramework.p2p (WARNING): Connection lost to 127.0.0.1:58829 due to [Errno 54] Connection reset by peer
...

Github-Pull: bitcoin#34750
Rebased-From: 7ee8c0a
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Mar 12, 2026
we don't need to send GETADDR for initial self announcement
anymore + can construct addr_receivers using
AddrReceiver(send_getaddr=False).

however we would need to send an empty ADDR message to each
of the addr_receivers to initialise addr relay for inbound
connections. so current code is simpler and we can just
clarify the comment.

Github-Pull: bitcoin#34750
Rebased-From: 57bfa86
@fanquake
Copy link
Member

Backported to 31.x in #34800.

@fanquake fanquake mentioned this pull request Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants