@streamr/dht 102.0.0-beta.1 → 102.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/dist/generated/google/protobuf/any.d.ts +180 -0
  2. package/dist/generated/google/protobuf/any.js +155 -0
  3. package/dist/generated/google/protobuf/any.js.map +1 -0
  4. package/dist/generated/google/protobuf/empty.d.ts +31 -0
  5. package/dist/generated/google/protobuf/empty.js +32 -0
  6. package/dist/generated/google/protobuf/empty.js.map +1 -0
  7. package/dist/generated/google/protobuf/timestamp.d.ts +155 -0
  8. package/dist/generated/google/protobuf/timestamp.js +136 -0
  9. package/dist/generated/google/protobuf/timestamp.js.map +1 -0
  10. package/dist/generated/packages/dht/protos/DhtRpc.client.d.ts +361 -0
  11. package/dist/generated/packages/dht/protos/DhtRpc.client.js +285 -0
  12. package/dist/generated/packages/dht/protos/DhtRpc.client.js.map +1 -0
  13. package/dist/generated/packages/dht/protos/DhtRpc.d.ts +999 -0
  14. package/dist/generated/packages/dht/protos/DhtRpc.js +677 -0
  15. package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -0
  16. package/dist/generated/packages/dht/protos/DhtRpc.server.d.ts +162 -0
  17. package/dist/generated/packages/dht/protos/DhtRpc.server.js +3 -0
  18. package/dist/generated/packages/dht/protos/DhtRpc.server.js.map +1 -0
  19. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.d.ts +87 -0
  20. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js +66 -0
  21. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js.map +1 -0
  22. package/dist/package.json +7 -7
  23. package/package.json +7 -7
  24. package/src/connection/Connection.ts +0 -28
  25. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  26. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  27. package/src/connection/ConnectionLockStates.ts +0 -131
  28. package/src/connection/ConnectionManager.ts +0 -661
  29. package/src/connection/ConnectionsView.ts +0 -8
  30. package/src/connection/ConnectorFacade.ts +0 -217
  31. package/src/connection/Handshaker.ts +0 -209
  32. package/src/connection/IConnection.ts +0 -40
  33. package/src/connection/ManagedConnection.ts +0 -113
  34. package/src/connection/OutputBuffer.ts +0 -28
  35. package/src/connection/PendingConnection.ts +0 -68
  36. package/src/connection/connectivityChecker.ts +0 -108
  37. package/src/connection/connectivityRequestHandler.ts +0 -116
  38. package/src/connection/simulator/Simulator.ts +0 -369
  39. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  40. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  41. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  42. package/src/connection/simulator/pings.ts +0 -42
  43. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  44. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  45. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -245
  46. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  47. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  48. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  49. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  50. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  51. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  52. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  53. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  54. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  55. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  56. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  57. package/src/connection/websocket/WebsocketServer.ts +0 -164
  58. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  59. package/src/connection/websocket/WebsocketServerConnector.ts +0 -290
  60. package/src/dht/DhtNode.ts +0 -683
  61. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  62. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  63. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  64. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  65. package/src/dht/PeerManager.ts +0 -305
  66. package/src/dht/contact/Contact.ts +0 -19
  67. package/src/dht/contact/ContactList.ts +0 -43
  68. package/src/dht/contact/RandomContactList.ts +0 -56
  69. package/src/dht/contact/RingContactList.ts +0 -143
  70. package/src/dht/contact/RpcRemote.ts +0 -72
  71. package/src/dht/contact/SortedContactList.ts +0 -173
  72. package/src/dht/contact/getClosestNodes.ts +0 -24
  73. package/src/dht/contact/ringIdentifiers.ts +0 -62
  74. package/src/dht/discovery/DiscoverySession.ts +0 -129
  75. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  76. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  77. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  78. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  79. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  80. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  81. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  82. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  83. package/src/dht/routing/DuplicateDetector.ts +0 -34
  84. package/src/dht/routing/Router.ts +0 -246
  85. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  86. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  87. package/src/dht/routing/RoutingSession.ts +0 -243
  88. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  89. package/src/dht/routing/getPreviousPeer.ts +0 -6
  90. package/src/dht/store/LocalDataStore.ts +0 -84
  91. package/src/dht/store/StoreManager.ts +0 -170
  92. package/src/dht/store/StoreRpcLocal.ts +0 -89
  93. package/src/dht/store/StoreRpcRemote.ts +0 -32
  94. package/src/exports.ts +0 -33
  95. package/src/helpers/AddressTools.ts +0 -28
  96. package/src/helpers/Connectivity.ts +0 -19
  97. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  98. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  99. package/src/helpers/createPeerDescriptor.ts +0 -57
  100. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  101. package/src/helpers/debugHelpers.ts +0 -9
  102. package/src/helpers/errors.ts +0 -49
  103. package/src/helpers/offering.ts +0 -15
  104. package/src/helpers/protoClasses.ts +0 -57
  105. package/src/helpers/protoToString.ts +0 -21
  106. package/src/helpers/version.ts +0 -32
  107. package/src/identifiers.ts +0 -29
  108. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  109. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  110. package/src/transport/ITransport.ts +0 -37
  111. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  112. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  113. package/src/types/ServiceID.ts +0 -1
  114. package/src/types/textencoding.d.ts +0 -6
  115. package/test/benchmark/Find.test.ts +0 -72
  116. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  117. package/test/benchmark/RingCorrectness.test.ts +0 -157
  118. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  119. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  120. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  121. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  122. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  123. package/test/end-to-end/Layer0.test.ts +0 -76
  124. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  125. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  126. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  127. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  128. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  129. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  130. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  131. package/test/end-to-end/memory-leak.test.ts +0 -80
  132. package/test/integration/ConnectionLocking.test.ts +0 -192
  133. package/test/integration/ConnectionManager.test.ts +0 -528
  134. package/test/integration/ConnectivityChecking.test.ts +0 -53
  135. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  136. package/test/integration/DhtNode.test.ts +0 -66
  137. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  138. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  139. package/test/integration/DhtRpc.test.ts +0 -121
  140. package/test/integration/Find.test.ts +0 -45
  141. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  142. package/test/integration/Layer1-scale.test.ts +0 -189
  143. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  144. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  145. package/test/integration/ReplicateData.test.ts +0 -104
  146. package/test/integration/RouteMessage.test.ts +0 -230
  147. package/test/integration/RouterRpcRemote.test.ts +0 -77
  148. package/test/integration/SimultaneousConnections.test.ts +0 -316
  149. package/test/integration/Store.test.ts +0 -85
  150. package/test/integration/StoreAndDelete.test.ts +0 -77
  151. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  152. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  153. package/test/integration/StoreRpcRemote.test.ts +0 -54
  154. package/test/integration/WebrtcConnectionManagement.test.ts +0 -191
  155. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  156. package/test/integration/Websocket.test.ts +0 -65
  157. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  158. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  159. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -123
  160. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  161. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  162. package/test/types/global.d.ts +0 -1
  163. package/test/unit/AddressTools.test.ts +0 -44
  164. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  165. package/test/unit/ConnectionManager.test.ts +0 -65
  166. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  167. package/test/unit/DiscoverySession.test.ts +0 -87
  168. package/test/unit/DuplicateDetector.test.ts +0 -31
  169. package/test/unit/Handshaker.test.ts +0 -169
  170. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  171. package/test/unit/LocalDataStore.test.ts +0 -108
  172. package/test/unit/ManagedConnection.test.ts +0 -58
  173. package/test/unit/PeerManager.test.ts +0 -93
  174. package/test/unit/PendingConnection.test.ts +0 -57
  175. package/test/unit/ProtobufMessage.test.ts +0 -21
  176. package/test/unit/RandomContactList.test.ts +0 -58
  177. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  178. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  179. package/test/unit/Router.test.ts +0 -137
  180. package/test/unit/RoutingSession.test.ts +0 -86
  181. package/test/unit/SortedContactList.test.ts +0 -115
  182. package/test/unit/StoreManager.test.ts +0 -146
  183. package/test/unit/StoreRpcLocal.test.ts +0 -167
  184. package/test/unit/WebrtcConnection.test.ts +0 -29
  185. package/test/unit/WebrtcConnector.test.ts +0 -56
  186. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  187. package/test/unit/WebsocketServer.test.ts +0 -66
  188. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  189. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  190. package/test/unit/createPeerDescriptor.test.ts +0 -69
  191. package/test/unit/customMatchers.test.ts +0 -34
  192. package/test/unit/getClosestNodes.test.ts +0 -30
  193. package/test/unit/version.test.ts +0 -18
  194. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  195. package/test/utils/FakeConnectorFacade.ts +0 -41
  196. package/test/utils/FakeRpcCommunicator.ts +0 -23
  197. package/test/utils/FakeTransport.ts +0 -79
  198. package/test/utils/customMatchers.ts +0 -71
  199. package/test/utils/mock/MockConnection.ts +0 -26
  200. package/test/utils/mock/MockConnectionsView.ts +0 -18
  201. package/test/utils/mock/MockRouter.ts +0 -62
  202. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  203. package/test/utils/mock/MockTransport.ts +0 -26
  204. package/test/utils/mock/mockDataEntry.ts +0 -38
  205. package/test/utils/topology.ts +0 -79
  206. package/test/utils/utils.ts +0 -268
  207. package/tsconfig.browser.json +0 -17
  208. package/tsconfig.jest.json +0 -25
  209. package/tsconfig.json +0 -3
  210. package/tsconfig.node.json +0 -24
