libp2p 0.37.3 → 0.38.0
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/README.md +1 -2
- package/dist/src/address-manager/index.d.ts +2 -2
- package/dist/src/address-manager/index.d.ts.map +1 -1
- package/dist/src/circuit/auto-relay.d.ts +4 -4
- package/dist/src/circuit/auto-relay.d.ts.map +1 -1
- package/dist/src/circuit/circuit/hop.d.ts +7 -5
- package/dist/src/circuit/circuit/hop.d.ts.map +1 -1
- package/dist/src/circuit/circuit/hop.js +8 -4
- package/dist/src/circuit/circuit/hop.js.map +1 -1
- package/dist/src/circuit/circuit/stop.d.ts +6 -4
- package/dist/src/circuit/circuit/stop.d.ts.map +1 -1
- package/dist/src/circuit/circuit/stop.js +4 -2
- package/dist/src/circuit/circuit/stop.js.map +1 -1
- package/dist/src/circuit/circuit/stream-handler.d.ts +3 -2
- package/dist/src/circuit/circuit/stream-handler.d.ts.map +1 -1
- package/dist/src/circuit/circuit/stream-handler.js +2 -2
- package/dist/src/circuit/circuit/stream-handler.js.map +1 -1
- package/dist/src/circuit/index.d.ts +4 -12
- package/dist/src/circuit/index.d.ts.map +1 -1
- package/dist/src/circuit/index.js.map +1 -1
- package/dist/src/circuit/listener.d.ts +3 -3
- package/dist/src/circuit/listener.d.ts.map +1 -1
- package/dist/src/circuit/pb/index.d.ts +5 -4
- package/dist/src/circuit/pb/index.d.ts.map +1 -1
- package/dist/src/circuit/pb/index.js +107 -11
- package/dist/src/circuit/pb/index.js.map +1 -1
- package/dist/src/circuit/transport.d.ts +8 -5
- package/dist/src/circuit/transport.d.ts.map +1 -1
- package/dist/src/circuit/transport.js +81 -59
- package/dist/src/circuit/transport.js.map +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +27 -4
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts.map +1 -1
- package/dist/src/connection-manager/dialer/auto-dialer.d.ts +2 -2
- package/dist/src/connection-manager/dialer/auto-dialer.d.ts.map +1 -1
- package/dist/src/connection-manager/dialer/auto-dialer.js +6 -0
- package/dist/src/connection-manager/dialer/auto-dialer.js.map +1 -1
- package/dist/src/connection-manager/dialer/dial-request.d.ts +1 -1
- package/dist/src/connection-manager/dialer/dial-request.d.ts.map +1 -1
- package/dist/src/connection-manager/dialer/index.d.ts +9 -9
- package/dist/src/connection-manager/dialer/index.d.ts.map +1 -1
- package/dist/src/connection-manager/dialer/index.js +11 -11
- package/dist/src/connection-manager/dialer/index.js.map +1 -1
- package/dist/src/connection-manager/index.d.ts +20 -16
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/connection-manager/index.js +185 -65
- package/dist/src/connection-manager/index.js.map +1 -1
- package/dist/src/constants.d.ts +4 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +4 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/content-routing/index.d.ts +4 -4
- package/dist/src/content-routing/index.d.ts.map +1 -1
- package/dist/src/content-routing/utils.d.ts +2 -2
- package/dist/src/content-routing/utils.d.ts.map +1 -1
- package/dist/src/dht/dht-content-routing.d.ts +3 -3
- package/dist/src/dht/dht-content-routing.d.ts.map +1 -1
- package/dist/src/dht/dht-peer-routing.d.ts +5 -5
- package/dist/src/dht/dht-peer-routing.d.ts.map +1 -1
- package/dist/src/dht/dummy-dht.d.ts +3 -3
- package/dist/src/dht/dummy-dht.d.ts.map +1 -1
- package/dist/src/dht/dummy-dht.js +1 -1
- package/dist/src/dht/dummy-dht.js.map +1 -1
- package/dist/src/errors.d.ts +4 -1
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +3 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/fetch/index.d.ts +11 -4
- package/dist/src/fetch/index.d.ts.map +1 -1
- package/dist/src/fetch/index.js +82 -41
- package/dist/src/fetch/index.js.map +1 -1
- package/dist/src/fetch/pb/proto.d.ts +4 -3
- package/dist/src/fetch/pb/proto.d.ts.map +1 -1
- package/dist/src/fetch/pb/proto.js +88 -8
- package/dist/src/fetch/pb/proto.js.map +1 -1
- package/dist/src/get-peer.d.ts +2 -2
- package/dist/src/get-peer.d.ts.map +1 -1
- package/dist/src/get-peer.js +1 -1
- package/dist/src/get-peer.js.map +1 -1
- package/dist/src/identify/index.d.ts +8 -8
- package/dist/src/identify/index.d.ts.map +1 -1
- package/dist/src/identify/index.js +49 -34
- package/dist/src/identify/index.js.map +1 -1
- package/dist/src/identify/pb/message.d.ts +2 -1
- package/dist/src/identify/pb/message.d.ts.map +1 -1
- package/dist/src/identify/pb/message.js +94 -10
- package/dist/src/identify/pb/message.js.map +1 -1
- package/dist/src/index.d.ts +18 -17
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/insecure/index.d.ts +2 -2
- package/dist/src/insecure/index.d.ts.map +1 -1
- package/dist/src/insecure/index.js +8 -4
- package/dist/src/insecure/index.js.map +1 -1
- package/dist/src/insecure/pb/proto.d.ts +4 -3
- package/dist/src/insecure/pb/proto.d.ts.map +1 -1
- package/dist/src/insecure/pb/proto.js +89 -9
- package/dist/src/insecure/pb/proto.js.map +1 -1
- package/dist/src/keychain/index.d.ts +2 -2
- package/dist/src/keychain/index.d.ts.map +1 -1
- package/dist/src/libp2p.d.ts +14 -14
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +17 -17
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/metrics/index.d.ts +4 -5
- package/dist/src/metrics/index.d.ts.map +1 -1
- package/dist/src/metrics/index.js +9 -6
- package/dist/src/metrics/index.js.map +1 -1
- package/dist/src/metrics/moving-average.d.ts +1 -1
- package/dist/src/metrics/moving-average.d.ts.map +1 -1
- package/dist/src/metrics/stats.d.ts +1 -1
- package/dist/src/metrics/stats.d.ts.map +1 -1
- package/dist/src/nat-manager.d.ts +1 -1
- package/dist/src/nat-manager.d.ts.map +1 -1
- package/dist/src/peer-record-updater.d.ts +1 -1
- package/dist/src/peer-record-updater.d.ts.map +1 -1
- package/dist/src/peer-routing.d.ts +4 -4
- package/dist/src/peer-routing.d.ts.map +1 -1
- package/dist/src/ping/index.d.ts +10 -3
- package/dist/src/ping/index.d.ts.map +1 -1
- package/dist/src/ping/index.js +32 -9
- package/dist/src/ping/index.js.map +1 -1
- package/dist/src/pnet/index.d.ts +1 -2
- package/dist/src/pnet/index.d.ts.map +1 -1
- package/dist/src/pnet/index.js +2 -1
- package/dist/src/pnet/index.js.map +1 -1
- package/dist/src/pubsub/dummy-pubsub.d.ts +2 -2
- package/dist/src/pubsub/dummy-pubsub.d.ts.map +1 -1
- package/dist/src/registrar.d.ts +10 -8
- package/dist/src/registrar.d.ts.map +1 -1
- package/dist/src/registrar.js +63 -44
- package/dist/src/registrar.js.map +1 -1
- package/dist/src/transport-manager.d.ts +3 -3
- package/dist/src/transport-manager.d.ts.map +1 -1
- package/dist/src/upgrader.d.ts +12 -6
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +183 -82
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/version.d.ts.map +1 -1
- package/dist/src/version.js.map +1 -1
- package/package.json +66 -42
- package/src/address-manager/index.ts +2 -2
- package/src/circuit/README.md +2 -2
- package/src/circuit/auto-relay.ts +4 -4
- package/src/circuit/circuit/hop.ts +20 -11
- package/src/circuit/circuit/stop.ts +10 -5
- package/src/circuit/circuit/stream-handler.ts +6 -5
- package/src/circuit/index.ts +4 -13
- package/src/circuit/listener.ts +3 -3
- package/src/circuit/pb/index.ts +133 -15
- package/src/circuit/transport.ts +92 -63
- package/src/config.ts +27 -4
- package/src/connection-manager/auto-dialler.ts +1 -1
- package/src/connection-manager/dialer/auto-dialer.ts +8 -2
- package/src/connection-manager/dialer/dial-request.ts +1 -1
- package/src/connection-manager/dialer/index.ts +15 -15
- package/src/connection-manager/index.ts +239 -82
- package/src/constants.ts +5 -0
- package/src/content-routing/index.ts +2 -2
- package/src/content-routing/utils.ts +2 -2
- package/src/dht/dht-content-routing.ts +2 -2
- package/src/dht/dht-peer-routing.ts +3 -3
- package/src/dht/dummy-dht.ts +3 -3
- package/src/errors.ts +4 -1
- package/src/fetch/index.ts +120 -53
- package/src/fetch/pb/proto.ts +109 -11
- package/src/get-peer.ts +3 -3
- package/src/identify/index.ts +64 -47
- package/src/identify/pb/message.ts +111 -11
- package/src/index.ts +18 -17
- package/src/insecure/index.ts +11 -6
- package/src/insecure/pb/proto.ts +111 -12
- package/src/keychain/index.ts +2 -2
- package/src/libp2p.ts +34 -29
- package/src/metrics/index.ts +13 -12
- package/src/metrics/moving-average.ts +1 -1
- package/src/metrics/stats.ts +1 -1
- package/src/nat-manager.ts +1 -1
- package/src/peer-record-updater.ts +1 -1
- package/src/peer-routing.ts +4 -4
- package/src/ping/index.ts +48 -15
- package/src/pnet/index.ts +3 -2
- package/src/pubsub/dummy-pubsub.ts +2 -2
- package/src/registrar.ts +79 -55
- package/src/transport-manager.ts +3 -3
- package/src/upgrader.ts +223 -93
- package/src/version.ts +1 -2
package/src/fetch/index.ts
CHANGED
|
@@ -3,21 +3,30 @@ import errCode from 'err-code'
|
|
|
3
3
|
import { codes } from '../errors.js'
|
|
4
4
|
import * as lp from 'it-length-prefixed'
|
|
5
5
|
import { FetchRequest, FetchResponse } from './pb/proto.js'
|
|
6
|
-
import { handshake } from 'it-handshake'
|
|
7
6
|
import { PROTOCOL_NAME, PROTOCOL_VERSION } from './constants.js'
|
|
8
|
-
import type { PeerId } from '@libp2p/
|
|
7
|
+
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
9
8
|
import type { Startable } from '@libp2p/interfaces/startable'
|
|
10
|
-
import type { Stream } from '@libp2p/
|
|
11
|
-
import type { IncomingStreamData } from '@libp2p/
|
|
12
|
-
import type { Components } from '@libp2p/
|
|
9
|
+
import type { Stream } from '@libp2p/interface-connection'
|
|
10
|
+
import type { IncomingStreamData } from '@libp2p/interface-registrar'
|
|
11
|
+
import type { Components } from '@libp2p/components'
|
|
13
12
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
14
|
-
import type { Duplex } from 'it-stream-types'
|
|
15
13
|
import { abortableDuplex } from 'abortable-iterator'
|
|
14
|
+
import { pipe } from 'it-pipe'
|
|
15
|
+
import first from 'it-first'
|
|
16
|
+
import { TimeoutController } from 'timeout-abort-controller'
|
|
17
|
+
import { setMaxListeners } from 'events'
|
|
16
18
|
|
|
17
19
|
const log = logger('libp2p:fetch')
|
|
18
20
|
|
|
19
21
|
export interface FetchServiceInit {
|
|
20
22
|
protocolPrefix: string
|
|
23
|
+
maxInboundStreams: number
|
|
24
|
+
maxOutboundStreams: number
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* How long we should wait for a remote peer to send any data
|
|
28
|
+
*/
|
|
29
|
+
timeout: number
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
export interface HandleMessageOptions {
|
|
@@ -40,6 +49,7 @@ export class FetchService implements Startable {
|
|
|
40
49
|
private readonly components: Components
|
|
41
50
|
private readonly lookupFunctions: Map<string, LookupFunction>
|
|
42
51
|
private started: boolean
|
|
52
|
+
private readonly init: FetchServiceInit
|
|
43
53
|
|
|
44
54
|
constructor (components: Components, init: FetchServiceInit) {
|
|
45
55
|
this.started = false
|
|
@@ -47,13 +57,21 @@ export class FetchService implements Startable {
|
|
|
47
57
|
this.protocol = `/${init.protocolPrefix ?? 'libp2p'}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`
|
|
48
58
|
this.lookupFunctions = new Map() // Maps key prefix to value lookup function
|
|
49
59
|
this.handleMessage = this.handleMessage.bind(this)
|
|
60
|
+
this.init = init
|
|
50
61
|
}
|
|
51
62
|
|
|
52
63
|
async start () {
|
|
53
64
|
await this.components.getRegistrar().handle(this.protocol, (data) => {
|
|
54
|
-
void this.handleMessage(data)
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
void this.handleMessage(data)
|
|
66
|
+
.catch(err => {
|
|
67
|
+
log.error(err)
|
|
68
|
+
})
|
|
69
|
+
.finally(() => {
|
|
70
|
+
data.stream.close()
|
|
71
|
+
})
|
|
72
|
+
}, {
|
|
73
|
+
maxInboundStreams: this.init.maxInboundStreams,
|
|
74
|
+
maxOutboundStreams: this.init.maxOutboundStreams
|
|
57
75
|
})
|
|
58
76
|
this.started = true
|
|
59
77
|
}
|
|
@@ -74,35 +92,69 @@ export class FetchService implements Startable {
|
|
|
74
92
|
log('dialing %s to %p', this.protocol, peer)
|
|
75
93
|
|
|
76
94
|
const connection = await this.components.getConnectionManager().openConnection(peer, options)
|
|
77
|
-
|
|
78
|
-
let
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if
|
|
82
|
-
|
|
95
|
+
let timeoutController
|
|
96
|
+
let signal = options.signal
|
|
97
|
+
let stream: Stream | undefined
|
|
98
|
+
|
|
99
|
+
// create a timeout if no abort signal passed
|
|
100
|
+
if (signal == null) {
|
|
101
|
+
timeoutController = new TimeoutController(this.init.timeout)
|
|
102
|
+
signal = timeoutController.signal
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
// fails on node < 15.4
|
|
106
|
+
setMaxListeners?.(Infinity, timeoutController.signal)
|
|
107
|
+
} catch {}
|
|
83
108
|
}
|
|
84
109
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
110
|
+
try {
|
|
111
|
+
stream = await connection.newStream([this.protocol], {
|
|
112
|
+
signal
|
|
113
|
+
})
|
|
89
114
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
115
|
+
// make stream abortable
|
|
116
|
+
const source = abortableDuplex(stream, signal)
|
|
117
|
+
|
|
118
|
+
const result = await pipe(
|
|
119
|
+
[FetchRequest.encode({ identifier: key })],
|
|
120
|
+
lp.encode(),
|
|
121
|
+
source,
|
|
122
|
+
lp.decode(),
|
|
123
|
+
async function (source) {
|
|
124
|
+
const buf = await first(source)
|
|
125
|
+
|
|
126
|
+
if (buf == null) {
|
|
127
|
+
throw errCode(new Error('No data received'), codes.ERR_INVALID_MESSAGE)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const response = FetchResponse.decode(buf)
|
|
131
|
+
|
|
132
|
+
switch (response.status) {
|
|
133
|
+
case (FetchResponse.StatusCode.OK): {
|
|
134
|
+
return response.data
|
|
135
|
+
}
|
|
136
|
+
case (FetchResponse.StatusCode.NOT_FOUND): {
|
|
137
|
+
return null
|
|
138
|
+
}
|
|
139
|
+
case (FetchResponse.StatusCode.ERROR): {
|
|
140
|
+
const errmsg = (new TextDecoder()).decode(response.data)
|
|
141
|
+
throw errCode(new Error('Error in fetch protocol response: ' + errmsg), codes.ERR_INVALID_PARAMETERS)
|
|
142
|
+
}
|
|
143
|
+
default: {
|
|
144
|
+
throw errCode(new Error('Unknown response status'), codes.ERR_INVALID_MESSAGE)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
return result ?? null
|
|
151
|
+
} finally {
|
|
152
|
+
if (timeoutController != null) {
|
|
153
|
+
timeoutController.clear()
|
|
99
154
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
default: {
|
|
105
|
-
throw errCode(new Error('Unknown response status'), codes.ERR_INVALID_MESSAGE)
|
|
155
|
+
|
|
156
|
+
if (stream != null) {
|
|
157
|
+
stream.close()
|
|
106
158
|
}
|
|
107
159
|
}
|
|
108
160
|
}
|
|
@@ -114,25 +166,40 @@ export class FetchService implements Startable {
|
|
|
114
166
|
*/
|
|
115
167
|
async handleMessage (data: IncomingStreamData) {
|
|
116
168
|
const { stream } = data
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
169
|
+
const self = this
|
|
170
|
+
|
|
171
|
+
await pipe(
|
|
172
|
+
stream,
|
|
173
|
+
lp.decode(),
|
|
174
|
+
async function * (source) {
|
|
175
|
+
const buf = await first(source)
|
|
176
|
+
|
|
177
|
+
if (buf == null) {
|
|
178
|
+
throw errCode(new Error('No data received'), codes.ERR_INVALID_MESSAGE)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// for await (const buf of source) {
|
|
182
|
+
const request = FetchRequest.decode(buf)
|
|
183
|
+
|
|
184
|
+
let response: FetchResponse
|
|
185
|
+
const lookup = self._getLookupFunction(request.identifier)
|
|
186
|
+
if (lookup != null) {
|
|
187
|
+
const data = await lookup(request.identifier)
|
|
188
|
+
if (data != null) {
|
|
189
|
+
response = { status: FetchResponse.StatusCode.OK, data }
|
|
190
|
+
} else {
|
|
191
|
+
response = { status: FetchResponse.StatusCode.NOT_FOUND, data: new Uint8Array(0) }
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
const errmsg = (new TextEncoder()).encode('No lookup function registered for key: ' + request.identifier)
|
|
195
|
+
response = { status: FetchResponse.StatusCode.ERROR, data: errmsg }
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
yield FetchResponse.encode(response)
|
|
199
|
+
},
|
|
200
|
+
lp.encode(),
|
|
201
|
+
stream
|
|
202
|
+
)
|
|
136
203
|
}
|
|
137
204
|
|
|
138
205
|
/**
|
package/src/fetch/pb/proto.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/* eslint-disable import/export */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-namespace */
|
|
3
3
|
|
|
4
|
-
import { encodeMessage, decodeMessage, message,
|
|
4
|
+
import { encodeMessage, decodeMessage, message, enumeration } from 'protons-runtime'
|
|
5
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
5
6
|
import type { Codec } from 'protons-runtime'
|
|
6
7
|
|
|
7
8
|
export interface FetchRequest {
|
|
@@ -9,17 +10,59 @@ export interface FetchRequest {
|
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export namespace FetchRequest {
|
|
13
|
+
let _codec: Codec<FetchRequest>
|
|
14
|
+
|
|
12
15
|
export const codec = (): Codec<FetchRequest> => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
if (_codec == null) {
|
|
17
|
+
_codec = message<FetchRequest>((obj, writer, opts = {}) => {
|
|
18
|
+
if (opts.lengthDelimited !== false) {
|
|
19
|
+
writer.fork()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (obj.identifier != null) {
|
|
23
|
+
writer.uint32(10)
|
|
24
|
+
writer.string(obj.identifier)
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error('Protocol error: required field "identifier" was not found in object')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (opts.lengthDelimited !== false) {
|
|
30
|
+
writer.ldelim()
|
|
31
|
+
}
|
|
32
|
+
}, (reader, length) => {
|
|
33
|
+
const obj: any = {}
|
|
34
|
+
|
|
35
|
+
const end = length == null ? reader.len : reader.pos + length
|
|
36
|
+
|
|
37
|
+
while (reader.pos < end) {
|
|
38
|
+
const tag = reader.uint32()
|
|
39
|
+
|
|
40
|
+
switch (tag >>> 3) {
|
|
41
|
+
case 1:
|
|
42
|
+
obj.identifier = reader.string()
|
|
43
|
+
break
|
|
44
|
+
default:
|
|
45
|
+
reader.skipType(tag & 7)
|
|
46
|
+
break
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (obj.identifier == null) {
|
|
51
|
+
throw new Error('Protocol error: value for required field "identifier" was not found in protobuf')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return obj
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return _codec
|
|
16
59
|
}
|
|
17
60
|
|
|
18
61
|
export const encode = (obj: FetchRequest): Uint8Array => {
|
|
19
62
|
return encodeMessage(obj, FetchRequest.codec())
|
|
20
63
|
}
|
|
21
64
|
|
|
22
|
-
export const decode = (buf: Uint8Array): FetchRequest => {
|
|
65
|
+
export const decode = (buf: Uint8Array | Uint8ArrayList): FetchRequest => {
|
|
23
66
|
return decodeMessage(buf, FetchRequest.codec())
|
|
24
67
|
}
|
|
25
68
|
}
|
|
@@ -44,22 +87,77 @@ export namespace FetchResponse {
|
|
|
44
87
|
|
|
45
88
|
export namespace StatusCode {
|
|
46
89
|
export const codec = () => {
|
|
47
|
-
return enumeration<
|
|
90
|
+
return enumeration<StatusCode>(__StatusCodeValues)
|
|
48
91
|
}
|
|
49
92
|
}
|
|
50
93
|
|
|
94
|
+
let _codec: Codec<FetchResponse>
|
|
95
|
+
|
|
51
96
|
export const codec = (): Codec<FetchResponse> => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
97
|
+
if (_codec == null) {
|
|
98
|
+
_codec = message<FetchResponse>((obj, writer, opts = {}) => {
|
|
99
|
+
if (opts.lengthDelimited !== false) {
|
|
100
|
+
writer.fork()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (obj.status != null) {
|
|
104
|
+
writer.uint32(8)
|
|
105
|
+
FetchResponse.StatusCode.codec().encode(obj.status, writer)
|
|
106
|
+
} else {
|
|
107
|
+
throw new Error('Protocol error: required field "status" was not found in object')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (obj.data != null) {
|
|
111
|
+
writer.uint32(18)
|
|
112
|
+
writer.bytes(obj.data)
|
|
113
|
+
} else {
|
|
114
|
+
throw new Error('Protocol error: required field "data" was not found in object')
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (opts.lengthDelimited !== false) {
|
|
118
|
+
writer.ldelim()
|
|
119
|
+
}
|
|
120
|
+
}, (reader, length) => {
|
|
121
|
+
const obj: any = {}
|
|
122
|
+
|
|
123
|
+
const end = length == null ? reader.len : reader.pos + length
|
|
124
|
+
|
|
125
|
+
while (reader.pos < end) {
|
|
126
|
+
const tag = reader.uint32()
|
|
127
|
+
|
|
128
|
+
switch (tag >>> 3) {
|
|
129
|
+
case 1:
|
|
130
|
+
obj.status = FetchResponse.StatusCode.codec().decode(reader)
|
|
131
|
+
break
|
|
132
|
+
case 2:
|
|
133
|
+
obj.data = reader.bytes()
|
|
134
|
+
break
|
|
135
|
+
default:
|
|
136
|
+
reader.skipType(tag & 7)
|
|
137
|
+
break
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (obj.status == null) {
|
|
142
|
+
throw new Error('Protocol error: value for required field "status" was not found in protobuf')
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (obj.data == null) {
|
|
146
|
+
throw new Error('Protocol error: value for required field "data" was not found in protobuf')
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return obj
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return _codec
|
|
56
154
|
}
|
|
57
155
|
|
|
58
156
|
export const encode = (obj: FetchResponse): Uint8Array => {
|
|
59
157
|
return encodeMessage(obj, FetchResponse.codec())
|
|
60
158
|
}
|
|
61
159
|
|
|
62
|
-
export const decode = (buf: Uint8Array): FetchResponse => {
|
|
160
|
+
export const decode = (buf: Uint8Array | Uint8ArrayList): FetchResponse => {
|
|
63
161
|
return decodeMessage(buf, FetchResponse.codec())
|
|
64
162
|
}
|
|
65
163
|
}
|
package/src/get-peer.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { peerIdFromString } from '@libp2p/peer-id'
|
|
|
2
2
|
import { Multiaddr } from '@multiformats/multiaddr'
|
|
3
3
|
import errCode from 'err-code'
|
|
4
4
|
import { codes } from './errors.js'
|
|
5
|
-
import { isPeerId } from '@libp2p/
|
|
6
|
-
import type { PeerId } from '@libp2p/
|
|
7
|
-
import type { PeerInfo } from '@libp2p/
|
|
5
|
+
import { isPeerId } from '@libp2p/interface-peer-id'
|
|
6
|
+
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
7
|
+
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
8
8
|
|
|
9
9
|
function peerIdFromMultiaddr (ma: Multiaddr) {
|
|
10
10
|
const idStr = ma.getPeerId()
|
package/src/identify/index.ts
CHANGED
|
@@ -18,21 +18,18 @@ import {
|
|
|
18
18
|
MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION
|
|
19
19
|
} from './consts.js'
|
|
20
20
|
import { codes } from '../errors.js'
|
|
21
|
-
import type { IncomingStreamData } from '@libp2p/
|
|
22
|
-
import type { Connection, Stream } from '@libp2p/
|
|
21
|
+
import type { IncomingStreamData } from '@libp2p/interface-registrar'
|
|
22
|
+
import type { Connection, Stream } from '@libp2p/interface-connection'
|
|
23
23
|
import type { Startable } from '@libp2p/interfaces/startable'
|
|
24
24
|
import { peerIdFromKeys } from '@libp2p/peer-id'
|
|
25
|
-
import type { Components } from '@libp2p/
|
|
25
|
+
import type { Components } from '@libp2p/components'
|
|
26
26
|
import { TimeoutController } from 'timeout-abort-controller'
|
|
27
27
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
28
28
|
import { abortableDuplex } from 'abortable-iterator'
|
|
29
|
-
import
|
|
29
|
+
import { setMaxListeners } from 'events'
|
|
30
30
|
|
|
31
31
|
const log = logger('libp2p:identify')
|
|
32
32
|
|
|
33
|
-
// https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/identify/id.go#L48
|
|
34
|
-
const IDENTIFY_TIMEOUT = 60000
|
|
35
|
-
|
|
36
33
|
// https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/identify/id.go#L52
|
|
37
34
|
const MAX_IDENTIFY_MESSAGE_SIZE = 1024 * 8
|
|
38
35
|
|
|
@@ -54,12 +51,18 @@ export interface IdentifyServiceInit {
|
|
|
54
51
|
/**
|
|
55
52
|
* How long we should wait for a remote peer to send their identify response
|
|
56
53
|
*/
|
|
57
|
-
timeout
|
|
54
|
+
timeout: number
|
|
58
55
|
|
|
59
56
|
/**
|
|
60
57
|
* Identify responses larger than this in bytes will be rejected (default: 8192)
|
|
61
58
|
*/
|
|
62
59
|
maxIdentifyMessageSize?: number
|
|
60
|
+
|
|
61
|
+
maxInboundStreams: number
|
|
62
|
+
maxOutboundStreams: number
|
|
63
|
+
|
|
64
|
+
maxPushIncomingStreams: number
|
|
65
|
+
maxPushOutgoingStreams: number
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
export class IdentifyService implements Startable {
|
|
@@ -79,8 +82,6 @@ export class IdentifyService implements Startable {
|
|
|
79
82
|
this.started = false
|
|
80
83
|
this.init = init
|
|
81
84
|
|
|
82
|
-
this.handleMessage = this.handleMessage.bind(this)
|
|
83
|
-
|
|
84
85
|
this.identifyProtocolStr = `/${init.protocolPrefix}/${MULTICODEC_IDENTIFY_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PROTOCOL_VERSION}`
|
|
85
86
|
this.identifyPushProtocolStr = `/${init.protocolPrefix}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION}`
|
|
86
87
|
|
|
@@ -127,13 +128,21 @@ export class IdentifyService implements Startable {
|
|
|
127
128
|
await this.components.getPeerStore().metadataBook.setValue(this.components.getPeerId(), 'AgentVersion', uint8ArrayFromString(this.host.agentVersion))
|
|
128
129
|
await this.components.getPeerStore().metadataBook.setValue(this.components.getPeerId(), 'ProtocolVersion', uint8ArrayFromString(this.host.protocolVersion))
|
|
129
130
|
|
|
130
|
-
await this.components.getRegistrar().handle(
|
|
131
|
-
this.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
await this.components.getRegistrar().handle(this.identifyProtocolStr, (data) => {
|
|
132
|
+
void this._handleIdentify(data).catch(err => {
|
|
133
|
+
log.error(err)
|
|
134
|
+
})
|
|
135
|
+
}, {
|
|
136
|
+
maxInboundStreams: this.init.maxInboundStreams,
|
|
137
|
+
maxOutboundStreams: this.init.maxOutboundStreams
|
|
138
|
+
})
|
|
139
|
+
await this.components.getRegistrar().handle(this.identifyPushProtocolStr, (data) => {
|
|
140
|
+
void this._handlePush(data).catch(err => {
|
|
135
141
|
log.error(err)
|
|
136
142
|
})
|
|
143
|
+
}, {
|
|
144
|
+
maxInboundStreams: this.init.maxPushIncomingStreams,
|
|
145
|
+
maxOutboundStreams: this.init.maxPushOutgoingStreams
|
|
137
146
|
})
|
|
138
147
|
|
|
139
148
|
this.started = true
|
|
@@ -155,17 +164,21 @@ export class IdentifyService implements Startable {
|
|
|
155
164
|
const protocols = await this.components.getPeerStore().protoBook.get(this.components.getPeerId())
|
|
156
165
|
|
|
157
166
|
const pushes = connections.map(async connection => {
|
|
158
|
-
const timeoutController = new TimeoutController(this.init.timeout ?? IDENTIFY_TIMEOUT)
|
|
159
167
|
let stream: Stream | undefined
|
|
168
|
+
const timeoutController = new TimeoutController(this.init.timeout)
|
|
160
169
|
|
|
161
170
|
try {
|
|
162
|
-
|
|
171
|
+
// fails on node < 15.4
|
|
172
|
+
setMaxListeners?.(Infinity, timeoutController.signal)
|
|
173
|
+
} catch {}
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
stream = await connection.newStream([this.identifyPushProtocolStr], {
|
|
163
177
|
signal: timeoutController.signal
|
|
164
178
|
})
|
|
165
|
-
stream = data.stream
|
|
166
179
|
|
|
167
180
|
// make stream abortable
|
|
168
|
-
const source
|
|
181
|
+
const source = abortableDuplex(stream, timeoutController.signal)
|
|
169
182
|
|
|
170
183
|
await pipe(
|
|
171
184
|
[Identify.encode({
|
|
@@ -218,21 +231,29 @@ export class IdentifyService implements Startable {
|
|
|
218
231
|
}
|
|
219
232
|
|
|
220
233
|
async _identify (connection: Connection, options: AbortOptions = {}): Promise<Identify> {
|
|
221
|
-
const { stream } = await connection.newStream([this.identifyProtocolStr], options)
|
|
222
|
-
let source: Duplex<Uint8Array> = stream
|
|
223
234
|
let timeoutController
|
|
224
235
|
let signal = options.signal
|
|
236
|
+
let stream: Stream | undefined
|
|
225
237
|
|
|
226
238
|
// create a timeout if no abort signal passed
|
|
227
239
|
if (signal == null) {
|
|
228
|
-
timeoutController = new TimeoutController(this.init.timeout
|
|
240
|
+
timeoutController = new TimeoutController(this.init.timeout)
|
|
229
241
|
signal = timeoutController.signal
|
|
230
|
-
}
|
|
231
242
|
|
|
232
|
-
|
|
233
|
-
|
|
243
|
+
try {
|
|
244
|
+
// fails on node < 15.4
|
|
245
|
+
setMaxListeners?.(Infinity, timeoutController.signal)
|
|
246
|
+
} catch {}
|
|
247
|
+
}
|
|
234
248
|
|
|
235
249
|
try {
|
|
250
|
+
stream = await connection.newStream([this.identifyProtocolStr], {
|
|
251
|
+
signal
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
// make stream abortable
|
|
255
|
+
const source = abortableDuplex(stream, signal)
|
|
256
|
+
|
|
236
257
|
const data = await pipe(
|
|
237
258
|
[],
|
|
238
259
|
source,
|
|
@@ -256,7 +277,9 @@ export class IdentifyService implements Startable {
|
|
|
256
277
|
timeoutController.clear()
|
|
257
278
|
}
|
|
258
279
|
|
|
259
|
-
stream
|
|
280
|
+
if (stream != null) {
|
|
281
|
+
stream.close()
|
|
282
|
+
}
|
|
260
283
|
}
|
|
261
284
|
}
|
|
262
285
|
|
|
@@ -353,29 +376,18 @@ export class IdentifyService implements Startable {
|
|
|
353
376
|
// this.components.getAddressManager().addObservedAddr(observedAddr)
|
|
354
377
|
}
|
|
355
378
|
|
|
356
|
-
/**
|
|
357
|
-
* A handler to register with Libp2p to process identify messages
|
|
358
|
-
*/
|
|
359
|
-
handleMessage (data: IncomingStreamData) {
|
|
360
|
-
const { protocol } = data
|
|
361
|
-
|
|
362
|
-
switch (protocol) {
|
|
363
|
-
case this.identifyProtocolStr:
|
|
364
|
-
return this._handleIdentify(data)
|
|
365
|
-
case this.identifyPushProtocolStr:
|
|
366
|
-
return this._handlePush(data)
|
|
367
|
-
default:
|
|
368
|
-
log.error('cannot handle unknown protocol %s', protocol)
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
379
|
/**
|
|
373
380
|
* Sends the `Identify` response with the Signed Peer Record
|
|
374
381
|
* to the requesting peer over the given `connection`
|
|
375
382
|
*/
|
|
376
383
|
async _handleIdentify (data: IncomingStreamData) {
|
|
377
384
|
const { connection, stream } = data
|
|
378
|
-
const timeoutController = new TimeoutController(this.init.timeout
|
|
385
|
+
const timeoutController = new TimeoutController(this.init.timeout)
|
|
386
|
+
|
|
387
|
+
try {
|
|
388
|
+
// fails on node < 15.4
|
|
389
|
+
setMaxListeners?.(Infinity, timeoutController.signal)
|
|
390
|
+
} catch {}
|
|
379
391
|
|
|
380
392
|
try {
|
|
381
393
|
const publicKey = this.components.getPeerId().publicKey ?? new Uint8Array(0)
|
|
@@ -391,7 +403,7 @@ export class IdentifyService implements Startable {
|
|
|
391
403
|
|
|
392
404
|
const envelope = await RecordEnvelope.seal(peerRecord, this.components.getPeerId())
|
|
393
405
|
await this.components.getPeerStore().addressBook.consumePeerRecord(envelope)
|
|
394
|
-
signedPeerRecord = envelope.marshal()
|
|
406
|
+
signedPeerRecord = envelope.marshal().subarray()
|
|
395
407
|
}
|
|
396
408
|
|
|
397
409
|
const message = Identify.encode({
|
|
@@ -405,7 +417,7 @@ export class IdentifyService implements Startable {
|
|
|
405
417
|
})
|
|
406
418
|
|
|
407
419
|
// make stream abortable
|
|
408
|
-
const source
|
|
420
|
+
const source = abortableDuplex(stream, timeoutController.signal)
|
|
409
421
|
|
|
410
422
|
await pipe(
|
|
411
423
|
[message],
|
|
@@ -426,12 +438,17 @@ export class IdentifyService implements Startable {
|
|
|
426
438
|
*/
|
|
427
439
|
async _handlePush (data: IncomingStreamData) {
|
|
428
440
|
const { connection, stream } = data
|
|
429
|
-
const timeoutController = new TimeoutController(this.init.timeout
|
|
441
|
+
const timeoutController = new TimeoutController(this.init.timeout)
|
|
442
|
+
|
|
443
|
+
try {
|
|
444
|
+
// fails on node < 15.4
|
|
445
|
+
setMaxListeners?.(Infinity, timeoutController.signal)
|
|
446
|
+
} catch {}
|
|
430
447
|
|
|
431
448
|
let message: Identify | undefined
|
|
432
449
|
try {
|
|
433
450
|
// make stream abortable
|
|
434
|
-
const source
|
|
451
|
+
const source = abortableDuplex(stream, timeoutController.signal)
|
|
435
452
|
|
|
436
453
|
const data = await pipe(
|
|
437
454
|
[],
|