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

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 (211) 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/eslint.config.mjs +0 -12
  25. package/src/connection/Connection.ts +0 -28
  26. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  27. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  28. package/src/connection/ConnectionLockStates.ts +0 -131
  29. package/src/connection/ConnectionManager.ts +0 -661
  30. package/src/connection/ConnectionsView.ts +0 -8
  31. package/src/connection/ConnectorFacade.ts +0 -217
  32. package/src/connection/Handshaker.ts +0 -209
  33. package/src/connection/IConnection.ts +0 -40
  34. package/src/connection/ManagedConnection.ts +0 -113
  35. package/src/connection/OutputBuffer.ts +0 -28
  36. package/src/connection/PendingConnection.ts +0 -68
  37. package/src/connection/connectivityChecker.ts +0 -108
  38. package/src/connection/connectivityRequestHandler.ts +0 -116
  39. package/src/connection/simulator/Simulator.ts +0 -369
  40. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  41. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  42. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  43. package/src/connection/simulator/pings.ts +0 -42
  44. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  45. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  46. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -245
  47. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  48. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  49. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  50. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  51. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  52. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  53. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  54. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  55. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  56. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  57. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  58. package/src/connection/websocket/WebsocketServer.ts +0 -164
  59. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  60. package/src/connection/websocket/WebsocketServerConnector.ts +0 -290
  61. package/src/dht/DhtNode.ts +0 -683
  62. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  63. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  64. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  65. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  66. package/src/dht/PeerManager.ts +0 -305
  67. package/src/dht/contact/Contact.ts +0 -19
  68. package/src/dht/contact/ContactList.ts +0 -43
  69. package/src/dht/contact/RandomContactList.ts +0 -56
  70. package/src/dht/contact/RingContactList.ts +0 -143
  71. package/src/dht/contact/RpcRemote.ts +0 -72
  72. package/src/dht/contact/SortedContactList.ts +0 -173
  73. package/src/dht/contact/getClosestNodes.ts +0 -24
  74. package/src/dht/contact/ringIdentifiers.ts +0 -62
  75. package/src/dht/discovery/DiscoverySession.ts +0 -129
  76. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  77. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  78. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  79. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  80. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  81. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  82. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  83. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  84. package/src/dht/routing/DuplicateDetector.ts +0 -34
  85. package/src/dht/routing/Router.ts +0 -246
  86. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  87. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  88. package/src/dht/routing/RoutingSession.ts +0 -243
  89. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  90. package/src/dht/routing/getPreviousPeer.ts +0 -6
  91. package/src/dht/store/LocalDataStore.ts +0 -84
  92. package/src/dht/store/StoreManager.ts +0 -170
  93. package/src/dht/store/StoreRpcLocal.ts +0 -89
  94. package/src/dht/store/StoreRpcRemote.ts +0 -32
  95. package/src/exports.ts +0 -33
  96. package/src/helpers/AddressTools.ts +0 -28
  97. package/src/helpers/Connectivity.ts +0 -19
  98. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  99. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  100. package/src/helpers/createPeerDescriptor.ts +0 -57
  101. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  102. package/src/helpers/debugHelpers.ts +0 -9
  103. package/src/helpers/errors.ts +0 -49
  104. package/src/helpers/offering.ts +0 -15
  105. package/src/helpers/protoClasses.ts +0 -57
  106. package/src/helpers/protoToString.ts +0 -21
  107. package/src/helpers/version.ts +0 -32
  108. package/src/identifiers.ts +0 -29
  109. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  110. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  111. package/src/transport/ITransport.ts +0 -37
  112. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  113. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  114. package/src/types/ServiceID.ts +0 -1
  115. package/src/types/textencoding.d.ts +0 -6
  116. package/test/benchmark/Find.test.ts +0 -72
  117. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  118. package/test/benchmark/RingCorrectness.test.ts +0 -157
  119. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  120. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  121. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  122. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  123. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  124. package/test/end-to-end/Layer0.test.ts +0 -76
  125. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  126. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  127. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  128. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  129. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  130. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  131. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  132. package/test/end-to-end/memory-leak.test.ts +0 -80
  133. package/test/integration/ConnectionLocking.test.ts +0 -192
  134. package/test/integration/ConnectionManager.test.ts +0 -528
  135. package/test/integration/ConnectivityChecking.test.ts +0 -53
  136. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  137. package/test/integration/DhtNode.test.ts +0 -66
  138. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  139. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  140. package/test/integration/DhtRpc.test.ts +0 -121
  141. package/test/integration/Find.test.ts +0 -45
  142. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  143. package/test/integration/Layer1-scale.test.ts +0 -189
  144. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  145. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  146. package/test/integration/ReplicateData.test.ts +0 -104
  147. package/test/integration/RouteMessage.test.ts +0 -230
  148. package/test/integration/RouterRpcRemote.test.ts +0 -77
  149. package/test/integration/SimultaneousConnections.test.ts +0 -316
  150. package/test/integration/Store.test.ts +0 -85
  151. package/test/integration/StoreAndDelete.test.ts +0 -77
  152. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  153. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  154. package/test/integration/StoreRpcRemote.test.ts +0 -54
  155. package/test/integration/WebrtcConnectionManagement.test.ts +0 -191
  156. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  157. package/test/integration/Websocket.test.ts +0 -65
  158. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  159. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  160. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -123
  161. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  162. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  163. package/test/types/global.d.ts +0 -1
  164. package/test/unit/AddressTools.test.ts +0 -44
  165. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  166. package/test/unit/ConnectionManager.test.ts +0 -65
  167. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  168. package/test/unit/DiscoverySession.test.ts +0 -87
  169. package/test/unit/DuplicateDetector.test.ts +0 -31
  170. package/test/unit/Handshaker.test.ts +0 -169
  171. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  172. package/test/unit/LocalDataStore.test.ts +0 -108
  173. package/test/unit/ManagedConnection.test.ts +0 -58
  174. package/test/unit/PeerManager.test.ts +0 -93
  175. package/test/unit/PendingConnection.test.ts +0 -57
  176. package/test/unit/ProtobufMessage.test.ts +0 -21
  177. package/test/unit/RandomContactList.test.ts +0 -58
  178. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  179. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  180. package/test/unit/Router.test.ts +0 -137
  181. package/test/unit/RoutingSession.test.ts +0 -86
  182. package/test/unit/SortedContactList.test.ts +0 -115
  183. package/test/unit/StoreManager.test.ts +0 -146
  184. package/test/unit/StoreRpcLocal.test.ts +0 -167
  185. package/test/unit/WebrtcConnection.test.ts +0 -29
  186. package/test/unit/WebrtcConnector.test.ts +0 -56
  187. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  188. package/test/unit/WebsocketServer.test.ts +0 -66
  189. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  190. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  191. package/test/unit/createPeerDescriptor.test.ts +0 -69
  192. package/test/unit/customMatchers.test.ts +0 -34
  193. package/test/unit/getClosestNodes.test.ts +0 -30
  194. package/test/unit/version.test.ts +0 -18
  195. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  196. package/test/utils/FakeConnectorFacade.ts +0 -41
  197. package/test/utils/FakeRpcCommunicator.ts +0 -23
  198. package/test/utils/FakeTransport.ts +0 -79
  199. package/test/utils/customMatchers.ts +0 -71
  200. package/test/utils/mock/MockConnection.ts +0 -26
  201. package/test/utils/mock/MockConnectionsView.ts +0 -18
  202. package/test/utils/mock/MockRouter.ts +0 -62
  203. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  204. package/test/utils/mock/MockTransport.ts +0 -26
  205. package/test/utils/mock/mockDataEntry.ts +0 -38
  206. package/test/utils/topology.ts +0 -79
  207. package/test/utils/utils.ts +0 -268
  208. package/tsconfig.browser.json +0 -17
  209. package/tsconfig.jest.json +0 -25
  210. package/tsconfig.json +0 -3
  211. 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
- }