@streamr/dht 0.0.1-tatum.5 → 0.0.1-tatum.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/src/connection/ConnectionLockHandler.d.ts +1 -1
  2. package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
  3. package/dist/src/connection/ConnectionManager.d.ts +17 -39
  4. package/dist/src/connection/ConnectionManager.js +138 -192
  5. package/dist/src/connection/ConnectionManager.js.map +1 -1
  6. package/dist/src/connection/ConnectivityChecker.js +14 -11
  7. package/dist/src/connection/ConnectivityChecker.js.map +1 -1
  8. package/dist/src/connection/ConnectorFacade.d.ts +49 -0
  9. package/dist/src/connection/ConnectorFacade.js +86 -0
  10. package/dist/src/connection/ConnectorFacade.js.map +1 -0
  11. package/dist/src/connection/ManagedConnection.d.ts +1 -4
  12. package/dist/src/connection/ManagedConnection.js +23 -31
  13. package/dist/src/connection/ManagedConnection.js.map +1 -1
  14. package/dist/src/connection/RemoteConnectionLocker.js +4 -3
  15. package/dist/src/connection/RemoteConnectionLocker.js.map +1 -1
  16. package/dist/src/connection/Simulator/Simulator.d.ts +0 -2
  17. package/dist/src/connection/Simulator/Simulator.js +0 -5
  18. package/dist/src/connection/Simulator/Simulator.js.map +1 -1
  19. package/dist/src/connection/Simulator/SimulatorConnection.js +16 -13
  20. package/dist/src/connection/Simulator/SimulatorConnection.js.map +1 -1
  21. package/dist/src/connection/Simulator/SimulatorConnector.d.ts +2 -2
  22. package/dist/src/connection/Simulator/SimulatorConnector.js +10 -11
  23. package/dist/src/connection/Simulator/SimulatorConnector.js.map +1 -1
  24. package/dist/src/connection/Simulator/SimulatorTransport.js +6 -1
  25. package/dist/src/connection/Simulator/SimulatorTransport.js.map +1 -1
  26. package/dist/src/connection/WebRTC/NodeWebRtcConnection.d.ts +2 -0
  27. package/dist/src/connection/WebRTC/NodeWebRtcConnection.js +12 -12
  28. package/dist/src/connection/WebRTC/NodeWebRtcConnection.js.map +1 -1
  29. package/dist/src/connection/WebRTC/WebRtcConnector.d.ts +9 -9
  30. package/dist/src/connection/WebRTC/WebRtcConnector.js +22 -22
  31. package/dist/src/connection/WebRTC/WebRtcConnector.js.map +1 -1
  32. package/dist/src/connection/WebSocket/RemoteWebSocketConnector.js +2 -1
  33. package/dist/src/connection/WebSocket/RemoteWebSocketConnector.js.map +1 -1
  34. package/dist/src/connection/WebSocket/WebSocketConnector.d.ts +19 -8
  35. package/dist/src/connection/WebSocket/WebSocketConnector.js +67 -46
  36. package/dist/src/connection/WebSocket/WebSocketConnector.js.map +1 -1
  37. package/dist/src/connection/WebSocket/WebSocketServer.d.ts +11 -1
  38. package/dist/src/connection/WebSocket/WebSocketServer.js +15 -10
  39. package/dist/src/connection/WebSocket/WebSocketServer.js.map +1 -1
  40. package/dist/src/dht/DhtNode.d.ts +16 -54
  41. package/dist/src/dht/DhtNode.js +116 -137
  42. package/dist/src/dht/DhtNode.js.map +1 -1
  43. package/dist/src/dht/{DhtPeer.d.ts → RemoteDhtNode.d.ts} +3 -2
  44. package/dist/src/dht/{DhtPeer.js → RemoteDhtNode.js} +22 -16
  45. package/dist/src/dht/RemoteDhtNode.js.map +1 -0
  46. package/dist/src/dht/contact/Contact.d.ts +1 -15
  47. package/dist/src/dht/contact/Contact.js +1 -9
  48. package/dist/src/dht/contact/Contact.js.map +1 -1
  49. package/dist/src/dht/contact/ContactList.d.ts +13 -3
  50. package/dist/src/dht/contact/ContactList.js +9 -4
  51. package/dist/src/dht/contact/ContactList.js.map +1 -1
  52. package/dist/src/dht/contact/RandomContactList.d.ts +3 -3
  53. package/dist/src/dht/contact/RandomContactList.js +4 -8
  54. package/dist/src/dht/contact/RandomContactList.js.map +1 -1
  55. package/dist/src/dht/contact/Remote.d.ts +1 -5
  56. package/dist/src/dht/contact/Remote.js +0 -5
  57. package/dist/src/dht/contact/Remote.js.map +1 -1
  58. package/dist/src/dht/contact/SortedContactList.d.ts +3 -5
  59. package/dist/src/dht/contact/SortedContactList.js +9 -19
  60. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  61. package/dist/src/dht/discovery/DiscoverySession.d.ts +5 -7
  62. package/dist/src/dht/discovery/DiscoverySession.js +9 -10
  63. package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
  64. package/dist/src/dht/discovery/PeerDiscovery.d.ts +11 -10
  65. package/dist/src/dht/discovery/PeerDiscovery.js +32 -37
  66. package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
  67. package/dist/src/dht/find/RecursiveFindSession.d.ts +5 -6
  68. package/dist/src/dht/find/RecursiveFindSession.js +8 -8
  69. package/dist/src/dht/find/RecursiveFindSession.js.map +1 -1
  70. package/dist/src/dht/find/RecursiveFinder.d.ts +2 -4
  71. package/dist/src/dht/find/RecursiveFinder.js +11 -12
  72. package/dist/src/dht/find/RecursiveFinder.js.map +1 -1
  73. package/dist/src/dht/registerExternalApiRpcMethods.d.ts +1 -1
  74. package/dist/src/dht/routing/DuplicateDetector.d.ts +1 -2
  75. package/dist/src/dht/routing/DuplicateDetector.js +2 -7
  76. package/dist/src/dht/routing/DuplicateDetector.js.map +1 -1
  77. package/dist/src/dht/routing/RemoteRouter.js +4 -4
  78. package/dist/src/dht/routing/RemoteRouter.js.map +1 -1
  79. package/dist/src/dht/routing/Router.d.ts +10 -13
  80. package/dist/src/dht/routing/Router.js +28 -29
  81. package/dist/src/dht/routing/Router.js.map +1 -1
  82. package/dist/src/dht/routing/RoutingSession.d.ts +3 -5
  83. package/dist/src/dht/routing/RoutingSession.js +19 -13
  84. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  85. package/dist/src/dht/store/DataStore.d.ts +2 -2
  86. package/dist/src/dht/store/DataStore.js +7 -7
  87. package/dist/src/dht/store/DataStore.js.map +1 -1
  88. package/dist/src/exports.d.ts +1 -8
  89. package/dist/src/exports.js +2 -16
  90. package/dist/src/exports.js.map +1 -1
  91. package/dist/src/helpers/PeerID.d.ts +0 -1
  92. package/dist/src/helpers/PeerID.js +0 -6
  93. package/dist/src/helpers/PeerID.js.map +1 -1
  94. package/dist/src/helpers/browser/isBrowserEnvironment.d.ts +1 -0
  95. package/dist/src/helpers/browser/isBrowserEnvironment.js +6 -0
  96. package/dist/src/helpers/browser/isBrowserEnvironment.js.map +1 -0
  97. package/dist/src/helpers/browser/isBrowserEnvironment_override.d.ts +1 -0
  98. package/dist/src/helpers/browser/isBrowserEnvironment_override.js +7 -0
  99. package/dist/src/helpers/browser/isBrowserEnvironment_override.js.map +1 -0
  100. package/dist/src/helpers/kademliaId.d.ts +1 -0
  101. package/dist/src/helpers/kademliaId.js +14 -0
  102. package/dist/src/helpers/kademliaId.js.map +1 -0
  103. package/dist/src/helpers/peerIdFromPeerDescriptor.d.ts +1 -1
  104. package/dist/src/helpers/peerIdFromPeerDescriptor.js +3 -3
  105. package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +1 -1
  106. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +0 -4
  107. package/dist/src/proto/packages/dht/protos/DhtRpc.js +1 -2
  108. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  109. package/package.json +10 -9
  110. package/protos/DhtRpc.proto +0 -1
  111. package/src/connection/ConnectionLockHandler.ts +1 -1
  112. package/src/connection/ConnectionManager.ts +156 -240
  113. package/src/connection/ConnectivityChecker.ts +14 -11
  114. package/src/connection/ConnectorFacade.ts +143 -0
  115. package/src/connection/ManagedConnection.ts +23 -34
  116. package/src/connection/RemoteConnectionLocker.ts +4 -3
  117. package/src/connection/Simulator/Simulator.ts +0 -7
  118. package/src/connection/Simulator/SimulatorConnection.ts +16 -13
  119. package/src/connection/Simulator/SimulatorConnector.ts +11 -12
  120. package/src/connection/Simulator/SimulatorTransport.ts +6 -1
  121. package/src/connection/WebRTC/NodeWebRtcConnection.ts +14 -13
  122. package/src/connection/WebRTC/WebRtcConnector.ts +31 -31
  123. package/src/connection/WebSocket/RemoteWebSocketConnector.ts +2 -1
  124. package/src/connection/WebSocket/WebSocketConnector.ts +85 -62
  125. package/src/connection/WebSocket/WebSocketServer.ts +26 -8
  126. package/src/dht/DhtNode.ts +164 -189
  127. package/src/dht/{DhtPeer.ts → RemoteDhtNode.ts} +14 -7
  128. package/src/dht/contact/Contact.ts +1 -18
  129. package/src/dht/contact/ContactList.ts +16 -6
  130. package/src/dht/contact/RandomContactList.ts +6 -11
  131. package/src/dht/contact/Remote.ts +1 -10
  132. package/src/dht/contact/SortedContactList.ts +12 -25
  133. package/src/dht/discovery/DiscoverySession.ts +20 -23
  134. package/src/dht/discovery/PeerDiscovery.ts +45 -44
  135. package/src/dht/find/RecursiveFindSession.ts +12 -13
  136. package/src/dht/find/RecursiveFinder.ts +16 -19
  137. package/src/dht/registerExternalApiRpcMethods.ts +1 -1
  138. package/src/dht/routing/DuplicateDetector.ts +3 -10
  139. package/src/dht/routing/RemoteRouter.ts +5 -5
  140. package/src/dht/routing/Router.ts +35 -39
  141. package/src/dht/routing/RoutingSession.ts +37 -28
  142. package/src/dht/store/DataStore.ts +11 -11
  143. package/src/exports.ts +1 -8
  144. package/src/helpers/PeerID.ts +0 -7
  145. package/src/helpers/browser/isBrowserEnvironment.ts +1 -0
  146. package/src/helpers/browser/isBrowserEnvironment_override.ts +3 -0
  147. package/src/helpers/kademliaId.ts +8 -0
  148. package/src/helpers/peerIdFromPeerDescriptor.ts +1 -1
  149. package/src/proto/packages/dht/protos/DhtRpc.ts +1 -6
  150. package/test/benchmark/KademliaCorrectness.test.ts +5 -2
  151. package/test/benchmark/RecursiveFind.test.ts +6 -6
  152. package/test/end-to-end/Layer0-Layer1.test.ts +14 -14
  153. package/test/end-to-end/Layer0WebRTC-Layer1.test.ts +5 -5
  154. package/test/end-to-end/Layer0WebRTC.test.ts +5 -6
  155. package/test/end-to-end/Layer1-Scale-WebRTC.test.ts +13 -8
  156. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +15 -10
  157. package/test/end-to-end/WebSocketConnectionRequest.test.ts +5 -5
  158. package/test/integration/ConnectionLocking.test.ts +32 -26
  159. package/test/integration/ConnectionManager.test.ts +90 -93
  160. package/test/integration/DhtJoinPeerDiscovery.test.ts +53 -0
  161. package/test/integration/DhtRpc.test.ts +4 -6
  162. package/test/integration/Layer1-scale.test.ts +8 -8
  163. package/test/integration/MigrateData.test.ts +9 -9
  164. package/test/integration/Mock-Layer1-Layer0.test.ts +1 -2
  165. package/test/integration/RecursiveFind.test.ts +5 -5
  166. package/test/integration/{DhtPeer.test.ts → RemoteDhtNode.test.ts} +11 -12
  167. package/test/integration/RemoteRouter.test.ts +5 -6
  168. package/test/integration/RemoteStore.test.ts +4 -5
  169. package/test/integration/RouteMessage.test.ts +7 -9
  170. package/test/integration/RpcErrors.test.ts +25 -10
  171. package/test/integration/ScaleDownDht.test.ts +8 -8
  172. package/test/integration/SimultaneousConnections.test.ts +35 -36
  173. package/test/integration/Store.test.ts +8 -9
  174. package/test/integration/StoreAndDelete.test.ts +11 -11
  175. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +7 -7
  176. package/test/integration/WebRtcConnectionManagement.test.ts +26 -19
  177. package/test/integration/WebRtcConnectorRpc.test.ts +6 -8
  178. package/test/integration/WebSocket.test.ts +4 -2
  179. package/test/integration/WebSocketConnectionManagement.test.ts +30 -17
  180. package/test/integration/WebSocketConnectorRpc.test.ts +2 -3
  181. package/test/unit/DuplicateDetector.test.ts +3 -4
  182. package/test/unit/LocalDataStore.test.ts +6 -8
  183. package/test/unit/RandomContactList.test.ts +25 -74
  184. package/test/unit/RecursiveFinder.test.ts +8 -12
  185. package/test/unit/Router.test.ts +18 -21
  186. package/test/unit/SortedContactList.test.ts +62 -112
  187. package/test/unit/WebSocketConnector.test.ts +64 -0
  188. package/test/unit/WebSocketServer.test.ts +24 -12
  189. package/test/utils/mock/RecursiveFinder.ts +2 -2
  190. package/test/utils/mock/Router.ts +9 -11
  191. package/test/utils/mock/Transport.ts +2 -2
  192. package/test/utils/utils.ts +40 -49
  193. package/dist/src/dht/DhtPeer.js.map +0 -1
  194. package/dist/src/helpers/browser/isBrowser.d.ts +0 -1
  195. package/dist/src/helpers/browser/isBrowser.js +0 -6
  196. package/dist/src/helpers/browser/isBrowser.js.map +0 -1
  197. package/dist/src/helpers/browser/isNodeJS.d.ts +0 -1
  198. package/dist/src/helpers/browser/isNodeJS.js +0 -6
  199. package/dist/src/helpers/browser/isNodeJS.js.map +0 -1
  200. package/src/helpers/browser/isBrowser.ts +0 -1
  201. package/src/helpers/browser/isNodeJS.ts +0 -1
  202. package/test/integration/DhtWithMockConnectionLatencies.test.ts +0 -46
  203. package/test/integration/DhtWithMockConnections.test.ts +0 -46
  204. package/test/integration/DhtWithRealConnectionLatencies.test.ts +0 -47
  205. /package/test/unit/{webrtcReplaceInternalIpWithExternalIp.ts → webrtcReplaceInternalIpWithExternalIp.test.ts} +0 -0
