@streamr/dht 102.0.0-beta.0 → 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 (264) hide show
  1. package/dist/generated/packages/dht/protos/DhtRpc.d.ts +16 -8
  2. package/dist/generated/packages/dht/protos/DhtRpc.js +7 -5
  3. package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -1
  4. package/dist/package.json +15 -16
  5. package/dist/src/connection/ConnectionManager.js +18 -8
  6. package/dist/src/connection/ConnectionManager.js.map +1 -1
  7. package/dist/src/connection/Handshaker.d.ts +1 -1
  8. package/dist/src/connection/Handshaker.js +9 -5
  9. package/dist/src/connection/Handshaker.js.map +1 -1
  10. package/dist/src/connection/ManagedConnection.js +17 -7
  11. package/dist/src/connection/ManagedConnection.js.map +1 -1
  12. package/dist/src/connection/connectivityChecker.js +20 -10
  13. package/dist/src/connection/connectivityChecker.js.map +1 -1
  14. package/dist/src/connection/connectivityRequestHandler.js +3 -3
  15. package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
  16. package/dist/src/connection/simulator/Simulator.js +3 -2
  17. package/dist/src/connection/simulator/Simulator.js.map +1 -1
  18. package/dist/src/connection/simulator/pings.d.ts +1 -1
  19. package/dist/src/connection/simulator/pings.js +3 -3
  20. package/dist/src/connection/simulator/pings.js.map +1 -1
  21. package/dist/src/connection/webrtc/NodeWebrtcConnection.js +0 -2
  22. package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
  23. package/dist/src/connection/webrtc/WebrtcConnector.js +19 -9
  24. package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
  25. package/dist/src/connection/webrtc/iceServerAsString.js +1 -2
  26. package/dist/src/connection/webrtc/iceServerAsString.js.map +1 -1
  27. package/dist/src/connection/websocket/AbstractWebsocketClientConnection.d.ts +0 -2
  28. package/dist/src/connection/websocket/WebsocketClientConnectorRpcLocal.d.ts +0 -1
  29. package/dist/src/connection/websocket/WebsocketServerConnection.d.ts +0 -1
  30. package/dist/src/connection/websocket/WebsocketServerConnector.js +28 -18
  31. package/dist/src/connection/websocket/WebsocketServerConnector.js.map +1 -1
  32. package/dist/src/dht/DhtNode.d.ts +1 -0
  33. package/dist/src/dht/DhtNode.js +3 -2
  34. package/dist/src/dht/DhtNode.js.map +1 -1
  35. package/dist/src/dht/DhtNodeRpcLocal.d.ts +1 -1
  36. package/dist/src/dht/PeerManager.d.ts +2 -1
  37. package/dist/src/dht/PeerManager.js +2 -1
  38. package/dist/src/dht/PeerManager.js.map +1 -1
  39. package/dist/src/dht/contact/SortedContactList.js +1 -1
  40. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  41. package/dist/src/dht/discovery/DiscoverySession.d.ts +0 -1
  42. package/dist/src/dht/discovery/PeerDiscovery.d.ts +0 -1
  43. package/dist/src/dht/discovery/RingDiscoverySession.d.ts +0 -1
  44. package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +2 -2
  45. package/dist/src/dht/routing/DuplicateDetector.js.map +1 -1
  46. package/dist/src/dht/routing/RoutingSession.js +2 -2
  47. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  48. package/dist/src/dht/routing/RoutingTablesCache.d.ts +1 -1
  49. package/dist/src/dht/store/LocalDataStore.js +1 -1
  50. package/dist/src/dht/store/LocalDataStore.js.map +1 -1
  51. package/dist/src/dht/store/StoreManager.d.ts +1 -1
  52. package/dist/src/dht/store/StoreRpcLocal.d.ts +1 -1
  53. package/dist/src/helpers/AddressTools.js +2 -3
  54. package/dist/src/helpers/AddressTools.js.map +1 -1
  55. package/dist/src/helpers/debugHelpers.js +2 -2
  56. package/dist/src/helpers/debugHelpers.js.map +1 -1
  57. package/dist/src/helpers/protoClasses.d.ts +1 -1
  58. package/dist/src/helpers/protoClasses.js.map +1 -1
  59. package/dist/src/helpers/protoToString.js +1 -2
  60. package/dist/src/helpers/protoToString.js.map +1 -1
  61. package/dist/src/helpers/version.d.ts +1 -1
  62. package/dist/src/helpers/version.js +4 -4
  63. package/dist/src/helpers/version.js.map +1 -1
  64. package/eslint.config.mjs +12 -0
  65. package/jest.config.ts +12 -0
  66. package/package.json +15 -16
  67. package/protos/DhtRpc.proto +6 -4
  68. package/.eslintignore +0 -5
  69. package/.eslintrc +0 -3
  70. package/generated/google/protobuf/any.ts +0 -326
  71. package/generated/google/protobuf/empty.ts +0 -81
  72. package/generated/google/protobuf/timestamp.ts +0 -287
  73. package/generated/packages/dht/protos/DhtRpc.client.ts +0 -419
  74. package/generated/packages/dht/protos/DhtRpc.server.ts +0 -165
  75. package/generated/packages/dht/protos/DhtRpc.ts +0 -1266
  76. package/generated/packages/proto-rpc/protos/ProtoRpc.ts +0 -108
  77. package/jest.config.js +0 -5
  78. package/src/connection/Connection.ts +0 -28
  79. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  80. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  81. package/src/connection/ConnectionLockStates.ts +0 -131
  82. package/src/connection/ConnectionManager.ts +0 -661
  83. package/src/connection/ConnectionsView.ts +0 -8
  84. package/src/connection/ConnectorFacade.ts +0 -217
  85. package/src/connection/Handshaker.ts +0 -205
  86. package/src/connection/IConnection.ts +0 -40
  87. package/src/connection/ManagedConnection.ts +0 -113
  88. package/src/connection/OutputBuffer.ts +0 -28
  89. package/src/connection/PendingConnection.ts +0 -68
  90. package/src/connection/connectivityChecker.ts +0 -108
  91. package/src/connection/connectivityRequestHandler.ts +0 -116
  92. package/src/connection/simulator/Simulator.ts +0 -368
  93. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  94. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  95. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  96. package/src/connection/simulator/pings.ts +0 -42
  97. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  98. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  99. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -247
  100. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  101. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  102. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  103. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  104. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  105. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  106. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  107. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  108. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  109. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  110. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  111. package/src/connection/websocket/WebsocketServer.ts +0 -164
  112. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  113. package/src/connection/websocket/WebsocketServerConnector.ts +0 -286
  114. package/src/dht/DhtNode.ts +0 -678
  115. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  116. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  117. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  118. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  119. package/src/dht/PeerManager.ts +0 -303
  120. package/src/dht/contact/Contact.ts +0 -19
  121. package/src/dht/contact/ContactList.ts +0 -43
  122. package/src/dht/contact/RandomContactList.ts +0 -56
  123. package/src/dht/contact/RingContactList.ts +0 -143
  124. package/src/dht/contact/RpcRemote.ts +0 -72
  125. package/src/dht/contact/SortedContactList.ts +0 -173
  126. package/src/dht/contact/getClosestNodes.ts +0 -24
  127. package/src/dht/contact/ringIdentifiers.ts +0 -62
  128. package/src/dht/discovery/DiscoverySession.ts +0 -129
  129. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  130. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  131. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  132. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  133. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  134. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  135. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  136. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  137. package/src/dht/routing/DuplicateDetector.ts +0 -34
  138. package/src/dht/routing/Router.ts +0 -246
  139. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  140. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  141. package/src/dht/routing/RoutingSession.ts +0 -243
  142. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  143. package/src/dht/routing/getPreviousPeer.ts +0 -6
  144. package/src/dht/store/LocalDataStore.ts +0 -84
  145. package/src/dht/store/StoreManager.ts +0 -170
  146. package/src/dht/store/StoreRpcLocal.ts +0 -89
  147. package/src/dht/store/StoreRpcRemote.ts +0 -32
  148. package/src/exports.ts +0 -33
  149. package/src/helpers/AddressTools.ts +0 -28
  150. package/src/helpers/Connectivity.ts +0 -19
  151. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  152. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  153. package/src/helpers/createPeerDescriptor.ts +0 -57
  154. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  155. package/src/helpers/debugHelpers.ts +0 -9
  156. package/src/helpers/errors.ts +0 -49
  157. package/src/helpers/offering.ts +0 -15
  158. package/src/helpers/protoClasses.ts +0 -57
  159. package/src/helpers/protoToString.ts +0 -21
  160. package/src/helpers/version.ts +0 -32
  161. package/src/identifiers.ts +0 -29
  162. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  163. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  164. package/src/transport/ITransport.ts +0 -37
  165. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  166. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  167. package/src/types/ServiceID.ts +0 -1
  168. package/src/types/textencoding.d.ts +0 -6
  169. package/test/benchmark/Find.test.ts +0 -72
  170. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  171. package/test/benchmark/RingCorrectness.test.ts +0 -157
  172. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  173. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  174. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  175. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  176. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  177. package/test/end-to-end/Layer0.test.ts +0 -76
  178. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  179. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  180. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  181. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  182. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  183. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  184. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  185. package/test/end-to-end/memory-leak.test.ts +0 -80
  186. package/test/integration/ConnectionLocking.test.ts +0 -182
  187. package/test/integration/ConnectionManager.test.ts +0 -528
  188. package/test/integration/ConnectivityChecking.test.ts +0 -53
  189. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  190. package/test/integration/DhtNode.test.ts +0 -66
  191. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  192. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  193. package/test/integration/DhtRpc.test.ts +0 -121
  194. package/test/integration/Find.test.ts +0 -45
  195. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  196. package/test/integration/Layer1-scale.test.ts +0 -189
  197. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  198. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  199. package/test/integration/ReplicateData.test.ts +0 -104
  200. package/test/integration/RouteMessage.test.ts +0 -230
  201. package/test/integration/RouterRpcRemote.test.ts +0 -77
  202. package/test/integration/SimultaneousConnections.test.ts +0 -316
  203. package/test/integration/Store.test.ts +0 -85
  204. package/test/integration/StoreAndDelete.test.ts +0 -77
  205. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  206. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  207. package/test/integration/StoreRpcRemote.test.ts +0 -54
  208. package/test/integration/WebrtcConnectionManagement.test.ts +0 -219
  209. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  210. package/test/integration/Websocket.test.ts +0 -65
  211. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  212. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  213. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -158
  214. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  215. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  216. package/test/types/global.d.ts +0 -1
  217. package/test/unit/AddressTools.test.ts +0 -44
  218. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  219. package/test/unit/ConnectionManager.test.ts +0 -65
  220. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  221. package/test/unit/DiscoverySession.test.ts +0 -87
  222. package/test/unit/DuplicateDetector.test.ts +0 -31
  223. package/test/unit/Handshaker.test.ts +0 -169
  224. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  225. package/test/unit/LocalDataStore.test.ts +0 -108
  226. package/test/unit/ManagedConnection.test.ts +0 -58
  227. package/test/unit/PeerManager.test.ts +0 -93
  228. package/test/unit/PendingConnection.test.ts +0 -57
  229. package/test/unit/ProtobufMessage.test.ts +0 -21
  230. package/test/unit/RandomContactList.test.ts +0 -58
  231. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  232. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  233. package/test/unit/Router.test.ts +0 -137
  234. package/test/unit/RoutingSession.test.ts +0 -79
  235. package/test/unit/SortedContactList.test.ts +0 -115
  236. package/test/unit/StoreManager.test.ts +0 -146
  237. package/test/unit/StoreRpcLocal.test.ts +0 -167
  238. package/test/unit/WebrtcConnection.test.ts +0 -29
  239. package/test/unit/WebrtcConnector.test.ts +0 -56
  240. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  241. package/test/unit/WebsocketServer.test.ts +0 -66
  242. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  243. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  244. package/test/unit/createPeerDescriptor.test.ts +0 -69
  245. package/test/unit/customMatchers.test.ts +0 -16
  246. package/test/unit/getClosestNodes.test.ts +0 -30
  247. package/test/unit/version.test.ts +0 -18
  248. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  249. package/test/utils/FakeConnectorFacade.ts +0 -41
  250. package/test/utils/FakeRpcCommunicator.ts +0 -23
  251. package/test/utils/FakeTransport.ts +0 -79
  252. package/test/utils/customMatchers.ts +0 -71
  253. package/test/utils/mock/MockConnection.ts +0 -26
  254. package/test/utils/mock/MockConnectionsView.ts +0 -18
  255. package/test/utils/mock/MockRouter.ts +0 -62
  256. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  257. package/test/utils/mock/MockTransport.ts +0 -26
  258. package/test/utils/mock/mockDataEntry.ts +0 -38
  259. package/test/utils/topology.ts +0 -80
  260. package/test/utils/utils.ts +0 -268
  261. package/tsconfig.browser.json +0 -17
  262. package/tsconfig.jest.json +0 -25
  263. package/tsconfig.json +0 -3
  264. package/tsconfig.node.json +0 -24
