Skip to content

Commit

Permalink
feat: refactored config to validate before returning service (libp2p#…
Browse files Browse the repository at this point in the history
  • Loading branch information
maschad committed Jul 4, 2023
1 parent 73f9fc7 commit 893e068
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 86 deletions.
2 changes: 1 addition & 1 deletion packages/libp2p/.aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default {
fetch: fetchService(),
relay: circuitRelayServer({
reservations: {
maxReservations: Infinity
maxReservations: 100000
}
})
}
Expand Down
19 changes: 19 additions & 0 deletions packages/libp2p/src/circuit-relay/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import pDefer from 'p-defer'
import { MAX_CONNECTIONS } from '../../connection-manager/constants.js'
import {
CIRCUIT_PROTO_CODE,
DEFAULT_DURATION_LIMIT,
DEFAULT_HOP_TIMEOUT,
DEFAULT_MAX_RESERVATION_CLEAR_INTERVAL,
DEFAULT_MAX_RESERVATION_STORE_SIZE,
DEFAULT_MAX_RESERVATION_TTL,
RELAY_SOURCE_TAG
, RELAY_V2_HOP_CODEC, RELAY_V2_STOP_CODEC
} from '../constants.js'
Expand All @@ -28,6 +32,8 @@ import type { AddressManager } from '@libp2p/interface-internal/address-manager'
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
import type { PeerMap } from '@libp2p/peer-collections'
import { object, number, boolean } from 'yup'
import { DEFAULT_MAX_INBOUND_STREAMS, DEFAULT_MAX_OUTBOUND_STREAMS } from '../../registrar.js'

const log = logger('libp2p:circuit-relay:server')

Expand Down Expand Up @@ -438,6 +444,19 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
}

export function circuitRelayServer (init: CircuitRelayServerInit = {}): (components: CircuitRelayServerComponents) => CircuitRelayService {
object({
hopTimeout: number().min(0).integer().default(DEFAULT_HOP_TIMEOUT),
reservations: object({
maxReservations: number().integer().min(0).default(DEFAULT_MAX_RESERVATION_STORE_SIZE),
reservationClearInterval: number().integer().min(0).default(DEFAULT_MAX_RESERVATION_CLEAR_INTERVAL),
applyDefaultLimit: boolean().default(true),
reservationTtl: number().integer().min(0).default(DEFAULT_MAX_RESERVATION_TTL),
defaultDurationLimit: number().integer().min(0).default(DEFAULT_DURATION_LIMIT).max(init?.reservations?.reservationTtl ?? DEFAULT_MAX_RESERVATION_TTL, `default duration limit must be less than reservation TTL: ${init?.reservations?.reservationTtl}`)
}),
maxInboundHopStreams: number().integer().min(0).default(DEFAULT_MAX_INBOUND_STREAMS),
maxOutboundHopStreams: number().integer().min(0).default(DEFAULT_MAX_OUTBOUND_STREAMS)
}).validateSync(init)

return (components) => {
return new CircuitRelayServer(components, init)
}
Expand Down
21 changes: 1 addition & 20 deletions packages/libp2p/src/circuit-relay/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ import { abortableSource } from 'abortable-iterator'
import { anySignal } from 'any-signal'
import { CID } from 'multiformats/cid'
import { sha256 } from 'multiformats/hashes/sha2'
import { object, number, boolean } from 'yup'
import { DEFAULT_MAX_INBOUND_STREAMS, DEFAULT_MAX_OUTBOUND_STREAMS } from '../registrar.js'
import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT, DEFAULT_HOP_TIMEOUT, DEFAULT_MAX_RESERVATION_CLEAR_INTERVAL, DEFAULT_MAX_RESERVATION_STORE_SIZE, DEFAULT_MAX_RESERVATION_TTL } from './constants.js'
import { type CircuitRelayServerInit, circuitRelayServer, type CircuitRelayServerComponents } from './server/index.js'
import type { CircuitRelayService } from './index.js'
import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT } from './constants.js'
import type { Limit } from './pb/index.js'
import type { Stream } from '@libp2p/interface/connection'
import type { Source } from 'it-stream-types'
Expand Down Expand Up @@ -128,18 +124,3 @@ export function getExpirationMilliseconds (expireTimeSeconds: bigint): number {
// downcast to number to use with setTimeout
return Number(expireTimeMillis - BigInt(currentTime))
}

