@libp2p/kad-dht 11.0.8 → 12.0.0-4e0135c7d
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 +23 -23
- 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 +13 -11
- 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/kad-dht.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { CustomEvent, TypedEventEmitter } from '@libp2p/interface'
|
|
1
|
+
import { CodeError, CustomEvent, TypedEventEmitter, contentRoutingSymbol, peerDiscoverySymbol, peerRoutingSymbol } from '@libp2p/interface'
|
|
2
|
+
import drain from 'it-drain'
|
|
3
|
+
import map from 'it-map'
|
|
4
|
+
import parallel from 'it-parallel'
|
|
2
5
|
import pDefer from 'p-defer'
|
|
3
|
-
import {
|
|
6
|
+
import { PROTOCOL } from './constants.js'
|
|
4
7
|
import { ContentFetching } from './content-fetching/index.js'
|
|
5
|
-
import { ContentRouting } from './content-routing/index.js'
|
|
8
|
+
import { ContentRouting as KADDHTContentRouting } from './content-routing/index.js'
|
|
6
9
|
import { Network } from './network.js'
|
|
7
|
-
import { PeerRouting } from './peer-routing/index.js'
|
|
10
|
+
import { PeerRouting as KADDHTPeerRouting } from './peer-routing/index.js'
|
|
8
11
|
import { Providers } from './providers.js'
|
|
9
12
|
import { QueryManager } from './query/manager.js'
|
|
10
13
|
import { QuerySelf } from './query-self.js'
|
|
@@ -15,45 +18,169 @@ import { RoutingTableRefresh } from './routing-table/refresh.js'
|
|
|
15
18
|
import { RPC } from './rpc/index.js'
|
|
16
19
|
import { TopologyListener } from './topology-listener.js'
|
|
17
20
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
multiaddrIsPublic,
|
|
22
|
+
removePrivateAddressesMapper
|
|
20
23
|
} from './utils.js'
|
|
21
|
-
import type { KadDHTComponents, KadDHTInit,
|
|
22
|
-
import type { Logger, PeerDiscoveryEvents, PeerId, PeerInfo } from '@libp2p/interface'
|
|
24
|
+
import type { KadDHTComponents, KadDHTInit, Validators, Selectors, KadDHT as KadDHTInterface, QueryEvent, PeerInfoMapper } from './index.js'
|
|
25
|
+
import type { AbortOptions, ContentRouting, Logger, PeerDiscovery, PeerDiscoveryEvents, PeerId, PeerInfo, PeerRouting, RoutingOptions, Startable } from '@libp2p/interface'
|
|
23
26
|
import type { CID } from 'multiformats/cid'
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
async function * ensurePeerInfoHasMultiaddrs (source: AsyncGenerator<PeerInfo>, peerRouting: PeerRouting, log: Logger, options: AbortOptions = {}): AsyncGenerator<() => Promise<PeerInfo | undefined>, void, undefined> {
|
|
29
|
+
yield * map(source, prov => {
|
|
30
|
+
return async () => {
|
|
31
|
+
if (prov.multiaddrs.length > 0) {
|
|
32
|
+
return prov
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
return await peerRouting.findPeer(prov.id, {
|
|
37
|
+
...options,
|
|
38
|
+
useCache: false
|
|
39
|
+
})
|
|
40
|
+
} catch (err) {
|
|
41
|
+
log.error('could not find peer', err)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
}
|
|
27
46
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Wrapper class to convert events into returned values
|
|
49
|
+
*/
|
|
50
|
+
class DHTContentRouting implements ContentRouting {
|
|
51
|
+
private readonly dht: KadDHTInterface
|
|
52
|
+
private readonly peerInfoMapper: PeerInfoMapper
|
|
53
|
+
private readonly peerRouting: PeerRouting
|
|
54
|
+
private readonly log: Logger
|
|
55
|
+
|
|
56
|
+
constructor (dht: KadDHTInterface, peerInfoMapper: PeerInfoMapper, peerRouting: PeerRouting, log: Logger) {
|
|
57
|
+
this.dht = dht
|
|
58
|
+
this.peerInfoMapper = peerInfoMapper
|
|
59
|
+
this.peerRouting = peerRouting
|
|
60
|
+
this.log = log
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async provide (cid: CID, options: RoutingOptions = {}): Promise<void> {
|
|
64
|
+
await drain(this.dht.provide(cid, options))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async * findProviders (cid: CID, options: RoutingOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
|
|
68
|
+
const self = this
|
|
69
|
+
const source = async function * (): AsyncGenerator<PeerInfo, void, undefined> {
|
|
70
|
+
for await (const event of self.dht.findProviders(cid, options)) {
|
|
71
|
+
if (event.name === 'PROVIDER') {
|
|
72
|
+
yield * event.providers
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
for await (let peerInfo of parallel(ensurePeerInfoHasMultiaddrs(source(), this.peerRouting, this.log, options))) {
|
|
77
|
+
if (peerInfo == null) {
|
|
78
|
+
continue
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
peerInfo = this.peerInfoMapper(peerInfo)
|
|
82
|
+
|
|
83
|
+
if (peerInfo.multiaddrs.length === 0) {
|
|
84
|
+
continue
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
yield peerInfo
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async put (key: Uint8Array, value: Uint8Array, options?: RoutingOptions): Promise<void> {
|
|
92
|
+
await drain(this.dht.put(key, value, options))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async get (key: Uint8Array, options?: RoutingOptions): Promise<Uint8Array> {
|
|
96
|
+
for await (const event of this.dht.get(key, options)) {
|
|
97
|
+
if (event.name === 'VALUE') {
|
|
98
|
+
return event.value
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
throw new CodeError('Not found', 'ERR_NOT_FOUND')
|
|
103
|
+
}
|
|
33
104
|
}
|
|
34
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Wrapper class to convert events into returned values
|
|
108
|
+
*/
|
|
109
|
+
class DHTPeerRouting implements PeerRouting {
|
|
110
|
+
private readonly dht: KadDHTInterface
|
|
111
|
+
private readonly peerInfoMapper: PeerInfoMapper
|
|
112
|
+
private readonly log: Logger
|
|
113
|
+
|
|
114
|
+
constructor (dht: KadDHTInterface, peerInfoMapper: PeerInfoMapper, log: Logger) {
|
|
115
|
+
this.dht = dht
|
|
116
|
+
this.peerInfoMapper = peerInfoMapper
|
|
117
|
+
this.log = log
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async findPeer (peerId: PeerId, options: RoutingOptions = {}): Promise<PeerInfo> {
|
|
121
|
+
for await (const event of this.dht.findPeer(peerId, options)) {
|
|
122
|
+
if (event.name === 'FINAL_PEER') {
|
|
123
|
+
const peer = this.peerInfoMapper(event.peer)
|
|
124
|
+
|
|
125
|
+
if (peer.multiaddrs.length > 0) {
|
|
126
|
+
return event.peer
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
throw new CodeError('Not found', 'ERR_NOT_FOUND')
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async * getClosestPeers (key: Uint8Array, options: RoutingOptions = {}): AsyncIterable<PeerInfo> {
|
|
135
|
+
const self = this
|
|
136
|
+
const source = async function * (): AsyncGenerator<PeerInfo, void, undefined> {
|
|
137
|
+
for await (const event of self.dht.getClosestPeers(key, options)) {
|
|
138
|
+
if (event.name === 'FINAL_PEER') {
|
|
139
|
+
yield event.peer
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for await (let peerInfo of parallel(ensurePeerInfoHasMultiaddrs(source(), this, this.log, options))) {
|
|
145
|
+
if (peerInfo == null) {
|
|
146
|
+
continue
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
peerInfo = this.peerInfoMapper(peerInfo)
|
|
150
|
+
|
|
151
|
+
if (peerInfo.multiaddrs.length === 0) {
|
|
152
|
+
continue
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
yield peerInfo
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const DEFAULT_MAX_INBOUND_STREAMS = 32
|
|
161
|
+
export const DEFAULT_MAX_OUTBOUND_STREAMS = 64
|
|
162
|
+
|
|
35
163
|
/**
|
|
36
164
|
* A DHT implementation modelled after Kademlia with S/Kademlia modifications.
|
|
37
165
|
* Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
|
|
38
166
|
*/
|
|
39
|
-
export class
|
|
167
|
+
export class KadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implements KadDHTInterface, Startable {
|
|
40
168
|
public protocol: string
|
|
41
169
|
public routingTable: RoutingTable
|
|
42
170
|
public providers: Providers
|
|
43
171
|
public network: Network
|
|
44
|
-
public peerRouting:
|
|
172
|
+
public peerRouting: KADDHTPeerRouting
|
|
45
173
|
|
|
46
174
|
public readonly components: KadDHTComponents
|
|
47
175
|
private readonly log: Logger
|
|
48
176
|
private running: boolean
|
|
49
177
|
private readonly kBucketSize: number
|
|
50
178
|
private clientMode: boolean
|
|
51
|
-
private readonly lan: boolean
|
|
52
179
|
private readonly validators: Validators
|
|
53
180
|
private readonly selectors: Selectors
|
|
54
181
|
private readonly queryManager: QueryManager
|
|
55
182
|
private readonly contentFetching: ContentFetching
|
|
56
|
-
private readonly contentRouting:
|
|
183
|
+
private readonly contentRouting: KADDHTContentRouting
|
|
57
184
|
private readonly routingTableRefresh: RoutingTableRefresh
|
|
58
185
|
private readonly rpc: RPC
|
|
59
186
|
private readonly topologyListener: TopologyListener
|
|
@@ -61,10 +188,14 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
61
188
|
private readonly maxInboundStreams: number
|
|
62
189
|
private readonly maxOutboundStreams: number
|
|
63
190
|
|
|
191
|
+
private readonly dhtContentRouting: DHTContentRouting
|
|
192
|
+
private readonly dhtPeerRouting: DHTPeerRouting
|
|
193
|
+
private readonly peerInfoMapper: PeerInfoMapper
|
|
194
|
+
|
|
64
195
|
/**
|
|
65
196
|
* Create a new KadDHT
|
|
66
197
|
*/
|
|
67
|
-
constructor (components: KadDHTComponents, init:
|
|
198
|
+
constructor (components: KadDHTComponents, init: KadDHTInit) {
|
|
68
199
|
super()
|
|
69
200
|
|
|
70
201
|
const {
|
|
@@ -73,8 +204,8 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
73
204
|
validators,
|
|
74
205
|
selectors,
|
|
75
206
|
querySelfInterval,
|
|
76
|
-
|
|
77
|
-
|
|
207
|
+
protocol,
|
|
208
|
+
logPrefix,
|
|
78
209
|
pingTimeout,
|
|
79
210
|
pingConcurrency,
|
|
80
211
|
maxInboundStreams,
|
|
@@ -82,21 +213,23 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
82
213
|
providers: providersInit
|
|
83
214
|
} = init
|
|
84
215
|
|
|
216
|
+
const loggingPrefix = logPrefix ?? 'libp2p:kad-dht'
|
|
217
|
+
|
|
85
218
|
this.running = false
|
|
86
219
|
this.components = components
|
|
87
|
-
this.
|
|
88
|
-
this.
|
|
89
|
-
this.protocol = `${protocolPrefix ?? PROTOCOL_PREFIX}${lan === true ? LAN_PREFIX : ''}${PROTOCOL_DHT}`
|
|
220
|
+
this.log = components.logger.forComponent(loggingPrefix)
|
|
221
|
+
this.protocol = protocol ?? PROTOCOL
|
|
90
222
|
this.kBucketSize = kBucketSize ?? 20
|
|
91
223
|
this.clientMode = clientMode ?? true
|
|
92
224
|
this.maxInboundStreams = maxInboundStreams ?? DEFAULT_MAX_INBOUND_STREAMS
|
|
93
225
|
this.maxOutboundStreams = maxOutboundStreams ?? DEFAULT_MAX_OUTBOUND_STREAMS
|
|
226
|
+
this.peerInfoMapper = init.peerInfoMapper ?? removePrivateAddressesMapper
|
|
94
227
|
this.routingTable = new RoutingTable(components, {
|
|
95
228
|
kBucketSize,
|
|
96
|
-
lan: this.lan,
|
|
97
229
|
pingTimeout,
|
|
98
230
|
pingConcurrency,
|
|
99
|
-
protocol: this.protocol
|
|
231
|
+
protocol: this.protocol,
|
|
232
|
+
logPrefix: loggingPrefix
|
|
100
233
|
})
|
|
101
234
|
|
|
102
235
|
this.providers = new Providers(components, providersInit ?? {})
|
|
@@ -111,7 +244,7 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
111
244
|
}
|
|
112
245
|
this.network = new Network(components, {
|
|
113
246
|
protocol: this.protocol,
|
|
114
|
-
|
|
247
|
+
logPrefix: loggingPrefix
|
|
115
248
|
})
|
|
116
249
|
|
|
117
250
|
// all queries should wait for the initial query-self query to run so we have
|
|
@@ -127,18 +260,18 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
127
260
|
this.queryManager = new QueryManager(components, {
|
|
128
261
|
// Number of disjoint query paths to use - This is set to `kBucketSize/2` per the S/Kademlia paper
|
|
129
262
|
disjointPaths: Math.ceil(this.kBucketSize / 2),
|
|
130
|
-
|
|
263
|
+
logPrefix: loggingPrefix,
|
|
131
264
|
initialQuerySelfHasRun,
|
|
132
265
|
routingTable: this.routingTable
|
|
133
266
|
})
|
|
134
267
|
|
|
135
268
|
// DHT components
|
|
136
|
-
this.peerRouting = new
|
|
269
|
+
this.peerRouting = new KADDHTPeerRouting(components, {
|
|
137
270
|
routingTable: this.routingTable,
|
|
138
271
|
network: this.network,
|
|
139
272
|
validators: this.validators,
|
|
140
273
|
queryManager: this.queryManager,
|
|
141
|
-
|
|
274
|
+
logPrefix: loggingPrefix
|
|
142
275
|
})
|
|
143
276
|
this.contentFetching = new ContentFetching(components, {
|
|
144
277
|
validators: this.validators,
|
|
@@ -146,37 +279,38 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
146
279
|
peerRouting: this.peerRouting,
|
|
147
280
|
queryManager: this.queryManager,
|
|
148
281
|
network: this.network,
|
|
149
|
-
|
|
282
|
+
logPrefix: loggingPrefix
|
|
150
283
|
})
|
|
151
|
-
this.contentRouting = new
|
|
284
|
+
this.contentRouting = new KADDHTContentRouting(components, {
|
|
152
285
|
network: this.network,
|
|
153
286
|
peerRouting: this.peerRouting,
|
|
154
287
|
queryManager: this.queryManager,
|
|
155
288
|
routingTable: this.routingTable,
|
|
156
289
|
providers: this.providers,
|
|
157
|
-
|
|
290
|
+
logPrefix: loggingPrefix
|
|
158
291
|
})
|
|
159
292
|
this.routingTableRefresh = new RoutingTableRefresh(components, {
|
|
160
293
|
peerRouting: this.peerRouting,
|
|
161
294
|
routingTable: this.routingTable,
|
|
162
|
-
|
|
295
|
+
logPrefix: loggingPrefix
|
|
163
296
|
})
|
|
164
297
|
this.rpc = new RPC(components, {
|
|
165
298
|
routingTable: this.routingTable,
|
|
166
299
|
providers: this.providers,
|
|
167
300
|
peerRouting: this.peerRouting,
|
|
168
301
|
validators: this.validators,
|
|
169
|
-
|
|
302
|
+
logPrefix: loggingPrefix,
|
|
303
|
+
peerInfoMapper: this.peerInfoMapper
|
|
170
304
|
})
|
|
171
305
|
this.topologyListener = new TopologyListener(components, {
|
|
172
306
|
protocol: this.protocol,
|
|
173
|
-
|
|
307
|
+
logPrefix: loggingPrefix
|
|
174
308
|
})
|
|
175
309
|
this.querySelf = new QuerySelf(components, {
|
|
176
310
|
peerRouting: this.peerRouting,
|
|
177
311
|
interval: querySelfInterval,
|
|
178
312
|
initialInterval: init.initialQuerySelfInterval,
|
|
179
|
-
|
|
313
|
+
logPrefix: loggingPrefix,
|
|
180
314
|
initialQuerySelfHasRun,
|
|
181
315
|
routingTable: this.routingTable
|
|
182
316
|
})
|
|
@@ -212,19 +346,55 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
212
346
|
this.log.error('could not add %p to routing table', peerId, err)
|
|
213
347
|
})
|
|
214
348
|
})
|
|
349
|
+
|
|
350
|
+
this.dhtPeerRouting = new DHTPeerRouting(this, this.peerInfoMapper, this.log)
|
|
351
|
+
this.dhtContentRouting = new DHTContentRouting(this, this.peerInfoMapper, this.dhtPeerRouting, this.log)
|
|
352
|
+
|
|
353
|
+
// if client mode has not been explicitly specified, auto-switch to server
|
|
354
|
+
// mode when the node's peer data is updated with publicly dialable
|
|
355
|
+
// addresses
|
|
356
|
+
if (init.clientMode == null) {
|
|
357
|
+
components.events.addEventListener('self:peer:update', (evt) => {
|
|
358
|
+
this.log('received update of self-peer info')
|
|
359
|
+
|
|
360
|
+
void Promise.resolve().then(async () => {
|
|
361
|
+
const hasPublicAddress = evt.detail.peer.addresses
|
|
362
|
+
.some(({ multiaddr }) => multiaddrIsPublic(multiaddr))
|
|
363
|
+
|
|
364
|
+
const mode = this.getMode()
|
|
365
|
+
|
|
366
|
+
if (hasPublicAddress && mode === 'client') {
|
|
367
|
+
await this.setMode('server')
|
|
368
|
+
} else if (mode === 'server' && !hasPublicAddress) {
|
|
369
|
+
await this.setMode('client')
|
|
370
|
+
}
|
|
371
|
+
})
|
|
372
|
+
.catch(err => {
|
|
373
|
+
this.log.error('error setting dht server mode', err)
|
|
374
|
+
})
|
|
375
|
+
})
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
get [contentRoutingSymbol] (): ContentRouting {
|
|
380
|
+
return this.dhtContentRouting
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
get [peerRoutingSymbol] (): PeerRouting {
|
|
384
|
+
return this.dhtPeerRouting
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
get [peerDiscoverySymbol] (): PeerDiscovery {
|
|
388
|
+
return this
|
|
215
389
|
}
|
|
216
390
|
|
|
217
391
|
async onPeerConnect (peerData: PeerInfo): Promise<void> {
|
|
218
392
|
this.log('peer %p connected', peerData.id)
|
|
219
393
|
|
|
220
|
-
|
|
221
|
-
peerData = removePublicAddresses(peerData)
|
|
222
|
-
} else {
|
|
223
|
-
peerData = removePrivateAddresses(peerData)
|
|
224
|
-
}
|
|
394
|
+
peerData = this.peerInfoMapper(peerData)
|
|
225
395
|
|
|
226
396
|
if (peerData.multiaddrs.length === 0) {
|
|
227
|
-
this.log('ignoring %p as
|
|
397
|
+
this.log('ignoring %p as there were no valid addresses in %s after filtering', peerData.id, peerData.multiaddrs.map(addr => addr.toString()))
|
|
228
398
|
return
|
|
229
399
|
}
|
|
230
400
|
|
|
@@ -245,7 +415,7 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
245
415
|
/**
|
|
246
416
|
* If 'server' this node will respond to DHT queries, if 'client' this node will not
|
|
247
417
|
*/
|
|
248
|
-
|
|
418
|
+
getMode (): 'client' | 'server' {
|
|
249
419
|
return this.clientMode ? 'client' : 'server'
|
|
250
420
|
}
|
|
251
421
|
|
|
@@ -277,17 +447,16 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
277
447
|
// Only respond to queries when not in client mode
|
|
278
448
|
await this.setMode(this.clientMode ? 'client' : 'server')
|
|
279
449
|
|
|
450
|
+
this.querySelf.start()
|
|
451
|
+
|
|
280
452
|
await Promise.all([
|
|
281
453
|
this.providers.start(),
|
|
282
454
|
this.queryManager.start(),
|
|
283
455
|
this.network.start(),
|
|
284
456
|
this.routingTable.start(),
|
|
285
|
-
this.topologyListener.start()
|
|
457
|
+
this.topologyListener.start(),
|
|
458
|
+
this.routingTableRefresh.start()
|
|
286
459
|
])
|
|
287
|
-
|
|
288
|
-
this.querySelf.start()
|
|
289
|
-
|
|
290
|
-
await this.routingTableRefresh.start()
|
|
291
460
|
}
|
|
292
461
|
|
|
293
462
|
/**
|
|
@@ -312,14 +481,14 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
312
481
|
/**
|
|
313
482
|
* Store the given key/value pair in the DHT
|
|
314
483
|
*/
|
|
315
|
-
async * put (key: Uint8Array, value: Uint8Array, options:
|
|
484
|
+
async * put (key: Uint8Array, value: Uint8Array, options: RoutingOptions = {}): AsyncGenerator<any, void, undefined> {
|
|
316
485
|
yield * this.contentFetching.put(key, value, options)
|
|
317
486
|
}
|
|
318
487
|
|
|
319
488
|
/**
|
|
320
489
|
* Get the value that corresponds to the passed key
|
|
321
490
|
*/
|
|
322
|
-
async * get (key: Uint8Array, options:
|
|
491
|
+
async * get (key: Uint8Array, options: RoutingOptions = {}): AsyncGenerator<QueryEvent, void, undefined> {
|
|
323
492
|
yield * this.contentFetching.get(key, options)
|
|
324
493
|
}
|
|
325
494
|
|
|
@@ -328,14 +497,14 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
328
497
|
/**
|
|
329
498
|
* Announce to the network that we can provide given key's value
|
|
330
499
|
*/
|
|
331
|
-
async * provide (key: CID, options:
|
|
500
|
+
async * provide (key: CID, options: RoutingOptions = {}): AsyncGenerator<QueryEvent, void, undefined> {
|
|
332
501
|
yield * this.contentRouting.provide(key, this.components.addressManager.getAddresses(), options)
|
|
333
502
|
}
|
|
334
503
|
|
|
335
504
|
/**
|
|
336
505
|
* Search the dht for providers of the given CID
|
|
337
506
|
*/
|
|
338
|
-
async * findProviders (key: CID, options:
|
|
507
|
+
async * findProviders (key: CID, options: RoutingOptions = {}): AsyncGenerator<QueryEvent, any, unknown> {
|
|
339
508
|
yield * this.contentRouting.findProviders(key, options)
|
|
340
509
|
}
|
|
341
510
|
|
|
@@ -344,14 +513,14 @@ export class DefaultKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implem
|
|
|
344
513
|
/**
|
|
345
514
|
* Search for a peer with the given ID
|
|
346
515
|
*/
|
|
347
|
-
async * findPeer (id: PeerId, options:
|
|
516
|
+
async * findPeer (id: PeerId, options: RoutingOptions = {}): AsyncGenerator<QueryEvent, any, unknown> {
|
|
348
517
|
yield * this.peerRouting.findPeer(id, options)
|
|
349
518
|
}
|
|
350
519
|
|
|
351
520
|
/**
|
|
352
521
|
* Kademlia 'node lookup' operation
|
|
353
522
|
*/
|
|
354
|
-
async * getClosestPeers (key: Uint8Array, options:
|
|
523
|
+
async * getClosestPeers (key: Uint8Array, options: RoutingOptions = {}): AsyncGenerator<QueryEvent, any, unknown> {
|
|
355
524
|
yield * this.peerRouting.getClosestPeers(key, options)
|
|
356
525
|
}
|
|
357
526
|
|
package/src/message/dht.proto
CHANGED
|
@@ -12,48 +12,48 @@ message Record {
|
|
|
12
12
|
optional string timeReceived = 5;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
15
|
+
enum MessageType {
|
|
16
|
+
PUT_VALUE = 0;
|
|
17
|
+
GET_VALUE = 1;
|
|
18
|
+
ADD_PROVIDER = 2;
|
|
19
|
+
GET_PROVIDERS = 3;
|
|
20
|
+
FIND_NODE = 4;
|
|
21
|
+
PING = 5;
|
|
22
|
+
}
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
enum ConnectionType {
|
|
25
|
+
// sender does not have a connection to peer, and no extra information (default)
|
|
26
|
+
NOT_CONNECTED = 0;
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
// sender has a live connection to peer
|
|
29
|
+
CONNECTED = 1;
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
// sender recently connected to peer
|
|
32
|
+
CAN_CONNECT = 2;
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
// sender recently tried to connect to peer repeatedly but failed to connect
|
|
35
|
+
// ("try" here is loose, but this should signal "made strong effort, failed")
|
|
36
|
+
CANNOT_CONNECT = 3;
|
|
37
|
+
}
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
message PeerInfo {
|
|
40
|
+
// ID of a given peer.
|
|
41
|
+
bytes id = 1;
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
// multiaddrs for a given peer
|
|
44
|
+
repeated bytes multiaddrs = 2;
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
// used to signal the sender's connection capabilities to the peer
|
|
47
|
+
optional ConnectionType connection = 3;
|
|
48
|
+
}
|
|
50
49
|
|
|
50
|
+
message Message {
|
|
51
51
|
// defines what type of message it is.
|
|
52
|
-
|
|
52
|
+
MessageType type = 1;
|
|
53
53
|
|
|
54
54
|
// defines what coral cluster level this query/response belongs to.
|
|
55
55
|
// in case we want to implement coral's cluster rings in the future.
|
|
56
|
-
optional int32
|
|
56
|
+
optional int32 clusterLevel = 10;
|
|
57
57
|
|
|
58
58
|
// Used to specify the key associated with this message.
|
|
59
59
|
// PUT_VALUE, GET_VALUE, ADD_PROVIDER, GET_PROVIDERS
|
|
@@ -67,9 +67,9 @@ message Message {
|
|
|
67
67
|
|
|
68
68
|
// Used to return peers closer to a key in a query
|
|
69
69
|
// GET_VALUE, GET_PROVIDERS, FIND_NODE
|
|
70
|
-
repeated
|
|
70
|
+
repeated PeerInfo closer = 8;
|
|
71
71
|
|
|
72
72
|
// Used to return Providers
|
|
73
73
|
// GET_VALUE, ADD_PROVIDER, GET_PROVIDERS
|
|
74
|
-
repeated
|
|
74
|
+
repeated PeerInfo providers = 9;
|
|
75
75
|
}
|