@@ -1,7 +1,6 @@
1
1
  import { IDhtRpcServiceClient } from '../proto/packages/dht/protos/DhtRpc.client'
2
2
  import {
3
3
  ClosestPeersRequest,
4
- LeaveNotice,
5
4
  PeerDescriptor,
6
5
  PingRequest
7
6
  } from '../proto/packages/dht/protos/DhtRpc'
@@ -9,6 +8,8 @@ import { v4 } from 'uuid'
9
8
  import { Logger } from '@streamr/utils'
10
9
  import { ProtoRpcClient } from '@streamr/proto-rpc'
11
10
  import { Remote } from './contact/Remote'
11
+ import { PeerID } from '../helpers/PeerID'
12
+ import { keyFromPeerDescriptor, peerIdFromPeerDescriptor } from '../helpers/peerIdFromPeerDescriptor'
12
13
 
13
14
  const logger = new Logger(module)
14
15
 
@@ -18,7 +19,7 @@ export interface KBucketContact {
18
19
  vectorClock: number
19
20
  }
20
21
 
21
- export class DhtPeer extends Remote<IDhtRpcServiceClient> implements KBucketContact {
22
+ export class RemoteDhtNode extends Remote<IDhtRpcServiceClient> implements KBucketContact {
22
23
 
23
24
  private static counter = 0
24
25
  public vectorClock: number
@@ -32,11 +33,11 @@ export class DhtPeer extends Remote<IDhtRpcServiceClient> implements KBucketCont
32
33
  ) {
33
34
  super(ownPeerDescriptor, peerDescriptor, serviceId, client)
34
35
  this.id = this.getPeerId().value
35
- this.vectorClock = DhtPeer.counter++
36
+ this.vectorClock = RemoteDhtNode.counter++
36
37
  }
37
38
 
38
39
  async getClosestPeers(kademliaId: Uint8Array): Promise<PeerDescriptor[]> {
39
- logger.trace(`Requesting getClosestPeers on ${this.getServiceId()} from ${this.getPeerId().toKey()}`)
40
+ logger.trace(`Requesting getClosestPeers on ${this.getServiceId()} from ${keyFromPeerDescriptor(this.getPeerDescriptor())}`)
40
41
  const request: ClosestPeersRequest = {
41
42
  kademliaId,
42
43
  requestId: v4()
@@ -51,7 +52,7 @@ export class DhtPeer extends Remote<IDhtRpcServiceClient> implements KBucketCont
51
52
  }
52
53
 
53
54
  async ping(): Promise<boolean> {
54
- logger.trace(`Requesting ping on ${this.getServiceId()} from ${this.getPeerId().toKey()}`)
55
+ logger.trace(`Requesting ping on ${this.getServiceId()} from ${keyFromPeerDescriptor(this.getPeerDescriptor())}`)
55
56
  const request: PingRequest = {
56
57
  requestId: v4()
57
58
  }
@@ -64,13 +65,15 @@ export class DhtPeer extends Remote<IDhtRpcServiceClient> implements KBucketCont
64
65
  return true
65
66
  }
66
67
  } catch (err) {
67
- logger.trace(`ping failed on ${this.getServiceId()} to ${this.getPeerId().toKey()}: ${err}`)
68
+ logger.trace(`ping failed on ${this.getServiceId()} to ${keyFromPeerDescriptor(this.getPeerDescriptor())}: ${err}`)
68
69
  }
69
70
  return false
70
71
  }