@@ -1,244 +0,0 @@
1
- import { Logger, scheduleAtInterval, setAbortableTimeout } from '@streamr/utils'
2
- import { ConnectionLocker } from '../../connection/ConnectionManager'
3
- import {
4
- DhtAddress,
5
- areEqualPeerDescriptors,
6
- randomDhtAddress,
7
- toDhtAddress,
8
- toNodeId,
9
- toDhtAddressRaw
10
- } from '../../identifiers'
11
- import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
12
- import { ServiceID } from '../../types/ServiceID'
13
- import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
14
- import { PeerManager } from '../PeerManager'
15
- import { getClosestNodes } from '../contact/getClosestNodes'
16
- import { RingIdRaw, getRingIdRawFromPeerDescriptor } from '../contact/ringIdentifiers'
17
- import { DiscoverySession } from './DiscoverySession'
18
- import { RingDiscoverySession } from './RingDiscoverySession'
19
- import { CONTROL_LAYER_NODE_SERVICE_ID } from '../DhtNode'
20
-
21
- interface PeerDiscoveryOptions {
22
- localPeerDescriptor: PeerDescriptor
23
- joinNoProgressLimit: number
24
- serviceId: ServiceID
25
- parallelism: number
26
- joinTimeout: number
27
- connectionLocker?: ConnectionLocker
28
- peerManager: PeerManager
29
- abortSignal: AbortSignal
30
- createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => DhtNodeRpcRemote
31
- }
32
-
33
- export const createDistantDhtAddress = (address: DhtAddress): DhtAddress => {
34
- const raw = toDhtAddressRaw(address)
35
- const flipped = raw.map((val) => ~val)
36
- return toDhtAddress(flipped)
37
- }
38
-
39
- const logger = new Logger(module)
40
-
41
- export class PeerDiscovery {
42
-
43
- private ongoingDiscoverySessions: Map<string, DiscoverySession> = new Map()
44
- private ongoingRingDiscoverySessions: Map<string, RingDiscoverySession> = new Map()
45
-
46
- private rejoinOngoing = false
47
- private joinCalled = false
48
- private recoveryIntervalStarted = false
49
- private readonly options: PeerDiscoveryOptions
50
-
51
- constructor(options: PeerDiscoveryOptions) {
52
- this.options = options
53
- }
54
-
55
- async joinDht(
56
- entryPoints: PeerDescriptor[],
57
- doAdditionalDistantPeerDiscovery = true,
58
- retry = true
59
- ): Promise<void> {
60
- const contactedPeers = new Set<DhtAddress>()
61
- const distantJoinOptions = doAdditionalDistantPeerDiscovery
62
- ? { enabled: true, contactedPeers: new Set<DhtAddress>() } : { enabled: false } as const
63
- await Promise.all(entryPoints.map((entryPoint) => this.joinThroughEntryPoint(
64
- entryPoint,
65
- contactedPeers,
66
- distantJoinOptions,
67
- retry
68
- )))
69
- }
70
-
71
- private async joinThroughEntryPoint(
72
- entryPointDescriptor: PeerDescriptor,
73
- // Note that this set is mutated by DiscoverySession
74
- contactedPeers: Set<DhtAddress>,
75
- additionalDistantJoin: { enabled: true, contactedPeers: Set<DhtAddress> } | { enabled: false },
76
- retry = true
77
- ): Promise<void> {
78
- if (this.isStopped()) {
79
- return
80
- }
81
- this.joinCalled = true
82
- logger.debug(
83
- `Joining ${this.options.serviceId === CONTROL_LAYER_NODE_SERVICE_ID
84
- ? 'The Streamr Network' : `Control Layer for ${this.options.serviceId}`}`
85
- + ` via entrypoint ${toNodeId(entryPointDescriptor)}`
86
- )
87
- if (areEqualPeerDescriptors(entryPointDescriptor, this.options.localPeerDescriptor)) {
88
- return
89
- }
90
- this.options.connectionLocker?.lockConnection(entryPointDescriptor, `${this.options.serviceId}::joinDht`)
91
- this.options.peerManager.addContact(entryPointDescriptor)
92
- const targetId = toNodeId(this.options.localPeerDescriptor)
93
- const sessions = [this.createSession(targetId, contactedPeers)]
94
- if (additionalDistantJoin.enabled) {
95
- sessions.push(this.createSession(createDistantDhtAddress(targetId), additionalDistantJoin.contactedPeers))
96
- }
97
- await this.runSessions(sessions, entryPointDescriptor, retry)
98
- this.options.connectionLocker?.unlockConnection(entryPointDescriptor, `${this.options.serviceId}::joinDht`)
99
-
100
- }
101
-
102
- async joinRing(): Promise<void> {
103
- const contactedPeers = new Set<DhtAddress>()
104
- const sessions = [this.createRingSession(getRingIdRawFromPeerDescriptor(this.options.localPeerDescriptor), contactedPeers)]
105
- await this.runRingSessions(sessions)
106
- }
107
-
108
- private createSession(targetId: DhtAddress, contactedPeers: Set<DhtAddress>): DiscoverySession {
109
- const sessionOptions = {
110
- targetId,
111
- parallelism: this.options.parallelism,
112
- noProgressLimit: this.options.joinNoProgressLimit,
113
- peerManager: this.options.peerManager,
114
- contactedPeers,
115
- abortSignal: this.options.abortSignal,
116
- createDhtNodeRpcRemote: this.options.createDhtNodeRpcRemote
117
- }
118
- return new DiscoverySession(sessionOptions)
119
- }
120
-
121
- private createRingSession(targetId: RingIdRaw, contactedPeers: Set<DhtAddress>): RingDiscoverySession {
122
- const sessionOptions = {
123
- targetId,
124
- parallelism: this.options.parallelism,
125
- noProgressLimit: this.options.joinNoProgressLimit,
126
- peerManager: this.options.peerManager,
127
- contactedPeers,
128
- abortSignal: this.options.abortSignal,
129
- createDhtNodeRpcRemote: this.options.createDhtNodeRpcRemote
130
- }
131
- return new RingDiscoverySession(sessionOptions)
132
- }
133
-
134
- private async runSessions(sessions: DiscoverySession[], entryPointDescriptor: PeerDescriptor, retry: boolean): Promise<void> {
135
- try {
136
- for (const session of sessions) {
137
- this.ongoingDiscoverySessions.set(session.id, session)
138
- await session.findClosestNodes(this.options.joinTimeout)
139
- }
140
- } catch (_e) {
141
- logger.debug(`DHT join on ${this.options.serviceId} timed out`)
142
- } finally {
143
- if (!this.isStopped()) {
144
- if (this.options.peerManager.getNeighborCount() === 0) {
145
- if (retry) {
146
- // TODO should we catch possible promise rejection?
147
- // TODO use options option or named constant?
148
- setAbortableTimeout(() => this.rejoinDht(entryPointDescriptor), 1000, this.options.abortSignal)
149
- }
150
- } else {
151
- await this.ensureRecoveryIntervalIsRunning()
152
- }
153
- }
154
- sessions.forEach((session) => this.ongoingDiscoverySessions.delete(session.id))
155
- }
156
- }
157
-
158
- private async runRingSessions(sessions: RingDiscoverySession[]): Promise<void> {
159
- try {
160
- for (const session of sessions) {
161
- this.ongoingRingDiscoverySessions.set(session.id, session)
162
- await session.findClosestNodes(this.options.joinTimeout)
163
- }
164
- } catch (_e) {
165
- logger.debug(`Ring join on ${this.options.serviceId} timed out`)
166
- } finally {
167
- sessions.forEach((session) => this.ongoingDiscoverySessions.delete(session.id))
168
- }
169
- }
170
-
171
- public async rejoinDht(
172
- entryPoint: PeerDescriptor,
173
- contactedPeers: Set<DhtAddress> = new Set(),
174
- distantJoinContactPeers: Set<DhtAddress> = new Set()
175
- ): Promise<void> {
176
- if (this.isStopped() || this.rejoinOngoing) {
177
- return
178
- }
179
- logger.debug(`Rejoining DHT ${this.options.serviceId}`)
180
- this.rejoinOngoing = true
181
- try {
182
- await this.joinThroughEntryPoint(entryPoint, contactedPeers, { enabled: true, contactedPeers: distantJoinContactPeers })
183
- logger.debug(`Rejoined DHT successfully ${this.options.serviceId}!`)
184
- } catch {
185
- logger.warn(`Rejoining DHT ${this.options.serviceId} failed`)
186
- if (!this.isStopped()) {
187
- // TODO should we catch possible promise rejection?
188
- // TODO use options option or named constant?
189
- setAbortableTimeout(() => this.rejoinDht(entryPoint), 5000, this.options.abortSignal)
190
- }
191
- } finally {
192
- this.rejoinOngoing = false
193
- }
194
- }
195
-
196
- private async ensureRecoveryIntervalIsRunning(): Promise<void> {
197
- if (!this.recoveryIntervalStarted) {
198
- this.recoveryIntervalStarted = true
199
- // TODO use options option or named constant?
200
- await scheduleAtInterval(() => this.fetchClosestAndRandomNeighbors(), 60000, true, this.options.abortSignal)
201
- }
202
- }
203
-
204
- private async fetchClosestAndRandomNeighbors(): Promise<void> {
205
- if (this.isStopped()) {
206
- return
207
- }
208
- const localNodeId = toNodeId(this.options.localPeerDescriptor)
209
- const nodes = this.getClosestNeighbors(localNodeId, this.options.parallelism)
210
- const randomNodes = this.getClosestNeighbors(randomDhtAddress(), 1)
211
- await Promise.allSettled([
212
- ...nodes.map(async (node: PeerDescriptor) => {
213
- const remote = this.options.createDhtNodeRpcRemote(node)
214
- const contacts = await remote.getClosestPeers(localNodeId)
215
- for (const contact of contacts) {
216
- this.options.peerManager.addContact(contact)
217
- }
218
- }),
219
- ...randomNodes.map(async (node: PeerDescriptor) => {
220
- const remote = this.options.createDhtNodeRpcRemote(node)
221
- const contacts = await remote.getClosestPeers(randomDhtAddress())
222
- for (const contact of contacts) {
223
- this.options.peerManager.addContact(contact)
224
- }
225
- })
226
- ])
227
- }
228
-
229
- private getClosestNeighbors(referenceId: DhtAddress, maxCount: number): PeerDescriptor[] {
230
- return getClosestNodes(referenceId, this.options.peerManager.getNeighbors().map((n) => n.getPeerDescriptor()), { maxCount })
231
- }
232
-
233
- public isJoinOngoing(): boolean {
234
- return !this.joinCalled ? true : this.ongoingDiscoverySessions.size > 0
235
- }
236
-
237
- public isJoinCalled(): boolean {
238
- return this.joinCalled
239
- }
240
-
241
- private isStopped() {
242
- return this.options.abortSignal.aborted
243
- }
244
- }
@@ -1,148 +0,0 @@
1
- import { Gate, Logger, withTimeout } from '@streamr/utils'
2
- import { v4 } from 'uuid'
3
- import { DhtAddress, toNodeId } from '../../identifiers'
4
- import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
5
- import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
6
- import { PeerManager } from '../PeerManager'
7
- import { RingContacts } from '../contact/RingContactList'
8
- import { RingId, RingIdRaw, getLeftDistance, getRingIdFromPeerDescriptor, getRingIdFromRaw } from '../contact/ringIdentifiers'
9
-
10
- const logger = new Logger(module)
11
-
12
- interface RingDiscoverySessionOptions {
13
- targetId: RingIdRaw
14
- parallelism: number
15
- noProgressLimit: number
16
- peerManager: PeerManager
17
- // Note that contacted peers will be mutated by the DiscoverySession or other parallel sessions
18
- contactedPeers: Set<DhtAddress>
19
- abortSignal: AbortSignal
20
- }
21
-
22
- export class RingDiscoverySession {
23
-
24
- public readonly id = v4()
25
- private noProgressCounter = 0
26
- private ongoingRequests: Set<DhtAddress> = new Set()
27
- private doneGate = new Gate(false)
28
- private readonly options: RingDiscoverySessionOptions
29
- private numContactedPeers = 0
30
- private targetIdAsRingId: RingId
31
-
32
- constructor(options: RingDiscoverySessionOptions) {
33
- this.options = options
34
- this.targetIdAsRingId = getRingIdFromRaw(this.options.targetId)
35
- }
36
-
37
- private addContacts(contacts: PeerDescriptor[]): void {
38
- if (this.options.abortSignal.aborted || this.doneGate.isOpen()) {
39
- return
40
- }
41
- for (const contact of contacts) {
42
- this.options.peerManager.addContact(contact)
43
- }
44
- }
45
-
46
- private async fetchClosestContactsFromRemote(contact: DhtNodeRpcRemote): Promise<RingContacts> {
47
- if (this.options.abortSignal.aborted || this.doneGate.isOpen()) {
48
- return { left: [], right: [] }
49
- }
50
- logger.trace(`Getting closest ring peers from contact: ${toNodeId(contact.getPeerDescriptor())}`)
51
- this.numContactedPeers++
52
- this.options.contactedPeers.add(contact.getNodeId())
53
- const returnedContacts = await contact.getClosestRingPeers(this.options.targetId)
54
- this.options.peerManager.setContactActive(contact.getNodeId())
55
- return returnedContacts
56
- }
57
-
58
- private onRequestSucceeded(nodeId: DhtAddress, contacts: RingContacts) {
59
- if (!this.ongoingRequests.has(nodeId)) {
60
- return
61
- }
62
- this.ongoingRequests.delete(nodeId)
63
- const oldClosestContacts = this.options.peerManager.getClosestRingContactsTo(this.options.targetId, 1)
64
- const oldClosestLeftDistance = getLeftDistance(
65
- this.targetIdAsRingId,
66
- getRingIdFromPeerDescriptor(oldClosestContacts.left[0].getPeerDescriptor())
67
- )
68
- const oldClosestRightDistance = getLeftDistance(
69
- this.targetIdAsRingId,
70
- getRingIdFromPeerDescriptor(oldClosestContacts.right[0].getPeerDescriptor())
71
- )
72
- this.addContacts(contacts.left.concat(contacts.right))
73
- const newClosestContacts = this.options.peerManager.getClosestRingContactsTo(this.options.targetId, 1)
74
- const newClosestLeftDistance = getLeftDistance(this.targetIdAsRingId,
75
- getRingIdFromPeerDescriptor(newClosestContacts.left[0].getPeerDescriptor()))
76
- const newClosestRightDistance = getLeftDistance(this.targetIdAsRingId,
77
- getRingIdFromPeerDescriptor(newClosestContacts.right[0].getPeerDescriptor()))
78
- if (newClosestLeftDistance >= oldClosestLeftDistance && newClosestRightDistance >= oldClosestRightDistance) {
79
- this.noProgressCounter++
80
- }
81
- }
82
-
83
- private onRequestFailed(peer: DhtNodeRpcRemote) {
84
- if (!this.ongoingRequests.has(peer.getNodeId())) {
85
- return
86
- }
87
- this.ongoingRequests.delete(peer.getNodeId())
88
- this.options.peerManager.removeContact(peer.getNodeId())
89
- }
90
-
91
- private findMoreContacts(): void {
92
- if (this.options.abortSignal.aborted || this.doneGate.isOpen()) {
93
- return
94
- }
95
- const uncontacted = this.options.peerManager.getClosestRingContactsTo(
96
- this.options.targetId,
97
- this.options.parallelism,
98
- this.options.contactedPeers
99
- )
100
- if ((uncontacted.left.length === 0 && uncontacted.right.length === 0)
101
- || this.noProgressCounter >= this.options.noProgressLimit) {
102
- this.doneGate.open()
103
- return
104
- }
105
- // ask from both sides equally
106
- const merged = []
107
- const alreadyInMerged: Set<DhtAddress> = new Set()
108
- const length = Math.max(uncontacted.left.length, uncontacted.right.length)
109
- for (let i = 0; i < length; i++) {
110
- if (i < uncontacted.left.length) {
111
- if (!alreadyInMerged.has(uncontacted.left[i].getNodeId())) {
112
- merged.push(uncontacted.left[i])
113
- alreadyInMerged.add(uncontacted.left[i].getNodeId())
114
- }
115
- }
116
- if (i < uncontacted.right.length) {
117
- if (!alreadyInMerged.has(uncontacted.right[i].getNodeId())) {
118
- merged.push(uncontacted.right[i])
119
- alreadyInMerged.add(uncontacted.right[i].getNodeId())
120
- }
121
- }
122
- }
123
-
124
- for (const nextPeer of merged) {
125
- if (this.ongoingRequests.size >= this.options.parallelism) {
126
- break
127
- }
128
- this.ongoingRequests.add(nextPeer.getNodeId())
129
- // eslint-disable-next-line promise/catch-or-return
130
- this.fetchClosestContactsFromRemote(nextPeer)
131
- .then((contacts) => this.onRequestSucceeded(nextPeer.getNodeId(), contacts))
132
- .catch(() => this.onRequestFailed(nextPeer))
133
- .finally(() => {
134
- this.findMoreContacts()
135
- })
136
- }
137
- }
138
-
139
- public async findClosestNodes(timeout: number): Promise<void> {
140
- if (this.options.peerManager.getNearbyContactCount(this.options.contactedPeers) === 0) {
141
- return
142
- }
143
- setImmediate(() => {
144
- this.findMoreContacts()
145
- })
146
- await withTimeout(this.doneGate.waitUntilOpen(), timeout, 'discovery session timed out', this.options.abortSignal)
147
- }
148
- }
@@ -1,251 +0,0 @@
1
- import {
2
- DataEntry,
3
- PeerDescriptor,
4
- RecursiveOperation,
5
- RecursiveOperationRequest,
6
- RouteMessageAck,
7
- RouteMessageError,
8
- RouteMessageWrapper
9
- } from '../../../generated/packages/dht/protos/DhtRpc'
10
- import { Router } from '../routing/Router'
11
- import { RoutingMode } from '../routing/RoutingSession'
12
- import { Logger, areEqualBinaries, runAndWaitForEvents3, wait } from '@streamr/utils'
13
- import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
14
- import { RecursiveOperationSessionRpcRemote } from './RecursiveOperationSessionRpcRemote'
15
- import { RECURSIVE_OPERATION_TIMEOUT, RecursiveOperationSession, RecursiveOperationSessionEvents } from './RecursiveOperationSession'
16
- import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
17
- import { ITransport } from '../../transport/ITransport'
18
- import { LocalDataStore } from '../store/LocalDataStore'
19
- import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
20
- import { RecursiveOperationSessionRpcClient } from '../../../generated/packages/dht/protos/DhtRpc.client'
21
- import { SortedContactList } from '../contact/SortedContactList'
22
- import { getPreviousPeer } from '../routing/getPreviousPeer'
23
- import { createRouteMessageAck } from '../routing/RouterRpcLocal'
24
- import { ServiceID } from '../../types/ServiceID'
25
- import { RecursiveOperationRpcLocal } from './RecursiveOperationRpcLocal'
26
- import { DhtAddress, areEqualPeerDescriptors, toDhtAddress, toNodeId, toDhtAddressRaw } from '../../identifiers'
27
- import { getDistance } from '../PeerManager'
28
- import { ConnectionsView } from '../../exports'
29
-
30
- interface RecursiveOperationManagerOptions {
31
- rpcCommunicator: RoutingRpcCommunicator
32
- sessionTransport: ITransport
33
- router: Router
34
- connectionsView: ConnectionsView
35
- localPeerDescriptor: PeerDescriptor
36
- serviceId: ServiceID
37
- localDataStore: LocalDataStore
38
- addContact: (contact: PeerDescriptor) => void
39
- createDhtNodeRpcRemote: (peerDescriptor: PeerDescriptor) => DhtNodeRpcRemote
40
- }
41
-
42
- export interface RecursiveOperationResult { closestNodes: Array<PeerDescriptor>, dataEntries?: Array<DataEntry> }
43
-
44
- const logger = new Logger(module)
45
-
46
- export class RecursiveOperationManager {
47
-
48
- private ongoingSessions: Map<string, RecursiveOperationSession> = new Map()
49
- private stopped = false
50
- private readonly options: RecursiveOperationManagerOptions
51
-
52
- constructor(options: RecursiveOperationManagerOptions) {
53
- this.options = options
54
- this.registerLocalRpcMethods()
55
- }
56
-
57
- private registerLocalRpcMethods() {
58
- const rpcLocal = new RecursiveOperationRpcLocal({
59
- doRouteRequest: (routedMessage: RouteMessageWrapper) => this.doRouteRequest(routedMessage),
60
- addContact: (contact: PeerDescriptor) => this.options.addContact(contact),
61
- isMostLikelyDuplicate: (requestId: string) => this.options.router.isMostLikelyDuplicate(requestId),
62
- addToDuplicateDetector: (requestId: string) => this.options.router.addToDuplicateDetector(requestId)
63
- })
64
- this.options.rpcCommunicator.registerRpcMethod(
65
- RouteMessageWrapper,
66
- RouteMessageAck,
67
- 'routeRequest',
68
- async (routedMessage: RouteMessageWrapper) => {
69
- if (this.stopped) {
70
- return createRouteMessageAck(routedMessage, RouteMessageError.STOPPED)
71
- } else {
72
- return rpcLocal.routeRequest(routedMessage)
73
- }
74
- }
75
- )
76
- }
77
-
78
- public async execute(
79
- targetId: DhtAddress,
80
- operation: RecursiveOperation,
81
- excludedPeer?: DhtAddress,
82
- waitForCompletion = true
83
- ): Promise<RecursiveOperationResult> {
84
- if (this.stopped) {
85
- return { closestNodes: [] }
86
- }
87
- const session = new RecursiveOperationSession({
88
- transport: this.options.sessionTransport,
89
- targetId,
90
- localPeerDescriptor: this.options.localPeerDescriptor,
91
- // TODO use options option or named constant?
92
- waitedRoutingPathCompletions: this.options.connectionsView.getConnectionCount() > 1 ? 2 : 1,
93
- operation,
94
- // TODO would it make sense to give excludedPeer as one of the fields RecursiveOperationSession?
95
- doRouteRequest: (routedMessage: RouteMessageWrapper) => {
96
- return this.doRouteRequest(routedMessage, excludedPeer)
97
- }
98
- })
99
- if (this.options.connectionsView.getConnectionCount() === 0) {
100
- const dataEntries = Array.from(this.options.localDataStore.values(targetId))
101
- session.onResponseReceived(
102
- toNodeId(this.options.localPeerDescriptor),
103
- [this.options.localPeerDescriptor],
104
- [this.options.localPeerDescriptor],
105
- dataEntries,
106
- true
107
- )
108
- return session.getResults()
109
- }
110
- this.ongoingSessions.set(session.getId(), session)
111
- if (waitForCompletion === true) {
112
- try {
113
- await runAndWaitForEvents3<RecursiveOperationSessionEvents>(
114
- [() => session.start(this.options.serviceId)],
115
- [[session, 'completed']],
116
- // TODO use options option or named constant?
117
- RECURSIVE_OPERATION_TIMEOUT
118
- )
119
- } catch (err) {
120
- logger.debug('start failed', { err })
121
- }
122
- } else {
123
- session.start(this.options.serviceId)
124
- // Wait for delete operation to be sent out by the router
125
- // TODO: Add a feature to wait for the router to pass the message?
126
- await wait(50)
127
- }
128
- if (operation === RecursiveOperation.FETCH_DATA) {
129
- const dataEntries = Array.from(this.options.localDataStore.values(targetId))
130
- if (dataEntries.length > 0) {
131
- this.sendResponse([this.options.localPeerDescriptor], this.options.localPeerDescriptor, session.getId(), [], dataEntries, true)
132
- }
133
- } else if (operation === RecursiveOperation.DELETE_DATA) {
134
- this.options.localDataStore.markAsDeleted(targetId, toNodeId(this.options.localPeerDescriptor))
135
- }
136
- this.ongoingSessions.delete(session.getId())
137
- session.stop()
138
- return session.getResults()
139
- }
140
-
141
- private sendResponse(
142
- routingPath: PeerDescriptor[],
143
- targetPeerDescriptor: PeerDescriptor,
144
- serviceId: ServiceID,
145
- closestConnectedNodes: PeerDescriptor[],
146
- dataEntries: DataEntry[],
147
- noCloserNodesFound: boolean = false
148
- ): void {
149
- const isOwnNode = areEqualPeerDescriptors(this.options.localPeerDescriptor, targetPeerDescriptor)
150
- if (isOwnNode && this.ongoingSessions.has(serviceId)) {
151
- this.ongoingSessions.get(serviceId)!
152
- .onResponseReceived(
153
- toNodeId(this.options.localPeerDescriptor),
154
- routingPath,
155
- closestConnectedNodes,
156
- dataEntries,
157
- noCloserNodesFound
158
- )
159
- } else {
160
- // TODO use options option or named constant?
161
- const remoteCommunicator = new ListeningRpcCommunicator(
162
- serviceId,
163
- this.options.sessionTransport,
164
- { rpcRequestTimeout: RECURSIVE_OPERATION_TIMEOUT }
165
- )
166
- const rpcRemote = new RecursiveOperationSessionRpcRemote(
167
- this.options.localPeerDescriptor,
168
- targetPeerDescriptor,
169
- remoteCommunicator,
170
- RecursiveOperationSessionRpcClient,
171
- // TODO use options option or named constant?
172
- 10000
173
- )
174
- rpcRemote.sendResponse(routingPath, closestConnectedNodes, dataEntries, noCloserNodesFound)
175
- remoteCommunicator.destroy()
176
- }
177
- }
178
-
179
- private doRouteRequest(routedMessage: RouteMessageWrapper, excludedPeer?: DhtAddress): RouteMessageAck {
180
- if (this.stopped) {
181
- return createRouteMessageAck(routedMessage, RouteMessageError.STOPPED)
182
- }
183
- const targetId = toDhtAddress(routedMessage.target)
184
- const request = (routedMessage.message!.body as { recursiveOperationRequest: RecursiveOperationRequest }).recursiveOperationRequest
185
- // TODO use options option or named constant?
186
- const closestConnectedNodes = this.getClosestConnectedNodes(targetId, 5)
187
- const dataEntries = (request.operation === RecursiveOperation.FETCH_DATA)
188
- ? Array.from(this.options.localDataStore.values(targetId))
189
- : []
190
- if (request.operation === RecursiveOperation.DELETE_DATA) {
191
- this.options.localDataStore.markAsDeleted(targetId, toNodeId(routedMessage.sourcePeer!))
192
- }
193
- if (areEqualBinaries(this.options.localPeerDescriptor.nodeId, routedMessage.target)) {
194
- // TODO this is also very similar case to what we do at line 255, could simplify the code paths?
195
- this.sendResponse(
196
- routedMessage.routingPath,
197
- routedMessage.sourcePeer!,
198
- request.sessionId,
199
- closestConnectedNodes,
200
- dataEntries,
201
- true
202
- )
203
- return createRouteMessageAck(routedMessage)
204
- } else {
205
- const ack = this.options.router.doRouteMessage(routedMessage, RoutingMode.RECURSIVE, excludedPeer)
206
- if ((ack.error === undefined) || (ack.error === RouteMessageError.NO_TARGETS)) {
207
- const noCloserContactsFound = (ack.error === RouteMessageError.NO_TARGETS) ||
208
- (
209
- closestConnectedNodes.length > 0
210
- && getPreviousPeer(routedMessage)
211
- && !this.isPeerCloserToIdThanSelf(closestConnectedNodes[0], targetId)
212
- )
213
- this.sendResponse(
214
- routedMessage.routingPath,
215
- routedMessage.sourcePeer!,
216
- request.sessionId,
217
- closestConnectedNodes,
218
- dataEntries,
219
- noCloserContactsFound
220
- )
221
- }
222
- return ack
223
- }
224
- }
225
-
226
- private getClosestConnectedNodes(referenceId: DhtAddress, limit: number): PeerDescriptor[] {
227
- const connectedNodes = this.options.connectionsView.getConnections().map((c) => this.options.createDhtNodeRpcRemote(c))
228
- const sorted = new SortedContactList<DhtNodeRpcRemote>({
229
- referenceId,
230
- maxSize: limit,
231
- allowToContainReferenceId: true
232
- })
233
- sorted.addContacts(connectedNodes)
234
- return sorted.getClosestContacts(limit).map((peer) => peer.getPeerDescriptor())
235
- }
236
-
237
- private isPeerCloserToIdThanSelf(peer: PeerDescriptor, nodeIdOrDataKey: DhtAddress): boolean {
238
- const nodeIdOrDataKeyRaw = toDhtAddressRaw(nodeIdOrDataKey)
239
- const distance1 = getDistance(peer.nodeId, nodeIdOrDataKeyRaw)
240
- const distance2 = getDistance(this.options.localPeerDescriptor.nodeId, nodeIdOrDataKeyRaw)
241
- return distance1 < distance2
242
- }
243
-
244
- public stop(): void {
245
- this.stopped = true
246
- this.ongoingSessions.forEach((session, _id) => {
247
- session.stop()
248
- })
249
- this.ongoingSessions.clear()
250
- }
251
- }
@@ -1,34 +0,0 @@
1
- import { Logger } from '@streamr/utils'
2
- import { PeerDescriptor, RouteMessageAck, RouteMessageError, RouteMessageWrapper } from '../../../generated/packages/dht/protos/DhtRpc'
3
- import { IRecursiveOperationRpc } from '../../../generated/packages/dht/protos/DhtRpc.server'
4
- import { createRouteMessageAck } from '../routing/RouterRpcLocal'
5
- import { getPreviousPeer } from '../routing/getPreviousPeer'
6
- import { toNodeId } from '../../identifiers'
7
-
8
- const logger = new Logger(module)
9
-
10
- interface RecursiveOperationRpcLocalOptions {
11
- doRouteRequest: (routedMessage: RouteMessageWrapper) => RouteMessageAck
12
- addContact: (contact: PeerDescriptor, setActive?: boolean) => void
13
- isMostLikelyDuplicate: (requestId: string) => boolean
14
- addToDuplicateDetector: (requestId: string) => void
15
- }
16
-
17
- export class RecursiveOperationRpcLocal implements IRecursiveOperationRpc {
18
-
19
- private readonly options: RecursiveOperationRpcLocalOptions
20
-
21
- constructor(options: RecursiveOperationRpcLocalOptions) {
22
- this.options = options
23
- }
24
-
25
- async routeRequest(routedMessage: RouteMessageWrapper): Promise<RouteMessageAck> {
26
- if (this.options.isMostLikelyDuplicate(routedMessage.requestId)) {
27
- return createRouteMessageAck(routedMessage, RouteMessageError.DUPLICATE)
28
- }
29
- const remoteNodeId = toNodeId(getPreviousPeer(routedMessage) ?? routedMessage.sourcePeer!)
30
- logger.trace(`Received routeRequest call from ${remoteNodeId}`)
31
- this.options.addToDuplicateDetector(routedMessage.requestId)
32
- return this.options.doRouteRequest(routedMessage)
33
- }
34
- }