libp2p 0.43.4 → 0.44.0-17eb162a
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 +29 -29
- package/dist/src/address-manager/index.d.ts +4 -4
- package/dist/src/address-manager/index.d.ts.map +1 -1
- package/dist/src/address-manager/index.js +9 -6
- package/dist/src/address-manager/index.js.map +1 -1
- package/dist/src/autonat/index.d.ts +1 -2
- package/dist/src/autonat/index.d.ts.map +1 -1
- package/dist/src/autonat/index.js +4 -6
- package/dist/src/autonat/index.js.map +1 -1
- package/dist/src/circuit-relay/server/advert-service.d.ts.map +1 -1
- package/dist/src/circuit-relay/server/advert-service.js +2 -2
- package/dist/src/circuit-relay/server/advert-service.js.map +1 -1
- package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/server/index.js +7 -3
- package/dist/src/circuit-relay/server/index.js.map +1 -1
- package/dist/src/circuit-relay/transport/discovery.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/discovery.js +3 -1
- package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
- package/dist/src/circuit-relay/transport/index.d.ts +3 -0
- package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/index.js +6 -2
- package/dist/src/circuit-relay/transport/index.js.map +1 -1
- package/dist/src/circuit-relay/transport/listener.d.ts +3 -0
- package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/listener.js +5 -4
- package/dist/src/circuit-relay/transport/listener.js.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.d.ts +4 -1
- package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.js +11 -6
- package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
- package/dist/src/circuit-relay/utils.d.ts.map +1 -1
- package/dist/src/circuit-relay/utils.js +3 -1
- package/dist/src/circuit-relay/utils.js.map +1 -1
- package/dist/src/components.d.ts +8 -6
- package/dist/src/components.d.ts.map +1 -1
- package/dist/src/components.js +10 -10
- package/dist/src/components.js.map +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +0 -9
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection-manager/auto-dial.d.ts +39 -0
- package/dist/src/connection-manager/auto-dial.d.ts.map +1 -0
- package/dist/src/connection-manager/auto-dial.js +131 -0
- package/dist/src/connection-manager/auto-dial.js.map +1 -0
- package/dist/src/connection-manager/connection-pruner.d.ts +32 -0
- package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -0
- package/dist/src/connection-manager/connection-pruner.js +111 -0
- package/dist/src/connection-manager/connection-pruner.js.map +1 -0
- package/dist/src/connection-manager/constants.d.ts +49 -0
- package/dist/src/connection-manager/constants.d.ts.map +1 -0
- package/dist/src/connection-manager/constants.js +49 -0
- package/dist/src/connection-manager/constants.js.map +1 -0
- package/dist/src/connection-manager/dial-queue.d.ts +78 -0
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -0
- package/dist/src/connection-manager/dial-queue.js +374 -0
- package/dist/src/connection-manager/dial-queue.js.map +1 -0
- package/dist/src/connection-manager/index.d.ts +70 -73
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/connection-manager/index.js +116 -248
- package/dist/src/connection-manager/index.js.map +1 -1
- package/dist/src/connection-manager/utils.d.ts +9 -0
- package/dist/src/connection-manager/utils.d.ts.map +1 -0
- package/dist/src/connection-manager/utils.js +66 -0
- package/dist/src/connection-manager/utils.js.map +1 -0
- package/dist/src/content-routing/index.js +1 -1
- package/dist/src/content-routing/index.js.map +1 -1
- package/dist/src/content-routing/utils.d.ts.map +1 -1
- package/dist/src/content-routing/utils.js +3 -1
- package/dist/src/content-routing/utils.js.map +1 -1
- package/dist/src/fetch/index.js +3 -3
- package/dist/src/fetch/index.js.map +1 -1
- package/dist/src/identify/index.d.ts +4 -0
- package/dist/src/identify/index.d.ts.map +1 -1
- package/dist/src/identify/index.js +104 -128
- package/dist/src/identify/index.js.map +1 -1
- package/dist/src/index.d.ts +2 -19
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/insecure/index.d.ts.map +1 -1
- package/dist/src/insecure/index.js +3 -1
- package/dist/src/insecure/index.js.map +1 -1
- package/dist/src/libp2p.d.ts +5 -3
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +47 -50
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/registrar.d.ts +5 -2
- package/dist/src/registrar.d.ts.map +1 -1
- package/dist/src/registrar.js +25 -23
- package/dist/src/registrar.js.map +1 -1
- package/dist/src/transport-manager.d.ts +9 -3
- package/dist/src/transport-manager.d.ts.map +1 -1
- package/dist/src/transport-manager.js +23 -9
- package/dist/src/transport-manager.js.map +1 -1
- package/dist/src/upgrader.d.ts +14 -11
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +14 -10
- package/dist/src/upgrader.js.map +1 -1
- package/package.json +46 -45
- package/src/address-manager/index.ts +12 -8
- package/src/autonat/index.ts +6 -9
- package/src/circuit-relay/server/advert-service.ts +2 -2
- package/src/circuit-relay/server/index.ts +7 -3
- package/src/circuit-relay/transport/discovery.ts +3 -1
- package/src/circuit-relay/transport/index.ts +10 -2
- package/src/circuit-relay/transport/listener.ts +8 -4
- package/src/circuit-relay/transport/reservation-store.ts +15 -7
- package/src/circuit-relay/utils.ts +3 -1
- package/src/components.ts +19 -17
- package/src/config.ts +0 -9
- package/src/connection-manager/auto-dial.ts +183 -0
- package/src/connection-manager/connection-pruner.ts +157 -0
- package/src/connection-manager/constants.ts +60 -0
- package/src/connection-manager/dial-queue.ts +512 -0
- package/src/connection-manager/index.ts +191 -340
- package/src/connection-manager/utils.ts +76 -0
- package/src/content-routing/index.ts +1 -1
- package/src/content-routing/utils.ts +3 -1
- package/src/fetch/index.ts +4 -4
- package/src/identify/index.ts +100 -140
- package/src/index.ts +2 -20
- package/src/insecure/index.ts +9 -5
- package/src/libp2p.ts +54 -60
- package/src/registrar.ts +29 -25
- package/src/transport-manager.ts +31 -11
- package/src/upgrader.ts +31 -22
- package/src/version.ts +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts +0 -42
- package/dist/src/connection-manager/auto-dialler.d.ts.map +0 -1
- package/dist/src/connection-manager/auto-dialler.js +0 -105
- package/dist/src/connection-manager/auto-dialler.js.map +0 -1
- package/dist/src/connection-manager/dialer/dial-request.d.ts +0 -27
- package/dist/src/connection-manager/dialer/dial-request.d.ts.map +0 -1
- package/dist/src/connection-manager/dialer/dial-request.js +0 -114
- package/dist/src/connection-manager/dialer/dial-request.js.map +0 -1
- package/dist/src/connection-manager/dialer/index.d.ts +0 -121
- package/dist/src/connection-manager/dialer/index.d.ts.map +0 -1
- package/dist/src/connection-manager/dialer/index.js +0 -324
- package/dist/src/connection-manager/dialer/index.js.map +0 -1
- package/dist/src/connection-manager/latency-monitor.d.ts +0 -120
- package/dist/src/connection-manager/latency-monitor.d.ts.map +0 -1
- package/dist/src/connection-manager/latency-monitor.js +0 -220
- package/dist/src/connection-manager/latency-monitor.js.map +0 -1
- package/dist/src/connection-manager/visibility-change-emitter.d.ts +0 -66
- package/dist/src/connection-manager/visibility-change-emitter.d.ts.map +0 -1
- package/dist/src/connection-manager/visibility-change-emitter.js +0 -118
- package/dist/src/connection-manager/visibility-change-emitter.js.map +0 -1
- package/dist/src/constants.d.ts +0 -27
- package/dist/src/constants.d.ts.map +0 -1
- package/dist/src/constants.js +0 -31
- package/dist/src/constants.js.map +0 -1
- package/dist/src/peer-record-updater.d.ts +0 -24
- package/dist/src/peer-record-updater.d.ts.map +0 -1
- package/dist/src/peer-record-updater.js +0 -44
- package/dist/src/peer-record-updater.js.map +0 -1
- package/dist/typedoc-urls.json +0 -41
- package/src/connection-manager/auto-dialler.ts +0 -158
- package/src/connection-manager/dialer/dial-request.ts +0 -144
- package/src/connection-manager/dialer/index.ts +0 -461
- package/src/connection-manager/latency-monitor.ts +0 -319
- package/src/connection-manager/visibility-change-emitter.ts +0 -135
- package/src/constants.ts +0 -36
- package/src/peer-record-updater.ts +0 -65
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { AbortOptions, multiaddr } from '@multiformats/multiaddr'
|
|
2
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
3
|
+
import { logger } from '@libp2p/logger'
|
|
4
|
+
import { ClearableSignal, anySignal } from 'any-signal'
|
|
5
|
+
import { setMaxListeners } from 'events'
|
|
6
|
+
|
|
7
|
+
const log = logger('libp2p:connection-manager:utils')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolve multiaddr recursively
|
|
11
|
+
*/
|
|
12
|
+
export async function resolveMultiaddrs (ma: Multiaddr, options: AbortOptions): Promise<Multiaddr[]> {
|
|
13
|
+
// TODO: recursive logic should live in multiaddr once dns4/dns6 support is in place
|
|
14
|
+
// Now only supporting resolve for dnsaddr
|
|
15
|
+
const resolvableProto = ma.protoNames().includes('dnsaddr')
|
|
16
|
+
|
|
17
|
+
// Multiaddr is not resolvable? End recursion!
|
|
18
|
+
if (!resolvableProto) {
|
|
19
|
+
return [ma]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const resolvedMultiaddrs = await resolveRecord(ma, options)
|
|
23
|
+
const recursiveMultiaddrs = await Promise.all(resolvedMultiaddrs.map(async (nm) => {
|
|
24
|
+
return await resolveMultiaddrs(nm, options)
|
|
25
|
+
}))
|
|
26
|
+
|
|
27
|
+
const addrs = recursiveMultiaddrs.flat()
|
|
28
|
+
const output = addrs.reduce<Multiaddr[]>((array, newM) => {
|
|
29
|
+
if (array.find(m => m.equals(newM)) == null) {
|
|
30
|
+
array.push(newM)
|
|
31
|
+
}
|
|
32
|
+
return array
|
|
33
|
+
}, ([]))
|
|
34
|
+
|
|
35
|
+
log('resolved %s to', ma, output.map(ma => ma.toString()))
|
|
36
|
+
|
|
37
|
+
return output
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Resolve a given multiaddr. If this fails, an empty array will be returned
|
|
42
|
+
*/
|
|
43
|
+
async function resolveRecord (ma: Multiaddr, options: AbortOptions): Promise<Multiaddr[]> {
|
|
44
|
+
try {
|
|
45
|
+
ma = multiaddr(ma.toString()) // Use current multiaddr module
|
|
46
|
+
const multiaddrs = await ma.resolve(options)
|
|
47
|
+
return multiaddrs
|
|
48
|
+
} catch (err) {
|
|
49
|
+
log.error(`multiaddr ${ma.toString()} could not be resolved`, err)
|
|
50
|
+
return []
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function combineSignals (...signals: Array<AbortSignal | undefined>): ClearableSignal {
|
|
55
|
+
const sigs: AbortSignal[] = []
|
|
56
|
+
|
|
57
|
+
for (const sig of signals) {
|
|
58
|
+
if (sig != null) {
|
|
59
|
+
try {
|
|
60
|
+
// fails on node < 15.4
|
|
61
|
+
setMaxListeners?.(Infinity, sig)
|
|
62
|
+
} catch { }
|
|
63
|
+
sigs.push(sig)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// let any signal abort the dial
|
|
68
|
+
const signal = anySignal(sigs)
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
// fails on node < 15.4
|
|
72
|
+
setMaxListeners?.(Infinity, signal)
|
|
73
|
+
} catch {}
|
|
74
|
+
|
|
75
|
+
return signal
|
|
76
|
+
}
|
|
@@ -54,7 +54,7 @@ export class CompoundContentRouting implements ContentRouting, Startable {
|
|
|
54
54
|
*/
|
|
55
55
|
async * findProviders (key: CID, options: AbortOptions = {}): AsyncIterable<PeerInfo> {
|
|
56
56
|
if (this.routers.length === 0) {
|
|
57
|
-
throw new CodeError('No content
|
|
57
|
+
throw new CodeError('No content routers available', codes.ERR_NO_ROUTERS_AVAILABLE)
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
yield * pipe(
|
|
@@ -11,7 +11,9 @@ import type { PeerStore } from '@libp2p/interface-peer-store'
|
|
|
11
11
|
export async function * storeAddresses (source: Source<PeerInfo>, peerStore: PeerStore): AsyncIterable<PeerInfo> {
|
|
12
12
|
yield * map(source, async (peer) => {
|
|
13
13
|
// ensure we have the addresses for a given peer
|
|
14
|
-
await peerStore.
|
|
14
|
+
await peerStore.merge(peer.id, {
|
|
15
|
+
multiaddrs: peer.multiaddrs
|
|
16
|
+
})
|
|
15
17
|
|
|
16
18
|
return peer
|
|
17
19
|
})
|
package/src/fetch/index.ts
CHANGED
|
@@ -127,9 +127,9 @@ export class FetchService implements Startable {
|
|
|
127
127
|
|
|
128
128
|
const result = await pipe(
|
|
129
129
|
[FetchRequest.encode({ identifier: key })],
|
|
130
|
-
lp.encode(),
|
|
130
|
+
(source) => lp.encode(source),
|
|
131
131
|
source,
|
|
132
|
-
lp.decode(),
|
|
132
|
+
(source) => lp.decode(source),
|
|
133
133
|
async function (source) {
|
|
134
134
|
const buf = await first(source)
|
|
135
135
|
|
|
@@ -184,7 +184,7 @@ export class FetchService implements Startable {
|
|
|
184
184
|
|
|
185
185
|
await pipe(
|
|
186
186
|
stream,
|
|
187
|
-
lp.decode(),
|
|
187
|
+
(source) => lp.decode(source),
|
|
188
188
|
async function * (source) {
|
|
189
189
|
const buf = await first(source)
|
|
190
190
|
|
|
@@ -215,7 +215,7 @@ export class FetchService implements Startable {
|
|
|
215
215
|
|
|
216
216
|
yield FetchResponse.encode(response)
|
|
217
217
|
},
|
|
218
|
-
lp.encode(),
|
|
218
|
+
(source) => lp.encode(source),
|
|
219
219
|
stream
|
|
220
220
|
)
|
|
221
221
|
}
|
package/src/identify/index.ts
CHANGED
|
@@ -27,8 +27,12 @@ import { abortableDuplex } from 'abortable-iterator'
|
|
|
27
27
|
import { setMaxListeners } from 'events'
|
|
28
28
|
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
|
|
29
29
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
30
|
-
import type { PeerStore } from '@libp2p/interface-peer-store'
|
|
30
|
+
import type { Peer, PeerStore } from '@libp2p/interface-peer-store'
|
|
31
31
|
import type { AddressManager } from '@libp2p/interface-address-manager'
|
|
32
|
+
import type { EventEmitter } from '@libp2p/interfaces/events'
|
|
33
|
+
import type { Libp2pEvents } from '@libp2p/interface-libp2p'
|
|
34
|
+
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
35
|
+
import { pbStream } from 'it-pb-stream'
|
|
32
36
|
|
|
33
37
|
const log = logger('libp2p:identify')
|
|
34
38
|
|
|
@@ -74,6 +78,7 @@ export interface IdentifyServiceComponents {
|
|
|
74
78
|
connectionManager: ConnectionManager
|
|
75
79
|
registrar: Registrar
|
|
76
80
|
addressManager: AddressManager
|
|
81
|
+
events: EventEmitter<Libp2pEvents>
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
export class IdentifyService implements Startable {
|
|
@@ -103,27 +108,14 @@ export class IdentifyService implements Startable {
|
|
|
103
108
|
}
|
|
104
109
|
|
|
105
110
|
// When a new connection happens, trigger identify
|
|
106
|
-
this.components.
|
|
111
|
+
this.components.events.addEventListener('connection:open', (evt) => {
|
|
107
112
|
const connection = evt.detail
|
|
108
|
-
this.identify(connection).catch(log.error)
|
|
113
|
+
this.identify(connection).catch(err => { log.error('error during identify trigged by connection:open', err) })
|
|
109
114
|
})
|
|
110
115
|
|
|
111
|
-
// When self
|
|
112
|
-
this.components.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (this.components.peerId.equals(peerId)) {
|
|
116
|
-
void this.pushToPeerStore().catch(err => { log.error(err) })
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
// When self protocols change, trigger identify-push
|
|
121
|
-
this.components.peerStore.addEventListener('change:protocols', (evt) => {
|
|
122
|
-
const { peerId } = evt.detail
|
|
123
|
-
|
|
124
|
-
if (this.components.peerId.equals(peerId)) {
|
|
125
|
-
void this.pushToPeerStore().catch(err => { log.error(err) })
|
|
126
|
-
}
|
|
116
|
+
// When self peer record changes, trigger identify-push
|
|
117
|
+
this.components.events.addEventListener('self:peer:update', (evt) => {
|
|
118
|
+
void this.pushToPeerStore().catch(err => { log.error(err) })
|
|
127
119
|
})
|
|
128
120
|
}
|
|
129
121
|
|
|
@@ -136,8 +128,12 @@ export class IdentifyService implements Startable {
|
|
|
136
128
|
return
|
|
137
129
|
}
|
|
138
130
|
|
|
139
|
-
await this.components.peerStore.
|
|
140
|
-
|
|
131
|
+
await this.components.peerStore.merge(this.components.peerId, {
|
|
132
|
+
metadata: {
|
|
133
|
+
AgentVersion: uint8ArrayFromString(this.host.agentVersion),
|
|
134
|
+
ProtocolVersion: uint8ArrayFromString(this.host.protocolVersion)
|
|
135
|
+
}
|
|
136
|
+
})
|
|
141
137
|
|
|
142
138
|
await this.components.registrar.handle(this.identifyProtocolStr, (data) => {
|
|
143
139
|
void this._handleIdentify(data).catch(err => {
|
|
@@ -170,9 +166,16 @@ export class IdentifyService implements Startable {
|
|
|
170
166
|
* Send an Identify Push update to the list of connections
|
|
171
167
|
*/
|
|
172
168
|
async push (connections: Connection[]): Promise<void> {
|
|
173
|
-
const
|
|
174
|
-
const
|
|
175
|
-
|
|
169
|
+
const listenAddresses = this.components.addressManager.getAddresses().map(ma => ma.decapsulateCode(protocols('p2p').code))
|
|
170
|
+
const peerRecord = new PeerRecord({
|
|
171
|
+
peerId: this.components.peerId,
|
|
172
|
+
multiaddrs: listenAddresses
|
|
173
|
+
})
|
|
174
|
+
const signedPeerRecord = await RecordEnvelope.seal(peerRecord, this.components.peerId)
|
|
175
|
+
const supportedProtocols = this.components.registrar.getProtocols()
|
|
176
|
+
const peer = await this.components.peerStore.get(this.components.peerId)
|
|
177
|
+
const agentVersion = uint8ArrayToString(peer.metadata.get('AgentVersion') ?? uint8ArrayFromString(this.host.agentVersion))
|
|
178
|
+
const protocolVersion = uint8ArrayToString(peer.metadata.get('ProtocolVersion') ?? uint8ArrayFromString(this.host.protocolVersion))
|
|
176
179
|
|
|
177
180
|
const pushes = connections.map(async connection => {
|
|
178
181
|
let stream: Stream | undefined
|
|
@@ -193,11 +196,13 @@ export class IdentifyService implements Startable {
|
|
|
193
196
|
|
|
194
197
|
await source.sink(pipe(
|
|
195
198
|
[Identify.encode({
|
|
196
|
-
listenAddrs,
|
|
197
|
-
signedPeerRecord,
|
|
198
|
-
protocols
|
|
199
|
+
listenAddrs: listenAddresses.map(ma => ma.bytes),
|
|
200
|
+
signedPeerRecord: signedPeerRecord.marshal(),
|
|
201
|
+
protocols: supportedProtocols,
|
|
202
|
+
agentVersion,
|
|
203
|
+
protocolVersion
|
|
199
204
|
})],
|
|
200
|
-
lp.encode()
|
|
205
|
+
(source) => lp.encode(source)
|
|
201
206
|
))
|
|
202
207
|
} catch (err: any) {
|
|
203
208
|
// Just log errors
|
|
@@ -266,7 +271,7 @@ export class IdentifyService implements Startable {
|
|
|
266
271
|
const data = await pipe(
|
|
267
272
|
[],
|
|
268
273
|
source,
|
|
269
|
-
lp.decode({
|
|
274
|
+
(source) => lp.decode(source, {
|
|
270
275
|
maxDataLength: this.init.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
|
|
271
276
|
}),
|
|
272
277
|
async (source) => await first(source)
|
|
@@ -299,15 +304,10 @@ export class IdentifyService implements Startable {
|
|
|
299
304
|
*/
|
|
300
305
|
async identify (connection: Connection, options: AbortOptions = {}): Promise<void> {
|
|
301
306
|
const message = await this._identify(connection, options)
|
|
302
|
-
|
|
303
307
|
const {
|
|
304
308
|
publicKey,
|
|
305
|
-
listenAddrs,
|
|
306
309
|
protocols,
|
|
307
|
-
observedAddr
|
|
308
|
-
signedPeerRecord,
|
|
309
|
-
agentVersion,
|
|
310
|
-
protocolVersion
|
|
310
|
+
observedAddr
|
|
311
311
|
} = message
|
|
312
312
|
|
|
313
313
|
if (publicKey == null) {
|
|
@@ -327,57 +327,6 @@ export class IdentifyService implements Startable {
|
|
|
327
327
|
// Get the observedAddr if there is one
|
|
328
328
|
const cleanObservedAddr = IdentifyService.getCleanMultiaddr(observedAddr)
|
|
329
329
|
|
|
330
|
-
if (signedPeerRecord != null) {
|
|
331
|
-
log('received signed peer record from %p', id)
|
|
332
|
-
|
|
333
|
-
try {
|
|
334
|
-
const envelope = await RecordEnvelope.openAndCertify(signedPeerRecord, PeerRecord.DOMAIN)
|
|
335
|
-
|
|
336
|
-
if (!envelope.peerId.equals(id)) {
|
|
337
|
-
throw new CodeError('identified peer does not match the expected peer', codes.ERR_INVALID_PEER)
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (await this.components.peerStore.addressBook.consumePeerRecord(envelope)) {
|
|
341
|
-
await this.components.peerStore.protoBook.set(id, protocols)
|
|
342
|
-
|
|
343
|
-
if (agentVersion != null) {
|
|
344
|
-
await this.components.peerStore.metadataBook.setValue(id, 'AgentVersion', uint8ArrayFromString(agentVersion))
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (protocolVersion != null) {
|
|
348
|
-
await this.components.peerStore.metadataBook.setValue(id, 'ProtocolVersion', uint8ArrayFromString(protocolVersion))
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
log('identify completed for peer %p with and protocols %o', id, protocols)
|
|
352
|
-
|
|
353
|
-
return
|
|
354
|
-
}
|
|
355
|
-
} catch (err: any) {
|
|
356
|
-
log('received invalid envelope, discard it and fallback to listenAddrs is available', err)
|
|
357
|
-
}
|
|
358
|
-
} else {
|
|
359
|
-
log('no signed peer record received from %p', id)
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
log('falling back to legacy addresses from %p', id)
|
|
363
|
-
|
|
364
|
-
// LEGACY: Update peers data in PeerStore
|
|
365
|
-
try {
|
|
366
|
-
await this.components.peerStore.addressBook.set(id, listenAddrs.map((addr) => multiaddr(addr)))
|
|
367
|
-
} catch (err: any) {
|
|
368
|
-
log.error('received invalid addrs', err)
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
await this.components.peerStore.protoBook.set(id, protocols)
|
|
372
|
-
|
|
373
|
-
if (agentVersion != null) {
|
|
374
|
-
await this.components.peerStore.metadataBook.setValue(id, 'AgentVersion', uint8ArrayFromString(agentVersion))
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (protocolVersion != null) {
|
|
378
|
-
await this.components.peerStore.metadataBook.setValue(id, 'ProtocolVersion', uint8ArrayFromString(protocolVersion))
|
|
379
|
-
}
|
|
380
|
-
|
|
381
330
|
log('identify completed for peer %p and protocols %o', id, protocols)
|
|
382
331
|
log('our observed address is %s', cleanObservedAddr)
|
|
383
332
|
|
|
@@ -386,6 +335,8 @@ export class IdentifyService implements Startable {
|
|
|
386
335
|
log('storing our observed address %s', cleanObservedAddr?.toString())
|
|
387
336
|
this.components.addressManager.addObservedAddr(cleanObservedAddr)
|
|
388
337
|
}
|
|
338
|
+
|
|
339
|
+
await this.#consumeIdentifyMessage(connection.remotePeer, message)
|
|
389
340
|
}
|
|
390
341
|
|
|
391
342
|
/**
|
|
@@ -414,7 +365,6 @@ export class IdentifyService implements Startable {
|
|
|
414
365
|
})
|
|
415
366
|
|
|
416
367
|
const envelope = await RecordEnvelope.seal(peerRecord, this.components.peerId)
|
|
417
|
-
await this.components.peerStore.addressBook.consumePeerRecord(envelope)
|
|
418
368
|
signedPeerRecord = envelope.marshal().subarray()
|
|
419
369
|
}
|
|
420
370
|
|
|
@@ -431,7 +381,7 @@ export class IdentifyService implements Startable {
|
|
|
431
381
|
// make stream abortable
|
|
432
382
|
const source = abortableDuplex(stream, timeoutController.signal)
|
|
433
383
|
|
|
434
|
-
const msgWithLenPrefix = pipe([message], lp.encode())
|
|
384
|
+
const msgWithLenPrefix = pipe([message], (source) => lp.encode(source))
|
|
435
385
|
await source.sink(msgWithLenPrefix)
|
|
436
386
|
} catch (err: any) {
|
|
437
387
|
log.error('could not respond to identify request', err)
|
|
@@ -446,88 +396,98 @@ export class IdentifyService implements Startable {
|
|
|
446
396
|
*/
|
|
447
397
|
async _handlePush (data: IncomingStreamData): Promise<void> {
|
|
448
398
|
const { connection, stream } = data
|
|
449
|
-
const timeoutController = new TimeoutController(this.init.timeout)
|
|
450
399
|
|
|
451
400
|
try {
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
401
|
+
if (this.components.peerId.equals(connection.remotePeer)) {
|
|
402
|
+
throw new Error('received push from ourselves?')
|
|
403
|
+
}
|
|
455
404
|
|
|
456
|
-
let message: Identify | undefined
|
|
457
|
-
try {
|
|
458
405
|
// make stream abortable
|
|
459
|
-
const source = abortableDuplex(stream,
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
lp.decode({
|
|
465
|
-
maxDataLength: this.init.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
|
|
466
|
-
}),
|
|
467
|
-
async (source) => await first(source)
|
|
468
|
-
)
|
|
406
|
+
const source = abortableDuplex(stream, AbortSignal.timeout(this.init.timeout))
|
|
407
|
+
const pb = pbStream(source, {
|
|
408
|
+
maxDataLength: this.init.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
|
|
409
|
+
})
|
|
410
|
+
const message = await pb.readPB(Identify)
|
|
469
411
|
|
|
470
|
-
|
|
471
|
-
message = Identify.decode(data)
|
|
472
|
-
}
|
|
412
|
+
await this.#consumeIdentifyMessage(connection.remotePeer, message)
|
|
473
413
|
} catch (err: any) {
|
|
474
414
|
log.error('received invalid message', err)
|
|
475
415
|
return
|
|
476
416
|
} finally {
|
|
477
417
|
stream.close()
|
|
478
|
-
timeoutController.clear()
|
|
479
418
|
}
|
|
480
419
|
|
|
420
|
+
log('handled push from %p', connection.remotePeer)
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
async #consumeIdentifyMessage (remotePeer: PeerId, message: Identify): Promise<void> {
|
|
481
424
|
if (message == null) {
|
|
482
|
-
|
|
483
|
-
return
|
|
425
|
+
throw new Error('Message was null or undefined')
|
|
484
426
|
}
|
|
485
427
|
|
|
486
|
-
|
|
428
|
+
log('received identify from %p', remotePeer)
|
|
487
429
|
|
|
488
|
-
if (
|
|
489
|
-
log('received push from ourselves?')
|
|
430
|
+
if (message.signedPeerRecord == null) {
|
|
490
431
|
return
|
|
491
432
|
}
|
|
492
433
|
|
|
493
|
-
|
|
434
|
+
const envelope = await RecordEnvelope.openAndCertify(message.signedPeerRecord, PeerRecord.DOMAIN)
|
|
435
|
+
const peerRecord = PeerRecord.createFromProtobuf(envelope.payload)
|
|
494
436
|
|
|
495
|
-
|
|
496
|
-
|
|
437
|
+
// Verify peerId
|
|
438
|
+
if (!peerRecord.peerId.equals(envelope.peerId)) {
|
|
439
|
+
throw new Error('signing key does not match PeerId in the PeerRecord')
|
|
440
|
+
}
|
|
497
441
|
|
|
498
|
-
|
|
499
|
-
|
|
442
|
+
// Make sure remote peer is the one sending the record
|
|
443
|
+
if (!remotePeer.equals(peerRecord.peerId)) {
|
|
444
|
+
throw new Error('signing key does not match remote PeerId')
|
|
445
|
+
}
|
|
500
446
|
|
|
501
|
-
|
|
502
|
-
log('consumed signedPeerRecord sent in push')
|
|
447
|
+
let peer: Peer | undefined
|
|
503
448
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
} catch (err: any) {
|
|
510
|
-
log('received invalid envelope, discard it and fallback to listenAddrs is available', err)
|
|
449
|
+
try {
|
|
450
|
+
peer = await this.components.peerStore.get(peerRecord.peerId)
|
|
451
|
+
} catch (err: any) {
|
|
452
|
+
if (err.code !== 'ERR_NOT_FOUND') {
|
|
453
|
+
throw err
|
|
511
454
|
}
|
|
512
|
-
} else {
|
|
513
|
-
log('did not receive signedPeerRecord in push')
|
|
514
455
|
}
|
|
515
456
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
457
|
+
log('received signedPeerRecord in push from %p', remotePeer)
|
|
458
|
+
let metadata = new Map()
|
|
459
|
+
|
|
460
|
+
if (peer?.peerRecordEnvelope != null) {
|
|
461
|
+
const storedEnvelope = await RecordEnvelope.createFromProtobuf(peer.peerRecordEnvelope)
|
|
462
|
+
const storedRecord = PeerRecord.createFromProtobuf(storedEnvelope.payload)
|
|
463
|
+
|
|
464
|
+
// ensure seq is greater than, or equal to, the last received
|
|
465
|
+
if (storedRecord.seqNumber >= peerRecord.seqNumber) {
|
|
466
|
+
log('sequence number was lower or equal to existing sequence number - stored: %d received: %d', storedRecord.seqNumber, peerRecord.seqNumber)
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
metadata = peer.metadata
|
|
521
470
|
}
|
|
522
471
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
await this.components.peerStore.protoBook.set(id, message.protocols)
|
|
526
|
-
} catch (err: any) {
|
|
527
|
-
log.error('received invalid protocols', err)
|
|
472
|
+
if (message.agentVersion != null) {
|
|
473
|
+
metadata.set('AgentVersion', uint8ArrayFromString(message.agentVersion))
|
|
528
474
|
}
|
|
529
475
|
|
|
530
|
-
|
|
476
|
+
if (message.protocolVersion != null) {
|
|
477
|
+
metadata.set('ProtocolVersion', uint8ArrayFromString(message.protocolVersion))
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
await this.components.peerStore.patch(peerRecord.peerId, {
|
|
481
|
+
peerRecordEnvelope: message.signedPeerRecord,
|
|
482
|
+
protocols: message.protocols,
|
|
483
|
+
addresses: peerRecord.multiaddrs.map(multiaddr => ({
|
|
484
|
+
isCertified: true,
|
|
485
|
+
multiaddr
|
|
486
|
+
})),
|
|
487
|
+
metadata
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
log('consumed signedPeerRecord sent in push from %p', remotePeer)
|
|
531
491
|
}
|
|
532
492
|
|
|
533
493
|
/**
|
package/src/index.ts
CHANGED
|
@@ -20,7 +20,6 @@ import type { TransportManagerInit } from './transport-manager.js'
|
|
|
20
20
|
import type { IdentifyServiceInit } from './identify/index.js'
|
|
21
21
|
import type { DualDHT } from '@libp2p/interface-dht'
|
|
22
22
|
import type { Datastore } from 'interface-datastore'
|
|
23
|
-
import type { PeerStoreInit } from '@libp2p/interface-peer-store'
|
|
24
23
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
25
24
|
import type { PeerDiscovery } from '@libp2p/interface-peer-discovery'
|
|
26
25
|
import type { ConnectionProtector } from '@libp2p/interface-connection'
|
|
@@ -32,7 +31,6 @@ import type { PeerRouting } from '@libp2p/interface-peer-routing'
|
|
|
32
31
|
import type { ContentRouting } from '@libp2p/interface-content-routing'
|
|
33
32
|
import type { PubSub } from '@libp2p/interface-pubsub'
|
|
34
33
|
import type { Metrics } from '@libp2p/interface-metrics'
|
|
35
|
-
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
36
34
|
import type { PingServiceInit } from './ping/index.js'
|
|
37
35
|
import type { FetchServiceInit } from './fetch/index.js'
|
|
38
36
|
import type { AutonatServiceInit } from './autonat/index.js'
|
|
@@ -44,6 +42,7 @@ import type { AddressManagerInit } from './address-manager/index.js'
|
|
|
44
42
|
import type { PeerRoutingInit } from './peer-routing.js'
|
|
45
43
|
import type { ConnectionManagerInit } from './connection-manager/index.js'
|
|
46
44
|
import type { CircuitRelayService } from './circuit-relay/index.js'
|
|
45
|
+
import type { PersistentPeerStoreInit } from '@libp2p/peer-store'
|
|
47
46
|
|
|
48
47
|
/**
|
|
49
48
|
* For Libp2p configurations and modules details read the [Configuration Document](./CONFIGURATION.md).
|
|
@@ -84,7 +83,7 @@ export interface Libp2pInit {
|
|
|
84
83
|
/**
|
|
85
84
|
* libp2p PeerStore configuration
|
|
86
85
|
*/
|
|
87
|
-
peerStore:
|
|
86
|
+
peerStore: PersistentPeerStoreInit
|
|
88
87
|
|
|
89
88
|
/**
|
|
90
89
|
* libp2p Peer routing service configuration
|
|
@@ -158,23 +157,6 @@ export interface Libp2pInit {
|
|
|
158
157
|
connectionProtector?: (components: Components) => ConnectionProtector
|
|
159
158
|
}
|
|
160
159
|
|
|
161
|
-
/**
|
|
162
|
-
* Once you have a libp2p instance, you can listen to several events it emits, so that you can be notified of relevant network events.
|
|
163
|
-
*/
|
|
164
|
-
export interface Libp2pEvents {
|
|
165
|
-
/**
|
|
166
|
-
* @example
|
|
167
|
-
*
|
|
168
|
-
* ```js
|
|
169
|
-
* libp2p.addEventListener('peer:discovery', (event) => {
|
|
170
|
-
* const peerInfo = event.detail
|
|
171
|
-
* // ...
|
|
172
|
-
* })
|
|
173
|
-
* ```
|
|
174
|
-
*/
|
|
175
|
-
'peer:discovery': CustomEvent<PeerInfo>
|
|
176
|
-
}
|
|
177
|
-
|
|
178
160
|
export type { Libp2p }
|
|
179
161
|
|
|
180
162
|
export type Libp2pOptions = RecursivePartial<Libp2pInit> & { start?: boolean }
|
package/src/insecure/index.ts
CHANGED
|
@@ -30,7 +30,7 @@ import { Exchange, KeyType } from './pb/proto.js'
|
|
|
30
30
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
31
31
|
import { peerIdFromBytes, peerIdFromKeys } from '@libp2p/peer-id'
|
|
32
32
|
import type { ConnectionEncrypter, SecuredConnection } from '@libp2p/interface-connection-encrypter'
|
|
33
|
-
import type { Duplex } from 'it-stream-types'
|
|
33
|
+
import type { Duplex, Source } from 'it-stream-types'
|
|
34
34
|
import map from 'it-map'
|
|
35
35
|
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
36
36
|
|
|
@@ -46,7 +46,7 @@ function lpEncodeExchange (exchange: Exchange): Uint8ArrayList {
|
|
|
46
46
|
/**
|
|
47
47
|
* Encrypt connection
|
|
48
48
|
*/
|
|
49
|
-
async function encrypt (localId: PeerId, conn: Duplex<Uint8Array>, remoteId?: PeerId): Promise<SecuredConnection> {
|
|
49
|
+
async function encrypt (localId: PeerId, conn: Duplex<AsyncGenerator<Uint8Array>, Source<Uint8Array>, Promise<void>>, remoteId?: PeerId): Promise<SecuredConnection> {
|
|
50
50
|
const shake = handshake(conn)
|
|
51
51
|
|
|
52
52
|
let type = KeyType.RSA
|
|
@@ -71,8 +71,12 @@ async function encrypt (localId: PeerId, conn: Duplex<Uint8Array>, remoteId?: Pe
|
|
|
71
71
|
log('write pubkey exchange to peer %p', remoteId)
|
|
72
72
|
|
|
73
73
|
// Get the Exchange message
|
|
74
|
-
// @ts-expect-error needs to be generator
|
|
75
74
|
const response = (await lp.decode.fromReader(shake.reader).next()).value
|
|
75
|
+
|
|
76
|
+
if (response == null) {
|
|
77
|
+
throw new Error('Did not read response')
|
|
78
|
+
}
|
|
79
|
+
|
|
76
80
|
const id = Exchange.decode(response)
|
|
77
81
|
log('read pubkey exchange from peer %p', remoteId)
|
|
78
82
|
|
|
@@ -120,11 +124,11 @@ async function encrypt (localId: PeerId, conn: Duplex<Uint8Array>, remoteId?: Pe
|
|
|
120
124
|
class Plaintext implements ConnectionEncrypter {
|
|
121
125
|
public protocol: string = PROTOCOL
|
|
122
126
|
|
|
123
|
-
async secureInbound (localId: PeerId, conn: Duplex<Uint8Array>, remoteId?: PeerId): Promise<SecuredConnection> {
|
|
127
|
+
async secureInbound (localId: PeerId, conn: Duplex<AsyncGenerator<Uint8Array>, Source<Uint8Array>, Promise<void>>, remoteId?: PeerId): Promise<SecuredConnection> {
|
|
124
128
|
return await encrypt(localId, conn, remoteId)
|
|
125
129
|
}
|
|
126
130
|
|
|
127
|
-
async secureOutbound (localId: PeerId, conn: Duplex<Uint8Array>, remoteId?: PeerId): Promise<SecuredConnection> {
|
|
131
|
+
async secureOutbound (localId: PeerId, conn: Duplex<AsyncGenerator<Uint8Array>, Source<Uint8Array>, Promise<void>>, remoteId?: PeerId): Promise<SecuredConnection> {
|
|
128
132
|
return await encrypt(localId, conn, remoteId)
|
|
129
133
|
}
|
|
130
134
|
}
|