Subject: [bitcoin-dev] Signaling support for addr relay (revision #1)

From: Gleb Naumenko <[email-masked]>
Date: Wed, 23 Oct 2019 17:52:49 -0400

Hi,

### Introduction

I was recently looking into AddrMan and I realized that unlike with blocks (BIP152) and transactions (a node can opt-out via various mechanisms such as blocks-only or block-only-relay), address relay is under-specified.

For example, we had a discussion [1] on whether SPV nodes store/relay IP addresses. While it seems they don’t do it currently in practice, in some cases they should if they want to be secure and reliable.

### Motivation

This change would decouple addr relay considerations from light/full node/block-relay-only.
This would also allow us to easier analyze (in a scientific sense, not in a spying sense) and adjust address relay, which currently seems to have understudied properties and guarantees.
In practice, this may allow more efficient address relay (fewer messages and less time to relay a new address across all nodes) both immediately and potentially long-term.

### Solution

I want to suggest making explicit whether a node promises to participate in address relay by a) forwarding unsolicited messages (I work on a somewhat related issue in this PR [2]) , and, b) responding to GETADDR.

In my opinion, these 2 signals (a and b) should be viewed independently.

Obviously, these signals should not be relied upon and future protocol changes should assume they may represent lies.
However, explicitly opting-out of relay addresses will help to improve non-adversarial address relay.

### Implementation

I see 2 ways to implement this:
- 2 new service bits
- per-link-direction negotiation: e.g., use BIP-155 (a new message sendaddrv2 is discussed here [3] and can be used to signal this)

Both of them can allow decoupling addr relay from node type, but they do have different trade-offs.

#### Service bits

Having service bits makes sense only if nodes are going to make peering decisions based on it. (everything else might be achieved without introducing a service bit). It is not clear to me whether this makes sense in this context.

The fundamental problem with service bits is that they make a uniform “promise” for all connections to a given node. E.g., if node X announces NODE_ADDR_FORWARD, all nodes in the network expect node X to forward addresses. (If the “promise” is not strong, then additional negotiation is required anyway, so service bits do not solve the problem).

It’s worth keeping in mind that all of the honest reachable full nodes nodes DO relay addresses, and we already won’t connect to those nodes which don’t (light clients). Service bits won’t help here because the problem of connecting to non-addr-relaying full nodes does not exist.
Maybe, if we think that a large fraction of reachable nodes might start completely disabling addr relay to all in the future, then it makes sense to have this service bit, to prevent nodes from accidentally connecting to these peers only and not learning addrs.

Intuitively, it’s also easier to shoot in the leg with the deployment of service bits (might make it easier for attacker to accumulate connections comparing to the case of victims choosing their peers uniformly at random without considering new service bit).

#### Per-link-direction negotiation

This approach does not have the shortcomings mentioned above.

In addition, I think that having more flexibility (Per-link-direction negotiation) is better for the future of the protocol, where some nodes might want to opt-out of addr relay for a subset of their links.
(A node might want to opt-out from addr relay for particular links due to privacy reasons because addr-relay currently leaks information and maybe we shouldn’t relay transactions through the same links).

And I think this future is much more likely to happen than a future where a significant fraction of reachable nodes disable addr relay to *everyone* and need to announce this to the network. Also, even if needed, this can be done with per-link-direction negotiation too, and handled by the peers accordingly.

Per-link-direction negotiation also allows to decouple the behaviour from inbound/outbound type of connection (currently we do not respond to GETADDR from outbound). This logic seems not fundamental to me, but rather a temporary heuristic to prevent attacks, which might be changed in future.

### Conclusion

I think the solution fundamentally depends on the answer to:
“Do we believe that some of the future security advices for node operators would be to disable address relay to all (or most) of the links”.

If yes, I think we should use service bits.
If no, I think we should use per-link-direction negotiation.

If the answer will change, we can also add a service bit later.

Anyway, according to the current considerations I explained in this email, I’d suggest extending BIP-155 with per-link-direction negotiation, but I’m interested in the opinion of the community.

### References

1. Bitcoin core dev IRC meeting (http://www.erisian.com.au/bitcoin-core-dev/log-2019-10-17.html)
2. p2p: Avoid forwarding ADDR messages to SPV nodes (https://github.com/bitcoin/bitcoin/pull/17194)
3. BIP 155: addrv2 BIP proposal (https://github.com/bitcoin/bips/pull/766)

– gleb