Skip to content

fix: skip validation when encapsulating/decapsulating #420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

achingbrain
Copy link
Member

@achingbrain achingbrain commented Jun 5, 2025

Shifts expensive validation to validate function which gives the user more control over operations take place.

Skips validation when we create a multiaddr from an existing multiaddr.

Adds a validate method that can perform explicit validation.

For example we currently run multiple regex passes over IP addresses when creating new multiaddrs which can cause CPU bottlenecks.

Running the benchmark added in this PR it's an order of magnitude faster:

┌─────────┬──────────────────────────────────┬─────────────┬────────┬───────┬────────┐
│ (index) │ Implementation                   │ ops/s       │ ms/op  │ runs  │ p99    │
├─────────┼──────────────────────────────────┼─────────────┼────────┼───────┼────────┤
│ 0       │ 'head'                           │ '105679.89' │ '0.01' │ 50000 │ '0.01' │
│ 1       │ '@multiformats/[email protected]' │ '18244.31'  │ '0.06' │ 50000 │ '0.13' │
└─────────┴──────────────────────────────────┴─────────────┴────────┴───────┴────────┘

@achingbrain achingbrain force-pushed the feat/add-validation-function branch 3 times, most recently from 6977a41 to df20b6b Compare June 5, 2025 15:16
Shifts validation to `validate` function which gives the user more
control over when expensive validation operations take place.

For example we currently run multiple regex passes over IP addresses
when creating new multiaddrs which can cause CPU bottlenecks.
@achingbrain achingbrain force-pushed the feat/add-validation-function branch from df20b6b to ec0635f Compare June 5, 2025 15:25
@achingbrain achingbrain changed the title feat: add validate function feat: add validate function and improve performance Jun 6, 2025
@achingbrain
Copy link
Member Author

Refs: ipshipyard/roadmaps#1

@achingbrain achingbrain changed the title feat: add validate function and improve performance fix: skip validation when encapsulating/decapsulating Jun 13, 2025
Copy link
Contributor

@SgtPooki SgtPooki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did not review it all.

Comment on lines +12 to +13
if (value < 0) {
throw new ValidationError('Value must be a positive integer')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we considering 0 positive? We should indicate that in the message,

Suggested change
if (value < 0) {
throw new ValidationError('Value must be a positive integer')
if (value < 0) {
throw new ValidationError('Value must be a positive integer, or zero')

or guard against 0

Suggested change
if (value < 0) {
throw new ValidationError('Value must be a positive integer')
if (value <= 0) {
throw new ValidationError('Value must be a positive integer')

Comment on lines +17 to +21
export function maxValue (max: number): (value: any) => void {
return (value) => {
if (value > max) {
throw new ValidationError(`Value must be smaller than ${max}`)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export function maxValue (max: number): (value: any) => void {
return (value) => {
if (value > max) {
throw new ValidationError(`Value must be smaller than ${max}`)
}
export function maxValue (max: number): (value: any) => void {
return (value) => {
if (value > max) {
throw new ValidationError(`Value must be smaller than or equal to ${max}`)
}

@@ -0,0 +1,40 @@
export const CODE_IP4 = 4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add an jsdoc comment here so someone else can understand how to check if these are valid or not? or how to add a new key in the future?

*/
export const resolvers = new Map<string, Resolver>()

export type { Resolver }

export { MultiaddrFilter } from './filter/multiaddr-filter.js'

/**
* @deprecated DNS resolving will be removed in a future release
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines +11 to +26
function bench (m: typeof multiaddr | typeof multiaddr12): void {
const ma = m('/ip4/127.0.0.1/udp/1234/quic-v1/webtransport/certhash/uEiAkH5a4DPGKUuOBjYw0CgwjvcJCJMD2K_1aluKR_tpevQ/certhash/uEiAfbgiymPP2_nX7Dgir8B4QkksjHp2lVuJZz0F79Be9JA')
ma.encapsulate('/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
ma.decapsulate('/quic-v1')

const ma2 = m(ma.bytes)
ma2.encapsulate('/tls/sni/example.com/http/http-path/path%2Findex.html')
ma2.equals(ma)

ma2.getPath()
ma2.getPeerId()

const ma3 = m('/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/udp/1234/quic-v1/webtransport/certhash/uEiAkH5a4DPGKUuOBjYw0CgwjvcJCJMD2K_1aluKR_tpevQ/certhash/uEiAfbgiymPP2_nX7Dgir8B4QkksjHp2lVuJZz0F79Be9JA')
ma3.encapsulate('/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
ma3.decapsulate('/quic-v1')
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this do any validation on the newer version? if not, it might be good to get a benchmark of the performance with the new validation to ensure there isn't a significant hit there..

Also, can we provide some recommendations for folks as to when & how to validate multiaddrs? i.e. only when reading multiaddr as a string, and then we don't need to again if using ma.* functions.. or whatever the case may be.

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