@streamr/dht 100.0.0-testnet-three.6 → 100.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/package.json +12 -8
- package/dist/src/connection/ConnectionLockRpcLocal.d.ts +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.d.ts +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.js +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
- package/dist/src/connection/{ConnectionLockHandler.d.ts → ConnectionLockStates.d.ts} +3 -3
- package/dist/src/connection/{ConnectionLockHandler.js → ConnectionLockStates.js} +17 -9
- package/dist/src/connection/ConnectionLockStates.js.map +1 -0
- package/dist/src/connection/ConnectionManager.d.ts +9 -7
- package/dist/src/connection/ConnectionManager.js +16 -18
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.js +1 -1
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/Handshaker.js +6 -13
- package/dist/src/connection/Handshaker.js.map +1 -1
- package/dist/src/connection/ManagedConnection.d.ts +2 -2
- package/dist/src/connection/ManagedConnection.js +8 -8
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/connectivityChecker.d.ts +1 -1
- package/dist/src/connection/connectivityChecker.js +8 -8
- package/dist/src/connection/connectivityChecker.js.map +1 -1
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -2
- package/dist/src/connection/connectivityRequestHandler.js +10 -11
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.d.ts +1 -0
- package/dist/src/connection/webrtc/WebrtcConnector.js +13 -8
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +2 -0
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +4 -6
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/AbstractWebsocketClientConnection.d.ts +28 -0
- package/dist/src/connection/websocket/{ClientWebsocket.js → AbstractWebsocketClientConnection.js} +42 -68
- package/dist/src/connection/websocket/AbstractWebsocketClientConnection.js.map +1 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.d.ts +7 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.js +39 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.js.map +1 -0
- package/dist/src/connection/websocket/WebsocketConnector.js +26 -23
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServer.js +25 -35
- package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
- package/dist/src/connection/websocket/{ServerWebsocket.d.ts → WebsocketServerConnection.d.ts} +4 -5
- package/dist/src/connection/websocket/{ServerWebsocket.js → WebsocketServerConnection.js} +18 -51
- package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -0
- package/dist/src/dht/DhtNode.d.ts +15 -8
- package/dist/src/dht/DhtNode.js +62 -31
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +5 -1
- package/dist/src/dht/DhtNodeRpcLocal.js +10 -0
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcRemote.d.ts +3 -0
- package/dist/src/dht/DhtNodeRpcRemote.js +16 -1
- package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcLocal.d.ts +2 -2
- package/dist/src/dht/ExternalApiRpcLocal.js +3 -3
- package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.d.ts +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.js +2 -2
- package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +15 -3
- package/dist/src/dht/PeerManager.js +54 -40
- package/dist/src/dht/PeerManager.js.map +1 -1
- package/dist/src/dht/contact/RingContactList.d.ts +31 -0
- package/dist/src/dht/contact/RingContactList.js +133 -0
- package/dist/src/dht/contact/RingContactList.js.map +1 -0
- package/dist/src/dht/contact/SortedContactList.d.ts +2 -1
- package/dist/src/dht/contact/SortedContactList.js +19 -17
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- package/dist/src/dht/contact/ringIdentifiers.d.ts +16 -0
- package/dist/src/dht/contact/ringIdentifiers.js +54 -0
- package/dist/src/dht/contact/ringIdentifiers.js.map +1 -0
- package/dist/src/dht/discovery/DiscoverySession.js +3 -1
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +6 -2
- package/dist/src/dht/discovery/PeerDiscovery.js +41 -4
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/discovery/RingDiscoverySession.d.ts +29 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js +125 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js +0 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +0 -1
- package/dist/src/dht/routing/Router.js +0 -1
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcLocal.d.ts +0 -1
- package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcRemote.js +2 -2
- package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.js +2 -2
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/store/LocalDataStore.js +2 -2
- package/dist/src/dht/store/LocalDataStore.js.map +1 -1
- package/dist/src/dht/store/StoreManager.js +2 -2
- package/dist/src/dht/store/StoreManager.js.map +1 -1
- package/dist/src/exports.d.ts +3 -2
- package/dist/src/exports.js +3 -3
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/createPeerDescriptor.d.ts +1 -1
- package/dist/src/helpers/createPeerDescriptor.js +2 -1
- package/dist/src/helpers/createPeerDescriptor.js.map +1 -1
- package/dist/src/helpers/version.d.ts +6 -0
- package/dist/src/helpers/version.js +38 -0
- package/dist/src/helpers/version.js.map +1 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +16 -6
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +11 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +98 -87
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +45 -49
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +10 -4
- package/dist/src/transport/RoutingRpcCommunicator.js +0 -2
- package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
- package/karma.config.js +4 -1
- package/package.json +12 -8
- package/protos/DhtRpc.proto +21 -21
- package/src/connection/ConnectionLockRpcLocal.ts +1 -1
- package/src/connection/ConnectionLockRpcRemote.ts +2 -2
- package/src/connection/{ConnectionLockHandler.ts → ConnectionLockStates.ts} +14 -6
- package/src/connection/ConnectionManager.ts +21 -22
- package/src/connection/ConnectorFacade.ts +1 -2
- package/src/connection/Handshaker.ts +7 -15
- package/src/connection/ManagedConnection.ts +8 -8
- package/src/connection/connectivityChecker.ts +9 -10
- package/src/connection/connectivityRequestHandler.ts +16 -16
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +18 -0
- package/src/connection/webrtc/NodeWebrtcConnection.ts +1 -1
- package/src/connection/webrtc/WebrtcConnector.ts +14 -8
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +5 -5
- package/src/connection/websocket/{ClientWebsocket.ts → AbstractWebsocketClientConnection.ts} +57 -70
- package/src/connection/websocket/BrowserWebsocketClientConnection.ts +44 -0
- package/src/connection/websocket/NodeWebsocketClientConnection.ts +39 -0
- package/src/connection/websocket/WebsocketConnector.ts +27 -28
- package/src/connection/websocket/WebsocketServer.ts +27 -42
- package/src/connection/websocket/{ServerWebsocket.ts → WebsocketServerConnection.ts} +15 -56
- package/src/dht/DhtNode.ts +85 -50
- package/src/dht/DhtNodeRpcLocal.ts +16 -0
- package/src/dht/DhtNodeRpcRemote.ts +19 -1
- package/src/dht/ExternalApiRpcLocal.ts +5 -5
- package/src/dht/ExternalApiRpcRemote.ts +4 -4
- package/src/dht/PeerManager.ts +70 -44
- package/src/dht/contact/RingContactList.ts +151 -0
- package/src/dht/contact/SortedContactList.ts +22 -18
- package/src/dht/contact/ringIdentifiers.ts +62 -0
- package/src/dht/discovery/DiscoverySession.ts +3 -1
- package/src/dht/discovery/PeerDiscovery.ts +45 -6
- package/src/dht/discovery/RingDiscoverySession.ts +162 -0
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +1 -1
- package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +1 -1
- package/src/dht/recursive-operation/RecursiveOperationSession.ts +1 -3
- package/src/dht/routing/Router.ts +0 -2
- package/src/dht/routing/RouterRpcLocal.ts +0 -1
- package/src/dht/routing/RouterRpcRemote.ts +2 -2
- package/src/dht/routing/RoutingSession.ts +2 -2
- package/src/dht/store/LocalDataStore.ts +1 -1
- package/src/dht/store/StoreManager.ts +2 -2
- package/src/exports.ts +3 -2
- package/src/helpers/createPeerDescriptor.ts +2 -1
- package/src/helpers/version.ts +32 -0
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +22 -9
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +10 -4
- package/src/proto/packages/dht/protos/DhtRpc.ts +122 -100
- package/src/transport/RoutingRpcCommunicator.ts +1 -2
- package/test/benchmark/Find.test.ts +3 -4
- package/test/benchmark/KademliaCorrectness.test.ts +14 -8
- package/test/benchmark/RingCorrectness.test.ts +157 -0
- package/test/benchmark/WebsocketServerMemoryLeak.test.ts +2 -2
- package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +72 -0
- package/test/data/generateGroundTruthData.ts +2 -2
- package/test/end-to-end/memory-leak.test.ts +1 -2
- package/test/integration/ConnectionManager.test.ts +28 -10
- package/test/integration/ConnectivityChecking.test.ts +3 -15
- package/test/integration/DhtNodeExternalAPI.test.ts +6 -6
- package/test/integration/Find.test.ts +6 -6
- package/test/integration/Layer1-scale.test.ts +0 -1
- package/test/integration/ReplicateData.test.ts +4 -4
- package/test/integration/RouteMessage.test.ts +1 -6
- package/test/integration/RouterRpcRemote.test.ts +1 -3
- package/test/integration/SimultaneousConnections.test.ts +9 -10
- package/test/integration/Store.test.ts +4 -4
- package/test/integration/StoreAndDelete.test.ts +5 -5
- package/test/integration/StoreOnDhtWithThreeNodes.test.ts +5 -5
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +3 -3
- package/test/integration/WebrtcConnectionManagement.test.ts +3 -9
- package/test/integration/Websocket.test.ts +2 -2
- package/test/integration/WebsocketConnectionManagement.test.ts +1 -6
- package/test/integration/rpc-connections-over-webrpc.test.ts +1 -2
- package/test/unit/PeerManager.test.ts +44 -10
- package/test/unit/RecursiveOperationManager.test.ts +14 -8
- package/test/unit/RecursiveOperationSession.test.ts +1 -1
- package/test/unit/Router.test.ts +0 -3
- package/test/unit/RoutingSession.test.ts +1 -2
- package/test/unit/connectivityRequestHandler.test.ts +5 -9
- package/test/unit/createPeerDescriptor.test.ts +12 -6
- package/test/unit/version.test.ts +18 -0
- package/test/utils/utils.ts +60 -47
- package/tsconfig.browser.json +2 -1
- package/tsconfig.jest.json +4 -2
- package/tsconfig.node.json +4 -2
- package/dist/src/connection/ConnectionLockHandler.js.map +0 -1
- package/dist/src/connection/websocket/ClientWebsocket.d.ts +0 -17
- package/dist/src/connection/websocket/ClientWebsocket.js.map +0 -1
- package/dist/src/connection/websocket/ServerWebsocket.js.map +0 -1
- package/dist/src/helpers/MapWithTtl.d.ts +0 -14
- package/dist/src/helpers/MapWithTtl.js +0 -60
- package/dist/src/helpers/MapWithTtl.js.map +0 -1
- package/dist/src/helpers/versionCompatibility.d.ts +0 -2
- package/dist/src/helpers/versionCompatibility.js +0 -18
- package/dist/src/helpers/versionCompatibility.js.map +0 -1
- package/src/helpers/MapWithTtl.ts +0 -71
- package/src/helpers/versionCompatibility.ts +0 -13
- package/test/unit/versionCompatibility.test.ts +0 -16
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { Logger, runAndWaitForEvents3 } from '@streamr/utils'
|
|
2
|
+
import EventEmitter from 'eventemitter3'
|
|
3
|
+
import { v4 } from 'uuid'
|
|
4
|
+
import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
|
|
5
|
+
import { PeerManager } from '../PeerManager'
|
|
6
|
+
import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
|
|
7
|
+
import { DhtAddress, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
8
|
+
import { RingId, RingIdRaw, getLeftDistance, getRingIdFromPeerDescriptor, getRingIdFromRaw } from '../contact/ringIdentifiers'
|
|
9
|
+
import { RingContacts } from '../contact/RingContactList'
|
|
10
|
+
|
|
11
|
+
const logger = new Logger(module)
|
|
12
|
+
|
|
13
|
+
interface RingDiscoverySessionEvents {
|
|
14
|
+
discoveryCompleted: () => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface RingDiscoverySessionConfig {
|
|
18
|
+
targetId: RingIdRaw
|
|
19
|
+
parallelism: number
|
|
20
|
+
noProgressLimit: number
|
|
21
|
+
peerManager: PeerManager
|
|
22
|
+
// Note that contacted peers will be mutated by the DiscoverySession or other parallel sessions
|
|
23
|
+
contactedPeers: Set<DhtAddress>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class RingDiscoverySession {
|
|
27
|
+
|
|
28
|
+
public readonly id = v4()
|
|
29
|
+
private stopped = false
|
|
30
|
+
private emitter = new EventEmitter<RingDiscoverySessionEvents>()
|
|
31
|
+
private noProgressCounter = 0
|
|
32
|
+
private ongoingClosestPeersRequests: Set<DhtAddress> = new Set()
|
|
33
|
+
private readonly config: RingDiscoverySessionConfig
|
|
34
|
+
private numContactedPeers = 0
|
|
35
|
+
private targetIdAsRingId: RingId
|
|
36
|
+
|
|
37
|
+
constructor(config: RingDiscoverySessionConfig) {
|
|
38
|
+
this.config = config
|
|
39
|
+
this.targetIdAsRingId = getRingIdFromRaw(this.config.targetId)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private addContacts(contacts: PeerDescriptor[]): void {
|
|
43
|
+
if (this.stopped) {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
for (const contact of contacts) {
|
|
47
|
+
this.config.peerManager.addContact(contact)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private async getClosestPeersFromContact(contact: DhtNodeRpcRemote): Promise<RingContacts> {
|
|
52
|
+
if (this.stopped) {
|
|
53
|
+
return { left: [], right: [] }
|
|
54
|
+
}
|
|
55
|
+
logger.trace(`Getting closest ring peers from contact: ${getNodeIdFromPeerDescriptor(contact.getPeerDescriptor())}`)
|
|
56
|
+
this.numContactedPeers++
|
|
57
|
+
this.config.contactedPeers.add(contact.getNodeId())
|
|
58
|
+
const returnedContacts = await contact.getClosestRingPeers(this.config.targetId)
|
|
59
|
+
this.config.peerManager.setContactActive(contact.getNodeId())
|
|
60
|
+
return returnedContacts
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private onClosestPeersRequestSucceeded(nodeId: DhtAddress, contacts: RingContacts) {
|
|
64
|
+
if (!this.ongoingClosestPeersRequests.has(nodeId)) {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
this.ongoingClosestPeersRequests.delete(nodeId)
|
|
68
|
+
const oldClosestContacts = this.config.peerManager.getClosestRingContactsTo(this.config.targetId, 1)
|
|
69
|
+
const oldClosestLeftDistance = getLeftDistance(
|
|
70
|
+
this.targetIdAsRingId,
|
|
71
|
+
getRingIdFromPeerDescriptor(oldClosestContacts.left[0].getPeerDescriptor())
|
|
72
|
+
)
|
|
73
|
+
const oldClosestRightDistance = getLeftDistance(
|
|
74
|
+
this.targetIdAsRingId,
|
|
75
|
+
getRingIdFromPeerDescriptor(oldClosestContacts.right[0].getPeerDescriptor())
|
|
76
|
+
)
|
|
77
|
+
this.addContacts(contacts.left.concat(contacts.right))
|
|
78
|
+
const newClosestContacts = this.config.peerManager.getClosestRingContactsTo(this.config.targetId, 1)
|
|
79
|
+
const newClosestLeftDistance = getLeftDistance(this.targetIdAsRingId,
|
|
80
|
+
getRingIdFromPeerDescriptor(newClosestContacts.left[0].getPeerDescriptor()))
|
|
81
|
+
const newClosestRightDistance = getLeftDistance(this.targetIdAsRingId,
|
|
82
|
+
getRingIdFromPeerDescriptor(newClosestContacts.right[0].getPeerDescriptor()))
|
|
83
|
+
if (newClosestLeftDistance >= oldClosestLeftDistance && newClosestRightDistance >= oldClosestRightDistance) {
|
|
84
|
+
this.noProgressCounter++
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private onClosestPeersRequestFailed(peer: DhtNodeRpcRemote) {
|
|
89
|
+
if (!this.ongoingClosestPeersRequests.has(peer.getNodeId())) {
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
this.ongoingClosestPeersRequests.delete(peer.getNodeId())
|
|
93
|
+
this.config.peerManager.removeContact(peer.getNodeId())
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private findMoreContacts(): void {
|
|
97
|
+
if (this.stopped) {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
const uncontacted = this.config.peerManager.getClosestRingContactsTo(
|
|
101
|
+
this.config.targetId,
|
|
102
|
+
this.config.parallelism,
|
|
103
|
+
this.config.contactedPeers
|
|
104
|
+
)
|
|
105
|
+
if ((uncontacted.left.length === 0 && uncontacted.right.length === 0)
|
|
106
|
+
|| this.noProgressCounter >= this.config.noProgressLimit) {
|
|
107
|
+
this.emitter.emit('discoveryCompleted')
|
|
108
|
+
this.stopped = true
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
// ask from both sides equally
|
|
112
|
+
const merged = []
|
|
113
|
+
const alreadyInMerged: Set<DhtAddress> = new Set()
|
|
114
|
+
const length = Math.max(uncontacted.left.length, uncontacted.right.length)
|
|
115
|
+
for (let i = 0; i < length; i++) {
|
|
116
|
+
if (i < uncontacted.left.length) {
|
|
117
|
+
if (!alreadyInMerged.has(uncontacted.left[i].getNodeId())) {
|
|
118
|
+
merged.push(uncontacted.left[i])
|
|
119
|
+
alreadyInMerged.add(uncontacted.left[i].getNodeId())
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (i < uncontacted.right.length) {
|
|
123
|
+
if (!alreadyInMerged.has(uncontacted.right[i].getNodeId())) {
|
|
124
|
+
merged.push(uncontacted.right[i])
|
|
125
|
+
alreadyInMerged.add(uncontacted.right[i].getNodeId())
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
for (const nextPeer of merged) {
|
|
131
|
+
if (this.ongoingClosestPeersRequests.size >= this.config.parallelism) {
|
|
132
|
+
break
|
|
133
|
+
}
|
|
134
|
+
this.ongoingClosestPeersRequests.add(nextPeer.getNodeId())
|
|
135
|
+
// eslint-disable-next-line promise/catch-or-return
|
|
136
|
+
this.getClosestPeersFromContact(nextPeer)
|
|
137
|
+
.then((contacts) => this.onClosestPeersRequestSucceeded(nextPeer.getNodeId(), contacts))
|
|
138
|
+
.catch(() => this.onClosestPeersRequestFailed(nextPeer))
|
|
139
|
+
.finally(() => {
|
|
140
|
+
this.findMoreContacts()
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public async findClosestNodes(timeout: number): Promise<void> {
|
|
146
|
+
if (this.config.peerManager.getContactCount(this.config.contactedPeers) === 0) {
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
// TODO add abortController and signal it in stop()
|
|
150
|
+
await runAndWaitForEvents3<RingDiscoverySessionEvents>(
|
|
151
|
+
[this.findMoreContacts.bind(this)],
|
|
152
|
+
[[this.emitter, 'discoveryCompleted']],
|
|
153
|
+
timeout
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public stop(): void {
|
|
158
|
+
this.stopped = true
|
|
159
|
+
this.emitter.emit('discoveryCompleted')
|
|
160
|
+
this.emitter.removeAllListeners()
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -35,7 +35,7 @@ export class RecursiveOperationRpcRemote extends RpcRemote<RecursiveOperationRpc
|
|
|
35
35
|
? getNodeIdFromPeerDescriptor(previousPeer)
|
|
36
36
|
: getNodeIdFromPeerDescriptor(params.sourcePeer!)
|
|
37
37
|
const toNode = getNodeIdFromPeerDescriptor(this.getPeerDescriptor())
|
|
38
|
-
logger.debug(`Failed to send routeRequest message from ${fromNode} to ${toNode}
|
|
38
|
+
logger.debug(`Failed to send routeRequest message from ${fromNode} to ${toNode}`, { err })
|
|
39
39
|
return false
|
|
40
40
|
}
|
|
41
41
|
return true
|
|
@@ -8,8 +8,7 @@ import {
|
|
|
8
8
|
RouteMessageWrapper,
|
|
9
9
|
RouteMessageAck,
|
|
10
10
|
RecursiveOperationRequest,
|
|
11
|
-
Message
|
|
12
|
-
MessageType
|
|
11
|
+
Message
|
|
13
12
|
} from '../../proto/packages/dht/protos/DhtRpc'
|
|
14
13
|
import { ITransport } from '../../transport/ITransport'
|
|
15
14
|
import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
|
|
@@ -90,7 +89,6 @@ export class RecursiveOperationSession extends EventEmitter<RecursiveOperationSe
|
|
|
90
89
|
operation: this.config.operation
|
|
91
90
|
}
|
|
92
91
|
const msg: Message = {
|
|
93
|
-
messageType: MessageType.RECURSIVE_OPERATION_REQUEST,
|
|
94
92
|
messageId: v4(),
|
|
95
93
|
serviceId,
|
|
96
94
|
body: {
|
|
@@ -13,7 +13,6 @@ export interface RouterConfig {
|
|
|
13
13
|
rpcCommunicator: RoutingRpcCommunicator
|
|
14
14
|
localPeerDescriptor: PeerDescriptor
|
|
15
15
|
connections: Map<DhtAddress, DhtNodeRpcRemote>
|
|
16
|
-
addContact: (contact: PeerDescriptor, setActive?: boolean) => void
|
|
17
16
|
handleMessage: (message: Message) => void
|
|
18
17
|
}
|
|
19
18
|
|
|
@@ -42,7 +41,6 @@ export class Router {
|
|
|
42
41
|
private registerLocalRpcMethods() {
|
|
43
42
|
const rpcLocal = new RouterRpcLocal({
|
|
44
43
|
doRouteMessage: (routedMessage: RouteMessageWrapper, mode?: RoutingMode) => this.doRouteMessage(routedMessage, mode),
|
|
45
|
-
addContact: (contact: PeerDescriptor, setActive: boolean) => this.config.addContact(contact, setActive),
|
|
46
44
|
setForwardingEntries: (routedMessage: RouteMessageWrapper) => this.setForwardingEntries(routedMessage),
|
|
47
45
|
duplicateRequestDetector: this.duplicateRequestDetector,
|
|
48
46
|
localPeerDescriptor: this.config.localPeerDescriptor,
|
|
@@ -8,7 +8,6 @@ import { v4 } from 'uuid'
|
|
|
8
8
|
|
|
9
9
|
interface RouterRpcLocalConfig {
|
|
10
10
|
doRouteMessage: (routedMessage: RouteMessageWrapper, mode?: RoutingMode) => RouteMessageAck
|
|
11
|
-
addContact: (contact: PeerDescriptor, setActive: boolean) => void
|
|
12
11
|
setForwardingEntries: (routedMessage: RouteMessageWrapper) => void
|
|
13
12
|
handleMessage: (message: Message) => void
|
|
14
13
|
duplicateRequestDetector: DuplicateDetector
|
|
@@ -39,7 +39,7 @@ export class RouterRpcRemote extends RpcRemote<RouterRpcClient> {
|
|
|
39
39
|
? getNodeIdFromPeerDescriptor(previousPeer)
|
|
40
40
|
: getNodeIdFromPeerDescriptor(params.sourcePeer!)
|
|
41
41
|
const toNode = getNodeIdFromPeerDescriptor(this.getPeerDescriptor())
|
|
42
|
-
logger.trace(`Failed to send routeMessage from ${fromNode} to ${toNode}
|
|
42
|
+
logger.trace(`Failed to send routeMessage from ${fromNode} to ${toNode}`, { err })
|
|
43
43
|
return false
|
|
44
44
|
}
|
|
45
45
|
return true
|
|
@@ -69,7 +69,7 @@ export class RouterRpcRemote extends RpcRemote<RouterRpcClient> {
|
|
|
69
69
|
? getNodeIdFromPeerDescriptor(previousPeer)
|
|
70
70
|
: getNodeIdFromPeerDescriptor(params.sourcePeer!)
|
|
71
71
|
const toNode = getNodeIdFromPeerDescriptor(this.getPeerDescriptor())
|
|
72
|
-
logger.trace(`Failed to send forwardMessage from ${fromNode} to ${toNode}
|
|
72
|
+
logger.trace(`Failed to send forwardMessage from ${fromNode} to ${toNode}`, { err })
|
|
73
73
|
return false
|
|
74
74
|
}
|
|
75
75
|
return true
|
|
@@ -212,8 +212,8 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
|
|
|
212
212
|
} else {
|
|
213
213
|
this.onRequestFailed(nextPeer!.getNodeId())
|
|
214
214
|
}
|
|
215
|
-
} catch (
|
|
216
|
-
logger.debug('Unable to route message ', {
|
|
215
|
+
} catch (err) {
|
|
216
|
+
logger.debug('Unable to route message ', { err })
|
|
217
217
|
} finally {
|
|
218
218
|
logger.trace('sendRouteMessageRequest returned')
|
|
219
219
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DataEntry } from '../../proto/packages/dht/protos/DhtRpc'
|
|
2
|
-
import { MapWithTtl } from '../../helpers/MapWithTtl'
|
|
3
2
|
import { DhtAddress, getDhtAddressFromRaw } from '../../identifiers'
|
|
3
|
+
import { MapWithTtl } from '@streamr/utils'
|
|
4
4
|
|
|
5
5
|
export class LocalDataStore {
|
|
6
6
|
|
|
@@ -98,7 +98,7 @@ export class StoreManager {
|
|
|
98
98
|
|
|
99
99
|
public async storeDataToDht(key: DhtAddress, data: Any, creator: DhtAddress): Promise<PeerDescriptor[]> {
|
|
100
100
|
logger.debug(`Storing data to DHT ${this.config.serviceId}`)
|
|
101
|
-
const result = await this.config.recursiveOperationManager.execute(key, RecursiveOperation.
|
|
101
|
+
const result = await this.config.recursiveOperationManager.execute(key, RecursiveOperation.FIND_CLOSEST_NODES)
|
|
102
102
|
const closestNodes = result.closestNodes
|
|
103
103
|
const successfulNodes: PeerDescriptor[] = []
|
|
104
104
|
const ttl = this.config.highestTtl // ToDo: make TTL decrease according to some nice curve
|
|
@@ -158,7 +158,7 @@ export class StoreManager {
|
|
|
158
158
|
try {
|
|
159
159
|
await rpcRemote.replicateData({ entry: dataEntry })
|
|
160
160
|
} catch (err) {
|
|
161
|
-
logger.trace('Failed to replicate data in replicateDataToClosestNodes', {
|
|
161
|
+
logger.trace('Failed to replicate data in replicateDataToClosestNodes', { err })
|
|
162
162
|
}
|
|
163
163
|
}))
|
|
164
164
|
}))
|
package/src/exports.ts
CHANGED
|
@@ -7,16 +7,17 @@ export { getRandomRegion, getRegionDelayMatrix } from './connection/simulator/pi
|
|
|
7
7
|
export { PeerDescriptor, Message, NodeType, DataEntry } from './proto/packages/dht/protos/DhtRpc'
|
|
8
8
|
export { ITransport } from './transport/ITransport'
|
|
9
9
|
export { ConnectionManager, ConnectionLocker, PortRange, TlsCertificate } from './connection/ConnectionManager'
|
|
10
|
-
export { LockID } from './connection/
|
|
10
|
+
export { LockID } from './connection/ConnectionLockStates'
|
|
11
11
|
export { DefaultConnectorFacade } from './connection/ConnectorFacade'
|
|
12
12
|
export { DhtRpcOptions } from './rpc-protocol/DhtRpcOptions'
|
|
13
13
|
export { RpcRemote, EXISTING_CONNECTION_TIMEOUT } from './dht/contact/RpcRemote'
|
|
14
14
|
export { IceServer } from './connection/webrtc/WebrtcConnector'
|
|
15
15
|
export { DhtCallContext } from './rpc-protocol/DhtCallContext'
|
|
16
|
-
export {
|
|
16
|
+
export { WebsocketClientConnection } from './connection/websocket/NodeWebsocketClientConnection'
|
|
17
17
|
export { ManagedConnection } from './connection/ManagedConnection'
|
|
18
18
|
export { ConnectionType } from './connection/IConnection'
|
|
19
19
|
export { ServiceID } from './types/ServiceID'
|
|
20
|
+
export { RingContacts } from './dht/contact/RingContactList'
|
|
20
21
|
export {
|
|
21
22
|
DhtAddress,
|
|
22
23
|
DhtAddressRaw,
|
|
@@ -29,7 +29,7 @@ const calculateNodeIdRaw = (ipAddress: number, privateKey: Uint8Array): DhtAddre
|
|
|
29
29
|
return nodeIdRaw
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export const createPeerDescriptor = (connectivityResponse: ConnectivityResponse, nodeId?: DhtAddress): PeerDescriptor => {
|
|
32
|
+
export const createPeerDescriptor = (connectivityResponse: ConnectivityResponse, region: number, nodeId?: DhtAddress): PeerDescriptor => {
|
|
33
33
|
const privateKey = crypto.randomBytes(32)
|
|
34
34
|
const publicKey = crypto.randomBytes(20) // TODO calculate publicKey from privateKey
|
|
35
35
|
let nodeIdRaw: DhtAddressRaw
|
|
@@ -42,6 +42,7 @@ export const createPeerDescriptor = (connectivityResponse: ConnectivityResponse,
|
|
|
42
42
|
nodeId: nodeIdRaw,
|
|
43
43
|
type: isBrowserEnvironment() ? NodeType.BROWSER : NodeType.NODEJS,
|
|
44
44
|
ipAddress: connectivityResponse.ipAddress,
|
|
45
|
+
region,
|
|
45
46
|
publicKey
|
|
46
47
|
}
|
|
47
48
|
if (connectivityResponse.websocket) {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const LOCAL_PROTOCOL_VERSION = '1.0'
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* When two nodes negotiate whether they are compatible or not, it is up to the
|
|
5
|
+
* newer version to decide if it supports the old version or not.
|
|
6
|
+
*
|
|
7
|
+
* The older version assumes optimistically that it may be supported by the newer
|
|
8
|
+
* version. It can't know for sure, but the other node will tell if it is not
|
|
9
|
+
* supported (e.g. rejecting the handshake with UNSUPPORTED_VERSION error).
|
|
10
|
+
*/
|
|
11
|
+
export const isMaybeSupportedVersion = (remoteVersion: string): boolean => {
|
|
12
|
+
const localMajor = parseVersion(LOCAL_PROTOCOL_VERSION)!.major
|
|
13
|
+
const remoteMajor = parseVersion(remoteVersion)?.major
|
|
14
|
+
if ((remoteMajor === undefined) || (remoteMajor < localMajor)) {
|
|
15
|
+
return false
|
|
16
|
+
} else {
|
|
17
|
+
// TODO implement proper checking when there are new protocol versions
|
|
18
|
+
return true
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const parseVersion = (version: string): { major: number, minor: number } | undefined => {
|
|
23
|
+
const parts = version.split('.')
|
|
24
|
+
if (parts.length === 2) {
|
|
25
|
+
const values = parts.map((p) => Number(p))
|
|
26
|
+
if (!values.some((v) => isNaN(v))) {
|
|
27
|
+
return { major: values[0], minor: values[1] }
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
return undefined
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { ExternalApiRpc } from "./DhtRpc";
|
|
5
5
|
import type { ExternalStoreDataResponse } from "./DhtRpc";
|
|
6
6
|
import type { ExternalStoreDataRequest } from "./DhtRpc";
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
7
|
+
import type { ExternalFetchDataResponse } from "./DhtRpc";
|
|
8
|
+
import type { ExternalFetchDataRequest } from "./DhtRpc";
|
|
9
9
|
import { ConnectionLockRpc } from "./DhtRpc";
|
|
10
10
|
import type { DisconnectNotice } from "./DhtRpc";
|
|
11
11
|
import type { UnlockRequest } from "./DhtRpc";
|
|
@@ -35,6 +35,8 @@ import type { Empty } from "../../../google/protobuf/empty";
|
|
|
35
35
|
import type { LeaveNotice } from "./DhtRpc";
|
|
36
36
|
import type { PingResponse } from "./DhtRpc";
|
|
37
37
|
import type { PingRequest } from "./DhtRpc";
|
|
38
|
+
import type { ClosestRingPeersResponse } from "./DhtRpc";
|
|
39
|
+
import type { ClosestRingPeersRequest } from "./DhtRpc";
|
|
38
40
|
import { stackIntercept } from "@protobuf-ts/runtime-rpc";
|
|
39
41
|
import type { ClosestPeersResponse } from "./DhtRpc";
|
|
40
42
|
import type { ClosestPeersRequest } from "./DhtRpc";
|
|
@@ -48,6 +50,10 @@ export interface IDhtNodeRpcClient {
|
|
|
48
50
|
* @generated from protobuf rpc: getClosestPeers(dht.ClosestPeersRequest) returns (dht.ClosestPeersResponse);
|
|
49
51
|
*/
|
|
50
52
|
getClosestPeers(input: ClosestPeersRequest, options?: RpcOptions): UnaryCall<ClosestPeersRequest, ClosestPeersResponse>;
|
|
53
|
+
/**
|
|
54
|
+
* @generated from protobuf rpc: getClosestRingPeers(dht.ClosestRingPeersRequest) returns (dht.ClosestRingPeersResponse);
|
|
55
|
+
*/
|
|
56
|
+
getClosestRingPeers(input: ClosestRingPeersRequest, options?: RpcOptions): UnaryCall<ClosestRingPeersRequest, ClosestRingPeersResponse>;
|
|
51
57
|
/**
|
|
52
58
|
* @generated from protobuf rpc: ping(dht.PingRequest) returns (dht.PingResponse);
|
|
53
59
|
*/
|
|
@@ -73,18 +79,25 @@ export class DhtNodeRpcClient implements IDhtNodeRpcClient, ServiceInfo {
|
|
|
73
79
|
const method = this.methods[0], opt = this._transport.mergeOptions(options);
|
|
74
80
|
return stackIntercept<ClosestPeersRequest, ClosestPeersResponse>("unary", this._transport, method, opt, input);
|
|
75
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* @generated from protobuf rpc: getClosestRingPeers(dht.ClosestRingPeersRequest) returns (dht.ClosestRingPeersResponse);
|
|
84
|
+
*/
|
|
85
|
+
getClosestRingPeers(input: ClosestRingPeersRequest, options?: RpcOptions): UnaryCall<ClosestRingPeersRequest, ClosestRingPeersResponse> {
|
|
86
|
+
const method = this.methods[1], opt = this._transport.mergeOptions(options);
|
|
87
|
+
return stackIntercept<ClosestRingPeersRequest, ClosestRingPeersResponse>("unary", this._transport, method, opt, input);
|
|
88
|
+
}
|
|
76
89
|
/**
|
|
77
90
|
* @generated from protobuf rpc: ping(dht.PingRequest) returns (dht.PingResponse);
|
|
78
91
|
*/
|
|
79
92
|
ping(input: PingRequest, options?: RpcOptions): UnaryCall<PingRequest, PingResponse> {
|
|
80
|
-
const method = this.methods[
|
|
93
|
+
const method = this.methods[2], opt = this._transport.mergeOptions(options);
|
|
81
94
|
return stackIntercept<PingRequest, PingResponse>("unary", this._transport, method, opt, input);
|
|
82
95
|
}
|
|
83
96
|
/**
|
|
84
97
|
* @generated from protobuf rpc: leaveNotice(dht.LeaveNotice) returns (google.protobuf.Empty);
|
|
85
98
|
*/
|
|
86
99
|
leaveNotice(input: LeaveNotice, options?: RpcOptions): UnaryCall<LeaveNotice, Empty> {
|
|
87
|
-
const method = this.methods[
|
|
100
|
+
const method = this.methods[3], opt = this._transport.mergeOptions(options);
|
|
88
101
|
return stackIntercept<LeaveNotice, Empty>("unary", this._transport, method, opt, input);
|
|
89
102
|
}
|
|
90
103
|
}
|
|
@@ -352,9 +365,9 @@ export class ConnectionLockRpcClient implements IConnectionLockRpcClient, Servic
|
|
|
352
365
|
*/
|
|
353
366
|
export interface IExternalApiRpcClient {
|
|
354
367
|
/**
|
|
355
|
-
* @generated from protobuf rpc:
|
|
368
|
+
* @generated from protobuf rpc: externalFetchData(dht.ExternalFetchDataRequest) returns (dht.ExternalFetchDataResponse);
|
|
356
369
|
*/
|
|
357
|
-
|
|
370
|
+
externalFetchData(input: ExternalFetchDataRequest, options?: RpcOptions): UnaryCall<ExternalFetchDataRequest, ExternalFetchDataResponse>;
|
|
358
371
|
/**
|
|
359
372
|
* @generated from protobuf rpc: externalStoreData(dht.ExternalStoreDataRequest) returns (dht.ExternalStoreDataResponse);
|
|
360
373
|
*/
|
|
@@ -370,11 +383,11 @@ export class ExternalApiRpcClient implements IExternalApiRpcClient, ServiceInfo
|
|
|
370
383
|
constructor(private readonly _transport: RpcTransport) {
|
|
371
384
|
}
|
|
372
385
|
/**
|
|
373
|
-
* @generated from protobuf rpc:
|
|
386
|
+
* @generated from protobuf rpc: externalFetchData(dht.ExternalFetchDataRequest) returns (dht.ExternalFetchDataResponse);
|
|
374
387
|
*/
|
|
375
|
-
|
|
388
|
+
externalFetchData(input: ExternalFetchDataRequest, options?: RpcOptions): UnaryCall<ExternalFetchDataRequest, ExternalFetchDataResponse> {
|
|
376
389
|
const method = this.methods[0], opt = this._transport.mergeOptions(options);
|
|
377
|
-
return stackIntercept<
|
|
390
|
+
return stackIntercept<ExternalFetchDataRequest, ExternalFetchDataResponse>("unary", this._transport, method, opt, input);
|
|
378
391
|
}
|
|
379
392
|
/**
|
|
380
393
|
* @generated from protobuf rpc: externalStoreData(dht.ExternalStoreDataRequest) returns (dht.ExternalStoreDataResponse);
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// tslint:disable
|
|
4
4
|
import { ExternalStoreDataResponse } from "./DhtRpc";
|
|
5
5
|
import { ExternalStoreDataRequest } from "./DhtRpc";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { ExternalFetchDataResponse } from "./DhtRpc";
|
|
7
|
+
import { ExternalFetchDataRequest } from "./DhtRpc";
|
|
8
8
|
import { DisconnectNotice } from "./DhtRpc";
|
|
9
9
|
import { UnlockRequest } from "./DhtRpc";
|
|
10
10
|
import { LockResponse } from "./DhtRpc";
|
|
@@ -24,6 +24,8 @@ import { Empty } from "../../../google/protobuf/empty";
|
|
|
24
24
|
import { LeaveNotice } from "./DhtRpc";
|
|
25
25
|
import { PingResponse } from "./DhtRpc";
|
|
26
26
|
import { PingRequest } from "./DhtRpc";
|
|
27
|
+
import { ClosestRingPeersResponse } from "./DhtRpc";
|
|
28
|
+
import { ClosestRingPeersRequest } from "./DhtRpc";
|
|
27
29
|
import { ClosestPeersResponse } from "./DhtRpc";
|
|
28
30
|
import { ClosestPeersRequest } from "./DhtRpc";
|
|
29
31
|
import { ServerCallContext } from "@protobuf-ts/runtime-rpc";
|
|
@@ -35,6 +37,10 @@ export interface IDhtNodeRpc<T = ServerCallContext> {
|
|
|
35
37
|
* @generated from protobuf rpc: getClosestPeers(dht.ClosestPeersRequest) returns (dht.ClosestPeersResponse);
|
|
36
38
|
*/
|
|
37
39
|
getClosestPeers(request: ClosestPeersRequest, context: T): Promise<ClosestPeersResponse>;
|
|
40
|
+
/**
|
|
41
|
+
* @generated from protobuf rpc: getClosestRingPeers(dht.ClosestRingPeersRequest) returns (dht.ClosestRingPeersResponse);
|
|
42
|
+
*/
|
|
43
|
+
getClosestRingPeers(request: ClosestRingPeersRequest, context: T): Promise<ClosestRingPeersResponse>;
|
|
38
44
|
/**
|
|
39
45
|
* @generated from protobuf rpc: ping(dht.PingRequest) returns (dht.PingResponse);
|
|
40
46
|
*/
|
|
@@ -140,9 +146,9 @@ export interface IConnectionLockRpc<T = ServerCallContext> {
|
|
|
140
146
|
*/
|
|
141
147
|
export interface IExternalApiRpc<T = ServerCallContext> {
|
|
142
148
|
/**
|
|
143
|
-
* @generated from protobuf rpc:
|
|
149
|
+
* @generated from protobuf rpc: externalFetchData(dht.ExternalFetchDataRequest) returns (dht.ExternalFetchDataResponse);
|
|
144
150
|
*/
|
|
145
|
-
|
|
151
|
+
externalFetchData(request: ExternalFetchDataRequest, context: T): Promise<ExternalFetchDataResponse>;
|
|
146
152
|
/**
|
|
147
153
|
* @generated from protobuf rpc: externalStoreData(dht.ExternalStoreDataRequest) returns (dht.ExternalStoreDataResponse);
|
|
148
154
|
*/
|