Skip to content

feat(net): advertise --nat extip/extaddr IP in discv5 ENR#23863

Open
nktaushanov wants to merge 4 commits intoparadigmxyz:mainfrom
nktaushanov:discv5-advertise-non-local-ip
Open

feat(net): advertise --nat extip/extaddr IP in discv5 ENR#23863
nktaushanov wants to merge 4 commits intoparadigmxyz:mainfrom
nktaushanov:discv5-advertise-non-local-ip

Conversation

@nktaushanov
Copy link
Copy Markdown

Issue:

This change is required because when running reth nodes in Kubernetes
behind a load balancer, discv5 is not working. The local ENR was built from
the UDP listen address (the pod IP), so peers could never reach the node on
the LB's public IP. discv5's peer-observation ENR update doesn't help here
either — the LB rewrites source addresses, so observed IPs are noise.

Changes:

Adds an advertised_ip override on the discv5 config and wires --nat (the
static extip:/extaddr: variants) into it, so the locally built ENR carries
the user-provided external address instead of the UDP listen IP. Also disables
discv5's peer-observation ENR update when an override is set, so the
statically advertised address can't be flapped by observed source IPs.

Useful for nodes reachable on an address they don't bind locally (load
balancer, static NAT, 1:1 DNAT). Async resolvers (upnp, publicip, any)
are unaffected and still rely on discv5's observation-based update.

nktaushanov and others added 3 commits April 30, 2026 14:38
Adds `advertised_ip: Option<IpAddr>` to `reth_discv5::Config`. When
set, `build_local_enr` uses it for the ENR `ip4`/`ip6` field regardless
of the UDP listen address, and `enr_update` is disabled so discv5's
peer-observation does not overwrite the static value.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
When `--nat extip:<IP>` or `--nat extaddr:<DOMAIN>` is set, the
resolved IP is now wired into the discv5 `advertised_ip` field so it
appears in the ENR gossiped to peers. Only `ExternalIp`/`ExternalAddr`
variants are resolved synchronously; other variants keep existing
peer-observation behaviour.

Fixes nodes behind load balancers that bound discv5 to 0.0.0.0 and
gossiped an ENR with no ip4 field, breaking inbound gossip-based peer
discovery.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Expand `if advertised_ip.is_some()` block with comment above
- Use `nat.clone().and_then(|n| n.as_external_ip(0))` (idiomatic)
- Fix `netif` doc: no argument accepted
- Compact Config destructure in `build_local_enr` per nightly fmt
- Assert `udp6` is present in dual-stack test (documented edge case)

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant