@libp2p/kad-dht 11.0.8 → 12.0.0-cd8cafcd5
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 +78 -0
- package/dist/index.min.js +20 -20
- package/dist/src/constants.d.ts +2 -4
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +7 -9
- package/dist/src/constants.js.map +1 -1
- package/dist/src/content-fetching/index.d.ts +7 -7
- package/dist/src/content-fetching/index.d.ts.map +1 -1
- package/dist/src/content-fetching/index.js +13 -7
- package/dist/src/content-fetching/index.js.map +1 -1
- package/dist/src/content-routing/index.d.ts +5 -4
- package/dist/src/content-routing/index.d.ts.map +1 -1
- package/dist/src/content-routing/index.js +23 -13
- package/dist/src/content-routing/index.js.map +1 -1
- package/dist/src/index.d.ts +142 -28
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +87 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/kad-dht.d.ts +20 -21
- package/dist/src/kad-dht.d.ts.map +1 -1
- package/dist/src/kad-dht.js +181 -35
- package/dist/src/kad-dht.js.map +1 -1
- package/dist/src/message/dht.d.ts +35 -35
- package/dist/src/message/dht.d.ts.map +1 -1
- package/dist/src/message/dht.js +150 -130
- package/dist/src/message/dht.js.map +1 -1
- package/dist/src/message/utils.d.ts +5 -0
- package/dist/src/message/utils.d.ts.map +1 -0
- package/dist/src/message/utils.js +20 -0
- package/dist/src/message/utils.js.map +1 -0
- package/dist/src/network.d.ts +8 -8
- package/dist/src/network.d.ts.map +1 -1
- package/dist/src/network.js +30 -18
- package/dist/src/network.js.map +1 -1
- package/dist/src/peer-routing/index.d.ts +6 -6
- package/dist/src/peer-routing/index.d.ts.map +1 -1
- package/dist/src/peer-routing/index.js +48 -35
- package/dist/src/peer-routing/index.js.map +1 -1
- package/dist/src/providers.d.ts +7 -0
- package/dist/src/providers.d.ts.map +1 -1
- package/dist/src/providers.js.map +1 -1
- package/dist/src/query/events.d.ts +13 -12
- package/dist/src/query/events.d.ts.map +1 -1
- package/dist/src/query/events.js +2 -2
- package/dist/src/query/events.js.map +1 -1
- package/dist/src/query/manager.d.ts +8 -5
- package/dist/src/query/manager.d.ts.map +1 -1
- package/dist/src/query/manager.js +6 -6
- package/dist/src/query/manager.js.map +1 -1
- package/dist/src/query/query-path.d.ts +3 -3
- package/dist/src/query/query-path.d.ts.map +1 -1
- package/dist/src/query-self.d.ts +1 -1
- package/dist/src/query-self.d.ts.map +1 -1
- package/dist/src/query-self.js +2 -2
- package/dist/src/query-self.js.map +1 -1
- package/dist/src/routing-table/index.d.ts +5 -6
- package/dist/src/routing-table/index.d.ts.map +1 -1
- package/dist/src/routing-table/index.js +72 -58
- package/dist/src/routing-table/index.js.map +1 -1
- package/dist/src/routing-table/refresh.d.ts +1 -1
- package/dist/src/routing-table/refresh.d.ts.map +1 -1
- package/dist/src/routing-table/refresh.js +2 -2
- package/dist/src/routing-table/refresh.js.map +1 -1
- package/dist/src/rpc/handlers/add-provider.d.ts +2 -1
- package/dist/src/rpc/handlers/add-provider.d.ts.map +1 -1
- package/dist/src/rpc/handlers/add-provider.js +8 -6
- package/dist/src/rpc/handlers/add-provider.js.map +1 -1
- package/dist/src/rpc/handlers/find-node.d.ts +5 -3
- package/dist/src/rpc/handlers/find-node.d.ts.map +1 -1
- package/dist/src/rpc/handlers/find-node.js +22 -14
- package/dist/src/rpc/handlers/find-node.js.map +1 -1
- package/dist/src/rpc/handlers/get-providers.d.ts +5 -3
- package/dist/src/rpc/handlers/get-providers.d.ts.map +1 -1
- package/dist/src/rpc/handlers/get-providers.js +29 -16
- package/dist/src/rpc/handlers/get-providers.js.map +1 -1
- package/dist/src/rpc/handlers/get-value.d.ts +2 -1
- package/dist/src/rpc/handlers/get-value.d.ts.map +1 -1
- package/dist/src/rpc/handlers/get-value.js +16 -7
- package/dist/src/rpc/handlers/get-value.js.map +1 -1
- package/dist/src/rpc/handlers/ping.d.ts +5 -2
- package/dist/src/rpc/handlers/ping.d.ts.map +1 -1
- package/dist/src/rpc/handlers/ping.js +2 -2
- package/dist/src/rpc/handlers/ping.js.map +1 -1
- package/dist/src/rpc/handlers/put-value.d.ts +2 -1
- package/dist/src/rpc/handlers/put-value.d.ts.map +1 -1
- package/dist/src/rpc/handlers/put-value.js +8 -7
- package/dist/src/rpc/handlers/put-value.js.map +1 -1
- package/dist/src/rpc/index.d.ts +4 -3
- package/dist/src/rpc/index.d.ts.map +1 -1
- package/dist/src/rpc/index.js +11 -11
- package/dist/src/rpc/index.js.map +1 -1
- package/dist/src/topology-listener.d.ts +1 -1
- package/dist/src/topology-listener.d.ts.map +1 -1
- package/dist/src/topology-listener.js +2 -2
- package/dist/src/topology-listener.js.map +1 -1
- package/dist/src/utils.d.ts +5 -2
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +32 -2
- package/dist/src/utils.js.map +1 -1
- package/package.json +12 -10
- package/src/constants.ts +7 -11
- package/src/content-fetching/index.ts +21 -14
- package/src/content-routing/index.ts +29 -18
- package/src/index.ts +148 -32
- package/src/kad-dht.ts +225 -56
- package/src/message/dht.proto +32 -32
- package/src/message/dht.ts +155 -138
- package/src/message/utils.ts +25 -0
- package/src/network.ts +41 -25
- package/src/peer-routing/index.ts +57 -42
- package/src/providers.ts +7 -0
- package/src/query/events.ts +14 -14
- package/src/query/manager.ts +14 -10
- package/src/query/query-path.ts +3 -3
- package/src/query-self.ts +3 -3
- package/src/routing-table/index.ts +86 -64
- package/src/routing-table/refresh.ts +4 -4
- package/src/rpc/handlers/add-provider.ts +10 -7
- package/src/rpc/handlers/find-node.ts +27 -18
- package/src/rpc/handlers/get-providers.ts +33 -20
- package/src/rpc/handlers/get-value.ts +18 -7
- package/src/rpc/handlers/ping.ts +7 -3
- package/src/rpc/handlers/put-value.ts +11 -9
- package/src/rpc/index.ts +14 -13
- package/src/topology-listener.ts +3 -3
- package/src/utils.ts +41 -2
- package/dist/src/dual-kad-dht.d.ts +0 -69
- package/dist/src/dual-kad-dht.d.ts.map +0 -1
- package/dist/src/dual-kad-dht.js +0 -304
- package/dist/src/dual-kad-dht.js.map +0 -1
- package/dist/src/message/index.d.ts +0 -35
- package/dist/src/message/index.d.ts.map +0 -1
- package/dist/src/message/index.js +0 -92
- package/dist/src/message/index.js.map +0 -1
- package/dist/typedoc-urls.json +0 -55
- package/src/dual-kad-dht.ts +0 -384
- package/src/message/index.ts +0 -117
package/src/dual-kad-dht.ts
DELETED
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
import { contentRoutingSymbol, peerDiscoverySymbol, peerRoutingSymbol, CodeError, TypedEventEmitter, CustomEvent } from '@libp2p/interface'
|
|
2
|
-
import drain from 'it-drain'
|
|
3
|
-
import merge from 'it-merge'
|
|
4
|
-
import isPrivate from 'private-ip'
|
|
5
|
-
import { DefaultKadDHT } from './kad-dht.js'
|
|
6
|
-
import { queryErrorEvent } from './query/events.js'
|
|
7
|
-
import type { DualKadDHT, KadDHT, KadDHTComponents, KadDHTInit, QueryEvent, QueryOptions } from './index.js'
|
|
8
|
-
import type { PeerDiscovery, PeerDiscoveryEvents, PeerRouting, ContentRouting, Logger, PeerId, PeerInfo } from '@libp2p/interface'
|
|
9
|
-
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
10
|
-
import type { CID } from 'multiformats/cid'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Wrapper class to convert events into returned values
|
|
14
|
-
*/
|
|
15
|
-
class DHTContentRouting implements ContentRouting {
|
|
16
|
-
private readonly dht: KadDHT
|
|
17
|
-
|
|
18
|
-
constructor (dht: KadDHT) {
|
|
19
|
-
this.dht = dht
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async provide (cid: CID, options: QueryOptions = {}): Promise<void> {
|
|
23
|
-
await drain(this.dht.provide(cid, options))
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async * findProviders (cid: CID, options: QueryOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
|
|
27
|
-
for await (const event of this.dht.findProviders(cid, options)) {
|
|
28
|
-
if (event.name === 'PROVIDER') {
|
|
29
|
-
yield * event.providers
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async put (key: Uint8Array, value: Uint8Array, options?: QueryOptions): Promise<void> {
|
|
35
|
-
await drain(this.dht.put(key, value, options))
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async get (key: Uint8Array, options?: QueryOptions): Promise<Uint8Array> {
|
|
39
|
-
for await (const event of this.dht.get(key, options)) {
|
|
40
|
-
if (event.name === 'VALUE') {
|
|
41
|
-
return event.value
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
throw new CodeError('Not found', 'ERR_NOT_FOUND')
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Wrapper class to convert events into returned values
|
|
51
|
-
*/
|
|
52
|
-
class DHTPeerRouting implements PeerRouting {
|
|
53
|
-
private readonly dht: KadDHT
|
|
54
|
-
|
|
55
|
-
constructor (dht: KadDHT) {
|
|
56
|
-
this.dht = dht
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async findPeer (peerId: PeerId, options: QueryOptions = {}): Promise<PeerInfo> {
|
|
60
|
-
for await (const event of this.dht.findPeer(peerId, options)) {
|
|
61
|
-
if (event.name === 'FINAL_PEER') {
|
|
62
|
-
return event.peer
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
throw new CodeError('Not found', 'ERR_NOT_FOUND')
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncIterable<PeerInfo> {
|
|
70
|
-
for await (const event of this.dht.getClosestPeers(key, options)) {
|
|
71
|
-
if (event.name === 'FINAL_PEER') {
|
|
72
|
-
yield event.peer
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// see https://github.com/multiformats/multiaddr/blob/master/protocols.csv
|
|
79
|
-
const P2P_CIRCUIT_CODE = 290
|
|
80
|
-
const DNS4_CODE = 54
|
|
81
|
-
const DNS6_CODE = 55
|
|
82
|
-
const DNSADDR_CODE = 56
|
|
83
|
-
const IP4_CODE = 4
|
|
84
|
-
const IP6_CODE = 41
|
|
85
|
-
|
|
86
|
-
function multiaddrIsPublic (multiaddr: Multiaddr): boolean {
|
|
87
|
-
const tuples = multiaddr.stringTuples()
|
|
88
|
-
|
|
89
|
-
// p2p-circuit should not enable server mode
|
|
90
|
-
for (const tuple of tuples) {
|
|
91
|
-
if (tuple[0] === P2P_CIRCUIT_CODE) {
|
|
92
|
-
return false
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// dns4 or dns6 or dnsaddr
|
|
97
|
-
if (tuples[0][0] === DNS4_CODE || tuples[0][0] === DNS6_CODE || tuples[0][0] === DNSADDR_CODE) {
|
|
98
|
-
return true
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// ip4 or ip6
|
|
102
|
-
if (tuples[0][0] === IP4_CODE || tuples[0][0] === IP6_CODE) {
|
|
103
|
-
const result = isPrivate(`${tuples[0][1]}`)
|
|
104
|
-
const isPublic = result == null || !result
|
|
105
|
-
|
|
106
|
-
return isPublic
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return false
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* A DHT implementation modelled after Kademlia with S/Kademlia modifications.
|
|
114
|
-
* Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
|
|
115
|
-
*/
|
|
116
|
-
export class DefaultDualKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implements DualKadDHT, PeerDiscovery {
|
|
117
|
-
public readonly wan: DefaultKadDHT
|
|
118
|
-
public readonly lan: DefaultKadDHT
|
|
119
|
-
public readonly components: KadDHTComponents
|
|
120
|
-
private readonly contentRouting: ContentRouting
|
|
121
|
-
private readonly peerRouting: PeerRouting
|
|
122
|
-
private readonly log: Logger
|
|
123
|
-
|
|
124
|
-
constructor (components: KadDHTComponents, init: KadDHTInit = {}) {
|
|
125
|
-
super()
|
|
126
|
-
|
|
127
|
-
this.components = components
|
|
128
|
-
this.log = components.logger.forComponent('libp2p:kad-dht')
|
|
129
|
-
|
|
130
|
-
this.wan = new DefaultKadDHT(components, {
|
|
131
|
-
protocolPrefix: '/ipfs',
|
|
132
|
-
...init,
|
|
133
|
-
lan: false
|
|
134
|
-
})
|
|
135
|
-
this.lan = new DefaultKadDHT(components, {
|
|
136
|
-
protocolPrefix: '/ipfs',
|
|
137
|
-
...init,
|
|
138
|
-
clientMode: false,
|
|
139
|
-
lan: true
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
this.contentRouting = new DHTContentRouting(this)
|
|
143
|
-
this.peerRouting = new DHTPeerRouting(this)
|
|
144
|
-
|
|
145
|
-
// handle peers being discovered during processing of DHT messages
|
|
146
|
-
this.wan.addEventListener('peer', (evt) => {
|
|
147
|
-
this.dispatchEvent(new CustomEvent('peer', {
|
|
148
|
-
detail: evt.detail
|
|
149
|
-
}))
|
|
150
|
-
})
|
|
151
|
-
this.lan.addEventListener('peer', (evt) => {
|
|
152
|
-
this.dispatchEvent(new CustomEvent('peer', {
|
|
153
|
-
detail: evt.detail
|
|
154
|
-
}))
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
// if client mode has not been explicitly specified, auto-switch to server
|
|
158
|
-
// mode when the node's peer data is updated with publicly dialable addresses
|
|
159
|
-
if (init.clientMode == null) {
|
|
160
|
-
components.events.addEventListener('self:peer:update', (evt) => {
|
|
161
|
-
this.log('received update of self-peer info')
|
|
162
|
-
const hasPublicAddress = evt.detail.peer.addresses
|
|
163
|
-
.some(({ multiaddr }) => multiaddrIsPublic(multiaddr))
|
|
164
|
-
|
|
165
|
-
this.getMode()
|
|
166
|
-
.then(async mode => {
|
|
167
|
-
if (hasPublicAddress && mode === 'client') {
|
|
168
|
-
await this.setMode('server')
|
|
169
|
-
} else if (mode === 'server' && !hasPublicAddress) {
|
|
170
|
-
await this.setMode('client')
|
|
171
|
-
}
|
|
172
|
-
})
|
|
173
|
-
.catch(err => {
|
|
174
|
-
this.log.error('error setting dht server mode', err)
|
|
175
|
-
})
|
|
176
|
-
})
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
readonly [Symbol.toStringTag] = '@libp2p/dual-kad-dht'
|
|
181
|
-
|
|
182
|
-
get [contentRoutingSymbol] (): ContentRouting {
|
|
183
|
-
return this.contentRouting
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
get [peerRoutingSymbol] (): PeerRouting {
|
|
187
|
-
return this.peerRouting
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
get [peerDiscoverySymbol] (): PeerDiscovery {
|
|
191
|
-
return this
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Is this DHT running.
|
|
196
|
-
*/
|
|
197
|
-
isStarted (): boolean {
|
|
198
|
-
return this.wan.isStarted() && this.lan.isStarted()
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* If 'server' this node will respond to DHT queries, if 'client' this node will not
|
|
203
|
-
*/
|
|
204
|
-
async getMode (): Promise<'client' | 'server'> {
|
|
205
|
-
return this.wan.getMode()
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* If 'server' this node will respond to DHT queries, if 'client' this node will not
|
|
210
|
-
*/
|
|
211
|
-
async setMode (mode: 'client' | 'server'): Promise<void> {
|
|
212
|
-
await this.wan.setMode(mode)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Start listening to incoming connections.
|
|
217
|
-
*/
|
|
218
|
-
async start (): Promise<void> {
|
|
219
|
-
await Promise.all([
|
|
220
|
-
this.lan.start(),
|
|
221
|
-
this.wan.start()
|
|
222
|
-
])
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Stop accepting incoming connections and sending outgoing
|
|
227
|
-
* messages.
|
|
228
|
-
*/
|
|
229
|
-
async stop (): Promise<void> {
|
|
230
|
-
await Promise.all([
|
|
231
|
-
this.lan.stop(),
|
|
232
|
-
this.wan.stop()
|
|
233
|
-
])
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Store the given key/value pair in the DHT
|
|
238
|
-
*/
|
|
239
|
-
async * put (key: Uint8Array, value: Uint8Array, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
|
|
240
|
-
for await (const event of merge(
|
|
241
|
-
this.lan.put(key, value, options),
|
|
242
|
-
this.wan.put(key, value, options)
|
|
243
|
-
)) {
|
|
244
|
-
yield event
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Get the value that corresponds to the passed key
|
|
250
|
-
*/
|
|
251
|
-
async * get (key: Uint8Array, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
|
|
252
|
-
let queriedPeers = false
|
|
253
|
-
let foundValue = false
|
|
254
|
-
|
|
255
|
-
for await (const event of merge(
|
|
256
|
-
this.lan.get(key, options),
|
|
257
|
-
this.wan.get(key, options)
|
|
258
|
-
)) {
|
|
259
|
-
yield event
|
|
260
|
-
|
|
261
|
-
if (event.name === 'DIAL_PEER') {
|
|
262
|
-
queriedPeers = true
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (event.name === 'VALUE') {
|
|
266
|
-
queriedPeers = true
|
|
267
|
-
|
|
268
|
-
if (event.value != null) {
|
|
269
|
-
foundValue = true
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (event.name === 'SEND_QUERY') {
|
|
274
|
-
queriedPeers = true
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (!queriedPeers) {
|
|
279
|
-
throw new CodeError('No peers found in routing table!', 'ERR_NO_PEERS_IN_ROUTING_TABLE')
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (!foundValue) {
|
|
283
|
-
yield queryErrorEvent({
|
|
284
|
-
from: this.components.peerId,
|
|
285
|
-
error: new CodeError('Not found', 'ERR_NOT_FOUND')
|
|
286
|
-
}, options)
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// ----------- Content Routing
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Announce to the network that we can provide given key's value
|
|
294
|
-
*/
|
|
295
|
-
async * provide (key: CID, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
|
|
296
|
-
let sent = 0
|
|
297
|
-
let success = 0
|
|
298
|
-
const errors = []
|
|
299
|
-
|
|
300
|
-
const dhts = [this.lan]
|
|
301
|
-
|
|
302
|
-
// only run provide on the wan if we are in server mode
|
|
303
|
-
if ((await this.wan.getMode()) === 'server') {
|
|
304
|
-
dhts.push(this.wan)
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
for await (const event of merge(...dhts.map(dht => dht.provide(key, options)))) {
|
|
308
|
-
yield event
|
|
309
|
-
|
|
310
|
-
if (event.name === 'SEND_QUERY') {
|
|
311
|
-
sent++
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (event.name === 'QUERY_ERROR') {
|
|
315
|
-
errors.push(event.error)
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (event.name === 'PEER_RESPONSE' && event.messageName === 'ADD_PROVIDER') {
|
|
319
|
-
this.log('sent provider record for %s to %p', key, event.from)
|
|
320
|
-
success++
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (success === 0) {
|
|
325
|
-
if (errors.length > 0) {
|
|
326
|
-
// if all sends failed, throw an error to inform the caller
|
|
327
|
-
throw new CodeError(`Failed to provide to ${errors.length} of ${sent} peers`, 'ERR_PROVIDES_FAILED', { errors })
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
throw new CodeError('Failed to provide - no peers found', 'ERR_PROVIDES_FAILED')
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Search the dht for up to `K` providers of the given CID
|
|
336
|
-
*/
|
|
337
|
-
async * findProviders (key: CID, options: QueryOptions = {}): AsyncGenerator<QueryEvent, void, undefined> {
|
|
338
|
-
yield * merge(
|
|
339
|
-
this.lan.findProviders(key, options),
|
|
340
|
-
this.wan.findProviders(key, options)
|
|
341
|
-
)
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// ----------- Peer Routing -----------
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Search for a peer with the given ID
|
|
348
|
-
*/
|
|
349
|
-
async * findPeer (id: PeerId, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
|
|
350
|
-
let queriedPeers = false
|
|
351
|
-
|
|
352
|
-
for await (const event of merge(
|
|
353
|
-
this.lan.findPeer(id, options),
|
|
354
|
-
this.wan.findPeer(id, options)
|
|
355
|
-
)) {
|
|
356
|
-
yield event
|
|
357
|
-
|
|
358
|
-
if (event.name === 'SEND_QUERY' || event.name === 'FINAL_PEER') {
|
|
359
|
-
queriedPeers = true
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
if (!queriedPeers) {
|
|
364
|
-
throw new CodeError('Peer lookup failed', 'ERR_LOOKUP_FAILED')
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Kademlia 'node lookup' operation
|
|
370
|
-
*/
|
|
371
|
-
async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncGenerator<QueryEvent, void, undefined> {
|
|
372
|
-
yield * merge(
|
|
373
|
-
this.lan.getClosestPeers(key, options),
|
|
374
|
-
this.wan.getClosestPeers(key, options)
|
|
375
|
-
)
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
async refreshRoutingTable (): Promise<void> {
|
|
379
|
-
await Promise.all([
|
|
380
|
-
this.lan.refreshRoutingTable(),
|
|
381
|
-
this.wan.refreshRoutingTable()
|
|
382
|
-
])
|
|
383
|
-
}
|
|
384
|
-
}
|
package/src/message/index.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { peerIdFromBytes } from '@libp2p/peer-id'
|
|
2
|
-
import { multiaddr } from '@multiformats/multiaddr'
|
|
3
|
-
import { Libp2pRecord } from '../record/index.js'
|
|
4
|
-
import { Message as PBMessage } from './dht.js'
|
|
5
|
-
import type { PeerInfo } from '@libp2p/interface'
|
|
6
|
-
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
7
|
-
|
|
8
|
-
export const MESSAGE_TYPE = PBMessage.MessageType
|
|
9
|
-
export const CONNECTION_TYPE = PBMessage.ConnectionType
|
|
10
|
-
export const MESSAGE_TYPE_LOOKUP = Object.keys(MESSAGE_TYPE)
|
|
11
|
-
|
|
12
|
-
interface PBPeer {
|
|
13
|
-
id: Uint8Array
|
|
14
|
-
addrs: Uint8Array[]
|
|
15
|
-
connection: PBMessage.ConnectionType
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Represents a single DHT control message.
|
|
20
|
-
*/
|
|
21
|
-
export class Message {
|
|
22
|
-
public type: PBMessage.MessageType
|
|
23
|
-
public key: Uint8Array
|
|
24
|
-
private clusterLevelRaw: number
|
|
25
|
-
public closerPeers: PeerInfo[]
|
|
26
|
-
public providerPeers: PeerInfo[]
|
|
27
|
-
public record?: Libp2pRecord
|
|
28
|
-
|
|
29
|
-
constructor (type: PBMessage.MessageType, key: Uint8Array, level: number) {
|
|
30
|
-
if (!(key instanceof Uint8Array)) {
|
|
31
|
-
throw new Error('Key must be a Uint8Array')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
this.type = type
|
|
35
|
-
this.key = key
|
|
36
|
-
this.clusterLevelRaw = level
|
|
37
|
-
this.closerPeers = []
|
|
38
|
-
this.providerPeers = []
|
|
39
|
-
this.record = undefined
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @type {number}
|
|
44
|
-
*/
|
|
45
|
-
get clusterLevel (): number {
|
|
46
|
-
const level = this.clusterLevelRaw - 1
|
|
47
|
-
if (level < 0) {
|
|
48
|
-
return 0
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return level
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
set clusterLevel (level) {
|
|
55
|
-
this.clusterLevelRaw = level
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Encode into protobuf
|
|
60
|
-
*/
|
|
61
|
-
serialize (): Uint8Array {
|
|
62
|
-
return PBMessage.encode({
|
|
63
|
-
key: this.key,
|
|
64
|
-
type: this.type,
|
|
65
|
-
clusterLevelRaw: this.clusterLevelRaw,
|
|
66
|
-
closerPeers: this.closerPeers.map(toPbPeer),
|
|
67
|
-
providerPeers: this.providerPeers.map(toPbPeer),
|
|
68
|
-
record: this.record == null ? undefined : this.record.serialize().subarray()
|
|
69
|
-
})
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Decode from protobuf
|
|
74
|
-
*/
|
|
75
|
-
static deserialize (raw: Uint8ArrayList | Uint8Array): Message {
|
|
76
|
-
const dec = PBMessage.decode(raw)
|
|
77
|
-
|
|
78
|
-
const msg = new Message(dec.type ?? PBMessage.MessageType.PUT_VALUE, dec.key ?? Uint8Array.from([]), dec.clusterLevelRaw ?? 0)
|
|
79
|
-
msg.closerPeers = dec.closerPeers.map(fromPbPeer)
|
|
80
|
-
msg.providerPeers = dec.providerPeers.map(fromPbPeer)
|
|
81
|
-
|
|
82
|
-
if (dec.record?.length != null) {
|
|
83
|
-
msg.record = Libp2pRecord.deserialize(dec.record)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return msg
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
static encode (message: Message): Uint8Array {
|
|
90
|
-
return message.serialize()
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
static decode (buf: Uint8Array | Uint8ArrayList): Message {
|
|
94
|
-
return Message.deserialize(buf)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function toPbPeer (peer: PeerInfo): PBPeer {
|
|
99
|
-
const output: PBPeer = {
|
|
100
|
-
id: peer.id.toBytes(),
|
|
101
|
-
addrs: (peer.multiaddrs ?? []).map((m) => m.bytes),
|
|
102
|
-
connection: CONNECTION_TYPE.CONNECTED
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return output
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function fromPbPeer (peer: PBMessage.Peer): PeerInfo {
|
|
109
|
-
if (peer.id == null) {
|
|
110
|
-
throw new Error('Invalid peer in message')
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
id: peerIdFromBytes(peer.id),
|
|
115
|
-
multiaddrs: (peer.addrs ?? []).map((a) => multiaddr(a))
|
|
116
|
-
}
|
|
117
|
-
}
|