ethereum / ethereum/devp2p

discv5/EIP-778: unspecified ENR port range and NODES per-record tolerance

Open
#273 4 comments 3 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
1.1k
Forks
297
Avg merge
5h 50m
Merged PRs (30d)
1

Description

## Summary

Two related points where the discv5 wire spec and EIP-778 are silent, which has led implementations to diverge in ways that create a peer-acquisition availability surface. Filing to get normative guidance.

### 1. Port value range in ENR

EIP-778 defines the predefined keys `tcp`/`udp` (and `tcp6`/`udp6`) only as "big endian integer". It does not state a `uint16` bound, and gives no guidance on what a decoder should do with a value outside 1–65535. The only size constraint in the document is the 300-byte whole-record limit.

Consequences observed across clients:
- Some decoders reject the whole ENR when a port doesn't fit `u16` (strict `uint16` decode).
- Others read the value and later produce an undialable endpoint (e.g. a `tcp` of 0, or a truncated value).

Question: should ENR port values be normatively constrained to `uint16` (1–65535), and should a decoder reject just the offending key, reject the record, or clamp?

### 2. Per-record tolerance inside a NODES response

The wire spec defines `NODES` as `[request-id, total, [ENR, ...]]` and says records are "encoded and verified as specified in EIP-778", and that a recipient "should verify that the received nodes match the requested distances" — but it says nothing about what to do when **one** record in the list fails to decode or verify.

Implementations diverge:
- Several abort decoding of the **entire** `NODES` message when any single record fails (so one bad record discards up to N good sibling records).
- At least one isolates per-record and skips only the bad one.

Because `NODES` records are relayed from a responder's own routing table, a single malformed-but-signed ENR propagating through honest nodes degrades the `NODES` responses those honest nodes serve — an availability surface, not just a per-peer nuisance.

Question: should the spec state that a recipient MUST/SHOULD skip an individual invalid record and process the remainder, rather than dropping the whole response?

## Why raise it

The spec being silent means all current behaviors are equally "compliant," yet they differ in robustness. A one-line normative statement on each point would let clients converge on the resilient behavior. This came out of a cross-client audit where the "one bad record poisons the batch" pattern appeared independently in multiple discv5 implementations (client-side issue filed at sigp/discv5#308).

Possibly relevant to the discv5 v5.2 work (#226) and the attack-mitigation collection (#161).

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading the EIP-778 port definitions and the discv5 NODES encoding and verification requirements, then review the related discv5 v5.2 and attack-mitigation issues and sigp/discv5#308. Done means reaching agreement on normative handling for out-of-range ports and invalid records, then expressing both decisions in the relevant specification text.

Written by the indexing model from the issue text.

Assessment

Domain
distributed-systems, networking
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.