export const validateCircuitRelayServicesConfig = (opts: CircuitRelayServerInit): (components: CircuitRelayServerComponents) => CircuitRelayService => {
return circuitRelayServer(object({
hopTimeout: number().min(0).integer().default(DEFAULT_HOP_TIMEOUT).optional(),
reservations: object({
maxReservations: number().integer().min(0).default(DEFAULT_MAX_RESERVATION_STORE_SIZE).optional(),
reservationClearInterval: number().integer().min(0).default(DEFAULT_MAX_RESERVATION_CLEAR_INTERVAL).optional(),
applyDefaultLimit: boolean().default(true).optional(),
reservationTtl: number().integer().min(0).default(DEFAULT_MAX_RESERVATION_TTL).optional(),
defaultDurationLimit: number().integer().min(0).default(DEFAULT_DURATION_LIMIT).max(opts?.reservations?.reservationTtl ?? DEFAULT_MAX_RESERVATION_TTL, `default duration limit must be less than reservation TTL: ${opts?.reservations?.reservationTtl}`).optional()
}),
maxInboundHopStreams: number().integer().min(0).default(DEFAULT_MAX_INBOUND_STREAMS).optional(),
maxOutboundHopStreams: number().integer().min(0).default(DEFAULT_MAX_OUTBOUND_STREAMS).optional()
}).validateSync(opts))
}
11 changes: 7 additions & 4 deletions packages/libp2p/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import { publicAddressesFirst } from '@libp2p/utils/address-sort'
import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
import mergeOptions from 'merge-options'
import type { ServiceMap, RecursivePartial } from '@libp2p/interface'
import type { Libp2pInit, ServiceFactoryMap } from '../index.js'
import type { Libp2pInit } from '../index.js'
import type { AddressManagerInit } from '../address-manager'
import { validateAddressManagerConfig } from '../address-manager/utils.js'
import { object } from 'yup'
import { validateConnectionManagerConfig } from '../connection-manager/utils.js'
import type { ConnectionManagerInit } from '../connection-manager/index.js'
import { validateServicesConfig } from './helpers.js'

const DefaultConfig: Partial<Libp2pInit> = {
connectionManager: {
Expand All @@ -29,8 +28,12 @@ export function validateConfig <T extends ServiceMap = Record<string, unknown>>
connectionManager: validateConnectionManagerConfig(opts?.connectionManager as ConnectionManagerInit),
})

//@ts-expect-error
opts.services = validateServicesConfig(opts?.services as ServiceFactoryMap<T>) as ServiceFactoryMap<T>
if (opts?.services) {
// @ts-expect-error
if ((opts.services?.kadDHT || opts.services?.relay || opts.services?.ping) && !opts.services.identify) {
throw new Error('identify service is required when using kadDHT, relay, or ping')
}
}

const parsedOpts = libp2pConfig.validateSync(opts)

Expand Down
19 changes: 0 additions & 19 deletions packages/libp2p/src/config/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import { multiaddr } from '@multiformats/multiaddr'
import { validateCircuitRelayServicesConfig } from '../circuit-relay/utils.js'
import { validateIdentifyConfig } from '../identify/config.js'
import type { CircuitRelayServerInit } from '../circuit-relay/server/index.js'
import type { IdentifyServiceInit } from '../identify/index.js'
import type { ServiceMap } from '@libp2p/interface-libp2p'
import type { PingServiceInit } from '../ping/index.js'
import { validatePingConfig } from '../ping/config.js'
import type { FetchServiceInit } from '../fetch/index.js'
import { validateFetchConfig } from '../fetch/config.js'

export const validateMultiaddr = (value: Array<string | undefined> | undefined): boolean => {
value?.forEach((addr) => {
Expand All @@ -19,13 +10,3 @@ export const validateMultiaddr = (value: Array<string | undefined> | undefined):
})
return true
}

export const validateServicesConfig = (opts: ServiceMap): ServiceMap => {
return {
ping: validatePingConfig(opts?.ping as PingServiceInit),
fetch: validateFetchConfig(opts?.fetch as FetchServiceInit),
identify: validateIdentifyConfig(opts?.identify as IdentifyServiceInit),
relay: validateCircuitRelayServicesConfig(opts?.relay as CircuitRelayServerInit),
...opts,
}
}
12 changes: 0 additions & 12 deletions packages/libp2p/src/fetch/config.ts

This file was deleted.

11 changes: 10 additions & 1 deletion packages/libp2p/src/fetch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { pipe } from 'it-pipe'
import { fromString as uint8arrayFromString } from 'uint8arrays/from-string'
import { toString as uint8arrayToString } from 'uint8arrays/to-string'
import { codes } from '../errors.js'
import { PROTOCOL_NAME, PROTOCOL_VERSION } from './constants.js'
import { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, PROTOCOL_VERSION, TIMEOUT } from './constants.js'
import { FetchRequest, FetchResponse } from './pb/proto.js'
import type { AbortOptions } from '@libp2p/interface'
import type { Stream } from '@libp2p/interface/connection'
import type { PeerId } from '@libp2p/interface/peer-id'
import type { Startable } from '@libp2p/interface/startable'
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
import { number, object, string } from 'yup'

