@streamr/dht 0.0.1-tatum.5 → 0.0.1-tatum.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/connection/ConnectionLockHandler.d.ts +1 -1
- package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
- package/dist/src/connection/ConnectionManager.d.ts +17 -39
- package/dist/src/connection/ConnectionManager.js +138 -192
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectivityChecker.js +14 -11
- package/dist/src/connection/ConnectivityChecker.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.d.ts +49 -0
- package/dist/src/connection/ConnectorFacade.js +86 -0
- package/dist/src/connection/ConnectorFacade.js.map +1 -0
- package/dist/src/connection/ManagedConnection.d.ts +1 -4
- package/dist/src/connection/ManagedConnection.js +23 -31
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/RemoteConnectionLocker.js +4 -3
- package/dist/src/connection/RemoteConnectionLocker.js.map +1 -1
- package/dist/src/connection/Simulator/Simulator.d.ts +0 -2
- package/dist/src/connection/Simulator/Simulator.js +0 -5
- package/dist/src/connection/Simulator/Simulator.js.map +1 -1
- package/dist/src/connection/Simulator/SimulatorConnection.js +16 -13
- package/dist/src/connection/Simulator/SimulatorConnection.js.map +1 -1
- package/dist/src/connection/Simulator/SimulatorConnector.d.ts +2 -2
- package/dist/src/connection/Simulator/SimulatorConnector.js +10 -11
- package/dist/src/connection/Simulator/SimulatorConnector.js.map +1 -1
- package/dist/src/connection/Simulator/SimulatorTransport.js +6 -1
- package/dist/src/connection/Simulator/SimulatorTransport.js.map +1 -1
- package/dist/src/connection/WebRTC/NodeWebRtcConnection.d.ts +2 -0
- package/dist/src/connection/WebRTC/NodeWebRtcConnection.js +12 -12
- package/dist/src/connection/WebRTC/NodeWebRtcConnection.js.map +1 -1
- package/dist/src/connection/WebRTC/WebRtcConnector.d.ts +9 -9
- package/dist/src/connection/WebRTC/WebRtcConnector.js +22 -22
- package/dist/src/connection/WebRTC/WebRtcConnector.js.map +1 -1
- package/dist/src/connection/WebSocket/RemoteWebSocketConnector.js +2 -1
- package/dist/src/connection/WebSocket/RemoteWebSocketConnector.js.map +1 -1
- package/dist/src/connection/WebSocket/WebSocketConnector.d.ts +19 -8
- package/dist/src/connection/WebSocket/WebSocketConnector.js +67 -46
- package/dist/src/connection/WebSocket/WebSocketConnector.js.map +1 -1
- package/dist/src/connection/WebSocket/WebSocketServer.d.ts +11 -1
- package/dist/src/connection/WebSocket/WebSocketServer.js +15 -10
- package/dist/src/connection/WebSocket/WebSocketServer.js.map +1 -1
- package/dist/src/dht/DhtNode.d.ts +16 -54
- package/dist/src/dht/DhtNode.js +116 -137
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/{DhtPeer.d.ts → RemoteDhtNode.d.ts} +3 -2
- package/dist/src/dht/{DhtPeer.js → RemoteDhtNode.js} +22 -16
- package/dist/src/dht/RemoteDhtNode.js.map +1 -0
- package/dist/src/dht/contact/Contact.d.ts +1 -15
- package/dist/src/dht/contact/Contact.js +1 -9
- package/dist/src/dht/contact/Contact.js.map +1 -1
- package/dist/src/dht/contact/ContactList.d.ts +13 -3
- package/dist/src/dht/contact/ContactList.js +9 -4
- package/dist/src/dht/contact/ContactList.js.map +1 -1
- package/dist/src/dht/contact/RandomContactList.d.ts +3 -3
- package/dist/src/dht/contact/RandomContactList.js +4 -8
- package/dist/src/dht/contact/RandomContactList.js.map +1 -1
- package/dist/src/dht/contact/Remote.d.ts +1 -5
- package/dist/src/dht/contact/Remote.js +0 -5
- package/dist/src/dht/contact/Remote.js.map +1 -1
- package/dist/src/dht/contact/SortedContactList.d.ts +3 -5
- package/dist/src/dht/contact/SortedContactList.js +9 -19
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- package/dist/src/dht/discovery/DiscoverySession.d.ts +5 -7
- package/dist/src/dht/discovery/DiscoverySession.js +9 -10
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +11 -10
- package/dist/src/dht/discovery/PeerDiscovery.js +32 -37
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/find/RecursiveFindSession.d.ts +5 -6
- package/dist/src/dht/find/RecursiveFindSession.js +8 -8
- package/dist/src/dht/find/RecursiveFindSession.js.map +1 -1
- package/dist/src/dht/find/RecursiveFinder.d.ts +2 -4
- package/dist/src/dht/find/RecursiveFinder.js +11 -12
- package/dist/src/dht/find/RecursiveFinder.js.map +1 -1
- package/dist/src/dht/registerExternalApiRpcMethods.d.ts +1 -1
- package/dist/src/dht/routing/DuplicateDetector.d.ts +1 -2
- package/dist/src/dht/routing/DuplicateDetector.js +2 -7
- package/dist/src/dht/routing/DuplicateDetector.js.map +1 -1
- package/dist/src/dht/routing/RemoteRouter.js +4 -4
- package/dist/src/dht/routing/RemoteRouter.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +10 -13
- package/dist/src/dht/routing/Router.js +28 -29
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.d.ts +3 -5
- package/dist/src/dht/routing/RoutingSession.js +19 -13
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/store/DataStore.d.ts +2 -2
- package/dist/src/dht/store/DataStore.js +7 -7
- package/dist/src/dht/store/DataStore.js.map +1 -1
- package/dist/src/exports.d.ts +1 -8
- package/dist/src/exports.js +2 -16
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/PeerID.d.ts +0 -1
- package/dist/src/helpers/PeerID.js +0 -6
- package/dist/src/helpers/PeerID.js.map +1 -1
- package/dist/src/helpers/browser/isBrowserEnvironment.d.ts +1 -0
- package/dist/src/helpers/browser/isBrowserEnvironment.js +6 -0
- package/dist/src/helpers/browser/isBrowserEnvironment.js.map +1 -0
- package/dist/src/helpers/browser/isBrowserEnvironment_override.d.ts +1 -0
- package/dist/src/helpers/browser/isBrowserEnvironment_override.js +7 -0
- package/dist/src/helpers/browser/isBrowserEnvironment_override.js.map +1 -0
- package/dist/src/helpers/kademliaId.d.ts +1 -0
- package/dist/src/helpers/kademliaId.js +14 -0
- package/dist/src/helpers/kademliaId.js.map +1 -0
- package/dist/src/helpers/peerIdFromPeerDescriptor.d.ts +1 -1
- package/dist/src/helpers/peerIdFromPeerDescriptor.js +3 -3
- package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +0 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +1 -2
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/package.json +10 -9
- package/protos/DhtRpc.proto +0 -1
- package/src/connection/ConnectionLockHandler.ts +1 -1
- package/src/connection/ConnectionManager.ts +156 -240
- package/src/connection/ConnectivityChecker.ts +14 -11
- package/src/connection/ConnectorFacade.ts +143 -0
- package/src/connection/ManagedConnection.ts +23 -34
- package/src/connection/RemoteConnectionLocker.ts +4 -3
- package/src/connection/Simulator/Simulator.ts +0 -7
- package/src/connection/Simulator/SimulatorConnection.ts +16 -13
- package/src/connection/Simulator/SimulatorConnector.ts +11 -12
- package/src/connection/Simulator/SimulatorTransport.ts +6 -1
- package/src/connection/WebRTC/NodeWebRtcConnection.ts +14 -13
- package/src/connection/WebRTC/WebRtcConnector.ts +31 -31
- package/src/connection/WebSocket/RemoteWebSocketConnector.ts +2 -1
- package/src/connection/WebSocket/WebSocketConnector.ts +85 -62
- package/src/connection/WebSocket/WebSocketServer.ts +26 -8
- package/src/dht/DhtNode.ts +164 -189
- package/src/dht/{DhtPeer.ts → RemoteDhtNode.ts} +14 -7
- package/src/dht/contact/Contact.ts +1 -18
- package/src/dht/contact/ContactList.ts +16 -6
- package/src/dht/contact/RandomContactList.ts +6 -11
- package/src/dht/contact/Remote.ts +1 -10
- package/src/dht/contact/SortedContactList.ts +12 -25
- package/src/dht/discovery/DiscoverySession.ts +20 -23
- package/src/dht/discovery/PeerDiscovery.ts +45 -44
- package/src/dht/find/RecursiveFindSession.ts +12 -13
- package/src/dht/find/RecursiveFinder.ts +16 -19
- package/src/dht/registerExternalApiRpcMethods.ts +1 -1
- package/src/dht/routing/DuplicateDetector.ts +3 -10
- package/src/dht/routing/RemoteRouter.ts +5 -5
- package/src/dht/routing/Router.ts +35 -39
- package/src/dht/routing/RoutingSession.ts +37 -28
- package/src/dht/store/DataStore.ts +11 -11
- package/src/exports.ts +1 -8
- package/src/helpers/PeerID.ts +0 -7
- package/src/helpers/browser/isBrowserEnvironment.ts +1 -0
- package/src/helpers/browser/isBrowserEnvironment_override.ts +3 -0
- package/src/helpers/kademliaId.ts +8 -0
- package/src/helpers/peerIdFromPeerDescriptor.ts +1 -1
- package/src/proto/packages/dht/protos/DhtRpc.ts +1 -6
- package/test/benchmark/KademliaCorrectness.test.ts +5 -2
- package/test/benchmark/RecursiveFind.test.ts +6 -6
- package/test/end-to-end/Layer0-Layer1.test.ts +14 -14
- package/test/end-to-end/Layer0WebRTC-Layer1.test.ts +5 -5
- package/test/end-to-end/Layer0WebRTC.test.ts +5 -6
- package/test/end-to-end/Layer1-Scale-WebRTC.test.ts +13 -8
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +15 -10
- package/test/end-to-end/WebSocketConnectionRequest.test.ts +5 -5
- package/test/integration/ConnectionLocking.test.ts +32 -26
- package/test/integration/ConnectionManager.test.ts +90 -93
- package/test/integration/DhtJoinPeerDiscovery.test.ts +53 -0
- package/test/integration/DhtRpc.test.ts +4 -6
- package/test/integration/Layer1-scale.test.ts +8 -8
- package/test/integration/MigrateData.test.ts +9 -9
- package/test/integration/Mock-Layer1-Layer0.test.ts +1 -2
- package/test/integration/RecursiveFind.test.ts +5 -5
- package/test/integration/{DhtPeer.test.ts → RemoteDhtNode.test.ts} +11 -12
- package/test/integration/RemoteRouter.test.ts +5 -6
- package/test/integration/RemoteStore.test.ts +4 -5
- package/test/integration/RouteMessage.test.ts +7 -9
- package/test/integration/RpcErrors.test.ts +25 -10
- package/test/integration/ScaleDownDht.test.ts +8 -8
- package/test/integration/SimultaneousConnections.test.ts +35 -36
- package/test/integration/Store.test.ts +8 -9
- package/test/integration/StoreAndDelete.test.ts +11 -11
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +7 -7
- package/test/integration/WebRtcConnectionManagement.test.ts +26 -19
- package/test/integration/WebRtcConnectorRpc.test.ts +6 -8
- package/test/integration/WebSocket.test.ts +4 -2
- package/test/integration/WebSocketConnectionManagement.test.ts +30 -17
- package/test/integration/WebSocketConnectorRpc.test.ts +2 -3
- package/test/unit/DuplicateDetector.test.ts +3 -4
- package/test/unit/LocalDataStore.test.ts +6 -8
- package/test/unit/RandomContactList.test.ts +25 -74
- package/test/unit/RecursiveFinder.test.ts +8 -12
- package/test/unit/Router.test.ts +18 -21
- package/test/unit/SortedContactList.test.ts +62 -112
- package/test/unit/WebSocketConnector.test.ts +64 -0
- package/test/unit/WebSocketServer.test.ts +24 -12
- package/test/utils/mock/RecursiveFinder.ts +2 -2
- package/test/utils/mock/Router.ts +9 -11
- package/test/utils/mock/Transport.ts +2 -2
- package/test/utils/utils.ts +40 -49
- package/dist/src/dht/DhtPeer.js.map +0 -1
- package/dist/src/helpers/browser/isBrowser.d.ts +0 -1
- package/dist/src/helpers/browser/isBrowser.js +0 -6
- package/dist/src/helpers/browser/isBrowser.js.map +0 -1
- package/dist/src/helpers/browser/isNodeJS.d.ts +0 -1
- package/dist/src/helpers/browser/isNodeJS.js +0 -6
- package/dist/src/helpers/browser/isNodeJS.js.map +0 -1
- package/src/helpers/browser/isBrowser.ts +0 -1
- package/src/helpers/browser/isNodeJS.ts +0 -1
- package/test/integration/DhtWithMockConnectionLatencies.test.ts +0 -46
- package/test/integration/DhtWithMockConnections.test.ts +0 -46
- package/test/integration/DhtWithRealConnectionLatencies.test.ts +0 -47
- /package/test/unit/{webrtcReplaceInternalIpWithExternalIp.ts → webrtcReplaceInternalIpWithExternalIp.test.ts} +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
2
1
|
import { Logger } from '@streamr/utils'
|
|
3
2
|
import EventEmitter from 'eventemitter3'
|
|
4
3
|
import { PeerID, PeerIDKey } from '../../helpers/PeerID'
|
|
@@ -20,18 +19,18 @@ const logger = new Logger(module)
|
|
|
20
19
|
|
|
21
20
|
export interface RecursiveFindSessionConfig {
|
|
22
21
|
serviceId: string
|
|
23
|
-
|
|
22
|
+
transport: ITransport
|
|
24
23
|
kademliaIdToFind: Uint8Array
|
|
25
|
-
|
|
24
|
+
ownPeerId: PeerID
|
|
26
25
|
waitedRoutingPathCompletions: number
|
|
27
26
|
mode: FindMode
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
export class RecursiveFindSession extends EventEmitter<RecursiveFindSessionEvents> implements IRecursiveFindSessionService {
|
|
31
30
|
private readonly serviceId: string
|
|
32
|
-
private readonly
|
|
31
|
+
private readonly transport: ITransport
|
|
33
32
|
private readonly kademliaIdToFind: Uint8Array
|
|
34
|
-
private readonly
|
|
33
|
+
private readonly ownPeerId: PeerID
|
|
35
34
|
private readonly waitedRoutingPathCompletions: number
|
|
36
35
|
private readonly rpcCommunicator: ListeningRpcCommunicator
|
|
37
36
|
private readonly mode: FindMode
|
|
@@ -46,17 +45,17 @@ export class RecursiveFindSession extends EventEmitter<RecursiveFindSessionEvent
|
|
|
46
45
|
constructor(config: RecursiveFindSessionConfig) {
|
|
47
46
|
super()
|
|
48
47
|
this.serviceId = config.serviceId
|
|
49
|
-
this.
|
|
48
|
+
this.transport = config.transport
|
|
50
49
|
this.kademliaIdToFind = config.kademliaIdToFind
|
|
51
|
-
this.
|
|
50
|
+
this.ownPeerId = config.ownPeerId
|
|
52
51
|
this.waitedRoutingPathCompletions = config.waitedRoutingPathCompletions
|
|
53
52
|
this.results = new SortedContactList(PeerID.fromValue(this.kademliaIdToFind), 10, undefined, true)
|
|
54
53
|
this.mode = config.mode
|
|
55
|
-
this.rpcCommunicator = new ListeningRpcCommunicator(this.serviceId, this.
|
|
54
|
+
this.rpcCommunicator = new ListeningRpcCommunicator(this.serviceId, this.transport, {
|
|
56
55
|
rpcRequestTimeout: 15000
|
|
57
56
|
})
|
|
58
57
|
this.rpcCommunicator.registerRpcNotification(RecursiveFindReport, 'reportRecursiveFindResult',
|
|
59
|
-
(req: RecursiveFindReport
|
|
58
|
+
(req: RecursiveFindReport) => this.reportRecursiveFindResult(req))
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
private isFindCompleted(): boolean {
|
|
@@ -90,7 +89,7 @@ export class RecursiveFindSession extends EventEmitter<RecursiveFindSessionEvent
|
|
|
90
89
|
if (routingPath.length >= 1) {
|
|
91
90
|
this.setHopAsReported(routingPath[routingPath.length - 1])
|
|
92
91
|
}
|
|
93
|
-
nodes.
|
|
92
|
+
nodes.forEach((descriptor: PeerDescriptor) => {
|
|
94
93
|
this.results.addContact(new Contact(descriptor))
|
|
95
94
|
})
|
|
96
95
|
this.processFoundData(dataEntries)
|
|
@@ -102,7 +101,7 @@ export class RecursiveFindSession extends EventEmitter<RecursiveFindSessionEvent
|
|
|
102
101
|
private addKnownHops(routingPath: PeerDescriptor[]) {
|
|
103
102
|
routingPath.forEach((desc) => {
|
|
104
103
|
const newPeerId = PeerID.fromValue(desc.kademliaId)
|
|
105
|
-
if (!this.
|
|
104
|
+
if (!this.ownPeerId.equals(newPeerId)) {
|
|
106
105
|
this.allKnownHops.add(newPeerId.toKey())
|
|
107
106
|
}
|
|
108
107
|
})
|
|
@@ -110,7 +109,7 @@ export class RecursiveFindSession extends EventEmitter<RecursiveFindSessionEvent
|
|
|
110
109
|
|
|
111
110
|
private setHopAsReported(desc: PeerDescriptor) {
|
|
112
111
|
const newPeerId = PeerID.fromValue(desc.kademliaId)
|
|
113
|
-
if (!this.
|
|
112
|
+
if (!this.ownPeerId.equals(newPeerId)) {
|
|
114
113
|
this.reportedHops.add(newPeerId.toKey())
|
|
115
114
|
}
|
|
116
115
|
if (this.isFindCompleted()) {
|
|
@@ -157,7 +156,7 @@ export class RecursiveFindSession extends EventEmitter<RecursiveFindSessionEvent
|
|
|
157
156
|
}
|
|
158
157
|
}
|
|
159
158
|
|
|
160
|
-
public async reportRecursiveFindResult(report: RecursiveFindReport
|
|
159
|
+
public async reportRecursiveFindResult(report: RecursiveFindReport): Promise<Empty> {
|
|
161
160
|
logger.trace('recursiveFindReport arrived: ' + JSON.stringify(report))
|
|
162
161
|
this.doReportRecursiveFindResult(report.routingPath, report.nodes, report.dataEntries, report.noCloserNodesFound)
|
|
163
162
|
return {}
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
import { PeerID, PeerIDKey } from '../../helpers/PeerID'
|
|
13
13
|
import { createRouteMessageAck, RoutingErrors, IRouter } from '../routing/Router'
|
|
14
14
|
import { RoutingMode } from '../routing/RoutingSession'
|
|
15
|
-
import { keyFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
|
|
15
|
+
import { areEqualPeerDescriptors, keyFromPeerDescriptor, peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
|
|
16
16
|
import { Logger, runAndWaitForEvents3 } from '@streamr/utils'
|
|
17
17
|
import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
|
|
18
18
|
import { RemoteRecursiveFindSession } from './RemoteRecursiveFindSession'
|
|
19
19
|
import { v4 } from 'uuid'
|
|
20
20
|
import { RecursiveFindSession, RecursiveFindSessionEvents } from './RecursiveFindSession'
|
|
21
|
-
import {
|
|
21
|
+
import { RemoteDhtNode } from '../RemoteDhtNode'
|
|
22
22
|
import { ITransport } from '../../transport/ITransport'
|
|
23
23
|
import { LocalDataStore } from '../store/LocalDataStore'
|
|
24
24
|
import { IRoutingService } from '../../proto/packages/dht/protos/DhtRpc.server'
|
|
@@ -30,10 +30,9 @@ import { SortedContactList } from '../contact/SortedContactList'
|
|
|
30
30
|
interface RecursiveFinderConfig {
|
|
31
31
|
rpcCommunicator: RoutingRpcCommunicator
|
|
32
32
|
sessionTransport: ITransport
|
|
33
|
-
connections: Map<PeerIDKey,
|
|
33
|
+
connections: Map<PeerIDKey, RemoteDhtNode>
|
|
34
34
|
router: IRouter
|
|
35
35
|
ownPeerDescriptor: PeerDescriptor
|
|
36
|
-
ownPeerId: PeerID
|
|
37
36
|
serviceId: string
|
|
38
37
|
localDataStore: LocalDataStore
|
|
39
38
|
addContact: (contact: PeerDescriptor, setActive?: boolean) => void
|
|
@@ -54,10 +53,9 @@ export class RecursiveFinder implements IRecursiveFinder {
|
|
|
54
53
|
|
|
55
54
|
private readonly rpcCommunicator: RoutingRpcCommunicator
|
|
56
55
|
private readonly sessionTransport: ITransport
|
|
57
|
-
private readonly connections: Map<PeerIDKey,
|
|
56
|
+
private readonly connections: Map<PeerIDKey, RemoteDhtNode>
|
|
58
57
|
private readonly router: IRouter
|
|
59
58
|
private readonly ownPeerDescriptor: PeerDescriptor
|
|
60
|
-
private readonly ownPeerId: PeerID
|
|
61
59
|
private readonly serviceId: string
|
|
62
60
|
private readonly localDataStore: LocalDataStore
|
|
63
61
|
private readonly addContact: (contact: PeerDescriptor, setActive?: boolean) => void
|
|
@@ -71,7 +69,6 @@ export class RecursiveFinder implements IRecursiveFinder {
|
|
|
71
69
|
this.connections = config.connections
|
|
72
70
|
this.router = config.router
|
|
73
71
|
this.ownPeerDescriptor = config.ownPeerDescriptor
|
|
74
|
-
this.ownPeerId = config.ownPeerId
|
|
75
72
|
this.serviceId = config.serviceId
|
|
76
73
|
this.localDataStore = config.localDataStore
|
|
77
74
|
this.addContact = config.addContact
|
|
@@ -91,9 +88,9 @@ export class RecursiveFinder implements IRecursiveFinder {
|
|
|
91
88
|
const sessionId = v4()
|
|
92
89
|
const recursiveFindSession = new RecursiveFindSession({
|
|
93
90
|
serviceId: sessionId,
|
|
94
|
-
|
|
91
|
+
transport: this.sessionTransport,
|
|
95
92
|
kademliaIdToFind: idToFind,
|
|
96
|
-
|
|
93
|
+
ownPeerId: peerIdFromPeerDescriptor(this.ownPeerDescriptor),
|
|
97
94
|
waitedRoutingPathCompletions: this.connections.size > 1 ? 2 : 1,
|
|
98
95
|
mode: findMode
|
|
99
96
|
})
|
|
@@ -116,7 +113,7 @@ export class RecursiveFinder implements IRecursiveFinder {
|
|
|
116
113
|
15000
|
|
117
114
|
)
|
|
118
115
|
} catch (err) {
|
|
119
|
-
logger.debug(`doFindRecursively failed with error ${
|
|
116
|
+
logger.debug(`doFindRecursively failed with error ${err}`)
|
|
120
117
|
}
|
|
121
118
|
this.findAndReportLocalData(idToFind, findMode, [], this.ownPeerDescriptor, sessionId)
|
|
122
119
|
this.ongoingSessions.delete(sessionId)
|
|
@@ -186,8 +183,8 @@ export class RecursiveFinder implements IRecursiveFinder {
|
|
|
186
183
|
noCloserNodesFound: boolean = false
|
|
187
184
|
): void {
|
|
188
185
|
const dataEntries = data ? Array.from(data.values(), DataEntry.create.bind(DataEntry)) : []
|
|
189
|
-
const
|
|
190
|
-
if (
|
|
186
|
+
const isOwnNode = areEqualPeerDescriptors(this.ownPeerDescriptor, targetPeerDescriptor)
|
|
187
|
+
if (isOwnNode && this.ongoingSessions.has(serviceId)) {
|
|
191
188
|
this.ongoingSessions.get(serviceId)!
|
|
192
189
|
.doReportRecursiveFindResult(routingPath, closestNodes, dataEntries, noCloserNodesFound)
|
|
193
190
|
} else {
|
|
@@ -206,19 +203,19 @@ export class RecursiveFinder implements IRecursiveFinder {
|
|
|
206
203
|
if (this.stopped) {
|
|
207
204
|
return createRouteMessageAck(routedMessage, 'DhtNode Stopped')
|
|
208
205
|
}
|
|
209
|
-
const idToFind =
|
|
206
|
+
const idToFind = peerIdFromPeerDescriptor(routedMessage.destinationPeer!)
|
|
210
207
|
const msg = routedMessage.message
|
|
211
208
|
const recursiveFindRequest = msg?.body.oneofKind === 'recursiveFindRequest' ? msg.body.recursiveFindRequest : undefined
|
|
212
209
|
const closestPeersToDestination = this.getClosestConnections(routedMessage.destinationPeer!.kademliaId, 5)
|
|
213
210
|
const data = this.findLocalData(idToFind.value, recursiveFindRequest!.findMode)
|
|
214
|
-
if (this.
|
|
211
|
+
if (areEqualPeerDescriptors(this.ownPeerDescriptor, routedMessage.destinationPeer!)) {
|
|
215
212
|
this.reportRecursiveFindResult(routedMessage.routingPath, routedMessage.sourcePeer!, recursiveFindRequest!.recursiveFindSessionId,
|
|
216
213
|
closestPeersToDestination, data, true)
|
|
217
214
|
return createRouteMessageAck(routedMessage)
|
|
218
215
|
}
|
|
219
216
|
const ack = this.router.doRouteMessage(routedMessage, RoutingMode.RECURSIVE_FIND, excludedPeer)
|
|
220
217
|
if (ack.error === RoutingErrors.NO_CANDIDATES_FOUND) {
|
|
221
|
-
logger.trace(`findRecursively Node
|
|
218
|
+
logger.trace(`findRecursively Node found no candidates`)
|
|
222
219
|
this.reportRecursiveFindResult(routedMessage.routingPath, routedMessage.sourcePeer!, recursiveFindRequest!.recursiveFindSessionId,
|
|
223
220
|
closestPeersToDestination, data, true)
|
|
224
221
|
} else if (ack.error) {
|
|
@@ -237,7 +234,7 @@ export class RecursiveFinder implements IRecursiveFinder {
|
|
|
237
234
|
|
|
238
235
|
private getClosestConnections(kademliaId: Uint8Array, limit: number): PeerDescriptor[] {
|
|
239
236
|
const connectedPeers = Array.from(this.connections.values())
|
|
240
|
-
const closestPeers = new SortedContactList(
|
|
237
|
+
const closestPeers = new SortedContactList<RemoteDhtNode>(
|
|
241
238
|
PeerID.fromValue(kademliaId),
|
|
242
239
|
limit,
|
|
243
240
|
undefined,
|
|
@@ -252,13 +249,13 @@ export class RecursiveFinder implements IRecursiveFinder {
|
|
|
252
249
|
async findRecursively(routedMessage: RouteMessageWrapper): Promise<RouteMessageAck> {
|
|
253
250
|
if (this.stopped) {
|
|
254
251
|
return createRouteMessageAck(routedMessage, 'findRecursively() service is not running')
|
|
255
|
-
} else if (this.router.
|
|
252
|
+
} else if (this.router.isMostLikelyDuplicate(routedMessage.requestId)) {
|
|
256
253
|
return createRouteMessageAck(routedMessage, 'message given to findRecursively() service is likely a duplicate')
|
|
257
254
|
}
|
|
258
255
|
const senderKey = keyFromPeerDescriptor(routedMessage.previousPeer || routedMessage.sourcePeer!)
|
|
259
|
-
logger.trace(`
|
|
256
|
+
logger.trace(`Received findRecursively call from ${senderKey}`)
|
|
260
257
|
this.addContact(routedMessage.sourcePeer!, true)
|
|
261
|
-
this.router.addToDuplicateDetector(routedMessage.requestId
|
|
258
|
+
this.router.addToDuplicateDetector(routedMessage.requestId)
|
|
262
259
|
return this.doFindRecursevily(routedMessage)
|
|
263
260
|
}
|
|
264
261
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DhtNode } from '../
|
|
1
|
+
import { DhtNode } from '../dht/DhtNode'
|
|
2
2
|
import { ExternalStoreDataRequest, ExternalStoreDataResponse, FindDataRequest, FindDataResponse, FindMode } from '../proto/packages/dht/protos/DhtRpc'
|
|
3
3
|
|
|
4
4
|
export const registerExternalApiRpcMethods = (thisNode: DhtNode): void => {
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type QueueEntry = [timeStamp: number, value: string, senderId: string, message?: Message]
|
|
1
|
+
type QueueEntry = [timestamp: number, value: string]
|
|
4
2
|
|
|
5
3
|
export class DuplicateDetector {
|
|
6
4
|
|
|
@@ -17,13 +15,9 @@ export class DuplicateDetector {
|
|
|
17
15
|
this.maxAge = maxAgeInSeconds * 1000
|
|
18
16
|
}
|
|
19
17
|
|
|
20
|
-
public add(value: string
|
|
18
|
+
public add(value: string): void {
|
|
21
19
|
this.values.add(value)
|
|
22
|
-
|
|
23
|
-
this.queue.push([Date.now(), value, senderId, message])
|
|
24
|
-
} else {
|
|
25
|
-
this.queue.push([Date.now(), value, senderId])
|
|
26
|
-
}
|
|
20
|
+
this.queue.push([Date.now(), value])
|
|
27
21
|
this.cleanUp()
|
|
28
22
|
}
|
|
29
23
|
|
|
@@ -49,5 +43,4 @@ export class DuplicateDetector {
|
|
|
49
43
|
this.values.clear()
|
|
50
44
|
this.queue = []
|
|
51
45
|
}
|
|
52
|
-
|
|
53
46
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
|
|
2
2
|
import { v4 } from 'uuid'
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
areEqualPeerDescriptors,
|
|
5
5
|
keyFromPeerDescriptor,
|
|
6
6
|
peerIdFromPeerDescriptor
|
|
7
7
|
} from '../../helpers/peerIdFromPeerDescriptor'
|
|
@@ -30,7 +30,7 @@ export class RemoteRouter extends Remote<IRoutingServiceClient> {
|
|
|
30
30
|
const ack = await this.getClient().routeMessage(message, options)
|
|
31
31
|
// Success signal if sent to destination and error includes duplicate
|
|
32
32
|
if (
|
|
33
|
-
|
|
33
|
+
areEqualPeerDescriptors(params.destinationPeer!, this.getPeerDescriptor())
|
|
34
34
|
&& ack.error.includes('duplicate')
|
|
35
35
|
) {
|
|
36
36
|
return true
|
|
@@ -40,7 +40,7 @@ export class RemoteRouter extends Remote<IRoutingServiceClient> {
|
|
|
40
40
|
} catch (err) {
|
|
41
41
|
const fromNode = params.previousPeer ?
|
|
42
42
|
peerIdFromPeerDescriptor(params.previousPeer) : keyFromPeerDescriptor(params.sourcePeer!)
|
|
43
|
-
logger.trace(`Failed to send routeMessage from ${fromNode} to ${this.
|
|
43
|
+
logger.trace(`Failed to send routeMessage from ${fromNode} to ${keyFromPeerDescriptor(this.getPeerDescriptor())} with: ${err}`)
|
|
44
44
|
return false
|
|
45
45
|
}
|
|
46
46
|
return true
|
|
@@ -69,7 +69,7 @@ export class RemoteRouter extends Remote<IRoutingServiceClient> {
|
|
|
69
69
|
keyFromPeerDescriptor(params.previousPeer) : keyFromPeerDescriptor(params.sourcePeer!)
|
|
70
70
|
|
|
71
71
|
logger.trace(
|
|
72
|
-
`Failed to send forwardMessage from ${fromNode} to ${this.
|
|
72
|
+
`Failed to send forwardMessage from ${fromNode} to ${keyFromPeerDescriptor(this.getPeerDescriptor())} with: ${err}`
|
|
73
73
|
)
|
|
74
74
|
return false
|
|
75
75
|
}
|
|
@@ -97,7 +97,7 @@ export class RemoteRouter extends Remote<IRoutingServiceClient> {
|
|
|
97
97
|
}
|
|
98
98
|
} catch (err) {
|
|
99
99
|
const fromNode = params.previousPeer ? keyFromPeerDescriptor(params.previousPeer) : keyFromPeerDescriptor(params.sourcePeer!)
|
|
100
|
-
logger.debug(`Failed to send recursiveFind message from ${fromNode} to ${this.
|
|
100
|
+
logger.debug(`Failed to send recursiveFind message from ${fromNode} to ${keyFromPeerDescriptor(this.getPeerDescriptor())} with: ${err}`)
|
|
101
101
|
return false
|
|
102
102
|
}
|
|
103
103
|
return true
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { Message, PeerDescriptor, RouteMessageAck, RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
|
|
2
|
-
import {
|
|
3
|
-
import { keyFromPeerDescriptor, peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
|
|
2
|
+
import { areEqualPeerDescriptors, keyFromPeerDescriptor, peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
|
|
4
3
|
import { RoutingMode, RoutingSession, RoutingSessionEvents } from './RoutingSession'
|
|
5
4
|
import { Logger, executeSafePromise, raceEvents3, withTimeout } from '@streamr/utils'
|
|
6
5
|
import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
|
|
7
|
-
import {
|
|
6
|
+
import { PeerIDKey } from '../../helpers/PeerID'
|
|
8
7
|
import { DuplicateDetector } from './DuplicateDetector'
|
|
9
8
|
import { ConnectionManager } from '../../connection/ConnectionManager'
|
|
10
|
-
import {
|
|
9
|
+
import { RemoteDhtNode } from '../RemoteDhtNode'
|
|
11
10
|
import { v4 } from 'uuid'
|
|
12
11
|
import { IRoutingService } from '../../proto/packages/dht/protos/DhtRpc.server'
|
|
13
12
|
|
|
@@ -29,8 +28,7 @@ export enum RoutingErrors {
|
|
|
29
28
|
export interface RouterConfig {
|
|
30
29
|
rpcCommunicator: RoutingRpcCommunicator
|
|
31
30
|
ownPeerDescriptor: PeerDescriptor
|
|
32
|
-
|
|
33
|
-
connections: Map<PeerIDKey, DhtPeer>
|
|
31
|
+
connections: Map<PeerIDKey, RemoteDhtNode>
|
|
34
32
|
addContact: (contact: PeerDescriptor, setActive?: boolean) => void
|
|
35
33
|
serviceId: string
|
|
36
34
|
connectionManager?: ConnectionManager
|
|
@@ -44,8 +42,8 @@ interface ForwardingTableEntry {
|
|
|
44
42
|
interface IRouterFunc {
|
|
45
43
|
doRouteMessage(routedMessage: RouteMessageWrapper, mode: RoutingMode, excludedPeer?: PeerDescriptor): RouteMessageAck
|
|
46
44
|
send(msg: Message, reachableThrough: PeerDescriptor[]): Promise<void>
|
|
47
|
-
|
|
48
|
-
addToDuplicateDetector(
|
|
45
|
+
isMostLikelyDuplicate(requestId: string): boolean
|
|
46
|
+
addToDuplicateDetector(requestId: string): void
|
|
49
47
|
addRoutingSession(session: RoutingSession): void
|
|
50
48
|
removeRoutingSession(sessionId: string): void
|
|
51
49
|
stop(): void
|
|
@@ -58,28 +56,26 @@ const logger = new Logger(module)
|
|
|
58
56
|
export class Router implements IRouter {
|
|
59
57
|
private readonly rpcCommunicator: RoutingRpcCommunicator
|
|
60
58
|
private readonly ownPeerDescriptor: PeerDescriptor
|
|
61
|
-
private readonly
|
|
62
|
-
private readonly connections: Map<PeerIDKey, DhtPeer>
|
|
59
|
+
private readonly connections: Map<PeerIDKey, RemoteDhtNode>
|
|
63
60
|
private readonly addContact: (contact: PeerDescriptor, setActive?: boolean) => void
|
|
64
61
|
private readonly serviceId: string
|
|
65
62
|
private readonly connectionManager?: ConnectionManager
|
|
66
63
|
private readonly forwardingTable: Map<string, ForwardingTableEntry> = new Map()
|
|
67
64
|
private ongoingRoutingSessions: Map<string, RoutingSession> = new Map()
|
|
68
|
-
private readonly
|
|
65
|
+
private readonly duplicateRequestDetector: DuplicateDetector = new DuplicateDetector(100000, 100)
|
|
69
66
|
private stopped = false
|
|
70
67
|
|
|
71
68
|
constructor(config: RouterConfig) {
|
|
72
69
|
this.rpcCommunicator = config.rpcCommunicator
|
|
73
70
|
this.ownPeerDescriptor = config.ownPeerDescriptor
|
|
74
|
-
this.ownPeerId = config.ownPeerId
|
|
75
71
|
this.connections = config.connections
|
|
76
72
|
this.addContact = config.addContact
|
|
77
73
|
this.serviceId = config.serviceId
|
|
78
74
|
this.connectionManager = config.connectionManager
|
|
79
75
|
this.rpcCommunicator.registerRpcMethod(RouteMessageWrapper, RouteMessageAck, 'forwardMessage',
|
|
80
|
-
(forwardMessage: RouteMessageWrapper
|
|
76
|
+
(forwardMessage: RouteMessageWrapper) => this.forwardMessage(forwardMessage))
|
|
81
77
|
this.rpcCommunicator.registerRpcMethod(RouteMessageWrapper, RouteMessageAck, 'routeMessage',
|
|
82
|
-
(routedMessage: RouteMessageWrapper
|
|
78
|
+
(routedMessage: RouteMessageWrapper) => this.routeMessage(routedMessage))
|
|
83
79
|
}
|
|
84
80
|
|
|
85
81
|
public async send(msg: Message, reachableThrough: PeerDescriptor[]): Promise<void> {
|
|
@@ -114,8 +110,8 @@ export class Router implements IRouter {
|
|
|
114
110
|
if (this.stopped) {
|
|
115
111
|
return createRouteMessageAck(routedMessage, RoutingErrors.STOPPED)
|
|
116
112
|
}
|
|
117
|
-
logger.trace(`
|
|
118
|
-
|
|
113
|
+
logger.trace(`Routing message ${routedMessage.requestId} from ${keyFromPeerDescriptor(routedMessage.sourcePeer!)} `
|
|
114
|
+
+ `to ${keyFromPeerDescriptor(routedMessage.destinationPeer!)}`)
|
|
119
115
|
routedMessage.routingPath.push(this.ownPeerDescriptor)
|
|
120
116
|
const session = this.createRoutingSession(routedMessage, mode, excludedPeer)
|
|
121
117
|
this.addRoutingSession(session)
|
|
@@ -141,7 +137,7 @@ export class Router implements IRouter {
|
|
|
141
137
|
})
|
|
142
138
|
session.start()
|
|
143
139
|
} catch (e) {
|
|
144
|
-
if (
|
|
140
|
+
if (areEqualPeerDescriptors(routedMessage.sourcePeer!, this.ownPeerDescriptor)) {
|
|
145
141
|
logger.warn(
|
|
146
142
|
`Failed to send (routeMessage: ${this.serviceId}) to ${keyFromPeerDescriptor(routedMessage.destinationPeer!)}: ${e}`
|
|
147
143
|
)
|
|
@@ -162,19 +158,19 @@ export class Router implements IRouter {
|
|
|
162
158
|
this.ownPeerDescriptor,
|
|
163
159
|
routedMessage,
|
|
164
160
|
this.connections,
|
|
165
|
-
this.
|
|
161
|
+
areEqualPeerDescriptors(this.ownPeerDescriptor, routedMessage.sourcePeer!) ? 2 : 1,
|
|
166
162
|
mode,
|
|
167
163
|
undefined,
|
|
168
164
|
excludedPeers
|
|
169
165
|
)
|
|
170
166
|
}
|
|
171
167
|
|
|
172
|
-
public
|
|
173
|
-
return this.
|
|
168
|
+
public isMostLikelyDuplicate(requestId: string): boolean {
|
|
169
|
+
return this.duplicateRequestDetector.isMostLikelyDuplicate(requestId)
|
|
174
170
|
}
|
|
175
171
|
|
|
176
|
-
public addToDuplicateDetector(
|
|
177
|
-
this.
|
|
172
|
+
public addToDuplicateDetector(requestId: string): void {
|
|
173
|
+
this.duplicateRequestDetector.add(requestId)
|
|
178
174
|
}
|
|
179
175
|
|
|
180
176
|
public addRoutingSession(session: RoutingSession): void {
|
|
@@ -195,23 +191,23 @@ export class Router implements IRouter {
|
|
|
195
191
|
clearTimeout(entry.timeout)
|
|
196
192
|
})
|
|
197
193
|
this.forwardingTable.clear()
|
|
198
|
-
this.
|
|
194
|
+
this.duplicateRequestDetector.clear()
|
|
199
195
|
}
|
|
200
196
|
|
|
201
197
|
// IRoutingService method
|
|
202
|
-
async routeMessage(routedMessage: RouteMessageWrapper
|
|
198
|
+
async routeMessage(routedMessage: RouteMessageWrapper): Promise<RouteMessageAck> {
|
|
203
199
|
if (this.stopped) {
|
|
204
200
|
return createRouteMessageAck(routedMessage, 'routeMessage() service is not running')
|
|
205
|
-
} else if (this.
|
|
206
|
-
logger.trace(`
|
|
207
|
-
|
|
201
|
+
} else if (this.duplicateRequestDetector.isMostLikelyDuplicate(routedMessage.requestId)) {
|
|
202
|
+
logger.trace(`Routing message ${routedMessage.requestId} from ${keyFromPeerDescriptor(routedMessage.sourcePeer!)} `
|
|
203
|
+
+ `to ${keyFromPeerDescriptor(routedMessage.destinationPeer!)} is likely a duplicate`)
|
|
208
204
|
return createRouteMessageAck(routedMessage, 'message given to routeMessage() service is likely a duplicate')
|
|
209
205
|
}
|
|
210
206
|
logger.trace(`Processing received routeMessage ${routedMessage.requestId}`)
|
|
211
207
|
this.addContact(routedMessage.sourcePeer!, true)
|
|
212
|
-
this.addToDuplicateDetector(routedMessage.requestId
|
|
213
|
-
if (this.
|
|
214
|
-
logger.trace(
|
|
208
|
+
this.addToDuplicateDetector(routedMessage.requestId)
|
|
209
|
+
if (areEqualPeerDescriptors(this.ownPeerDescriptor, routedMessage.destinationPeer!)) {
|
|
210
|
+
logger.trace(`routing message targeted to self ${routedMessage.requestId}`)
|
|
215
211
|
this.setForwardingEntries(routedMessage)
|
|
216
212
|
this.connectionManager?.handleMessage(routedMessage.message!)
|
|
217
213
|
return createRouteMessageAck(routedMessage)
|
|
@@ -222,7 +218,7 @@ export class Router implements IRouter {
|
|
|
222
218
|
|
|
223
219
|
private setForwardingEntries(routedMessage: RouteMessageWrapper): void {
|
|
224
220
|
const reachableThroughWithoutSelf = routedMessage.reachableThrough.filter((peer) => {
|
|
225
|
-
return !
|
|
221
|
+
return !areEqualPeerDescriptors(peer, this.ownPeerDescriptor)
|
|
226
222
|
})
|
|
227
223
|
|
|
228
224
|
if (reachableThroughWithoutSelf.length > 0) {
|
|
@@ -243,18 +239,18 @@ export class Router implements IRouter {
|
|
|
243
239
|
}
|
|
244
240
|
|
|
245
241
|
// IRoutingService method
|
|
246
|
-
async forwardMessage(forwardMessage: RouteMessageWrapper
|
|
242
|
+
async forwardMessage(forwardMessage: RouteMessageWrapper): Promise<RouteMessageAck> {
|
|
247
243
|
if (this.stopped) {
|
|
248
244
|
return createRouteMessageAck(forwardMessage, 'forwardMessage() service is not running')
|
|
249
|
-
} else if (this.
|
|
250
|
-
logger.trace(`
|
|
251
|
-
|
|
245
|
+
} else if (this.duplicateRequestDetector.isMostLikelyDuplicate(forwardMessage.requestId)) {
|
|
246
|
+
logger.trace(`Forwarding message ${forwardMessage.requestId} from ${keyFromPeerDescriptor(forwardMessage.sourcePeer!)} `
|
|
247
|
+
+ `to ${keyFromPeerDescriptor(forwardMessage.destinationPeer!)} is likely a duplicate`)
|
|
252
248
|
return createRouteMessageAck(forwardMessage, 'message given to forwardMessage() service is likely a duplicate')
|
|
253
249
|
}
|
|
254
250
|
logger.trace(`Processing received forward routeMessage ${forwardMessage.requestId}`)
|
|
255
251
|
this.addContact(forwardMessage.sourcePeer!, true)
|
|
256
|
-
this.addToDuplicateDetector(forwardMessage.requestId
|
|
257
|
-
if (this.
|
|
252
|
+
this.addToDuplicateDetector(forwardMessage.requestId)
|
|
253
|
+
if (areEqualPeerDescriptors(this.ownPeerDescriptor, forwardMessage.destinationPeer!)) {
|
|
258
254
|
return this.forwardToDestination(forwardMessage)
|
|
259
255
|
} else {
|
|
260
256
|
return this.doRouteMessage(forwardMessage, RoutingMode.FORWARD)
|
|
@@ -262,9 +258,9 @@ export class Router implements IRouter {
|
|
|
262
258
|
}
|
|
263
259
|
|
|
264
260
|
private forwardToDestination(routedMessage: RouteMessageWrapper): RouteMessageAck {
|
|
265
|
-
logger.trace(`
|
|
261
|
+
logger.trace(`Forwarding found message targeted to self ${routedMessage.requestId}`)
|
|
266
262
|
const forwardedMessage = routedMessage.message!
|
|
267
|
-
if (this.
|
|
263
|
+
if (areEqualPeerDescriptors(this.ownPeerDescriptor, forwardedMessage.targetDescriptor!)) {
|
|
268
264
|
this.connectionManager?.handleMessage(forwardedMessage)
|
|
269
265
|
return createRouteMessageAck(routedMessage)
|
|
270
266
|
}
|
|
@@ -1,20 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DhtPeer } from '../DhtPeer'
|
|
1
|
+
import { RemoteDhtNode } from '../RemoteDhtNode'
|
|
3
2
|
import { SortedContactList } from '../contact/SortedContactList'
|
|
4
3
|
import { PeerID, PeerIDKey } from '../../helpers/PeerID'
|
|
4
|
+
import { keyFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
|
|
5
5
|
import { Logger } from '@streamr/utils'
|
|
6
6
|
import EventEmitter from 'eventemitter3'
|
|
7
7
|
import { v4 } from 'uuid'
|
|
8
|
-
import { RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
|
|
8
|
+
import { PeerDescriptor, RouteMessageWrapper } from '../../proto/packages/dht/protos/DhtRpc'
|
|
9
9
|
import { RemoteRouter } from './RemoteRouter'
|
|
10
10
|
import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
|
|
11
11
|
import { RoutingServiceClient } from '../../proto/packages/dht/protos/DhtRpc.client'
|
|
12
12
|
import { toProtoRpcClient } from '@streamr/proto-rpc'
|
|
13
|
+
import { Contact } from '../contact/Contact'
|
|
13
14
|
|
|
14
15
|
const logger = new Logger(module)
|
|
15
16
|
|
|
16
17
|
const MAX_FAILED_HOPS = 2
|
|
17
18
|
|
|
19
|
+
class RemoteContact extends Contact {
|
|
20
|
+
|
|
21
|
+
private router: RemoteRouter
|
|
22
|
+
|
|
23
|
+
constructor(peer: RemoteDhtNode, ownPeerDescriptor: PeerDescriptor, rpcCommunicator: RoutingRpcCommunicator) {
|
|
24
|
+
super(peer.getPeerDescriptor())
|
|
25
|
+
this.router = new RemoteRouter(
|
|
26
|
+
ownPeerDescriptor,
|
|
27
|
+
peer.getPeerDescriptor(),
|
|
28
|
+
peer.getServiceId(),
|
|
29
|
+
toProtoRpcClient(new RoutingServiceClient(rpcCommunicator.getRpcClientTransport()))
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getRouter(): RemoteRouter {
|
|
34
|
+
return this.router
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
18
38
|
export interface RoutingSessionEvents {
|
|
19
39
|
// This event is emitted when a peer responds with a success ack
|
|
20
40
|
// to routeMessage call
|
|
@@ -35,10 +55,10 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
|
|
|
35
55
|
public readonly sessionId = v4()
|
|
36
56
|
private readonly rpcCommunicator: RoutingRpcCommunicator
|
|
37
57
|
private ongoingRequests: Set<PeerIDKey> = new Set()
|
|
38
|
-
private contactList: SortedContactList<
|
|
58
|
+
private contactList: SortedContactList<RemoteContact>
|
|
39
59
|
private readonly ownPeerDescriptor: PeerDescriptor
|
|
40
60
|
private readonly messageToRoute: RouteMessageWrapper
|
|
41
|
-
private connections: Map<PeerIDKey,
|
|
61
|
+
private connections: Map<PeerIDKey, RemoteDhtNode>
|
|
42
62
|
private readonly parallelism: number
|
|
43
63
|
private failedHopCounter = 0
|
|
44
64
|
private successfulHopCounter = 0
|
|
@@ -49,7 +69,7 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
|
|
|
49
69
|
rpcCommunicator: RoutingRpcCommunicator,
|
|
50
70
|
ownPeerDescriptor: PeerDescriptor,
|
|
51
71
|
messageToRoute: RouteMessageWrapper,
|
|
52
|
-
connections: Map<PeerIDKey,
|
|
72
|
+
connections: Map<PeerIDKey, RemoteDhtNode>,
|
|
53
73
|
parallelism: number,
|
|
54
74
|
mode: RoutingMode = RoutingMode.ROUTE,
|
|
55
75
|
destinationId?: Uint8Array,
|
|
@@ -102,7 +122,7 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
|
|
|
102
122
|
}
|
|
103
123
|
}
|
|
104
124
|
|
|
105
|
-
private onRequestSucceeded = (
|
|
125
|
+
private onRequestSucceeded = () => {
|
|
106
126
|
logger.trace('onRequestSucceeded() sessionId: ' + this.sessionId)
|
|
107
127
|
if (this.stopped) {
|
|
108
128
|
return
|
|
@@ -117,51 +137,40 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
|
|
|
117
137
|
}
|
|
118
138
|
}
|
|
119
139
|
|
|
120
|
-
private sendRouteMessageRequest = async (contact:
|
|
140
|
+
private sendRouteMessageRequest = async (contact: RemoteContact): Promise<boolean> => {
|
|
121
141
|
if (this.stopped) {
|
|
122
142
|
return false
|
|
123
143
|
}
|
|
144
|
+
const router = contact.getRouter()
|
|
124
145
|
if (this.mode === RoutingMode.FORWARD) {
|
|
125
|
-
return
|
|
146
|
+
return router.forwardMessage({
|
|
126
147
|
...this.messageToRoute,
|
|
127
148
|
previousPeer: this.ownPeerDescriptor
|
|
128
149
|
})
|
|
129
150
|
} else if (this.mode === RoutingMode.RECURSIVE_FIND) {
|
|
130
|
-
return
|
|
151
|
+
return router.findRecursively({
|
|
131
152
|
...this.messageToRoute,
|
|
132
153
|
previousPeer: this.ownPeerDescriptor
|
|
133
154
|
})
|
|
134
155
|
} else {
|
|
135
|
-
return
|
|
156
|
+
return router.routeMessage({
|
|
136
157
|
...this.messageToRoute,
|
|
137
158
|
previousPeer: this.ownPeerDescriptor
|
|
138
159
|
})
|
|
139
160
|
}
|
|
140
161
|
}
|
|
141
162
|
|
|
142
|
-
private findMoreContacts = ():
|
|
163
|
+
private findMoreContacts = (): RemoteContact[] => {
|
|
143
164
|
logger.trace('findMoreContacts() sessionId: ' + this.sessionId)
|
|
144
165
|
// the contents of the connections might have changed between the rounds
|
|
145
166
|
// addContacts() will only add new contacts that were not there yet
|
|
146
167
|
const contacts = Array.from(this.connections.values())
|
|
147
|
-
.map((
|
|
148
|
-
return new RemoteRouter(
|
|
149
|
-
this.ownPeerDescriptor,
|
|
150
|
-
contact.getPeerDescriptor(),
|
|
151
|
-
contact.getServiceId(),
|
|
152
|
-
toProtoRpcClient(new RoutingServiceClient(this.rpcCommunicator.getRpcClientTransport()))
|
|
153
|
-
)
|
|
154
|
-
})
|
|
168
|
+
.map((peer) => new RemoteContact(peer, this.ownPeerDescriptor, this.rpcCommunicator))
|
|
155
169
|
this.contactList.addContacts(contacts)
|
|
156
170
|
return this.contactList.getUncontactedContacts(this.parallelism)
|
|
157
171
|
}
|
|
158
172
|
|
|
159
|
-
|
|
160
|
-
const contacts = this.contactList.getClosestContacts(limit)
|
|
161
|
-
return contacts.map((contact) => contact.getPeerDescriptor())
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
private sendMoreRequests = (uncontacted: RemoteRouter[]) => {
|
|
173
|
+
private sendMoreRequests = (uncontacted: RemoteContact[]) => {
|
|
165
174
|
logger.trace('sendMoreRequests() sessionId: ' + this.sessionId)
|
|
166
175
|
if (this.stopped) {
|
|
167
176
|
return
|
|
@@ -178,14 +187,14 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
|
|
|
178
187
|
while ((this.ongoingRequests.size) < this.parallelism && (uncontacted.length > 0) && !this.stopped) {
|
|
179
188
|
const nextPeer = uncontacted.shift()
|
|
180
189
|
// eslint-disable-next-line max-len
|
|
181
|
-
logger.trace(`Sending routeMessage request
|
|
190
|
+
logger.trace(`Sending routeMessage request to contact: ${keyFromPeerDescriptor(nextPeer!.getPeerDescriptor())} (sessionId=${this.sessionId})`)
|
|
182
191
|
this.contactList.setContacted(nextPeer!.getPeerId())
|
|
183
192
|
this.ongoingRequests.add(nextPeer!.getPeerId().toKey())
|
|
184
193
|
setImmediate(async () => {
|
|
185
194
|
try {
|
|
186
195
|
const succeeded = await this.sendRouteMessageRequest(nextPeer!)
|
|
187
196
|
if (succeeded) {
|
|
188
|
-
this.onRequestSucceeded(
|
|
197
|
+
this.onRequestSucceeded()
|
|
189
198
|
} else {
|
|
190
199
|
this.onRequestFailed(nextPeer!.getPeerId())
|
|
191
200
|
}
|