@libp2p/kad-dht 1.0.0 → 1.0.3
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/src/content-fetching/index.d.ts +6 -9
- package/dist/src/content-fetching/index.d.ts.map +1 -1
- package/dist/src/content-fetching/index.js +14 -11
- package/dist/src/content-fetching/index.js.map +1 -1
- package/dist/src/content-routing/index.d.ts +6 -9
- package/dist/src/content-routing/index.d.ts.map +1 -1
- package/dist/src/content-routing/index.js +15 -13
- package/dist/src/content-routing/index.js.map +1 -1
- package/dist/src/dual-kad-dht.d.ts +6 -6
- package/dist/src/dual-kad-dht.d.ts.map +1 -1
- package/dist/src/dual-kad-dht.js +9 -4
- package/dist/src/dual-kad-dht.js.map +1 -1
- package/dist/src/index.d.ts +14 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +14 -12
- package/dist/src/index.js.map +1 -1
- package/dist/src/kad-dht.d.ts +14 -54
- package/dist/src/kad-dht.d.ts.map +1 -1
- package/dist/src/kad-dht.js +45 -48
- package/dist/src/kad-dht.js.map +1 -1
- package/dist/src/message/index.d.ts +3 -3
- package/dist/src/network.d.ts +9 -9
- package/dist/src/network.d.ts.map +1 -1
- package/dist/src/network.js +10 -6
- package/dist/src/network.js.map +1 -1
- package/dist/src/peer-list/index.d.ts +1 -1
- package/dist/src/peer-list/index.js +1 -1
- package/dist/src/peer-routing/index.d.ts +8 -10
- package/dist/src/peer-routing/index.d.ts.map +1 -1
- package/dist/src/peer-routing/index.js +18 -16
- package/dist/src/peer-routing/index.js.map +1 -1
- package/dist/src/providers.d.ts +6 -6
- package/dist/src/providers.d.ts.map +1 -1
- package/dist/src/providers.js +11 -7
- package/dist/src/providers.js.map +1 -1
- package/dist/src/query/events.d.ts +5 -5
- package/dist/src/query/manager.d.ts +6 -8
- package/dist/src/query/manager.d.ts.map +1 -1
- package/dist/src/query/manager.js +10 -7
- package/dist/src/query/manager.js.map +1 -1
- package/dist/src/query/query-path.d.ts.map +1 -1
- package/dist/src/query/query-path.js +2 -3
- package/dist/src/query/query-path.js.map +1 -1
- package/dist/src/query-self.d.ts +6 -6
- package/dist/src/query-self.d.ts.map +1 -1
- package/dist/src/query-self.js +8 -4
- package/dist/src/query-self.js.map +1 -1
- package/dist/src/routing-table/index.d.ts +10 -14
- package/dist/src/routing-table/index.d.ts.map +1 -1
- package/dist/src/routing-table/index.js +12 -10
- package/dist/src/routing-table/index.js.map +1 -1
- package/dist/src/routing-table/refresh.d.ts +5 -3
- package/dist/src/routing-table/refresh.d.ts.map +1 -1
- package/dist/src/routing-table/refresh.js +4 -2
- package/dist/src/routing-table/refresh.js.map +1 -1
- package/dist/src/rpc/handlers/add-provider.d.ts +5 -3
- package/dist/src/rpc/handlers/add-provider.d.ts.map +1 -1
- package/dist/src/rpc/handlers/add-provider.js +4 -2
- 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 +4 -2
- package/dist/src/rpc/handlers/find-node.js.map +1 -1
- package/dist/src/rpc/handlers/get-providers.d.ts +8 -8
- package/dist/src/rpc/handlers/get-providers.d.ts.map +1 -1
- package/dist/src/rpc/handlers/get-providers.js +8 -4
- package/dist/src/rpc/handlers/get-providers.js.map +1 -1
- package/dist/src/rpc/handlers/get-value.d.ts +6 -9
- package/dist/src/rpc/handlers/get-value.d.ts.map +1 -1
- package/dist/src/rpc/handlers/get-value.js +10 -7
- package/dist/src/rpc/handlers/get-value.js.map +1 -1
- package/dist/src/rpc/handlers/ping.d.ts +3 -1
- package/dist/src/rpc/handlers/ping.d.ts.map +1 -1
- package/dist/src/rpc/handlers/ping.js +2 -0
- package/dist/src/rpc/handlers/ping.js.map +1 -1
- package/dist/src/rpc/handlers/put-value.d.ts +7 -8
- package/dist/src/rpc/handlers/put-value.d.ts.map +1 -1
- package/dist/src/rpc/handlers/put-value.js +10 -7
- package/dist/src/rpc/handlers/put-value.js.map +1 -1
- package/dist/src/rpc/index.d.ts +6 -10
- package/dist/src/rpc/index.d.ts.map +1 -1
- package/dist/src/rpc/index.js +14 -9
- package/dist/src/rpc/index.js.map +1 -1
- package/dist/src/topology-listener.d.ts +6 -6
- package/dist/src/topology-listener.d.ts.map +1 -1
- package/dist/src/topology-listener.js +9 -5
- package/dist/src/topology-listener.js.map +1 -1
- package/dist/src/utils.d.ts +3 -3
- package/package.json +21 -21
- package/src/content-fetching/index.ts +17 -19
- package/src/content-routing/index.ts +20 -23
- package/src/dual-kad-dht.ts +12 -9
- package/src/index.ts +22 -14
- package/src/kad-dht.ts +61 -119
- package/src/message/index.ts +4 -4
- package/src/network.ts +16 -14
- package/src/peer-list/index.ts +1 -1
- package/src/peer-routing/index.ts +23 -25
- package/src/providers.ts +14 -11
- package/src/query/events.ts +5 -5
- package/src/query/manager.ts +13 -14
- package/src/query/query-path.ts +2 -3
- package/src/query-self.ts +11 -9
- package/src/routing-table/index.ts +20 -23
- package/src/routing-table/refresh.ts +9 -4
- package/src/rpc/handlers/add-provider.ts +9 -4
- package/src/rpc/handlers/find-node.ts +9 -4
- package/src/rpc/handlers/get-providers.ts +13 -11
- package/src/rpc/handlers/get-value.ts +13 -15
- package/src/rpc/handlers/ping.ts +6 -1
- package/src/rpc/handlers/put-value.ts +14 -15
- package/src/rpc/index.ts +19 -18
- package/src/topology-listener.ts +12 -10
- package/src/utils.ts +3 -3
package/src/kad-dht.ts
CHANGED
|
@@ -14,92 +14,48 @@ import {
|
|
|
14
14
|
removePublicAddresses
|
|
15
15
|
} from './utils.js'
|
|
16
16
|
import { Logger, logger } from '@libp2p/logger'
|
|
17
|
-
import type {
|
|
18
|
-
import type {
|
|
17
|
+
import type { QueryOptions, Validators, Selectors, DHT } from '@libp2p/interfaces/dht'
|
|
18
|
+
import type { PeerInfo } from '@libp2p/interfaces/peer-info'
|
|
19
19
|
import { CustomEvent, EventEmitter } from '@libp2p/interfaces'
|
|
20
|
-
import type { Addressable, Dialer } from '@libp2p/interfaces'
|
|
21
20
|
import type { PeerId } from '@libp2p/interfaces/peer-id'
|
|
22
|
-
import type { PeerStore } from '@libp2p/interfaces/peer-store'
|
|
23
|
-
import type { ComponentMetricsTracker } from '@libp2p/interfaces/metrics'
|
|
24
|
-
import type { Datastore } from 'interface-datastore'
|
|
25
|
-
import type { Registrar } from '@libp2p/interfaces/registrar'
|
|
26
21
|
import type { CID } from 'multiformats/cid'
|
|
27
22
|
import type { PeerDiscoveryEvents } from '@libp2p/interfaces/peer-discovery'
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
*/
|
|
33
|
-
protocol: string
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* k-bucket size (default 20)
|
|
37
|
-
*/
|
|
38
|
-
kBucketSize?: number
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* If true, the DHT will not respond to queries. This should be true if your node will not be dialable. (default: false)
|
|
42
|
-
*/
|
|
43
|
-
clientMode?: boolean
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* validators object with namespace as keys and function(key, record, callback)
|
|
47
|
-
*/
|
|
48
|
-
validators: Validators
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* selectors object with namespace as keys and function(key, records)
|
|
52
|
-
*/
|
|
53
|
-
selectors: Selectors
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* how often to search the network for peers close to ourselves
|
|
57
|
-
*/
|
|
58
|
-
querySelfInterval: number
|
|
59
|
-
lan: boolean
|
|
60
|
-
bootstrapPeers: PeerData[]
|
|
61
|
-
dialer: Dialer
|
|
62
|
-
addressable: Addressable
|
|
63
|
-
peerStore: PeerStore
|
|
64
|
-
peerId: PeerId
|
|
65
|
-
datastore: Datastore
|
|
66
|
-
registrar: Registrar
|
|
67
|
-
metrics?: ComponentMetricsTracker
|
|
68
|
-
}
|
|
23
|
+
import { Components, Initializable } from '@libp2p/interfaces/components'
|
|
24
|
+
import type { KadDHTInit } from './index.js'
|
|
25
|
+
import { validators as recordValidators } from '@libp2p/record/validators'
|
|
26
|
+
import { selectors as recordSelectors } from '@libp2p/record/selectors'
|
|
69
27
|
|
|
70
28
|
/**
|
|
71
29
|
* A DHT implementation modelled after Kademlia with S/Kademlia modifications.
|
|
72
30
|
* Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
|
|
73
31
|
*/
|
|
74
|
-
export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT {
|
|
32
|
+
export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT, Initializable {
|
|
33
|
+
public protocol: string
|
|
34
|
+
public routingTable: RoutingTable
|
|
35
|
+
public providers: Providers
|
|
36
|
+
public network: Network
|
|
37
|
+
public peerRouting: PeerRouting
|
|
38
|
+
|
|
39
|
+
public components: Components = new Components()
|
|
75
40
|
private readonly log: Logger
|
|
76
41
|
private running: boolean
|
|
77
|
-
public protocol: string
|
|
78
42
|
private readonly kBucketSize: number
|
|
79
43
|
private clientMode: boolean
|
|
80
|
-
private readonly bootstrapPeers: PeerData[]
|
|
81
|
-
public routingTable: RoutingTable
|
|
82
|
-
public providers: Providers
|
|
83
44
|
private readonly lan: boolean
|
|
84
45
|
private readonly validators: Validators
|
|
85
46
|
private readonly selectors: Selectors
|
|
86
|
-
public network: Network
|
|
87
47
|
private readonly queryManager: QueryManager
|
|
88
|
-
public peerRouting: PeerRouting
|
|
89
48
|
private readonly contentFetching: ContentFetching
|
|
90
49
|
private readonly contentRouting: ContentRouting
|
|
91
50
|
private readonly routingTableRefresh: RoutingTableRefresh
|
|
92
51
|
private readonly rpc: RPC
|
|
93
52
|
private readonly topologyListener: TopologyListener
|
|
94
53
|
private readonly querySelf: QuerySelf
|
|
95
|
-
public addressable: Addressable
|
|
96
|
-
public registrar: Registrar
|
|
97
|
-
private registrarHandleId?: string
|
|
98
54
|
|
|
99
55
|
/**
|
|
100
56
|
* Create a new KadDHT
|
|
101
57
|
*/
|
|
102
|
-
constructor (
|
|
58
|
+
constructor (init: KadDHTInit) {
|
|
103
59
|
super()
|
|
104
60
|
|
|
105
61
|
const {
|
|
@@ -109,110 +65,85 @@ export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT {
|
|
|
109
65
|
selectors,
|
|
110
66
|
querySelfInterval,
|
|
111
67
|
lan,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
dialer,
|
|
115
|
-
addressable,
|
|
116
|
-
peerId,
|
|
117
|
-
peerStore,
|
|
118
|
-
metrics,
|
|
119
|
-
datastore,
|
|
120
|
-
registrar
|
|
121
|
-
} = options
|
|
68
|
+
protocolPrefix
|
|
69
|
+
} = init
|
|
122
70
|
|
|
123
71
|
this.running = false
|
|
124
|
-
this.
|
|
125
|
-
this.
|
|
72
|
+
this.lan = Boolean(lan)
|
|
73
|
+
this.log = logger(`libp2p:kad-dht:${lan === true ? 'lan' : 'wan'}`)
|
|
74
|
+
this.protocol = `${protocolPrefix ?? '/ipfs'}${lan === true ? '/lan' : ''}/kad/1.0.0`
|
|
126
75
|
this.kBucketSize = kBucketSize ?? 20
|
|
127
76
|
this.clientMode = clientMode ?? true
|
|
128
|
-
this.bootstrapPeers = bootstrapPeers ?? []
|
|
129
|
-
this.addressable = addressable
|
|
130
|
-
this.registrar = registrar
|
|
131
77
|
this.routingTable = new RoutingTable({
|
|
132
|
-
peerId,
|
|
133
|
-
dialer,
|
|
134
78
|
kBucketSize,
|
|
135
|
-
|
|
136
|
-
lan
|
|
79
|
+
lan: this.lan
|
|
137
80
|
})
|
|
138
81
|
|
|
139
|
-
this.providers = new Providers(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
82
|
+
this.providers = new Providers()
|
|
83
|
+
|
|
84
|
+
this.validators = {
|
|
85
|
+
...recordValidators,
|
|
86
|
+
...validators
|
|
87
|
+
}
|
|
88
|
+
this.selectors = {
|
|
89
|
+
...recordSelectors,
|
|
90
|
+
...selectors
|
|
91
|
+
}
|
|
145
92
|
this.network = new Network({
|
|
146
|
-
dialer,
|
|
147
93
|
protocol: this.protocol,
|
|
148
|
-
lan
|
|
149
|
-
peerId
|
|
94
|
+
lan: this.lan
|
|
150
95
|
})
|
|
151
96
|
this.queryManager = new QueryManager({
|
|
152
|
-
peerId: peerId,
|
|
153
97
|
// Number of disjoint query paths to use - This is set to `kBucketSize/2` per the S/Kademlia paper
|
|
154
98
|
disjointPaths: Math.ceil(this.kBucketSize / 2),
|
|
155
|
-
metrics,
|
|
156
99
|
lan
|
|
157
100
|
})
|
|
158
101
|
|
|
159
102
|
// DHT components
|
|
160
103
|
this.peerRouting = new PeerRouting({
|
|
161
|
-
peerId,
|
|
162
104
|
routingTable: this.routingTable,
|
|
163
|
-
peerStore,
|
|
164
105
|
network: this.network,
|
|
165
106
|
validators: this.validators,
|
|
166
107
|
queryManager: this.queryManager,
|
|
167
|
-
lan
|
|
108
|
+
lan: this.lan
|
|
168
109
|
})
|
|
169
110
|
this.contentFetching = new ContentFetching({
|
|
170
|
-
peerId,
|
|
171
|
-
datastore,
|
|
172
111
|
validators: this.validators,
|
|
173
112
|
selectors: this.selectors,
|
|
174
113
|
peerRouting: this.peerRouting,
|
|
175
114
|
queryManager: this.queryManager,
|
|
176
115
|
routingTable: this.routingTable,
|
|
177
116
|
network: this.network,
|
|
178
|
-
lan
|
|
117
|
+
lan: this.lan
|
|
179
118
|
})
|
|
180
119
|
this.contentRouting = new ContentRouting({
|
|
181
|
-
peerId,
|
|
182
120
|
network: this.network,
|
|
183
121
|
peerRouting: this.peerRouting,
|
|
184
122
|
queryManager: this.queryManager,
|
|
185
123
|
routingTable: this.routingTable,
|
|
186
124
|
providers: this.providers,
|
|
187
|
-
|
|
188
|
-
lan
|
|
125
|
+
lan: this.lan
|
|
189
126
|
})
|
|
190
127
|
this.routingTableRefresh = new RoutingTableRefresh({
|
|
191
128
|
peerRouting: this.peerRouting,
|
|
192
129
|
routingTable: this.routingTable,
|
|
193
|
-
lan
|
|
130
|
+
lan: this.lan
|
|
194
131
|
})
|
|
195
132
|
this.rpc = new RPC({
|
|
196
|
-
peerId,
|
|
197
133
|
routingTable: this.routingTable,
|
|
198
134
|
providers: this.providers,
|
|
199
135
|
peerRouting: this.peerRouting,
|
|
200
|
-
datastore,
|
|
201
136
|
validators: this.validators,
|
|
202
|
-
|
|
203
|
-
addressBook: peerStore.addressBook,
|
|
204
|
-
lan
|
|
137
|
+
lan: this.lan
|
|
205
138
|
})
|
|
206
139
|
this.topologyListener = new TopologyListener({
|
|
207
|
-
registrar,
|
|
208
140
|
protocol: this.protocol,
|
|
209
|
-
lan
|
|
141
|
+
lan: this.lan
|
|
210
142
|
})
|
|
211
143
|
this.querySelf = new QuerySelf({
|
|
212
|
-
peerId,
|
|
213
144
|
peerRouting: this.peerRouting,
|
|
214
145
|
interval: querySelfInterval,
|
|
215
|
-
lan
|
|
146
|
+
lan: this.lan
|
|
216
147
|
})
|
|
217
148
|
|
|
218
149
|
// handle peers being discovered during processing of DHT messages
|
|
@@ -233,7 +164,7 @@ export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT {
|
|
|
233
164
|
const peerId = evt.detail
|
|
234
165
|
|
|
235
166
|
Promise.resolve().then(async () => {
|
|
236
|
-
const multiaddrs = await
|
|
167
|
+
const multiaddrs = await this.components.getPeerStore().addressBook.get(peerId)
|
|
237
168
|
|
|
238
169
|
const peerData = {
|
|
239
170
|
id: peerId,
|
|
@@ -248,7 +179,23 @@ export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT {
|
|
|
248
179
|
})
|
|
249
180
|
}
|
|
250
181
|
|
|
251
|
-
|
|
182
|
+
init (components: Components): void {
|
|
183
|
+
this.components = components
|
|
184
|
+
|
|
185
|
+
this.routingTable.init(components)
|
|
186
|
+
this.providers.init(components)
|
|
187
|
+
this.network.init(components)
|
|
188
|
+
this.queryManager.init(components)
|
|
189
|
+
this.peerRouting.init(components)
|
|
190
|
+
this.contentFetching.init(components)
|
|
191
|
+
this.contentRouting.init(components)
|
|
192
|
+
this.routingTableRefresh.init(components)
|
|
193
|
+
this.rpc.init(components)
|
|
194
|
+
this.topologyListener.init(components)
|
|
195
|
+
this.querySelf.init(components)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async onPeerConnect (peerData: PeerInfo) {
|
|
252
199
|
this.log('peer %p connected', peerData.id)
|
|
253
200
|
|
|
254
201
|
if (this.lan) {
|
|
@@ -287,9 +234,7 @@ export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT {
|
|
|
287
234
|
* If 'server' this node will respond to DHT queries, if 'client' this node will not
|
|
288
235
|
*/
|
|
289
236
|
async setMode (mode: 'client' | 'server') {
|
|
290
|
-
|
|
291
|
-
await this.registrar.unhandle(this.registrarHandleId)
|
|
292
|
-
}
|
|
237
|
+
await this.components.getRegistrar().unhandle(this.protocol)
|
|
293
238
|
|
|
294
239
|
if (mode === 'client') {
|
|
295
240
|
this.log('enabling client mode')
|
|
@@ -297,7 +242,8 @@ export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT {
|
|
|
297
242
|
} else {
|
|
298
243
|
this.log('enabling server mode')
|
|
299
244
|
this.clientMode = false
|
|
300
|
-
|
|
245
|
+
|
|
246
|
+
await this.components.getRegistrar().handle(this.protocol, this.rpc.onIncomingStream.bind(this.rpc))
|
|
301
247
|
}
|
|
302
248
|
}
|
|
303
249
|
|
|
@@ -319,10 +265,6 @@ export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT {
|
|
|
319
265
|
this.querySelf.start()
|
|
320
266
|
])
|
|
321
267
|
|
|
322
|
-
await Promise.all(
|
|
323
|
-
this.bootstrapPeers.map(async peerData => await this.routingTable.add(peerData.id))
|
|
324
|
-
)
|
|
325
|
-
|
|
326
268
|
await this.routingTableRefresh.start()
|
|
327
269
|
}
|
|
328
270
|
|
|
@@ -364,7 +306,7 @@ export class KadDHT extends EventEmitter<PeerDiscoveryEvents> implements DHT {
|
|
|
364
306
|
* Announce to the network that we can provide given key's value
|
|
365
307
|
*/
|
|
366
308
|
async * provide (key: CID, options: QueryOptions = {}) { // eslint-disable-line require-await
|
|
367
|
-
yield * this.contentRouting.provide(key, this.
|
|
309
|
+
yield * this.contentRouting.provide(key, this.components.getAddressManager().getAddresses(), options)
|
|
368
310
|
}
|
|
369
311
|
|
|
370
312
|
/**
|
package/src/message/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { peerIdFromBytes } from '@libp2p/peer-id'
|
|
|
2
2
|
import { Multiaddr } from '@multiformats/multiaddr'
|
|
3
3
|
import { Libp2pRecord } from '@libp2p/record'
|
|
4
4
|
import Proto from './dht.js'
|
|
5
|
-
import type {
|
|
5
|
+
import type { PeerInfo } from '@libp2p/interfaces/peer-info'
|
|
6
6
|
|
|
7
7
|
export const MESSAGE_TYPE = Proto.Message.MessageType
|
|
8
8
|
export const CONNECTION_TYPE = Proto.Message.ConnectionType
|
|
@@ -23,8 +23,8 @@ export class Message {
|
|
|
23
23
|
public type: Proto.Message.MessageType
|
|
24
24
|
public key: Uint8Array
|
|
25
25
|
private clusterLevelRaw: number
|
|
26
|
-
public closerPeers:
|
|
27
|
-
public providerPeers:
|
|
26
|
+
public closerPeers: PeerInfo[]
|
|
27
|
+
public providerPeers: PeerInfo[]
|
|
28
28
|
public record?: Libp2pRecord
|
|
29
29
|
|
|
30
30
|
constructor (type: Proto.Message.MessageType, key: Uint8Array, level: number) {
|
|
@@ -88,7 +88,7 @@ export class Message {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
function toPbPeer (peer:
|
|
91
|
+
function toPbPeer (peer: PeerInfo) {
|
|
92
92
|
const output: PBPeer = {
|
|
93
93
|
id: peer.id.toBytes(),
|
|
94
94
|
addrs: (peer.multiaddrs ?? []).map((m) => m.bytes),
|
package/src/network.ts
CHANGED
|
@@ -13,44 +13,46 @@ import {
|
|
|
13
13
|
} from './query/events.js'
|
|
14
14
|
import { logger } from '@libp2p/logger'
|
|
15
15
|
import type { PeerId } from '@libp2p/interfaces/peer-id'
|
|
16
|
-
import type { AbortOptions,
|
|
16
|
+
import type { AbortOptions, Startable } from '@libp2p/interfaces'
|
|
17
17
|
import type { Logger } from '@libp2p/logger'
|
|
18
18
|
import type { Duplex } from 'it-stream-types'
|
|
19
|
-
import type {
|
|
19
|
+
import type { PeerInfo } from '@libp2p/interfaces/peer-info'
|
|
20
|
+
import { Components, Initializable } from '@libp2p/interfaces/components'
|
|
20
21
|
|
|
21
|
-
export interface
|
|
22
|
-
dialer: Dialer
|
|
22
|
+
export interface NetworkInit {
|
|
23
23
|
protocol: string
|
|
24
24
|
lan: boolean
|
|
25
|
-
peerId: PeerId
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
interface NetworkEvents {
|
|
29
|
-
'peer': CustomEvent<
|
|
28
|
+
'peer': CustomEvent<PeerInfo>
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
32
|
* Handle network operations for the dht
|
|
34
33
|
*/
|
|
35
|
-
export class Network extends EventEmitter<NetworkEvents> implements Startable {
|
|
34
|
+
export class Network extends EventEmitter<NetworkEvents> implements Startable, Initializable {
|
|
36
35
|
private readonly log: Logger
|
|
37
|
-
public dialer: Dialer
|
|
38
36
|
private readonly protocol: string
|
|
39
37
|
private running: boolean
|
|
38
|
+
private components: Components = new Components()
|
|
40
39
|
|
|
41
40
|
/**
|
|
42
41
|
* Create a new network
|
|
43
42
|
*/
|
|
44
|
-
constructor (
|
|
43
|
+
constructor (init: NetworkInit) {
|
|
45
44
|
super()
|
|
46
45
|
|
|
47
|
-
const {
|
|
48
|
-
this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:network
|
|
46
|
+
const { protocol, lan } = init
|
|
47
|
+
this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:network`)
|
|
49
48
|
this.running = false
|
|
50
|
-
this.dialer = dialer
|
|
51
49
|
this.protocol = protocol
|
|
52
50
|
}
|
|
53
51
|
|
|
52
|
+
init (components: Components): void {
|
|
53
|
+
this.components = components
|
|
54
|
+
}
|
|
55
|
+
|
|
54
56
|
/**
|
|
55
57
|
* Start the network
|
|
56
58
|
*/
|
|
@@ -89,7 +91,7 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
|
|
|
89
91
|
try {
|
|
90
92
|
yield dialingPeerEvent({ peer: to })
|
|
91
93
|
|
|
92
|
-
const { stream } = await this.
|
|
94
|
+
const { stream } = await this.components.getDialer().dialProtocol(to, this.protocol, options)
|
|
93
95
|
|
|
94
96
|
yield sendingQueryEvent({ to, type: msg.type })
|
|
95
97
|
|
|
@@ -119,7 +121,7 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
|
|
|
119
121
|
|
|
120
122
|
yield dialingPeerEvent({ peer: to })
|
|
121
123
|
|
|
122
|
-
const { stream } = await this.
|
|
124
|
+
const { stream } = await this.components.getDialer().dialProtocol(to, this.protocol, options)
|
|
123
125
|
|
|
124
126
|
yield sendingQueryEvent({ to, type: msg.type })
|
|
125
127
|
|
package/src/peer-list/index.ts
CHANGED
|
@@ -10,52 +10,50 @@ import {
|
|
|
10
10
|
} from '../query/events.js'
|
|
11
11
|
import { PeerDistanceList } from '../peer-list/peer-distance-list.js'
|
|
12
12
|
import { Libp2pRecord } from '@libp2p/record'
|
|
13
|
-
import { base58btc } from 'multiformats/bases/base58'
|
|
14
13
|
import { logger } from '@libp2p/logger'
|
|
15
14
|
import { keys } from '@libp2p/crypto'
|
|
16
15
|
import { peerIdFromKeys } from '@libp2p/peer-id'
|
|
17
16
|
import type { DHTRecord, QueryOptions, Validators } from '@libp2p/interfaces/dht'
|
|
18
17
|
import type { RoutingTable } from '../routing-table/index.js'
|
|
19
|
-
import type { PeerStore } from '@libp2p/interfaces/peer-store'
|
|
20
18
|
import type { QueryManager } from '../query/manager.js'
|
|
21
19
|
import type { Network } from '../network.js'
|
|
22
20
|
import type { Logger } from '@libp2p/logger'
|
|
23
21
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
24
22
|
import type { QueryFunc } from '../query/types.js'
|
|
25
|
-
import type {
|
|
23
|
+
import type { PeerInfo } from '@libp2p/interfaces/peer-info'
|
|
26
24
|
import type { PeerId } from '@libp2p/interfaces/peer-id'
|
|
25
|
+
import { Components, Initializable } from '@libp2p/interfaces/components'
|
|
27
26
|
|
|
28
|
-
export interface
|
|
29
|
-
peerId: PeerId
|
|
27
|
+
export interface PeerRoutingInit {
|
|
30
28
|
routingTable: RoutingTable
|
|
31
|
-
peerStore: PeerStore
|
|
32
29
|
network: Network
|
|
33
30
|
validators: Validators
|
|
34
31
|
queryManager: QueryManager
|
|
35
32
|
lan: boolean
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
export class PeerRouting {
|
|
35
|
+
export class PeerRouting implements Initializable {
|
|
36
|
+
private components: Components = new Components()
|
|
39
37
|
private readonly log: Logger
|
|
40
|
-
private readonly peerId: PeerId
|
|
41
38
|
private readonly routingTable: RoutingTable
|
|
42
|
-
private readonly peerStore: PeerStore
|
|
43
39
|
private readonly network: Network
|
|
44
40
|
private readonly validators: Validators
|
|
45
41
|
private readonly queryManager: QueryManager
|
|
46
42
|
|
|
47
|
-
constructor (
|
|
48
|
-
const {
|
|
43
|
+
constructor (init: PeerRoutingInit) {
|
|
44
|
+
const { routingTable, network, validators, queryManager, lan } = init
|
|
49
45
|
|
|
50
|
-
this.peerId = peerId
|
|
51
46
|
this.routingTable = routingTable
|
|
52
|
-
this.peerStore = peerStore
|
|
53
47
|
this.network = network
|
|
54
48
|
this.validators = validators
|
|
55
49
|
this.queryManager = queryManager
|
|
56
50
|
this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:peer-routing`)
|
|
57
51
|
}
|
|
58
52
|
|
|
53
|
+
init (components: Components): void {
|
|
54
|
+
this.components = components
|
|
55
|
+
}
|
|
56
|
+
|
|
59
57
|
/**
|
|
60
58
|
* Look if we are connected to a peer with the given id.
|
|
61
59
|
* Returns its id and addresses, if found, otherwise `undefined`.
|
|
@@ -68,7 +66,7 @@ export class PeerRouting {
|
|
|
68
66
|
this.log('findPeerLocal found %p in routing table', peer)
|
|
69
67
|
|
|
70
68
|
try {
|
|
71
|
-
peerData = await this.
|
|
69
|
+
peerData = await this.components.getPeerStore().get(p)
|
|
72
70
|
} catch (err: any) {
|
|
73
71
|
if (err.code !== 'ERR_NOT_FOUND') {
|
|
74
72
|
throw err
|
|
@@ -78,7 +76,7 @@ export class PeerRouting {
|
|
|
78
76
|
|
|
79
77
|
if (peerData == null) {
|
|
80
78
|
try {
|
|
81
|
-
peerData = await this.
|
|
79
|
+
peerData = await this.components.getPeerStore().get(peer)
|
|
82
80
|
} catch (err: any) {
|
|
83
81
|
if (err.code !== 'ERR_NOT_FOUND') {
|
|
84
82
|
throw err
|
|
@@ -130,7 +128,7 @@ export class PeerRouting {
|
|
|
130
128
|
}
|
|
131
129
|
}
|
|
132
130
|
|
|
133
|
-
throw errcode(new Error(`Node not responding with its public key: ${peer.toString(
|
|
131
|
+
throw errcode(new Error(`Node not responding with its public key: ${peer.toString()}`), 'ERR_INVALID_RECORD')
|
|
134
132
|
}
|
|
135
133
|
|
|
136
134
|
/**
|
|
@@ -146,7 +144,7 @@ export class PeerRouting {
|
|
|
146
144
|
if (pi != null) {
|
|
147
145
|
this.log('found local')
|
|
148
146
|
yield finalPeerEvent({
|
|
149
|
-
from: this.
|
|
147
|
+
from: this.components.getPeerId(),
|
|
150
148
|
peer: pi
|
|
151
149
|
})
|
|
152
150
|
return
|
|
@@ -160,11 +158,11 @@ export class PeerRouting {
|
|
|
160
158
|
|
|
161
159
|
if (match != null) {
|
|
162
160
|
try {
|
|
163
|
-
const peer = await this.
|
|
161
|
+
const peer = await this.components.getPeerStore().get(id)
|
|
164
162
|
|
|
165
163
|
this.log('found in peerStore')
|
|
166
164
|
yield finalPeerEvent({
|
|
167
|
-
from: this.
|
|
165
|
+
from: this.components.getPeerId(),
|
|
168
166
|
peer: {
|
|
169
167
|
id: peer.id,
|
|
170
168
|
multiaddrs: peer.addresses.map((address) => address.multiaddr),
|
|
@@ -210,7 +208,7 @@ export class PeerRouting {
|
|
|
210
208
|
}
|
|
211
209
|
|
|
212
210
|
if (!foundPeer) {
|
|
213
|
-
yield queryErrorEvent({ from: this.
|
|
211
|
+
yield queryErrorEvent({ from: this.components.getPeerId(), error: errcode(new Error('Not found'), 'ERR_NOT_FOUND') })
|
|
214
212
|
}
|
|
215
213
|
}
|
|
216
214
|
|
|
@@ -246,10 +244,10 @@ export class PeerRouting {
|
|
|
246
244
|
|
|
247
245
|
for (const peer of peers.peers) {
|
|
248
246
|
yield finalPeerEvent({
|
|
249
|
-
from: this.
|
|
247
|
+
from: this.components.getPeerId(),
|
|
250
248
|
peer: {
|
|
251
249
|
id: peer,
|
|
252
|
-
multiaddrs: (await (this.
|
|
250
|
+
multiaddrs: (await (this.components.getPeerStore().addressBook.get(peer)) ?? []).map(addr => addr.multiaddr),
|
|
253
251
|
protocols: []
|
|
254
252
|
}
|
|
255
253
|
})
|
|
@@ -298,7 +296,7 @@ export class PeerRouting {
|
|
|
298
296
|
async getCloserPeersOffline (key: Uint8Array, closerThan: PeerId) {
|
|
299
297
|
const id = await utils.convertBuffer(key)
|
|
300
298
|
const ids = this.routingTable.closestPeers(id)
|
|
301
|
-
const output:
|
|
299
|
+
const output: PeerInfo[] = []
|
|
302
300
|
|
|
303
301
|
for (const peerId of ids) {
|
|
304
302
|
if (peerId.equals(closerThan)) {
|
|
@@ -306,8 +304,8 @@ export class PeerRouting {
|
|
|
306
304
|
}
|
|
307
305
|
|
|
308
306
|
try {
|
|
309
|
-
const addresses = await this.
|
|
310
|
-
const protocols = await this.
|
|
307
|
+
const addresses = await this.components.getPeerStore().addressBook.get(peerId)
|
|
308
|
+
const protocols = await this.components.getPeerStore().protoBook.get(peerId)
|
|
311
309
|
|
|
312
310
|
output.push({
|
|
313
311
|
id: peerId,
|
package/src/providers.ts
CHANGED
|
@@ -15,11 +15,11 @@ import type { Datastore } from 'interface-datastore'
|
|
|
15
15
|
import type { Startable } from '@libp2p/interfaces'
|
|
16
16
|
import type { CID } from 'multiformats'
|
|
17
17
|
import type { PeerId } from '@libp2p/interfaces/peer-id'
|
|
18
|
+
import { Components, Initializable } from '@libp2p/interfaces/components'
|
|
18
19
|
|
|
19
20
|
const log = logger('libp2p:kad-dht:providers')
|
|
20
21
|
|
|
21
|
-
export interface
|
|
22
|
-
datastore: Datastore
|
|
22
|
+
export interface ProvidersInit {
|
|
23
23
|
cacheSize?: number
|
|
24
24
|
/**
|
|
25
25
|
* How often invalid records are cleaned. (in seconds)
|
|
@@ -43,8 +43,8 @@ export interface ProvidersOptions {
|
|
|
43
43
|
* providers are stored in the datastore, but to ensure
|
|
44
44
|
* access is fast there is an LRU cache in front of that.
|
|
45
45
|
*/
|
|
46
|
-
export class Providers implements Startable {
|
|
47
|
-
private
|
|
46
|
+
export class Providers implements Startable, Initializable {
|
|
47
|
+
private components: Components = new Components()
|
|
48
48
|
private readonly cache: ReturnType<typeof cache>
|
|
49
49
|
private readonly cleanupInterval: number
|
|
50
50
|
private readonly provideValidity: number
|
|
@@ -52,10 +52,9 @@ export class Providers implements Startable {
|
|
|
52
52
|
private started: boolean
|
|
53
53
|
private cleaner?: NodeJS.Timer
|
|
54
54
|
|
|
55
|
-
constructor (
|
|
56
|
-
const {
|
|
55
|
+
constructor (init: ProvidersInit = {}) {
|
|
56
|
+
const { cacheSize, cleanupInterval, provideValidity } = init
|
|
57
57
|
|
|
58
|
-
this.datastore = datastore
|
|
59
58
|
this.cleanupInterval = cleanupInterval ?? PROVIDERS_CLEANUP_INTERVAL
|
|
60
59
|
this.provideValidity = provideValidity ?? PROVIDERS_VALIDITY
|
|
61
60
|
this.cache = cache(cacheSize ?? PROVIDERS_LRU_CACHE_SIZE)
|
|
@@ -63,6 +62,10 @@ export class Providers implements Startable {
|
|
|
63
62
|
this.started = false
|
|
64
63
|
}
|
|
65
64
|
|
|
65
|
+
init (components: Components): void {
|
|
66
|
+
this.components = components
|
|
67
|
+
}
|
|
68
|
+
|
|
66
69
|
isStarted () {
|
|
67
70
|
return this.started
|
|
68
71
|
}
|
|
@@ -109,10 +112,10 @@ export class Providers implements Startable {
|
|
|
109
112
|
let count = 0
|
|
110
113
|
let deleteCount = 0
|
|
111
114
|
const deleted = new Map<string, Set<string>>()
|
|
112
|
-
const batch = this.
|
|
115
|
+
const batch = this.components.getDatastore().batch()
|
|
113
116
|
|
|
114
117
|
// Get all provider entries from the datastore
|
|
115
|
-
const query = this.
|
|
118
|
+
const query = this.components.getDatastore().query({ prefix: PROVIDER_KEY_PREFIX })
|
|
116
119
|
|
|
117
120
|
for await (const entry of query) {
|
|
118
121
|
try {
|
|
@@ -176,7 +179,7 @@ export class Providers implements Startable {
|
|
|
176
179
|
let provs: Map<string, Date> = this.cache.get(cacheKey)
|
|
177
180
|
|
|
178
181
|
if (provs == null) {
|
|
179
|
-
provs = await loadProviders(this.
|
|
182
|
+
provs = await loadProviders(this.components.getDatastore(), cid)
|
|
180
183
|
this.cache.set(cacheKey, provs)
|
|
181
184
|
}
|
|
182
185
|
|
|
@@ -198,7 +201,7 @@ export class Providers implements Startable {
|
|
|
198
201
|
const dsKey = makeProviderKey(cid)
|
|
199
202
|
this.cache.set(dsKey, provs)
|
|
200
203
|
|
|
201
|
-
await writeProviderEntry(this.
|
|
204
|
+
await writeProviderEntry(this.components.getDatastore(), cid, provider, now)
|
|
202
205
|
})
|
|
203
206
|
}
|
|
204
207
|
|