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

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 (84) hide show
  1. package/dist/src/connection/ConnectivityChecker.js +27 -17
  2. package/dist/src/connection/ConnectivityChecker.js.map +1 -1
  3. package/dist/src/connection/Handshaker.js +18 -13
  4. package/dist/src/connection/Handshaker.js.map +1 -1
  5. package/dist/src/connection/WebSocket/ServerWebSocket.js +0 -1
  6. package/dist/src/connection/WebSocket/ServerWebSocket.js.map +1 -1
  7. package/dist/src/dht/DhtNode.d.ts +1 -0
  8. package/dist/src/dht/DhtNode.js +12 -31
  9. package/dist/src/dht/DhtNode.js.map +1 -1
  10. package/dist/src/dht/DhtPeer.d.ts +0 -1
  11. package/dist/src/dht/DhtPeer.js +15 -26
  12. package/dist/src/dht/DhtPeer.js.map +1 -1
  13. package/dist/src/dht/RemoteExternalApi.d.ts +3 -1
  14. package/dist/src/dht/RemoteExternalApi.js +20 -6
  15. package/dist/src/dht/RemoteExternalApi.js.map +1 -1
  16. package/dist/src/dht/contact/ContactList.d.ts +16 -0
  17. package/dist/src/dht/contact/ContactList.js +36 -0
  18. package/dist/src/dht/contact/ContactList.js.map +1 -0
  19. package/dist/src/dht/contact/RandomContactList.d.ts +7 -16
  20. package/dist/src/dht/contact/RandomContactList.js +7 -31
  21. package/dist/src/dht/contact/RandomContactList.js.map +1 -1
  22. package/dist/src/dht/contact/Remote.d.ts +10 -6
  23. package/dist/src/dht/contact/Remote.js +19 -6
  24. package/dist/src/dht/contact/Remote.js.map +1 -1
  25. package/dist/src/dht/contact/SortedContactList.d.ts +10 -20
  26. package/dist/src/dht/contact/SortedContactList.js +10 -31
  27. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  28. package/dist/src/dht/find/RecursiveFinder.js +1 -1
  29. package/dist/src/dht/find/RecursiveFinder.js.map +1 -1
  30. package/dist/src/dht/find/RemoteRecursiveFindSession.js +1 -5
  31. package/dist/src/dht/find/RemoteRecursiveFindSession.js.map +1 -1
  32. package/dist/src/dht/registerExternalApiRpcMethods.d.ts +2 -0
  33. package/dist/src/dht/{registerExternalApiRpcMethod.js → registerExternalApiRpcMethods.js} +13 -5
  34. package/dist/src/dht/registerExternalApiRpcMethods.js.map +1 -0
  35. package/dist/src/dht/routing/RemoteRouter.js +13 -19
  36. package/dist/src/dht/routing/RemoteRouter.js.map +1 -1
  37. package/dist/src/dht/routing/RoutingSession.js +1 -1
  38. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  39. package/dist/src/dht/store/DataStore.js +3 -3
  40. package/dist/src/dht/store/DataStore.js.map +1 -1
  41. package/dist/src/dht/store/RemoteStore.js +13 -17
  42. package/dist/src/dht/store/RemoteStore.js.map +1 -1
  43. package/dist/src/exports.d.ts +1 -0
  44. package/dist/src/exports.js +3 -1
  45. package/dist/src/exports.js.map +1 -1
  46. package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +10 -0
  47. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +7 -0
  48. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
  49. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +36 -0
  50. package/dist/src/proto/packages/dht/protos/DhtRpc.js +29 -2
  51. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  52. package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +6 -0
  53. package/package.json +6 -6
  54. package/protos/DhtRpc.proto +10 -0
  55. package/src/connection/ConnectionManager.ts +1 -1
  56. package/src/connection/ConnectivityChecker.ts +26 -17
  57. package/src/connection/Handshaker.ts +18 -13
  58. package/src/connection/WebSocket/ServerWebSocket.ts +0 -1
  59. package/src/dht/DhtNode.ts +19 -9
  60. package/src/dht/DhtPeer.ts +17 -29
  61. package/src/dht/RemoteExternalApi.ts +22 -8
  62. package/src/dht/contact/ContactList.ts +45 -0
  63. package/src/dht/contact/RandomContactList.ts +16 -41
  64. package/src/dht/contact/Remote.ts +30 -14
  65. package/src/dht/contact/SortedContactList.ts +25 -53
  66. package/src/dht/find/RecursiveFinder.ts +2 -2
  67. package/src/dht/find/RemoteRecursiveFindSession.ts +1 -8
  68. package/src/dht/registerExternalApiRpcMethods.ts +41 -0
  69. package/src/dht/routing/RemoteRouter.ts +13 -20
  70. package/src/dht/routing/RoutingSession.ts +2 -2
  71. package/src/dht/store/DataStore.ts +6 -6
  72. package/src/dht/store/RemoteStore.ts +13 -20
  73. package/src/exports.ts +1 -0
  74. package/src/proto/packages/dht/protos/DhtRpc.client.ts +13 -0
  75. package/src/proto/packages/dht/protos/DhtRpc.server.ts +6 -0
  76. package/src/proto/packages/dht/protos/DhtRpc.ts +49 -1
  77. package/test/integration/DhtNodeExternalAPI.test.ts +9 -0
  78. package/test/integration/RemoteRouter.test.ts +1 -1
  79. package/test/integration/RemoteStore.test.ts +1 -1
  80. package/test/unit/RandomContactList.test.ts +24 -17
  81. package/test/unit/SortedContactList.test.ts +56 -30
  82. package/dist/src/dht/registerExternalApiRpcMethod.d.ts +0 -2
  83. package/dist/src/dht/registerExternalApiRpcMethod.js.map +0 -1
  84. package/src/dht/registerExternalApiRpcMethod.ts +0 -26
