@streamr/dht 100.0.0-pretestnet.6 → 100.0.0-rc.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 +90 -8
- package/dist/package.json +70 -0
- package/dist/src/connection/Connection.d.ts +1 -0
- package/dist/src/connection/Connection.js +10 -3
- package/dist/src/connection/Connection.js.map +1 -1
- package/dist/src/connection/ConnectionLockHandler.d.ts +14 -14
- package/dist/src/connection/ConnectionLockHandler.js +22 -16
- package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
- package/dist/src/connection/ConnectionLockRpcLocal.d.ts +3 -3
- package/dist/src/connection/ConnectionLockRpcLocal.js +7 -6
- package/dist/src/connection/ConnectionLockRpcLocal.js.map +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.d.ts +4 -6
- package/dist/src/connection/ConnectionLockRpcRemote.js +10 -37
- package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
- package/dist/src/connection/ConnectionManager.d.ts +19 -20
- package/dist/src/connection/ConnectionManager.js +132 -117
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.d.ts +3 -2
- package/dist/src/connection/ConnectorFacade.js +10 -3
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/Handshaker.d.ts +3 -1
- package/dist/src/connection/Handshaker.js +18 -9
- package/dist/src/connection/Handshaker.js.map +1 -1
- package/dist/src/connection/IConnection.d.ts +2 -7
- package/dist/src/connection/IConnection.js +1 -8
- package/dist/src/connection/IConnection.js.map +1 -1
- package/dist/src/connection/ManagedConnection.d.ts +5 -7
- package/dist/src/connection/ManagedConnection.js +42 -26
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/ManagedWebrtcConnection.js.map +1 -1
- package/dist/src/connection/connectivityChecker.d.ts +9 -0
- package/dist/src/connection/connectivityChecker.js +130 -0
- package/dist/src/connection/connectivityChecker.js.map +1 -0
- package/dist/src/connection/connectivityRequestHandler.d.ts +3 -0
- package/dist/src/connection/connectivityRequestHandler.js +101 -0
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -0
- package/dist/src/connection/simulator/Simulator.d.ts +0 -3
- package/dist/src/connection/simulator/Simulator.js +34 -69
- package/dist/src/connection/simulator/Simulator.js.map +1 -1
- package/dist/src/connection/simulator/SimulatorConnection.js +27 -25
- package/dist/src/connection/simulator/SimulatorConnection.js.map +1 -1
- package/dist/src/connection/simulator/SimulatorConnector.js +16 -12
- package/dist/src/connection/simulator/SimulatorConnector.js.map +1 -1
- package/dist/src/connection/simulator/pings.js.map +1 -1
- package/dist/src/connection/webrtc/NodeWebrtcConnection.d.ts +2 -3
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js +40 -27
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.d.ts +0 -2
- package/dist/src/connection/webrtc/WebrtcConnector.js +24 -25
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +2 -2
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +27 -20
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.d.ts +3 -6
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js +2 -5
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js.map +1 -1
- package/dist/src/connection/webrtc/iceServerAsString.js +1 -1
- package/dist/src/connection/webrtc/iceServerAsString.js.map +1 -1
- package/dist/src/connection/websocket/AutoCertifierClientFacade.d.ts +1 -2
- package/dist/src/connection/websocket/AutoCertifierClientFacade.js +6 -4
- package/dist/src/connection/websocket/AutoCertifierClientFacade.js.map +1 -1
- package/dist/src/connection/websocket/ClientWebsocket.d.ts +1 -0
- package/dist/src/connection/websocket/ClientWebsocket.js +14 -7
- package/dist/src/connection/websocket/ClientWebsocket.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnector.d.ts +3 -9
- package/dist/src/connection/websocket/WebsocketConnector.js +142 -74
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.d.ts +5 -3
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js +9 -12
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.d.ts +4 -7
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js +7 -44
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServer.d.ts +1 -4
- package/dist/src/connection/websocket/WebsocketServer.js +49 -40
- package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
- package/dist/src/connection/websocket/{ServerWebsocket.d.ts → WebsocketServerConnection.d.ts} +8 -4
- package/dist/src/connection/websocket/WebsocketServerConnection.js +97 -0
- package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -0
- package/dist/src/dht/DhtNode.d.ts +45 -49
- package/dist/src/dht/DhtNode.js +229 -317
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +10 -9
- package/dist/src/dht/DhtNodeRpcLocal.js +19 -11
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcRemote.d.ts +15 -10
- package/dist/src/dht/DhtNodeRpcRemote.js +38 -21
- package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcLocal.d.ts +7 -6
- package/dist/src/dht/ExternalApiRpcLocal.js +9 -13
- package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.d.ts +6 -5
- package/dist/src/dht/ExternalApiRpcRemote.js +10 -7
- package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +61 -0
- package/dist/src/dht/PeerManager.js +288 -0
- package/dist/src/dht/PeerManager.js.map +1 -0
- package/dist/src/dht/contact/Contact.d.ts +2 -2
- package/dist/src/dht/contact/Contact.js +4 -3
- package/dist/src/dht/contact/Contact.js.map +1 -1
- package/dist/src/dht/contact/ContactList.d.ts +8 -8
- package/dist/src/dht/contact/ContactList.js +12 -7
- package/dist/src/dht/contact/ContactList.js.map +1 -1
- package/dist/src/dht/contact/RandomContactList.d.ts +4 -4
- package/dist/src/dht/contact/RandomContactList.js +13 -12
- package/dist/src/dht/contact/RandomContactList.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/{Remote.d.ts → RpcRemote.d.ts} +8 -7
- package/dist/src/dht/contact/{Remote.js → RpcRemote.js} +16 -13
- package/dist/src/dht/contact/RpcRemote.js.map +1 -0
- package/dist/src/dht/contact/SortedContactList.d.ts +29 -15
- package/dist/src/dht/contact/SortedContactList.js +79 -42
- 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.d.ts +8 -18
- package/dist/src/dht/discovery/DiscoverySession.js +32 -48
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +16 -12
- package/dist/src/dht/discovery/PeerDiscovery.js +82 -39
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/discovery/RingDiscoverySession.d.ts +29 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js +123 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +36 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +166 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.d.ts +14 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.js +26 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.d.ts +6 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js +44 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.d.ts +44 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js +187 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.d.ts +14 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.js +20 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.d.ts +6 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.js +21 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.js.map +1 -0
- package/dist/src/dht/routing/DuplicateDetector.d.ts +2 -4
- package/dist/src/dht/routing/DuplicateDetector.js +10 -15
- package/dist/src/dht/routing/DuplicateDetector.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +11 -27
- package/dist/src/dht/routing/Router.js +92 -58
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcLocal.d.ts +3 -4
- package/dist/src/dht/routing/RouterRpcLocal.js +17 -16
- package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcRemote.d.ts +3 -3
- package/dist/src/dht/routing/RouterRpcRemote.js +29 -20
- package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.d.ts +29 -21
- package/dist/src/dht/routing/RoutingSession.js +93 -68
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/routing/RoutingTablesCache.d.ts +24 -0
- package/dist/src/dht/routing/RoutingTablesCache.js +46 -0
- package/dist/src/dht/routing/RoutingTablesCache.js.map +1 -0
- package/dist/src/dht/routing/getPreviousPeer.js.map +1 -1
- package/dist/src/dht/store/LocalDataStore.d.ts +9 -14
- package/dist/src/dht/store/LocalDataStore.js +46 -72
- package/dist/src/dht/store/LocalDataStore.js.map +1 -1
- package/dist/src/dht/store/StoreManager.d.ts +33 -0
- package/dist/src/dht/store/StoreManager.js +182 -0
- package/dist/src/dht/store/StoreManager.js.map +1 -0
- package/dist/src/dht/store/StoreRpcLocal.d.ts +11 -41
- package/dist/src/dht/store/StoreRpcLocal.js +27 -234
- package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
- package/dist/src/dht/store/StoreRpcRemote.d.ts +6 -7
- package/dist/src/dht/store/StoreRpcRemote.js +10 -20
- package/dist/src/dht/store/StoreRpcRemote.js.map +1 -1
- package/dist/src/exports.d.ts +5 -3
- package/dist/src/exports.js +10 -8
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/AddressTools.js +2 -0
- package/dist/src/helpers/AddressTools.js.map +1 -1
- package/dist/src/helpers/Connectivity.js.map +1 -1
- package/dist/src/helpers/MapWithTtl.d.ts +14 -0
- package/dist/src/helpers/MapWithTtl.js +60 -0
- package/dist/src/helpers/MapWithTtl.js.map +1 -0
- package/dist/src/helpers/createPeerDescriptor.d.ts +3 -0
- package/dist/src/helpers/createPeerDescriptor.js +57 -0
- package/dist/src/helpers/createPeerDescriptor.js.map +1 -0
- package/dist/src/helpers/createPeerDescriptorSignaturePayload.d.ts +2 -0
- package/dist/src/helpers/createPeerDescriptorSignaturePayload.js +30 -0
- package/dist/src/helpers/createPeerDescriptorSignaturePayload.js.map +1 -0
- package/dist/src/helpers/debugHelpers.js.map +1 -1
- package/dist/src/helpers/errors.js +2 -0
- package/dist/src/helpers/errors.js.map +1 -1
- package/dist/src/helpers/offering.d.ts +4 -0
- package/dist/src/helpers/offering.js +18 -0
- package/dist/src/helpers/offering.js.map +1 -0
- package/dist/src/helpers/protoClasses.js +2 -3
- package/dist/src/helpers/protoClasses.js.map +1 -1
- package/dist/src/helpers/protoToString.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/identifiers.d.ts +10 -0
- package/dist/src/identifiers.js +31 -0
- package/dist/src/identifiers.js.map +1 -0
- package/dist/src/proto/google/protobuf/any.js +8 -8
- package/dist/src/proto/google/protobuf/any.js.map +1 -1
- package/dist/src/proto/google/protobuf/empty.js +2 -4
- package/dist/src/proto/google/protobuf/empty.js.map +1 -1
- package/dist/src/proto/google/protobuf/timestamp.js +10 -10
- package/dist/src/proto/google/protobuf/timestamp.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +46 -49
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +63 -54
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +226 -232
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +146 -168
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +26 -29
- package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js +1 -1
- package/dist/src/rpc-protocol/DhtCallContext.d.ts +2 -2
- package/dist/src/rpc-protocol/DhtCallContext.js +8 -0
- package/dist/src/rpc-protocol/DhtCallContext.js.map +1 -1
- package/dist/src/rpc-protocol/DhtRpcOptions.d.ts +2 -1
- package/dist/src/transport/ITransport.d.ts +10 -2
- package/dist/src/transport/ITransport.js +5 -0
- package/dist/src/transport/ITransport.js.map +1 -1
- package/dist/src/transport/ListeningRpcCommunicator.js +3 -1
- package/dist/src/transport/ListeningRpcCommunicator.js.map +1 -1
- package/dist/src/transport/RoutingRpcCommunicator.d.ts +4 -2
- package/dist/src/transport/RoutingRpcCommunicator.js +19 -12
- package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
- package/jest.config.js +4 -1
- package/karma-setup.js +2 -0
- package/karma.config.js +13 -9
- package/package.json +16 -13
- package/protos/DhtRpc.proto +76 -76
- package/src/connection/Connection.ts +6 -1
- package/src/connection/ConnectionLockHandler.ts +30 -22
- package/src/connection/ConnectionLockRpcLocal.ts +7 -12
- package/src/connection/ConnectionLockRpcRemote.ts +9 -19
- package/src/connection/ConnectionManager.ts +132 -138
- package/src/connection/ConnectorFacade.ts +10 -9
- package/src/connection/Handshaker.ts +23 -11
- package/src/connection/IConnection.ts +2 -8
- package/src/connection/ManagedConnection.ts +34 -35
- package/src/connection/connectivityChecker.ts +109 -0
- package/src/connection/connectivityRequestHandler.ts +103 -0
- package/src/connection/simulator/Simulator.ts +6 -37
- package/src/connection/simulator/SimulatorConnection.ts +23 -25
- package/src/connection/simulator/SimulatorConnector.ts +11 -11
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +17 -25
- package/src/connection/webrtc/NodeWebrtcConnection.ts +24 -26
- package/src/connection/webrtc/WebrtcConnector.ts +18 -29
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +29 -24
- package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +4 -14
- package/src/connection/webrtc/iceServerAsString.ts +1 -1
- package/src/connection/websocket/AutoCertifierClientFacade.ts +4 -6
- package/src/connection/websocket/ClientWebsocket.ts +10 -4
- package/src/connection/websocket/WebsocketConnector.ts +120 -97
- package/src/connection/websocket/WebsocketConnectorRpcLocal.ts +13 -15
- package/src/connection/websocket/WebsocketConnectorRpcRemote.ts +7 -27
- package/src/connection/websocket/WebsocketServer.ts +50 -53
- package/src/connection/websocket/WebsocketServerConnection.ts +104 -0
- package/src/dht/DhtNode.ts +289 -410
- package/src/dht/DhtNodeRpcLocal.ts +25 -17
- package/src/dht/DhtNodeRpcRemote.ts +43 -27
- package/src/dht/ExternalApiRpcLocal.ts +30 -17
- package/src/dht/ExternalApiRpcRemote.ts +14 -11
- package/src/dht/PeerManager.ts +339 -0
- package/src/dht/contact/Contact.ts +4 -4
- package/src/dht/contact/ContactList.ts +11 -10
- package/src/dht/contact/RandomContactList.ts +15 -15
- package/src/dht/contact/RingContactList.ts +151 -0
- package/src/dht/contact/{Remote.ts → RpcRemote.ts} +16 -19
- package/src/dht/contact/SortedContactList.ts +120 -72
- package/src/dht/contact/ringIdentifiers.ts +62 -0
- package/src/dht/discovery/DiscoverySession.ts +36 -61
- package/src/dht/discovery/PeerDiscovery.ts +98 -43
- package/src/dht/discovery/RingDiscoverySession.ts +160 -0
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +246 -0
- package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +34 -0
- package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +43 -0
- package/src/dht/recursive-operation/RecursiveOperationSession.ts +232 -0
- package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +35 -0
- package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +30 -0
- package/src/dht/routing/DuplicateDetector.ts +9 -21
- package/src/dht/routing/Router.ts +95 -92
- package/src/dht/routing/RouterRpcLocal.ts +16 -18
- package/src/dht/routing/RouterRpcRemote.ts +26 -24
- package/src/dht/routing/RoutingSession.ts +119 -98
- package/src/dht/routing/RoutingTablesCache.ts +58 -0
- package/src/dht/routing/getPreviousPeer.ts +1 -1
- package/src/dht/store/LocalDataStore.ts +47 -77
- package/src/dht/store/StoreManager.ts +209 -0
- package/src/dht/store/StoreRpcLocal.ts +39 -308
- package/src/dht/store/StoreRpcRemote.ts +13 -31
- package/src/exports.ts +13 -3
- package/src/helpers/AddressTools.ts +2 -0
- package/src/helpers/MapWithTtl.ts +71 -0
- package/src/helpers/createPeerDescriptor.ts +57 -0
- package/src/helpers/createPeerDescriptorSignaturePayload.ts +28 -0
- package/src/helpers/offering.ts +15 -0
- package/src/helpers/protoClasses.ts +4 -6
- package/src/helpers/version.ts +32 -0
- package/src/identifiers.ts +29 -0
- package/src/proto/google/protobuf/any.ts +4 -4
- package/src/proto/google/protobuf/empty.ts +2 -4
- package/src/proto/google/protobuf/timestamp.ts +4 -4
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +65 -68
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +27 -30
- package/src/proto/packages/dht/protos/DhtRpc.ts +297 -313
- package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +1 -1
- package/src/rpc-protocol/DhtCallContext.ts +2 -2
- package/src/rpc-protocol/DhtRpcOptions.ts +2 -1
- package/src/transport/ITransport.ts +11 -2
- package/src/transport/ListeningRpcCommunicator.ts +1 -1
- package/src/transport/RoutingRpcCommunicator.ts +21 -14
- package/test/RandomGraphSimulation.ts +3 -2
- package/test/benchmark/Find.test.ts +13 -28
- package/test/benchmark/KademliaCorrectness.test.ts +24 -28
- package/test/benchmark/RingCorrectness.test.ts +157 -0
- package/test/benchmark/SortedContactListBenchmark.test.ts +151 -0
- package/test/benchmark/WebsocketServerMemoryLeak.test.ts +41 -0
- package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +72 -0
- package/test/benchmark/kademlia-simulation/Contact.ts +9 -9
- package/test/benchmark/kademlia-simulation/KademliaSimulation.ts +11 -11
- package/test/benchmark/kademlia-simulation/SimulationNode.ts +29 -25
- package/test/data/generateGroundTruthData.ts +7 -6
- package/test/end-to-end/Layer0-Layer1.test.ts +11 -15
- package/test/end-to-end/Layer0.test.ts +19 -22
- package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +19 -21
- package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +26 -28
- package/test/end-to-end/Layer0Webrtc.test.ts +19 -19
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +10 -18
- package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +8 -15
- package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +2 -2
- package/test/end-to-end/WebsocketConnectionRequest.test.ts +8 -9
- package/test/end-to-end/memory-leak.test.ts +19 -24
- package/test/integration/ConnectionLocking.test.ts +66 -60
- package/test/integration/ConnectionManager.test.ts +43 -63
- package/test/integration/ConnectivityChecking.test.ts +52 -0
- package/test/integration/DhtJoinPeerDiscovery.test.ts +8 -12
- package/test/integration/DhtNodeExternalAPI.test.ts +17 -21
- package/test/integration/DhtNodeRpcRemote.test.ts +19 -26
- package/test/integration/DhtRpc.test.ts +20 -24
- package/test/integration/Find.test.ts +10 -12
- package/test/integration/Layer1-scale.test.ts +25 -37
- package/test/integration/Mock-Layer1-Layer0.test.ts +39 -59
- package/test/integration/MultipleEntryPointJoining.test.ts +14 -14
- package/test/integration/ReplicateData.test.ts +106 -0
- package/test/integration/RouteMessage.test.ts +42 -68
- package/test/integration/RouterRpcRemote.test.ts +19 -24
- package/test/integration/ScaleDownDht.test.ts +14 -12
- package/test/integration/SimultaneousConnections.test.ts +112 -111
- package/test/integration/Store.test.ts +43 -27
- package/test/integration/StoreAndDelete.test.ts +36 -48
- package/test/integration/StoreOnDhtWithThreeNodes.test.ts +59 -0
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +17 -37
- package/test/integration/StoreRpcRemote.test.ts +20 -32
- package/test/integration/WebrtcConnectionManagement.test.ts +39 -25
- package/test/integration/WebrtcConnectorRpc.test.ts +6 -11
- package/test/integration/WebsocketConnectionManagement.test.ts +87 -22
- package/test/integration/WebsocketConnectorRpc.test.ts +14 -24
- package/test/integration/{RpcErrors.test.ts → rpc-connections-over-webrpc.test.ts} +15 -26
- package/test/unit/AddressTools.test.ts +4 -0
- package/test/unit/ConnectivityHelpers.test.ts +9 -17
- package/test/unit/DuplicateDetector.test.ts +8 -5
- package/test/unit/LocalDataStore.test.ts +78 -75
- package/test/unit/PeerManager.test.ts +33 -0
- package/test/unit/RandomContactList.test.ts +12 -9
- package/test/unit/RecursiveOperationManager.test.ts +157 -0
- package/test/unit/RecursiveOperationSession.test.ts +68 -0
- package/test/unit/Router.test.ts +52 -35
- package/test/unit/RoutingSession.test.ts +79 -0
- package/test/unit/SortedContactList.test.ts +61 -30
- package/test/unit/StoreManager.test.ts +138 -0
- package/test/unit/WebsocketConnector.test.ts +27 -35
- package/test/unit/connectivityRequestHandler.test.ts +104 -0
- package/test/unit/createPeerDescriptor.test.ts +69 -0
- package/test/unit/customMatchers.test.ts +16 -0
- package/test/unit/version.test.ts +18 -0
- package/test/utils/FakeTransport.ts +47 -0
- package/test/utils/customMatchers.ts +71 -0
- package/test/utils/mock/MockRpcCommunicator.ts +7 -0
- package/test/utils/mock/Router.ts +13 -3
- package/test/utils/mock/Transport.ts +1 -1
- package/test/utils/mock/mockDataEntry.ts +38 -0
- package/test/utils/utils.ts +104 -107
- package/tsconfig.browser.json +2 -1
- package/tsconfig.jest.json +4 -2
- package/tsconfig.node.json +4 -2
- package/dist/src/connection/ConnectivityChecker.d.ts +0 -17
- package/dist/src/connection/ConnectivityChecker.js +0 -208
- package/dist/src/connection/ConnectivityChecker.js.map +0 -1
- package/dist/src/connection/websocket/ServerWebsocket.js +0 -100
- package/dist/src/connection/websocket/ServerWebsocket.js.map +0 -1
- package/dist/src/dht/contact/Remote.js.map +0 -1
- package/dist/src/dht/find/FindRpcLocal.d.ts +0 -14
- package/dist/src/dht/find/FindRpcLocal.js +0 -25
- package/dist/src/dht/find/FindRpcLocal.js.map +0 -1
- package/dist/src/dht/find/FindSession.d.ts +0 -44
- package/dist/src/dht/find/FindSession.js +0 -145
- package/dist/src/dht/find/FindSession.js.map +0 -1
- package/dist/src/dht/find/FindSessionRpcLocal.d.ts +0 -12
- package/dist/src/dht/find/FindSessionRpcLocal.js +0 -17
- package/dist/src/dht/find/FindSessionRpcLocal.js.map +0 -1
- package/dist/src/dht/find/FindSessionRpcRemote.d.ts +0 -6
- package/dist/src/dht/find/FindSessionRpcRemote.js +0 -21
- package/dist/src/dht/find/FindSessionRpcRemote.js.map +0 -1
- package/dist/src/dht/find/Finder.d.ts +0 -49
- package/dist/src/dht/find/Finder.js +0 -184
- package/dist/src/dht/find/Finder.js.map +0 -1
- package/dist/src/dht/routing/FindRpcRemote.d.ts +0 -6
- package/dist/src/dht/routing/FindRpcRemote.js +0 -41
- package/dist/src/dht/routing/FindRpcRemote.js.map +0 -1
- package/dist/src/helpers/PeerID.d.ts +0 -24
- package/dist/src/helpers/PeerID.js +0 -78
- package/dist/src/helpers/PeerID.js.map +0 -1
- package/dist/src/helpers/UUID.d.ts +0 -8
- package/dist/src/helpers/UUID.js +0 -36
- package/dist/src/helpers/UUID.js.map +0 -1
- package/dist/src/helpers/kademliaId.d.ts +0 -1
- package/dist/src/helpers/kademliaId.js +0 -14
- package/dist/src/helpers/kademliaId.js.map +0 -1
- package/dist/src/helpers/peerIdFromPeerDescriptor.d.ts +0 -6
- package/dist/src/helpers/peerIdFromPeerDescriptor.js +0 -23
- package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +0 -1
- package/src/connection/ConnectivityChecker.ts +0 -199
- package/src/connection/websocket/ServerWebsocket.ts +0 -114
- package/src/dht/find/FindRpcLocal.ts +0 -35
- package/src/dht/find/FindSession.ts +0 -178
- package/src/dht/find/FindSessionRpcLocal.ts +0 -25
- package/src/dht/find/FindSessionRpcRemote.ts +0 -30
- package/src/dht/find/Finder.ts +0 -275
- package/src/dht/routing/FindRpcRemote.ts +0 -40
- package/src/helpers/PeerID.ts +0 -88
- package/src/helpers/UUID.ts +0 -35
- package/src/helpers/kademliaId.ts +0 -8
- package/src/helpers/peerIdFromPeerDescriptor.ts +0 -20
- package/test/integration/MigrateData.test.ts +0 -204
- package/test/unit/Finder.test.ts +0 -110
- package/test/unit/PeerID.test.ts +0 -22
- package/test/unit/UUID.test.ts +0 -55
package/src/dht/DhtNode.ts
CHANGED
|
@@ -1,70 +1,68 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
2
|
+
import {
|
|
3
|
+
Logger,
|
|
4
|
+
MetricsContext,
|
|
5
|
+
merge,
|
|
6
|
+
waitForCondition
|
|
7
|
+
} from '@streamr/utils'
|
|
3
8
|
import { EventEmitter } from 'eventemitter3'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
9
|
+
import { sample } from 'lodash'
|
|
10
|
+
import { MarkRequired } from 'ts-essentials'
|
|
11
|
+
import { ConnectionManager, PortRange, TlsCertificate } from '../connection/ConnectionManager'
|
|
12
|
+
import { DefaultConnectorFacade, DefaultConnectorFacadeConfig } from '../connection/ConnectorFacade'
|
|
13
|
+
import { IceServer } from '../connection/webrtc/WebrtcConnector'
|
|
14
|
+
import { isBrowserEnvironment } from '../helpers/browser/isBrowserEnvironment'
|
|
15
|
+
import { DhtAddress, KADEMLIA_ID_LENGTH_IN_BYTES, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
16
|
+
import { Any } from '../proto/google/protobuf/any'
|
|
7
17
|
import {
|
|
8
18
|
ClosestPeersRequest,
|
|
9
19
|
ClosestPeersResponse,
|
|
10
|
-
|
|
20
|
+
ClosestRingPeersRequest,
|
|
21
|
+
ClosestRingPeersResponse,
|
|
11
22
|
ConnectivityResponse,
|
|
23
|
+
DataEntry,
|
|
24
|
+
ExternalFetchDataRequest,
|
|
25
|
+
ExternalFetchDataResponse,
|
|
26
|
+
ExternalStoreDataRequest,
|
|
27
|
+
ExternalStoreDataResponse,
|
|
28
|
+
LeaveNotice,
|
|
12
29
|
Message,
|
|
13
|
-
NodeType,
|
|
14
30
|
PeerDescriptor,
|
|
15
31
|
PingRequest,
|
|
16
32
|
PingResponse,
|
|
17
|
-
|
|
18
|
-
ExternalFindDataRequest,
|
|
19
|
-
ExternalFindDataResponse,
|
|
20
|
-
ExternalStoreDataRequest,
|
|
21
|
-
ExternalStoreDataResponse,
|
|
33
|
+
RecursiveOperation
|
|
22
34
|
} from '../proto/packages/dht/protos/DhtRpc'
|
|
35
|
+
import { ExternalApiRpcClient, StoreRpcClient } from '../proto/packages/dht/protos/DhtRpc.client'
|
|
23
36
|
import { ITransport, TransportEvents } from '../transport/ITransport'
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
Logger,
|
|
28
|
-
MetricsContext,
|
|
29
|
-
hexToBinary,
|
|
30
|
-
merge,
|
|
31
|
-
waitForCondition
|
|
32
|
-
} from '@streamr/utils'
|
|
33
|
-
import { toProtoRpcClient } from '@streamr/proto-rpc'
|
|
34
|
-
import { RandomContactList } from './contact/RandomContactList'
|
|
35
|
-
import { Any } from '../proto/google/protobuf/any'
|
|
36
|
-
import {
|
|
37
|
-
areEqualPeerDescriptors,
|
|
38
|
-
getNodeIdFromPeerDescriptor,
|
|
39
|
-
keyFromPeerDescriptor,
|
|
40
|
-
peerIdFromPeerDescriptor
|
|
41
|
-
} from '../helpers/peerIdFromPeerDescriptor'
|
|
42
|
-
import { Router } from './routing/Router'
|
|
43
|
-
import { Finder, FindResult } from './find/Finder'
|
|
44
|
-
import { StoreRpcLocal } from './store/StoreRpcLocal'
|
|
45
|
-
import { PeerDiscovery } from './discovery/PeerDiscovery'
|
|
46
|
-
import { LocalDataStore } from './store/LocalDataStore'
|
|
47
|
-
import { IceServer } from '../connection/webrtc/WebrtcConnector'
|
|
48
|
-
import { ExternalApiRpcRemote } from './ExternalApiRpcRemote'
|
|
49
|
-
import { UUID } from '../helpers/UUID'
|
|
50
|
-
import { isBrowserEnvironment } from '../helpers/browser/isBrowserEnvironment'
|
|
51
|
-
import { sample } from 'lodash'
|
|
52
|
-
import { DefaultConnectorFacade, DefaultConnectorFacadeConfig } from '../connection/ConnectorFacade'
|
|
53
|
-
import { MarkRequired } from 'ts-essentials'
|
|
37
|
+
import { RoutingRpcCommunicator } from '../transport/RoutingRpcCommunicator'
|
|
38
|
+
import { ServiceID } from '../types/ServiceID'
|
|
54
39
|
import { DhtNodeRpcLocal } from './DhtNodeRpcLocal'
|
|
55
|
-
import {
|
|
40
|
+
import { DhtNodeRpcRemote } from './DhtNodeRpcRemote'
|
|
56
41
|
import { ExternalApiRpcLocal } from './ExternalApiRpcLocal'
|
|
42
|
+
import { ExternalApiRpcRemote } from './ExternalApiRpcRemote'
|
|
43
|
+
import { PeerManager } from './PeerManager'
|
|
44
|
+
import { PeerDiscovery } from './discovery/PeerDiscovery'
|
|
45
|
+
import { RecursiveOperationManager } from './recursive-operation/RecursiveOperationManager'
|
|
46
|
+
import { Router } from './routing/Router'
|
|
47
|
+
import { LocalDataStore } from './store/LocalDataStore'
|
|
48
|
+
import { StoreManager } from './store/StoreManager'
|
|
49
|
+
import { StoreRpcRemote } from './store/StoreRpcRemote'
|
|
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'
|
|
57
54
|
|
|
58
55
|
export interface DhtNodeEvents {
|
|
59
|
-
|
|
56
|
+
contactAdded: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
60
57
|
contactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
61
|
-
|
|
62
|
-
newRandomContact: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
58
|
+
randomContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
63
59
|
randomContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
|
|
60
|
+
ringContactAdded: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
|
|
61
|
+
ringContactRemoved: (peerDescriptor: PeerDescriptor, closestPeers: RingContacts) => void
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
export interface DhtNodeOptions {
|
|
67
|
-
serviceId?:
|
|
65
|
+
serviceId?: ServiceID
|
|
68
66
|
joinParallelism?: number
|
|
69
67
|
maxNeighborListSize?: number
|
|
70
68
|
numberOfNodesPerKBucket?: number
|
|
@@ -76,6 +74,7 @@ export interface DhtNodeOptions {
|
|
|
76
74
|
storeMaxTtl?: number
|
|
77
75
|
networkConnectivityTimeout?: number
|
|
78
76
|
storageRedundancyFactor?: number
|
|
77
|
+
region?: number
|
|
79
78
|
|
|
80
79
|
transport?: ITransport
|
|
81
80
|
peerDescriptor?: PeerDescriptor
|
|
@@ -83,7 +82,7 @@ export interface DhtNodeOptions {
|
|
|
83
82
|
websocketHost?: string
|
|
84
83
|
websocketPortRange?: PortRange
|
|
85
84
|
websocketServerEnableTls?: boolean
|
|
86
|
-
|
|
85
|
+
nodeId?: DhtAddress
|
|
87
86
|
|
|
88
87
|
rpcRequestTimeout?: number
|
|
89
88
|
iceServers?: IceServer[]
|
|
@@ -100,7 +99,7 @@ export interface DhtNodeOptions {
|
|
|
100
99
|
autoCertifierConfigFile?: string
|
|
101
100
|
}
|
|
102
101
|
|
|
103
|
-
type StrictDhtNodeOptions = MarkRequired<DhtNodeOptions,
|
|
102
|
+
type StrictDhtNodeOptions = MarkRequired<DhtNodeOptions,
|
|
104
103
|
'serviceId' |
|
|
105
104
|
'joinParallelism' |
|
|
106
105
|
'maxNeighborListSize' |
|
|
@@ -113,49 +112,28 @@ type StrictDhtNodeOptions = MarkRequired<DhtNodeOptions,
|
|
|
113
112
|
'storeMaxTtl' |
|
|
114
113
|
'networkConnectivityTimeout' |
|
|
115
114
|
'storageRedundancyFactor' |
|
|
116
|
-
'metricsContext'
|
|
117
|
-
'peerId'>
|
|
115
|
+
'metricsContext'>
|
|
118
116
|
|
|
119
117
|
const logger = new Logger(module)
|
|
120
118
|
|
|
121
119
|
export type Events = TransportEvents & DhtNodeEvents
|
|
122
120
|
|
|
123
|
-
export const createPeerDescriptor = (msg?: ConnectivityResponse, peerId?: string): PeerDescriptor => {
|
|
124
|
-
let kademliaId: Uint8Array
|
|
125
|
-
if (msg) {
|
|
126
|
-
kademliaId = peerId ? hexToBinary(peerId) : PeerID.fromIp(msg.host).value
|
|
127
|
-
} else {
|
|
128
|
-
kademliaId = hexToBinary(peerId!)
|
|
129
|
-
}
|
|
130
|
-
const nodeType = isBrowserEnvironment() ? NodeType.BROWSER : NodeType.NODEJS
|
|
131
|
-
const ret: PeerDescriptor = { kademliaId, type: nodeType }
|
|
132
|
-
if (msg && msg.websocket) {
|
|
133
|
-
ret.websocket = { host: msg.websocket.host, port: msg.websocket.port, tls: msg.websocket.tls }
|
|
134
|
-
}
|
|
135
|
-
return ret
|
|
136
|
-
}
|
|
137
|
-
|
|
138
121
|
export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
139
122
|
|
|
140
123
|
private readonly config: StrictDhtNodeOptions
|
|
141
|
-
private bucket?: KBucket<DhtNodeRpcRemote>
|
|
142
|
-
private connections: Map<PeerIDKey, DhtNodeRpcRemote> = new Map()
|
|
143
|
-
private neighborList?: SortedContactList<DhtNodeRpcRemote>
|
|
144
|
-
private randomPeers?: RandomContactList<DhtNodeRpcRemote>
|
|
145
124
|
private rpcCommunicator?: RoutingRpcCommunicator
|
|
146
125
|
private transport?: ITransport
|
|
147
126
|
private localPeerDescriptor?: PeerDescriptor
|
|
148
127
|
public router?: Router
|
|
149
|
-
private
|
|
150
|
-
private localDataStore
|
|
151
|
-
private
|
|
128
|
+
private storeManager?: StoreManager
|
|
129
|
+
private localDataStore: LocalDataStore
|
|
130
|
+
private recursiveOperationManager?: RecursiveOperationManager
|
|
152
131
|
private peerDiscovery?: PeerDiscovery
|
|
153
|
-
|
|
132
|
+
private peerManager?: PeerManager
|
|
154
133
|
public connectionManager?: ConnectionManager
|
|
134
|
+
private region?: number
|
|
155
135
|
private started = false
|
|
156
|
-
private
|
|
157
|
-
private entryPointDisconnectTimeout?: NodeJS.Timeout
|
|
158
|
-
|
|
136
|
+
private abortController = new AbortController()
|
|
159
137
|
constructor(conf: DhtNodeOptions) {
|
|
160
138
|
super()
|
|
161
139
|
this.config = merge({
|
|
@@ -163,7 +141,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
163
141
|
joinParallelism: 3,
|
|
164
142
|
maxNeighborListSize: 200,
|
|
165
143
|
numberOfNodesPerKBucket: 8,
|
|
166
|
-
joinNoProgressLimit:
|
|
144
|
+
joinNoProgressLimit: 5,
|
|
167
145
|
dhtJoinTimeout: 60000,
|
|
168
146
|
peerDiscoveryQueryBatchSize: 5,
|
|
169
147
|
maxConnections: 80,
|
|
@@ -171,14 +149,31 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
171
149
|
storeMaxTtl: 60000,
|
|
172
150
|
networkConnectivityTimeout: 10000,
|
|
173
151
|
storageRedundancyFactor: 5,
|
|
174
|
-
metricsContext: new MetricsContext()
|
|
175
|
-
peerId: new UUID().toHex()
|
|
152
|
+
metricsContext: new MetricsContext()
|
|
176
153
|
}, conf)
|
|
154
|
+
this.validateConfig()
|
|
155
|
+
this.localDataStore = new LocalDataStore(this.config.storeMaxTtl)
|
|
177
156
|
this.send = this.send.bind(this)
|
|
178
157
|
}
|
|
179
158
|
|
|
159
|
+
private validateConfig(): void {
|
|
160
|
+
const expectedNodeIdLength = KADEMLIA_ID_LENGTH_IN_BYTES * 2
|
|
161
|
+
if (this.config.nodeId !== undefined) {
|
|
162
|
+
if (!/^[0-9a-fA-F]+$/.test(this.config.nodeId)) {
|
|
163
|
+
throw new Error('Invalid nodeId, the nodeId should be a hex string')
|
|
164
|
+
} else if (this.config.nodeId.length !== expectedNodeIdLength) {
|
|
165
|
+
throw new Error(`Invalid nodeId, the length of the nodeId should be ${expectedNodeIdLength}`)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (this.config.peerDescriptor !== undefined) {
|
|
169
|
+
if (this.config.peerDescriptor.nodeId.length !== KADEMLIA_ID_LENGTH_IN_BYTES) {
|
|
170
|
+
throw new Error(`Invalid peerDescriptor, the length of the nodeId should be ${KADEMLIA_ID_LENGTH_IN_BYTES} bytes`)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
180
175
|
public async start(): Promise<void> {
|
|
181
|
-
if (this.started || this.
|
|
176
|
+
if (this.started || this.abortController.signal.aborted) {
|
|
182
177
|
return
|
|
183
178
|
}
|
|
184
179
|
logger.trace(`Starting new Streamr Network DHT Node with serviceId ${this.config.serviceId}`)
|
|
@@ -190,6 +185,14 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
190
185
|
this.config.peerDescriptor.websocket = undefined
|
|
191
186
|
}
|
|
192
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
|
+
|
|
193
196
|
// If transport is given, do not create a ConnectionManager
|
|
194
197
|
if (this.config.transport) {
|
|
195
198
|
this.transport = this.config.transport
|
|
@@ -218,12 +221,12 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
218
221
|
// If own PeerDescriptor is given in config, create a ConnectionManager with ws server
|
|
219
222
|
if (this.config.peerDescriptor?.websocket) {
|
|
220
223
|
connectorFacadeConfig.websocketHost = this.config.peerDescriptor.websocket.host
|
|
221
|
-
connectorFacadeConfig.websocketPortRange = {
|
|
224
|
+
connectorFacadeConfig.websocketPortRange = {
|
|
222
225
|
min: this.config.peerDescriptor.websocket.port,
|
|
223
226
|
max: this.config.peerDescriptor.websocket.port
|
|
224
227
|
}
|
|
225
|
-
|
|
226
|
-
} else if (this.config.websocketPortRange) {
|
|
228
|
+
// If websocketPortRange is given, create ws server using it, websocketHost can be undefined
|
|
229
|
+
} else if (this.config.websocketPortRange) {
|
|
227
230
|
connectorFacadeConfig.websocketHost = this.config.websocketHost
|
|
228
231
|
connectorFacadeConfig.websocketPortRange = this.config.websocketPortRange
|
|
229
232
|
}
|
|
@@ -244,426 +247,296 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
244
247
|
{ rpcRequestTimeout: this.config.rpcRequestTimeout }
|
|
245
248
|
)
|
|
246
249
|
|
|
247
|
-
this.transport.on('message', (message: Message) => this.
|
|
250
|
+
this.transport.on('message', (message: Message) => this.handleMessageFromTransport(message))
|
|
251
|
+
|
|
252
|
+
this.initPeerManager()
|
|
248
253
|
|
|
249
|
-
this.initKBuckets(peerIdFromPeerDescriptor(this.localPeerDescriptor!))
|
|
250
254
|
this.peerDiscovery = new PeerDiscovery({
|
|
251
|
-
rpcCommunicator: this.rpcCommunicator,
|
|
252
255
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
253
|
-
bucket: this.bucket!,
|
|
254
|
-
neighborList: this.neighborList!,
|
|
255
256
|
joinNoProgressLimit: this.config.joinNoProgressLimit,
|
|
256
257
|
peerDiscoveryQueryBatchSize: this.config.peerDiscoveryQueryBatchSize,
|
|
257
258
|
joinTimeout: this.config.dhtJoinTimeout,
|
|
258
259
|
serviceId: this.config.serviceId,
|
|
259
260
|
parallelism: this.config.joinParallelism,
|
|
260
|
-
addContact: this.addNewContact.bind(this),
|
|
261
261
|
connectionManager: this.connectionManager,
|
|
262
|
-
|
|
262
|
+
peerManager: this.peerManager!
|
|
263
263
|
})
|
|
264
264
|
this.router = new Router({
|
|
265
265
|
rpcCommunicator: this.rpcCommunicator,
|
|
266
|
-
connections: this.connections,
|
|
266
|
+
connections: this.peerManager!.connections,
|
|
267
267
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
268
|
-
addContact: this.
|
|
269
|
-
|
|
270
|
-
connectionManager: this.connectionManager
|
|
268
|
+
addContact: (contact: PeerDescriptor, setActive?: boolean) => this.peerManager!.addContact([contact], setActive),
|
|
269
|
+
handleMessage: (message: Message) => this.handleMessageFromRouter(message),
|
|
271
270
|
})
|
|
272
|
-
this.
|
|
271
|
+
this.recursiveOperationManager = new RecursiveOperationManager({
|
|
273
272
|
rpcCommunicator: this.rpcCommunicator,
|
|
274
273
|
router: this.router,
|
|
275
274
|
sessionTransport: this,
|
|
276
|
-
connections: this.connections,
|
|
275
|
+
connections: this.peerManager!.connections,
|
|
277
276
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
278
277
|
serviceId: this.config.serviceId,
|
|
279
|
-
addContact: this.
|
|
280
|
-
isPeerCloserToIdThanSelf: this.isPeerCloserToIdThanSelf.bind(this),
|
|
278
|
+
addContact: (contact: PeerDescriptor) => this.peerManager!.addContact([contact]),
|
|
281
279
|
localDataStore: this.localDataStore
|
|
282
280
|
})
|
|
283
|
-
this.
|
|
281
|
+
this.storeManager = new StoreManager({
|
|
284
282
|
rpcCommunicator: this.rpcCommunicator,
|
|
285
|
-
|
|
283
|
+
recursiveOperationManager: this.recursiveOperationManager,
|
|
286
284
|
localPeerDescriptor: this.localPeerDescriptor!,
|
|
287
285
|
serviceId: this.config.serviceId,
|
|
288
286
|
highestTtl: this.config.storeHighestTtl,
|
|
289
|
-
maxTtl: this.config.storeMaxTtl,
|
|
290
287
|
redundancyFactor: this.config.storageRedundancyFactor,
|
|
291
288
|
localDataStore: this.localDataStore,
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return this.bucket!.closest(id, n)
|
|
289
|
+
getClosestNeighborsTo: (key: DhtAddress, n?: number) => {
|
|
290
|
+
return this.peerManager!.getClosestNeighborsTo(key, n).map((n) => n.getPeerDescriptor())
|
|
295
291
|
},
|
|
296
|
-
|
|
292
|
+
createRpcRemote: (contact: PeerDescriptor) => {
|
|
293
|
+
return new StoreRpcRemote(
|
|
294
|
+
this.localPeerDescriptor!,
|
|
295
|
+
contact,
|
|
296
|
+
this.rpcCommunicator!,
|
|
297
|
+
StoreRpcClient,
|
|
298
|
+
this.config.rpcRequestTimeout
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
})
|
|
302
|
+
this.on('contactAdded', (peerDescriptor: PeerDescriptor) => {
|
|
303
|
+
this.storeManager!.onContactAdded(peerDescriptor)
|
|
297
304
|
})
|
|
298
305
|
this.bindRpcLocalMethods()
|
|
299
|
-
if (this.connectionManager! && this.config.entryPoints && this.config.entryPoints.length > 0
|
|
300
|
-
&& !areEqualPeerDescriptors(this.config.entryPoints[0], this.localPeerDescriptor!)) {
|
|
301
|
-
this.connectToEntryPoint(this.config.entryPoints[0])
|
|
302
|
-
}
|
|
303
306
|
}
|
|
304
307
|
|
|
305
|
-
private
|
|
306
|
-
this.
|
|
307
|
-
localNodeId: selfId.value,
|
|
308
|
+
private initPeerManager() {
|
|
309
|
+
this.peerManager = new PeerManager({
|
|
308
310
|
numberOfNodesPerKBucket: this.config.numberOfNodesPerKBucket,
|
|
309
|
-
|
|
311
|
+
maxContactListSize: this.config.maxNeighborListSize,
|
|
312
|
+
localNodeId: this.getNodeId(),
|
|
313
|
+
localPeerDescriptor: this.localPeerDescriptor!,
|
|
314
|
+
connectionManager: this.connectionManager!,
|
|
315
|
+
peerDiscoveryQueryBatchSize: this.config.peerDiscoveryQueryBatchSize,
|
|
316
|
+
isLayer0: (this.connectionManager !== undefined),
|
|
317
|
+
createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => this.createDhtNodeRpcRemote(peerDescriptor),
|
|
318
|
+
lockId: this.config.serviceId
|
|
310
319
|
})
|
|
311
|
-
this.
|
|
312
|
-
|
|
313
|
-
this.bucket.on('added', (contact: DhtNodeRpcRemote) => this.onKBucketAdded(contact))
|
|
314
|
-
this.bucket.on('updated', () => {
|
|
315
|
-
// TODO: Update contact info to the connection manager and reconnect
|
|
320
|
+
this.peerManager.on('contactRemoved', (peerDescriptor: PeerDescriptor, activeContacts: PeerDescriptor[]) => {
|
|
321
|
+
this.emit('contactRemoved', peerDescriptor, activeContacts)
|
|
316
322
|
})
|
|
317
|
-
this.
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
323
|
+
this.peerManager.on('contactAdded', (peerDescriptor: PeerDescriptor, activeContacts: PeerDescriptor[]) =>
|
|
324
|
+
this.emit('contactAdded', peerDescriptor, activeContacts)
|
|
325
|
+
)
|
|
326
|
+
this.peerManager.on('randomContactRemoved', (peerDescriptor: PeerDescriptor, activeContacts: PeerDescriptor[]) =>
|
|
327
|
+
this.emit('randomContactRemoved', peerDescriptor, activeContacts)
|
|
328
|
+
)
|
|
329
|
+
this.peerManager.on('randomContactAdded', (peerDescriptor: PeerDescriptor, activeContacts: PeerDescriptor[]) =>
|
|
330
|
+
this.emit('randomContactAdded', peerDescriptor, activeContacts)
|
|
331
|
+
)
|
|
332
|
+
this.peerManager.on('ringContactRemoved', (peerDescriptor: PeerDescriptor, activeContacts: RingContacts) => {
|
|
333
|
+
this.emit('ringContactRemoved', peerDescriptor, activeContacts)
|
|
334
|
+
})
|
|
335
|
+
this.peerManager.on('ringContactAdded', (peerDescriptor: PeerDescriptor, activeContacts: RingContacts) => {
|
|
336
|
+
this.emit('ringContactAdded', peerDescriptor, activeContacts)
|
|
337
|
+
})
|
|
338
|
+
this.peerManager.on('kBucketEmpty', () => {
|
|
339
|
+
if (!this.peerDiscovery!.isJoinOngoing()
|
|
340
|
+
&& this.config.entryPoints
|
|
341
|
+
&& this.config.entryPoints.length > 0
|
|
342
|
+
) {
|
|
343
|
+
setImmediate(async () => {
|
|
344
|
+
// TODO should we catch possible promise rejection?
|
|
345
|
+
await Promise.all(this.config.entryPoints!.map((entryPoint) =>
|
|
346
|
+
this.peerDiscovery!.rejoinDht(entryPoint)
|
|
347
|
+
))
|
|
348
|
+
})
|
|
321
349
|
}
|
|
322
|
-
this.emit('contactRemoved', removedContact.getPeerDescriptor(), activeContacts.map((c) => c.getPeerDescriptor()))
|
|
323
|
-
this.randomPeers!.addContact(
|
|
324
|
-
new DhtNodeRpcRemote(
|
|
325
|
-
this.localPeerDescriptor!,
|
|
326
|
-
removedContact.getPeerDescriptor(),
|
|
327
|
-
toProtoRpcClient(new DhtNodeRpcClient(this.rpcCommunicator!.getRpcClientTransport())),
|
|
328
|
-
this.config.serviceId,
|
|
329
|
-
this.config.rpcRequestTimeout
|
|
330
|
-
)
|
|
331
|
-
)
|
|
332
350
|
})
|
|
333
|
-
this.
|
|
334
|
-
this.
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
351
|
+
this.transport!.on('connected', (peerDescriptor: PeerDescriptor) => {
|
|
352
|
+
this.peerManager!.onContactConnected(peerDescriptor)
|
|
353
|
+
this.router!.onNodeConnected(peerDescriptor)
|
|
354
|
+
this.emit('connected', peerDescriptor)
|
|
355
|
+
})
|
|
338
356
|
this.transport!.on('disconnected', (peerDescriptor: PeerDescriptor, gracefulLeave: boolean) => {
|
|
339
|
-
this.
|
|
357
|
+
this.peerManager!.onContactDisconnected(getNodeIdFromPeerDescriptor(peerDescriptor), gracefulLeave)
|
|
358
|
+
this.router!.onNodeDisconnected(peerDescriptor)
|
|
359
|
+
this.emit('disconnected', peerDescriptor, gracefulLeave)
|
|
340
360
|
})
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const rpcRemote = new DhtNodeRpcRemote(
|
|
344
|
-
this.localPeerDescriptor!,
|
|
345
|
-
peer,
|
|
346
|
-
toProtoRpcClient(new DhtNodeRpcClient(this.rpcCommunicator!.getRpcClientTransport())),
|
|
347
|
-
this.config.serviceId,
|
|
348
|
-
this.config.rpcRequestTimeout
|
|
349
|
-
)
|
|
350
|
-
if (areEqualPeerDescriptors(peer, this.localPeerDescriptor!)) {
|
|
351
|
-
logger.error('own peerdescriptor added to connections in initKBucket')
|
|
352
|
-
}
|
|
353
|
-
this.connections.set(keyFromPeerDescriptor(peer), rpcRemote)
|
|
361
|
+
this.transport!.getConnections().forEach((peer) => {
|
|
362
|
+
this.peerManager!.onContactConnected(peer)
|
|
354
363
|
})
|
|
355
|
-
this.randomPeers = new RandomContactList(selfId, this.config.maxNeighborListSize)
|
|
356
|
-
this.randomPeers.on('contactRemoved', (removedContact: DhtNodeRpcRemote, activeContacts: DhtNodeRpcRemote[]) =>
|
|
357
|
-
this.emit('randomContactRemoved', removedContact.getPeerDescriptor(), activeContacts.map((c) => c.getPeerDescriptor()))
|
|
358
|
-
)
|
|
359
|
-
this.randomPeers.on('newContact', (newContact: DhtNodeRpcRemote, activeContacts: DhtNodeRpcRemote[]) =>
|
|
360
|
-
this.emit('newRandomContact', newContact.getPeerDescriptor(), activeContacts.map((c) => c.getPeerDescriptor()))
|
|
361
|
-
)
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
private onTransportConnected(peerDescriptor: PeerDescriptor): void {
|
|
365
|
-
|
|
366
|
-
if (areEqualPeerDescriptors(this.localPeerDescriptor!, peerDescriptor)) {
|
|
367
|
-
logger.error('onTransportConnected() to self')
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const rpcRemote = new DhtNodeRpcRemote(
|
|
371
|
-
this.localPeerDescriptor!,
|
|
372
|
-
peerDescriptor,
|
|
373
|
-
toProtoRpcClient(new DhtNodeRpcClient(this.rpcCommunicator!.getRpcClientTransport())),
|
|
374
|
-
this.config.serviceId,
|
|
375
|
-
this.config.rpcRequestTimeout
|
|
376
|
-
)
|
|
377
|
-
if (!this.connections.has(PeerID.fromValue(rpcRemote.id).toKey())) {
|
|
378
|
-
this.connections.set(PeerID.fromValue(rpcRemote.id).toKey(), rpcRemote)
|
|
379
|
-
logger.trace('connectionschange add ' + this.connections.size)
|
|
380
|
-
} else {
|
|
381
|
-
logger.trace('new connection not set to connections, there is already a connection with the peer ID')
|
|
382
|
-
}
|
|
383
|
-
logger.trace('connected: ' + getNodeIdFromPeerDescriptor(peerDescriptor) + ' ' + this.connections.size)
|
|
384
|
-
this.emit('connected', peerDescriptor)
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
private onTransportDisconnected(peerDescriptor: PeerDescriptor, gracefulLeave: boolean): void {
|
|
388
|
-
logger.trace('disconnected: ' + getNodeIdFromPeerDescriptor(peerDescriptor))
|
|
389
|
-
this.connections.delete(keyFromPeerDescriptor(peerDescriptor))
|
|
390
|
-
// only remove from bucket if we are on layer 0
|
|
391
|
-
if (this.connectionManager) {
|
|
392
|
-
this.bucket!.remove(peerDescriptor.kademliaId)
|
|
393
|
-
|
|
394
|
-
if (gracefulLeave === true) {
|
|
395
|
-
logger.trace(getNodeIdFromPeerDescriptor(peerDescriptor) + ' ' + 'onTransportDisconnected with gracefulLeave ' + gracefulLeave)
|
|
396
|
-
this.removeContact(peerDescriptor)
|
|
397
|
-
} else {
|
|
398
|
-
logger.trace(getNodeIdFromPeerDescriptor(peerDescriptor) + ' ' + 'onTransportDisconnected with gracefulLeave ' + gracefulLeave)
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
this.emit('disconnected', peerDescriptor, gracefulLeave)
|
|
403
364
|
}
|
|
404
365
|
|
|
405
366
|
private bindRpcLocalMethods(): void {
|
|
406
|
-
if (!this.started || this.
|
|
367
|
+
if (!this.started || this.abortController.signal.aborted) {
|
|
407
368
|
return
|
|
408
369
|
}
|
|
409
370
|
const dhtNodeRpcLocal = new DhtNodeRpcLocal({
|
|
410
|
-
bucket: this.bucket!,
|
|
411
|
-
serviceId: this.config.serviceId,
|
|
412
371
|
peerDiscoveryQueryBatchSize: this.config.peerDiscoveryQueryBatchSize,
|
|
413
|
-
|
|
414
|
-
|
|
372
|
+
getClosestPeersTo: (nodeId: DhtAddress, limit: number) => {
|
|
373
|
+
return this.peerManager!.getClosestNeighborsTo(nodeId, limit)
|
|
374
|
+
.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor())
|
|
375
|
+
},
|
|
376
|
+
getClosestRingPeersTo: (ringIdRaw: RingIdRaw, limit: number) => {
|
|
377
|
+
return this.getClosestRingContactsTo(ringIdRaw, limit)
|
|
378
|
+
},
|
|
379
|
+
addContact: (contact: PeerDescriptor) => this.peerManager!.addContact([contact]),
|
|
380
|
+
removeContact: (nodeId: DhtAddress) => this.removeContact(nodeId)
|
|
415
381
|
})
|
|
416
382
|
this.rpcCommunicator!.registerRpcMethod(ClosestPeersRequest, ClosestPeersResponse, 'getClosestPeers',
|
|
417
383
|
(req: ClosestPeersRequest, context) => dhtNodeRpcLocal.getClosestPeers(req, context))
|
|
384
|
+
this.rpcCommunicator!.registerRpcMethod(ClosestRingPeersRequest, ClosestRingPeersResponse, 'getClosestRingPeers',
|
|
385
|
+
(req: ClosestRingPeersRequest, context) => dhtNodeRpcLocal.getClosestRingPeers(req, context))
|
|
418
386
|
this.rpcCommunicator!.registerRpcMethod(PingRequest, PingResponse, 'ping',
|
|
419
387
|
(req: PingRequest, context) => dhtNodeRpcLocal.ping(req, context))
|
|
420
388
|
this.rpcCommunicator!.registerRpcNotification(LeaveNotice, 'leaveNotice',
|
|
421
|
-
(
|
|
389
|
+
(_req: LeaveNotice, context) => dhtNodeRpcLocal.leaveNotice(context))
|
|
422
390
|
const externalApiRpcLocal = new ExternalApiRpcLocal({
|
|
423
|
-
|
|
424
|
-
return this.
|
|
391
|
+
executeRecursiveOperation: (key: DhtAddress, operation: RecursiveOperation, excludedPeer: DhtAddress) => {
|
|
392
|
+
return this.recursiveOperationManager!.execute(key, operation, excludedPeer)
|
|
425
393
|
},
|
|
426
|
-
storeDataToDht: (key:
|
|
394
|
+
storeDataToDht: (key: DhtAddress, data: Any, creator?: DhtAddress) => this.storeDataToDht(key, data, creator)
|
|
427
395
|
})
|
|
428
396
|
this.rpcCommunicator!.registerRpcMethod(
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
'
|
|
432
|
-
(req:
|
|
433
|
-
{ timeout: 10000 }
|
|
397
|
+
ExternalFetchDataRequest,
|
|
398
|
+
ExternalFetchDataResponse,
|
|
399
|
+
'externalFetchData',
|
|
400
|
+
(req: ExternalFetchDataRequest, context: ServerCallContext) => externalApiRpcLocal.externalFetchData(req, context),
|
|
401
|
+
{ timeout: 10000 } // TODO use config option or named constant?
|
|
434
402
|
)
|
|
435
403
|
this.rpcCommunicator!.registerRpcMethod(
|
|
436
404
|
ExternalStoreDataRequest,
|
|
437
405
|
ExternalStoreDataResponse,
|
|
438
406
|
'externalStoreData',
|
|
439
|
-
(req: ExternalStoreDataRequest) => externalApiRpcLocal.externalStoreData(req),
|
|
440
|
-
{ timeout: 10000 }
|
|
407
|
+
(req: ExternalStoreDataRequest, context: ServerCallContext) => externalApiRpcLocal.externalStoreData(req, context),
|
|
408
|
+
{ timeout: 10000 } // TODO use config option or named constant?
|
|
441
409
|
)
|
|
442
410
|
}
|
|
443
411
|
|
|
444
|
-
private
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
412
|
+
private handleMessageFromTransport(message: Message): void {
|
|
413
|
+
if (message.serviceId === this.config.serviceId) {
|
|
414
|
+
this.rpcCommunicator?.handleMessageFromPeer(message)
|
|
415
|
+
}
|
|
448
416
|
}
|
|
449
|
-
|
|
450
|
-
private
|
|
417
|
+
|
|
418
|
+
private handleMessageFromRouter(message: Message): void {
|
|
451
419
|
if (message.serviceId === this.config.serviceId) {
|
|
452
|
-
logger.trace('callig this.handleMessageFromPeer ' + getNodeIdFromPeerDescriptor(message.sourceDescriptor!)
|
|
453
|
-
+ ' ' + message.serviceId + ' ' + message.messageId)
|
|
454
420
|
this.rpcCommunicator?.handleMessageFromPeer(message)
|
|
421
|
+
} else if (this.connectionManager?.handleIncomingMessage(message)) {
|
|
422
|
+
// message was handled by connectionManager
|
|
455
423
|
} else {
|
|
456
|
-
logger.trace('emit "message" ' + getNodeIdFromPeerDescriptor(message.sourceDescriptor!)
|
|
457
|
-
+ ' ' + message.serviceId + ' ' + message.messageId)
|
|
458
424
|
this.emit('message', message)
|
|
459
425
|
}
|
|
460
426
|
}
|
|
461
427
|
|
|
462
428
|
private generatePeerDescriptorCallBack(connectivityResponse: ConnectivityResponse) {
|
|
463
|
-
if (this.config.peerDescriptor) {
|
|
429
|
+
if (this.config.peerDescriptor !== undefined) {
|
|
464
430
|
this.localPeerDescriptor = this.config.peerDescriptor
|
|
465
431
|
} else {
|
|
466
|
-
this.localPeerDescriptor = createPeerDescriptor(connectivityResponse, this.config.
|
|
432
|
+
this.localPeerDescriptor = createPeerDescriptor(connectivityResponse, this.region!, this.config.nodeId)
|
|
467
433
|
}
|
|
468
434
|
return this.localPeerDescriptor
|
|
469
435
|
}
|
|
470
436
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const sortingList: SortedContactList<DhtNodeRpcRemote> = new SortedContactList(this.getNodeId(), 100)
|
|
476
|
-
sortingList.addContacts(oldContacts)
|
|
477
|
-
const sortedContacts = sortingList.getAllContacts()
|
|
478
|
-
this.connectionManager?.weakUnlockConnection(sortedContacts[sortedContacts.length - 1].getPeerDescriptor())
|
|
479
|
-
this.bucket?.remove(sortedContacts[sortedContacts.length - 1].getPeerId().value)
|
|
480
|
-
this.bucket!.add(newContact)
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
private onKBucketRemoved(contact: DhtNodeRpcRemote): void {
|
|
484
|
-
if (this.stopped) {
|
|
485
|
-
return
|
|
486
|
-
}
|
|
487
|
-
this.connectionManager?.weakUnlockConnection(contact.getPeerDescriptor())
|
|
488
|
-
logger.trace(`Removed contact ${getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())}`)
|
|
489
|
-
if (this.bucket!.count() === 0
|
|
490
|
-
&& !this.peerDiscovery!.isJoinOngoing()
|
|
491
|
-
&& this.config.entryPoints
|
|
492
|
-
&& this.config.entryPoints.length > 0
|
|
493
|
-
) {
|
|
494
|
-
setImmediate(async () => {
|
|
495
|
-
await Promise.all(this.config.entryPoints!.map((entryPoint) =>
|
|
496
|
-
this.peerDiscovery!.rejoinDht(entryPoint)
|
|
497
|
-
))
|
|
498
|
-
})
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
private onKBucketAdded(contact: DhtNodeRpcRemote): void {
|
|
503
|
-
if (this.stopped) {
|
|
504
|
-
return
|
|
505
|
-
}
|
|
506
|
-
if (!contact.getPeerId().equals(this.getNodeId())) {
|
|
507
|
-
// Important to lock here, before the ping result is known
|
|
508
|
-
this.connectionManager?.weakLockConnection(contact.getPeerDescriptor())
|
|
509
|
-
if (this.connections.has(contact.getPeerId().toKey())) {
|
|
510
|
-
logger.trace(`Added new contact ${getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())}`)
|
|
511
|
-
} else { // open connection by pinging
|
|
512
|
-
logger.trace('starting ping ' + getNodeIdFromPeerDescriptor(contact.getPeerDescriptor()))
|
|
513
|
-
contact.ping().then((result) => {
|
|
514
|
-
if (result) {
|
|
515
|
-
logger.trace(`Added new contact ${getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())}`)
|
|
516
|
-
} else {
|
|
517
|
-
logger.trace('ping failed ' + getNodeIdFromPeerDescriptor(contact.getPeerDescriptor()))
|
|
518
|
-
this.connectionManager?.weakUnlockConnection(contact.getPeerDescriptor())
|
|
519
|
-
this.removeContact(contact.getPeerDescriptor())
|
|
520
|
-
this.addClosestContactToBucket()
|
|
521
|
-
}
|
|
522
|
-
return
|
|
523
|
-
}).catch((_e) => {
|
|
524
|
-
this.connectionManager?.weakUnlockConnection(contact.getPeerDescriptor())
|
|
525
|
-
this.removeContact(contact.getPeerDescriptor())
|
|
526
|
-
this.addClosestContactToBucket()
|
|
527
|
-
})
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
private addClosestContactToBucket(): void {
|
|
533
|
-
if (!this.started || this.stopped) {
|
|
534
|
-
return
|
|
535
|
-
}
|
|
536
|
-
const closest = this.getClosestActiveContactNotInBucket()
|
|
537
|
-
if (closest) {
|
|
538
|
-
this.addNewContact(closest.getPeerDescriptor())
|
|
539
|
-
}
|
|
437
|
+
public getClosestContacts(limit?: number): PeerDescriptor[] {
|
|
438
|
+
return this.peerManager!.getClosestContactsTo(
|
|
439
|
+
this.getNodeId(),
|
|
440
|
+
limit).map((peer) => peer.getPeerDescriptor())
|
|
540
441
|
}
|
|
541
442
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
443
|
+
public getClosestRingContactsTo(ringIdRaw: RingIdRaw, limit?: number): RingContacts {
|
|
444
|
+
const closest = this.peerManager!.getClosestRingContactsTo(ringIdRaw, limit)
|
|
445
|
+
return {
|
|
446
|
+
left: closest.left.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor()),
|
|
447
|
+
right: closest.right.map((dhtPeer: DhtNodeRpcRemote) => dhtPeer.getPeerDescriptor())
|
|
547
448
|
}
|
|
548
|
-
return undefined
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
public getClosestContacts(maxCount?: number): PeerDescriptor[] {
|
|
552
|
-
return this.neighborList!.getClosestContacts(maxCount).map((c) => c.getPeerDescriptor())
|
|
553
449
|
}
|
|
554
450
|
|
|
555
|
-
public getNodeId():
|
|
556
|
-
return
|
|
451
|
+
public getNodeId(): DhtAddress {
|
|
452
|
+
return getNodeIdFromPeerDescriptor(this.localPeerDescriptor!)
|
|
557
453
|
}
|
|
558
454
|
|
|
559
|
-
public
|
|
560
|
-
return this.
|
|
455
|
+
public getNeighborCount(): number {
|
|
456
|
+
return this.peerManager!.getNeighborCount()
|
|
561
457
|
}
|
|
562
458
|
|
|
563
|
-
|
|
564
|
-
if (!this.started
|
|
459
|
+
public removeContact(nodeId: DhtAddress): void {
|
|
460
|
+
if (!this.started) { // the stopped state is checked in PeerManager
|
|
565
461
|
return
|
|
566
462
|
}
|
|
567
|
-
|
|
568
|
-
logger.trace(`Adding new contact ${getNodeIdFromPeerDescriptor(contact)}`)
|
|
569
|
-
const rpcRemote = new DhtNodeRpcRemote(
|
|
570
|
-
this.localPeerDescriptor!,
|
|
571
|
-
contact,
|
|
572
|
-
toProtoRpcClient(new DhtNodeRpcClient(this.rpcCommunicator!.getRpcClientTransport())),
|
|
573
|
-
this.config.serviceId,
|
|
574
|
-
this.config.rpcRequestTimeout
|
|
575
|
-
)
|
|
576
|
-
if (!this.bucket!.get(contact.kademliaId) && !this.neighborList!.getContact(peerIdFromPeerDescriptor(contact))) {
|
|
577
|
-
this.neighborList!.addContact(rpcRemote)
|
|
578
|
-
if (setActive) {
|
|
579
|
-
const peerId = peerIdFromPeerDescriptor(contact)
|
|
580
|
-
this.neighborList!.setActive(peerId)
|
|
581
|
-
}
|
|
582
|
-
this.bucket!.add(rpcRemote)
|
|
583
|
-
} else {
|
|
584
|
-
this.randomPeers!.addContact(rpcRemote)
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
private connectToEntryPoint(entryPoint: PeerDescriptor): void {
|
|
590
|
-
this.connectionManager!.lockConnection(entryPoint, 'temporary-layer0-connection')
|
|
591
|
-
this.entryPointDisconnectTimeout = setTimeout(() => {
|
|
592
|
-
this.connectionManager!.unlockConnection(entryPoint, 'temporary-layer0-connection')
|
|
593
|
-
}, 10 * 1000)
|
|
463
|
+
this.peerManager!.removeContact(nodeId)
|
|
594
464
|
}
|
|
595
465
|
|
|
596
|
-
public
|
|
597
|
-
if (!this.started || this.
|
|
466
|
+
public async send(msg: Message): Promise<void> {
|
|
467
|
+
if (!this.started || this.abortController.signal.aborted) {
|
|
598
468
|
return
|
|
599
469
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
this.bucket!.remove(peerId.value)
|
|
603
|
-
this.neighborList!.removeContact(peerId)
|
|
604
|
-
this.randomPeers!.removeContact(peerId)
|
|
470
|
+
const reachableThrough = this.peerDiscovery!.isJoinOngoing() ? this.getConnectedEntryPoints() : []
|
|
471
|
+
this.router!.send(msg, reachableThrough)
|
|
605
472
|
}
|
|
606
473
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
const reachableThrough = this.peerDiscovery!.isJoinOngoing() ? this.config.entryPoints ?? [] : []
|
|
612
|
-
await this.router!.send(msg, reachableThrough)
|
|
474
|
+
private getConnectedEntryPoints(): PeerDescriptor[] {
|
|
475
|
+
return this.config.entryPoints !== undefined ? this.config.entryPoints.filter((entryPoint) =>
|
|
476
|
+
this.peerManager!.connections.has(getNodeIdFromPeerDescriptor(entryPoint))
|
|
477
|
+
) : []
|
|
613
478
|
}
|
|
614
479
|
|
|
615
|
-
public async joinDht(entryPointDescriptors: PeerDescriptor[],
|
|
480
|
+
public async joinDht(entryPointDescriptors: PeerDescriptor[], doAdditionalDistantPeerDiscovery?: boolean, retry?: boolean): Promise<void> {
|
|
616
481
|
if (!this.started) {
|
|
617
482
|
throw new Error('Cannot join DHT before calling start() on DhtNode')
|
|
618
483
|
}
|
|
619
|
-
await
|
|
620
|
-
this.peerDiscovery!.joinDht(entryPoint, doAdditionalRandomPeerDiscovery, retry)
|
|
621
|
-
))
|
|
484
|
+
await this.peerDiscovery!.joinDht(entryPointDescriptors, doAdditionalDistantPeerDiscovery, retry)
|
|
622
485
|
}
|
|
623
486
|
|
|
624
|
-
public async
|
|
625
|
-
|
|
487
|
+
public async joinRing(): Promise<void> {
|
|
488
|
+
if (!this.started) {
|
|
489
|
+
throw new Error('Cannot join ring before calling start() on DhtNode')
|
|
490
|
+
}
|
|
491
|
+
await this.peerDiscovery!.joinRing()
|
|
626
492
|
}
|
|
627
493
|
|
|
628
|
-
public async storeDataToDht(key:
|
|
629
|
-
|
|
630
|
-
|
|
494
|
+
public async storeDataToDht(key: DhtAddress, data: Any, creator?: DhtAddress): Promise<PeerDescriptor[]> {
|
|
495
|
+
const connectedEntryPoints = this.getConnectedEntryPoints()
|
|
496
|
+
if (this.peerDiscovery!.isJoinOngoing() && connectedEntryPoints.length > 0) {
|
|
497
|
+
return this.storeDataToDhtViaPeer(key, data, sample(connectedEntryPoints)!)
|
|
631
498
|
}
|
|
632
|
-
return this.
|
|
499
|
+
return this.storeManager!.storeDataToDht(key, data, creator ?? this.getNodeId())
|
|
633
500
|
}
|
|
634
501
|
|
|
635
|
-
public async
|
|
502
|
+
public async storeDataToDhtViaPeer(key: DhtAddress, data: Any, peer: PeerDescriptor): Promise<PeerDescriptor[]> {
|
|
636
503
|
const rpcRemote = new ExternalApiRpcRemote(
|
|
637
504
|
this.localPeerDescriptor!,
|
|
638
505
|
peer,
|
|
639
|
-
this.
|
|
640
|
-
|
|
506
|
+
this.rpcCommunicator!,
|
|
507
|
+
ExternalApiRpcClient
|
|
641
508
|
)
|
|
642
509
|
return await rpcRemote.storeData(key, data)
|
|
643
510
|
}
|
|
644
511
|
|
|
645
|
-
public async
|
|
646
|
-
|
|
647
|
-
|
|
512
|
+
public async fetchDataFromDht(key: DhtAddress): Promise<DataEntry[]> {
|
|
513
|
+
const connectedEntryPoints = this.getConnectedEntryPoints()
|
|
514
|
+
if (this.peerDiscovery!.isJoinOngoing() && connectedEntryPoints.length > 0) {
|
|
515
|
+
return this.fetchDataFromDhtViaPeer(key, sample(connectedEntryPoints)!)
|
|
648
516
|
}
|
|
649
|
-
const result = await this.
|
|
650
|
-
return result.dataEntries ?? []
|
|
517
|
+
const result = await this.recursiveOperationManager!.execute(key, RecursiveOperation.FETCH_DATA)
|
|
518
|
+
return result.dataEntries ?? [] // TODO is this fallback needed?
|
|
651
519
|
}
|
|
652
520
|
|
|
653
|
-
public async
|
|
654
|
-
if (!this.stopped) {
|
|
655
|
-
return this.storeRpcLocal!.deleteDataFromDht(idToDelete)
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
public async findDataViaPeer(idToFind: Uint8Array, peer: PeerDescriptor): Promise<DataEntry[]> {
|
|
521
|
+
public async fetchDataFromDhtViaPeer(key: DhtAddress, peer: PeerDescriptor): Promise<DataEntry[]> {
|
|
660
522
|
const rpcRemote = new ExternalApiRpcRemote(
|
|
661
523
|
this.localPeerDescriptor!,
|
|
662
524
|
peer,
|
|
663
|
-
this.
|
|
664
|
-
|
|
525
|
+
this.rpcCommunicator!,
|
|
526
|
+
ExternalApiRpcClient
|
|
665
527
|
)
|
|
666
|
-
return await rpcRemote.
|
|
528
|
+
return await rpcRemote.externalFetchData(key)
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
public async deleteDataFromDht(key: DhtAddress, waitForCompletion: boolean): Promise<void> {
|
|
532
|
+
if (!this.abortController.signal.aborted) {
|
|
533
|
+
await this.recursiveOperationManager!.execute(key, RecursiveOperation.DELETE_DATA, undefined, waitForCompletion)
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
async findClosestNodesFromDht(key: DhtAddress): Promise<PeerDescriptor[]> {
|
|
538
|
+
const result = await this.recursiveOperationManager!.execute(key, RecursiveOperation.FIND_CLOSEST_NODES)
|
|
539
|
+
return result.closestNodes
|
|
667
540
|
}
|
|
668
541
|
|
|
669
542
|
public getTransport(): ITransport {
|
|
@@ -674,32 +547,38 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
674
547
|
return this.localPeerDescriptor!
|
|
675
548
|
}
|
|
676
549
|
|
|
677
|
-
public
|
|
678
|
-
return Array.from(this.connections.values()).map((peer) => peer.getPeerDescriptor())
|
|
550
|
+
public getConnections(): PeerDescriptor[] {
|
|
551
|
+
return Array.from(this.peerManager!.connections.values()).map((peer) => peer.getPeerDescriptor())
|
|
679
552
|
}
|
|
680
553
|
|
|
681
|
-
public
|
|
682
|
-
return this.
|
|
554
|
+
public getNeighbors(): PeerDescriptor[] {
|
|
555
|
+
return this.started ? this.peerManager!.getNeighbors() : []
|
|
683
556
|
}
|
|
684
557
|
|
|
685
|
-
public
|
|
686
|
-
return this.
|
|
558
|
+
public getConnectionCount(): number {
|
|
559
|
+
return this.peerManager!.getConnectionCount()
|
|
687
560
|
}
|
|
688
561
|
|
|
689
|
-
public
|
|
690
|
-
return this.connectionManager!.
|
|
562
|
+
public getLocalLockedConnectionCount(): number {
|
|
563
|
+
return this.connectionManager!.getLocalLockedConnectionCount()
|
|
691
564
|
}
|
|
692
565
|
|
|
693
|
-
public
|
|
694
|
-
return this.connectionManager!.
|
|
566
|
+
public getRemoteLockedConnectionCount(): number {
|
|
567
|
+
return this.connectionManager!.getRemoteLockedConnectionCount()
|
|
695
568
|
}
|
|
696
569
|
|
|
697
|
-
public
|
|
698
|
-
return this.connectionManager!.
|
|
570
|
+
public getWeakLockedConnectionCount(): number {
|
|
571
|
+
return this.connectionManager!.getWeakLockedConnectionCount()
|
|
699
572
|
}
|
|
700
573
|
|
|
701
574
|
public async waitForNetworkConnectivity(): Promise<void> {
|
|
702
|
-
await waitForCondition(() =>
|
|
575
|
+
await waitForCondition(() => {
|
|
576
|
+
if (!this.peerManager) {
|
|
577
|
+
return false
|
|
578
|
+
} else {
|
|
579
|
+
return (this.peerManager.getConnectionCount() > 0)
|
|
580
|
+
}
|
|
581
|
+
}, this.config.networkConnectivityTimeout, 100, this.abortController.signal)
|
|
703
582
|
}
|
|
704
583
|
|
|
705
584
|
public hasJoined(): boolean {
|
|
@@ -707,35 +586,35 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
|
|
|
707
586
|
}
|
|
708
587
|
|
|
709
588
|
public async stop(): Promise<void> {
|
|
710
|
-
if (this.
|
|
589
|
+
if (this.abortController.signal.aborted || !this.started) {
|
|
711
590
|
return
|
|
712
591
|
}
|
|
713
592
|
logger.trace('stop()')
|
|
714
|
-
this.
|
|
715
|
-
|
|
716
|
-
if (this.entryPointDisconnectTimeout) {
|
|
717
|
-
clearTimeout(this.entryPointDisconnectTimeout)
|
|
718
|
-
}
|
|
719
|
-
this.bucket!.toArray().forEach((rpcRemote: DhtNodeRpcRemote) => {
|
|
720
|
-
rpcRemote.leaveNotice()
|
|
721
|
-
this.bucket!.remove(rpcRemote.id)
|
|
722
|
-
})
|
|
723
|
-
this.bucket!.removeAllListeners()
|
|
593
|
+
this.abortController.abort()
|
|
594
|
+
await this.storeManager!.destroy()
|
|
724
595
|
this.localDataStore.clear()
|
|
725
|
-
this.
|
|
726
|
-
this.randomPeers!.stop()
|
|
596
|
+
this.peerManager?.stop()
|
|
727
597
|
this.rpcCommunicator!.stop()
|
|
728
598
|
this.router!.stop()
|
|
729
|
-
this.
|
|
599
|
+
this.recursiveOperationManager!.stop()
|
|
730
600
|
this.peerDiscovery!.stop()
|
|
731
601
|
if (this.config.transport === undefined) {
|
|
732
|
-
// if the transport was not given in config, the instance was created in start() and
|
|
602
|
+
// if the transport was not given in config, the instance was created in start() and
|
|
733
603
|
// this component is responsible for stopping it
|
|
734
604
|
await this.transport!.stop()
|
|
735
605
|
}
|
|
736
606
|
this.transport = undefined
|
|
737
607
|
this.connectionManager = undefined
|
|
738
|
-
this.connections.clear()
|
|
739
608
|
this.removeAllListeners()
|
|
740
609
|
}
|
|
610
|
+
|
|
611
|
+
private createDhtNodeRpcRemote(peerDescriptor: PeerDescriptor) {
|
|
612
|
+
return new DhtNodeRpcRemote(
|
|
613
|
+
this.localPeerDescriptor!,
|
|
614
|
+
peerDescriptor,
|
|
615
|
+
this.config.serviceId,
|
|
616
|
+
this.rpcCommunicator!,
|
|
617
|
+
this.config.rpcRequestTimeout
|
|
618
|
+
)
|
|
619
|
+
}
|
|
741
620
|
}
|