@streamr/dht 100.0.0-testnet-three.6 → 100.1.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 +12 -8
- package/dist/src/connection/ConnectionLockRpcLocal.d.ts +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.d.ts +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.js +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
- package/dist/src/connection/{ConnectionLockHandler.d.ts → ConnectionLockStates.d.ts} +3 -3
- package/dist/src/connection/{ConnectionLockHandler.js → ConnectionLockStates.js} +17 -9
- package/dist/src/connection/ConnectionLockStates.js.map +1 -0
- package/dist/src/connection/ConnectionManager.d.ts +9 -7
- package/dist/src/connection/ConnectionManager.js +16 -18
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.js +1 -1
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/Handshaker.js +6 -13
- package/dist/src/connection/Handshaker.js.map +1 -1
- package/dist/src/connection/ManagedConnection.d.ts +2 -2
- package/dist/src/connection/ManagedConnection.js +8 -8
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/connectivityChecker.d.ts +1 -1
- package/dist/src/connection/connectivityChecker.js +8 -8
- package/dist/src/connection/connectivityChecker.js.map +1 -1
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -2
- package/dist/src/connection/connectivityRequestHandler.js +10 -11
- 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/AbstractWebsocketClientConnection.d.ts +28 -0
- package/dist/src/connection/websocket/{ClientWebsocket.js → AbstractWebsocketClientConnection.js} +42 -68
- package/dist/src/connection/websocket/AbstractWebsocketClientConnection.js.map +1 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.d.ts +7 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.js +39 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.js.map +1 -0
- package/dist/src/connection/websocket/WebsocketConnector.js +26 -23
- 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} +18 -51
- package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -0
- package/dist/src/dht/DhtNode.d.ts +15 -8
- package/dist/src/dht/DhtNode.js +62 -31
- 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 +16 -1
- 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 +15 -3
- package/dist/src/dht/PeerManager.js +54 -40
- 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/SortedContactList.d.ts +2 -1
- package/dist/src/dht/contact/SortedContactList.js +19 -17
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- 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/DiscoverySession.js +3 -1
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +6 -2
- package/dist/src/dht/discovery/PeerDiscovery.js +41 -4
- 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 +125 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js.map +1 -1
- 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 +0 -1
- package/dist/src/dht/routing/Router.js +0 -1
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcLocal.d.ts +0 -1
- package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcRemote.js +2 -2
- package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.js +2 -2
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/store/LocalDataStore.js +2 -2
- package/dist/src/dht/store/LocalDataStore.js.map +1 -1
- package/dist/src/dht/store/StoreManager.js +2 -2
- package/dist/src/dht/store/StoreManager.js.map +1 -1
- package/dist/src/exports.d.ts +3 -2
- package/dist/src/exports.js +3 -3
- 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/karma.config.js +4 -1
- package/package.json +12 -8
- package/protos/DhtRpc.proto +21 -21
- package/src/connection/ConnectionLockRpcLocal.ts +1 -1
- package/src/connection/ConnectionLockRpcRemote.ts +2 -2
- package/src/connection/{ConnectionLockHandler.ts → ConnectionLockStates.ts} +14 -6
- package/src/connection/ConnectionManager.ts +21 -22
- package/src/connection/ConnectorFacade.ts +1 -2
- package/src/connection/Handshaker.ts +7 -15
- package/src/connection/ManagedConnection.ts +8 -8
- package/src/connection/connectivityChecker.ts +9 -10
- package/src/connection/connectivityRequestHandler.ts +16 -16
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +18 -0
- 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/{ClientWebsocket.ts → AbstractWebsocketClientConnection.ts} +57 -70
- package/src/connection/websocket/BrowserWebsocketClientConnection.ts +44 -0
- package/src/connection/websocket/NodeWebsocketClientConnection.ts +39 -0
- package/src/connection/websocket/WebsocketConnector.ts +27 -28
- package/src/connection/websocket/WebsocketServer.ts +27 -42
- package/src/connection/websocket/{ServerWebsocket.ts → WebsocketServerConnection.ts} +15 -56
- package/src/dht/DhtNode.ts +85 -50
- package/src/dht/DhtNodeRpcLocal.ts +16 -0
- package/src/dht/DhtNodeRpcRemote.ts +19 -1
- package/src/dht/ExternalApiRpcLocal.ts +5 -5
- package/src/dht/ExternalApiRpcRemote.ts +4 -4
- package/src/dht/PeerManager.ts +70 -44
- package/src/dht/contact/RingContactList.ts +151 -0
- package/src/dht/contact/SortedContactList.ts +22 -18
- package/src/dht/contact/ringIdentifiers.ts +62 -0
- package/src/dht/discovery/DiscoverySession.ts +3 -1
- package/src/dht/discovery/PeerDiscovery.ts +45 -6
- package/src/dht/discovery/RingDiscoverySession.ts +162 -0
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +1 -1
- package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +1 -1
- package/src/dht/recursive-operation/RecursiveOperationSession.ts +1 -3
- package/src/dht/routing/Router.ts +0 -2
- package/src/dht/routing/RouterRpcLocal.ts +0 -1
- package/src/dht/routing/RouterRpcRemote.ts +2 -2
- package/src/dht/routing/RoutingSession.ts +2 -2
- package/src/dht/store/LocalDataStore.ts +1 -1
- package/src/dht/store/StoreManager.ts +2 -2
- package/src/exports.ts +3 -2
- 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/WebsocketServerMemoryLeak.test.ts +2 -2
- 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 +6 -6
- package/test/integration/Layer1-scale.test.ts +0 -1
- package/test/integration/ReplicateData.test.ts +4 -4
- 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 +4 -4
- package/test/integration/StoreAndDelete.test.ts +5 -5
- 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/Websocket.test.ts +2 -2
- 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 +44 -10
- package/test/unit/RecursiveOperationManager.test.ts +14 -8
- package/test/unit/RecursiveOperationSession.test.ts +1 -1
- package/test/unit/Router.test.ts +0 -3
- package/test/unit/RoutingSession.test.ts +1 -2
- 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/utils.ts +60 -47
- package/tsconfig.browser.json +2 -1
- package/tsconfig.jest.json +4 -2
- package/tsconfig.node.json +4 -2
- package/dist/src/connection/ConnectionLockHandler.js.map +0 -1
- package/dist/src/connection/websocket/ClientWebsocket.d.ts +0 -17
- package/dist/src/connection/websocket/ClientWebsocket.js.map +0 -1
- package/dist/src/connection/websocket/ServerWebsocket.js.map +0 -1
- package/dist/src/helpers/MapWithTtl.d.ts +0 -14
- package/dist/src/helpers/MapWithTtl.js +0 -60
- package/dist/src/helpers/MapWithTtl.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/MapWithTtl.ts +0 -71
- package/src/helpers/versionCompatibility.ts +0 -13
- package/test/unit/versionCompatibility.test.ts +0 -16
package/src/dht/DhtNode.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { EventEmitter } from 'eventemitter3'
|
|
9
9
|
import { sample } from 'lodash'
|
|
10
10
|
import { MarkRequired } from 'ts-essentials'
|
|
11
|
-
import { ConnectionManager, PortRange, TlsCertificate } from '../connection/ConnectionManager'
|
|
11
|
+
import { ConnectionLocker, ConnectionManager, PortRange, TlsCertificate } from '../connection/ConnectionManager'
|
|
12
12
|
import { DefaultConnectorFacade, DefaultConnectorFacadeConfig } from '../connection/ConnectorFacade'
|
|
13
13
|
import { IceServer } from '../connection/webrtc/WebrtcConnector'
|
|
14
14
|
import { isBrowserEnvironment } from '../helpers/browser/isBrowserEnvironment'
|
|
@@ -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
|
|
@@ -122,10 +130,10 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
122
130
|
private recursiveOperationManager?: RecursiveOperationManager
|
|
123
131
|
private peerDiscovery?: PeerDiscovery
|
|
124
132
|
private peerManager?: PeerManager
|
|
125
|
-
public
|
|
133
|
+
public connectionLocker?: ConnectionLocker
|
|
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,12 +185,20 @@ 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
|
|
183
199
|
this.localPeerDescriptor = this.transport.getLocalPeerDescriptor()
|
|
184
200
|
if (this.config.transport instanceof ConnectionManager) {
|
|
185
|
-
this.
|
|
201
|
+
this.connectionLocker = this.config.transport
|
|
186
202
|
}
|
|
187
203
|
} else {
|
|
188
204
|
const connectorFacadeConfig: DefaultConnectorFacadeConfig = {
|
|
@@ -221,7 +237,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
221
237
|
metricsContext: this.config.metricsContext
|
|
222
238
|
})
|
|
223
239
|
await connectionManager.start()
|
|
224
|
-
this.
|
|
240
|
+
this.connectionLocker = connectionManager
|
|
225
241
|
this.transport = connectionManager
|
|
226
242
|
}
|
|
227
243
|
|
|
@@ -242,14 +258,13 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
242
258
|
joinTimeout: this.config.dhtJoinTimeout,
|
|
243
259
|
serviceId: this.config.serviceId,
|
|
244
260
|
parallelism: this.config.joinParallelism,
|
|
245
|
-
|
|
261
|
+
connectionLocker: this.connectionLocker,
|
|
246
262
|
peerManager: this.peerManager!
|
|
247
263
|
})
|
|
248
264
|
this.router = new Router({
|
|
249
265
|
rpcCommunicator: this.rpcCommunicator,
|
|
250
266
|
connections: this.peerManager!.connections,
|
|
251
267
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
252
|
-
addContact: (contact: PeerDescriptor, setActive?: boolean) => this.peerManager!.addContact([contact], setActive),
|
|
253
268
|
handleMessage: (message: Message) => this.handleMessageFromRouter(message),
|
|
254
269
|
})
|
|
255
270
|
this.recursiveOperationManager = new RecursiveOperationManager({
|
|
@@ -259,7 +274,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
259
274
|
connections: this.peerManager!.connections,
|
|
260
275
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
261
276
|
serviceId: this.config.serviceId,
|
|
262
|
-
addContact: (contact: PeerDescriptor) => this.peerManager!.addContact(
|
|
277
|
+
addContact: (contact: PeerDescriptor) => this.peerManager!.addContact(contact),
|
|
263
278
|
localDataStore: this.localDataStore
|
|
264
279
|
})
|
|
265
280
|
this.storeManager = new StoreManager({
|
|
@@ -294,10 +309,12 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
294
309
|
numberOfNodesPerKBucket: this.config.numberOfNodesPerKBucket,
|
|
295
310
|
maxContactListSize: this.config.maxNeighborListSize,
|
|
296
311
|
localNodeId: this.getNodeId(),
|
|
297
|
-
|
|
312
|
+
localPeerDescriptor: this.localPeerDescriptor!,
|
|
313
|
+
connectionLocker: this.connectionLocker!,
|
|
298
314
|
peerDiscoveryQueryBatchSize: this.config.peerDiscoveryQueryBatchSize,
|
|
299
|
-
isLayer0: (this.
|
|
300
|
-
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor)
|
|
315
|
+
isLayer0: (this.connectionLocker !== undefined),
|
|
316
|
+
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor),
|
|
317
|
+
lockId: this.config.serviceId
|
|
301
318
|
})
|
|
302
319
|
this.peerManager.on('contactRemoved', (peerDescriptor: PeerDescriptor, activeContacts: PeerDescriptor[]) => {
|
|
303
320
|
this.emit('contactRemoved', peerDescriptor, activeContacts)
|
|
@@ -311,6 +328,12 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
311
328
|
this.peerManager.on('randomContactAdded', (peerDescriptor: PeerDescriptor, activeContacts: PeerDescriptor[]) =>
|
|
312
329
|
this.emit('randomContactAdded', peerDescriptor, activeContacts)
|
|
313
330
|
)
|
|
331
|
+
this.peerManager.on('ringContactRemoved', (peerDescriptor: PeerDescriptor, activeContacts: RingContacts) => {
|
|
332
|
+
this.emit('ringContactRemoved', peerDescriptor, activeContacts)
|
|
333
|
+
})
|
|
334
|
+
this.peerManager.on('ringContactAdded', (peerDescriptor: PeerDescriptor, activeContacts: RingContacts) => {
|
|
335
|
+
this.emit('ringContactAdded', peerDescriptor, activeContacts)
|
|
336
|
+
})
|
|
314
337
|
this.peerManager.on('kBucketEmpty', () => {
|
|
315
338
|
if (!this.peerDiscovery!.isJoinOngoing()
|
|
316
339
|
&& this.config.entryPoints
|
|
@@ -349,26 +372,31 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
349
372
|
return this.peerManager!.getClosestNeighborsTo(nodeId, limit)
|
|
350
373
|
.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor())
|
|
351
374
|
},
|
|
352
|
-
|
|
375
|
+
getClosestRingPeersTo: (ringIdRaw: RingIdRaw, limit: number) => {
|
|
376
|
+
return this.getClosestRingContactsTo(ringIdRaw, limit)
|
|
377
|
+
},
|
|
378
|
+
addContact: (contact: PeerDescriptor) => this.peerManager!.addContact(contact),
|
|
353
379
|
removeContact: (nodeId: DhtAddress) => this.removeContact(nodeId)
|
|
354
380
|
})
|
|
355
381
|
this.rpcCommunicator!.registerRpcMethod(ClosestPeersRequest, ClosestPeersResponse, 'getClosestPeers',
|
|
356
382
|
(req: ClosestPeersRequest, context) => dhtNodeRpcLocal.getClosestPeers(req, context))
|
|
383
|
+
this.rpcCommunicator!.registerRpcMethod(ClosestRingPeersRequest, ClosestRingPeersResponse, 'getClosestRingPeers',
|
|
384
|
+
(req: ClosestRingPeersRequest, context) => dhtNodeRpcLocal.getClosestRingPeers(req, context))
|
|
357
385
|
this.rpcCommunicator!.registerRpcMethod(PingRequest, PingResponse, 'ping',
|
|
358
386
|
(req: PingRequest, context) => dhtNodeRpcLocal.ping(req, context))
|
|
359
387
|
this.rpcCommunicator!.registerRpcNotification(LeaveNotice, 'leaveNotice',
|
|
360
388
|
(_req: LeaveNotice, context) => dhtNodeRpcLocal.leaveNotice(context))
|
|
361
389
|
const externalApiRpcLocal = new ExternalApiRpcLocal({
|
|
362
390
|
executeRecursiveOperation: (key: DhtAddress, operation: RecursiveOperation, excludedPeer: DhtAddress) => {
|
|
363
|
-
return this.
|
|
391
|
+
return this.recursiveOperationManager!.execute(key, operation, excludedPeer)
|
|
364
392
|
},
|
|
365
393
|
storeDataToDht: (key: DhtAddress, data: Any, creator?: DhtAddress) => this.storeDataToDht(key, data, creator)
|
|
366
394
|
})
|
|
367
395
|
this.rpcCommunicator!.registerRpcMethod(
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
'
|
|
371
|
-
(req:
|
|
396
|
+
ExternalFetchDataRequest,
|
|
397
|
+
ExternalFetchDataResponse,
|
|
398
|
+
'externalFetchData',
|
|
399
|
+
(req: ExternalFetchDataRequest, context: ServerCallContext) => externalApiRpcLocal.externalFetchData(req, context),
|
|
372
400
|
{ timeout: 10000 } // TODO use config option or named constant?
|
|
373
401
|
)
|
|
374
402
|
this.rpcCommunicator!.registerRpcMethod(
|
|
@@ -389,8 +417,6 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
389
417
|
private handleMessageFromRouter(message: Message): void {
|
|
390
418
|
if (message.serviceId === this.config.serviceId) {
|
|
391
419
|
this.rpcCommunicator?.handleMessageFromPeer(message)
|
|
392
|
-
} else if (this.connectionManager?.handleIncomingMessage(message)) {
|
|
393
|
-
// message was handled by connectionManager
|
|
394
420
|
} else {
|
|
395
421
|
this.emit('message', message)
|
|
396
422
|
}
|
|
@@ -400,7 +426,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
400
426
|
if (this.config.peerDescriptor !== undefined) {
|
|
401
427
|
this.localPeerDescriptor = this.config.peerDescriptor
|
|
402
428
|
} else {
|
|
403
|
-
this.localPeerDescriptor = createPeerDescriptor(connectivityResponse, this.config.nodeId)
|
|
429
|
+
this.localPeerDescriptor = createPeerDescriptor(connectivityResponse, this.region!, this.config.nodeId)
|
|
404
430
|
}
|
|
405
431
|
return this.localPeerDescriptor
|
|
406
432
|
}
|
|
@@ -408,8 +434,15 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
408
434
|
public getClosestContacts(limit?: number): PeerDescriptor[] {
|
|
409
435
|
return this.peerManager!.getClosestContactsTo(
|
|
410
436
|
this.getNodeId(),
|
|
411
|
-
limit).map((peer) => peer.getPeerDescriptor()
|
|
412
|
-
|
|
437
|
+
limit).map((peer) => peer.getPeerDescriptor())
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
public getClosestRingContactsTo(ringIdRaw: RingIdRaw, limit?: number): RingContacts {
|
|
441
|
+
const closest = this.peerManager!.getClosestRingContactsTo(ringIdRaw, limit)
|
|
442
|
+
return {
|
|
443
|
+
left: closest.left.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor()),
|
|
444
|
+
right: closest.right.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor())
|
|
445
|
+
}
|
|
413
446
|
}
|
|
414
447
|
|
|
415
448
|
public getNodeId(): DhtAddress {
|
|
@@ -448,25 +481,22 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
448
481
|
await this.peerDiscovery!.joinDht(entryPointDescriptors, doAdditionalDistantPeerDiscovery, retry)
|
|
449
482
|
}
|
|
450
483
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
excludedPeer?: DhtAddress
|
|
457
|
-
): Promise<RecursiveOperationResult> {
|
|
458
|
-
return this.recursiveOperationManager!.execute(key, operation, excludedPeer)
|
|
484
|
+
public async joinRing(): Promise<void> {
|
|
485
|
+
if (!this.started) {
|
|
486
|
+
throw new Error('Cannot join ring before calling start() on DhtNode')
|
|
487
|
+
}
|
|
488
|
+
await this.peerDiscovery!.joinRing()
|
|
459
489
|
}
|
|
460
490
|
|
|
461
491
|
public async storeDataToDht(key: DhtAddress, data: Any, creator?: DhtAddress): Promise<PeerDescriptor[]> {
|
|
462
492
|
const connectedEntryPoints = this.getConnectedEntryPoints()
|
|
463
493
|
if (this.peerDiscovery!.isJoinOngoing() && connectedEntryPoints.length > 0) {
|
|
464
|
-
return this.
|
|
494
|
+
return this.storeDataToDhtViaPeer(key, data, sample(connectedEntryPoints)!)
|
|
465
495
|
}
|
|
466
496
|
return this.storeManager!.storeDataToDht(key, data, creator ?? this.getNodeId())
|
|
467
497
|
}
|
|
468
498
|
|
|
469
|
-
public async
|
|
499
|
+
public async storeDataToDhtViaPeer(key: DhtAddress, data: Any, peer: PeerDescriptor): Promise<PeerDescriptor[]> {
|
|
470
500
|
const rpcRemote = new ExternalApiRpcRemote(
|
|
471
501
|
this.localPeerDescriptor!,
|
|
472
502
|
peer,
|
|
@@ -476,29 +506,34 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
476
506
|
return await rpcRemote.storeData(key, data)
|
|
477
507
|
}
|
|
478
508
|
|
|
479
|
-
public async
|
|
509
|
+
public async fetchDataFromDht(key: DhtAddress): Promise<DataEntry[]> {
|
|
480
510
|
const connectedEntryPoints = this.getConnectedEntryPoints()
|
|
481
511
|
if (this.peerDiscovery!.isJoinOngoing() && connectedEntryPoints.length > 0) {
|
|
482
|
-
return this.
|
|
512
|
+
return this.fetchDataFromDhtViaPeer(key, sample(connectedEntryPoints)!)
|
|
483
513
|
}
|
|
484
514
|
const result = await this.recursiveOperationManager!.execute(key, RecursiveOperation.FETCH_DATA)
|
|
485
515
|
return result.dataEntries ?? [] // TODO is this fallback needed?
|
|
486
516
|
}
|
|
487
517
|
|
|
488
|
-
public async
|
|
489
|
-
if (!this.abortController.signal.aborted) {
|
|
490
|
-
await this.recursiveOperationManager!.execute(key, RecursiveOperation.DELETE_DATA, undefined, waitForCompletion)
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
public async findDataViaPeer(key: DhtAddress, peer: PeerDescriptor): Promise<DataEntry[]> {
|
|
518
|
+
public async fetchDataFromDhtViaPeer(key: DhtAddress, peer: PeerDescriptor): Promise<DataEntry[]> {
|
|
495
519
|
const rpcRemote = new ExternalApiRpcRemote(
|
|
496
520
|
this.localPeerDescriptor!,
|
|
497
521
|
peer,
|
|
498
522
|
this.rpcCommunicator!,
|
|
499
523
|
ExternalApiRpcClient
|
|
500
524
|
)
|
|
501
|
-
return await rpcRemote.
|
|
525
|
+
return await rpcRemote.externalFetchData(key)
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
public async deleteDataFromDht(key: DhtAddress, waitForCompletion: boolean): Promise<void> {
|
|
529
|
+
if (!this.abortController.signal.aborted) {
|
|
530
|
+
await this.recursiveOperationManager!.execute(key, RecursiveOperation.DELETE_DATA, undefined, waitForCompletion)
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
async findClosestNodesFromDht(key: DhtAddress): Promise<PeerDescriptor[]> {
|
|
535
|
+
const result = await this.recursiveOperationManager!.execute(key, RecursiveOperation.FIND_CLOSEST_NODES)
|
|
536
|
+
return result.closestNodes
|
|
502
537
|
}
|
|
503
538
|
|
|
504
539
|
public getTransport(): ITransport {
|
|
@@ -522,15 +557,15 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
522
557
|
}
|
|
523
558
|
|
|
524
559
|
public getLocalLockedConnectionCount(): number {
|
|
525
|
-
return this.
|
|
560
|
+
return this.connectionLocker!.getLocalLockedConnectionCount()
|
|
526
561
|
}
|
|
527
562
|
|
|
528
563
|
public getRemoteLockedConnectionCount(): number {
|
|
529
|
-
return this.
|
|
564
|
+
return this.connectionLocker!.getRemoteLockedConnectionCount()
|
|
530
565
|
}
|
|
531
566
|
|
|
532
567
|
public getWeakLockedConnectionCount(): number {
|
|
533
|
-
return this.
|
|
568
|
+
return this.connectionLocker!.getWeakLockedConnectionCount()
|
|
534
569
|
}
|
|
535
570
|
|
|
536
571
|
public async waitForNetworkConnectivity(): Promise<void> {
|
|
@@ -566,7 +601,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
566
601
|
await this.transport!.stop()
|
|
567
602
|
}
|
|
568
603
|
this.transport = undefined
|
|
569
|
-
this.
|
|
604
|
+
this.connectionLocker = undefined
|
|
570
605
|
this.removeAllListeners()
|
|
571
606
|
}
|
|
572
607
|
|
|
@@ -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 = {
|
|
@@ -67,7 +85,7 @@ export class DhtNodeRpcRemote extends RpcRemote<DhtNodeRpcClient> implements KBu
|
|
|
67
85
|
return true
|
|
68
86
|
}
|
|
69
87
|
} catch (err) {
|
|
70
|
-
logger.trace(`ping failed on ${this.serviceId} to ${this.getNodeId()}
|
|
88
|
+
logger.trace(`ping failed on ${this.serviceId} to ${this.getNodeId()}`, { err })
|
|
71
89
|
}
|
|
72
90
|
return false
|
|
73
91
|
}
|
|
@@ -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 []
|