Skip to content

feat(libp2p): validate config options at startup - #3659

Open
sharmis-tp wants to merge 3 commits into
libp2p:mainfrom
sharmis-tp:feat/config-validation
Open

sharmis-tp wants to merge 3 commits into
libp2p:mainfrom
sharmis-tp:feat/config-validation

Conversation

@sharmis-tp

Copy link
Copy Markdown

Description

Related #1573

Adds config validation to the libp2p package only, as suggested on the issue; other modules can follow. validateConfig() now checks the options this package consumes directly with a valibot schema and fails fast with an InvalidParametersError that names the field, e.g. "Invalid libp2p config: addresses.listen.1 is not a valid multiaddr: foo".

Validated: address lists (listen, announce, noAnnounce, appendAnnounce, connectionManager.allow/deny) must parse as multiaddrs; connection manager limits and timeouts must be non-negative numbers (Infinity allowed); maxConnections must be > 0; connectionMonitor flags must be booleans; transportManager.faultTolerance must be a FaultTolerance value. Unknown keys are allowed so services keep their own options.

Notes & open questions

  • Library choice and bundle sizes are in the issue comment: valibot adds about 1.5 KB gzip to the browser bundle.
  • Multiaddr instances are accepted in address lists because the address manager already calls toString() on them.
  • The existing "maxConnections must be greater than 0" wording is kept, so the connection manager test still passes.

Change checklist

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation if necessary (this includes comments as well)
  • I have added tests that prove my fix is effective or that my feature works

@sharmis-tp
sharmis-tp requested a review from a team as a code owner October 10, 2026 16:48
@tabcat

tabcat commented Oct 15, 2026

Copy link
Copy Markdown
Member

The validation calls should happen inside of the constructors. The constructor should validate only parts of the config that class uses directly. Config options that get passed to sub-module classes are validated by those sub-modules. The validation code should live somewhere by the constructor that calls it in most cases. Some of the utilities, like multiaddrInput, could go in a new file inside of @libp2p/utils in a file named valibot.ts. Try with just the Libp2p class and one of the sub-modules.

@sharmis-tp

Copy link
Copy Markdown
Author

Thanks @tabcat, reworked as you suggested:

  • Validation now happens in the constructors. Libp2p validates only what it reads itself (nodeInfo, the factory arrays such as transports and streamMuxers, services, and connectionMonitor.enabled). AddressManager validates its own addresses options.
  • The shared pieces are in a new @libp2p/utils file, valibot.ts: multiaddrInput, nonNegativeNumber, and a small validateOptions helper that throws an InvalidParametersError naming the first bad option, e.g. Invalid addresses config: listen.1 is not a valid multiaddr: not-a-multiaddr.
  • The schema in config.ts is gone, so the other sub-modules (connection manager, transport manager, connection monitor, upgrader) aren't validated yet. I'll add them the same way if this shape looks right.

Tests: a new valibot spec in @libp2p/utils, and config.spec.ts now goes through createLibp2p. Node and Chrome tests pass for both packages (libp2p 279; utils 292 node / 287 Chrome), as do lint, dep-check, doc-check and spell-check.

One note: announceFilter isn't validated, since existing tests pass sinon stub objects for it and it's a pass-through callback.

This branch has not been deployed

No deployments
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