@@ -1,43 +0,0 @@
1
- import { Logger } from '@streamr/utils'
2
- import { v4 } from 'uuid'
3
- import { RouteMessageWrapper } from '../../../generated/packages/dht/protos/DhtRpc'
4
- import { RecursiveOperationRpcClient } from '../../../generated/packages/dht/protos/DhtRpc.client'
5
- import { RpcRemote } from '../contact/RpcRemote'
6
- import { getPreviousPeer } from '../routing/getPreviousPeer'
7
- import { toNodeId } from '../../identifiers'
8
-
9
- const logger = new Logger(module)
10
-
11
- export class RecursiveOperationRpcRemote extends RpcRemote<RecursiveOperationRpcClient> {
12
-
13
- async routeRequest(params: RouteMessageWrapper): Promise<boolean> {
14
- const message: RouteMessageWrapper = {
15
- target: params.target,
16
- sourcePeer: params.sourcePeer,
17
- message: params.message,
18
- requestId: params.requestId ?? v4(),
19
- reachableThrough: params.reachableThrough ?? [],
20
- routingPath: params.routingPath,
21
- parallelRootNodeIds: params.parallelRootNodeIds
22
- }
23
- const options = this.formDhtRpcOptions({
24
- connect: false
25
- })
26
- try {
27
- const ack = await this.getClient().routeRequest(message, options)
28
- if (ack.error !== undefined) {
29
- logger.trace('Next hop responded with error ' + ack.error)
30
- return false
31
- }
32
- } catch (err) {
33
- const previousPeer = getPreviousPeer(params)
34
- const fromNode = previousPeer
35
- ? toNodeId(previousPeer)
36
- : toNodeId(params.sourcePeer!)
37
- const toNode = toNodeId(this.getPeerDescriptor())
38
- logger.debug(`Failed to send routeRequest message from ${fromNode} to ${toNode}`, { err })
39
- return false
40
- }
41
- return true
42
- }
43
- }
@@ -1,231 +0,0 @@
1
- import EventEmitter from 'eventemitter3'
2
- import { v4 } from 'uuid'
3
- import {
4
- DataEntry,
5
- PeerDescriptor,
6
- RecursiveOperationResponse,
7
- RecursiveOperation,
8
- RouteMessageWrapper,
9
- RouteMessageAck,
10
- RecursiveOperationRequest,
11
- Message
12
- } from '../../../generated/packages/dht/protos/DhtRpc'
13
- import { ITransport } from '../../transport/ITransport'
14
- import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
15
- import { Contact } from '../contact/Contact'
16
- import { SortedContactList } from '../contact/SortedContactList'
17
- import { RecursiveOperationResult } from './RecursiveOperationManager'
18
- import { ServiceID } from '../../types/ServiceID'
19
- import { RecursiveOperationSessionRpcLocal } from './RecursiveOperationSessionRpcLocal'
20
- import { DhtAddress, toDhtAddress, toNodeId, toDhtAddressRaw } from '../../identifiers'
21
- import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
22
-
23
- export interface RecursiveOperationSessionEvents {
24
- completed: () => void
25
- }
26
-
27
- export const RECURSIVE_OPERATION_TIMEOUT = 10 * 1000
28
-
29
- export interface RecursiveOperationSessionOptions {
30
- transport: ITransport
31
- targetId: DhtAddress
32
- localPeerDescriptor: PeerDescriptor
33
- waitedRoutingPathCompletions: number
34
- operation: RecursiveOperation
35
- doRouteRequest: (routedMessage: RouteMessageWrapper) => RouteMessageAck
36
- }
37
-
38
- export class RecursiveOperationSession extends EventEmitter<RecursiveOperationSessionEvents> {
39
-
40
- private readonly id = v4()
41
- private readonly rpcCommunicator: ListeningRpcCommunicator
42
- private results: SortedContactList<Contact>
43
- private foundData: Map<DhtAddress, DataEntry> = new Map()
44
- private allKnownHops: Set<DhtAddress> = new Set()
45
- private reportedHops: Set<DhtAddress> = new Set()
46
- private timeoutTask?: NodeJS.Timeout
47
- private completionEventEmitted = false
48
- private noCloserNodesReceivedCounter = 0
49
- private readonly noCloserNodesReceivedFrom: Set<DhtAddress> = new Set()
50
- private readonly options: RecursiveOperationSessionOptions
51
-
52
- constructor(options: RecursiveOperationSessionOptions) {
53
- super()
54
- this.options = options
55
- this.results = new SortedContactList({
56
- referenceId: options.targetId,
57
- maxSize: 10, // TODO use options option or named constant?
58
- allowToContainReferenceId: true
59
- })
60
- this.rpcCommunicator = new ListeningRpcCommunicator(this.id, options.transport, {
61
- rpcRequestTimeout: RECURSIVE_OPERATION_TIMEOUT
62
- })
63
- this.registerLocalRpcMethods()
64
- }
65
-
66
- private registerLocalRpcMethods() {
67
- const rpcLocal = new RecursiveOperationSessionRpcLocal({
68
- onResponseReceived: (
69
- remoteNodeId: DhtAddress,
70
- routingPath: PeerDescriptor[],
71
- closestConnectedNodes: PeerDescriptor[],
72
- dataEntries: DataEntry[],
73
- noCloserNodesFound: boolean
74
- ) => {
75
- this.onResponseReceived(remoteNodeId, routingPath, closestConnectedNodes, dataEntries, noCloserNodesFound)
76
- }
77
- })
78
- this.rpcCommunicator.registerRpcNotification(RecursiveOperationResponse, 'sendResponse',
79
- (req: RecursiveOperationResponse, context: ServerCallContext) => rpcLocal.sendResponse(req, context))
80
- }
81
-
82
- public start(serviceId: ServiceID): void {
83
- const routeMessage = this.wrapRequest(serviceId)
84
- this.options.doRouteRequest(routeMessage)
85
- }
86
-
87
- private wrapRequest(serviceId: ServiceID): RouteMessageWrapper {
88
- const request: RecursiveOperationRequest = {
89
- sessionId: this.getId(),
90
- operation: this.options.operation
91
- }
92
- const msg: Message = {
93
- messageId: v4(),
94
- serviceId,
95
- body: {
96
- oneofKind: 'recursiveOperationRequest',
97
- recursiveOperationRequest: request
98
- }
99
- }
100
- const routeMessage: RouteMessageWrapper = {
101
- message: msg,
102
- requestId: v4(),
103
- target: toDhtAddressRaw(this.options.targetId),
104
- sourcePeer: this.options.localPeerDescriptor,
105
- reachableThrough: [],
106
- routingPath: [],
107
- parallelRootNodeIds: []
108
- }
109
- return routeMessage
110
- }
111
-
112
- private isCompleted(): boolean {
113
- const unreportedHops: Set<DhtAddress> = new Set(this.allKnownHops)
114
- this.reportedHops.forEach((id) => {
115
- unreportedHops.delete(id)
116
- })
117
- if (this.noCloserNodesReceivedCounter >= 1 && unreportedHops.size === 0) {
118
- if (this.options.operation === RecursiveOperation.FETCH_DATA
119
- && (this.hasNonStaleData() || this.noCloserNodesReceivedCounter >= this.options.waitedRoutingPathCompletions)) {
120
- return true
121
- } else if (this.options.operation === RecursiveOperation.FETCH_DATA) {
122
- return false
123
- }
124
- return true
125
- }
126
- return false
127
- }
128
-
129
- private hasNonStaleData(): boolean {
130
- return Array.from(this.foundData.values()).some((entry) => entry.stale === false)
131
- }
132
-
133
- public onResponseReceived(
134
- remoteNodeId: DhtAddress,
135
- routingPath: PeerDescriptor[],
136
- closestConnectedNodes: PeerDescriptor[],
137
- dataEntries: DataEntry[],
138
- noCloserNodesFound: boolean
139
- ): void {
140
- this.addKnownHops(routingPath)
141
- if (routingPath.length >= 1) {
142
- this.setHopAsReported(routingPath[routingPath.length - 1])
143
- }
144
- closestConnectedNodes.forEach((descriptor: PeerDescriptor) => {
145
- this.results.addContact(new Contact(descriptor))
146
- })
147
- this.processFoundData(dataEntries)
148
- if (noCloserNodesFound || this.noCloserNodesReceivedFrom.has(remoteNodeId)) {
149
- this.onNoCloserPeersFound(remoteNodeId)
150
- }
151
- }
152
-
153
- private addKnownHops(routingPath: PeerDescriptor[]) {
154
- const localNodeId = toNodeId(this.options.localPeerDescriptor)
155
- routingPath.forEach((desc) => {
156
- const newNodeId = toNodeId(desc)
157
- if (localNodeId !== newNodeId) {
158
- this.allKnownHops.add(newNodeId)
159
- }
160
- })
161
- }
162
-
163
- private setHopAsReported(desc: PeerDescriptor) {
164
- const localNodeId = toNodeId(this.options.localPeerDescriptor)
165
- const newNodeId = toNodeId(desc)
166
- if (localNodeId !== newNodeId) {
167
- this.reportedHops.add(newNodeId)
168
- }
169
- if (this.isCompleted()) {
170
- if (!this.completionEventEmitted && this.isCompleted()) {
171
- if (this.timeoutTask) {
172
- clearTimeout(this.timeoutTask)
173
- this.timeoutTask = undefined
174
- }
175
- this.emit('completed')
176
- this.completionEventEmitted = true
177
- }
178
- }
179
- }
180
-
181
- private processFoundData(dataEntries: DataEntry[]): void {
182
- dataEntries.forEach((entry) => {
183
- const creatorNodeId = toDhtAddress(entry.creator)
184
- const existingEntry = this.foundData.get(creatorNodeId)
185
- if (!existingEntry || existingEntry.createdAt! < entry.createdAt!
186
- || (existingEntry.createdAt! <= entry.createdAt! && entry.deleted)) {
187
- this.foundData.set(creatorNodeId, entry)
188
- }
189
- })
190
- }
191
-
192
- private onNoCloserPeersFound(remoteNodeId: DhtAddress): void {
193
- this.noCloserNodesReceivedCounter += 1
194
- this.noCloserNodesReceivedFrom.add(remoteNodeId)
195
- if (this.isCompleted()) {
196
- this.emit('completed')
197
- this.completionEventEmitted = true
198
- if (this.timeoutTask) {
199
- clearTimeout(this.timeoutTask)
200
- this.timeoutTask = undefined
201
- }
202
- } else if (!this.timeoutTask && !this.completionEventEmitted) {
203
- this.timeoutTask = setTimeout(() => {
204
- if (!this.completionEventEmitted) {
205
- this.emit('completed')
206
- this.completionEventEmitted = true
207
- }
208
- }, 4000) // TODO use options option or named constant?
209
- }
210
- }
211
-
212
- public getResults(): RecursiveOperationResult {
213
- return {
214
- closestNodes: this.results.getClosestContacts().map((contact) => contact.getPeerDescriptor()),
215
- dataEntries: Array.from(this.foundData.values())
216
- }
217
- }
218
-
219
- public getId(): string {
220
- return this.id
221
- }
222
-
223
- public stop(): void {
224
- if (this.timeoutTask) {
225
- clearTimeout(this.timeoutTask)
226
- this.timeoutTask = undefined
227
- }
228
- this.rpcCommunicator.destroy()
229
- this.emit('completed')
230
- }
231
- }
@@ -1,35 +0,0 @@
1
- import { IRecursiveOperationSessionRpc } from '../../../generated/packages/dht/protos/DhtRpc.server'
2
- import { Empty } from '../../../generated/google/protobuf/empty'
3
- import { DataEntry, RecursiveOperationResponse, PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
4
- import { Logger } from '@streamr/utils'
5
- import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
6
- import { DhtCallContext } from '../../rpc-protocol/DhtCallContext'
7
- import { DhtAddress, toNodeId } from '../../identifiers'
8
-
9
- const logger = new Logger(module)
10
-
11
- interface RecursiveOperationSessionRpcLocalOptions {
12
- onResponseReceived: (
13
- remoteNodeId: DhtAddress,
14
- routingPath: PeerDescriptor[],
15
- nodes: PeerDescriptor[],
16
- dataEntries: DataEntry[],
17
- noCloserNodesFound: boolean
18
- ) => void
19
- }
20
-
21
- export class RecursiveOperationSessionRpcLocal implements IRecursiveOperationSessionRpc {
22
-
23
- private readonly options: RecursiveOperationSessionRpcLocalOptions
24
-
25
- constructor(options: RecursiveOperationSessionRpcLocalOptions) {
26
- this.options = options
27
- }
28
-
29
- async sendResponse(report: RecursiveOperationResponse, context: ServerCallContext): Promise<Empty> {
30
- const remoteNodeId = toNodeId((context as DhtCallContext).incomingSourceDescriptor!)
31
- logger.trace('RecursiveOperationResponse arrived: ' + JSON.stringify(report))
32
- this.options.onResponseReceived(remoteNodeId, report.routingPath, report.closestConnectedNodes, report.dataEntries, report.noCloserNodesFound)
33
- return {}
34
- }
35
- }
@@ -1,30 +0,0 @@
1
- import { Logger } from '@streamr/utils'
2
- import {
3
- DataEntry,
4
- PeerDescriptor,
5
- RecursiveOperationResponse
6
- } from '../../../generated/packages/dht/protos/DhtRpc'
7
- import { RecursiveOperationSessionRpcClient } from '../../../generated/packages/dht/protos/DhtRpc.client'
8
- import { RpcRemote } from '../contact/RpcRemote'
9
-
10
- const logger = new Logger(module)
11
-
12
- export class RecursiveOperationSessionRpcRemote extends RpcRemote<RecursiveOperationSessionRpcClient> {
13
-
14
- sendResponse(
15
- routingPath: PeerDescriptor[],
16
- closestConnectedNodes: PeerDescriptor[],
17
- dataEntries: DataEntry[],
18
- noCloserNodesFound: boolean
19
- ): void {
20
- const report: RecursiveOperationResponse = {
21
- routingPath,
22
- closestConnectedNodes,
23
- dataEntries,
24
- noCloserNodesFound
25
- }
26
- this.getClient().sendResponse(report, this.formDhtRpcOptions()).catch((_e) => {
27
- logger.trace('Failed to send RecursiveOperationResponse')
28
- })
29
- }
30
- }
@@ -1,34 +0,0 @@
1
- export class DuplicateDetector {
2
-
3
- private values: Set<string> = new Set()
4
- private queue: string[] = []
5
- private maxItemCount: number
6
-
7
- constructor(
8
- maxItemCount: number,
9
- ) {
10
- this.maxItemCount = maxItemCount
11
- }
12
-
13
- public add(value: string): void {
14
- this.values.add(value)
15
- this.queue.push(value)
16
- if (this.queue.length > this.maxItemCount) {
17
- const removed = this.queue.shift()!
18
- this.values.delete(removed)
19
- }
20
- }
21
-
22
- public isMostLikelyDuplicate(value: string): boolean {
23
- return this.values.has(value)
24
- }
25
-
26
- public size(): number {
27
- return this.values.size
28
- }
29
-
30
- public clear(): void {
31
- this.values.clear()
32
- this.queue = []
33
- }
34
- }
@@ -1,246 +0,0 @@
1
- import { Message, PeerDescriptor, RouteMessageAck, RouteMessageError, RouteMessageWrapper } from '../../../generated/packages/dht/protos/DhtRpc'
2
- import { RoutingMode, RoutingRemoteContact, RoutingSession, RoutingSessionEvents } from './RoutingSession'
3
- import { Logger, executeSafePromise, raceEvents3, withTimeout } from '@streamr/utils'
4
- import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
5
- import { DuplicateDetector } from './DuplicateDetector'
6
- import { v4 } from 'uuid'
7
- import { RouterRpcLocal, createRouteMessageAck } from './RouterRpcLocal'
8
- import { DhtAddress, areEqualPeerDescriptors, toDhtAddress, toNodeId } from '../../identifiers'
9
- import { RoutingTablesCache } from './RoutingTablesCache'
10
-
11
- export interface RouterOptions {
12
- rpcCommunicator: RoutingRpcCommunicator
13
- localPeerDescriptor: PeerDescriptor
14
- handleMessage: (message: Message) => void
15
- getConnections: () => PeerDescriptor[]
16
- }
17
-
18
- interface ForwardingTableEntry {
19
- timeout: NodeJS.Timeout
20
- peerDescriptors: PeerDescriptor[]
21
- }
22
-
23
- const logger = new Logger(module)
24
-
25
- export class Router {
26
-
27
- private readonly forwardingTable: Map<DhtAddress, ForwardingTableEntry> = new Map()
28
- private readonly routingTablesCache = new RoutingTablesCache()
29
- private ongoingRoutingSessions: Map<string, RoutingSession> = new Map()
30
- // TODO use options option or named constant?
31
- private readonly duplicateRequestDetector: DuplicateDetector = new DuplicateDetector(10000)
32
- private stopped = false
33
- private readonly options: RouterOptions
34
- private messagesRouted = 0
35
- private messagesSent = 0
36
-
37
- constructor(options: RouterOptions) {
38
- this.options = options
39
- this.registerLocalRpcMethods()
40
- }
41
-
42
- private registerLocalRpcMethods() {
43
- const rpcLocal = new RouterRpcLocal({
44
- doRouteMessage: (routedMessage: RouteMessageWrapper, mode?: RoutingMode) => this.doRouteMessage(routedMessage, mode),
45
- setForwardingEntries: (routedMessage: RouteMessageWrapper) => this.setForwardingEntries(routedMessage),
46
- duplicateRequestDetector: this.duplicateRequestDetector,
47
- localPeerDescriptor: this.options.localPeerDescriptor,
48
- handleMessage: this.options.handleMessage
49
- })
50
- this.options.rpcCommunicator.registerRpcMethod(
51
- RouteMessageWrapper,
52
- RouteMessageAck,
53
- 'routeMessage',
54
- async (routedMessage: RouteMessageWrapper) => {
55
- if (this.stopped) {
56
- return createRouteMessageAck(routedMessage, RouteMessageError.STOPPED)
57
- }
58
- return rpcLocal.routeMessage(routedMessage)
59
- }
60
- )
61
- this.options.rpcCommunicator.registerRpcMethod(
62
- RouteMessageWrapper,
63
- RouteMessageAck,
64
- 'forwardMessage',
65
- async (forwardMessage: RouteMessageWrapper) => {
66
- if (this.stopped) {
67
- return createRouteMessageAck(forwardMessage, RouteMessageError.STOPPED)
68
- }
69
- return rpcLocal.forwardMessage(forwardMessage)
70
- }
71
- )
72
-
73
- }
74
-
75
- public send(msg: Message, reachableThrough: PeerDescriptor[]): void {
76
- msg.sourceDescriptor = this.options.localPeerDescriptor
77
- const targetPeerDescriptor = msg.targetDescriptor!
78
- const forwardingEntry = this.forwardingTable.get(toNodeId(targetPeerDescriptor))
79
- if (forwardingEntry && forwardingEntry.peerDescriptors.length > 0) {
80
- const forwardedMessage: RouteMessageWrapper = {
81
- message: msg,
82
- requestId: v4(),
83
- target: forwardingEntry.peerDescriptors[0].nodeId,
84
- sourcePeer: this.options.localPeerDescriptor,
85
- reachableThrough,
86
- routingPath: [],
87
- parallelRootNodeIds: []
88
- }
89
- const ack = this.doRouteMessage(forwardedMessage, RoutingMode.FORWARD)
90
- if (ack.error !== undefined) {
91
- const error = 'Could not forward message with error ' + ack.error
92
- logger.debug(error)
93
- throw new Error(error)
94
- }
95
- } else {
96
- const routedMessage: RouteMessageWrapper = {
97
- message: msg,
98
- requestId: v4(),
99
- target: targetPeerDescriptor.nodeId,
100
- sourcePeer: this.options.localPeerDescriptor,
101
- reachableThrough,
102
- routingPath: [],
103
- parallelRootNodeIds: []
104
- }
105
- const ack = this.doRouteMessage(routedMessage, RoutingMode.ROUTE)
106
- if (ack.error !== undefined) {
107
- const error = 'Could not route message with error ' + ack.error
108
- logger.debug(error)
109
- throw new Error(error)
110
- }
111
- }
112
- this.messagesSent += 1
113
- }
114
-
115
- public doRouteMessage(routedMessage: RouteMessageWrapper, mode = RoutingMode.ROUTE, excludedPeer?: DhtAddress): RouteMessageAck {
116
- if (this.stopped) {
117
- return createRouteMessageAck(routedMessage, RouteMessageError.STOPPED)
118
- }
119
- logger.trace(`Routing message ${routedMessage.requestId} from ${toNodeId(routedMessage.sourcePeer!)} `
120
- + `to ${toDhtAddress(routedMessage.target)}`)
121
- const session = this.createRoutingSession(routedMessage, mode, excludedPeer)
122
- const contacts = session.updateAndGetRoutablePeers()
123
- if (contacts.length > 0) {
124
- this.addRoutingSession(session)
125
- logger.trace('starting to raceEvents from routingSession: ' + session.sessionId)
126
- let eventReceived: Promise<unknown>
127
- executeSafePromise(async () => {
128
- eventReceived = raceEvents3<RoutingSessionEvents>(
129
- session,
130
- ['routingSucceeded', 'partialSuccess', 'routingFailed', 'stopped'],
131
- null
132
- )
133
- })
134
- setImmediate(async () => {
135
- try {
136
- // TODO use options option or named constant?
137
- await withTimeout(eventReceived, 10000)
138
- logger.trace('raceEvents ended from routingSession: ' + session.sessionId)
139
- } catch {
140
- logger.trace('raceEvents timed out for routingSession ' + session.sessionId)
141
- }
142
- session.stop()
143
- this.removeRoutingSession(session.sessionId)
144
- })
145
- session.sendMoreRequests(contacts)
146
- this.messagesRouted += 1
147
- return createRouteMessageAck(routedMessage)
148
- } else {
149
- logger.trace('no targets', { sessionId: session.sessionId })
150
- return createRouteMessageAck(routedMessage, RouteMessageError.NO_TARGETS)
151
- }
152
- }
153
-
154
- private createRoutingSession(routedMessage: RouteMessageWrapper, mode: RoutingMode, excludedNode?: DhtAddress): RoutingSession {
155
- const excludedNodeIds = new Set<DhtAddress>(routedMessage.routingPath.map((descriptor) => toNodeId(descriptor)))
156
- if (excludedNode) {
157
- excludedNodeIds.add(excludedNode)
158
- }
159
- routedMessage.parallelRootNodeIds.forEach((nodeId) => {
160
- excludedNodeIds.add(nodeId as DhtAddress)
161
- })
162
- return new RoutingSession({
163
- rpcCommunicator: this.options.rpcCommunicator,
164
- localPeerDescriptor: this.options.localPeerDescriptor,
165
- routedMessage,
166
- // TODO use options option or named constant?
167
- parallelism: areEqualPeerDescriptors(this.options.localPeerDescriptor, routedMessage.sourcePeer!) ? 2 : 1,
168
- mode,
169
- excludedNodeIds,
170
- routingTablesCache: this.routingTablesCache,
171
- getConnections: this.options.getConnections
172
- })
173
- }
174
-
175
- public isMostLikelyDuplicate(requestId: string): boolean {
176
- return this.duplicateRequestDetector.isMostLikelyDuplicate(requestId)
177
- }
178
-
179
- public addToDuplicateDetector(requestId: string): void {
180
- this.duplicateRequestDetector.add(requestId)
181
- }
182
-
183
- public addRoutingSession(session: RoutingSession): void {
184
- this.ongoingRoutingSessions.set(session.sessionId, session)
185
- }
186
-
187
- public removeRoutingSession(sessionId: string): void {
188
- this.ongoingRoutingSessions.delete(sessionId)
189
- }
190
-
191
- onNodeConnected(peerDescriptor: PeerDescriptor): void {
192
- const remote = new RoutingRemoteContact(peerDescriptor, this.options.localPeerDescriptor, this.options.rpcCommunicator)
193
- this.routingTablesCache.onNodeConnected(remote)
194
- }
195
-
196
- onNodeDisconnected(peerDescriptor: PeerDescriptor): void {
197
- this.routingTablesCache.onNodeDisconnected(toNodeId(peerDescriptor))
198
- }
199
-
200
- public resetCache(): void {
201
- this.routingTablesCache.reset()
202
- }
203
-
204
- public stop(): void {
205
- this.stopped = true
206
- this.ongoingRoutingSessions.forEach((session, _id) => {
207
- session.stop()
208
- })
209
- this.ongoingRoutingSessions.clear()
210
- this.forwardingTable.forEach((entry) => {
211
- clearTimeout(entry.timeout)
212
- })
213
- this.forwardingTable.clear()
214
- this.duplicateRequestDetector.clear()
215
- this.routingTablesCache.reset()
216
- }
217
-
218
- getDiagnosticInfo(): Record<string, unknown> {
219
- return {
220
- messagesRouted: this.messagesRouted,
221
- messagesSent: this.messagesSent
222
- }
223
- }
224
-
225
- private setForwardingEntries(routedMessage: RouteMessageWrapper): void {
226
- const reachableThroughWithoutSelf = routedMessage.reachableThrough.filter((peer) => {
227
- return !areEqualPeerDescriptors(peer, this.options.localPeerDescriptor)
228
- })
229
-
230
- if (reachableThroughWithoutSelf.length > 0) {
231
- const sourceNodeId = toNodeId(routedMessage.sourcePeer!)
232
- if (this.forwardingTable.has(sourceNodeId)) {
233
- const oldEntry = this.forwardingTable.get(sourceNodeId)
234
- clearTimeout(oldEntry!.timeout)
235
- this.forwardingTable.delete(sourceNodeId)
236
- }
237
- const forwardingEntry: ForwardingTableEntry = {
238
- peerDescriptors: reachableThroughWithoutSelf,
239
- timeout: setTimeout(() => {
240
- this.forwardingTable.delete(sourceNodeId)
241
- }, 10000) // TODO use options option or named constant?
242
- }
243
- this.forwardingTable.set(sourceNodeId, forwardingEntry)
244
- }
245
- }
246
- }