@streamr/dht 102.0.0-beta.1 → 102.0.0-beta.2
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/generated/google/protobuf/any.d.ts +180 -0
- package/dist/generated/google/protobuf/any.js +155 -0
- package/dist/generated/google/protobuf/any.js.map +1 -0
- package/dist/generated/google/protobuf/empty.d.ts +31 -0
- package/dist/generated/google/protobuf/empty.js +32 -0
- package/dist/generated/google/protobuf/empty.js.map +1 -0
- package/dist/generated/google/protobuf/timestamp.d.ts +155 -0
- package/dist/generated/google/protobuf/timestamp.js +136 -0
- package/dist/generated/google/protobuf/timestamp.js.map +1 -0
- package/dist/generated/packages/dht/protos/DhtRpc.client.d.ts +361 -0
- package/dist/generated/packages/dht/protos/DhtRpc.client.js +285 -0
- package/dist/generated/packages/dht/protos/DhtRpc.client.js.map +1 -0
- package/dist/generated/packages/dht/protos/DhtRpc.d.ts +999 -0
- package/dist/generated/packages/dht/protos/DhtRpc.js +677 -0
- package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -0
- package/dist/generated/packages/dht/protos/DhtRpc.server.d.ts +162 -0
- package/dist/generated/packages/dht/protos/DhtRpc.server.js +3 -0
- package/dist/generated/packages/dht/protos/DhtRpc.server.js.map +1 -0
- package/dist/generated/packages/proto-rpc/protos/ProtoRpc.d.ts +87 -0
- package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js +66 -0
- package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js.map +1 -0
- package/dist/package.json +7 -7
- package/package.json +7 -7
- package/src/connection/Connection.ts +0 -28
- package/src/connection/ConnectionLockRpcLocal.ts +0 -78
- package/src/connection/ConnectionLockRpcRemote.ts +0 -64
- package/src/connection/ConnectionLockStates.ts +0 -131
- package/src/connection/ConnectionManager.ts +0 -661
- package/src/connection/ConnectionsView.ts +0 -8
- package/src/connection/ConnectorFacade.ts +0 -217
- package/src/connection/Handshaker.ts +0 -209
- package/src/connection/IConnection.ts +0 -40
- package/src/connection/ManagedConnection.ts +0 -113
- package/src/connection/OutputBuffer.ts +0 -28
- package/src/connection/PendingConnection.ts +0 -68
- package/src/connection/connectivityChecker.ts +0 -108
- package/src/connection/connectivityRequestHandler.ts +0 -116
- package/src/connection/simulator/Simulator.ts +0 -369
- package/src/connection/simulator/SimulatorConnection.ts +0 -137
- package/src/connection/simulator/SimulatorConnector.ts +0 -98
- package/src/connection/simulator/SimulatorTransport.ts +0 -15
- package/src/connection/simulator/pings.ts +0 -42
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
- package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
- package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -245
- package/src/connection/webrtc/WebrtcConnector.ts +0 -234
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
- package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
- package/src/connection/webrtc/iceServerAsString.ts +0 -15
- package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
- package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
- package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
- package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
- package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
- package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
- package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
- package/src/connection/websocket/WebsocketServer.ts +0 -164
- package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
- package/src/connection/websocket/WebsocketServerConnector.ts +0 -290
- package/src/dht/DhtNode.ts +0 -683
- package/src/dht/DhtNodeRpcLocal.ts +0 -84
- package/src/dht/DhtNodeRpcRemote.ts +0 -107
- package/src/dht/ExternalApiRpcLocal.ts +0 -58
- package/src/dht/ExternalApiRpcRemote.ts +0 -41
- package/src/dht/PeerManager.ts +0 -305
- package/src/dht/contact/Contact.ts +0 -19
- package/src/dht/contact/ContactList.ts +0 -43
- package/src/dht/contact/RandomContactList.ts +0 -56
- package/src/dht/contact/RingContactList.ts +0 -143
- package/src/dht/contact/RpcRemote.ts +0 -72
- package/src/dht/contact/SortedContactList.ts +0 -173
- package/src/dht/contact/getClosestNodes.ts +0 -24
- package/src/dht/contact/ringIdentifiers.ts +0 -62
- package/src/dht/discovery/DiscoverySession.ts +0 -129
- package/src/dht/discovery/PeerDiscovery.ts +0 -244
- package/src/dht/discovery/RingDiscoverySession.ts +0 -148
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
- package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
- package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
- package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
- package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
- package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
- package/src/dht/routing/DuplicateDetector.ts +0 -34
- package/src/dht/routing/Router.ts +0 -246
- package/src/dht/routing/RouterRpcLocal.ts +0 -78
- package/src/dht/routing/RouterRpcRemote.ts +0 -80
- package/src/dht/routing/RoutingSession.ts +0 -243
- package/src/dht/routing/RoutingTablesCache.ts +0 -60
- package/src/dht/routing/getPreviousPeer.ts +0 -6
- package/src/dht/store/LocalDataStore.ts +0 -84
- package/src/dht/store/StoreManager.ts +0 -170
- package/src/dht/store/StoreRpcLocal.ts +0 -89
- package/src/dht/store/StoreRpcRemote.ts +0 -32
- package/src/exports.ts +0 -33
- package/src/helpers/AddressTools.ts +0 -28
- package/src/helpers/Connectivity.ts +0 -19
- package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
- package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
- package/src/helpers/createPeerDescriptor.ts +0 -57
- package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
- package/src/helpers/debugHelpers.ts +0 -9
- package/src/helpers/errors.ts +0 -49
- package/src/helpers/offering.ts +0 -15
- package/src/helpers/protoClasses.ts +0 -57
- package/src/helpers/protoToString.ts +0 -21
- package/src/helpers/version.ts +0 -32
- package/src/identifiers.ts +0 -29
- package/src/rpc-protocol/DhtCallContext.ts +0 -14
- package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
- package/src/transport/ITransport.ts +0 -37
- package/src/transport/ListeningRpcCommunicator.ts +0 -32
- package/src/transport/RoutingRpcCommunicator.ts +0 -66
- package/src/types/ServiceID.ts +0 -1
- package/src/types/textencoding.d.ts +0 -6
- package/test/benchmark/Find.test.ts +0 -72
- package/test/benchmark/KademliaCorrectness.test.ts +0 -114
- package/test/benchmark/RingCorrectness.test.ts +0 -157
- package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
- package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
- package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
- package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
- package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
- package/test/end-to-end/Layer0.test.ts +0 -76
- package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
- package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
- package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
- package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
- package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
- package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
- package/test/end-to-end/memory-leak.test.ts +0 -80
- package/test/integration/ConnectionLocking.test.ts +0 -192
- package/test/integration/ConnectionManager.test.ts +0 -528
- package/test/integration/ConnectivityChecking.test.ts +0 -53
- package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
- package/test/integration/DhtNode.test.ts +0 -66
- package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
- package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
- package/test/integration/DhtRpc.test.ts +0 -121
- package/test/integration/Find.test.ts +0 -45
- package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
- package/test/integration/Layer1-scale.test.ts +0 -189
- package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
- package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
- package/test/integration/ReplicateData.test.ts +0 -104
- package/test/integration/RouteMessage.test.ts +0 -230
- package/test/integration/RouterRpcRemote.test.ts +0 -77
- package/test/integration/SimultaneousConnections.test.ts +0 -316
- package/test/integration/Store.test.ts +0 -85
- package/test/integration/StoreAndDelete.test.ts +0 -77
- package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
- package/test/integration/StoreRpcRemote.test.ts +0 -54
- package/test/integration/WebrtcConnectionManagement.test.ts +0 -191
- package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
- package/test/integration/Websocket.test.ts +0 -65
- package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
- package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
- package/test/integration/rpc-connections-over-webrtc.test.ts +0 -123
- package/test/kademlia-simulation/data/nodeids.json +0 -13002
- package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
- package/test/types/global.d.ts +0 -1
- package/test/unit/AddressTools.test.ts +0 -44
- package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
- package/test/unit/ConnectionManager.test.ts +0 -65
- package/test/unit/ConnectivityHelpers.test.ts +0 -61
- package/test/unit/DiscoverySession.test.ts +0 -87
- package/test/unit/DuplicateDetector.test.ts +0 -31
- package/test/unit/Handshaker.test.ts +0 -169
- package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
- package/test/unit/LocalDataStore.test.ts +0 -108
- package/test/unit/ManagedConnection.test.ts +0 -58
- package/test/unit/PeerManager.test.ts +0 -93
- package/test/unit/PendingConnection.test.ts +0 -57
- package/test/unit/ProtobufMessage.test.ts +0 -21
- package/test/unit/RandomContactList.test.ts +0 -58
- package/test/unit/RecursiveOperationManager.test.ts +0 -161
- package/test/unit/RecursiveOperationSession.test.ts +0 -68
- package/test/unit/Router.test.ts +0 -137
- package/test/unit/RoutingSession.test.ts +0 -86
- package/test/unit/SortedContactList.test.ts +0 -115
- package/test/unit/StoreManager.test.ts +0 -146
- package/test/unit/StoreRpcLocal.test.ts +0 -167
- package/test/unit/WebrtcConnection.test.ts +0 -29
- package/test/unit/WebrtcConnector.test.ts +0 -56
- package/test/unit/WebsocketClientConnector.test.ts +0 -101
- package/test/unit/WebsocketServer.test.ts +0 -66
- package/test/unit/WebsocketServerConnector.test.ts +0 -102
- package/test/unit/connectivityRequestHandler.test.ts +0 -104
- package/test/unit/createPeerDescriptor.test.ts +0 -69
- package/test/unit/customMatchers.test.ts +0 -34
- package/test/unit/getClosestNodes.test.ts +0 -30
- package/test/unit/version.test.ts +0 -18
- package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
- package/test/utils/FakeConnectorFacade.ts +0 -41
- package/test/utils/FakeRpcCommunicator.ts +0 -23
- package/test/utils/FakeTransport.ts +0 -79
- package/test/utils/customMatchers.ts +0 -71
- package/test/utils/mock/MockConnection.ts +0 -26
- package/test/utils/mock/MockConnectionsView.ts +0 -18
- package/test/utils/mock/MockRouter.ts +0 -62
- package/test/utils/mock/MockRpcCommunicator.ts +0 -7
- package/test/utils/mock/MockTransport.ts +0 -26
- package/test/utils/mock/mockDataEntry.ts +0 -38
- package/test/utils/topology.ts +0 -79
- package/test/utils/utils.ts +0 -268
- package/tsconfig.browser.json +0 -17
- package/tsconfig.jest.json +0 -25
- package/tsconfig.json +0 -3
- package/tsconfig.node.json +0 -24
package/src/dht/DhtNode.ts
DELETED
|
@@ -1,683 +0,0 @@
|
|
|
1
|
-
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
2
|
-
import {
|
|
3
|
-
Logger,
|
|
4
|
-
MetricsContext,
|
|
5
|
-
merge,
|
|
6
|
-
scheduleAtInterval,
|
|
7
|
-
until
|
|
8
|
-
} from '@streamr/utils'
|
|
9
|
-
import { EventEmitter } from 'eventemitter3'
|
|
10
|
-
import { sample } from 'lodash'
|
|
11
|
-
import type { MarkRequired } from 'ts-essentials'
|
|
12
|
-
import { ConnectionLocker, ConnectionManager, PortRange, TlsCertificate } from '../connection/ConnectionManager'
|
|
13
|
-
import { ConnectionsView } from '../connection/ConnectionsView'
|
|
14
|
-
import { DefaultConnectorFacade, DefaultConnectorFacadeOptions } from '../connection/ConnectorFacade'
|
|
15
|
-
import { IceServer } from '../connection/webrtc/WebrtcConnector'
|
|
16
|
-
import { isBrowserEnvironment } from '../helpers/browser/isBrowserEnvironment'
|
|
17
|
-
import { createPeerDescriptor } from '../helpers/createPeerDescriptor'
|
|
18
|
-
import { DhtAddress, KADEMLIA_ID_LENGTH_IN_BYTES, toNodeId } from '../identifiers'
|
|
19
|
-
import { Any } from '../../generated/google/protobuf/any'
|
|
20
|
-
import {
|
|
21
|
-
ClosestPeersRequest,
|
|
22
|
-
ClosestPeersResponse,
|
|
23
|
-
ClosestRingPeersRequest,
|
|
24
|
-
ClosestRingPeersResponse,
|
|
25
|
-
ConnectivityResponse,
|
|
26
|
-
DataEntry,
|
|
27
|
-
ExternalFetchDataRequest,
|
|
28
|
-
ExternalFetchDataResponse,
|
|
29
|
-
ExternalStoreDataRequest,
|
|
30
|
-
ExternalStoreDataResponse,
|
|
31
|
-
LeaveNotice,
|
|
32
|
-
Message,
|
|
33
|
-
PeerDescriptor,
|
|
34
|
-
PingRequest,
|
|
35
|
-
PingResponse,
|
|
36
|
-
RecursiveOperation
|
|
37
|
-
} from '../../generated/packages/dht/protos/DhtRpc'
|
|
38
|
-
import { ExternalApiRpcClient, StoreRpcClient } from '../../generated/packages/dht/protos/DhtRpc.client'
|
|
39
|
-
import { ITransport, TransportEvents } from '../transport/ITransport'
|
|
40
|
-
import { RoutingRpcCommunicator } from '../transport/RoutingRpcCommunicator'
|
|
41
|
-
import { ServiceID } from '../types/ServiceID'
|
|
42
|
-
import { DhtNodeRpcLocal } from './DhtNodeRpcLocal'
|
|
43
|
-
import { DhtNodeRpcRemote } from './DhtNodeRpcRemote'
|
|
44
|
-
import { ExternalApiRpcLocal } from './ExternalApiRpcLocal'
|
|
45
|
-
import { ExternalApiRpcRemote } from './ExternalApiRpcRemote'
|
|
46
|
-
import { PeerManager } from './PeerManager'
|
|
47
|
-
import { RingContacts } from './contact/RingContactList'
|
|
48
|
-
import { RingIdRaw } from './contact/ringIdentifiers'
|
|
49
|
-
import { PeerDiscovery } from './discovery/PeerDiscovery'
|
|
50
|
-
import { RecursiveOperationManager } from './recursive-operation/RecursiveOperationManager'
|
|
51
|
-
import { Router } from './routing/Router'
|
|
52
|
-
import { LocalDataStore } from './store/LocalDataStore'
|
|
53
|
-
import { StoreManager } from './store/StoreManager'
|
|
54
|
-
import { StoreRpcRemote } from './store/StoreRpcRemote'
|
|
55
|
-
import { getLocalRegionByCoordinates, getLocalRegionWithCache } from '@streamr/cdn-location'
|
|
56
|
-
|
|
57
|
-
export interface DhtNodeEvents {
|
|
58
|
-
nearbyContactAdded: (peerDescriptor: PeerDescriptor) => void
|
|
59
|
-
nearbyContactRemoved: (peerDescriptor: PeerDescriptor) => void
|
|
60
|
-
randomContactAdded: (peerDescriptor: PeerDescriptor) => void
|
|
61
|
-
randomContactRemoved: (peerDescriptor: PeerDescriptor) => void
|
|
62
|
-
ringContactAdded: (peerDescriptor: PeerDescriptor) => void
|
|
63
|
-
ringContactRemoved: (peerDescriptor: PeerDescriptor) => void
|
|
64
|
-
manualRejoinRequired: () => void
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface DhtNodeOptions {
|
|
68
|
-
serviceId?: ServiceID
|
|
69
|
-
joinParallelism?: number
|
|
70
|
-
maxContactCount?: number
|
|
71
|
-
numberOfNodesPerKBucket?: number
|
|
72
|
-
joinNoProgressLimit?: number
|
|
73
|
-
peerDiscoveryQueryBatchSize?: number
|
|
74
|
-
dhtJoinTimeout?: number
|
|
75
|
-
metricsContext?: MetricsContext
|
|
76
|
-
storeHighestTtl?: number
|
|
77
|
-
storeMaxTtl?: number
|
|
78
|
-
networkConnectivityTimeout?: number
|
|
79
|
-
storageRedundancyFactor?: number
|
|
80
|
-
periodicallyPingNeighbors?: boolean
|
|
81
|
-
periodicallyPingRingContacts?: boolean
|
|
82
|
-
// Limit for how many new neighbors to ping. If number of neighbors is higher than the limit new neighbors
|
|
83
|
-
// are not pinged when they are added. This is to prevent flooding the network with pings when joining.
|
|
84
|
-
// Enable periodicallyPingNeighbors to eventually ping all neighbors.
|
|
85
|
-
neighborPingLimit?: number
|
|
86
|
-
|
|
87
|
-
transport?: ITransport
|
|
88
|
-
connectionsView?: ConnectionsView
|
|
89
|
-
connectionLocker?: ConnectionLocker
|
|
90
|
-
peerDescriptor?: PeerDescriptor
|
|
91
|
-
entryPoints?: PeerDescriptor[]
|
|
92
|
-
websocketHost?: string
|
|
93
|
-
websocketPortRange?: PortRange
|
|
94
|
-
websocketServerEnableTls?: boolean
|
|
95
|
-
nodeId?: DhtAddress
|
|
96
|
-
region?: number
|
|
97
|
-
|
|
98
|
-
rpcRequestTimeout?: number
|
|
99
|
-
iceServers?: IceServer[]
|
|
100
|
-
webrtcAllowPrivateAddresses?: boolean
|
|
101
|
-
webrtcDatachannelBufferThresholdLow?: number
|
|
102
|
-
webrtcDatachannelBufferThresholdHigh?: number
|
|
103
|
-
webrtcPortRange?: PortRange
|
|
104
|
-
maxMessageSize?: number
|
|
105
|
-
maxConnections?: number
|
|
106
|
-
tlsCertificate?: TlsCertificate
|
|
107
|
-
externalIp?: string
|
|
108
|
-
autoCertifierUrl?: string
|
|
109
|
-
autoCertifierConfigFile?: string
|
|
110
|
-
geoIpDatabaseFolder?: string
|
|
111
|
-
allowIncomingPrivateConnections?: boolean
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
type StrictDhtNodeOptions = MarkRequired<DhtNodeOptions,
|
|
115
|
-
'serviceId' |
|
|
116
|
-
'joinParallelism' |
|
|
117
|
-
'maxContactCount' |
|
|
118
|
-
'numberOfNodesPerKBucket' |
|
|
119
|
-
'joinNoProgressLimit' |
|
|
120
|
-
'dhtJoinTimeout' |
|
|
121
|
-
'peerDiscoveryQueryBatchSize' |
|
|
122
|
-
'maxConnections' |
|
|
123
|
-
'storeHighestTtl' |
|
|
124
|
-
'storeMaxTtl' |
|
|
125
|
-
'networkConnectivityTimeout' |
|
|
126
|
-
'storageRedundancyFactor' |
|
|
127
|
-
'metricsContext'>
|
|
128
|
-
|
|
129
|
-
const logger = new Logger(module)
|
|
130
|
-
|
|
131
|
-
const PERIODICAL_PING_INTERVAL = 60 * 1000
|
|
132
|
-
|
|
133
|
-
// TODO move this to trackerless-network package and change serviceId to be a required paramater
|
|
134
|
-
export const CONTROL_LAYER_NODE_SERVICE_ID = 'layer0'
|
|
135
|
-
|
|
136
|
-
export type Events = TransportEvents & DhtNodeEvents
|
|
137
|
-
|
|
138
|
-
export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
139
|
-
|
|
140
|
-
private readonly options: StrictDhtNodeOptions
|
|
141
|
-
private rpcCommunicator?: RoutingRpcCommunicator
|
|
142
|
-
private transport?: ITransport
|
|
143
|
-
private localPeerDescriptor?: PeerDescriptor
|
|
144
|
-
private router?: Router
|
|
145
|
-
private storeManager?: StoreManager
|
|
146
|
-
private localDataStore: LocalDataStore
|
|
147
|
-
private recursiveOperationManager?: RecursiveOperationManager
|
|
148
|
-
private peerDiscovery?: PeerDiscovery
|
|
149
|
-
private peerManager?: PeerManager
|
|
150
|
-
private connectionsView?: ConnectionsView
|
|
151
|
-
public connectionLocker?: ConnectionLocker
|
|
152
|
-
private started = false
|
|
153
|
-
private abortController = new AbortController()
|
|
154
|
-
|
|
155
|
-
constructor(conf: DhtNodeOptions) {
|
|
156
|
-
super()
|
|
157
|
-
this.options = merge({
|
|
158
|
-
serviceId: CONTROL_LAYER_NODE_SERVICE_ID,
|
|
159
|
-
joinParallelism: 3,
|
|
160
|
-
maxContactCount: 200,
|
|
161
|
-
numberOfNodesPerKBucket: 8,
|
|
162
|
-
joinNoProgressLimit: 5,
|
|
163
|
-
dhtJoinTimeout: 60000,
|
|
164
|
-
peerDiscoveryQueryBatchSize: 5,
|
|
165
|
-
maxConnections: 80,
|
|
166
|
-
storeHighestTtl: 60000,
|
|
167
|
-
storeMaxTtl: 60000,
|
|
168
|
-
networkConnectivityTimeout: 10000,
|
|
169
|
-
storageRedundancyFactor: 5, // TODO validate that this is > 1 (as each node should replicate the data to other node)
|
|
170
|
-
metricsContext: new MetricsContext()
|
|
171
|
-
}, conf)
|
|
172
|
-
this.validateOptions()
|
|
173
|
-
this.localDataStore = new LocalDataStore(this.options.storeMaxTtl)
|
|
174
|
-
this.send = this.send.bind(this)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
private validateOptions(): void {
|
|
178
|
-
const expectedNodeIdLength = KADEMLIA_ID_LENGTH_IN_BYTES * 2
|
|
179
|
-
if (this.options.nodeId !== undefined) {
|
|
180
|
-
if (!/^[0-9a-fA-F]+$/.test(this.options.nodeId)) {
|
|
181
|
-
throw new Error('Invalid nodeId, the nodeId should be a hex string')
|
|
182
|
-
} else if (this.options.nodeId.length !== expectedNodeIdLength) {
|
|
183
|
-
throw new Error(`Invalid nodeId, the length of the nodeId should be ${expectedNodeIdLength}`)
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
if (this.options.peerDescriptor !== undefined) {
|
|
187
|
-
if (this.options.peerDescriptor.nodeId.length !== KADEMLIA_ID_LENGTH_IN_BYTES) {
|
|
188
|
-
throw new Error(`Invalid peerDescriptor, the length of the nodeId should be ${KADEMLIA_ID_LENGTH_IN_BYTES} bytes`)
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
if (this.options.transport !== undefined && this.options.connectionsView === undefined) {
|
|
192
|
-
throw new Error('connectionsView is required when transport is given')
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
public async start(): Promise<void> {
|
|
197
|
-
if (this.started || this.abortController.signal.aborted) {
|
|
198
|
-
return
|
|
199
|
-
}
|
|
200
|
-
logger.trace(`Starting new Streamr Network DHT Node with serviceId ${this.options.serviceId}`)
|
|
201
|
-
this.started = true
|
|
202
|
-
|
|
203
|
-
if (isBrowserEnvironment()) {
|
|
204
|
-
this.options.websocketPortRange = undefined
|
|
205
|
-
if (this.options.peerDescriptor) {
|
|
206
|
-
this.options.peerDescriptor.websocket = undefined
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// If transport is given, do not create a ConnectionManager
|
|
211
|
-
if (this.options.transport) {
|
|
212
|
-
this.transport = this.options.transport
|
|
213
|
-
this.connectionsView = this.options.connectionsView
|
|
214
|
-
this.connectionLocker = this.options.connectionLocker
|
|
215
|
-
this.localPeerDescriptor = this.transport.getLocalPeerDescriptor()
|
|
216
|
-
} else {
|
|
217
|
-
const connectorFacadeOptions: DefaultConnectorFacadeOptions = {
|
|
218
|
-
transport: this,
|
|
219
|
-
entryPoints: this.options.entryPoints,
|
|
220
|
-
iceServers: this.options.iceServers,
|
|
221
|
-
webrtcAllowPrivateAddresses: this.options.webrtcAllowPrivateAddresses,
|
|
222
|
-
webrtcDatachannelBufferThresholdLow: this.options.webrtcDatachannelBufferThresholdLow,
|
|
223
|
-
webrtcDatachannelBufferThresholdHigh: this.options.webrtcDatachannelBufferThresholdHigh,
|
|
224
|
-
webrtcPortRange: this.options.webrtcPortRange,
|
|
225
|
-
maxMessageSize: this.options.maxMessageSize,
|
|
226
|
-
websocketServerEnableTls: this.options.websocketServerEnableTls,
|
|
227
|
-
tlsCertificate: this.options.tlsCertificate,
|
|
228
|
-
externalIp: this.options.externalIp,
|
|
229
|
-
autoCertifierUrl: this.options.autoCertifierUrl,
|
|
230
|
-
autoCertifierConfigFile: this.options.autoCertifierConfigFile,
|
|
231
|
-
geoIpDatabaseFolder: this.options.geoIpDatabaseFolder,
|
|
232
|
-
createLocalPeerDescriptor: (connectivityResponse: ConnectivityResponse) => this.generatePeerDescriptorCallBack(connectivityResponse)
|
|
233
|
-
}
|
|
234
|
-
// If own PeerDescriptor is given in options, create a ConnectionManager with ws server
|
|
235
|
-
if (this.options.peerDescriptor?.websocket) {
|
|
236
|
-
connectorFacadeOptions.websocketHost = this.options.peerDescriptor.websocket.host
|
|
237
|
-
connectorFacadeOptions.websocketPortRange = {
|
|
238
|
-
min: this.options.peerDescriptor.websocket.port,
|
|
239
|
-
max: this.options.peerDescriptor.websocket.port
|
|
240
|
-
}
|
|
241
|
-
// If websocketPortRange is given, create ws server using it, websocketHost can be undefined
|
|
242
|
-
} else if (this.options.websocketPortRange) {
|
|
243
|
-
connectorFacadeOptions.websocketHost = this.options.websocketHost
|
|
244
|
-
connectorFacadeOptions.websocketPortRange = this.options.websocketPortRange
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const connectionManager = new ConnectionManager({
|
|
248
|
-
createConnectorFacade: () => new DefaultConnectorFacade(connectorFacadeOptions),
|
|
249
|
-
maxConnections: this.options.maxConnections,
|
|
250
|
-
metricsContext: this.options.metricsContext,
|
|
251
|
-
allowIncomingPrivateConnections: this.options.allowIncomingPrivateConnections ?? false
|
|
252
|
-
})
|
|
253
|
-
await connectionManager.start()
|
|
254
|
-
this.connectionsView = connectionManager
|
|
255
|
-
this.connectionLocker = connectionManager
|
|
256
|
-
this.transport = connectionManager
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
this.rpcCommunicator = new RoutingRpcCommunicator(
|
|
260
|
-
this.options.serviceId,
|
|
261
|
-
(msg, opts) => this.transport!.send(msg, opts),
|
|
262
|
-
{ rpcRequestTimeout: this.options.rpcRequestTimeout }
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
this.transport.on('message', (message: Message) => this.handleMessageFromTransport(message))
|
|
266
|
-
|
|
267
|
-
this.initPeerManager()
|
|
268
|
-
|
|
269
|
-
this.peerDiscovery = new PeerDiscovery({
|
|
270
|
-
localPeerDescriptor: this.localPeerDescriptor!,
|
|
271
|
-
joinNoProgressLimit: this.options.joinNoProgressLimit,
|
|
272
|
-
joinTimeout: this.options.dhtJoinTimeout,
|
|
273
|
-
serviceId: this.options.serviceId,
|
|
274
|
-
parallelism: this.options.joinParallelism,
|
|
275
|
-
connectionLocker: this.connectionLocker,
|
|
276
|
-
peerManager: this.peerManager!,
|
|
277
|
-
abortSignal: this.abortController.signal,
|
|
278
|
-
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor),
|
|
279
|
-
})
|
|
280
|
-
this.router = new Router({
|
|
281
|
-
rpcCommunicator: this.rpcCommunicator,
|
|
282
|
-
localPeerDescriptor: this.localPeerDescriptor!,
|
|
283
|
-
handleMessage: (message: Message) => this.handleMessageFromRouter(message),
|
|
284
|
-
getConnections: () => this.connectionsView!.getConnections()
|
|
285
|
-
})
|
|
286
|
-
this.recursiveOperationManager = new RecursiveOperationManager({
|
|
287
|
-
rpcCommunicator: this.rpcCommunicator,
|
|
288
|
-
router: this.router,
|
|
289
|
-
sessionTransport: this,
|
|
290
|
-
connectionsView: this.connectionsView!,
|
|
291
|
-
localPeerDescriptor: this.localPeerDescriptor!,
|
|
292
|
-
serviceId: this.options.serviceId,
|
|
293
|
-
localDataStore: this.localDataStore,
|
|
294
|
-
addContact: (contact: PeerDescriptor) => this.peerManager!.addContact(contact),
|
|
295
|
-
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor),
|
|
296
|
-
})
|
|
297
|
-
this.storeManager = new StoreManager({
|
|
298
|
-
rpcCommunicator: this.rpcCommunicator,
|
|
299
|
-
recursiveOperationManager: this.recursiveOperationManager,
|
|
300
|
-
localPeerDescriptor: this.localPeerDescriptor!,
|
|
301
|
-
serviceId: this.options.serviceId,
|
|
302
|
-
highestTtl: this.options.storeHighestTtl,
|
|
303
|
-
redundancyFactor: this.options.storageRedundancyFactor,
|
|
304
|
-
localDataStore: this.localDataStore,
|
|
305
|
-
getNeighbors: () => this.peerManager!.getNeighbors().map((n) => n.getPeerDescriptor()),
|
|
306
|
-
createRpcRemote: (contact: PeerDescriptor) => {
|
|
307
|
-
return new StoreRpcRemote(
|
|
308
|
-
this.localPeerDescriptor!,
|
|
309
|
-
contact,
|
|
310
|
-
this.rpcCommunicator!,
|
|
311
|
-
StoreRpcClient,
|
|
312
|
-
this.options.rpcRequestTimeout
|
|
313
|
-
)
|
|
314
|
-
}
|
|
315
|
-
})
|
|
316
|
-
this.on('nearbyContactAdded', (peerDescriptor: PeerDescriptor) => {
|
|
317
|
-
this.storeManager!.onContactAdded(peerDescriptor)
|
|
318
|
-
})
|
|
319
|
-
this.bindRpcLocalMethods()
|
|
320
|
-
|
|
321
|
-
const pruneTargets = []
|
|
322
|
-
if (this.options.periodicallyPingNeighbors === true) {
|
|
323
|
-
pruneTargets.push(() => this.peerManager!.getNeighbors().map((node) => this.createDhtNodeRpcRemote(node.getPeerDescriptor())))
|
|
324
|
-
}
|
|
325
|
-
if (this.options.periodicallyPingRingContacts === true) {
|
|
326
|
-
pruneTargets.push(() => this.peerManager!.getRingContacts().getAllContacts())
|
|
327
|
-
}
|
|
328
|
-
for (const pruneTarget of pruneTargets) {
|
|
329
|
-
await scheduleAtInterval(
|
|
330
|
-
async () => {
|
|
331
|
-
const nodes = pruneTarget()
|
|
332
|
-
await this.peerManager!.pruneOfflineNodes(nodes)
|
|
333
|
-
}, PERIODICAL_PING_INTERVAL, false, this.abortController.signal
|
|
334
|
-
)
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
private initPeerManager() {
|
|
339
|
-
this.peerManager = new PeerManager({
|
|
340
|
-
numberOfNodesPerKBucket: this.options.numberOfNodesPerKBucket,
|
|
341
|
-
maxContactCount: this.options.maxContactCount,
|
|
342
|
-
localNodeId: this.getNodeId(),
|
|
343
|
-
localPeerDescriptor: this.localPeerDescriptor!,
|
|
344
|
-
connectionLocker: this.connectionLocker,
|
|
345
|
-
lockId: this.options.serviceId,
|
|
346
|
-
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor),
|
|
347
|
-
hasConnection: (nodeId: DhtAddress) => this.connectionsView!.hasConnection(nodeId),
|
|
348
|
-
neighborPingLimit: this.options.neighborPingLimit
|
|
349
|
-
})
|
|
350
|
-
this.peerManager.on('nearbyContactRemoved', (peerDescriptor: PeerDescriptor) => {
|
|
351
|
-
this.emit('nearbyContactRemoved', peerDescriptor)
|
|
352
|
-
})
|
|
353
|
-
this.peerManager.on('nearbyContactAdded', (peerDescriptor: PeerDescriptor) =>
|
|
354
|
-
this.emit('nearbyContactAdded', peerDescriptor)
|
|
355
|
-
)
|
|
356
|
-
this.peerManager.on('randomContactRemoved', (peerDescriptor: PeerDescriptor) =>
|
|
357
|
-
this.emit('randomContactRemoved', peerDescriptor)
|
|
358
|
-
)
|
|
359
|
-
this.peerManager.on('randomContactAdded', (peerDescriptor: PeerDescriptor) =>
|
|
360
|
-
this.emit('randomContactAdded', peerDescriptor)
|
|
361
|
-
)
|
|
362
|
-
this.peerManager.on('ringContactRemoved', (peerDescriptor: PeerDescriptor) => {
|
|
363
|
-
this.emit('ringContactRemoved', peerDescriptor)
|
|
364
|
-
})
|
|
365
|
-
this.peerManager.on('ringContactAdded', (peerDescriptor: PeerDescriptor) => {
|
|
366
|
-
this.emit('ringContactAdded', peerDescriptor)
|
|
367
|
-
})
|
|
368
|
-
this.peerManager.on('kBucketEmpty', () => {
|
|
369
|
-
if (!this.peerDiscovery!.isJoinOngoing()) {
|
|
370
|
-
if (this.options.entryPoints && this.options.entryPoints.length > 0) {
|
|
371
|
-
setImmediate(async () => {
|
|
372
|
-
const contactedPeers = new Set<DhtAddress>()
|
|
373
|
-
const distantJoinContactPeers = new Set<DhtAddress>()
|
|
374
|
-
// TODO should we catch possible promise rejection?
|
|
375
|
-
await Promise.all(this.options.entryPoints!.map((entryPoint) =>
|
|
376
|
-
this.peerDiscovery!.rejoinDht(entryPoint, contactedPeers, distantJoinContactPeers)
|
|
377
|
-
))
|
|
378
|
-
})
|
|
379
|
-
} else {
|
|
380
|
-
this.emit('manualRejoinRequired')
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
})
|
|
384
|
-
this.transport!.on('connected', (peerDescriptor: PeerDescriptor) => {
|
|
385
|
-
this.router!.onNodeConnected(peerDescriptor)
|
|
386
|
-
this.emit('connected', peerDescriptor)
|
|
387
|
-
})
|
|
388
|
-
this.transport!.on('disconnected', (peerDescriptor: PeerDescriptor, gracefulLeave: boolean) => {
|
|
389
|
-
const isControlLayerNode = (this.connectionLocker !== undefined)
|
|
390
|
-
if (isControlLayerNode) {
|
|
391
|
-
const nodeId = toNodeId(peerDescriptor)
|
|
392
|
-
if (gracefulLeave) {
|
|
393
|
-
this.peerManager!.removeContact(nodeId)
|
|
394
|
-
} else {
|
|
395
|
-
this.peerManager!.removeNeighbor(nodeId)
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
this.router!.onNodeDisconnected(peerDescriptor)
|
|
399
|
-
this.emit('disconnected', peerDescriptor, gracefulLeave)
|
|
400
|
-
})
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
private bindRpcLocalMethods(): void {
|
|
404
|
-
if (!this.started || this.abortController.signal.aborted) {
|
|
405
|
-
return
|
|
406
|
-
}
|
|
407
|
-
const dhtNodeRpcLocal = new DhtNodeRpcLocal({
|
|
408
|
-
peerDiscoveryQueryBatchSize: this.options.peerDiscoveryQueryBatchSize,
|
|
409
|
-
getNeighbors: () => this.peerManager!.getNeighbors().map((n) => n.getPeerDescriptor()),
|
|
410
|
-
getClosestRingContactsTo: (ringIdRaw: RingIdRaw, limit: number) => {
|
|
411
|
-
return this.getClosestRingContactsTo(ringIdRaw, limit)
|
|
412
|
-
},
|
|
413
|
-
addContact: (contact: PeerDescriptor) => this.peerManager!.addContact(contact),
|
|
414
|
-
removeContact: (nodeId: DhtAddress) => this.removeContact(nodeId)
|
|
415
|
-
})
|
|
416
|
-
this.rpcCommunicator!.registerRpcMethod(ClosestPeersRequest, ClosestPeersResponse, 'getClosestPeers',
|
|
417
|
-
(req: ClosestPeersRequest, context) => dhtNodeRpcLocal.getClosestPeers(req, context))
|
|
418
|
-
this.rpcCommunicator!.registerRpcMethod(ClosestRingPeersRequest, ClosestRingPeersResponse, 'getClosestRingPeers',
|
|
419
|
-
(req: ClosestRingPeersRequest, context) => dhtNodeRpcLocal.getClosestRingPeers(req, context))
|
|
420
|
-
this.rpcCommunicator!.registerRpcMethod(PingRequest, PingResponse, 'ping',
|
|
421
|
-
(req: PingRequest, context) => dhtNodeRpcLocal.ping(req, context))
|
|
422
|
-
this.rpcCommunicator!.registerRpcNotification(LeaveNotice, 'leaveNotice',
|
|
423
|
-
(_req: LeaveNotice, context) => dhtNodeRpcLocal.leaveNotice(context))
|
|
424
|
-
const externalApiRpcLocal = new ExternalApiRpcLocal({
|
|
425
|
-
executeRecursiveOperation: (key: DhtAddress, operation: RecursiveOperation, excludedPeer: DhtAddress) => {
|
|
426
|
-
return this.recursiveOperationManager!.execute(key, operation, excludedPeer)
|
|
427
|
-
},
|
|
428
|
-
storeDataToDht: (key: DhtAddress, data: Any, creator?: DhtAddress) => this.storeDataToDht(key, data, creator)
|
|
429
|
-
})
|
|
430
|
-
this.rpcCommunicator!.registerRpcMethod(
|
|
431
|
-
ExternalFetchDataRequest,
|
|
432
|
-
ExternalFetchDataResponse,
|
|
433
|
-
'externalFetchData',
|
|
434
|
-
(req: ExternalFetchDataRequest, context: ServerCallContext) => externalApiRpcLocal.externalFetchData(req, context),
|
|
435
|
-
{ timeout: 10000 } // TODO use options option or named constant?
|
|
436
|
-
)
|
|
437
|
-
this.rpcCommunicator!.registerRpcMethod(
|
|
438
|
-
ExternalStoreDataRequest,
|
|
439
|
-
ExternalStoreDataResponse,
|
|
440
|
-
'externalStoreData',
|
|
441
|
-
(req: ExternalStoreDataRequest, context: ServerCallContext) => externalApiRpcLocal.externalStoreData(req, context),
|
|
442
|
-
{ timeout: 10000 } // TODO use options option or named constant?
|
|
443
|
-
)
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
private handleMessageFromTransport(message: Message): void {
|
|
447
|
-
if (message.serviceId === this.options.serviceId) {
|
|
448
|
-
this.rpcCommunicator?.handleMessageFromPeer(message)
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
private handleMessageFromRouter(message: Message): void {
|
|
453
|
-
if (message.serviceId === this.options.serviceId) {
|
|
454
|
-
this.rpcCommunicator?.handleMessageFromPeer(message)
|
|
455
|
-
} else {
|
|
456
|
-
this.emit('message', message)
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
private async generatePeerDescriptorCallBack(connectivityResponse: ConnectivityResponse) {
|
|
461
|
-
if (this.options.peerDescriptor !== undefined) {
|
|
462
|
-
this.localPeerDescriptor = this.options.peerDescriptor
|
|
463
|
-
} else {
|
|
464
|
-
let region: number | undefined = undefined
|
|
465
|
-
if (this.options.region !== undefined) {
|
|
466
|
-
region = this.options.region
|
|
467
|
-
logger.debug(`Using region ${region} from options when generating local PeerDescriptor`)
|
|
468
|
-
} else if (connectivityResponse.latitude !== undefined && connectivityResponse.longitude !== undefined) {
|
|
469
|
-
region = getLocalRegionByCoordinates(connectivityResponse.latitude, connectivityResponse.longitude)
|
|
470
|
-
logger.debug(`Using region ${region} from GeoIP when generating local PeerDescriptor`)
|
|
471
|
-
} else {
|
|
472
|
-
// as a fallback get the region from the CDN
|
|
473
|
-
// and if it's not available, use a random region
|
|
474
|
-
region = await getLocalRegionWithCache()
|
|
475
|
-
logger.debug(`Using region ${region} from CDN when generating local PeerDescriptor`)
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
this.localPeerDescriptor = createPeerDescriptor(connectivityResponse, region, this.options.nodeId)
|
|
479
|
-
}
|
|
480
|
-
return this.localPeerDescriptor
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
public getClosestContacts(limit?: number): PeerDescriptor[] {
|
|
484
|
-
return this.peerManager!.getNearbyContacts()
|
|
485
|
-
.getClosestContacts(limit)
|
|
486
|
-
.map((peer) => peer.getPeerDescriptor())
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
getRandomContacts(limit?: number): PeerDescriptor[] {
|
|
490
|
-
return this.peerManager!.getRandomContacts().getContacts(limit).map((c) => c.getPeerDescriptor())
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
getRingContacts(): RingContacts {
|
|
494
|
-
const contacts = this.peerManager!.getRingContacts().getClosestContacts()
|
|
495
|
-
return {
|
|
496
|
-
left: contacts.left.map((c) => c.getPeerDescriptor()),
|
|
497
|
-
right: contacts.right.map((c) => c.getPeerDescriptor())
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
public getClosestRingContactsTo(ringIdRaw: RingIdRaw, limit?: number): RingContacts {
|
|
502
|
-
const closest = this.peerManager!.getClosestRingContactsTo(ringIdRaw, limit)
|
|
503
|
-
return {
|
|
504
|
-
left: closest.left.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor()),
|
|
505
|
-
right: closest.right.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor())
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
public getNodeId(): DhtAddress {
|
|
510
|
-
return toNodeId(this.localPeerDescriptor!)
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
public getNeighborCount(): number {
|
|
514
|
-
return this.peerManager!.getNeighborCount()
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
public removeContact(nodeId: DhtAddress): void {
|
|
518
|
-
if (!this.started) { // the stopped state is checked in PeerManager
|
|
519
|
-
return
|
|
520
|
-
}
|
|
521
|
-
this.peerManager!.removeContact(nodeId)
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
public async send(msg: Message): Promise<void> {
|
|
525
|
-
if (!this.started || this.abortController.signal.aborted) {
|
|
526
|
-
return
|
|
527
|
-
}
|
|
528
|
-
const reachableThrough = this.peerDiscovery!.isJoinOngoing() ? this.getConnectedEntryPoints() : []
|
|
529
|
-
this.router!.send(msg, reachableThrough)
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
private getConnectedEntryPoints(): PeerDescriptor[] {
|
|
533
|
-
return this.options.entryPoints !== undefined ? this.options.entryPoints.filter((entryPoint) =>
|
|
534
|
-
this.connectionsView!.hasConnection(toNodeId(entryPoint))
|
|
535
|
-
) : []
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
public async joinDht(entryPointDescriptors: PeerDescriptor[], doAdditionalDistantPeerDiscovery?: boolean, retry?: boolean): Promise<void> {
|
|
539
|
-
if (!this.started) {
|
|
540
|
-
throw new Error('Cannot join DHT before calling start() on DhtNode')
|
|
541
|
-
}
|
|
542
|
-
await this.peerDiscovery!.joinDht(entryPointDescriptors, doAdditionalDistantPeerDiscovery, retry)
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
public async joinRing(): Promise<void> {
|
|
546
|
-
if (!this.started) {
|
|
547
|
-
throw new Error('Cannot join ring before calling start() on DhtNode')
|
|
548
|
-
}
|
|
549
|
-
await this.peerDiscovery!.joinRing()
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
public async storeDataToDht(key: DhtAddress, data: Any, creator?: DhtAddress): Promise<PeerDescriptor[]> {
|
|
553
|
-
const connectedEntryPoints = this.getConnectedEntryPoints()
|
|
554
|
-
if (this.peerDiscovery!.isJoinOngoing() && connectedEntryPoints.length > 0) {
|
|
555
|
-
return this.storeDataToDhtViaPeer(key, data, sample(connectedEntryPoints)!)
|
|
556
|
-
}
|
|
557
|
-
return this.storeManager!.storeDataToDht(key, data, creator ?? this.getNodeId())
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
public async storeDataToDhtViaPeer(key: DhtAddress, data: Any, peer: PeerDescriptor): Promise<PeerDescriptor[]> {
|
|
561
|
-
const rpcRemote = new ExternalApiRpcRemote(
|
|
562
|
-
this.localPeerDescriptor!,
|
|
563
|
-
peer,
|
|
564
|
-
this.rpcCommunicator!,
|
|
565
|
-
ExternalApiRpcClient
|
|
566
|
-
)
|
|
567
|
-
return await rpcRemote.storeData(key, data)
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
public async fetchDataFromDht(key: DhtAddress): Promise<DataEntry[]> {
|
|
571
|
-
const connectedEntryPoints = this.getConnectedEntryPoints()
|
|
572
|
-
if (this.peerDiscovery!.isJoinOngoing() && connectedEntryPoints.length > 0) {
|
|
573
|
-
return this.fetchDataFromDhtViaPeer(key, sample(connectedEntryPoints)!)
|
|
574
|
-
}
|
|
575
|
-
const result = await this.recursiveOperationManager!.execute(key, RecursiveOperation.FETCH_DATA)
|
|
576
|
-
return result.dataEntries ?? [] // TODO is this fallback needed?
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
public async fetchDataFromDhtViaPeer(key: DhtAddress, peer: PeerDescriptor): Promise<DataEntry[]> {
|
|
580
|
-
const rpcRemote = new ExternalApiRpcRemote(
|
|
581
|
-
this.localPeerDescriptor!,
|
|
582
|
-
peer,
|
|
583
|
-
this.rpcCommunicator!,
|
|
584
|
-
ExternalApiRpcClient
|
|
585
|
-
)
|
|
586
|
-
return await rpcRemote.externalFetchData(key)
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
public async deleteDataFromDht(key: DhtAddress, waitForCompletion: boolean): Promise<void> {
|
|
590
|
-
if (!this.abortController.signal.aborted) {
|
|
591
|
-
await this.recursiveOperationManager!.execute(key, RecursiveOperation.DELETE_DATA, undefined, waitForCompletion)
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
async findClosestNodesFromDht(key: DhtAddress): Promise<PeerDescriptor[]> {
|
|
596
|
-
const result = await this.recursiveOperationManager!.execute(key, RecursiveOperation.FIND_CLOSEST_NODES)
|
|
597
|
-
return result.closestNodes
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
public getTransport(): ITransport {
|
|
601
|
-
return this.transport!
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
public getLocalPeerDescriptor(): PeerDescriptor {
|
|
605
|
-
return this.localPeerDescriptor!
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
public getNeighbors(): PeerDescriptor[] {
|
|
609
|
-
return this.started ? this.peerManager!.getNeighbors().map((remote: DhtNodeRpcRemote) => remote.getPeerDescriptor()) : []
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
getConnectionsView(): ConnectionsView {
|
|
613
|
-
return this.connectionsView!
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
public getLocalLockedConnectionCount(): number {
|
|
617
|
-
return this.connectionLocker!.getLocalLockedConnectionCount()
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
public getRemoteLockedConnectionCount(): number {
|
|
621
|
-
return this.connectionLocker!.getRemoteLockedConnectionCount()
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
public getWeakLockedConnectionCount(): number {
|
|
625
|
-
return this.connectionLocker!.getWeakLockedConnectionCount()
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
public async waitForNetworkConnectivity(): Promise<void> {
|
|
629
|
-
await until(
|
|
630
|
-
() => this.connectionsView!.getConnectionCount() > 0,
|
|
631
|
-
this.options.networkConnectivityTimeout,
|
|
632
|
-
100,
|
|
633
|
-
this.abortController.signal
|
|
634
|
-
)
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
public hasJoined(): boolean {
|
|
638
|
-
return this.peerDiscovery!.isJoinCalled()
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
public getDiagnosticInfo(): Record<string, unknown> {
|
|
642
|
-
return {
|
|
643
|
-
localPeerDescriptor: this.localPeerDescriptor,
|
|
644
|
-
transport: this.transport!.getDiagnosticInfo(),
|
|
645
|
-
router: this.router!.getDiagnosticInfo(),
|
|
646
|
-
neighborCount: this.getNeighborCount(),
|
|
647
|
-
nearbyContactCount: Array.from(this.peerManager!.getNearbyContacts().getAllContactsInUndefinedOrder()).length,
|
|
648
|
-
randomContactCount: this.peerManager!.getRandomContacts().getSize()
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
public async stop(): Promise<void> {
|
|
653
|
-
if (this.abortController.signal.aborted || !this.started) {
|
|
654
|
-
return
|
|
655
|
-
}
|
|
656
|
-
logger.trace('stop()')
|
|
657
|
-
this.abortController.abort()
|
|
658
|
-
await this.storeManager!.destroy()
|
|
659
|
-
this.localDataStore.clear()
|
|
660
|
-
this.peerManager?.stop()
|
|
661
|
-
this.rpcCommunicator!.stop()
|
|
662
|
-
this.router!.stop()
|
|
663
|
-
this.recursiveOperationManager!.stop()
|
|
664
|
-
if (this.options.transport === undefined) {
|
|
665
|
-
// if the transport was not given in options, the instance was created in start() and
|
|
666
|
-
// this component is responsible for stopping it
|
|
667
|
-
await this.transport!.stop()
|
|
668
|
-
}
|
|
669
|
-
this.transport = undefined
|
|
670
|
-
this.connectionLocker = undefined
|
|
671
|
-
this.removeAllListeners()
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
private createDhtNodeRpcRemote(peerDescriptor: PeerDescriptor) {
|
|
675
|
-
return new DhtNodeRpcRemote(
|
|
676
|
-
this.localPeerDescriptor!,
|
|
677
|
-
peerDescriptor,
|
|
678
|
-
this.options.serviceId,
|
|
679
|
-
this.rpcCommunicator!,
|
|
680
|
-
this.options.rpcRequestTimeout
|
|
681
|
-
)
|
|
682
|
-
}
|
|
683
|
-
}
|