@streamr/dht 100.2.4-beta.0 → 100.2.5-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +8 -9
- package/dist/src/connection/ConnectionManager.d.ts +2 -1
- package/dist/src/connection/ConnectionManager.js +2 -10
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectionsView.d.ts +7 -0
- package/dist/src/connection/ConnectionsView.js +3 -0
- package/dist/src/connection/ConnectionsView.js.map +1 -0
- package/dist/src/connection/ConnectorFacade.d.ts +2 -1
- package/dist/src/connection/ConnectorFacade.js +5 -4
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/connectivityChecker.d.ts +3 -3
- package/dist/src/connection/connectivityChecker.js +3 -3
- package/dist/src/connection/connectivityChecker.js.map +1 -1
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -1
- package/dist/src/connection/connectivityRequestHandler.js +13 -6
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
- package/dist/src/connection/{ManagedWebrtcConnection.d.ts → webrtc/ManagedWebrtcConnection.d.ts} +3 -3
- package/dist/src/connection/{ManagedWebrtcConnection.js → webrtc/ManagedWebrtcConnection.js} +2 -2
- package/dist/src/connection/webrtc/ManagedWebrtcConnection.js.map +1 -0
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js +3 -26
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/AbstractWebsocketClientConnection.d.ts +1 -1
- package/dist/src/connection/websocket/WebsocketConnector.d.ts +3 -1
- package/dist/src/connection/websocket/WebsocketConnector.js +26 -18
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServerConnection.d.ts +2 -1
- package/dist/src/connection/websocket/WebsocketServerConnection.js +4 -0
- package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -1
- package/dist/src/dht/DhtNode.d.ts +14 -11
- package/dist/src/dht/DhtNode.js +74 -61
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +3 -3
- package/dist/src/dht/DhtNodeRpcLocal.js +5 -2
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +14 -14
- package/dist/src/dht/PeerManager.js +51 -42
- package/dist/src/dht/PeerManager.js.map +1 -1
- package/dist/src/dht/contact/ContactList.d.ts +1 -2
- package/dist/src/dht/contact/ContactList.js +1 -3
- package/dist/src/dht/contact/ContactList.js.map +1 -1
- package/dist/src/dht/contact/RandomContactList.d.ts +1 -1
- package/dist/src/dht/contact/RandomContactList.js +7 -4
- package/dist/src/dht/contact/RandomContactList.js.map +1 -1
- package/dist/src/dht/contact/getClosestNodes.d.ts +6 -0
- package/dist/src/dht/contact/{getClosestContacts.js → getClosestNodes.js} +7 -6
- package/dist/src/dht/contact/getClosestNodes.js.map +1 -0
- package/dist/src/dht/discovery/DiscoverySession.d.ts +4 -0
- package/dist/src/dht/discovery/DiscoverySession.js +27 -21
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +8 -5
- package/dist/src/dht/discovery/PeerDiscovery.js +34 -24
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/discovery/RingDiscoverySession.d.ts +4 -4
- package/dist/src/dht/discovery/RingDiscoverySession.js +10 -19
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +2 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +3 -3
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
- package/dist/src/dht/store/StoreManager.d.ts +5 -6
- package/dist/src/dht/store/StoreManager.js +21 -76
- package/dist/src/dht/store/StoreManager.js.map +1 -1
- package/dist/src/dht/store/StoreRpcLocal.d.ts +5 -2
- package/dist/src/dht/store/StoreRpcLocal.js +22 -5
- package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
- package/dist/src/exports.d.ts +2 -1
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/version.d.ts +1 -1
- package/dist/src/helpers/version.js +1 -1
- package/dist/src/proto/google/protobuf/any.d.ts +8 -5
- package/dist/src/proto/google/protobuf/any.js.map +1 -1
- package/dist/src/proto/google/protobuf/empty.d.ts +0 -1
- package/dist/src/proto/google/protobuf/empty.js.map +1 -1
- package/dist/src/proto/google/protobuf/timestamp.d.ts +10 -1
- package/dist/src/proto/google/protobuf/timestamp.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +10 -2
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +4 -2
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/transport/ITransport.d.ts +0 -4
- package/dist/src/transport/ITransport.js.map +1 -1
- package/karma.config.js +2 -2
- package/package.json +8 -9
- package/protos/DhtRpc.proto +3 -1
- package/src/connection/ConnectionManager.ts +4 -10
- package/src/connection/ConnectionsView.ts +8 -0
- package/src/connection/ConnectorFacade.ts +7 -5
- package/src/connection/connectivityChecker.ts +4 -4
- package/src/connection/connectivityRequestHandler.ts +19 -6
- package/src/connection/{ManagedWebrtcConnection.ts → webrtc/ManagedWebrtcConnection.ts} +4 -4
- package/src/connection/webrtc/NodeWebrtcConnection.ts +3 -3
- package/src/connection/webrtc/WebrtcConnector.ts +1 -1
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +3 -3
- package/src/connection/websocket/AbstractWebsocketClientConnection.ts +1 -1
- package/src/connection/websocket/WebsocketConnector.ts +33 -21
- package/src/connection/websocket/WebsocketServerConnection.ts +6 -1
- package/src/dht/DhtNode.ts +102 -74
- package/src/dht/DhtNodeRpcLocal.ts +12 -5
- package/src/dht/PeerManager.ts +58 -49
- package/src/dht/contact/ContactList.ts +1 -4
- package/src/dht/contact/RandomContactList.ts +7 -5
- package/src/dht/contact/{getClosestContacts.ts → getClosestNodes.ts} +8 -6
- package/src/dht/discovery/DiscoverySession.ts +34 -22
- package/src/dht/discovery/PeerDiscovery.ts +44 -30
- package/src/dht/discovery/RingDiscoverySession.ts +15 -29
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +5 -3
- package/src/dht/store/StoreManager.ts +46 -84
- package/src/dht/store/StoreRpcLocal.ts +32 -9
- package/src/exports.ts +2 -1
- package/src/helpers/version.ts +1 -1
- package/src/proto/google/protobuf/any.ts +8 -5
- package/src/proto/google/protobuf/empty.ts +0 -1
- package/src/proto/google/protobuf/timestamp.ts +10 -1
- package/src/proto/packages/dht/protos/DhtRpc.ts +14 -4
- package/src/transport/ITransport.ts +0 -4
- package/test/benchmark/Find.test.ts +1 -1
- package/test/benchmark/WebsocketServerMemoryLeak.test.ts +1 -1
- package/test/end-to-end/GeoIpLayer0.test.ts +55 -0
- package/test/end-to-end/Layer0-Layer1.test.ts +4 -4
- package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +11 -5
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +7 -1
- package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +11 -2
- package/test/integration/ConnectionLocking.test.ts +1 -1
- package/test/integration/ConnectionManager.test.ts +3 -3
- package/test/integration/ConnectivityChecking.test.ts +3 -3
- package/test/integration/DhtNode.test.ts +5 -20
- package/test/integration/GeoIpConnectivityChecking.test.ts +71 -0
- package/test/integration/Layer1-scale.test.ts +6 -6
- package/test/integration/RouteMessage.test.ts +4 -0
- package/test/integration/ScaleDownDht.test.ts +1 -1
- package/test/integration/SimultaneousConnections.test.ts +2 -2
- package/test/integration/WebrtcConnectionManagement.test.ts +1 -1
- package/test/integration/Websocket.test.ts +1 -1
- package/test/integration/WebsocketConnectionManagement.test.ts +1 -1
- package/test/integration/rpc-connections-over-webrpc.test.ts +1 -1
- package/test/unit/AutoCertifierClientFacade.test.ts +1 -1
- package/test/unit/DiscoverySession.test.ts +4 -2
- package/test/unit/PeerManager.test.ts +45 -51
- package/test/unit/RandomContactList.test.ts +10 -0
- package/test/unit/RecursiveOperationManager.test.ts +4 -2
- package/test/unit/StoreManager.test.ts +42 -34
- package/test/unit/StoreRpcLocal.test.ts +167 -0
- package/test/unit/WebsocketConnector.test.ts +1 -1
- package/test/unit/connectivityRequestHandler.test.ts +3 -3
- package/test/unit/getClosestNodes.test.ts +30 -0
- package/test/utils/FakeTransport.ts +4 -2
- package/test/utils/mock/MockConnectionsView.ts +18 -0
- package/test/utils/mock/{Transport.ts → MockTransport.ts} +0 -15
- package/test/utils/utils.ts +4 -1
- package/tsconfig.jest.json +2 -1
- package/tsconfig.node.json +2 -1
- package/dist/src/connection/ManagedWebrtcConnection.js.map +0 -1
- package/dist/src/dht/contact/getClosestContacts.d.ts +0 -7
- package/dist/src/dht/contact/getClosestContacts.js.map +0 -1
- package/test/unit/getClosestContacts.test.ts +0 -28
- /package/test/utils/mock/{Router.ts → MockRouter.ts} +0 -0
package/src/dht/DhtNode.ts
CHANGED
|
@@ -3,15 +3,18 @@ import {
|
|
|
3
3
|
Logger,
|
|
4
4
|
MetricsContext,
|
|
5
5
|
merge,
|
|
6
|
+
scheduleAtInterval,
|
|
6
7
|
waitForCondition
|
|
7
8
|
} from '@streamr/utils'
|
|
8
9
|
import { EventEmitter } from 'eventemitter3'
|
|
9
10
|
import { sample } from 'lodash'
|
|
10
11
|
import { MarkRequired } from 'ts-essentials'
|
|
11
12
|
import { ConnectionLocker, ConnectionManager, PortRange, TlsCertificate } from '../connection/ConnectionManager'
|
|
13
|
+
import { ConnectionsView } from '../connection/ConnectionsView'
|
|
12
14
|
import { DefaultConnectorFacade, DefaultConnectorFacadeConfig } from '../connection/ConnectorFacade'
|
|
13
15
|
import { IceServer } from '../connection/webrtc/WebrtcConnector'
|
|
14
16
|
import { isBrowserEnvironment } from '../helpers/browser/isBrowserEnvironment'
|
|
17
|
+
import { createPeerDescriptor } from '../helpers/createPeerDescriptor'
|
|
15
18
|
import { DhtAddress, KADEMLIA_ID_LENGTH_IN_BYTES, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
16
19
|
import { Any } from '../proto/google/protobuf/any'
|
|
17
20
|
import {
|
|
@@ -41,24 +44,24 @@ import { DhtNodeRpcRemote } from './DhtNodeRpcRemote'
|
|
|
41
44
|
import { ExternalApiRpcLocal } from './ExternalApiRpcLocal'
|
|
42
45
|
import { ExternalApiRpcRemote } from './ExternalApiRpcRemote'
|
|
43
46
|
import { PeerManager } from './PeerManager'
|
|
47
|
+
import { RingContacts } from './contact/RingContactList'
|
|
48
|
+
import { RingIdRaw } from './contact/ringIdentifiers'
|
|
44
49
|
import { PeerDiscovery } from './discovery/PeerDiscovery'
|
|
45
50
|
import { RecursiveOperationManager } from './recursive-operation/RecursiveOperationManager'
|
|
46
51
|
import { Router } from './routing/Router'
|
|
47
52
|
import { LocalDataStore } from './store/LocalDataStore'
|
|
48
53
|
import { StoreManager } from './store/StoreManager'
|
|
49
54
|
import { StoreRpcRemote } from './store/StoreRpcRemote'
|
|
50
|
-
import {
|
|
51
|
-
import { RingIdRaw } from './contact/ringIdentifiers'
|
|
52
|
-
import { getLocalRegion } from '@streamr/cdn-location'
|
|
53
|
-
import { RingContacts } from './contact/RingContactList'
|
|
55
|
+
import { getLocalRegionByCoordinates, getLocalRegionWithCache } from '@streamr/cdn-location'
|
|
54
56
|
|
|
55
57
|
export interface DhtNodeEvents {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
nearbyContactAdded: (peerDescriptor: PeerDescriptor) => void
|
|
59
|
+
nearbyContactRemoved: (peerDescriptor: PeerDescriptor) => void
|
|
58
60
|
randomContactAdded: (peerDescriptor: PeerDescriptor) => void
|
|
59
61
|
randomContactRemoved: (peerDescriptor: PeerDescriptor) => void
|
|
60
62
|
ringContactAdded: (peerDescriptor: PeerDescriptor) => void
|
|
61
63
|
ringContactRemoved: (peerDescriptor: PeerDescriptor) => void
|
|
64
|
+
manualRejoinRequired: () => void
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
export interface DhtNodeOptions {
|
|
@@ -74,9 +77,11 @@ export interface DhtNodeOptions {
|
|
|
74
77
|
storeMaxTtl?: number
|
|
75
78
|
networkConnectivityTimeout?: number
|
|
76
79
|
storageRedundancyFactor?: number
|
|
77
|
-
|
|
80
|
+
periodicallyPingNeighbors?: boolean
|
|
81
|
+
periodicallyPingRingContacts?: boolean
|
|
78
82
|
|
|
79
83
|
transport?: ITransport
|
|
84
|
+
connectionsView?: ConnectionsView
|
|
80
85
|
connectionLocker?: ConnectionLocker
|
|
81
86
|
peerDescriptor?: PeerDescriptor
|
|
82
87
|
entryPoints?: PeerDescriptor[]
|
|
@@ -84,6 +89,7 @@ export interface DhtNodeOptions {
|
|
|
84
89
|
websocketPortRange?: PortRange
|
|
85
90
|
websocketServerEnableTls?: boolean
|
|
86
91
|
nodeId?: DhtAddress
|
|
92
|
+
region?: number
|
|
87
93
|
|
|
88
94
|
rpcRequestTimeout?: number
|
|
89
95
|
iceServers?: IceServer[]
|
|
@@ -98,6 +104,7 @@ export interface DhtNodeOptions {
|
|
|
98
104
|
externalIp?: string
|
|
99
105
|
autoCertifierUrl?: string
|
|
100
106
|
autoCertifierConfigFile?: string
|
|
107
|
+
geoIpDatabaseFolder?: string
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
type StrictDhtNodeOptions = MarkRequired<DhtNodeOptions,
|
|
@@ -117,6 +124,8 @@ type StrictDhtNodeOptions = MarkRequired<DhtNodeOptions,
|
|
|
117
124
|
|
|
118
125
|
const logger = new Logger(module)
|
|
119
126
|
|
|
127
|
+
const PERIODICAL_PING_INTERVAL = 60 * 1000
|
|
128
|
+
|
|
120
129
|
export type Events = TransportEvents & DhtNodeEvents
|
|
121
130
|
|
|
122
131
|
export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
@@ -125,16 +134,17 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
125
134
|
private rpcCommunicator?: RoutingRpcCommunicator
|
|
126
135
|
private transport?: ITransport
|
|
127
136
|
private localPeerDescriptor?: PeerDescriptor
|
|
128
|
-
|
|
137
|
+
private router?: Router
|
|
129
138
|
private storeManager?: StoreManager
|
|
130
139
|
private localDataStore: LocalDataStore
|
|
131
140
|
private recursiveOperationManager?: RecursiveOperationManager
|
|
132
141
|
private peerDiscovery?: PeerDiscovery
|
|
133
142
|
private peerManager?: PeerManager
|
|
143
|
+
private connectionsView?: ConnectionsView
|
|
134
144
|
public connectionLocker?: ConnectionLocker
|
|
135
|
-
private region?: number
|
|
136
145
|
private started = false
|
|
137
146
|
private abortController = new AbortController()
|
|
147
|
+
|
|
138
148
|
constructor(conf: DhtNodeOptions) {
|
|
139
149
|
super()
|
|
140
150
|
this.config = merge({
|
|
@@ -149,7 +159,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
149
159
|
storeHighestTtl: 60000,
|
|
150
160
|
storeMaxTtl: 60000,
|
|
151
161
|
networkConnectivityTimeout: 10000,
|
|
152
|
-
storageRedundancyFactor: 5,
|
|
162
|
+
storageRedundancyFactor: 5, // TODO validate that this is > 1 (as each node should replicate the data to other node)
|
|
153
163
|
metricsContext: new MetricsContext()
|
|
154
164
|
}, conf)
|
|
155
165
|
this.validateConfig()
|
|
@@ -171,6 +181,9 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
171
181
|
throw new Error(`Invalid peerDescriptor, the length of the nodeId should be ${KADEMLIA_ID_LENGTH_IN_BYTES} bytes`)
|
|
172
182
|
}
|
|
173
183
|
}
|
|
184
|
+
if (this.config.transport !== undefined && this.config.connectionsView === undefined) {
|
|
185
|
+
throw new Error('connectionsView is required when transport is given')
|
|
186
|
+
}
|
|
174
187
|
}
|
|
175
188
|
|
|
176
189
|
public async start(): Promise<void> {
|
|
@@ -185,17 +198,12 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
185
198
|
if (this.config.peerDescriptor) {
|
|
186
199
|
this.config.peerDescriptor.websocket = undefined
|
|
187
200
|
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
} else if (this.config.peerDescriptor?.region !== undefined) {
|
|
192
|
-
this.region = this.config.peerDescriptor.region
|
|
193
|
-
} else {
|
|
194
|
-
this.region = await getLocalRegion()
|
|
195
|
-
}
|
|
196
|
-
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// If transport is given, do not create a ConnectionManager
|
|
197
204
|
if (this.config.transport) {
|
|
198
205
|
this.transport = this.config.transport
|
|
206
|
+
this.connectionsView = this.config.connectionsView
|
|
199
207
|
this.connectionLocker = this.config.connectionLocker
|
|
200
208
|
this.localPeerDescriptor = this.transport.getLocalPeerDescriptor()
|
|
201
209
|
} else {
|
|
@@ -214,7 +222,8 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
214
222
|
externalIp: this.config.externalIp,
|
|
215
223
|
autoCertifierUrl: this.config.autoCertifierUrl,
|
|
216
224
|
autoCertifierConfigFile: this.config.autoCertifierConfigFile,
|
|
217
|
-
|
|
225
|
+
geoIpDatabaseFolder: this.config.geoIpDatabaseFolder,
|
|
226
|
+
createLocalPeerDescriptor: (connectivityResponse: ConnectivityResponse) => this.generatePeerDescriptorCallBack(connectivityResponse)
|
|
218
227
|
}
|
|
219
228
|
// If own PeerDescriptor is given in config, create a ConnectionManager with ws server
|
|
220
229
|
if (this.config.peerDescriptor?.websocket) {
|
|
@@ -235,6 +244,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
235
244
|
metricsContext: this.config.metricsContext
|
|
236
245
|
})
|
|
237
246
|
await connectionManager.start()
|
|
247
|
+
this.connectionsView = connectionManager
|
|
238
248
|
this.connectionLocker = connectionManager
|
|
239
249
|
this.transport = connectionManager
|
|
240
250
|
}
|
|
@@ -256,18 +266,21 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
256
266
|
serviceId: this.config.serviceId,
|
|
257
267
|
parallelism: this.config.joinParallelism,
|
|
258
268
|
connectionLocker: this.connectionLocker,
|
|
259
|
-
peerManager: this.peerManager
|
|
269
|
+
peerManager: this.peerManager!,
|
|
270
|
+
abortSignal: this.abortController.signal,
|
|
271
|
+
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor),
|
|
260
272
|
})
|
|
261
273
|
this.router = new Router({
|
|
262
274
|
rpcCommunicator: this.rpcCommunicator,
|
|
263
275
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
264
276
|
handleMessage: (message: Message) => this.handleMessageFromRouter(message),
|
|
265
|
-
getConnections: () => this.getConnections()
|
|
277
|
+
getConnections: () => this.connectionsView!.getConnections()
|
|
266
278
|
})
|
|
267
279
|
this.recursiveOperationManager = new RecursiveOperationManager({
|
|
268
280
|
rpcCommunicator: this.rpcCommunicator,
|
|
269
281
|
router: this.router,
|
|
270
282
|
sessionTransport: this,
|
|
283
|
+
connectionsView: this.connectionsView!,
|
|
271
284
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
272
285
|
serviceId: this.config.serviceId,
|
|
273
286
|
localDataStore: this.localDataStore,
|
|
@@ -282,9 +295,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
282
295
|
highestTtl: this.config.storeHighestTtl,
|
|
283
296
|
redundancyFactor: this.config.storageRedundancyFactor,
|
|
284
297
|
localDataStore: this.localDataStore,
|
|
285
|
-
|
|
286
|
-
return this.peerManager!.getClosestNeighborsTo(key, n).map((n) => n.getPeerDescriptor())
|
|
287
|
-
},
|
|
298
|
+
getNeighbors: () => this.peerManager!.getNeighbors().map((n) => n.getPeerDescriptor()),
|
|
288
299
|
createRpcRemote: (contact: PeerDescriptor) => {
|
|
289
300
|
return new StoreRpcRemote(
|
|
290
301
|
this.localPeerDescriptor!,
|
|
@@ -295,10 +306,26 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
295
306
|
)
|
|
296
307
|
}
|
|
297
308
|
})
|
|
298
|
-
this.on('
|
|
309
|
+
this.on('nearbyContactAdded', (peerDescriptor: PeerDescriptor) => {
|
|
299
310
|
this.storeManager!.onContactAdded(peerDescriptor)
|
|
300
311
|
})
|
|
301
312
|
this.bindRpcLocalMethods()
|
|
313
|
+
|
|
314
|
+
const pruneTargets = []
|
|
315
|
+
if (this.config.periodicallyPingNeighbors === true) {
|
|
316
|
+
pruneTargets.push(() => this.peerManager!.getNeighbors().map((node) => this.createDhtNodeRpcRemote(node.getPeerDescriptor())))
|
|
317
|
+
}
|
|
318
|
+
if (this.config.periodicallyPingRingContacts === true) {
|
|
319
|
+
pruneTargets.push(() => this.peerManager!.getRingContacts().getAllContacts())
|
|
320
|
+
}
|
|
321
|
+
for (const pruneTarget of pruneTargets) {
|
|
322
|
+
await scheduleAtInterval(
|
|
323
|
+
async () => {
|
|
324
|
+
const nodes = pruneTarget()
|
|
325
|
+
await this.peerManager!.pruneOfflineNodes(nodes)
|
|
326
|
+
}, PERIODICAL_PING_INTERVAL, false, this.abortController.signal
|
|
327
|
+
)
|
|
328
|
+
}
|
|
302
329
|
}
|
|
303
330
|
|
|
304
331
|
private initPeerManager() {
|
|
@@ -310,13 +337,13 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
310
337
|
connectionLocker: this.connectionLocker,
|
|
311
338
|
lockId: this.config.serviceId,
|
|
312
339
|
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor),
|
|
313
|
-
hasConnection: (nodeId: DhtAddress) => this.
|
|
340
|
+
hasConnection: (nodeId: DhtAddress) => this.connectionsView!.hasConnection(nodeId)
|
|
314
341
|
})
|
|
315
|
-
this.peerManager.on('
|
|
316
|
-
this.emit('
|
|
342
|
+
this.peerManager.on('nearbyContactRemoved', (peerDescriptor: PeerDescriptor) => {
|
|
343
|
+
this.emit('nearbyContactRemoved', peerDescriptor)
|
|
317
344
|
})
|
|
318
|
-
this.peerManager.on('
|
|
319
|
-
this.emit('
|
|
345
|
+
this.peerManager.on('nearbyContactAdded', (peerDescriptor: PeerDescriptor) =>
|
|
346
|
+
this.emit('nearbyContactAdded', peerDescriptor)
|
|
320
347
|
)
|
|
321
348
|
this.peerManager.on('randomContactRemoved', (peerDescriptor: PeerDescriptor) =>
|
|
322
349
|
this.emit('randomContactRemoved', peerDescriptor)
|
|
@@ -331,18 +358,19 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
331
358
|
this.emit('ringContactAdded', peerDescriptor)
|
|
332
359
|
})
|
|
333
360
|
this.peerManager.on('kBucketEmpty', () => {
|
|
334
|
-
if (!this.peerDiscovery!.isJoinOngoing()
|
|
335
|
-
&& this.config.entryPoints
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
361
|
+
if (!this.peerDiscovery!.isJoinOngoing()) {
|
|
362
|
+
if (this.config.entryPoints && this.config.entryPoints.length > 0) {
|
|
363
|
+
setImmediate(async () => {
|
|
364
|
+
const contactedPeers = new Set<DhtAddress>()
|
|
365
|
+
const distantJoinContactPeers = new Set<DhtAddress>()
|
|
366
|
+
// TODO should we catch possible promise rejection?
|
|
367
|
+
await Promise.all(this.config.entryPoints!.map((entryPoint) =>
|
|
368
|
+
this.peerDiscovery!.rejoinDht(entryPoint, contactedPeers, distantJoinContactPeers)
|
|
369
|
+
))
|
|
370
|
+
})
|
|
371
|
+
} else {
|
|
372
|
+
this.emit('manualRejoinRequired')
|
|
373
|
+
}
|
|
346
374
|
}
|
|
347
375
|
})
|
|
348
376
|
this.transport!.on('connected', (peerDescriptor: PeerDescriptor) => {
|
|
@@ -370,10 +398,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
370
398
|
}
|
|
371
399
|
const dhtNodeRpcLocal = new DhtNodeRpcLocal({
|
|
372
400
|
peerDiscoveryQueryBatchSize: this.config.peerDiscoveryQueryBatchSize,
|
|
373
|
-
|
|
374
|
-
return this.peerManager!.getClosestNeighborsTo(nodeId, limit)
|
|
375
|
-
.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor())
|
|
376
|
-
},
|
|
401
|
+
getNeighbors: () => this.peerManager!.getNeighbors().map((n) => n.getPeerDescriptor()),
|
|
377
402
|
getClosestRingContactsTo: (ringIdRaw: RingIdRaw, limit: number) => {
|
|
378
403
|
return this.getClosestRingContactsTo(ringIdRaw, limit)
|
|
379
404
|
},
|
|
@@ -424,24 +449,37 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
424
449
|
}
|
|
425
450
|
}
|
|
426
451
|
|
|
427
|
-
private generatePeerDescriptorCallBack(connectivityResponse: ConnectivityResponse) {
|
|
452
|
+
private async generatePeerDescriptorCallBack(connectivityResponse: ConnectivityResponse) {
|
|
428
453
|
if (this.config.peerDescriptor !== undefined) {
|
|
429
454
|
this.localPeerDescriptor = this.config.peerDescriptor
|
|
430
455
|
} else {
|
|
431
|
-
|
|
456
|
+
let region: number | undefined = undefined
|
|
457
|
+
if (this.config.region !== undefined) {
|
|
458
|
+
region = this.config.region
|
|
459
|
+
logger.debug(`Using region ${region} from config when generating local PeerDescriptor`)
|
|
460
|
+
} else if (connectivityResponse.latitude !== undefined && connectivityResponse.longitude !== undefined) {
|
|
461
|
+
region = getLocalRegionByCoordinates(connectivityResponse.latitude, connectivityResponse.longitude)
|
|
462
|
+
logger.debug(`Using region ${region} from GeoIP when generating local PeerDescriptor`)
|
|
463
|
+
} else {
|
|
464
|
+
// as a fallback get the region from the CDN
|
|
465
|
+
// and if it's not available, use a random region
|
|
466
|
+
region = await getLocalRegionWithCache()
|
|
467
|
+
logger.debug(`Using region ${region} from CDN when generating local PeerDescriptor`)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
this.localPeerDescriptor = createPeerDescriptor(connectivityResponse, region, this.config.nodeId)
|
|
432
471
|
}
|
|
433
472
|
return this.localPeerDescriptor
|
|
434
473
|
}
|
|
435
474
|
|
|
436
475
|
public getClosestContacts(limit?: number): PeerDescriptor[] {
|
|
437
|
-
return this.peerManager!.
|
|
476
|
+
return this.peerManager!.getNearbyContacts()
|
|
438
477
|
.getClosestContacts(limit)
|
|
439
478
|
.map((peer) => peer.getPeerDescriptor())
|
|
440
479
|
}
|
|
441
480
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
return this.peerManager!.getRandomContacts().getContacts().map((c) => c.getPeerDescriptor())
|
|
481
|
+
getRandomContacts(limit?: number): PeerDescriptor[] {
|
|
482
|
+
return this.peerManager!.getRandomContacts().getContacts(limit).map((c) => c.getPeerDescriptor())
|
|
445
483
|
}
|
|
446
484
|
|
|
447
485
|
getRingContacts(): RingContacts {
|
|
@@ -485,7 +523,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
485
523
|
|
|
486
524
|
private getConnectedEntryPoints(): PeerDescriptor[] {
|
|
487
525
|
return this.config.entryPoints !== undefined ? this.config.entryPoints.filter((entryPoint) =>
|
|
488
|
-
this.
|
|
526
|
+
this.connectionsView!.hasConnection(getNodeIdFromPeerDescriptor(entryPoint))
|
|
489
527
|
) : []
|
|
490
528
|
}
|
|
491
529
|
|
|
@@ -560,19 +598,11 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
560
598
|
}
|
|
561
599
|
|
|
562
600
|
public getNeighbors(): PeerDescriptor[] {
|
|
563
|
-
return this.started ? this.peerManager!.getNeighbors() : []
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
public getConnections(): PeerDescriptor[] {
|
|
567
|
-
return this.transport!.getConnections()
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
public getConnectionCount(): number {
|
|
571
|
-
return this.transport!.getConnectionCount()
|
|
601
|
+
return this.started ? this.peerManager!.getNeighbors().map((remote: DhtNodeRpcRemote) => remote.getPeerDescriptor()) : []
|
|
572
602
|
}
|
|
573
603
|
|
|
574
|
-
|
|
575
|
-
return this.
|
|
604
|
+
getConnectionsView(): ConnectionsView {
|
|
605
|
+
return this.connectionsView!
|
|
576
606
|
}
|
|
577
607
|
|
|
578
608
|
public getLocalLockedConnectionCount(): number {
|
|
@@ -586,15 +616,14 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
586
616
|
public getWeakLockedConnectionCount(): number {
|
|
587
617
|
return this.connectionLocker!.getWeakLockedConnectionCount()
|
|
588
618
|
}
|
|
589
|
-
|
|
619
|
+
|
|
590
620
|
public async waitForNetworkConnectivity(): Promise<void> {
|
|
591
|
-
await waitForCondition(
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
}, this.config.networkConnectivityTimeout, 100, this.abortController.signal)
|
|
621
|
+
await waitForCondition(
|
|
622
|
+
() => this.connectionsView!.getConnectionCount() > 0,
|
|
623
|
+
this.config.networkConnectivityTimeout,
|
|
624
|
+
100,
|
|
625
|
+
this.abortController.signal
|
|
626
|
+
)
|
|
598
627
|
}
|
|
599
628
|
|
|
600
629
|
public hasJoined(): boolean {
|
|
@@ -613,7 +642,6 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
613
642
|
this.rpcCommunicator!.stop()
|
|
614
643
|
this.router!.stop()
|
|
615
644
|
this.recursiveOperationManager!.stop()
|
|
616
|
-
this.peerDiscovery!.stop()
|
|
617
645
|
if (this.config.transport === undefined) {
|
|
618
646
|
// if the transport was not given in config, the instance was created in start() and
|
|
619
647
|
// this component is responsible for stopping it
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
2
2
|
import { Logger } from '@streamr/utils'
|
|
3
|
+
import { DhtAddress, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
3
4
|
import { Empty } from '../proto/google/protobuf/empty'
|
|
4
5
|
import {
|
|
5
6
|
ClosestPeersRequest,
|
|
@@ -12,13 +13,13 @@ import {
|
|
|
12
13
|
} from '../proto/packages/dht/protos/DhtRpc'
|
|
13
14
|
import { IDhtNodeRpc } from '../proto/packages/dht/protos/DhtRpc.server'
|
|
14
15
|
import { DhtCallContext } from '../rpc-protocol/DhtCallContext'
|
|
15
|
-
import { DhtAddress, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
16
|
-
import { RingIdRaw } from './contact/ringIdentifiers'
|
|
17
16
|
import { RingContacts } from './contact/RingContactList'
|
|
17
|
+
import { getClosestNodes } from './contact/getClosestNodes'
|
|
18
|
+
import { RingIdRaw } from './contact/ringIdentifiers'
|
|
18
19
|
|
|
19
20
|
interface DhtNodeRpcLocalConfig {
|
|
20
21
|
peerDiscoveryQueryBatchSize: number
|
|
21
|
-
|
|
22
|
+
getNeighbors: () => ReadonlyArray<PeerDescriptor>
|
|
22
23
|
getClosestRingContactsTo: (id: RingIdRaw, limit: number) => RingContacts
|
|
23
24
|
addContact: (contact: PeerDescriptor) => void
|
|
24
25
|
removeContact: (nodeId: DhtAddress) => void
|
|
@@ -34,16 +35,22 @@ export class DhtNodeRpcLocal implements IDhtNodeRpc {
|
|
|
34
35
|
this.config = config
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
// TODO rename to getClosestNeighbors (breaking change)
|
|
37
39
|
async getClosestPeers(request: ClosestPeersRequest, context: ServerCallContext): Promise<ClosestPeersResponse> {
|
|
38
40
|
this.config.addContact((context as DhtCallContext).incomingSourceDescriptor!)
|
|
41
|
+
const peers = getClosestNodes(
|
|
42
|
+
getDhtAddressFromRaw(request.nodeId),
|
|
43
|
+
this.config.getNeighbors(),
|
|
44
|
+
{ maxCount: this.config.peerDiscoveryQueryBatchSize }
|
|
45
|
+
)
|
|
39
46
|
const response = {
|
|
40
|
-
peers
|
|
47
|
+
peers,
|
|
41
48
|
requestId: request.requestId
|
|
42
49
|
}
|
|
43
50
|
return response
|
|
44
51
|
}
|
|
45
52
|
|
|
46
|
-
// TODO rename to getClosestRingContacts
|
|
53
|
+
// TODO rename to getClosestRingContacts (breaking change)
|
|
47
54
|
async getClosestRingPeers(request: ClosestRingPeersRequest, context: ServerCallContext): Promise<ClosestRingPeersResponse> {
|
|
48
55
|
this.config.addContact((context as DhtCallContext).incomingSourceDescriptor!)
|
|
49
56
|
const closestContacts = this.config.getClosestRingContactsTo(request.ringId as RingIdRaw, this.config.peerDiscoveryQueryBatchSize)
|