@@ -69,14 +69,18 @@ export class ConnectivityChecker {
69
69
  }, ConnectivityChecker.CONNECTIVITY_CHECKER_TIMEOUT)
70
70
  const listener = (bytes: Uint8Array) => {
71
71
  outgoingConnection.close('OTHER')
72
- const message: Message = Message.fromBinary(bytes)
73
- if (message.body.oneofKind === 'connectivityResponse') {
74
- const connectivityResponseMessage = message.body.connectivityResponse
75
- outgoingConnection!.off('data', listener)
76
- clearTimeout(timeoutId)
77
- resolve(connectivityResponseMessage)
78
- } else {
79
- return
72
+ try {
73
+ const message: Message = Message.fromBinary(bytes)
74
+ if (message.body.oneofKind === 'connectivityResponse') {
75
+ const connectivityResponseMessage = message.body.connectivityResponse
76
+ outgoingConnection!.off('data', listener)
77
+ clearTimeout(timeoutId)
78
+ resolve(connectivityResponseMessage)
79
+ } else {
80
+ return
81
+ }
82
+ } catch (err) {
83
+ logger.trace(`Could not parse message: ${err}`)
80
84
  }
81
85
  }
82
86
  outgoingConnection!.on('data', listener)
@@ -97,16 +101,21 @@ export class ConnectivityChecker {
97
101
  public listenToIncomingConnectivityRequests(connectionToListenTo: ServerWebSocket): void {
98
102
  connectionToListenTo.on('data', (data: Uint8Array) => {
99
103
  logger.trace('server received data')
100
- const message = Message.fromBinary(data)
101
- if (message.body.oneofKind === 'connectivityRequest') {
102
- logger.trace('received connectivity request')
103
- this.handleIncomingConnectivityRequest(connectionToListenTo, message.body.connectivityRequest).then(() => {
104
- logger.trace('handleIncomingConnectivityRequest ok')
105
- return
106
- }).catch((e) => {
107
- logger.error('handleIncomingConnectivityRequest' + e)
108
- })
104
+ try {
105
+ const message = Message.fromBinary(data)
106
+ if (message.body.oneofKind === 'connectivityRequest') {
107
+ logger.trace('received connectivity request')
108
+ this.handleIncomingConnectivityRequest(connectionToListenTo, message.body.connectivityRequest).then(() => {
109
+ logger.trace('handleIncomingConnectivityRequest ok')
110
+ return
111
+ }).catch((e) => {
112
+ logger.error('handleIncomingConnectivityRequest' + e)
113
+ })
114
+ }
115
+ } catch (err) {
116
+ logger.trace(`Could not parse message: ${err}`)
109
117
  }
118
+
110
119
  })
111
120
  }
112
121
 
@@ -32,21 +32,26 @@ export class Handshaker extends EventEmitter<HandshakerEvents> {
32
32
  }
33
33
 
34
34
  private onData = (data: Uint8Array) => {
35
- const message = Message.fromBinary(data)
36
- if (message.body.oneofKind === 'handshakeRequest') {
37
- logger.trace('handshake request received')
38
- const handshake = message.body.handshakeRequest
39
- this.emit('handshakeRequest', handshake.peerDescriptor!)
40
- }
41
- if (message.body.oneofKind === 'handshakeResponse') {
42
- logger.trace('handshake response received')
43
- const handshake = message.body.handshakeResponse
44
- if (handshake.responseError) {
45
- this.emit('handshakeFailed', handshake.responseError)
46
- } else {
47
- this.emit('handshakeCompleted', handshake.peerDescriptor!)
35
+ try {
36
+ const message = Message.fromBinary(data)
37
+ if (message.body.oneofKind === 'handshakeRequest') {
38
+ logger.trace('handshake request received')
39
+ const handshake = message.body.handshakeRequest
40
+ this.emit('handshakeRequest', handshake.peerDescriptor!)
41
+ }
42
+ if (message.body.oneofKind === 'handshakeResponse') {
43
+ logger.trace('handshake response received')
44
+ const handshake = message.body.handshakeResponse
45
+ if (handshake.responseError) {
46
+ this.emit('handshakeFailed', handshake.responseError)
47
+ } else {
48
+ this.emit('handshakeCompleted', handshake.peerDescriptor!)
49
+ }
48
50
  }
51
+ } catch (err) {
52
+ logger.error('error while parsing handshake message', err)
49
53
  }
54
+
50
55
  }
51
56
 
52
57
  public sendHandshakeRequest(): void {
@@ -67,7 +67,6 @@ export class ServerWebSocket extends EventEmitter<ConnectionEvents> implements I
67
67
  this.socket = undefined
68
68
 
69
69
  this.emit('disconnected', disconnectionType, reasonCode, description)
70
- this.removeAllListeners()
71
70
  }
72
71
 
73
72
  public send(data: Uint8Array): void {
@@ -18,7 +18,6 @@ import {
18
18
  FindMode,
19
19
  DataEntry,
20
20
  } from '../proto/packages/dht/protos/DhtRpc'
21
- import * as Err from '../helpers/errors'
22
21
  import { DisconnectionType, ITransport, TransportEvents } from '../transport/ITransport'
23
22
  import { ConnectionManager, ConnectionManagerConfig, PortRange, TlsCertificate } from '../connection/ConnectionManager'
24
23
  import { DhtRpcServiceClient, ExternalApiServiceClient } from '../proto/packages/dht/protos/DhtRpc.client'
@@ -40,10 +39,11 @@ import { DataStore } from './store/DataStore'
40
39
  import { PeerDiscovery } from './discovery/PeerDiscovery'
41
40
  import { LocalDataStore } from './store/LocalDataStore'
42
41
  import { IceServer } from '../connection/WebRTC/WebRtcConnector'
43
- import { registerExternalApiRpcMethod } from './registerExternalApiRpcMethod'
42
+ import { registerExternalApiRpcMethods } from './registerExternalApiRpcMethods'
44
43
  import { RemoteExternalApi } from './RemoteExternalApi'
45
44
  import { UUID } from '../exports'
46
45
  import { isNodeJS } from '../helpers/browser/isNodeJS'
46
+ import { sample } from 'lodash'
47
47
 
48
48
  export interface DhtNodeEvents {
49
49
  newContact: (peerDescriptor: PeerDescriptor, closestPeers: PeerDescriptor[]) => void
@@ -299,7 +299,7 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
299
299
  return this.bucket!.closest(id, n)
300
300
  }
301
301
  })
302
- registerExternalApiRpcMethod(this)
302
+ registerExternalApiRpcMethods(this)
303
303
  if (this.connectionManager! && this.config.entryPoints && this.config.entryPoints.length > 0
304
304
  && !isSamePeerDescriptor(this.config.entryPoints[0], this.ownPeerDescriptor!)) {
305
305
  this.connectToEntryPoint(this.config.entryPoints[0])
@@ -640,9 +640,22 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
640
640
  }
641
641
 
642
642
  public async storeDataToDht(key: Uint8Array, data: Any): Promise<PeerDescriptor[]> {
643
+ if (this.isJoinOngoing() && this.config.entryPoints && this.config.entryPoints.length > 0) {
644
+ return this.storeDataViaPeer(key, data, sample(this.config.entryPoints)!)
645
+ }
643
646
  return this.dataStore!.storeDataToDht(key, data)
644
647
  }
645
648
 
649
+ public async storeDataViaPeer(key: Uint8Array, data: Any, peer: PeerDescriptor): Promise<PeerDescriptor[]> {
650
+ const target = new RemoteExternalApi(
651
+ this.ownPeerDescriptor!,
652
+ peer,
653
+ this.config.serviceId,
654
+ toProtoRpcClient(new ExternalApiServiceClient(this.rpcCommunicator!.getRpcClientTransport()))
655
+ )
656
+ return await target.storeData(key, data)
657
+ }
658
+
646
659
  public async getDataFromDht(idToFind: Uint8Array): Promise<RecursiveFindResult> {
647
660
  return this.recursiveFinder!.startRecursiveFind(idToFind, FindMode.DATA)
648
661
  }
@@ -657,8 +670,8 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
657
670
  const target = new RemoteExternalApi(
658
671
  this.ownPeerDescriptor!,
659
672
  peer,
660
- toProtoRpcClient(new ExternalApiServiceClient(this.rpcCommunicator!.getRpcClientTransport())),
661
- this.config.serviceId
673
+ this.config.serviceId,
674
+ toProtoRpcClient(new ExternalApiServiceClient(this.rpcCommunicator!.getRpcClientTransport()))
662
675
  )
663
676
  return await target.findData(idToFind)
664
677
  }
@@ -720,13 +733,10 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
720
733
  }
721
734
 
722
735
  public async stop(): Promise<void> {
723
- if (this.stopped) {
736
+ if (this.stopped || !this.started) {
724
737
  return
725
738
  }
726
739
  logger.trace('stop()')
727
- if (!this.started) {
728
- throw new Err.CouldNotStop('Cannot not stop() before start()')
729
- }
730
740
  this.stopped = true
731
741
 
732
742
  if (this.entryPointDisconnectTimeout) {
@@ -6,7 +6,6 @@ import {
6
6
  PingRequest
7
7
  } from '../proto/packages/dht/protos/DhtRpc'
8
8
  import { v4 } from 'uuid'
9
- import { DhtRpcOptions } from '../rpc-protocol/DhtRpcOptions'
10
9
  import { Logger } from '@streamr/utils'
11
10
  import { ProtoRpcClient } from '@streamr/proto-rpc'
12
11
  import { Remote } from './contact/Remote'
@@ -20,77 +19,66 @@ export interface KBucketContact {
20
19
  }
21
20
 
22
21
  export class DhtPeer extends Remote<IDhtRpcServiceClient> implements KBucketContact {
22
+
23
23
  private static counter = 0
24
24
  public vectorClock: number
25
25
  public readonly id: Uint8Array
26
+
26
27
  constructor(
27
28
  ownPeerDescriptor: PeerDescriptor,
28
29
  peerDescriptor: PeerDescriptor,
29
30
  client: ProtoRpcClient<IDhtRpcServiceClient>,
30
31
  serviceId: string
31
32
  ) {
32
- super(ownPeerDescriptor, peerDescriptor, client, serviceId)
33
- this.id = this.peerId.value
33
+ super(ownPeerDescriptor, peerDescriptor, serviceId, client)
34
+ this.id = this.getPeerId().value
34
35
  this.vectorClock = DhtPeer.counter++
35
36
  }
36
37
 
37
38
  async getClosestPeers(kademliaId: Uint8Array): Promise<PeerDescriptor[]> {
38
- logger.trace(`Requesting getClosestPeers on ${this.serviceId} from ${this.peerId.toKey()}`)
39
+ logger.trace(`Requesting getClosestPeers on ${this.getServiceId()} from ${this.getPeerId().toKey()}`)
39
40
  const request: ClosestPeersRequest = {
40
41
  kademliaId,
41
42
  requestId: v4()
42
43
  }
43
- const options: DhtRpcOptions = {
44
- sourceDescriptor: this.ownPeerDescriptor,
45
- targetDescriptor: this.peerDescriptor
46
- }
47
44
  try {
48
- const peers = await this.client.getClosestPeers(request, options)
45
+ const peers = await this.getClient().getClosestPeers(request, this.formDhtRpcOptions())
49
46
  return peers.peers
50
47
  } catch (err) {
51
- logger.trace(`getClosestPeers error ${this.serviceId}`, { err })
48
+ logger.trace(`getClosestPeers error ${this.getServiceId()}`, { err })
52
49
  throw err
53
50
  }
54
51
  }
55
52
 
56
53
  async ping(): Promise<boolean> {
57
- logger.trace(`Requesting ping on ${this.serviceId} from ${this.peerId.toKey()}`)
54
+ logger.trace(`Requesting ping on ${this.getServiceId()} from ${this.getPeerId().toKey()}`)
58
55
  const request: PingRequest = {
59
56
  requestId: v4()
60
57
  }
61
- const options: DhtRpcOptions = {
62
- sourceDescriptor: this.ownPeerDescriptor,
63
- targetDescriptor: this.peerDescriptor,
58
+ const options = this.formDhtRpcOptions({
64
59
  timeout: 10000
65
- }
60
+ })
66
61
  try {
67
- const pong = await this.client.ping(request, options)
62
+ const pong = await this.getClient().ping(request, options)
68
63
  if (pong.requestId === request.requestId) {
69
64
  return true
70
65
  }
71
66
  } catch (err) {
72
- logger.trace(`ping failed on ${this.serviceId} to ${this.peerId.toKey()}: ${err}`)
67
+ logger.trace(`ping failed on ${this.getServiceId()} to ${this.getPeerId().toKey()}: ${err}`)
73
68
  }
74
69
  return false
75
70
  }
76
71
 
77
72
  leaveNotice(): void {
78
- logger.trace(`Sending leaveNotice on ${this.serviceId} from ${this.peerId.toKey()}`)
73
+ logger.trace(`Sending leaveNotice on ${this.getServiceId()} from ${this.getPeerId().toKey()}`)
79
74
  const request: LeaveNotice = {
80
- serviceId: this.serviceId
75
+ serviceId: this.getServiceId()
81
76
  }
82
- const options: DhtRpcOptions = {
83
- sourceDescriptor: this.ownPeerDescriptor,
84
- targetDescriptor: this.peerDescriptor,
77
+ const options = this.formDhtRpcOptions({
85
78
  notification: true
86
- }
87
- this.client.leaveNotice(request, options).catch((e) => {
79
+ })
80
+ this.getClient().leaveNotice(request, options).catch((e) => {
88
81
  logger.trace('Failed to send leaveNotice' + e)
89
82
  })
90
83
  }
91
-
92
- getPeerDescriptor(): PeerDescriptor {
93
- return this.peerDescriptor
94
- }
95
-
96
84
  }
@@ -1,5 +1,5 @@
1
- import { DhtRpcOptions } from '../exports'
2
- import { DataEntry, FindDataRequest } from '../proto/packages/dht/protos/DhtRpc'
1
+ import { Any } from '../proto/google/protobuf/any'
2
+ import { DataEntry, ExternalStoreDataRequest, FindDataRequest, PeerDescriptor } from '../proto/packages/dht/protos/DhtRpc'
3
3
  import { IExternalApiServiceClient } from '../proto/packages/dht/protos/DhtRpc.client'
4
4
  import { Remote } from './contact/Remote'
5
5
 
@@ -8,18 +8,32 @@ export class RemoteExternalApi extends Remote<IExternalApiServiceClient> {
8
8
  async findData(idToFind: Uint8Array): Promise<DataEntry[]> {
9
9
  const request: FindDataRequest = {
10
10
  kademliaId: idToFind,
11
- requestor: this.ownPeerDescriptor,
11
+ requestor: this.getLocalPeerDescriptor(),
12
12
  }
13
- const options: DhtRpcOptions = {
14
- sourceDescriptor: this.ownPeerDescriptor,
15
- targetDescriptor: this.peerDescriptor,
13
+ const options = this.formDhtRpcOptions({
16
14
  timeout: 10000
17
- }
15
+ })
18
16
  try {
19
- const data = await this.client.findData(request, options)
17
+ const data = await this.getClient().findData(request, options)
20
18
  return data.dataEntries
21
19
  } catch (err) {
22
20
  return []
23
21
  }
24
22
  }
23
+
24
+ async storeData(key: Uint8Array, data: Any): Promise<PeerDescriptor[]> {
25
+ const request: ExternalStoreDataRequest = {
26
+ key,
27
+ data
28
+ }
29
+ const options = this.formDhtRpcOptions({
30
+ timeout: 10000
31
+ })
32
+ try {
33
+ const response = await this.getClient().externalStoreData(request, options)
34
+ return response.storers
35
+ } catch (err) {
36
+ return []
37
+ }
38
+ }
25
39
  }
@@ -0,0 +1,45 @@
1
+ import { PeerID, PeerIDKey } from '../../helpers/PeerID'
2
+ import EventEmitter from 'eventemitter3'
3
+ import { Events, IContact, ContactState } from './Contact'
4
+
5
+ export class ContactList<C extends IContact> extends EventEmitter<Events> {
6
+
7
+ protected contactsById: Map<PeerIDKey, ContactState<C>> = new Map()
8
+ protected contactIds: PeerID[] = []
9
+ protected ownId: PeerID
10
+ protected maxSize: number
11
+ protected defaultContactQueryLimit
12
+
13
+ constructor(
14
+ ownId: PeerID,
15
+ maxSize: number,
16
+ defaultContactQueryLimit = 20
17
+ ) {
18
+ super()
19
+ this.ownId = ownId
20
+ this.maxSize = maxSize
21
+ this.defaultContactQueryLimit = defaultContactQueryLimit
22
+ }
23
+
24
+ public getContact(id: PeerID): ContactState<C> {
25
+ return this.contactsById.get(id.toKey())!
26
+ }
27
+
28
+ public hasContact(id: PeerID): boolean {
29
+ return this.contactsById.has(id.toKey())
30
+ }
31
+
32
+ public getSize(): number {
33
+ return this.contactIds.length
34
+ }
35
+
36
+ public clear(): void {
37
+ this.contactsById.clear()
38
+ this.contactIds = []
39
+ }
40
+
41
+ public stop(): void {
42
+ this.removeAllListeners()
43
+ this.clear()
44
+ }
45
+ }
@@ -1,29 +1,22 @@
1
- import { Events, IContact, ContactState } from './Contact'
1
+ import { PeerID } from '../../helpers/PeerID'
2
+ import { ContactState, IContact } from './Contact'
3
+ import { ContactList } from './ContactList'
2
4
 
3
- import EventEmitter from 'eventemitter3'
4
- import { PeerID, PeerIDKey } from '../../helpers/PeerID'
5
- export class RandomContactList<Contact extends IContact> extends EventEmitter<Events> {
6
- private contactsById: Map<PeerIDKey, ContactState<Contact>> = new Map()
7
- private contactIds: PeerID[] = []
8
- private ownId: PeerID
9
- private maxSize: number
10
- private randomness = 0.20
11
- private getContactsLimit = 20
5
+ export class RandomContactList<C extends IContact> extends ContactList<C> {
6
+
7
+ private randomness: number
12
8
 
13
9
  constructor(
14
10
  ownId: PeerID,
15
11
  maxSize: number,
16
12
  randomness = 0.20,
17
- getContactsLimit = 20
13
+ defaultContactQueryLimit?: number
18
14
  ) {
19
- super()
20
- this.ownId = ownId
21
- this.maxSize = maxSize
15
+ super(ownId, maxSize, defaultContactQueryLimit)
22
16
  this.randomness = randomness
23
- this.getContactsLimit = getContactsLimit
24
17
  }
25
18
 
26
- addContact(contact: Contact): void {
19
+ addContact(contact: C): void {
27
20
  if (this.ownId.equals(contact.getPeerId())) {
28
21
  return
29
22
  }
@@ -39,54 +32,36 @@ export class RandomContactList<Contact extends IContact> extends EventEmitter<Ev
39
32
  this.emit(
40
33
  'newContact',
41
34
  contact.getPeerDescriptor(),
42
- this.getContacts().map((contact: Contact) => contact.getPeerDescriptor())
35
+ this.getContacts().map((contact: C) => contact.getPeerDescriptor())
43
36
  )
44
37
  }
45
38
  }
46
39
  }
47
40
 
48
- addContacts(contacts: Contact[]): void {
41
+ addContacts(contacts: C[]): void {
49
42
  contacts.forEach((contact) => this.addContact(contact))
50
43
  }
51
44
 
52
45
  removeContact(id: PeerID): boolean {
53
46
  if (this.contactsById.has(id.toKey())) {
54
47
  const removedDescriptor = this.contactsById.get(id.toKey())!.contact.getPeerDescriptor()
55
- const index = this.contactIds.indexOf(id)
48
+ const index = this.contactIds.findIndex((element) => element.equals(id))
56
49
  this.contactIds.splice(index, 1)
57
50
  this.contactsById.delete(id.toKey())
58
- this.emit('contactRemoved', removedDescriptor, this.getContacts().map((contact: Contact) => contact.getPeerDescriptor()))
51
+ this.emit('contactRemoved', removedDescriptor, this.getContacts().map((contact: C) => contact.getPeerDescriptor()))
59
52
  return true
60
53
  }
61
54
  return false
62
55
  }
63
56
 
64
- public getSize(): number {
65
- return this.contactIds.length
66
- }
67
-
68
- public getContact(id: PeerID): ContactState<Contact> {
69
- return this.contactsById.get(id.toKey())!
70
- }
71
-
72
- public getContacts(limit = this.getContactsLimit): Contact[] {
73
- const ret: Contact[] = []
57
+ public getContacts(limit = this.defaultContactQueryLimit): C[] {
58
+ const ret: C[] = []
74
59
  this.contactIds.forEach((contactId) => {
75
60
  const contact = this.contactsById.get(contactId.toKey())
76
61
  if (contact) {
77
62
  ret.push(contact.contact)
78
63
  }
79
64
  })
80
- return ret.splice(0, limit)
81
- }
82
-
83
- public clear(): void {
84
- this.contactsById.clear()
85
- this.contactIds = []
86
- }
87
-
88
- public stop(): void {
89
- this.removeAllListeners()
90
- this.clear()
65
+ return ret.slice(0, limit)
91
66
  }
92
67
  }
@@ -3,38 +3,54 @@ import { ProtoRpcClient } from '@streamr/proto-rpc'
3
3
  import { peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
4
4
  import { PeerID } from '../../helpers/PeerID'
5
5
  import { IContact } from './Contact'
6
+ import { DhtRpcOptions } from '../../rpc-protocol/DhtRpcOptions'
6
7
 
7
8
  export abstract class Remote<T> implements IContact {
8
9
 
9
- protected readonly peerId: PeerID
10
- protected readonly peerDescriptor: PeerDescriptor
11
- protected readonly client: ProtoRpcClient<T>
12
- protected readonly serviceId: string
13
- protected readonly ownPeerDescriptor: PeerDescriptor
10
+ private readonly localPeerDescriptor: PeerDescriptor
11
+ private readonly remotePeerId: PeerID
12
+ private readonly remotePeerDescriptor: PeerDescriptor
13
+ private readonly serviceId: string
14
+ private readonly client: ProtoRpcClient<T>
14
15
 
15
16
  constructor(
16
- ownPeerDescriptor: PeerDescriptor,
17
- peerDescriptor: PeerDescriptor,
18
- client: ProtoRpcClient<T>,
19
- serviceId: string
17
+ localPeerDescriptor: PeerDescriptor,
18
+ remotePeerDescriptor: PeerDescriptor,
19
+ serviceId: string,
20
+ client: ProtoRpcClient<T>
20
21
  ) {
21
- this.ownPeerDescriptor = ownPeerDescriptor
22
- this.peerId = peerIdFromPeerDescriptor(peerDescriptor)
23
- this.peerDescriptor = peerDescriptor
22
+ this.localPeerDescriptor = localPeerDescriptor
23
+ this.remotePeerId = peerIdFromPeerDescriptor(remotePeerDescriptor)
24
+ this.remotePeerDescriptor = remotePeerDescriptor
24
25
  this.client = client
25
26
  this.serviceId = serviceId
26
27
  }
27
28
 
28
29
  getPeerId(): PeerID {
29
- return this.peerId
30
+ return this.remotePeerId
30
31
  }
31
32
 
32
33
  getPeerDescriptor(): PeerDescriptor {
33
- return this.peerDescriptor
34
+ return this.remotePeerDescriptor
35
+ }
36
+
37
+ getLocalPeerDescriptor(): PeerDescriptor {
38
+ return this.localPeerDescriptor
34
39
  }
35
40
 
36
41
  getServiceId(): string {
37
42
  return this.serviceId
38
43
  }
39
44
 
45
+ getClient(): ProtoRpcClient<T> {
46
+ return this.client
47
+ }
48
+
49
+ formDhtRpcOptions(opts?: Omit<DhtRpcOptions, 'sourceDescriptor' | 'targetDescriptor'>): DhtRpcOptions {
50
+ return {
51
+ sourceDescriptor: this.localPeerDescriptor,
52
+ targetDescriptor: this.remotePeerDescriptor,
53
+ ...opts
54
+ }
55
+ }
40
56
  }