const log = logger('libp2p:fetch')

Expand Down Expand Up @@ -309,5 +310,13 @@ class DefaultFetchService implements Startable, FetchService {
}

export function fetchService (init: FetchServiceInit = {}): (components: FetchServiceComponents) => FetchService {

object({
protocolPrefix: string().default('ipfs'),
timeout: number().integer().default(TIMEOUT),
maxInboundStreams: number().integer().min(0).default(MAX_INBOUND_STREAMS),
maxOutboundStreams: number().integer().min(0).default(MAX_OUTBOUND_STREAMS),
}).validateSync(init)

return (components) => new DefaultFetchService(components, init)
}
15 changes: 0 additions & 15 deletions packages/libp2p/src/identify/config.ts

This file was deleted.

18 changes: 17 additions & 1 deletion packages/libp2p/src/identify/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import {
AGENT_VERSION,
MAX_IDENTIFY_MESSAGE_SIZE,
MAX_INBOUND_STREAMS,
MAX_OUTBOUND_STREAMS,
MULTICODEC_IDENTIFY,
MULTICODEC_IDENTIFY_PUSH
MULTICODEC_IDENTIFY_PUSH,
PROTOCOL_PREFIX,
TIMEOUT
} from './consts.js'
import { DefaultIdentifyService } from './identify.js'
import { Identify } from './pb/message.js'
Expand All @@ -11,6 +17,7 @@ import type { PeerStore } from '@libp2p/interface/peer-store'
import type { AddressManager } from '@libp2p/interface-internal/address-manager'
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
import type { Registrar } from '@libp2p/interface-internal/registrar'
import { number, object, string } from 'yup'

export interface IdentifyServiceInit {
/**
Expand Down Expand Up @@ -61,5 +68,14 @@ export const multicodecs = {
export const Message = { Identify }

export function identifyService (init: IdentifyServiceInit = {}): (components: IdentifyServiceComponents) => DefaultIdentifyService {
object({
protocolPrefix: string().default(PROTOCOL_PREFIX),
agentVersion: string().default(AGENT_VERSION),
timeout: number().integer().default(TIMEOUT),
maxIdentifyMessageSize: number().integer().min(0).default(MAX_IDENTIFY_MESSAGE_SIZE),
maxInboundStreams: number().integer().min(0).default(MAX_INBOUND_STREAMS),
maxOutboundStreams: number().integer().min(0).default(MAX_OUTBOUND_STREAMS),
}).validateSync(init)

return (components) => new DefaultIdentifyService(components, init)
}
12 changes: 0 additions & 12 deletions packages/libp2p/src/ping/config.ts

This file was deleted.

9 changes: 9 additions & 0 deletions packages/libp2p/src/ping/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { Startable } from '@libp2p/interface/startable'
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
import type { Multiaddr } from '@multiformats/multiaddr'
import { number, object, string } from 'yup'

const log = logger('libp2p:ping')

Expand Down Expand Up @@ -136,5 +137,13 @@ class DefaultPingService implements Startable, PingService {
}

export function pingService (init: PingServiceInit = {}): (components: PingServiceComponents) => PingService {

object({
protocolPrefix: string().default(PROTOCOL_PREFIX),
timeout: number().integer().default(TIMEOUT),
maxInboundStreams: number().integer().min(0).default(MAX_INBOUND_STREAMS),
maxOutboundStreams: number().integer().min(0).default(MAX_OUTBOUND_STREAMS)
}).validateSync(init)

return (components) => new DefaultPingService(components, init)
}
4 changes: 3 additions & 1 deletion packages/libp2p/test/connection-manager/resolver.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { createLibp2pNode, type Libp2pNode } from '../../src/libp2p.js'
import type { PeerId } from '@libp2p/interface/peer-id'
import type { Transport } from '@libp2p/interface/transport'
import type { Multiaddr } from '@multiformats/multiaddr'
import { identifyService } from '../../src/identify/index.js'

const relayAddr = multiaddr(process.env.RELAY_MULTIADDR)

Expand Down Expand Up @@ -93,7 +94,8 @@ describe('dialing (resolvable addresses)', () => {
plaintext()
],
services: {
relay: circuitRelayServer()
relay: circuitRelayServer(),
identify: identifyService()
},
connectionGater: mockConnectionGater()
})
Expand Down

0 comments on commit 893e068

Please sign in to comment.