libp2p 1.9.4 → 2.0.0-d101aac4b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.min.js +17 -18
- package/dist/src/components.d.ts.map +1 -1
- package/dist/src/components.js +4 -3
- package/dist/src/components.js.map +1 -1
- package/dist/src/config.d.ts +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +2 -7
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection/index.d.ts +3 -3
- package/dist/src/connection/index.d.ts.map +1 -1
- package/dist/src/connection/index.js +7 -7
- package/dist/src/connection/index.js.map +1 -1
- package/dist/src/connection-manager/connection-pruner.js +1 -1
- package/dist/src/connection-manager/constants.browser.d.ts +0 -8
- package/dist/src/connection-manager/constants.browser.d.ts.map +1 -1
- package/dist/src/connection-manager/constants.browser.js +0 -8
- package/dist/src/connection-manager/constants.browser.js.map +1 -1
- package/dist/src/connection-manager/constants.d.ts +0 -8
- package/dist/src/connection-manager/constants.d.ts.map +1 -1
- package/dist/src/connection-manager/constants.defaults.d.ts +12 -22
- package/dist/src/connection-manager/constants.defaults.d.ts.map +1 -1
- package/dist/src/connection-manager/constants.defaults.js +12 -22
- package/dist/src/connection-manager/constants.defaults.js.map +1 -1
- package/dist/src/connection-manager/constants.js +0 -8
- package/dist/src/connection-manager/constants.js.map +1 -1
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
- package/dist/src/connection-manager/dial-queue.js +29 -15
- package/dist/src/connection-manager/dial-queue.js.map +1 -1
- package/dist/src/connection-manager/index.d.ts +47 -50
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/connection-manager/index.js +23 -57
- package/dist/src/connection-manager/index.js.map +1 -1
- package/dist/src/connection-manager/reconnect-queue.d.ts +35 -0
- package/dist/src/connection-manager/reconnect-queue.d.ts.map +1 -0
- package/dist/src/connection-manager/reconnect-queue.js +104 -0
- package/dist/src/connection-manager/reconnect-queue.js.map +1 -0
- package/dist/src/connection-monitor.d.ts +1 -0
- package/dist/src/connection-monitor.d.ts.map +1 -1
- package/dist/src/connection-monitor.js +15 -5
- package/dist/src/connection-monitor.js.map +1 -1
- package/dist/src/content-routing.js +6 -6
- package/dist/src/content-routing.js.map +1 -1
- package/dist/src/errors.d.ts +41 -61
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +84 -63
- package/dist/src/errors.js.map +1 -1
- package/dist/src/get-peer.d.ts.map +1 -1
- package/dist/src/get-peer.js +4 -5
- package/dist/src/get-peer.js.map +1 -1
- package/dist/src/index.d.ts +27 -9
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p.d.ts +11 -10
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +13 -31
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/peer-routing.js +8 -8
- package/dist/src/peer-routing.js.map +1 -1
- package/dist/src/registrar.js +7 -7
- package/dist/src/registrar.js.map +1 -1
- package/dist/src/transport-manager.d.ts.map +1 -1
- package/dist/src/transport-manager.js +15 -23
- package/dist/src/transport-manager.js.map +1 -1
- package/dist/src/upgrader.d.ts +8 -8
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +51 -51
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.d.ts.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/package.json +21 -21
- package/src/components.ts +4 -3
- package/src/config.ts +4 -10
- package/src/connection/index.ts +9 -9
- package/src/connection-manager/connection-pruner.ts +1 -1
- package/src/connection-manager/constants.browser.ts +0 -10
- package/src/connection-manager/constants.defaults.ts +14 -27
- package/src/connection-manager/constants.ts +0 -10
- package/src/connection-manager/dial-queue.ts +30 -15
- package/src/connection-manager/index.ts +80 -118
- package/src/connection-manager/reconnect-queue.ts +134 -0
- package/src/connection-monitor.ts +15 -6
- package/src/content-routing.ts +6 -6
- package/src/errors.ts +96 -61
- package/src/get-peer.ts +4 -5
- package/src/index.ts +42 -12
- package/src/libp2p.ts +22 -36
- package/src/peer-routing.ts +8 -8
- package/src/registrar.ts +7 -7
- package/src/transport-manager.ts +15 -23
- package/src/upgrader.ts +55 -56
- package/src/version.ts +1 -1
- package/dist/src/connection-manager/auto-dial.d.ts +0 -47
- package/dist/src/connection-manager/auto-dial.d.ts.map +0 -1
- package/dist/src/connection-manager/auto-dial.js +0 -223
- package/dist/src/connection-manager/auto-dial.js.map +0 -1
- package/dist/typedoc-urls.json +0 -14
- package/src/connection-manager/auto-dial.ts +0 -285
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { KEEP_ALIVE } from '@libp2p/interface'
|
|
2
|
+
import { PeerQueue } from '@libp2p/utils/peer-queue'
|
|
3
|
+
import pRetry from 'p-retry'
|
|
4
|
+
import { MAX_PARALLEL_RECONNECTS } from './constants.js'
|
|
5
|
+
import type { ComponentLogger, Libp2pEvents, Logger, Metrics, Peer, PeerId, PeerStore, Startable, TypedEventTarget } from '@libp2p/interface'
|
|
6
|
+
import type { ConnectionManager } from '@libp2p/interface-internal'
|
|
7
|
+
|
|
8
|
+
export interface ReconnectQueueComponents {
|
|
9
|
+
connectionManager: ConnectionManager
|
|
10
|
+
events: TypedEventTarget<Libp2pEvents>
|
|
11
|
+
peerStore: PeerStore
|
|
12
|
+
logger: ComponentLogger
|
|
13
|
+
metrics?: Metrics
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ReconnectQueueInit {
|
|
17
|
+
retries?: number
|
|
18
|
+
retryInterval?: number
|
|
19
|
+
backoffFactor?: number
|
|
20
|
+
maxParallelReconnects?: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* When peers tagged with `KEEP_ALIVE` disconnect, this component attempts to
|
|
25
|
+
* redial them
|
|
26
|
+
*/
|
|
27
|
+
export class ReconnectQueue implements Startable {
|
|
28
|
+
private readonly log: Logger
|
|
29
|
+
private readonly queue: PeerQueue
|
|
30
|
+
private started: boolean
|
|
31
|
+
private readonly peerStore: PeerStore
|
|
32
|
+
private readonly retries: number
|
|
33
|
+
private readonly retryInterval?: number
|
|
34
|
+
private readonly backoffFactor?: number
|
|
35
|
+
private readonly connectionManager: ConnectionManager
|
|
36
|
+
|
|
37
|
+
constructor (components: ReconnectQueueComponents, init: ReconnectQueueInit = {}) {
|
|
38
|
+
this.log = components.logger.forComponent('libp2p:reconnect-queue')
|
|
39
|
+
this.peerStore = components.peerStore
|
|
40
|
+
this.connectionManager = components.connectionManager
|
|
41
|
+
this.queue = new PeerQueue({
|
|
42
|
+
concurrency: init.maxParallelReconnects ?? MAX_PARALLEL_RECONNECTS,
|
|
43
|
+
metricName: 'libp2p_reconnect_queue',
|
|
44
|
+
metrics: components.metrics
|
|
45
|
+
})
|
|
46
|
+
this.started = false
|
|
47
|
+
this.retries = init.retries ?? 5
|
|
48
|
+
this.backoffFactor = init.backoffFactor
|
|
49
|
+
this.retryInterval = init.retryInterval
|
|
50
|
+
|
|
51
|
+
components.events.addEventListener('peer:disconnect', (evt) => {
|
|
52
|
+
this.maybeReconnect(evt.detail)
|
|
53
|
+
.catch(err => {
|
|
54
|
+
this.log.error('failed to maybe reconnect to %p', evt.detail, err)
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private async maybeReconnect (peerId: PeerId): Promise<void> {
|
|
60
|
+
if (!this.started) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const peer = await this.peerStore.get(peerId)
|
|
65
|
+
|
|
66
|
+
if (!peer.tags.has(KEEP_ALIVE)) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (this.queue.has(peerId)) {
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.queue.add(async (options) => {
|
|
75
|
+
await pRetry(async (attempt) => {
|
|
76
|
+
if (!this.started) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
await this.connectionManager.openConnection(peerId, {
|
|
82
|
+
signal: options?.signal
|
|
83
|
+
})
|
|
84
|
+
} catch (err) {
|
|
85
|
+
this.log('reconnecting to %p attempt %d of %d failed', peerId, attempt, this.retries, err)
|
|
86
|
+
throw err
|
|
87
|
+
}
|
|
88
|
+
}, {
|
|
89
|
+
signal: options?.signal,
|
|
90
|
+
retries: this.retries,
|
|
91
|
+
factor: this.backoffFactor,
|
|
92
|
+
minTimeout: this.retryInterval
|
|
93
|
+
})
|
|
94
|
+
}, {
|
|
95
|
+
peerId
|
|
96
|
+
})
|
|
97
|
+
.catch(err => {
|
|
98
|
+
this.log.error('failed to reconnect to %p', peerId, err)
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
start (): void {
|
|
103
|
+
this.started = true
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async afterStart (): Promise<void> {
|
|
107
|
+
// re-connect to any peers with the KEEP_ALIVE tag
|
|
108
|
+
void Promise.resolve()
|
|
109
|
+
.then(async () => {
|
|
110
|
+
const keepAlivePeers: Peer[] = await this.peerStore.all({
|
|
111
|
+
filters: [(peer) => {
|
|
112
|
+
return peer.tags.has(KEEP_ALIVE)
|
|
113
|
+
}]
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
await Promise.all(
|
|
117
|
+
keepAlivePeers.map(async peer => {
|
|
118
|
+
await this.connectionManager.openConnection(peer.id)
|
|
119
|
+
.catch(err => {
|
|
120
|
+
this.log.error(err)
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
)
|
|
124
|
+
})
|
|
125
|
+
.catch(err => {
|
|
126
|
+
this.log.error(err)
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
stop (): void {
|
|
131
|
+
this.started = false
|
|
132
|
+
this.queue.abort()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomBytes } from '@libp2p/crypto'
|
|
2
|
-
import { serviceCapabilities } from '@libp2p/interface'
|
|
2
|
+
import { serviceCapabilities, setMaxListeners } from '@libp2p/interface'
|
|
3
3
|
import { AdaptiveTimeout } from '@libp2p/utils/adaptive-timeout'
|
|
4
4
|
import { byteStream } from 'it-byte-stream'
|
|
5
5
|
import type { ComponentLogger, Logger, Metrics, Startable } from '@libp2p/interface'
|
|
@@ -11,6 +11,7 @@ const PROTOCOL_VERSION = '1.0.0'
|
|
|
11
11
|
const PROTOCOL_NAME = 'ping'
|
|
12
12
|
const PROTOCOL_PREFIX = 'ipfs'
|
|
13
13
|
const PING_LENGTH = 32
|
|
14
|
+
const DEFAULT_ABORT_CONNECTION_ON_PING_FAILURE = true
|
|
14
15
|
|
|
15
16
|
export interface ConnectionMonitorInit {
|
|
16
17
|
/**
|
|
@@ -65,6 +66,7 @@ export class ConnectionMonitor implements Startable {
|
|
|
65
66
|
private readonly pingIntervalMs: number
|
|
66
67
|
private abortController?: AbortController
|
|
67
68
|
private readonly timeout: AdaptiveTimeout
|
|
69
|
+
private readonly abortConnectionOnPingFailure: boolean
|
|
68
70
|
|
|
69
71
|
constructor (components: ConnectionMonitorComponents, init: ConnectionMonitorInit = {}) {
|
|
70
72
|
this.components = components
|
|
@@ -72,7 +74,7 @@ export class ConnectionMonitor implements Startable {
|
|
|
72
74
|
|
|
73
75
|
this.log = components.logger.forComponent('libp2p:connection-monitor')
|
|
74
76
|
this.pingIntervalMs = init.pingInterval ?? DEFAULT_PING_INTERVAL_MS
|
|
75
|
-
|
|
77
|
+
this.abortConnectionOnPingFailure = init.abortConnectionOnPingFailure ?? DEFAULT_ABORT_CONNECTION_ON_PING_FAILURE
|
|
76
78
|
this.timeout = new AdaptiveTimeout({
|
|
77
79
|
...(init.pingTimeout ?? {}),
|
|
78
80
|
metrics: components.metrics,
|
|
@@ -88,6 +90,7 @@ export class ConnectionMonitor implements Startable {
|
|
|
88
90
|
|
|
89
91
|
start (): void {
|
|
90
92
|
this.abortController = new AbortController()
|
|
93
|
+
setMaxListeners(Infinity, this.abortController.signal)
|
|
91
94
|
|
|
92
95
|
this.heartbeatInterval = setInterval(() => {
|
|
93
96
|
this.components.connectionManager.getConnections().forEach(conn => {
|
|
@@ -99,7 +102,7 @@ export class ConnectionMonitor implements Startable {
|
|
|
99
102
|
})
|
|
100
103
|
const stream = await conn.newStream(this.protocol, {
|
|
101
104
|
signal,
|
|
102
|
-
|
|
105
|
+
runOnLimitedConnection: true
|
|
103
106
|
})
|
|
104
107
|
const bs = byteStream(stream)
|
|
105
108
|
start = Date.now()
|
|
@@ -119,7 +122,7 @@ export class ConnectionMonitor implements Startable {
|
|
|
119
122
|
signal
|
|
120
123
|
})
|
|
121
124
|
} catch (err: any) {
|
|
122
|
-
if (err.
|
|
125
|
+
if (err.name !== 'UnsupportedProtocolError') {
|
|
123
126
|
throw err
|
|
124
127
|
}
|
|
125
128
|
|
|
@@ -131,8 +134,14 @@ export class ConnectionMonitor implements Startable {
|
|
|
131
134
|
}
|
|
132
135
|
})
|
|
133
136
|
.catch(err => {
|
|
134
|
-
this.log.error('error during heartbeat
|
|
135
|
-
|
|
137
|
+
this.log.error('error during heartbeat', err)
|
|
138
|
+
|
|
139
|
+
if (this.abortConnectionOnPingFailure) {
|
|
140
|
+
this.log.error('aborting connection due to ping failure')
|
|
141
|
+
conn.abort(err)
|
|
142
|
+
} else {
|
|
143
|
+
this.log('connection ping failed, but not aborting due to abortConnectionOnPingFailure flag')
|
|
144
|
+
}
|
|
136
145
|
})
|
|
137
146
|
})
|
|
138
147
|
}, this.pingIntervalMs)
|
package/src/content-routing.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NotStartedError } from '@libp2p/interface'
|
|
2
2
|
import { PeerSet } from '@libp2p/peer-collections'
|
|
3
3
|
import merge from 'it-merge'
|
|
4
|
-
import {
|
|
4
|
+
import { NoContentRoutersError } from './errors.js'
|
|
5
5
|
import type { AbortOptions, ComponentLogger, ContentRouting, PeerInfo, PeerRouting, PeerStore, RoutingOptions, Startable } from '@libp2p/interface'
|
|
6
6
|
import type { CID } from 'multiformats/cid'
|
|
7
7
|
|
|
@@ -45,7 +45,7 @@ export class CompoundContentRouting implements ContentRouting, Startable {
|
|
|
45
45
|
*/
|
|
46
46
|
async * findProviders (key: CID, options: RoutingOptions = {}): AsyncIterable<PeerInfo> {
|
|
47
47
|
if (this.routers.length === 0) {
|
|
48
|
-
throw new
|
|
48
|
+
throw new NoContentRoutersError('No content routers available')
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const self = this
|
|
@@ -84,7 +84,7 @@ export class CompoundContentRouting implements ContentRouting, Startable {
|
|
|
84
84
|
*/
|
|
85
85
|
async provide (key: CID, options: AbortOptions = {}): Promise<void> {
|
|
86
86
|
if (this.routers.length === 0) {
|
|
87
|
-
throw new
|
|
87
|
+
throw new NoContentRoutersError('No content routers available')
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
await Promise.all(this.routers.map(async (router) => {
|
|
@@ -97,7 +97,7 @@ export class CompoundContentRouting implements ContentRouting, Startable {
|
|
|
97
97
|
*/
|
|
98
98
|
async put (key: Uint8Array, value: Uint8Array, options?: AbortOptions): Promise<void> {
|
|
99
99
|
if (!this.isStarted()) {
|
|
100
|
-
throw new
|
|
100
|
+
throw new NotStartedError()
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
await Promise.all(this.routers.map(async (router) => {
|
|
@@ -111,7 +111,7 @@ export class CompoundContentRouting implements ContentRouting, Startable {
|
|
|
111
111
|
*/
|
|
112
112
|
async get (key: Uint8Array, options?: AbortOptions): Promise<Uint8Array> {
|
|
113
113
|
if (!this.isStarted()) {
|
|
114
|
-
throw new
|
|
114
|
+
throw new NotStartedError()
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
return Promise.any(this.routers.map(async (router) => {
|
package/src/errors.ts
CHANGED
|
@@ -1,67 +1,102 @@
|
|
|
1
1
|
export enum messages {
|
|
2
2
|
NOT_STARTED_YET = 'The libp2p node is not started yet',
|
|
3
|
-
ERR_PROTECTOR_REQUIRED = 'Private network is enforced, but no protector was provided',
|
|
4
3
|
NOT_FOUND = 'Not found'
|
|
5
4
|
}
|
|
6
5
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
6
|
+
export class MissingServiceError extends Error {
|
|
7
|
+
constructor (message = 'Missing service') {
|
|
8
|
+
super(message)
|
|
9
|
+
this.name = 'MissingServiceError'
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class UnmetServiceDependenciesError extends Error {
|
|
14
|
+
constructor (message = 'Unmet service dependencies') {
|
|
15
|
+
super(message)
|
|
16
|
+
this.name = 'UnmetServiceDependenciesError'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class NoContentRoutersError extends Error {
|
|
21
|
+
constructor (message = 'No content routers available') {
|
|
22
|
+
super(message)
|
|
23
|
+
this.name = 'NoContentRoutersError'
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class NoPeerRoutersError extends Error {
|
|
28
|
+
constructor (message = 'No peer routers available') {
|
|
29
|
+
super(message)
|
|
30
|
+
this.name = 'NoPeerRoutersError'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class QueriedForSelfError extends Error {
|
|
35
|
+
constructor (message = 'Should not try to find self') {
|
|
36
|
+
super(message)
|
|
37
|
+
this.name = 'QueriedForSelfError'
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class UnhandledProtocolError extends Error {
|
|
42
|
+
constructor (message = 'Unhandled protocol error') {
|
|
43
|
+
super(message)
|
|
44
|
+
this.name = 'UnhandledProtocolError'
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class DuplicateProtocolHandlerError extends Error {
|
|
49
|
+
constructor (message = 'Duplicate protocol handler error') {
|
|
50
|
+
super(message)
|
|
51
|
+
this.name = 'DuplicateProtocolHandlerError'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class DialDeniedError extends Error {
|
|
56
|
+
constructor (message = 'Dial denied error') {
|
|
57
|
+
super(message)
|
|
58
|
+
this.name = 'DialDeniedError'
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class NoValidAddressesError extends Error {
|
|
63
|
+
constructor (message = 'No valid addresses') {
|
|
64
|
+
super(message)
|
|
65
|
+
this.name = 'NoValidAddressesError'
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export class ConnectionInterceptedError extends Error {
|
|
70
|
+
constructor (message = 'Connection intercepted') {
|
|
71
|
+
super(message)
|
|
72
|
+
this.name = 'ConnectionInterceptedError'
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export class ConnectionDeniedError extends Error {
|
|
77
|
+
constructor (message = 'Connection denied') {
|
|
78
|
+
super(message)
|
|
79
|
+
this.name = 'ConnectionDeniedError'
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class MuxerUnavailableError extends Error {
|
|
84
|
+
constructor (message = 'Stream is not multiplexed') {
|
|
85
|
+
super(message)
|
|
86
|
+
this.name = 'MuxerUnavailableError'
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export class EncryptionFailedError extends Error {
|
|
91
|
+
constructor (message = 'Encryption failed') {
|
|
92
|
+
super(message)
|
|
93
|
+
this.name = 'EncryptionFailedError'
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export class TransportUnavailableError extends Error {
|
|
98
|
+
constructor (message = 'Transport unavailable') {
|
|
99
|
+
super(message)
|
|
100
|
+
this.name = 'TransportUnavailableError'
|
|
101
|
+
}
|
|
67
102
|
}
|
package/src/get-peer.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { InvalidMultiaddrError, InvalidParametersError, isPeerId } from '@libp2p/interface'
|
|
2
2
|
import { peerIdFromString } from '@libp2p/peer-id'
|
|
3
3
|
import { isMultiaddr } from '@multiformats/multiaddr'
|
|
4
|
-
import { codes } from './errors.js'
|
|
5
4
|
import type { PeerId } from '@libp2p/interface'
|
|
6
5
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
7
6
|
|
|
@@ -31,20 +30,20 @@ export function getPeerAddress (peer: PeerId | Multiaddr | Multiaddr[]): PeerAdd
|
|
|
31
30
|
// ensure PeerId is either not set or is consistent
|
|
32
31
|
peer.forEach(ma => {
|
|
33
32
|
if (!isMultiaddr(ma)) {
|
|
34
|
-
throw new
|
|
33
|
+
throw new InvalidMultiaddrError('Invalid multiaddr')
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
const maPeerIdStr = ma.getPeerId()
|
|
38
37
|
|
|
39
38
|
if (maPeerIdStr == null) {
|
|
40
39
|
if (peerId != null) {
|
|
41
|
-
throw new
|
|
40
|
+
throw new InvalidParametersError('Multiaddrs must all have the same peer id or have no peer id')
|
|
42
41
|
}
|
|
43
42
|
} else {
|
|
44
43
|
const maPeerId = peerIdFromString(maPeerIdStr)
|
|
45
44
|
|
|
46
45
|
if (peerId?.equals(maPeerId) !== true) {
|
|
47
|
-
throw new
|
|
46
|
+
throw new InvalidParametersError('Multiaddrs must all have the same peer id or have no peer id')
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
49
|
})
|
package/src/index.ts
CHANGED
|
@@ -14,13 +14,16 @@
|
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { generateKeyPair } from '@libp2p/crypto/keys'
|
|
18
|
+
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
|
|
19
|
+
import { validateConfig } from './config.js'
|
|
20
|
+
import { Libp2p as Libp2pClass } from './libp2p.js'
|
|
18
21
|
import type { AddressManagerInit } from './address-manager/index.js'
|
|
19
22
|
import type { Components } from './components.js'
|
|
20
23
|
import type { ConnectionManagerInit } from './connection-manager/index.js'
|
|
21
24
|
import type { ConnectionMonitorInit } from './connection-monitor.js'
|
|
22
25
|
import type { TransportManagerInit } from './transport-manager.js'
|
|
23
|
-
import type { Libp2p, ServiceMap, ComponentLogger, NodeInfo, ConnectionProtector, ConnectionEncrypter, ConnectionGater, ContentRouting, Metrics, PeerDiscovery,
|
|
26
|
+
import type { Libp2p, ServiceMap, ComponentLogger, NodeInfo, ConnectionProtector, ConnectionEncrypter, ConnectionGater, ContentRouting, Metrics, PeerDiscovery, PeerRouting, StreamMuxerFactory, Transport, PrivateKey } from '@libp2p/interface'
|
|
24
27
|
import type { PersistentPeerStoreInit } from '@libp2p/peer-store'
|
|
25
28
|
import type { DNS } from '@multiformats/dns'
|
|
26
29
|
import type { Datastore } from 'interface-datastore'
|
|
@@ -34,12 +37,11 @@ export type ServiceFactoryMap<T extends ServiceMap = ServiceMap> = {
|
|
|
34
37
|
*/
|
|
35
38
|
export interface Libp2pInit<T extends ServiceMap = ServiceMap> {
|
|
36
39
|
/**
|
|
37
|
-
*
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* Private key associated with the peerId
|
|
40
|
+
* The private key is used in cryptographic operations and the Peer ID derived
|
|
41
|
+
* from it's corresponding public key is used to identify the node to other
|
|
42
|
+
* peers on the network.
|
|
43
|
+
*
|
|
44
|
+
* If this is not passed a new Ed25519 private key will be generated.
|
|
43
45
|
*/
|
|
44
46
|
privateKey?: PrivateKey
|
|
45
47
|
|
|
@@ -86,13 +88,36 @@ export interface Libp2pInit<T extends ServiceMap = ServiceMap> {
|
|
|
86
88
|
peerStore?: PersistentPeerStoreInit
|
|
87
89
|
|
|
88
90
|
/**
|
|
89
|
-
*
|
|
91
|
+
* Transports are low-level communication channels
|
|
90
92
|
*/
|
|
91
93
|
transports?: Array<(components: Components) => Transport>
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Stream muxers allow the creation of many data streams over a single
|
|
97
|
+
* connection.
|
|
98
|
+
*/
|
|
92
99
|
streamMuxers?: Array<(components: Components) => StreamMuxerFactory>
|
|
93
|
-
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Connection encrypters ensure that data sent over connections cannot be
|
|
103
|
+
* eavesdropped on, and that the remote peer posesses the private key that
|
|
104
|
+
* corresponds to the public key that it's Peer ID is derived from.
|
|
105
|
+
*/
|
|
106
|
+
connectionEncrypters?: Array<(components: Components) => ConnectionEncrypter>
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Peer discovery mechanisms allow finding peers on the network
|
|
110
|
+
*/
|
|
94
111
|
peerDiscovery?: Array<(components: Components) => PeerDiscovery>
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Peer routers provide implementations for peer routing queries
|
|
115
|
+
*/
|
|
95
116
|
peerRouters?: Array<(components: Components) => PeerRouting>
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Content routers provide implementations for content routing queries
|
|
120
|
+
*/
|
|
96
121
|
contentRouters?: Array<(components: Components) => ContentRouting>
|
|
97
122
|
|
|
98
123
|
/**
|
|
@@ -162,7 +187,7 @@ export type Libp2pOptions<T extends ServiceMap = ServiceMap> = Libp2pInit<T> & {
|
|
|
162
187
|
* const options = {
|
|
163
188
|
* transports: [tcp()],
|
|
164
189
|
* streamMuxers: [yamux(), mplex()],
|
|
165
|
-
*
|
|
190
|
+
* connectionEncrypters: [noise()]
|
|
166
191
|
* }
|
|
167
192
|
*
|
|
168
193
|
* // create libp2p
|
|
@@ -170,7 +195,12 @@ export type Libp2pOptions<T extends ServiceMap = ServiceMap> = Libp2pInit<T> & {
|
|
|
170
195
|
* ```
|
|
171
196
|
*/
|
|
172
197
|
export async function createLibp2p <T extends ServiceMap = ServiceMap> (options: Libp2pOptions<T> = {}): Promise<Libp2p<T>> {
|
|
173
|
-
|
|
198
|
+
options.privateKey ??= await generateKeyPair('Ed25519')
|
|
199
|
+
|
|
200
|
+
const node = new Libp2pClass({
|
|
201
|
+
...await validateConfig(options),
|
|
202
|
+
peerId: peerIdFromPrivateKey(options.privateKey)
|
|
203
|
+
})
|
|
174
204
|
|
|
175
205
|
if (options.start !== false) {
|
|
176
206
|
await node.start()
|