Skip to content

Commit

Permalink
Add support for arbitrary modules.
Browse files Browse the repository at this point in the history
  • Loading branch information
saul-jb authored and achingbrain committed Apr 25, 2023
1 parent 8d408d5 commit 1554505
Show file tree
Hide file tree
Showing 34 changed files with 1,080 additions and 1,112 deletions.
12 changes: 6 additions & 6 deletions doc/LIMITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ We can also limit the number of connections in a "pending" state. These connecti
All fields are optional. The default values are defined in [src/connection-manager/index.ts](https://github.com/libp2p/js-libp2p/blob/master/src/connection-manager/index.ts) - please see that file for the current values.

```ts
const node = await createLibp2pNode({
const node = await createLibp2p({
connectionManager: {
/**
* The total number of connections allowed to be open at one time
Expand Down Expand Up @@ -69,7 +69,7 @@ To prevent individual peers from opening multiple connections to a node, an `inb
All fields are optional. The default values are defined in [src/connection-manager/index.ts](https://github.com/libp2p/js-libp2p/blob/master/src/connection-manager/index.ts) - please see that file for the current values.

```ts
const node = await createLibp2pNode({
const node = await createLibp2p({
connectionManager: {
/**
* A remote peer may attempt to open up to this many connections per second,
Expand All @@ -93,7 +93,7 @@ These settings are done on a per-muxer basis, please see the README of the relev
All fields are optional. The default values are defined in [@libp2p/mplex/src/mplex.ts](https://github.com/libp2p/js-libp2p-mplex/blob/master/src/mplex.ts) - please see that file for the current values.

```ts
const node = await createLibp2pNode({
const node = await createLibp2p({
muxers: [
mplex({
/**
Expand Down Expand Up @@ -133,7 +133,7 @@ const node = await createLibp2pNode({
All fields are optional. The default values are defined in [@chainsafe/libp2p-yamux/src/config.ts](https://github.com/ChainSafe/js-libp2p-yamux/blob/master/src/config.ts) - please see that file for the current values.

```ts
const node = await createLibp2pNode({
const node = await createLibp2p({
muxers: [
yamux({
/**
Expand Down Expand Up @@ -186,7 +186,7 @@ The [@libp2p/tcp](https://github.com/libp2p/js-libp2p-tcp) transport allows addi
All fields are optional. The full list of options is defined in [@libp2p/tcp/src/index.ts](https://github.com/libp2p/js-libp2p-tcp/blob/master/src/index.ts) - please see that file for more details.

```ts
const node = await createLibp2pNode({
const node = await createLibp2p({
transports: [
tcp({
/**
Expand Down Expand Up @@ -215,7 +215,7 @@ const node = await createLibp2pNode({
It is possible to configure some hosts to always accept connections from and some to always reject connections from.

```js
const node = await createLibp2pNode({
const node = await createLibp2p({
connectionManager: {
/**
* A list of multiaddrs, any connection with a `remoteAddress` property
Expand Down
6 changes: 3 additions & 3 deletions doc/METRICS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ Although designed to primarily integrate with tools such as [Prometheus](https:/
First enable metrics tracking by supplying a [Metrics](https://www.npmjs.com/package/@libp2p/interface-metrics) implementation:

```js
import { createLibp2pNode } from 'libp2p'
import { createLibp2p } from 'libp2p'
import { prometheusMetrics } from '@libp2p/prometheus-metrics'

const node = await createLibp2pNode({
const node = await createLibp2p({
metrics: prometheusMetrics()
//... other config
})
Expand Down Expand Up @@ -164,7 +164,7 @@ Metrics implementations will allow extracting the values for presentation in an
import { prometheusMetrics } from '@libp2p/prometheus-metrics'
import client from 'prom-client'

const libp2p = createLibp2pNode({
const libp2p = createLibp2p({
metrics: prometheusMetrics()
//... other config
})
Expand Down
20 changes: 7 additions & 13 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import mergeOptions from 'merge-options'
import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
import { AGENT_VERSION } from './identify/consts.js'
import { publicAddressesFirst } from '@libp2p/utils/address-sort'
import { FaultTolerance } from '@libp2p/interface-transport'
import type { Multiaddr } from '@multiformats/multiaddr'
import type { Libp2pInit } from './index.js'
import { codes, messages } from './errors.js'
import { CodeError } from '@libp2p/interfaces/errors'
import type { RecursivePartial } from '@libp2p/interfaces'
import { isNode, isBrowser, isWebWorker, isElectronMain, isElectronRenderer, isReactNative } from 'wherearewe'
import type { ServiceMap } from '@libp2p/interface-libp2p'

const DefaultConfig: Partial<Libp2pInit> = {
addresses: {
Expand All @@ -33,6 +32,8 @@ const DefaultConfig: Partial<Libp2pInit> = {
bootDelay: 10e3
}
},
/*
nat: {
enabled: true,
ttl: 7200,
Expand Down Expand Up @@ -77,10 +78,12 @@ const DefaultConfig: Partial<Libp2pInit> = {
startupDelay: 5000,
refreshInterval: 60000
}
*/
}

export function validateConfig (opts: RecursivePartial<Libp2pInit>): Libp2pInit {
const resultingOptions: Libp2pInit = mergeOptions(DefaultConfig, opts)
export function validateConfig <T extends ServiceMap = {}> (opts: RecursivePartial<Libp2pInit<T>>): Libp2pInit<T> {
const resultingOptions: Libp2pInit<T> = mergeOptions(DefaultConfig, opts)

if (resultingOptions.transports == null || resultingOptions.transports.length < 1) {
throw new CodeError(messages.ERR_TRANSPORTS_REQUIRED, codes.ERR_TRANSPORTS_REQUIRED)
Expand All @@ -94,14 +97,5 @@ export function validateConfig (opts: RecursivePartial<Libp2pInit>): Libp2pInit
throw new CodeError(messages.ERR_PROTECTOR_REQUIRED, codes.ERR_PROTECTOR_REQUIRED)
}

// Append user agent version to default AGENT_VERSION depending on the environment
if (resultingOptions.identify.host.agentVersion === AGENT_VERSION) {
if (isNode || isElectronMain) {
resultingOptions.identify.host.agentVersion += ` UserAgent=${globalThis.process.version}`
} else if (isBrowser || isWebWorker || isElectronRenderer || isReactNative) {
resultingOptions.identify.host.agentVersion += ` UserAgent=${globalThis.navigator.userAgent}`
}
}

return resultingOptions
}
56 changes: 50 additions & 6 deletions src/fetch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ import type { ConnectionManager } from '@libp2p/interface-connection-manager'

const log = logger('libp2p:fetch')

const DEFAULT_TIMEOUT = 10000

export interface FetchServiceInit {
protocolPrefix: string
maxInboundStreams: number
maxOutboundStreams: number
protocolPrefix?: string
maxInboundStreams?: number
maxOutboundStreams?: number

/**
* How long we should wait for a remote peer to send any data
*/
timeout: number
timeout?: number
}

export interface HandleMessageOptions {
Expand All @@ -45,13 +47,51 @@ export interface FetchServiceComponents {
connectionManager: ConnectionManager
}

export interface FetchService {
/**
* The protocol name used by this fetch service
*/
protocol: string

/**
* Sends a request to fetch the value associated with the given key from the given peer
*/
fetch (peer: PeerId, key: string, options?: AbortOptions): Promise<Uint8Array | null>

/**
* Registers a new lookup callback that can map keys to values, for a given set of keys that
* share the same prefix
*
* @example
*
* ```js
* // ...
* libp2p.fetchService.registerLookupFunction('/prefix', (key) => { ... })
* ```
*/
registerLookupFunction (prefix: string, lookup: LookupFunction): void

/**
* Registers a new lookup callback that can map keys to values, for a given set of keys that
* share the same prefix.
*
* @example
*
* ```js
* // ...
* libp2p.fetchService.unregisterLookupFunction('/prefix')
* ```
*/
unregisterLookupFunction (prefix: string, lookup?: LookupFunction): void
}

/**
* A simple libp2p protocol for requesting a value corresponding to a key from a peer.
* Developers can register one or more lookup function for retrieving the value corresponding to
* a given key. Each lookup function must act on a distinct part of the overall key space, defined
* by a fixed prefix that all keys that should be routed to that lookup function will start with.
*/
export class FetchService implements Startable {
class DefaultFetchService implements Startable, FetchService {
public readonly protocol: string
private readonly components: FetchServiceComponents
private readonly lookupFunctions: Map<string, LookupFunction>
Expand Down Expand Up @@ -106,7 +146,7 @@ export class FetchService implements Startable {
// create a timeout if no abort signal passed
if (signal == null) {
log('using default timeout of %d ms', this.init.timeout)
timeoutController = new TimeoutController(this.init.timeout)
timeoutController = new TimeoutController(this.init.timeout ?? DEFAULT_TIMEOUT)
signal = timeoutController.signal

try {
Expand Down Expand Up @@ -274,3 +314,7 @@ export class FetchService implements Startable {
this.lookupFunctions.delete(prefix)
}
}

export function fetchService (init: FetchServiceInit = {}): (components: FetchServiceComponents) => FetchService {
return (components) => new DefaultFetchService(components, init)
}
Loading

0 comments on commit 1554505

Please sign in to comment.