Skip to content

fix(enr): handle short port values without throwing - #339

Merged
wemeetagain merged 3 commits into
masterfrom
agent/handle-short-enr-ports
Aug 11, 2026
Merged

fix(enr): handle short port values without throwing#339
wemeetagain merged 3 commits into
masterfrom
agent/handle-short-enr-ports

Conversation

@nflaig

@nflaig nflaig commented Aug 9, 2026

Copy link
Copy Markdown
Member

What changed

  • normalize ENR port bytes before getProtocolValue() reads them
  • accept valid one-byte and two-byte big-endian port values
  • return undefined for empty, zero, or oversized port values instead of throwing
  • keep low ports produced by the existing setters usable by getLocationMultiaddr()
  • add ENR-level regression tests and direct coverage for discv5's getSocketAddressOnENR() path

Why

A mainnet Lodestar v1.45.0 node using @chainsafe/enr@6.0.1 and @chainsafe/discv5@12.0.1 received a signed remote ENR with a short udp value. During session establishment, getSocketAddressOnENR() accessed enr.udp, and getProtocolValue() threw:

uncaughtException: Encoded protocol length should be 2
at getProtocolValue
at get udp
at getSocketAddressOnENRByFamily
at getSocketAddressOnENR
at SessionService.onEstablished

ENR ports are big-endian integers, so one-byte values are valid. Invalid values received from untrusted peers should make the ENR non-contactable rather than escape as an exception.

This follows up on the normalization added in #333 and applies it to the direct port getters used by discv5.

Related: ChainSafe/lodestar#7445, ChainSafe/lodestar#9310.

Impact

Valid compact ports now decode correctly. Empty, zero, and oversized values are ignored without disrupting the discv5 session service. Normal two-byte ports are unchanged.

Validation

  • pnpm build
  • pnpm lint (passes; two existing warnings outside this change)
  • pnpm check-types
  • pnpm test:unit — 28 ENR tests and 65 discv5 tests pass
  • pnpm test:e2e — 5 tests pass

@nflaig
nflaig marked this pull request as ready for review August 9, 2026 18:39
@nflaig
nflaig requested a review from a team as a code owner August 9, 2026 18:39
@nflaig
nflaig requested a review from wemeetagain August 9, 2026 18:41
Comment thread packages/enr/src/enr.ts Outdated
Comment thread packages/enr/src/enr.ts Outdated
@wemeetagain
wemeetagain merged commit ef01255 into master Aug 11, 2026
5 checks passed
@wemeetagain
wemeetagain deleted the agent/handle-short-enr-ports branch August 11, 2026 15:05
@github-actions github-actions Bot mentioned this pull request Aug 11, 2026
nflaig added a commit to ChainSafe/lodestar that referenced this pull request Aug 11, 2026
Picks up ChainSafe/discv5#339, released as `@chainsafe/enr` 6.0.2 and
`@chainsafe/discv5` 12.0.2.

A signed remote ENR may encode a valid port in one byte. In 6.0.1 the
direct port getter expects exactly two bytes, so discv5's session
establishment path can throw `Encoded protocol length should be 2` from
`getSocketAddressOnENR()` instead of treating the ENR as
non-contactable. This was observed on a mainnet Lodestar v1.45.0 node.

ENR 6.0.2 decodes valid one-byte and two-byte big-endian ports and
returns `undefined` for empty, zero or oversized values. discv5 12.0.2
carries that ENR update. Normal two-byte ports are unchanged.

> This PR was written primarily by Codex.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants