@streamr/dht 100.0.0-testnet-three.5 → 100.0.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/README.md +1 -1
- package/dist/package.json +14 -9
- package/dist/src/connection/ConnectionLockHandler.d.ts +2 -2
- package/dist/src/connection/ConnectionLockHandler.js +13 -5
- package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
- package/dist/src/connection/ConnectionManager.d.ts +6 -5
- package/dist/src/connection/ConnectionManager.js +16 -8
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/Handshaker.d.ts +2 -0
- package/dist/src/connection/Handshaker.js +12 -14
- package/dist/src/connection/Handshaker.js.map +1 -1
- package/dist/src/connection/ManagedConnection.js +1 -0
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/connectivityChecker.d.ts +1 -1
- package/dist/src/connection/connectivityChecker.js +5 -5
- package/dist/src/connection/connectivityChecker.js.map +1 -1
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -2
- package/dist/src/connection/connectivityRequestHandler.js +6 -7
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.d.ts +1 -0
- package/dist/src/connection/webrtc/WebrtcConnector.js +13 -8
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +2 -0
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +4 -6
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnector.js +24 -21
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServer.js +25 -35
- package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
- package/dist/src/connection/websocket/{ServerWebsocket.d.ts → WebsocketServerConnection.d.ts} +4 -5
- package/dist/src/connection/websocket/{ServerWebsocket.js → WebsocketServerConnection.js} +15 -48
- package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -0
- package/dist/src/dht/DhtNode.d.ts +15 -7
- package/dist/src/dht/DhtNode.js +63 -21
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +5 -1
- package/dist/src/dht/DhtNodeRpcLocal.js +10 -0
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcRemote.d.ts +3 -0
- package/dist/src/dht/DhtNodeRpcRemote.js +15 -0
- package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcLocal.d.ts +2 -2
- package/dist/src/dht/ExternalApiRpcLocal.js +3 -3
- package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.d.ts +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.js +2 -2
- package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +12 -0
- package/dist/src/dht/PeerManager.js +30 -5
- package/dist/src/dht/PeerManager.js.map +1 -1
- package/dist/src/dht/contact/RingContactList.d.ts +31 -0
- package/dist/src/dht/contact/RingContactList.js +133 -0
- package/dist/src/dht/contact/RingContactList.js.map +1 -0
- package/dist/src/dht/contact/ringIdentifiers.d.ts +16 -0
- package/dist/src/dht/contact/ringIdentifiers.js +54 -0
- package/dist/src/dht/contact/ringIdentifiers.js.map +1 -0
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +4 -0
- package/dist/src/dht/discovery/PeerDiscovery.js +35 -0
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/discovery/RingDiscoverySession.d.ts +29 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js +123 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js +0 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +5 -2
- package/dist/src/dht/routing/Router.js +17 -3
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcLocal.d.ts +2 -3
- package/dist/src/dht/routing/RouterRpcLocal.js +2 -2
- package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.d.ts +8 -6
- package/dist/src/dht/routing/RoutingSession.js +42 -40
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/routing/RoutingTablesCache.d.ts +24 -0
- package/dist/src/dht/routing/RoutingTablesCache.js +46 -0
- package/dist/src/dht/routing/RoutingTablesCache.js.map +1 -0
- package/dist/src/dht/store/StoreManager.js +1 -1
- package/dist/src/dht/store/StoreManager.js.map +1 -1
- package/dist/src/exports.d.ts +1 -0
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/createPeerDescriptor.d.ts +1 -1
- package/dist/src/helpers/createPeerDescriptor.js +2 -1
- package/dist/src/helpers/createPeerDescriptor.js.map +1 -1
- package/dist/src/helpers/version.d.ts +6 -0
- package/dist/src/helpers/version.js +38 -0
- package/dist/src/helpers/version.js.map +1 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +16 -6
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +11 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +98 -87
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +45 -49
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +10 -4
- package/dist/src/transport/RoutingRpcCommunicator.js +0 -2
- package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
- package/package.json +14 -9
- package/protos/DhtRpc.proto +21 -21
- package/src/connection/ConnectionLockHandler.ts +13 -5
- package/src/connection/ConnectionManager.ts +20 -12
- package/src/connection/ConnectorFacade.ts +0 -1
- package/src/connection/Handshaker.ts +14 -17
- package/src/connection/ManagedConnection.ts +1 -0
- package/src/connection/connectivityChecker.ts +6 -7
- package/src/connection/connectivityRequestHandler.ts +12 -12
- package/src/connection/webrtc/NodeWebrtcConnection.ts +1 -1
- package/src/connection/webrtc/WebrtcConnector.ts +14 -8
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +5 -5
- package/src/connection/websocket/WebsocketConnector.ts +25 -26
- package/src/connection/websocket/WebsocketServer.ts +27 -42
- package/src/connection/websocket/{ServerWebsocket.ts → WebsocketServerConnection.ts} +14 -55
- package/src/dht/DhtNode.ts +85 -40
- package/src/dht/DhtNodeRpcLocal.ts +16 -0
- package/src/dht/DhtNodeRpcRemote.ts +18 -0
- package/src/dht/ExternalApiRpcLocal.ts +5 -5
- package/src/dht/ExternalApiRpcRemote.ts +4 -4
- package/src/dht/PeerManager.ts +48 -12
- package/src/dht/contact/RingContactList.ts +151 -0
- package/src/dht/contact/ringIdentifiers.ts +62 -0
- package/src/dht/discovery/PeerDiscovery.ts +37 -0
- package/src/dht/discovery/RingDiscoverySession.ts +160 -0
- package/src/dht/recursive-operation/RecursiveOperationSession.ts +1 -3
- package/src/dht/routing/Router.ts +22 -6
- package/src/dht/routing/RouterRpcLocal.ts +4 -5
- package/src/dht/routing/RoutingSession.ts +50 -44
- package/src/dht/routing/RoutingTablesCache.ts +58 -0
- package/src/dht/store/StoreManager.ts +1 -1
- package/src/exports.ts +1 -0
- package/src/helpers/createPeerDescriptor.ts +2 -1
- package/src/helpers/version.ts +32 -0
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +22 -9
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +10 -4
- package/src/proto/packages/dht/protos/DhtRpc.ts +122 -100
- package/src/transport/RoutingRpcCommunicator.ts +1 -2
- package/test/benchmark/Find.test.ts +3 -4
- package/test/benchmark/KademliaCorrectness.test.ts +14 -8
- package/test/benchmark/RingCorrectness.test.ts +157 -0
- package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +72 -0
- package/test/data/generateGroundTruthData.ts +2 -2
- package/test/end-to-end/memory-leak.test.ts +1 -2
- package/test/integration/ConnectionManager.test.ts +28 -10
- package/test/integration/ConnectivityChecking.test.ts +3 -15
- package/test/integration/DhtNodeExternalAPI.test.ts +6 -6
- package/test/integration/Find.test.ts +4 -4
- package/test/integration/Layer1-scale.test.ts +0 -1
- package/test/integration/ReplicateData.test.ts +1 -1
- package/test/integration/RouteMessage.test.ts +1 -6
- package/test/integration/RouterRpcRemote.test.ts +1 -3
- package/test/integration/SimultaneousConnections.test.ts +9 -10
- package/test/integration/Store.test.ts +2 -2
- package/test/integration/StoreAndDelete.test.ts +3 -3
- package/test/integration/StoreOnDhtWithThreeNodes.test.ts +5 -5
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +3 -3
- package/test/integration/WebrtcConnectionManagement.test.ts +3 -9
- package/test/integration/WebsocketConnectionManagement.test.ts +1 -6
- package/test/integration/rpc-connections-over-webrpc.test.ts +1 -2
- package/test/unit/PeerManager.test.ts +5 -2
- package/test/unit/RecursiveOperationManager.test.ts +14 -8
- package/test/unit/RecursiveOperationSession.test.ts +1 -1
- package/test/unit/Router.test.ts +2 -3
- package/test/unit/RoutingSession.test.ts +8 -3
- package/test/unit/connectivityRequestHandler.test.ts +5 -9
- package/test/unit/createPeerDescriptor.test.ts +12 -6
- package/test/unit/version.test.ts +18 -0
- package/test/utils/mock/Router.ts +9 -0
- package/test/utils/utils.ts +43 -10
- package/tsconfig.jest.json +2 -1
- package/tsconfig.node.json +2 -1
- package/dist/src/connection/websocket/ServerWebsocket.js.map +0 -1
- package/dist/src/helpers/versionCompatibility.d.ts +0 -2
- package/dist/src/helpers/versionCompatibility.js +0 -18
- package/dist/src/helpers/versionCompatibility.js.map +0 -1
- package/src/helpers/versionCompatibility.ts +0 -13
- package/test/unit/versionCompatibility.test.ts +0 -16
package/src/dht/DhtNode.ts
CHANGED
|
@@ -17,10 +17,12 @@ import { Any } from '../proto/google/protobuf/any'
|
|
|
17
17
|
import {
|
|
18
18
|
ClosestPeersRequest,
|
|
19
19
|
ClosestPeersResponse,
|
|
20
|
+
ClosestRingPeersRequest,
|
|
21
|
+
ClosestRingPeersResponse,
|
|
20
22
|
ConnectivityResponse,
|
|
21
23
|
DataEntry,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
ExternalFetchDataRequest,
|
|
25
|
+
ExternalFetchDataResponse,
|
|
24
26
|
ExternalStoreDataRequest,
|
|
25
27
|
ExternalStoreDataResponse,
|
|
26
28
|
LeaveNotice,
|
|
@@ -40,18 +42,23 @@ import { ExternalApiRpcLocal } from './ExternalApiRpcLocal'
|
|
|
40
42
|
import { ExternalApiRpcRemote } from './ExternalApiRpcRemote'
|
|
41
43
|
import { PeerManager } from './PeerManager'
|
|
42
44
|
import { PeerDiscovery } from './discovery/PeerDiscovery'
|
|
43
|
-
import { RecursiveOperationManager
|
|
45
|
+
import { RecursiveOperationManager } from './recursive-operation/RecursiveOperationManager'
|
|
44
46
|
import { Router } from './routing/Router'
|
|
45
47
|
import { LocalDataStore } from './store/LocalDataStore'
|
|
46
48
|
import { StoreManager } from './store/StoreManager'
|
|
47
49
|
import { StoreRpcRemote } from './store/StoreRpcRemote'
|
|
48
50
|
import { createPeerDescriptor } from '../helpers/createPeerDescriptor'
|
|
51
|
+
import { RingIdRaw } from './contact/ringIdentifiers'
|
|
52
|
+
import { getLocalRegion } from '@streamr/cdn-location'
|
|
53
|
+
import { RingContacts } from './contact/RingContactList'
|
|
49
54
|
|
|
50
55
|
export interface DhtNodeEvents {
|
|
51
56
|
contactAdded: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
52
57
|
contactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
53
58
|
randomContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
54
59
|
randomContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
60
|
+
ringContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
|
|
61
|
+
ringContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
export interface DhtNodeOptions {
|
|
@@ -67,6 +74,7 @@ export interface DhtNodeOptions {
|
|
|
67
74
|
storeMaxTtl?: number
|
|
68
75
|
networkConnectivityTimeout?: number
|
|
69
76
|
storageRedundancyFactor?: number
|
|
77
|
+
region?: number
|
|
70
78
|
|
|
71
79
|
transport?: ITransport
|
|
72
80
|
peerDescriptor?: PeerDescriptor
|
|
@@ -123,9 +131,9 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
123
131
|
private peerDiscovery?: PeerDiscovery
|
|
124
132
|
private peerManager?: PeerManager
|
|
125
133
|
public connectionManager?: ConnectionManager
|
|
134
|
+
private region?: number
|
|
126
135
|
private started = false
|
|
127
136
|
private abortController = new AbortController()
|
|
128
|
-
|
|
129
137
|
constructor(conf: DhtNodeOptions) {
|
|
130
138
|
super()
|
|
131
139
|
this.config = merge({
|
|
@@ -150,7 +158,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
150
158
|
|
|
151
159
|
private validateConfig(): void {
|
|
152
160
|
const expectedNodeIdLength = KADEMLIA_ID_LENGTH_IN_BYTES * 2
|
|
153
|
-
if (this.config.nodeId !== undefined
|
|
161
|
+
if (this.config.nodeId !== undefined) {
|
|
154
162
|
if (!/^[0-9a-fA-F]+$/.test(this.config.nodeId)) {
|
|
155
163
|
throw new Error('Invalid nodeId, the nodeId should be a hex string')
|
|
156
164
|
} else if (this.config.nodeId.length !== expectedNodeIdLength) {
|
|
@@ -177,6 +185,14 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
177
185
|
this.config.peerDescriptor.websocket = undefined
|
|
178
186
|
}
|
|
179
187
|
}
|
|
188
|
+
if (this.region !== undefined) {
|
|
189
|
+
this.region = this.config.region
|
|
190
|
+
} else if (this.config.peerDescriptor?.region !== undefined) {
|
|
191
|
+
this.region = this.config.peerDescriptor.region
|
|
192
|
+
} else {
|
|
193
|
+
this.region = await getLocalRegion()
|
|
194
|
+
}
|
|
195
|
+
|
|
180
196
|
// If transport is given, do not create a ConnectionManager
|
|
181
197
|
if (this.config.transport) {
|
|
182
198
|
this.transport = this.config.transport
|
|
@@ -231,7 +247,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
231
247
|
{ rpcRequestTimeout: this.config.rpcRequestTimeout }
|
|
232
248
|
)
|
|
233
249
|
|
|
234
|
-
this.transport.on('message', (message: Message) => this.
|
|
250
|
+
this.transport.on('message', (message: Message) => this.handleMessageFromTransport(message))
|
|
235
251
|
|
|
236
252
|
this.initPeerManager()
|
|
237
253
|
|
|
@@ -250,7 +266,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
250
266
|
connections: this.peerManager!.connections,
|
|
251
267
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
252
268
|
addContact: (contact: PeerDescriptor, setActive?: boolean) => this.peerManager!.addContact([contact], setActive),
|
|
253
|
-
|
|
269
|
+
handleMessage: (message: Message) => this.handleMessageFromRouter(message),
|
|
254
270
|
})
|
|
255
271
|
this.recursiveOperationManager = new RecursiveOperationManager({
|
|
256
272
|
rpcCommunicator: this.rpcCommunicator,
|
|
@@ -294,10 +310,12 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
294
310
|
numberOfNodesPerKBucket: this.config.numberOfNodesPerKBucket,
|
|
295
311
|
maxContactListSize: this.config.maxNeighborListSize,
|
|
296
312
|
localNodeId: this.getNodeId(),
|
|
313
|
+
localPeerDescriptor: this.localPeerDescriptor!,
|
|
297
314
|
connectionManager: this.connectionManager!,
|
|
298
315
|
peerDiscoveryQueryBatchSize: this.config.peerDiscoveryQueryBatchSize,
|
|
299
316
|
isLayer0: (this.connectionManager !== undefined),
|
|
300
|
-
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor)
|
|
317
|
+
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor),
|
|
318
|
+
lockId: this.config.serviceId
|
|
301
319
|
})
|
|
302
320
|
this.peerManager.on('contactRemoved', (peerDescriptor: PeerDescriptor, activeContacts: PeerDescriptor[]) => {
|
|
303
321
|
this.emit('contactRemoved', peerDescriptor, activeContacts)
|
|
@@ -311,6 +329,12 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
311
329
|
this.peerManager.on('randomContactAdded', (peerDescriptor: PeerDescriptor, activeContacts: PeerDescriptor[]) =>
|
|
312
330
|
this.emit('randomContactAdded', peerDescriptor, activeContacts)
|
|
313
331
|
)
|
|
332
|
+
this.peerManager.on('ringContactRemoved', (peerDescriptor: PeerDescriptor, activeContacts: RingContacts) => {
|
|
333
|
+
this.emit('ringContactRemoved', peerDescriptor, activeContacts)
|
|
334
|
+
})
|
|
335
|
+
this.peerManager.on('ringContactAdded', (peerDescriptor: PeerDescriptor, activeContacts: RingContacts) => {
|
|
336
|
+
this.emit('ringContactAdded', peerDescriptor, activeContacts)
|
|
337
|
+
})
|
|
314
338
|
this.peerManager.on('kBucketEmpty', () => {
|
|
315
339
|
if (!this.peerDiscovery!.isJoinOngoing()
|
|
316
340
|
&& this.config.entryPoints
|
|
@@ -326,10 +350,12 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
326
350
|
})
|
|
327
351
|
this.transport!.on('connected', (peerDescriptor: PeerDescriptor) => {
|
|
328
352
|
this.peerManager!.onContactConnected(peerDescriptor)
|
|
353
|
+
this.router!.onNodeConnected(peerDescriptor)
|
|
329
354
|
this.emit('connected', peerDescriptor)
|
|
330
355
|
})
|
|
331
356
|
this.transport!.on('disconnected', (peerDescriptor: PeerDescriptor, gracefulLeave: boolean) => {
|
|
332
357
|
this.peerManager!.onContactDisconnected(getNodeIdFromPeerDescriptor(peerDescriptor), gracefulLeave)
|
|
358
|
+
this.router!.onNodeDisconnected(peerDescriptor)
|
|
333
359
|
this.emit('disconnected', peerDescriptor, gracefulLeave)
|
|
334
360
|
})
|
|
335
361
|
this.transport!.getConnections().forEach((peer) => {
|
|
@@ -347,26 +373,31 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
347
373
|
return this.peerManager!.getClosestNeighborsTo(nodeId, limit)
|
|
348
374
|
.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor())
|
|
349
375
|
},
|
|
376
|
+
getClosestRingPeersTo: (ringIdRaw: RingIdRaw, limit: number) => {
|
|
377
|
+
return this.getClosestRingContactsTo(ringIdRaw, limit)
|
|
378
|
+
},
|
|
350
379
|
addContact: (contact: PeerDescriptor) => this.peerManager!.addContact([contact]),
|
|
351
380
|
removeContact: (nodeId: DhtAddress) => this.removeContact(nodeId)
|
|
352
381
|
})
|
|
353
382
|
this.rpcCommunicator!.registerRpcMethod(ClosestPeersRequest, ClosestPeersResponse, 'getClosestPeers',
|
|
354
383
|
(req: ClosestPeersRequest, context) => dhtNodeRpcLocal.getClosestPeers(req, context))
|
|
384
|
+
this.rpcCommunicator!.registerRpcMethod(ClosestRingPeersRequest, ClosestRingPeersResponse, 'getClosestRingPeers',
|
|
385
|
+
(req: ClosestRingPeersRequest, context) => dhtNodeRpcLocal.getClosestRingPeers(req, context))
|
|
355
386
|
this.rpcCommunicator!.registerRpcMethod(PingRequest, PingResponse, 'ping',
|
|
356
387
|
(req: PingRequest, context) => dhtNodeRpcLocal.ping(req, context))
|
|
357
388
|
this.rpcCommunicator!.registerRpcNotification(LeaveNotice, 'leaveNotice',
|
|
358
389
|
(_req: LeaveNotice, context) => dhtNodeRpcLocal.leaveNotice(context))
|
|
359
390
|
const externalApiRpcLocal = new ExternalApiRpcLocal({
|
|
360
391
|
executeRecursiveOperation: (key: DhtAddress, operation: RecursiveOperation, excludedPeer: DhtAddress) => {
|
|
361
|
-
return this.
|
|
392
|
+
return this.recursiveOperationManager!.execute(key, operation, excludedPeer)
|
|
362
393
|
},
|
|
363
394
|
storeDataToDht: (key: DhtAddress, data: Any, creator?: DhtAddress) => this.storeDataToDht(key, data, creator)
|
|
364
395
|
})
|
|
365
396
|
this.rpcCommunicator!.registerRpcMethod(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
'
|
|
369
|
-
(req:
|
|
397
|
+
ExternalFetchDataRequest,
|
|
398
|
+
ExternalFetchDataResponse,
|
|
399
|
+
'externalFetchData',
|
|
400
|
+
(req: ExternalFetchDataRequest, context: ServerCallContext) => externalApiRpcLocal.externalFetchData(req, context),
|
|
370
401
|
{ timeout: 10000 } // TODO use config option or named constant?
|
|
371
402
|
)
|
|
372
403
|
this.rpcCommunicator!.registerRpcMethod(
|
|
@@ -378,13 +409,18 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
378
409
|
)
|
|
379
410
|
}
|
|
380
411
|
|
|
381
|
-
private
|
|
382
|
-
const nodeId = getNodeIdFromPeerDescriptor(message.sourceDescriptor!)
|
|
412
|
+
private handleMessageFromTransport(message: Message): void {
|
|
383
413
|
if (message.serviceId === this.config.serviceId) {
|
|
384
|
-
logger.trace('calling this.handleMessageFromPeer ' + nodeId + ' ' + message.serviceId + ' ' + message.messageId)
|
|
385
414
|
this.rpcCommunicator?.handleMessageFromPeer(message)
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
private handleMessageFromRouter(message: Message): void {
|
|
419
|
+
if (message.serviceId === this.config.serviceId) {
|
|
420
|
+
this.rpcCommunicator?.handleMessageFromPeer(message)
|
|
421
|
+
} else if (this.connectionManager?.handleIncomingMessage(message)) {
|
|
422
|
+
// message was handled by connectionManager
|
|
386
423
|
} else {
|
|
387
|
-
logger.trace('emit "message" ' + nodeId + ' ' + message.serviceId + ' ' + message.messageId)
|
|
388
424
|
this.emit('message', message)
|
|
389
425
|
}
|
|
390
426
|
}
|
|
@@ -393,7 +429,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
393
429
|
if (this.config.peerDescriptor !== undefined) {
|
|
394
430
|
this.localPeerDescriptor = this.config.peerDescriptor
|
|
395
431
|
} else {
|
|
396
|
-
this.localPeerDescriptor = createPeerDescriptor(connectivityResponse, this.config.nodeId)
|
|
432
|
+
this.localPeerDescriptor = createPeerDescriptor(connectivityResponse, this.region!, this.config.nodeId)
|
|
397
433
|
}
|
|
398
434
|
return this.localPeerDescriptor
|
|
399
435
|
}
|
|
@@ -401,8 +437,15 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
401
437
|
public getClosestContacts(limit?: number): PeerDescriptor[] {
|
|
402
438
|
return this.peerManager!.getClosestContactsTo(
|
|
403
439
|
this.getNodeId(),
|
|
404
|
-
limit).map((peer) => peer.getPeerDescriptor()
|
|
405
|
-
|
|
440
|
+
limit).map((peer) => peer.getPeerDescriptor())
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
public getClosestRingContactsTo(ringIdRaw: RingIdRaw, limit?: number): RingContacts {
|
|
444
|
+
const closest = this.peerManager!.getClosestRingContactsTo(ringIdRaw, limit)
|
|
445
|
+
return {
|
|
446
|
+
left: closest.left.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor()),
|
|
447
|
+
right: closest.right.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor())
|
|
448
|
+
}
|
|
406
449
|
}
|
|
407
450
|
|
|
408
451
|
public getNodeId(): DhtAddress {
|
|
@@ -441,25 +484,22 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
441
484
|
await this.peerDiscovery!.joinDht(entryPointDescriptors, doAdditionalDistantPeerDiscovery, retry)
|
|
442
485
|
}
|
|
443
486
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
excludedPeer?: DhtAddress
|
|
450
|
-
): Promise<RecursiveOperationResult> {
|
|
451
|
-
return this.recursiveOperationManager!.execute(key, operation, excludedPeer)
|
|
487
|
+
public async joinRing(): Promise<void> {
|
|
488
|
+
if (!this.started) {
|
|
489
|
+
throw new Error('Cannot join ring before calling start() on DhtNode')
|
|
490
|
+
}
|
|
491
|
+
await this.peerDiscovery!.joinRing()
|
|
452
492
|
}
|
|
453
493
|
|
|
454
494
|
public async storeDataToDht(key: DhtAddress, data: Any, creator?: DhtAddress): Promise<PeerDescriptor[]> {
|
|
455
495
|
const connectedEntryPoints = this.getConnectedEntryPoints()
|
|
456
496
|
if (this.peerDiscovery!.isJoinOngoing() && connectedEntryPoints.length > 0) {
|
|
457
|
-
return this.
|
|
497
|
+
return this.storeDataToDhtViaPeer(key, data, sample(connectedEntryPoints)!)
|
|
458
498
|
}
|
|
459
499
|
return this.storeManager!.storeDataToDht(key, data, creator ?? this.getNodeId())
|
|
460
500
|
}
|
|
461
501
|
|
|
462
|
-
public async
|
|
502
|
+
public async storeDataToDhtViaPeer(key: DhtAddress, data: Any, peer: PeerDescriptor): Promise<PeerDescriptor[]> {
|
|
463
503
|
const rpcRemote = new ExternalApiRpcRemote(
|
|
464
504
|
this.localPeerDescriptor!,
|
|
465
505
|
peer,
|
|
@@ -469,29 +509,34 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
469
509
|
return await rpcRemote.storeData(key, data)
|
|
470
510
|
}
|
|
471
511
|
|
|
472
|
-
public async
|
|
512
|
+
public async fetchDataFromDht(key: DhtAddress): Promise<DataEntry[]> {
|
|
473
513
|
const connectedEntryPoints = this.getConnectedEntryPoints()
|
|
474
514
|
if (this.peerDiscovery!.isJoinOngoing() && connectedEntryPoints.length > 0) {
|
|
475
|
-
return this.
|
|
515
|
+
return this.fetchDataFromDhtViaPeer(key, sample(connectedEntryPoints)!)
|
|
476
516
|
}
|
|
477
517
|
const result = await this.recursiveOperationManager!.execute(key, RecursiveOperation.FETCH_DATA)
|
|
478
518
|
return result.dataEntries ?? [] // TODO is this fallback needed?
|
|
479
519
|
}
|
|
480
520
|
|
|
481
|
-
public async
|
|
482
|
-
if (!this.abortController.signal.aborted) {
|
|
483
|
-
await this.recursiveOperationManager!.execute(key, RecursiveOperation.DELETE_DATA, undefined, waitForCompletion)
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
public async findDataViaPeer(key: DhtAddress, peer: PeerDescriptor): Promise<DataEntry[]> {
|
|
521
|
+
public async fetchDataFromDhtViaPeer(key: DhtAddress, peer: PeerDescriptor): Promise<DataEntry[]> {
|
|
488
522
|
const rpcRemote = new ExternalApiRpcRemote(
|
|
489
523
|
this.localPeerDescriptor!,
|
|
490
524
|
peer,
|
|
491
525
|
this.rpcCommunicator!,
|
|
492
526
|
ExternalApiRpcClient
|
|
493
527
|
)
|
|
494
|
-
return await rpcRemote.
|
|
528
|
+
return await rpcRemote.externalFetchData(key)
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
public async deleteDataFromDht(key: DhtAddress, waitForCompletion: boolean): Promise<void> {
|
|
532
|
+
if (!this.abortController.signal.aborted) {
|
|
533
|
+
await this.recursiveOperationManager!.execute(key, RecursiveOperation.DELETE_DATA, undefined, waitForCompletion)
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
async findClosestNodesFromDht(key: DhtAddress): Promise<PeerDescriptor[]> {
|
|
538
|
+
const result = await this.recursiveOperationManager!.execute(key, RecursiveOperation.FIND_CLOSEST_NODES)
|
|
539
|
+
return result.closestNodes
|
|
495
540
|
}
|
|
496
541
|
|
|
497
542
|
public getTransport(): ITransport {
|
|
@@ -4,6 +4,8 @@ import { Empty } from '../proto/google/protobuf/empty'
|
|
|
4
4
|
import {
|
|
5
5
|
ClosestPeersRequest,
|
|
6
6
|
ClosestPeersResponse,
|
|
7
|
+
ClosestRingPeersRequest,
|
|
8
|
+
ClosestRingPeersResponse,
|
|
7
9
|
PeerDescriptor,
|
|
8
10
|
PingRequest,
|
|
9
11
|
PingResponse
|
|
@@ -11,10 +13,13 @@ import {
|
|
|
11
13
|
import { IDhtNodeRpc } from '../proto/packages/dht/protos/DhtRpc.server'
|
|
12
14
|
import { DhtCallContext } from '../rpc-protocol/DhtCallContext'
|
|
13
15
|
import { DhtAddress, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
16
|
+
import { RingIdRaw } from './contact/ringIdentifiers'
|
|
17
|
+
import { RingContacts } from './contact/RingContactList'
|
|
14
18
|
|
|
15
19
|
interface DhtNodeRpcLocalConfig {
|
|
16
20
|
peerDiscoveryQueryBatchSize: number
|
|
17
21
|
getClosestPeersTo: (nodeId: DhtAddress, limit: number) => PeerDescriptor[]
|
|
22
|
+
getClosestRingPeersTo: (id: RingIdRaw, limit: number) => RingContacts
|
|
18
23
|
addContact: (contact: PeerDescriptor) => void
|
|
19
24
|
removeContact: (nodeId: DhtAddress) => void
|
|
20
25
|
}
|
|
@@ -38,6 +43,17 @@ export class DhtNodeRpcLocal implements IDhtNodeRpc {
|
|
|
38
43
|
return response
|
|
39
44
|
}
|
|
40
45
|
|
|
46
|
+
async getClosestRingPeers(request: ClosestRingPeersRequest, context: ServerCallContext): Promise<ClosestRingPeersResponse> {
|
|
47
|
+
this.config.addContact((context as DhtCallContext).incomingSourceDescriptor!)
|
|
48
|
+
const closestPeers = this.config.getClosestRingPeersTo(request.ringId as RingIdRaw, this.config.peerDiscoveryQueryBatchSize)
|
|
49
|
+
const response = {
|
|
50
|
+
leftPeers: closestPeers.left,
|
|
51
|
+
rightPeers: closestPeers.right,
|
|
52
|
+
requestId: request.requestId
|
|
53
|
+
}
|
|
54
|
+
return response
|
|
55
|
+
}
|
|
56
|
+
|
|
41
57
|
async ping(request: PingRequest, context: ServerCallContext): Promise<PingResponse> {
|
|
42
58
|
logger.trace('received ping request: ' + getNodeIdFromPeerDescriptor((context as DhtCallContext).incomingSourceDescriptor!))
|
|
43
59
|
setImmediate(() => {
|
|
@@ -4,6 +4,7 @@ import { v4 } from 'uuid'
|
|
|
4
4
|
import { DhtAddress, DhtAddressRaw, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '../identifiers'
|
|
5
5
|
import {
|
|
6
6
|
ClosestPeersRequest,
|
|
7
|
+
ClosestRingPeersRequest,
|
|
7
8
|
PeerDescriptor,
|
|
8
9
|
PingRequest
|
|
9
10
|
} from '../proto/packages/dht/protos/DhtRpc'
|
|
@@ -11,6 +12,8 @@ import { DhtNodeRpcClient } from '../proto/packages/dht/protos/DhtRpc.client'
|
|
|
11
12
|
import { ServiceID } from '../types/ServiceID'
|
|
12
13
|
import { RpcRemote } from './contact/RpcRemote'
|
|
13
14
|
import { DhtCallContext } from '../rpc-protocol/DhtCallContext'
|
|
15
|
+
import { RingIdRaw } from './contact/ringIdentifiers'
|
|
16
|
+
import { RingContacts } from './contact/RingContactList'
|
|
14
17
|
|
|
15
18
|
const logger = new Logger(module)
|
|
16
19
|
|
|
@@ -55,6 +58,21 @@ export class DhtNodeRpcRemote extends RpcRemote<DhtNodeRpcClient> implements KBu
|
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
async getClosestRingPeers(ringIdRaw: RingIdRaw): Promise<RingContacts> {
|
|
62
|
+
logger.trace(`Requesting getClosestRingPeers on ${this.serviceId} from ${this.getNodeId()}`)
|
|
63
|
+
const request: ClosestRingPeersRequest = {
|
|
64
|
+
ringId: ringIdRaw,
|
|
65
|
+
requestId: v4()
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const response = await this.getClient().getClosestRingPeers(request, this.formDhtRpcOptions())
|
|
69
|
+
return { left: response.leftPeers ?? [], right: response.rightPeers ?? [] }
|
|
70
|
+
} catch (err) {
|
|
71
|
+
logger.trace(`getClosestRingPeers error ${this.serviceId}`, { err })
|
|
72
|
+
throw err
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
58
76
|
async ping(): Promise<boolean> {
|
|
59
77
|
logger.trace(`Requesting ping on ${this.serviceId} from ${this.getNodeId()}`)
|
|
60
78
|
const request: PingRequest = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IExternalApiRpc } from '../proto/packages/dht/protos/DhtRpc.server'
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
ExternalFetchDataRequest,
|
|
4
|
+
ExternalFetchDataResponse,
|
|
5
5
|
ExternalStoreDataRequest,
|
|
6
6
|
ExternalStoreDataResponse,
|
|
7
7
|
RecursiveOperation,
|
|
@@ -35,14 +35,14 @@ export class ExternalApiRpcLocal implements IExternalApiRpc {
|
|
|
35
35
|
this.config = config
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
async
|
|
38
|
+
async externalFetchData(request: ExternalFetchDataRequest, context: ServerCallContext): Promise<ExternalFetchDataResponse> {
|
|
39
39
|
const senderPeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
|
|
40
40
|
const result = await this.config.executeRecursiveOperation(
|
|
41
|
-
getDhtAddressFromRaw(
|
|
41
|
+
getDhtAddressFromRaw(request.key),
|
|
42
42
|
RecursiveOperation.FETCH_DATA,
|
|
43
43
|
getNodeIdFromPeerDescriptor(senderPeerDescriptor)
|
|
44
44
|
)
|
|
45
|
-
return
|
|
45
|
+
return ExternalFetchDataResponse.create({ entries: result.dataEntries ?? [] })
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
async externalStoreData(request: ExternalStoreDataRequest, context: ServerCallContext): Promise<ExternalStoreDataResponse> {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { DhtAddress, getRawFromDhtAddress } from '../identifiers'
|
|
2
2
|
import { Any } from '../proto/google/protobuf/any'
|
|
3
|
-
import { DataEntry,
|
|
3
|
+
import { DataEntry, ExternalFetchDataRequest, ExternalStoreDataRequest, PeerDescriptor } from '../proto/packages/dht/protos/DhtRpc'
|
|
4
4
|
import { ExternalApiRpcClient } from '../proto/packages/dht/protos/DhtRpc.client'
|
|
5
5
|
import { RpcRemote } from './contact/RpcRemote'
|
|
6
6
|
|
|
7
7
|
export class ExternalApiRpcRemote extends RpcRemote<ExternalApiRpcClient> {
|
|
8
8
|
|
|
9
|
-
async
|
|
10
|
-
const request:
|
|
9
|
+
async externalFetchData(key: DhtAddress): Promise<DataEntry[]> {
|
|
10
|
+
const request: ExternalFetchDataRequest = {
|
|
11
11
|
key: getRawFromDhtAddress(key)
|
|
12
12
|
}
|
|
13
13
|
const options = this.formDhtRpcOptions({
|
|
@@ -15,7 +15,7 @@ export class ExternalApiRpcRemote extends RpcRemote<ExternalApiRpcClient> {
|
|
|
15
15
|
timeout: 10000
|
|
16
16
|
})
|
|
17
17
|
try {
|
|
18
|
-
const data = await this.getClient().
|
|
18
|
+
const data = await this.getClient().externalFetchData(request, options)
|
|
19
19
|
return data.entries
|
|
20
20
|
} catch (err) {
|
|
21
21
|
return []
|
package/src/dht/PeerManager.ts
CHANGED
|
@@ -11,6 +11,9 @@ import { SortedContactList } from './contact/SortedContactList'
|
|
|
11
11
|
import { ConnectionManager } from '../connection/ConnectionManager'
|
|
12
12
|
import EventEmitter from 'eventemitter3'
|
|
13
13
|
import { DhtAddress, DhtAddressRaw, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '../identifiers'
|
|
14
|
+
import { RingContactList, RingContacts } from './contact/RingContactList'
|
|
15
|
+
import { RingIdRaw, getRingIdRawFromPeerDescriptor } from './contact/ringIdentifiers'
|
|
16
|
+
import { LockID } from '../connection/ConnectionLockHandler'
|
|
14
17
|
|
|
15
18
|
const logger = new Logger(module)
|
|
16
19
|
|
|
@@ -19,8 +22,10 @@ interface PeerManagerConfig {
|
|
|
19
22
|
maxContactListSize: number
|
|
20
23
|
peerDiscoveryQueryBatchSize: number
|
|
21
24
|
localNodeId: DhtAddress
|
|
25
|
+
localPeerDescriptor: PeerDescriptor
|
|
22
26
|
connectionManager: ConnectionManager
|
|
23
27
|
isLayer0: boolean
|
|
28
|
+
lockId: LockID
|
|
24
29
|
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => DhtNodeRpcRemote
|
|
25
30
|
}
|
|
26
31
|
|
|
@@ -29,6 +34,8 @@ export interface PeerManagerEvents {
|
|
|
29
34
|
contactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
30
35
|
randomContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
31
36
|
randomContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
37
|
+
ringContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
|
|
38
|
+
ringContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
|
|
32
39
|
kBucketEmpty: () => void
|
|
33
40
|
}
|
|
34
41
|
|
|
@@ -51,6 +58,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
51
58
|
// All nodes that we know about
|
|
52
59
|
private contacts: SortedContactList<DhtNodeRpcRemote>
|
|
53
60
|
private randomPeers: RandomContactList<DhtNodeRpcRemote>
|
|
61
|
+
private ringContacts: RingContactList<DhtNodeRpcRemote>
|
|
54
62
|
private stopped: boolean = false
|
|
55
63
|
private readonly config: PeerManagerConfig
|
|
56
64
|
|
|
@@ -62,6 +70,13 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
62
70
|
numberOfNodesPerKBucket: this.config.numberOfNodesPerKBucket,
|
|
63
71
|
numberOfNodesToPing: this.config.numberOfNodesPerKBucket
|
|
64
72
|
})
|
|
73
|
+
this.ringContacts = new RingContactList<DhtNodeRpcRemote>(getRingIdRawFromPeerDescriptor(this.config.localPeerDescriptor), true)
|
|
74
|
+
this.ringContacts.on('ringContactAdded', (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => {
|
|
75
|
+
this.emit('ringContactAdded', peerDescriptor, closestPeers)
|
|
76
|
+
})
|
|
77
|
+
this.ringContacts.on('ringContactRemoved', (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => {
|
|
78
|
+
this.emit('ringContactRemoved', peerDescriptor, closestPeers)
|
|
79
|
+
})
|
|
65
80
|
this.bucket.on('ping', (oldContacts: DhtNodeRpcRemote[], newContact: DhtNodeRpcRemote) => this.onKBucketPing(oldContacts, newContact))
|
|
66
81
|
this.bucket.on('removed', (contact: DhtNodeRpcRemote) => this.onKBucketRemoved(getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())))
|
|
67
82
|
this.bucket.on('added', (contact: DhtNodeRpcRemote) => this.onKBucketAdded(contact))
|
|
@@ -69,7 +84,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
69
84
|
// TODO: Update contact info to the connection manager and reconnect
|
|
70
85
|
})
|
|
71
86
|
this.contacts = new SortedContactList({
|
|
72
|
-
referenceId: this.config.localNodeId,
|
|
87
|
+
referenceId: this.config.localNodeId,
|
|
73
88
|
maxSize: this.config.maxContactListSize,
|
|
74
89
|
allowToContainReferenceId: false,
|
|
75
90
|
emitEvents: true
|
|
@@ -98,7 +113,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
98
113
|
return
|
|
99
114
|
}
|
|
100
115
|
const sortingList: SortedContactList<DhtNodeRpcRemote> = new SortedContactList({
|
|
101
|
-
referenceId: this.config.localNodeId,
|
|
116
|
+
referenceId: this.config.localNodeId,
|
|
102
117
|
maxSize: 100, // TODO use config option or named constant?
|
|
103
118
|
allowToContainReferenceId: false,
|
|
104
119
|
emitEvents: false
|
|
@@ -106,7 +121,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
106
121
|
sortingList.addContacts(oldContacts)
|
|
107
122
|
const sortedContacts = sortingList.getAllContacts()
|
|
108
123
|
const removableNodeId = sortedContacts[sortedContacts.length - 1].getNodeId()
|
|
109
|
-
this.config.connectionManager?.weakUnlockConnection(removableNodeId)
|
|
124
|
+
this.config.connectionManager?.weakUnlockConnection(removableNodeId, this.config.lockId)
|
|
110
125
|
this.bucket.remove(getRawFromDhtAddress(removableNodeId))
|
|
111
126
|
this.bucket.add(newContact)
|
|
112
127
|
}
|
|
@@ -115,7 +130,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
115
130
|
if (this.stopped) {
|
|
116
131
|
return
|
|
117
132
|
}
|
|
118
|
-
this.config.connectionManager?.weakUnlockConnection(nodeId)
|
|
133
|
+
this.config.connectionManager?.weakUnlockConnection(nodeId, this.config.lockId)
|
|
119
134
|
logger.trace(`Removed contact ${nodeId}`)
|
|
120
135
|
if (this.bucket.count() === 0) {
|
|
121
136
|
this.emit('kBucketEmpty')
|
|
@@ -130,7 +145,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
130
145
|
const peerDescriptor = contact.getPeerDescriptor()
|
|
131
146
|
const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
|
|
132
147
|
// Important to lock here, before the ping result is known
|
|
133
|
-
this.config.connectionManager?.weakLockConnection(nodeId)
|
|
148
|
+
this.config.connectionManager?.weakLockConnection(nodeId, this.config.lockId)
|
|
134
149
|
if (this.connections.has(contact.getNodeId())) {
|
|
135
150
|
logger.trace(`Added new contact ${nodeId}`)
|
|
136
151
|
} else { // open connection by pinging
|
|
@@ -140,13 +155,13 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
140
155
|
logger.trace(`Added new contact ${nodeId}`)
|
|
141
156
|
} else {
|
|
142
157
|
logger.trace('ping failed ' + nodeId)
|
|
143
|
-
this.config.connectionManager?.weakUnlockConnection(nodeId)
|
|
158
|
+
this.config.connectionManager?.weakUnlockConnection(nodeId, this.config.lockId)
|
|
144
159
|
this.removeContact(nodeId)
|
|
145
160
|
this.addClosestContactToBucket()
|
|
146
161
|
}
|
|
147
162
|
return
|
|
148
163
|
}).catch((_e) => {
|
|
149
|
-
this.config.connectionManager?.weakUnlockConnection(nodeId)
|
|
164
|
+
this.config.connectionManager?.weakUnlockConnection(nodeId, this.config.lockId)
|
|
150
165
|
this.removeContact(nodeId)
|
|
151
166
|
this.addClosestContactToBucket()
|
|
152
167
|
})
|
|
@@ -207,6 +222,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
207
222
|
return
|
|
208
223
|
}
|
|
209
224
|
logger.trace(`Removing contact ${nodeId}`)
|
|
225
|
+
this.ringContacts.removeContact(this.contacts.getContact(nodeId)?.contact)
|
|
210
226
|
this.bucket.remove(getRawFromDhtAddress(nodeId))
|
|
211
227
|
this.contacts.removeContact(nodeId)
|
|
212
228
|
this.randomPeers.removeContact(nodeId)
|
|
@@ -219,6 +235,10 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
219
235
|
this.bucket.remove(rpcRemote.id)
|
|
220
236
|
})
|
|
221
237
|
this.bucket.removeAllListeners()
|
|
238
|
+
this.ringContacts.getAllContacts().forEach((rpcRemote) => {
|
|
239
|
+
rpcRemote.leaveNotice()
|
|
240
|
+
this.ringContacts.removeContact(rpcRemote)
|
|
241
|
+
})
|
|
222
242
|
this.contacts.stop()
|
|
223
243
|
this.randomPeers.stop()
|
|
224
244
|
this.connections.clear()
|
|
@@ -230,7 +250,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
230
250
|
allowToContainReferenceId: true,
|
|
231
251
|
emitEvents: false,
|
|
232
252
|
excludedNodeIds
|
|
233
|
-
})
|
|
253
|
+
})
|
|
234
254
|
this.bucket.toArray().forEach((contact) => closest.addContact(contact))
|
|
235
255
|
return closest.getClosestContacts(limit)
|
|
236
256
|
}
|
|
@@ -248,13 +268,24 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
248
268
|
return closest.getClosestContacts(limit)
|
|
249
269
|
}
|
|
250
270
|
|
|
271
|
+
getClosestRingContactsTo(
|
|
272
|
+
ringIdRaw: RingIdRaw,
|
|
273
|
+
limit?: number,
|
|
274
|
+
excludedIds?: Set<DhtAddress>
|
|
275
|
+
): { left: DhtNodeRpcRemote[], right: DhtNodeRpcRemote[] } {
|
|
276
|
+
const closest = new RingContactList<DhtNodeRpcRemote>(ringIdRaw, false, excludedIds)
|
|
277
|
+
this.contacts.getAllContacts().map((contact) => closest.addContact(contact))
|
|
278
|
+
this.ringContacts.getAllContacts().map((contact) => closest.addContact(contact))
|
|
279
|
+
return closest.getClosestContacts(limit ?? 8)
|
|
280
|
+
}
|
|
281
|
+
|
|
251
282
|
getContactCount(excludedNodeIds?: Set<DhtAddress>): number {
|
|
252
283
|
return this.contacts.getAllContacts().filter((contact) => {
|
|
253
284
|
if (!excludedNodeIds) {
|
|
254
285
|
return true
|
|
255
286
|
} else {
|
|
256
287
|
return !excludedNodeIds.has(contact.getNodeId())
|
|
257
|
-
}
|
|
288
|
+
}
|
|
258
289
|
}).length
|
|
259
290
|
}
|
|
260
291
|
|
|
@@ -274,7 +305,7 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
274
305
|
this.contacts.setActive(nodeId)
|
|
275
306
|
}
|
|
276
307
|
|
|
277
|
-
addContact(peerDescriptors: PeerDescriptor[], setActive?: boolean): void {
|
|
308
|
+
addContact(peerDescriptors: PeerDescriptor[], setActive?: boolean): void {
|
|
278
309
|
if (this.stopped) {
|
|
279
310
|
return
|
|
280
311
|
}
|
|
@@ -285,18 +316,23 @@ export class PeerManager extends EventEmitter<PeerManagerEvents> {
|
|
|
285
316
|
const remote = this.config.createDhtNodeRpcRemote(contact)
|
|
286
317
|
const isInBucket = (this.bucket.get(contact.nodeId) !== null)
|
|
287
318
|
const isInContacts = (this.contacts.getContact(nodeId) !== undefined)
|
|
319
|
+
const isInRingContacts = this.ringContacts.getContact(contact) !== undefined
|
|
320
|
+
|
|
288
321
|
if (isInBucket || isInContacts) {
|
|
289
322
|
this.randomPeers.addContact(remote)
|
|
290
323
|
}
|
|
291
324
|
if (!isInBucket) {
|
|
292
325
|
this.bucket.add(remote)
|
|
293
|
-
}
|
|
326
|
+
}
|
|
294
327
|
if (!isInContacts) {
|
|
295
328
|
this.contacts.addContact(remote)
|
|
296
|
-
}
|
|
329
|
+
}
|
|
297
330
|
if (setActive) {
|
|
298
331
|
this.contacts.setActive(nodeId)
|
|
299
332
|
}
|
|
333
|
+
if (!isInRingContacts) {
|
|
334
|
+
this.ringContacts.addContact(remote)
|
|
335
|
+
}
|
|
300
336
|
}
|
|
301
337
|
})
|
|
302
338
|
}
|