@libp2p/kad-dht 9.1.5 → 9.3.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/dist/index.min.js +18 -18
- package/dist/src/content-fetching/index.js +4 -4
- package/dist/src/content-fetching/index.js.map +1 -1
- package/dist/src/content-routing/index.d.ts +1 -2
- package/dist/src/content-routing/index.d.ts.map +1 -1
- package/dist/src/content-routing/index.js +8 -5
- package/dist/src/content-routing/index.js.map +1 -1
- package/dist/src/dual-kad-dht.d.ts +1 -2
- package/dist/src/dual-kad-dht.d.ts.map +1 -1
- package/dist/src/dual-kad-dht.js +58 -7
- package/dist/src/dual-kad-dht.js.map +1 -1
- package/dist/src/index.d.ts +19 -14
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/network.d.ts +3 -3
- package/dist/src/network.d.ts.map +1 -1
- package/dist/src/network.js +9 -9
- package/dist/src/network.js.map +1 -1
- package/dist/src/peer-routing/index.d.ts +3 -3
- package/dist/src/peer-routing/index.d.ts.map +1 -1
- package/dist/src/peer-routing/index.js +14 -8
- package/dist/src/peer-routing/index.js.map +1 -1
- package/dist/src/query/events.d.ts +10 -10
- package/dist/src/query/events.d.ts.map +1 -1
- package/dist/src/query/events.js +36 -19
- package/dist/src/query/events.js.map +1 -1
- package/dist/src/query/manager.d.ts +2 -3
- package/dist/src/query/manager.d.ts.map +1 -1
- package/dist/src/query/manager.js +2 -1
- package/dist/src/query/manager.js.map +1 -1
- package/dist/src/query/query-path.d.ts +2 -2
- package/dist/src/query/query-path.d.ts.map +1 -1
- package/dist/src/query/query-path.js +1 -1
- package/dist/src/query/query-path.js.map +1 -1
- package/dist/typedoc-urls.json +4 -3
- package/package.json +2 -1
- package/src/content-fetching/index.ts +4 -4
- package/src/content-routing/index.ts +9 -7
- package/src/dual-kad-dht.ts +77 -14
- package/src/index.ts +28 -14
- package/src/network.ts +13 -13
- package/src/peer-routing/index.ts +17 -11
- package/src/query/events.ts +54 -21
- package/src/query/manager.ts +4 -4
- package/src/query/query-path.ts +3 -3
package/src/dual-kad-dht.ts
CHANGED
|
@@ -6,12 +6,13 @@ import { EventEmitter, CustomEvent } from '@libp2p/interfaces/events'
|
|
|
6
6
|
import { logger } from '@libp2p/logger'
|
|
7
7
|
import drain from 'it-drain'
|
|
8
8
|
import merge from 'it-merge'
|
|
9
|
+
import isPrivate from 'private-ip'
|
|
9
10
|
import { DefaultKadDHT } from './kad-dht.js'
|
|
10
11
|
import { queryErrorEvent } from './query/events.js'
|
|
11
12
|
import type { DualKadDHT, KadDHT, KadDHTComponents, KadDHTInit, QueryEvent, QueryOptions } from './index.js'
|
|
12
13
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
13
14
|
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
14
|
-
import type {
|
|
15
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
15
16
|
import type { CID } from 'multiformats/cid'
|
|
16
17
|
|
|
17
18
|
const log = logger('libp2p:kad-dht')
|
|
@@ -26,11 +27,11 @@ class DHTContentRouting implements ContentRouting {
|
|
|
26
27
|
this.dht = dht
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
async provide (cid: CID): Promise<void> {
|
|
30
|
-
await drain(this.dht.provide(cid))
|
|
30
|
+
async provide (cid: CID, options: QueryOptions = {}): Promise<void> {
|
|
31
|
+
await drain(this.dht.provide(cid, options))
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
async * findProviders (cid: CID, options:
|
|
34
|
+
async * findProviders (cid: CID, options: QueryOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
|
|
34
35
|
for await (const event of this.dht.findProviders(cid, options)) {
|
|
35
36
|
if (event.name === 'PROVIDER') {
|
|
36
37
|
yield * event.providers
|
|
@@ -38,11 +39,11 @@ class DHTContentRouting implements ContentRouting {
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
async put (key: Uint8Array, value: Uint8Array, options?:
|
|
42
|
+
async put (key: Uint8Array, value: Uint8Array, options?: QueryOptions): Promise<void> {
|
|
42
43
|
await drain(this.dht.put(key, value, options))
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
async get (key: Uint8Array, options?:
|
|
46
|
+
async get (key: Uint8Array, options?: QueryOptions): Promise<Uint8Array> {
|
|
46
47
|
for await (const event of this.dht.get(key, options)) {
|
|
47
48
|
if (event.name === 'VALUE') {
|
|
48
49
|
return event.value
|
|
@@ -63,7 +64,7 @@ class DHTPeerRouting implements PeerRouting {
|
|
|
63
64
|
this.dht = dht
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
async findPeer (peerId: PeerId, options:
|
|
67
|
+
async findPeer (peerId: PeerId, options: QueryOptions = {}): Promise<PeerInfo> {
|
|
67
68
|
for await (const event of this.dht.findPeer(peerId, options)) {
|
|
68
69
|
if (event.name === 'FINAL_PEER') {
|
|
69
70
|
return event.peer
|
|
@@ -73,7 +74,7 @@ class DHTPeerRouting implements PeerRouting {
|
|
|
73
74
|
throw new CodeError('Not found', 'ERR_NOT_FOUND')
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
async * getClosestPeers (key: Uint8Array, options:
|
|
77
|
+
async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncIterable<PeerInfo> {
|
|
77
78
|
for await (const event of this.dht.getClosestPeers(key, options)) {
|
|
78
79
|
if (event.name === 'FINAL_PEER') {
|
|
79
80
|
yield event.peer
|
|
@@ -82,6 +83,44 @@ class DHTPeerRouting implements PeerRouting {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
// see https://github.com/multiformats/multiaddr/blob/master/protocols.csv
|
|
87
|
+
const P2P_CIRCUIT_CODE = 290
|
|
88
|
+
const DNS4_CODE = 54
|
|
89
|
+
const DNS6_CODE = 55
|
|
90
|
+
const DNSADDR_CODE = 56
|
|
91
|
+
const IP4_CODE = 4
|
|
92
|
+
const IP6_CODE = 41
|
|
93
|
+
|
|
94
|
+
function multiaddrIsPublic (multiaddr: Multiaddr): boolean {
|
|
95
|
+
const tuples = multiaddr.stringTuples()
|
|
96
|
+
|
|
97
|
+
// p2p-circuit should not enable server mode
|
|
98
|
+
for (const tuple of tuples) {
|
|
99
|
+
if (tuple[0] === P2P_CIRCUIT_CODE) {
|
|
100
|
+
return false
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// dns4 or dns6 or dnsaddr
|
|
105
|
+
if (tuples[0][0] === DNS4_CODE || tuples[0][0] === DNS6_CODE || tuples[0][0] === DNSADDR_CODE) {
|
|
106
|
+
log('%m is public %s', multiaddr, true)
|
|
107
|
+
|
|
108
|
+
return true
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ip4 or ip6
|
|
112
|
+
if (tuples[0][0] === IP4_CODE || tuples[0][0] === IP6_CODE) {
|
|
113
|
+
const result = isPrivate(`${tuples[0][1]}`)
|
|
114
|
+
const isPublic = result == null || !result
|
|
115
|
+
|
|
116
|
+
log('%m is public %s', multiaddr, isPublic)
|
|
117
|
+
|
|
118
|
+
return isPublic
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return false
|
|
122
|
+
}
|
|
123
|
+
|
|
85
124
|
/**
|
|
86
125
|
* A DHT implementation modelled after Kademlia with S/Kademlia modifications.
|
|
87
126
|
* Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
|
|
@@ -124,6 +163,30 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
|
|
|
124
163
|
detail: evt.detail
|
|
125
164
|
}))
|
|
126
165
|
})
|
|
166
|
+
|
|
167
|
+
components.events.addEventListener('self:peer:update', (evt) => {
|
|
168
|
+
log('received update of self-peer info')
|
|
169
|
+
const hasPublicAddress = evt.detail.peer.addresses
|
|
170
|
+
.some(({ multiaddr }) => {
|
|
171
|
+
const isPublic = multiaddrIsPublic(multiaddr)
|
|
172
|
+
|
|
173
|
+
log('%m is public %s', multiaddr, isPublic)
|
|
174
|
+
|
|
175
|
+
return isPublic
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
this.getMode()
|
|
179
|
+
.then(async mode => {
|
|
180
|
+
if (hasPublicAddress && mode === 'client') {
|
|
181
|
+
await this.setMode('server')
|
|
182
|
+
} else if (mode === 'server' && !hasPublicAddress) {
|
|
183
|
+
await this.setMode('client')
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
.catch(err => {
|
|
187
|
+
log.error('error setting dht server mode', err)
|
|
188
|
+
})
|
|
189
|
+
})
|
|
127
190
|
}
|
|
128
191
|
|
|
129
192
|
readonly [Symbol.toStringTag] = '@libp2p/dual-kad-dht'
|
|
@@ -207,7 +270,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
|
|
|
207
270
|
)) {
|
|
208
271
|
yield event
|
|
209
272
|
|
|
210
|
-
if (event.name === '
|
|
273
|
+
if (event.name === 'DIAL_PEER') {
|
|
211
274
|
queriedPeers = true
|
|
212
275
|
}
|
|
213
276
|
|
|
@@ -219,7 +282,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
|
|
|
219
282
|
}
|
|
220
283
|
}
|
|
221
284
|
|
|
222
|
-
if (event.name === '
|
|
285
|
+
if (event.name === 'SEND_QUERY') {
|
|
223
286
|
queriedPeers = true
|
|
224
287
|
}
|
|
225
288
|
}
|
|
@@ -232,7 +295,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
|
|
|
232
295
|
yield queryErrorEvent({
|
|
233
296
|
from: this.components.peerId,
|
|
234
297
|
error: new CodeError('Not found', 'ERR_NOT_FOUND')
|
|
235
|
-
})
|
|
298
|
+
}, options)
|
|
236
299
|
}
|
|
237
300
|
}
|
|
238
301
|
|
|
@@ -241,7 +304,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
|
|
|
241
304
|
/**
|
|
242
305
|
* Announce to the network that we can provide given key's value
|
|
243
306
|
*/
|
|
244
|
-
async * provide (key: CID, options:
|
|
307
|
+
async * provide (key: CID, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
|
|
245
308
|
let sent = 0
|
|
246
309
|
let success = 0
|
|
247
310
|
const errors = []
|
|
@@ -256,7 +319,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
|
|
|
256
319
|
for await (const event of merge(...dhts.map(dht => dht.provide(key, options)))) {
|
|
257
320
|
yield event
|
|
258
321
|
|
|
259
|
-
if (event.name === '
|
|
322
|
+
if (event.name === 'SEND_QUERY') {
|
|
260
323
|
sent++
|
|
261
324
|
}
|
|
262
325
|
|
|
@@ -304,7 +367,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
|
|
|
304
367
|
)) {
|
|
305
368
|
yield event
|
|
306
369
|
|
|
307
|
-
if (event.name === '
|
|
370
|
+
if (event.name === 'SEND_QUERY' || event.name === 'FINAL_PEER') {
|
|
308
371
|
queriedPeers = true
|
|
309
372
|
}
|
|
310
373
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,27 +2,30 @@ import { DefaultDualKadDHT } from './dual-kad-dht.js'
|
|
|
2
2
|
import type { ProvidersInit } from './providers.js'
|
|
3
3
|
import type { AddressManager } from '@libp2p/interface-address-manager'
|
|
4
4
|
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
|
|
5
|
+
import type { Libp2pEvents } from '@libp2p/interface-libp2p'
|
|
5
6
|
import type { Metrics } from '@libp2p/interface-metrics'
|
|
6
7
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
7
8
|
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
8
9
|
import type { PeerStore } from '@libp2p/interface-peer-store'
|
|
9
10
|
import type { Registrar } from '@libp2p/interface-registrar'
|
|
10
11
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
12
|
+
import type { EventEmitter } from '@libp2p/interfaces/events'
|
|
11
13
|
import type { Datastore } from 'interface-datastore'
|
|
12
14
|
import type { CID } from 'multiformats/cid'
|
|
15
|
+
import type { ProgressOptions, ProgressEvent } from 'progress-events'
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* The types of events emitted during DHT queries
|
|
16
19
|
*/
|
|
17
20
|
export enum EventTypes {
|
|
18
|
-
|
|
21
|
+
SEND_QUERY = 0,
|
|
19
22
|
PEER_RESPONSE,
|
|
20
23
|
FINAL_PEER,
|
|
21
24
|
QUERY_ERROR,
|
|
22
25
|
PROVIDER,
|
|
23
26
|
VALUE,
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
ADD_PEER,
|
|
28
|
+
DIAL_PEER
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
/**
|
|
@@ -45,17 +48,27 @@ export interface DHTRecord {
|
|
|
45
48
|
timeReceived?: Date
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
export
|
|
51
|
+
export type DHTProgressEvents =
|
|
52
|
+
ProgressEvent<'kad-dht:query:send-query', SendQueryEvent> |
|
|
53
|
+
ProgressEvent<'kad-dht:query:peer-response', PeerResponseEvent> |
|
|
54
|
+
ProgressEvent<'kad-dht:query:final-peer', FinalPeerEvent> |
|
|
55
|
+
ProgressEvent<'kad-dht:query:query-error', QueryErrorEvent> |
|
|
56
|
+
ProgressEvent<'kad-dht:query:provider', ProviderEvent> |
|
|
57
|
+
ProgressEvent<'kad-dht:query:value', ValueEvent> |
|
|
58
|
+
ProgressEvent<'kad-dht:query:add-peer', AddPeerEvent> |
|
|
59
|
+
ProgressEvent<'kad-dht:query:dial-peer', DialPeerEvent>
|
|
60
|
+
|
|
61
|
+
export interface QueryOptions extends AbortOptions, ProgressOptions {
|
|
49
62
|
queryFuncTimeout?: number
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
/**
|
|
53
66
|
* Emitted when sending queries to remote peers
|
|
54
67
|
*/
|
|
55
|
-
export interface
|
|
68
|
+
export interface SendQueryEvent {
|
|
56
69
|
to: PeerId
|
|
57
|
-
type: EventTypes.
|
|
58
|
-
name: '
|
|
70
|
+
type: EventTypes.SEND_QUERY
|
|
71
|
+
name: 'SEND_QUERY'
|
|
59
72
|
messageName: keyof typeof MessageType
|
|
60
73
|
messageType: MessageType
|
|
61
74
|
}
|
|
@@ -118,22 +131,22 @@ export interface ValueEvent {
|
|
|
118
131
|
/**
|
|
119
132
|
* Emitted when peers are added to a query
|
|
120
133
|
*/
|
|
121
|
-
export interface
|
|
122
|
-
type: EventTypes.
|
|
123
|
-
name: '
|
|
134
|
+
export interface AddPeerEvent {
|
|
135
|
+
type: EventTypes.ADD_PEER
|
|
136
|
+
name: 'ADD_PEER'
|
|
124
137
|
peer: PeerId
|
|
125
138
|
}
|
|
126
139
|
|
|
127
140
|
/**
|
|
128
141
|
* Emitted when peers are dialled as part of a query
|
|
129
142
|
*/
|
|
130
|
-
export interface
|
|
143
|
+
export interface DialPeerEvent {
|
|
131
144
|
peer: PeerId
|
|
132
|
-
type: EventTypes.
|
|
133
|
-
name: '
|
|
145
|
+
type: EventTypes.DIAL_PEER
|
|
146
|
+
name: 'DIAL_PEER'
|
|
134
147
|
}
|
|
135
148
|
|
|
136
|
-
export type QueryEvent =
|
|
149
|
+
export type QueryEvent = SendQueryEvent | PeerResponseEvent | FinalPeerEvent | QueryErrorEvent | ProviderEvent | ValueEvent | AddPeerEvent | DialPeerEvent
|
|
137
150
|
|
|
138
151
|
export interface RoutingTable {
|
|
139
152
|
size: number
|
|
@@ -300,6 +313,7 @@ export interface KadDHTComponents {
|
|
|
300
313
|
metrics?: Metrics
|
|
301
314
|
connectionManager: ConnectionManager
|
|
302
315
|
datastore: Datastore
|
|
316
|
+
events: EventEmitter<Libp2pEvents>
|
|
303
317
|
}
|
|
304
318
|
|
|
305
319
|
export function kadDHT (init?: KadDHTInit): (components: KadDHTComponents) => DualKadDHT {
|
package/src/network.ts
CHANGED
|
@@ -8,12 +8,12 @@ import * as lp from 'it-length-prefixed'
|
|
|
8
8
|
import { pipe } from 'it-pipe'
|
|
9
9
|
import { Message } from './message/index.js'
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
dialPeerEvent,
|
|
12
|
+
sendQueryEvent,
|
|
13
13
|
peerResponseEvent,
|
|
14
14
|
queryErrorEvent
|
|
15
15
|
} from './query/events.js'
|
|
16
|
-
import type { KadDHTComponents, QueryEvent } from './index.js'
|
|
16
|
+
import type { KadDHTComponents, QueryEvent, QueryOptions } from './index.js'
|
|
17
17
|
import type { Stream } from '@libp2p/interface-connection'
|
|
18
18
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
19
19
|
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
@@ -82,14 +82,14 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
|
|
|
82
82
|
/**
|
|
83
83
|
* Send a request and record RTT for latency measurements
|
|
84
84
|
*/
|
|
85
|
-
async * sendRequest (to: PeerId, msg: Message, options:
|
|
85
|
+
async * sendRequest (to: PeerId, msg: Message, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
|
|
86
86
|
if (!this.running) {
|
|
87
87
|
return
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
this.log('sending %s to %p', msg.type, to)
|
|
91
|
-
yield
|
|
92
|
-
yield
|
|
91
|
+
yield dialPeerEvent({ peer: to }, options)
|
|
92
|
+
yield sendQueryEvent({ to, type: msg.type }, options)
|
|
93
93
|
|
|
94
94
|
let stream: Stream | undefined
|
|
95
95
|
|
|
@@ -105,9 +105,9 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
|
|
|
105
105
|
closer: response.closerPeers,
|
|
106
106
|
providers: response.providerPeers,
|
|
107
107
|
record: response.record
|
|
108
|
-
})
|
|
108
|
+
}, options)
|
|
109
109
|
} catch (err: any) {
|
|
110
|
-
yield queryErrorEvent({ from: to, error: err })
|
|
110
|
+
yield queryErrorEvent({ from: to, error: err }, options)
|
|
111
111
|
} finally {
|
|
112
112
|
if (stream != null) {
|
|
113
113
|
stream.close()
|
|
@@ -118,14 +118,14 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
|
|
|
118
118
|
/**
|
|
119
119
|
* Sends a message without expecting an answer
|
|
120
120
|
*/
|
|
121
|
-
async * sendMessage (to: PeerId, msg: Message, options:
|
|
121
|
+
async * sendMessage (to: PeerId, msg: Message, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
|
|
122
122
|
if (!this.running) {
|
|
123
123
|
return
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
this.log('sending %s to %p', msg.type, to)
|
|
127
|
-
yield
|
|
128
|
-
yield
|
|
127
|
+
yield dialPeerEvent({ peer: to }, options)
|
|
128
|
+
yield sendQueryEvent({ to, type: msg.type }, options)
|
|
129
129
|
|
|
130
130
|
let stream: Stream | undefined
|
|
131
131
|
|
|
@@ -135,9 +135,9 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
|
|
|
135
135
|
|
|
136
136
|
await this._writeMessage(stream, msg.serialize(), options)
|
|
137
137
|
|
|
138
|
-
yield peerResponseEvent({ from: to, messageType: msg.type })
|
|
138
|
+
yield peerResponseEvent({ from: to, messageType: msg.type }, options)
|
|
139
139
|
} catch (err: any) {
|
|
140
|
-
yield queryErrorEvent({ from: to, error: err })
|
|
140
|
+
yield queryErrorEvent({ from: to, error: err }, options)
|
|
141
141
|
} finally {
|
|
142
142
|
if (stream != null) {
|
|
143
143
|
stream.close()
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
valueEvent
|
|
14
14
|
} from '../query/events.js'
|
|
15
15
|
import * as utils from '../utils.js'
|
|
16
|
-
import type { KadDHTComponents, DHTRecord,
|
|
16
|
+
import type { KadDHTComponents, DHTRecord, DialPeerEvent, FinalPeerEvent, QueryEvent, Validators } from '../index.js'
|
|
17
17
|
import type { Network } from '../network.js'
|
|
18
18
|
import type { QueryManager, QueryOptions } from '../query/manager.js'
|
|
19
19
|
import type { QueryFunc } from '../query/types.js'
|
|
@@ -122,7 +122,7 @@ export class PeerRouting {
|
|
|
122
122
|
throw new CodeError('public key missing', 'ERR_PUBLIC_KEY_MISSING')
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
yield valueEvent({ from: peer, value: recPeer.publicKey })
|
|
125
|
+
yield valueEvent({ from: peer, value: recPeer.publicKey }, options)
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -144,7 +144,7 @@ export class PeerRouting {
|
|
|
144
144
|
yield finalPeerEvent({
|
|
145
145
|
from: this.components.peerId,
|
|
146
146
|
peer: pi
|
|
147
|
-
})
|
|
147
|
+
}, options)
|
|
148
148
|
return
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -153,7 +153,10 @@ export class PeerRouting {
|
|
|
153
153
|
const findPeerQuery: QueryFunc = async function * ({ peer, signal }) {
|
|
154
154
|
const request = new Message(MESSAGE_TYPE.FIND_NODE, id.toBytes(), 0)
|
|
155
155
|
|
|
156
|
-
for await (const event of self.network.sendRequest(peer, request, {
|
|
156
|
+
for await (const event of self.network.sendRequest(peer, request, {
|
|
157
|
+
...options,
|
|
158
|
+
signal
|
|
159
|
+
})) {
|
|
157
160
|
yield event
|
|
158
161
|
|
|
159
162
|
if (event.name === 'PEER_RESPONSE') {
|
|
@@ -161,7 +164,7 @@ export class PeerRouting {
|
|
|
161
164
|
|
|
162
165
|
// found the peer
|
|
163
166
|
if (match != null) {
|
|
164
|
-
yield finalPeerEvent({ from: event.from, peer: match })
|
|
167
|
+
yield finalPeerEvent({ from: event.from, peer: match }, options)
|
|
165
168
|
}
|
|
166
169
|
}
|
|
167
170
|
}
|
|
@@ -178,7 +181,7 @@ export class PeerRouting {
|
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
if (!foundPeer) {
|
|
181
|
-
yield queryErrorEvent({ from: this.components.peerId, error: new CodeError('Not found', 'ERR_NOT_FOUND') })
|
|
184
|
+
yield queryErrorEvent({ from: this.components.peerId, error: new CodeError('Not found', 'ERR_NOT_FOUND') }, options)
|
|
182
185
|
}
|
|
183
186
|
}
|
|
184
187
|
|
|
@@ -186,7 +189,7 @@ export class PeerRouting {
|
|
|
186
189
|
* Kademlia 'node lookup' operation on a key, which could be a the
|
|
187
190
|
* bytes from a multihash or a peer ID
|
|
188
191
|
*/
|
|
189
|
-
async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncGenerator<
|
|
192
|
+
async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncGenerator<DialPeerEvent | QueryEvent> {
|
|
190
193
|
this.log('getClosestPeers to %b', key)
|
|
191
194
|
const id = await utils.convertBuffer(key)
|
|
192
195
|
const tablePeers = this.routingTable.closestPeers(id)
|
|
@@ -199,7 +202,10 @@ export class PeerRouting {
|
|
|
199
202
|
self.log('closerPeersSingle %s from %p', uint8ArrayToString(key, 'base32'), peer)
|
|
200
203
|
const request = new Message(MESSAGE_TYPE.FIND_NODE, key, 0)
|
|
201
204
|
|
|
202
|
-
yield * self.network.sendRequest(peer, request, {
|
|
205
|
+
yield * self.network.sendRequest(peer, request, {
|
|
206
|
+
...options,
|
|
207
|
+
signal
|
|
208
|
+
})
|
|
203
209
|
}
|
|
204
210
|
|
|
205
211
|
for await (const event of this.queryManager.run(key, getCloserPeersQuery, options)) {
|
|
@@ -223,7 +229,7 @@ export class PeerRouting {
|
|
|
223
229
|
multiaddrs: peer.addresses.map(({ multiaddr }) => multiaddr),
|
|
224
230
|
protocols: peer.protocols
|
|
225
231
|
}
|
|
226
|
-
})
|
|
232
|
+
}, options)
|
|
227
233
|
} catch (err: any) {
|
|
228
234
|
if (err.code !== 'ERR_NOT_FOUND') {
|
|
229
235
|
throw err
|
|
@@ -238,7 +244,7 @@ export class PeerRouting {
|
|
|
238
244
|
*
|
|
239
245
|
* Note: The peerStore is updated with new addresses found for the given peer.
|
|
240
246
|
*/
|
|
241
|
-
async * getValueOrPeers (peer: PeerId, key: Uint8Array, options: AbortOptions = {}): AsyncGenerator<
|
|
247
|
+
async * getValueOrPeers (peer: PeerId, key: Uint8Array, options: AbortOptions = {}): AsyncGenerator<DialPeerEvent | QueryEvent> {
|
|
242
248
|
for await (const event of this._getValueSingle(peer, key, options)) {
|
|
243
249
|
if (event.name === 'PEER_RESPONSE') {
|
|
244
250
|
if (event.record != null) {
|
|
@@ -249,7 +255,7 @@ export class PeerRouting {
|
|
|
249
255
|
const errMsg = 'invalid record received, discarded'
|
|
250
256
|
this.log(errMsg)
|
|
251
257
|
|
|
252
|
-
yield queryErrorEvent({ from: event.from, error: new CodeError(errMsg, 'ERR_INVALID_RECORD') })
|
|
258
|
+
yield queryErrorEvent({ from: event.from, error: new CodeError(errMsg, 'ERR_INVALID_RECORD') }, options)
|
|
253
259
|
continue
|
|
254
260
|
}
|
|
255
261
|
}
|
package/src/query/events.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { CustomEvent } from '@libp2p/interfaces/events'
|
|
1
2
|
import { MESSAGE_TYPE_LOOKUP } from '../message/index.js'
|
|
2
|
-
import type {
|
|
3
|
+
import type { SendQueryEvent, PeerResponseEvent, DialPeerEvent, AddPeerEvent, ValueEvent, ProviderEvent, QueryErrorEvent, FinalPeerEvent, QueryOptions } from '../index.js'
|
|
3
4
|
import type { Message } from '../message/dht.js'
|
|
4
5
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
5
6
|
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
@@ -10,14 +11,18 @@ export interface QueryEventFields {
|
|
|
10
11
|
type: Message.MessageType
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
export function
|
|
14
|
-
|
|
14
|
+
export function sendQueryEvent (fields: QueryEventFields, options: QueryOptions = {}): SendQueryEvent {
|
|
15
|
+
const event: SendQueryEvent = {
|
|
15
16
|
...fields,
|
|
16
|
-
name: '
|
|
17
|
+
name: 'SEND_QUERY',
|
|
17
18
|
type: 0,
|
|
18
19
|
messageName: fields.type,
|
|
19
20
|
messageType: MESSAGE_TYPE_LOOKUP.indexOf(fields.type.toString())
|
|
20
21
|
}
|
|
22
|
+
|
|
23
|
+
options.onProgress?.(new CustomEvent('kad-dht:query:send-query', { detail: event }))
|
|
24
|
+
|
|
25
|
+
return event
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
export interface PeerResponseEventField {
|
|
@@ -28,8 +33,8 @@ export interface PeerResponseEventField {
|
|
|
28
33
|
record?: Libp2pRecord
|
|
29
34
|
}
|
|
30
35
|
|
|
31
|
-
export function peerResponseEvent (fields: PeerResponseEventField): PeerResponseEvent {
|
|
32
|
-
|
|
36
|
+
export function peerResponseEvent (fields: PeerResponseEventField, options: QueryOptions = {}): PeerResponseEvent {
|
|
37
|
+
const event: PeerResponseEvent = {
|
|
33
38
|
...fields,
|
|
34
39
|
name: 'PEER_RESPONSE',
|
|
35
40
|
type: 1,
|
|
@@ -37,6 +42,10 @@ export function peerResponseEvent (fields: PeerResponseEventField): PeerResponse
|
|
|
37
42
|
closer: (fields.closer != null) ? fields.closer : [],
|
|
38
43
|
providers: (fields.providers != null) ? fields.providers : []
|
|
39
44
|
}
|
|
45
|
+
|
|
46
|
+
options.onProgress?.(new CustomEvent('kad-dht:query:peer-response', { detail: event }))
|
|
47
|
+
|
|
48
|
+
return event
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
export interface FinalPeerEventFields {
|
|
@@ -44,12 +53,16 @@ export interface FinalPeerEventFields {
|
|
|
44
53
|
peer: PeerInfo
|
|
45
54
|
}
|
|
46
55
|
|
|
47
|
-
export function finalPeerEvent (fields: FinalPeerEventFields): FinalPeerEvent {
|
|
48
|
-
|
|
56
|
+
export function finalPeerEvent (fields: FinalPeerEventFields, options: QueryOptions = {}): FinalPeerEvent {
|
|
57
|
+
const event: FinalPeerEvent = {
|
|
49
58
|
...fields,
|
|
50
59
|
name: 'FINAL_PEER',
|
|
51
60
|
type: 2
|
|
52
61
|
}
|
|
62
|
+
|
|
63
|
+
options.onProgress?.(new CustomEvent('kad-dht:query:final-peer', { detail: event }))
|
|
64
|
+
|
|
65
|
+
return event
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
export interface ErrorEventFields {
|
|
@@ -57,12 +70,16 @@ export interface ErrorEventFields {
|
|
|
57
70
|
error: Error
|
|
58
71
|
}
|
|
59
72
|
|
|
60
|
-
export function queryErrorEvent (fields: ErrorEventFields): QueryErrorEvent {
|
|
61
|
-
|
|
73
|
+
export function queryErrorEvent (fields: ErrorEventFields, options: QueryOptions = {}): QueryErrorEvent {
|
|
74
|
+
const event: QueryErrorEvent = {
|
|
62
75
|
...fields,
|
|
63
76
|
name: 'QUERY_ERROR',
|
|
64
77
|
type: 3
|
|
65
78
|
}
|
|
79
|
+
|
|
80
|
+
options.onProgress?.(new CustomEvent('kad-dht:query:query-error', { detail: event }))
|
|
81
|
+
|
|
82
|
+
return event
|
|
66
83
|
}
|
|
67
84
|
|
|
68
85
|
export interface ProviderEventFields {
|
|
@@ -70,12 +87,16 @@ export interface ProviderEventFields {
|
|
|
70
87
|
providers: PeerInfo[]
|
|
71
88
|
}
|
|
72
89
|
|
|
73
|
-
export function providerEvent (fields: ProviderEventFields): ProviderEvent {
|
|
74
|
-
|
|
90
|
+
export function providerEvent (fields: ProviderEventFields, options: QueryOptions = {}): ProviderEvent {
|
|
91
|
+
const event: ProviderEvent = {
|
|
75
92
|
...fields,
|
|
76
93
|
name: 'PROVIDER',
|
|
77
94
|
type: 4
|
|
78
95
|
}
|
|
96
|
+
|
|
97
|
+
options.onProgress?.(new CustomEvent('kad-dht:query:provider', { detail: event }))
|
|
98
|
+
|
|
99
|
+
return event
|
|
79
100
|
}
|
|
80
101
|
|
|
81
102
|
export interface ValueEventFields {
|
|
@@ -83,34 +104,46 @@ export interface ValueEventFields {
|
|
|
83
104
|
value: Uint8Array
|
|
84
105
|
}
|
|
85
106
|
|
|
86
|
-
export function valueEvent (fields: ValueEventFields): ValueEvent {
|
|
87
|
-
|
|
107
|
+
export function valueEvent (fields: ValueEventFields, options: QueryOptions = {}): ValueEvent {
|
|
108
|
+
const event: ValueEvent = {
|
|
88
109
|
...fields,
|
|
89
110
|
name: 'VALUE',
|
|
90
111
|
type: 5
|
|
91
112
|
}
|
|
113
|
+
|
|
114
|
+
options.onProgress?.(new CustomEvent('kad-dht:query:value', { detail: event }))
|
|
115
|
+
|
|
116
|
+
return event
|
|
92
117
|
}
|
|
93
118
|
|
|
94
119
|
export interface PeerEventFields {
|
|
95
120
|
peer: PeerId
|
|
96
121
|
}
|
|
97
122
|
|
|
98
|
-
export function
|
|
99
|
-
|
|
123
|
+
export function addPeerEvent (fields: PeerEventFields, options: QueryOptions = {}): AddPeerEvent {
|
|
124
|
+
const event: AddPeerEvent = {
|
|
100
125
|
...fields,
|
|
101
|
-
name: '
|
|
126
|
+
name: 'ADD_PEER',
|
|
102
127
|
type: 6
|
|
103
128
|
}
|
|
129
|
+
|
|
130
|
+
options.onProgress?.(new CustomEvent('kad-dht:query:add-peer', { detail: event }))
|
|
131
|
+
|
|
132
|
+
return event
|
|
104
133
|
}
|
|
105
134
|
|
|
106
|
-
export interface
|
|
135
|
+
export interface DialPeerEventFields {
|
|
107
136
|
peer: PeerId
|
|
108
137
|
}
|
|
109
138
|
|
|
110
|
-
export function
|
|
111
|
-
|
|
139
|
+
export function dialPeerEvent (fields: DialPeerEventFields, options: QueryOptions = {}): DialPeerEvent {
|
|
140
|
+
const event: DialPeerEvent = {
|
|
112
141
|
...fields,
|
|
113
|
-
name: '
|
|
142
|
+
name: 'DIAL_PEER',
|
|
114
143
|
type: 7
|
|
115
144
|
}
|
|
145
|
+
|
|
146
|
+
options.onProgress?.(new CustomEvent('kad-dht:query:dial-peer', { detail: event }))
|
|
147
|
+
|
|
148
|
+
return event
|
|
116
149
|
}
|
package/src/query/manager.ts
CHANGED
|
@@ -12,11 +12,10 @@ import {
|
|
|
12
12
|
import { convertBuffer } from '../utils.js'
|
|
13
13
|
import { queryPath } from './query-path.js'
|
|
14
14
|
import type { QueryFunc } from './types.js'
|
|
15
|
-
import type { QueryEvent } from '../index.js'
|
|
15
|
+
import type { QueryEvent, QueryOptions as RootQueryOptions } from '../index.js'
|
|
16
16
|
import type { RoutingTable } from '../routing-table/index.js'
|
|
17
17
|
import type { Metric, Metrics } from '@libp2p/interface-metrics'
|
|
18
18
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
19
|
-
import type { AbortOptions } from '@libp2p/interfaces'
|
|
20
19
|
import type { Startable } from '@libp2p/interfaces/startable'
|
|
21
20
|
import type { DeferredPromise } from 'p-defer'
|
|
22
21
|
|
|
@@ -37,7 +36,7 @@ export interface QueryManagerComponents {
|
|
|
37
36
|
metrics?: Metrics
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
export interface QueryOptions extends
|
|
39
|
+
export interface QueryOptions extends RootQueryOptions {
|
|
41
40
|
queryFuncTimeout?: number
|
|
42
41
|
isSelfQuery?: boolean
|
|
43
42
|
}
|
|
@@ -192,7 +191,8 @@ export class QueryManager implements Startable {
|
|
|
192
191
|
cleanUp,
|
|
193
192
|
queryFuncTimeout: options.queryFuncTimeout,
|
|
194
193
|
log,
|
|
195
|
-
peersSeen
|
|
194
|
+
peersSeen,
|
|
195
|
+
onProgress: options.onProgress
|
|
196
196
|
})
|
|
197
197
|
})
|
|
198
198
|
|