@streamr/dht 100.0.0-testnet-three.6 → 100.1.0

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