71
72
 
73
+ /*
74
+ TODO remove or start using this method in NET-1131
72
75
  leaveNotice(): void {
73
- logger.trace(`Sending leaveNotice on ${this.getServiceId()} from ${this.getPeerId().toKey()}`)
76
+ logger.trace(`Sending leaveNotice on ${this.getServiceId()} from ${keyFromPeerDescriptor(this.getPeerDescriptor())}`)
74
77
  const request: LeaveNotice = {
75
78
  serviceId: this.getServiceId()
76
79
  }
@@ -80,5 +83,9 @@ export class DhtPeer extends Remote<IDhtRpcServiceClient> implements KBucketCont
80
83
  this.getClient().leaveNotice(request, options).catch((e) => {
81
84
  logger.trace('Failed to send leaveNotice' + e)
82
85
  })
86
+ }*/
87
+
88
+ getPeerId(): PeerID {
89
+ return peerIdFromPeerDescriptor(this.getPeerDescriptor())
83
90
  }
84
91
  }
@@ -2,24 +2,7 @@ import { PeerID } from '../../helpers/PeerID'
2
2
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
3
3
  import { peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
4
4
 
5
- export class ContactState<TContact> {
6
- public contacted = false
7
- public active = false
8
- public contact: TContact
9
-
10
- constructor(contact: TContact) {
11
- this.contact = contact
12
- }
13
- }
14
-
15
- export interface IContact { getPeerId: () => PeerID, getPeerDescriptor: () => PeerDescriptor }
16
-
17
- export interface Events {
18
- contactRemoved: (removedDescriptor: PeerDescriptor, closestDescriptors: PeerDescriptor[]) => void
19
- newContact: (newDescriptor: PeerDescriptor, closestDescriptors: PeerDescriptor[]) => void
20
- }
21
-
22
- export class Contact implements IContact {
5
+ export class Contact {
23
6
  private peerDescriptor: PeerDescriptor
24
7
 
25
8
  constructor(peerDescriptor: PeerDescriptor) {
@@ -1,8 +1,22 @@
1
1
  import { PeerID, PeerIDKey } from '../../helpers/PeerID'
2
2
  import EventEmitter from 'eventemitter3'
3
- import { Events, IContact, ContactState } from './Contact'
4
3
 
5
- export class ContactList<C extends IContact> extends EventEmitter<Events> {
4
+ export class ContactState<C> {
5
+ public contacted = false
6
+ public active = false
7
+ public contact: C
8
+
9
+ constructor(contact: C) {
10
+ this.contact = contact
11
+ }
12
+ }
13
+
14
+ export interface Events<C> {
15
+ contactRemoved: (removedContact: C, closestContacts: C[]) => void
16
+ newContact: (newContact: C, closestContacts: C[]) => void
17
+ }
18
+
19
+ export class ContactList<C extends { getPeerId: () => PeerID }> extends EventEmitter<Events<C>> {
6
20
 
7
21
  protected contactsById: Map<PeerIDKey, ContactState<C>> = new Map()
8
22
  protected contactIds: PeerID[] = []
@@ -25,10 +39,6 @@ export class ContactList<C extends IContact> extends EventEmitter<Events> {
25
39
  return this.contactsById.get(id.toKey())!
26
40
  }
27
41
 
28
- public hasContact(id: PeerID): boolean {
29
- return this.contactsById.has(id.toKey())
30
- }
31
-
32
42
  public getSize(): number {
33
43
  return this.contactIds.length
34
44
  }
@@ -1,8 +1,7 @@
1
1
  import { PeerID } from '../../helpers/PeerID'
2
- import { ContactState, IContact } from './Contact'
3
- import { ContactList } from './ContactList'
2
+ import { ContactList, ContactState } from './ContactList'
4
3
 
5
- export class RandomContactList<C extends IContact> extends ContactList<C> {
4
+ export class RandomContactList<C extends { getPeerId: () => PeerID }> extends ContactList<C> {
6
5
 
7
6
  private randomness: number
8
7
 
@@ -31,24 +30,20 @@ export class RandomContactList<C extends IContact> extends ContactList<C> {
31
30
  this.contactsById.set(contact.getPeerId().toKey(), new ContactState(contact))
32
31
  this.emit(
33
32
  'newContact',
34
- contact.getPeerDescriptor(),
35
- this.getContacts().map((contact: C) => contact.getPeerDescriptor())
33
+ contact,
34
+ this.getContacts()
36
35
  )
37
36
  }
38
37
  }
39
38
  }
40
39
 
41
- addContacts(contacts: C[]): void {
42
- contacts.forEach((contact) => this.addContact(contact))
43
- }
44
-
45
40
  removeContact(id: PeerID): boolean {
46
41
  if (this.contactsById.has(id.toKey())) {
47
- const removedDescriptor = this.contactsById.get(id.toKey())!.contact.getPeerDescriptor()
42
+ const removed = this.contactsById.get(id.toKey())!.contact
48
43
  const index = this.contactIds.findIndex((element) => element.equals(id))
49
44
  this.contactIds.splice(index, 1)
50
45
  this.contactsById.delete(id.toKey())
51
- this.emit('contactRemoved', removedDescriptor, this.getContacts().map((contact: C) => contact.getPeerDescriptor()))
46
+ this.emit('contactRemoved', removed, this.getContacts())
52
47
  return true
53
48
  }
54
49
  return false
@@ -1,14 +1,10 @@
1
1
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
2
2
  import { ProtoRpcClient } from '@streamr/proto-rpc'
3
- import { peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
4
- import { PeerID } from '../../helpers/PeerID'
5
- import { IContact } from './Contact'
6
3
  import { DhtRpcOptions } from '../../rpc-protocol/DhtRpcOptions'
7
4
 
8
- export abstract class Remote<T> implements IContact {
5
+ export abstract class Remote<T> {
9
6
 
10
7
  private readonly localPeerDescriptor: PeerDescriptor
11
- private readonly remotePeerId: PeerID
12
8
  private readonly remotePeerDescriptor: PeerDescriptor
13
9
  private readonly serviceId: string
14
10
  private readonly client: ProtoRpcClient<T>
@@ -20,16 +16,11 @@ export abstract class Remote<T> implements IContact {
20
16
  client: ProtoRpcClient<T>
21
17
  ) {
22
18
  this.localPeerDescriptor = localPeerDescriptor
23
- this.remotePeerId = peerIdFromPeerDescriptor(remotePeerDescriptor)
24
19
  this.remotePeerDescriptor = remotePeerDescriptor
25
20
  this.client = client
26
21
  this.serviceId = serviceId
27
22
  }
28
23
 
29
- getPeerId(): PeerID {
30
- return this.remotePeerId
31
- }
32
-
33
24
  getPeerDescriptor(): PeerDescriptor {
34
25
  return this.remotePeerDescriptor
35
26
  }
@@ -1,9 +1,8 @@
1
1
  import KBucket from 'k-bucket'
2
2
  import { PeerID } from '../../helpers/PeerID'
3
- import { ContactState, IContact } from './Contact'
4
- import { ContactList } from './ContactList'
3
+ import { ContactList, ContactState } from './ContactList'
5
4
 
6
- export class SortedContactList<C extends IContact> extends ContactList<C> {
5
+ export class SortedContactList<C extends { getPeerId: () => PeerID }> extends ContactList<C> {
7
6
 
8
7
  private allowOwnPeerId: boolean
9
8
  private peerIdDistanceLimit?: PeerID
@@ -48,22 +47,22 @@ export class SortedContactList<C extends IContact> extends ContactList<C> {
48
47
  this.contactIds.push(contact.getPeerId())
49
48
  this.contactIds.sort(this.compareIds)
50
49
  } else if (this.compareIds(this.contactIds[this.maxSize - 1], contact.getPeerId()) > 0) {
51
- const removed = this.contactIds.pop()
52
- const removedDescriptor = this.contactsById.get(removed!.toKey())!.contact.getPeerDescriptor()
53
- this.contactsById.delete(removed!.toKey())
50
+ const removedId = this.contactIds.pop()
51
+ const removedContact = this.contactsById.get(removedId!.toKey())!.contact
52
+ this.contactsById.delete(removedId!.toKey())
54
53
  this.contactsById.set(contact.getPeerId().toKey(), new ContactState(contact))
55
54
  this.contactIds.push(contact.getPeerId())
56
55
  this.contactIds.sort(this.compareIds)
57
56
  this.emit(
58
57
  'contactRemoved',
59
- removedDescriptor,
60
- this.getClosestContacts().map((contact: C) => contact.getPeerDescriptor())
58
+ removedContact,
59
+ this.getClosestContacts()
61
60
  )
62
61
  }
63
62
  this.emit(
64
63
  'newContact',
65
- contact.getPeerDescriptor(),
66
- this.getClosestContacts().map((contact: C) => contact.getPeerDescriptor())
64
+ contact,
65
+ this.getClosestContacts()
67
66
  )
68
67
  }
69
68
  }
@@ -130,20 +129,16 @@ export class SortedContactList<C extends IContact> extends ContactList<C> {
130
129
  return distance1 - distance2
131
130
  }
132
131
 
133
- public getStringIds(): string[] {
134
- return this.contactIds.map((peerId) => peerId.toKey())
135
- }
136
-
137
132
  public removeContact(id: PeerID): boolean {
138
133
  if (this.contactsById.has(id.toKey())) {
139
- const removedDescriptor = this.contactsById.get(id.toKey())!.contact.getPeerDescriptor()
134
+ const removed = this.contactsById.get(id.toKey())!.contact
140
135
  const index = this.contactIds.findIndex((element) => element.equals(id))
141
136
  this.contactIds.splice(index, 1)
142
137
  this.contactsById.delete(id.toKey())
143
138
  this.emit(
144
139
  'contactRemoved',
145
- removedDescriptor,
146
- this.getClosestContacts().map((contact: C) => contact.getPeerDescriptor())
140
+ removed,
141
+ this.getClosestContacts()
147
142
  )
148
143
  return true
149
144
  }
@@ -157,12 +152,4 @@ export class SortedContactList<C extends IContact> extends ContactList<C> {
157
152
  public getAllContacts(): C[] {
158
153
  return this.contactIds.map((peerId) => this.contactsById.get(peerId.toKey())!.contact)
159
154
  }
160
-
161
- public getMaxSize(): number {
162
- return this.maxSize
163
- }
164
-
165
- public setAllAsUncontacted(): void {
166
- this.contactsById.forEach((contact) => contact.contacted = false)
167
- }
168
155
  }
@@ -7,8 +7,8 @@ import { PeerID } from '../../helpers/PeerID'
7
7
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
8
8
  import { DhtRpcServiceClient } from '../../proto/packages/dht/protos/DhtRpc.client'
9
9
  import { SortedContactList } from '../contact/SortedContactList'
10
- import { DhtPeer } from '../DhtPeer'
11
- import { peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
10
+ import { RemoteDhtNode } from '../RemoteDhtNode'
11
+ import { areEqualPeerDescriptors, keyFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
12
12
 
13
13
  const logger = new Logger(module)
14
14
 
@@ -17,16 +17,15 @@ interface DiscoverySessionEvents {
17
17
  }
18
18
 
19
19
  interface DiscoverySessionConfig {
20
- bucket: KBucket<DhtPeer>
21
- neighborList: SortedContactList<DhtPeer>
20
+ bucket: KBucket<RemoteDhtNode>
21
+ neighborList: SortedContactList<RemoteDhtNode>
22
22
  targetId: Uint8Array
23
23
  ownPeerDescriptor: PeerDescriptor
24
24
  serviceId: string
25
25
  rpcCommunicator: RpcCommunicator
26
26
  parallelism: number
27
27
  noProgressLimit: number
28
- newContactListener?: (dhtPeer: DhtPeer) => void
29
- nodeName?: string
28
+ newContactListener?: (remoteDhtNode: RemoteDhtNode) => void
30
29
  }
31
30
 
32
31
  export class DiscoverySession {
@@ -38,11 +37,9 @@ export class DiscoverySession {
38
37
  private noProgressCounter = 0
39
38
  private ongoingClosestPeersRequests: Set<string> = new Set()
40
39
  private readonly config: DiscoverySessionConfig
41
- private readonly ownPeerId: PeerID
42
40
 
43
41
  constructor(config: DiscoverySessionConfig) {
44
42
  this.config = config
45
- this.ownPeerId = peerIdFromPeerDescriptor(config.ownPeerDescriptor)
46
43
  }
47
44
 
48
45
  private addNewContacts(contacts: PeerDescriptor[]): void {
@@ -50,28 +47,28 @@ export class DiscoverySession {
50
47
  return
51
48
  }
52
49
  contacts.forEach((contact) => {
53
- const dhtPeer = new DhtPeer(
54
- this.config.ownPeerDescriptor,
55
- contact,
56
- toProtoRpcClient(new DhtRpcServiceClient(this.config.rpcCommunicator.getRpcClientTransport())),
57
- this.config.serviceId
58
- )
59
- if (!dhtPeer.getPeerId().equals(this.ownPeerId)) {
50
+ if (!areEqualPeerDescriptors(contact, this.config.ownPeerDescriptor)) {
51
+ const remoteDhtNode = new RemoteDhtNode(
52
+ this.config.ownPeerDescriptor,
53
+ contact,
54
+ toProtoRpcClient(new DhtRpcServiceClient(this.config.rpcCommunicator.getRpcClientTransport())),
55
+ this.config.serviceId
56
+ )
60
57
  if (this.config.newContactListener) {
61
- this.config.newContactListener(dhtPeer)
58
+ this.config.newContactListener(remoteDhtNode)
62
59
  }
63
- if (!this.config.neighborList.getContact(dhtPeer.getPeerId())) {
64
- this.config.neighborList.addContact(dhtPeer)
60
+ if (!this.config.neighborList.getContact(remoteDhtNode.getPeerId())) {
61
+ this.config.neighborList.addContact(remoteDhtNode)
65
62
  }
66
63
  }
67
64
  })
68
65
  }
69
66
 
70
- private async getClosestPeersFromContact(contact: DhtPeer): Promise<PeerDescriptor[]> {
67
+ private async getClosestPeersFromContact(contact: RemoteDhtNode): Promise<PeerDescriptor[]> {
71
68
  if (this.stopped) {
72
69
  return []
73
70
  }
74
- logger.trace(`Getting closest peers from contact: ${contact.getPeerId().toKey()}`)
71
+ logger.trace(`Getting closest peers from contact: ${keyFromPeerDescriptor(contact.getPeerDescriptor())}`)
75
72
  this.outgoingClosestPeersRequestsCounter++
76
73
  this.config.neighborList.setContacted(contact.getPeerId())
77
74
  const returnedContacts = await contact.getClosestPeers(this.config.targetId)
@@ -93,7 +90,7 @@ export class DiscoverySession {
93
90
  }
94
91
  }
95
92
 
96
- private onClosestPeersRequestFailed(peer: DhtPeer, _exception: Error) {
93
+ private onClosestPeersRequestFailed(peer: RemoteDhtNode) {
97
94
  if (!this.ongoingClosestPeersRequests.has(peer.getPeerId().toKey())) {
98
95
  return
99
96
  }
@@ -120,7 +117,7 @@ export class DiscoverySession {
120
117
  // eslint-disable-next-line promise/catch-or-return
121
118
  this.getClosestPeersFromContact(nextPeer)
122
119
  .then((contacts) => this.onClosestPeersRequestSucceeded(nextPeer.getPeerId(), contacts))
123
- .catch((err) => this.onClosestPeersRequestFailed(nextPeer, err))
120
+ .catch(() => this.onClosestPeersRequestFailed(nextPeer))
124
121
  .finally(() => {
125
122
  this.outgoingClosestPeersRequestsCounter--
126
123
  this.findMoreContacts()
@@ -128,7 +125,7 @@ export class DiscoverySession {
128
125
  }
129
126
  }
130
127
 
131
- public async findClosestNodes(timeout: number): Promise<SortedContactList<DhtPeer>> {
128
+ public async findClosestNodes(timeout: number): Promise<SortedContactList<RemoteDhtNode>> {
132
129
  if (this.config.neighborList.getUncontactedContacts(this.config.parallelism).length < 1) {
133
130
  logger.trace('getUncontactedContacts length was 0 in beginning of discovery, this.neighborList.size: '
134
131
  + this.config.neighborList.getSize())
@@ -1,25 +1,24 @@
1
1
  import { DiscoverySession } from './DiscoverySession'
2
- import { DhtPeer } from '../DhtPeer'
3
- import crypto from 'crypto'
4
- import { isSamePeerDescriptor, keyFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
2
+ import { RemoteDhtNode } from '../RemoteDhtNode'
3
+ import { areEqualPeerDescriptors, keyFromPeerDescriptor, peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
5
4
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
6
5
  import { Logger, scheduleAtInterval, setAbortableTimeout } from '@streamr/utils'
7
6
  import KBucket from 'k-bucket'
8
7
  import { SortedContactList } from '../contact/SortedContactList'
9
8
  import { ConnectionManager } from '../../connection/ConnectionManager'
10
- import { PeerID, PeerIDKey } from '../../helpers/PeerID'
9
+ import { PeerIDKey } from '../../helpers/PeerID'
11
10
  import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
12
11
  import { RandomContactList } from '../contact/RandomContactList'
12
+ import { createRandomKademliaId } from '../../helpers/kademliaId'
13
13
 
14
14
  interface PeerDiscoveryConfig {
15
15
  rpcCommunicator: RoutingRpcCommunicator
16
16
  ownPeerDescriptor: PeerDescriptor
17
- ownPeerId: PeerID
18
- bucket: KBucket<DhtPeer>
19
- connections: Map<PeerIDKey, DhtPeer>
20
- neighborList: SortedContactList<DhtPeer>
21
- randomPeers: RandomContactList<DhtPeer>
22
- openInternetPeers: SortedContactList<DhtPeer>
17
+ bucket: KBucket<RemoteDhtNode>
18
+ connections: Map<PeerIDKey, RemoteDhtNode>
19
+ neighborList: SortedContactList<RemoteDhtNode>
20
+ randomPeers: RandomContactList<RemoteDhtNode>
21
+ openInternetPeers: SortedContactList<RemoteDhtNode>
23
22
  joinNoProgressLimit: number
24
23
  getClosestContactsLimit: number
25
24
  serviceId: string
@@ -32,12 +31,11 @@ interface PeerDiscoveryConfig {
32
31
  const logger = new Logger(module)
33
32
 
34
33
  export class PeerDiscovery {
34
+
35
35
  private readonly config: PeerDiscoveryConfig
36
36
  private ongoingDiscoverySessions: Map<string, DiscoverySession> = new Map()
37
- private stopped = false
38
37
  private rejoinOngoing = false
39
38
  private joinCalled = false
40
-
41
39
  private rejoinTimeoutRef?: NodeJS.Timeout
42
40
  private readonly abortController: AbortController
43
41
  private recoveryIntervalStarted = false
@@ -47,8 +45,8 @@ export class PeerDiscovery {
47
45
  this.abortController = new AbortController()
48
46
  }
49
47
 
50
- async joinDht(entryPointDescriptor: PeerDescriptor, doRandomJoin = true, retry = true): Promise<void> {
51
- if (this.stopped) {
48
+ async joinDht(entryPointDescriptor: PeerDescriptor, doAdditionalRandomPeerDiscovery = true, retry = true): Promise<void> {
49
+ if (this.isStopped()) {
52
50
  return
53
51
  }
54
52
  this.joinCalled = true
@@ -56,44 +54,47 @@ export class PeerDiscovery {
56
54
  `Joining ${this.config.serviceId === 'layer0' ? 'The Streamr Network' : `Control Layer for ${this.config.serviceId}`}`
57
55
  + ` via entrypoint ${keyFromPeerDescriptor(entryPointDescriptor)}`
58
56
  )
59
- if (isSamePeerDescriptor(entryPointDescriptor, this.config.ownPeerDescriptor)) {
57
+ if (areEqualPeerDescriptors(entryPointDescriptor, this.config.ownPeerDescriptor)) {
60
58
  return
61
59
  }
62
60
  this.config.connectionManager?.lockConnection(entryPointDescriptor, `${this.config.serviceId}::joinDht`)
63
61
  this.config.addContact(entryPointDescriptor)
64
- const closest = this.config.bucket.closest(this.config.ownPeerId.value, this.config.getClosestContactsLimit)
62
+ const closest = this.config.bucket.closest(peerIdFromPeerDescriptor(this.config.ownPeerDescriptor).value, this.config.getClosestContactsLimit)
65
63
  this.config.neighborList.addContacts(closest)
64
+ const sessions = [this.createSession(peerIdFromPeerDescriptor(this.config.ownPeerDescriptor).value)]
65
+ if (doAdditionalRandomPeerDiscovery) {
66
+ sessions.push(this.createSession(createRandomKademliaId()))
67
+ }
68
+ await this.runSessions(sessions, entryPointDescriptor, retry)
69
+ this.config.connectionManager?.unlockConnection(entryPointDescriptor, `${this.config.serviceId}::joinDht`)
70
+
71
+ }
72
+
73
+ private createSession(targetId: Uint8Array): DiscoverySession {
66
74
  const sessionOptions = {
67
75
  bucket: this.config.bucket,
68
76
  neighborList: this.config.neighborList,
69
- targetId: this.config.ownPeerId.value,
77
+ targetId,
70
78
  ownPeerDescriptor: this.config.ownPeerDescriptor,
71
79
  serviceId: this.config.serviceId,
72
80
  rpcCommunicator: this.config.rpcCommunicator,
73
81
  parallelism: this.config.parallelism,
74
82
  noProgressLimit: this.config.joinNoProgressLimit,
75
- newContactListener: (newPeer: DhtPeer) => this.config.addContact(newPeer.getPeerDescriptor()),
76
- nodeName: this.config.ownPeerDescriptor.nodeName
77
- }
78
- const session = new DiscoverySession(sessionOptions)
79
- const randomSession = doRandomJoin ? new DiscoverySession({
80
- ...sessionOptions,
81
- targetId: crypto.randomBytes(8),
82
- nodeName: this.config.ownPeerDescriptor.nodeName + '-random'
83
- }) : null
84
- this.ongoingDiscoverySessions.set(session.sessionId, session)
85
- if (randomSession) {
86
- this.ongoingDiscoverySessions.set(randomSession.sessionId, randomSession)
83
+ newContactListener: (newPeer: RemoteDhtNode) => this.config.addContact(newPeer.getPeerDescriptor())
87
84
  }
85
+ return new DiscoverySession(sessionOptions)
86
+ }
87
+
88
+ private async runSessions(sessions: DiscoverySession[], entryPointDescriptor: PeerDescriptor, retry: boolean): Promise<void> {
88
89
  try {
89
- await session.findClosestNodes(this.config.joinTimeout)
90
- if (randomSession) {
91
- await randomSession.findClosestNodes(this.config.joinTimeout)
90
+ for (const session of sessions) {
91
+ this.ongoingDiscoverySessions.set(session.sessionId, session)
92
+ await session.findClosestNodes(this.config.joinTimeout)
92
93
  }
93
94
  } catch (_e) {
94
95
  logger.debug(`DHT join on ${this.config.serviceId} timed out`)
95
96
  } finally {
96
- if (!this.stopped) {
97
+ if (!this.isStopped()) {
97
98
  if (this.config.bucket.count() === 0) {
98
99
  if (retry) {
99
100
  setAbortableTimeout(() => this.rejoinDht(entryPointDescriptor), 1000, this.abortController.signal)
@@ -102,19 +103,15 @@ export class PeerDiscovery {
102
103
  await this.ensureRecoveryIntervalIsRunning()
103
104
  }
104
105
  }
105
- this.ongoingDiscoverySessions.delete(session.sessionId)
106
- if (randomSession) {
107
- this.ongoingDiscoverySessions.delete(randomSession.sessionId)
108
- }
109
- this.config.connectionManager?.unlockConnection(entryPointDescriptor, `${this.config.serviceId}::joinDht`)
106
+ sessions.forEach((session) => this.ongoingDiscoverySessions.delete(session.sessionId))
110
107
  }
111
108
  }
112
109
 
113
110
  public async rejoinDht(entryPoint: PeerDescriptor): Promise<void> {
114
- if (this.stopped || this.rejoinOngoing) {
111
+ if (this.isStopped() || this.rejoinOngoing) {
115
112
  return
116
113
  }
117
- logger.debug(`Rejoining DHT ${this.config.serviceId} ${this.config.ownPeerDescriptor.nodeName}!`)
114
+ logger.debug(`Rejoining DHT ${this.config.serviceId}`)
118
115
  this.rejoinOngoing = true
119
116
  try {
120
117
  this.config.neighborList.clear()
@@ -122,7 +119,7 @@ export class PeerDiscovery {
122
119
  logger.debug(`Rejoined DHT successfully ${this.config.serviceId}!`)
123
120
  } catch (err) {
124
121
  logger.warn(`Rejoining DHT ${this.config.serviceId} failed`)
125
- if (!this.stopped) {
122
+ if (!this.isStopped()) {
126
123
  setAbortableTimeout(() => this.rejoinDht(entryPoint), 5000, this.abortController.signal)
127
124
  }
128
125
  } finally {
@@ -138,10 +135,11 @@ export class PeerDiscovery {
138
135
  }
139
136
 
140
137
  private async fetchClosestPeersFromBucket(): Promise<void> {
141
- if (this.stopped) {
138
+ if (this.isStopped()) {
142
139
  return
143
140
  }
144
- await Promise.allSettled(this.config.bucket.closest(this.config.ownPeerId.value, this.config.parallelism).map(async (peer: DhtPeer) => {
141
+ const nodes = this.config.bucket.closest(peerIdFromPeerDescriptor(this.config.ownPeerDescriptor).value, this.config.parallelism)
142
+ await Promise.allSettled(nodes.map(async (peer: RemoteDhtNode) => {
145
143
  const contacts = await peer.getClosestPeers(this.config.ownPeerDescriptor.kademliaId)
146
144
  contacts.forEach((contact) => {
147
145
  this.config.addContact(contact)
@@ -157,8 +155,11 @@ export class PeerDiscovery {
157
155
  return this.joinCalled
158
156
  }
159
157
 
158
+ private isStopped() {
159
+ return this.abortController.signal.aborted
160
+ }
161
+
160
162
  public stop(): void {
161
- this.stopped = true
162
163
  this.abortController.abort()
163
164
  if (this.rejoinTimeoutRef) {
164
165
  clearTimeout(this.rejoinTimeoutRef)