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).
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(andtcp6/udp6) only as "big endian integer". It does not state auint16bound, 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:
u16(strictuint16decode).tcpof 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
NODESas[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:
NODESmessage when any single record fails (so one bad record discards up to N good sibling records).Because
NODESrecords are relayed from a responder's own routing table, a single malformed-but-signed ENR propagating through honest nodes degrades theNODESresponses 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).