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

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 (52) hide show
  1. package/dist/src/connection/ConnectionManager.d.ts +1 -0
  2. package/dist/src/connection/ConnectionManager.js +14 -2
  3. package/dist/src/connection/ConnectionManager.js.map +1 -1
  4. package/dist/src/dht/DhtNode.d.ts +1 -3
  5. package/dist/src/dht/DhtNode.js +12 -11
  6. package/dist/src/dht/DhtNode.js.map +1 -1
  7. package/dist/src/dht/DhtPeer.d.ts +2 -0
  8. package/dist/src/dht/DhtPeer.js +4 -0
  9. package/dist/src/dht/DhtPeer.js.map +1 -1
  10. package/dist/src/dht/contact/Contact.d.ts +1 -15
  11. package/dist/src/dht/contact/Contact.js +1 -9
  12. package/dist/src/dht/contact/Contact.js.map +1 -1
  13. package/dist/src/dht/contact/ContactList.d.ts +13 -2
  14. package/dist/src/dht/contact/ContactList.js +9 -1
  15. package/dist/src/dht/contact/ContactList.js.map +1 -1
  16. package/dist/src/dht/contact/RandomContactList.d.ts +3 -2
  17. package/dist/src/dht/contact/RandomContactList.js +4 -5
  18. package/dist/src/dht/contact/RandomContactList.js.map +1 -1
  19. package/dist/src/dht/contact/Remote.d.ts +1 -5
  20. package/dist/src/dht/contact/Remote.js +0 -5
  21. package/dist/src/dht/contact/Remote.js.map +1 -1
  22. package/dist/src/dht/contact/SortedContactList.d.ts +3 -2
  23. package/dist/src/dht/contact/SortedContactList.js +9 -10
  24. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  25. package/dist/src/dht/routing/RemoteRouter.js +3 -3
  26. package/dist/src/dht/routing/RemoteRouter.js.map +1 -1
  27. package/dist/src/dht/routing/RoutingSession.d.ts +0 -1
  28. package/dist/src/dht/routing/RoutingSession.js +15 -10
  29. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  30. package/dist/src/exports.d.ts +0 -1
  31. package/dist/src/exports.js +1 -3
  32. package/dist/src/exports.js.map +1 -1
  33. package/package.json +4 -4
  34. package/src/connection/ConnectionManager.ts +16 -3
  35. package/src/dht/DhtNode.ts +17 -16
  36. package/src/dht/DhtPeer.ts +5 -0
  37. package/src/dht/contact/Contact.ts +1 -18
  38. package/src/dht/contact/ContactList.ts +16 -2
  39. package/src/dht/contact/RandomContactList.ts +6 -7
  40. package/src/dht/contact/Remote.ts +1 -10
  41. package/src/dht/contact/SortedContactList.ts +12 -13
  42. package/src/dht/find/RecursiveFinder.ts +1 -1
  43. package/src/dht/routing/RemoteRouter.ts +3 -3
  44. package/src/dht/routing/RoutingSession.ts +29 -20
  45. package/src/exports.ts +0 -1
  46. package/test/benchmark/KademliaCorrectness.test.ts +2 -1
  47. package/test/end-to-end/Layer0-Layer1.test.ts +10 -10
  48. package/test/integration/DhtWithMockConnectionLatencies.test.ts +1 -1
  49. package/test/integration/DhtWithMockConnections.test.ts +1 -1
  50. package/test/integration/DhtWithRealConnectionLatencies.test.ts +1 -1
  51. package/test/unit/RandomContactList.test.ts +26 -75
  52. package/test/unit/SortedContactList.test.ts +62 -112
@@ -237,7 +237,7 @@ export class RecursiveFinder implements IRecursiveFinder {
237
237
 
238
238
  private getClosestConnections(kademliaId: Uint8Array, limit: number): PeerDescriptor[] {
239
239
  const connectedPeers = Array.from(this.connections.values())
240
- const closestPeers = new SortedContactList(
240
+ const closestPeers = new SortedContactList<DhtPeer>(
241
241
  PeerID.fromValue(kademliaId),
242
242
  limit,
243
243
  undefined,
@@ -40,7 +40,7 @@ export class RemoteRouter extends Remote<IRoutingServiceClient> {
40
40
  } catch (err) {
41
41
  const fromNode = params.previousPeer ?
42
42
  peerIdFromPeerDescriptor(params.previousPeer) : keyFromPeerDescriptor(params.sourcePeer!)
43
- logger.trace(`Failed to send routeMessage from ${fromNode} to ${this.getPeerId().toKey()} with: ${err}`)
43
+ logger.trace(`Failed to send routeMessage from ${fromNode} to ${keyFromPeerDescriptor(this.getPeerDescriptor())} with: ${err}`)
44
44
  return false
45
45
  }
46
46
  return true
@@ -69,7 +69,7 @@ export class RemoteRouter extends Remote<IRoutingServiceClient> {
69
69
  keyFromPeerDescriptor(params.previousPeer) : keyFromPeerDescriptor(params.sourcePeer!)
70
70
 
71
71
  logger.trace(
72
- `Failed to send forwardMessage from ${fromNode} to ${this.getPeerId().toKey()} with: ${err}`
72
+ `Failed to send forwardMessage from ${fromNode} to ${keyFromPeerDescriptor(this.getPeerDescriptor())} with: ${err}`
73
73
  )
74
74
  return false
75
75
  }
@@ -97,7 +97,7 @@ export class RemoteRouter extends Remote<IRoutingServiceClient> {
97
97
  }
98
98
  } catch (err) {
99
99
  const fromNode = params.previousPeer ? keyFromPeerDescriptor(params.previousPeer) : keyFromPeerDescriptor(params.sourcePeer!)
100
- logger.debug(`Failed to send recursiveFind message from ${fromNode} to ${this.getPeerId().toKey()} with: ${err}`)
100
+ logger.debug(`Failed to send recursiveFind message from ${fromNode} to ${keyFromPeerDescriptor(this.getPeerDescriptor())} with: ${err}`)
101
101
  return false
102
102
  }
103
103
  return true
@@ -10,11 +10,31 @@ import { RemoteRouter } from './RemoteRouter'
10
10
  import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
11
11
  import { RoutingServiceClient } from '../../proto/packages/dht/protos/DhtRpc.client'
12
12
  import { toProtoRpcClient } from '@streamr/proto-rpc'
13
+ import { Contact } from '../contact/Contact'
13
14
 
14
15
  const logger = new Logger(module)
15
16
 
16
17
  const MAX_FAILED_HOPS = 2
17
18
 
19
+ class RemoteContact extends Contact {
20
+
21
+ private router: RemoteRouter
22
+
23
+ constructor(peer: DhtPeer, ownPeerDescriptor: PeerDescriptor, rpcCommunicator: RoutingRpcCommunicator) {
24
+ super(peer.getPeerDescriptor())
25
+ this.router = new RemoteRouter(
26
+ ownPeerDescriptor,
27
+ peer.getPeerDescriptor(),
28
+ peer.getServiceId(),
29
+ toProtoRpcClient(new RoutingServiceClient(rpcCommunicator.getRpcClientTransport()))
30
+ )
31
+ }
32
+
33
+ getRouter(): RemoteRouter {
34
+ return this.router
35
+ }
36
+ }
37
+
18
38
  export interface RoutingSessionEvents {
19
39
  // This event is emitted when a peer responds with a success ack
20
40
  // to routeMessage call
@@ -35,7 +55,7 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
35
55
  public readonly sessionId = v4()
36
56
  private readonly rpcCommunicator: RoutingRpcCommunicator
37
57
  private ongoingRequests: Set<PeerIDKey> = new Set()
38
- private contactList: SortedContactList<RemoteRouter>
58
+ private contactList: SortedContactList<RemoteContact>
39
59
  private readonly ownPeerDescriptor: PeerDescriptor
40
60
  private readonly messageToRoute: RouteMessageWrapper
41
61
  private connections: Map<PeerIDKey, DhtPeer>
@@ -117,51 +137,40 @@ export class RoutingSession extends EventEmitter<RoutingSessionEvents> {
117
137
  }
118
138
  }
119
139
 
120
- private sendRouteMessageRequest = async (contact: RemoteRouter): Promise<boolean> => {
140
+ private sendRouteMessageRequest = async (contact: RemoteContact): Promise<boolean> => {
121
141
  if (this.stopped) {
122
142
  return false
123
143
  }
144
+ const router = contact.getRouter()
124
145
  if (this.mode === RoutingMode.FORWARD) {
125
- return contact.forwardMessage({
146
+ return router.forwardMessage({
126
147
  ...this.messageToRoute,
127
148
  previousPeer: this.ownPeerDescriptor
128
149
  })
129
150
  } else if (this.mode === RoutingMode.RECURSIVE_FIND) {
130
- return contact.findRecursively({
151
+ return router.findRecursively({
131
152
  ...this.messageToRoute,
132
153
  previousPeer: this.ownPeerDescriptor
133
154
  })
134
155
  } else {
135
- return contact.routeMessage({
156
+ return router.routeMessage({
136
157
  ...this.messageToRoute,
137
158
  previousPeer: this.ownPeerDescriptor
138
159
  })
139
160
  }
140
161
  }
141
162
 
142
- private findMoreContacts = (): RemoteRouter[] => {
163
+ private findMoreContacts = (): RemoteContact[] => {
143
164
  logger.trace('findMoreContacts() sessionId: ' + this.sessionId)
144
165
  // the contents of the connections might have changed between the rounds
145
166
  // addContacts() will only add new contacts that were not there yet
146
167
  const contacts = Array.from(this.connections.values())
147
- .map((contact) => {
148
- return new RemoteRouter(
149
- this.ownPeerDescriptor,
150
- contact.getPeerDescriptor(),
151
- contact.getServiceId(),
152
- toProtoRpcClient(new RoutingServiceClient(this.rpcCommunicator.getRpcClientTransport()))
153
- )
154
- })
168
+ .map((peer) => new RemoteContact(peer, this.ownPeerDescriptor, this.rpcCommunicator))
155
169
  this.contactList.addContacts(contacts)
156
170
  return this.contactList.getUncontactedContacts(this.parallelism)
157
171
  }
158
172
 
159
- public getClosestContacts = (limit: number): PeerDescriptor[] => {
160
- const contacts = this.contactList.getClosestContacts(limit)
161
- return contacts.map((contact) => contact.getPeerDescriptor())
162
- }
163
-
164
- private sendMoreRequests = (uncontacted: RemoteRouter[]) => {
173
+ private sendMoreRequests = (uncontacted: RemoteContact[]) => {
165
174
  logger.trace('sendMoreRequests() sessionId: ' + this.sessionId)
166
175
  if (this.stopped) {
167
176
  return
package/src/exports.ts CHANGED
@@ -7,7 +7,6 @@ export { PeerDescriptor, Message, NodeType, DataEntry } from './proto/packages/d
7
7
  export { ITransport } from './transport/ITransport'
8
8
  export { ConnectionManager, ConnectionLocker, PortRange, TlsCertificate } from './connection/ConnectionManager'
9
9
  export { PeerID, PeerIDKey } from './helpers/PeerID'
10
- export { DhtPeer } from './dht/DhtPeer'
11
10
  export { UUID } from './helpers/UUID'
12
11
  export { DhtRpcOptions } from './rpc-protocol/DhtRpcOptions'
13
12
  export { protoClasses } from './helpers/protoClasses'
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable no-console */
2
2
  import { Simulator } from '../../src/connection/Simulator/Simulator'
3
3
  import { DhtNode } from '../../src/dht/DhtNode'
4
+ import { PeerID } from '../../src/exports'
4
5
  import { NodeType, PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
5
6
  import { createMockConnectionDhtNode } from '../utils/utils'
6
7
  import { execSync } from 'child_process'
@@ -70,7 +71,7 @@ describe('Kademlia correctness', () => {
70
71
  groundTruthString += groundTruth[i + ''][j].name + ','
71
72
  }
72
73
 
73
- const kademliaNeighbors = nodes[i].getNeighborList().getContactIds()
74
+ const kademliaNeighbors = nodes[i].getClosestContacts().map((p) => PeerID.fromValue(p.kademliaId))
74
75
 
75
76
  let kadString = 'kademliaNeighbors: '
76
77
  kademliaNeighbors.forEach((neighbor) => {
@@ -1,6 +1,6 @@
1
1
  import { NodeType, PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
2
2
  import { DhtNode } from '../../src/dht/DhtNode'
3
- import { peerIdFromPeerDescriptor } from '../../src/helpers/peerIdFromPeerDescriptor'
3
+ import { isSamePeerDescriptor } from '../../src/helpers/peerIdFromPeerDescriptor'
4
4
 
5
5
  describe('Layer0-Layer1', () => {
6
6
  const epPeerDescriptor: PeerDescriptor = {
@@ -76,14 +76,14 @@ describe('Layer0-Layer1', () => {
76
76
  stream2Node1.joinDht([epPeerDescriptor]),
77
77
  stream2Node2.joinDht([epPeerDescriptor])
78
78
  ])
79
- expect(stream1Node1.getNeighborList().getSize()).toEqual(1)
80
- expect(stream1Node2.getNeighborList().getSize()).toEqual(1)
81
- expect(stream2Node1.getNeighborList().getSize()).toEqual(1)
82
- expect(stream2Node2.getNeighborList().getSize()).toEqual(1)
83
-
84
- expect(stream1Node1.getNeighborList().getContactIds()[0].equals(peerIdFromPeerDescriptor(node1.getPeerDescriptor()))).toEqual(true)
85
- expect(stream1Node2.getNeighborList().getContactIds()[0].equals(peerIdFromPeerDescriptor(epPeerDescriptor))).toEqual(true)
86
- expect(stream2Node1.getNeighborList().getContactIds()[0].equals(peerIdFromPeerDescriptor(node2.getPeerDescriptor()))).toEqual(true)
87
- expect(stream2Node2.getNeighborList().getContactIds()[0].equals(peerIdFromPeerDescriptor(epPeerDescriptor))).toEqual(true)
79
+ expect(stream1Node1.getClosestContacts()).toHaveLength(1)
80
+ expect(stream1Node2.getClosestContacts()).toHaveLength(1)
81
+ expect(stream2Node1.getClosestContacts()).toHaveLength(1)
82
+ expect(stream2Node2.getClosestContacts()).toHaveLength(1)
83
+
84
+ expect(isSamePeerDescriptor(stream1Node1.getClosestContacts()[0], node1.getPeerDescriptor())).toBe(true)
85
+ expect(isSamePeerDescriptor(stream1Node2.getClosestContacts()[0], epPeerDescriptor)).toBe(true)
86
+ expect(isSamePeerDescriptor(stream2Node1.getClosestContacts()[0], node2.getPeerDescriptor())).toBe(true)
87
+ expect(isSamePeerDescriptor(stream2Node2.getClosestContacts()[0], epPeerDescriptor)).toBe(true)
88
88
  })
89
89
  })
@@ -39,7 +39,7 @@ describe('Mock connection Dht joining with latencies', () => {
39
39
  await Promise.all(nodes.map((node) => node.joinDht([entrypointDescriptor])))
40
40
  nodes.forEach((node) => {
41
41
  expect(node.getBucketSize()).toBeGreaterThanOrEqual(node.getK() - 2)
42
- expect(node.getNeighborList().getSize()).toBeGreaterThanOrEqual(node.getK() - 2)
42
+ expect(node.getClosestContacts().length).toBeGreaterThanOrEqual(node.getK() - 2)
43
43
  })
44
44
  expect(entryPoint.getBucketSize()).toBeGreaterThanOrEqual(entryPoint.getK() - 2)
45
45
  }, 60 * 1000)
@@ -39,7 +39,7 @@ describe('Mock IConnection DHT Joining', () => {
39
39
  await Promise.all(nodes.map((node) => node.joinDht([entrypointDescriptor])))
40
40
  nodes.forEach((node) => {
41
41
  expect(node.getBucketSize()).toBeGreaterThanOrEqual(node.getK() - 2)
42
- expect(node.getNeighborList().getSize()).toBeGreaterThanOrEqual(node.getK() - 2)
42
+ expect(node.getClosestContacts().length).toBeGreaterThanOrEqual(node.getK() - 2)
43
43
  })
44
44
  expect(entryPoint.getBucketSize()).toBeGreaterThanOrEqual(entryPoint.getK() - 2)
45
45
  }, 60000)
@@ -40,7 +40,7 @@ describe('Mock connection Dht joining with real latencies', () => {
40
40
  await Promise.all(nodes.map((node) => node.joinDht([entrypointDescriptor])))
41
41
  nodes.forEach((node) => {
42
42
  expect(node.getBucketSize()).toBeGreaterThanOrEqual(node.getK() - 3)
43
- expect(node.getNeighborList().getSize()).toBeGreaterThanOrEqual(node.getK() - 3)
43
+ expect(node.getClosestContacts().length).toBeGreaterThanOrEqual(node.getK() - 3)
44
44
  })
45
45
  expect(entryPoint.getBucketSize()).toBeGreaterThanOrEqual(entryPoint.getK())
46
46
  }, 60 * 1000)
@@ -1,92 +1,43 @@
1
1
  import { RandomContactList } from '../../src/dht/contact/RandomContactList'
2
- import type { ServiceInfo, MethodInfo } from '@protobuf-ts/runtime-rpc'
3
- import { PeerID } from '../../src/helpers/PeerID'
4
- import { toProtoRpcClient } from '@streamr/proto-rpc'
5
- import { IDhtRpcServiceClient } from '../../src/proto/packages/dht/protos/DhtRpc.client'
6
- import { LeaveNotice, NodeType, PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
7
- import type { FindDataRequest, FindDataResponse, PingResponse } from '../../src/proto/packages/dht/protos/DhtRpc'
8
- import type { PingRequest } from '../../src/proto/packages/dht/protos/DhtRpc'
9
- import type { ClosestPeersResponse } from '../../src/proto/packages/dht/protos/DhtRpc'
10
- import type { ClosestPeersRequest } from '../../src/proto/packages/dht/protos/DhtRpc'
11
- import { UnaryCall } from '@protobuf-ts/runtime-rpc'
12
- import type { RpcOptions } from '@protobuf-ts/runtime-rpc'
13
- import { DhtPeer } from '../../src/dht/DhtPeer'
14
- import { IMessageType } from '@protobuf-ts/runtime'
15
- import { Empty } from '../../src/proto/google/protobuf/empty'
2
+ import { PeerID } from '../../src/exports'
16
3
 
17
- class MockRpcClient implements IDhtRpcServiceClient, ServiceInfo {
18
- typeName = 'MockRpcClient'
19
- methods: MethodInfo<any, any> [] = [
20
- { name: 'getClosestPeers', O: {} as IMessageType<ClosestPeersResponse> } as MethodInfo<any, any>,
21
- { name: 'ping', O: {} as IMessageType<PingResponse> } as MethodInfo<any, any>,
22
- { name: 'findData', O: {} as IMessageType<FindDataRequest> } as MethodInfo<any, any>,
23
- { name: 'leaveNotice', O: {} as IMessageType<Empty> } as MethodInfo<any, any>
24
- ]
25
- options = {}
26
-
27
- // eslint-disable-next-line class-methods-use-this
28
- getClosestPeers(_input: ClosestPeersRequest, _options?: RpcOptions): UnaryCall<ClosestPeersRequest, ClosestPeersResponse> {
29
- return {} as UnaryCall<ClosestPeersRequest, ClosestPeersResponse>
30
- }
31
-
32
- // eslint-disable-next-line class-methods-use-this
33
- ping(_input: PingRequest, _options?: RpcOptions): UnaryCall <PingRequest, PingResponse> {
34
- return {} as UnaryCall<PingRequest, PingResponse>
35
- }
36
-
37
- // eslint-disable-next-line class-methods-use-this
38
- findData(_input: FindDataRequest, _options?: RpcOptions): UnaryCall<FindDataRequest, FindDataResponse> {
39
- return {} as UnaryCall<FindDataRequest, FindDataResponse>
40
- }
41
-
42
- // eslint-disable-next-line class-methods-use-this
43
- leaveNotice(_input: LeaveNotice, _options?: RpcOptions): UnaryCall<LeaveNotice, Empty> {
44
- return {} as UnaryCall<LeaveNotice, Empty>
45
- }
46
- }
47
-
48
- const getId = (descriptor: PeerDescriptor): PeerID => {
49
- return PeerID.fromValue(descriptor.kademliaId)
4
+ const createItem = (kademliaId: Uint8Array): { getPeerId: () => PeerID } => {
5
+ return { getPeerId: () => PeerID.fromValue(kademliaId) }
50
6
  }
51
7
 
52
8
  describe('RandomContactList', () => {
53
- const serviceId = 'random'
54
- const descriptor0: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 0]), type: NodeType.NODEJS }
55
- const descriptor1: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 1]), type: NodeType.NODEJS }
56
- const descriptor2: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 2]), type: NodeType.NODEJS }
57
- const descriptor3: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 3]), type: NodeType.NODEJS }
58
- const descriptor4: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 4]), type: NodeType.NODEJS }
59
- const peer1 = new DhtPeer(descriptor0, descriptor1, toProtoRpcClient(new MockRpcClient()), serviceId)
60
- const peer2 = new DhtPeer(descriptor0, descriptor2, toProtoRpcClient(new MockRpcClient()), serviceId)
61
- const peer3 = new DhtPeer(descriptor0, descriptor3, toProtoRpcClient(new MockRpcClient()), serviceId)
62
- const peer4 = new DhtPeer(descriptor0, descriptor4, toProtoRpcClient(new MockRpcClient()), serviceId)
9
+ const item0 = createItem(new Uint8Array([0, 0, 0, 0]))
10
+ const item1 = createItem(new Uint8Array([0, 0, 0, 1]))
11
+ const item2 = createItem(new Uint8Array([0, 0, 0, 2]))
12
+ const item3 = createItem(new Uint8Array([0, 0, 0, 3]))
13
+ const item4 = createItem(new Uint8Array([0, 0, 0, 4]))
63
14
 
64
15
  it('adds contacts correctly', () => {
65
- const list = new RandomContactList(getId(descriptor0), 5, 1)
66
- list.addContact(peer1)
67
- list.addContact(peer2)
68
- list.addContact(peer3)
69
- list.addContact(peer3)
70
- list.addContact(peer4)
71
- list.addContact(peer4)
16
+ const list = new RandomContactList(item0.getPeerId(), 5, 1)
17
+ list.addContact(item1)
18
+ list.addContact(item2)
19
+ list.addContact(item3)
20
+ list.addContact(item3)
21
+ list.addContact(item4)
22
+ list.addContact(item4)
72
23
  expect(list.getSize()).toEqual(4)
73
24
  expect(list.getContacts()).toEqual(
74
- [peer1, peer2, peer3, peer4]
25
+ [item1, item2, item3, item4]
75
26
  )
76
27
  })
77
28
 
78
29
  it('removes contacts correctly', () => {
79
- const list = new RandomContactList(getId(descriptor0), 5, 1)
80
- list.addContact(peer1)
81
- list.addContact(peer2)
82
- list.addContact(peer3)
83
- list.addContact(peer4)
84
- list.removeContact(getId(descriptor2))
85
- expect(list.getContact(getId(descriptor1))).toBeTruthy()
86
- expect(list.getContact(getId(descriptor3))).toBeTruthy()
87
- expect(list.getContact(getId(descriptor4))).toBeTruthy()
30
+ const list = new RandomContactList(item0.getPeerId(), 5, 1)
31
+ list.addContact(item1)
32
+ list.addContact(item2)
33
+ list.addContact(item3)
34
+ list.addContact(item4)
35
+ list.removeContact(item2.getPeerId())
36
+ expect(list.getContact(item1.getPeerId())).toBeTruthy()
37
+ expect(list.getContact(item3.getPeerId())).toBeTruthy()
38
+ expect(list.getContact(item4.getPeerId())).toBeTruthy()
88
39
  expect(list.getContacts()).toEqual(
89
- [peer1, peer3, peer4]
40
+ [item1, item3, item4]
90
41
  )
91
42
  expect(list.getSize()).toEqual(3)
92
43
  })
@@ -1,153 +1,103 @@
1
1
  import { SortedContactList } from '../../src/dht/contact/SortedContactList'
2
- import type { ServiceInfo, MethodInfo } from '@protobuf-ts/runtime-rpc'
3
2
  import { PeerID } from '../../src/helpers/PeerID'
4
- import { toProtoRpcClient } from '@streamr/proto-rpc'
5
- import { IDhtRpcServiceClient } from '../../src/proto/packages/dht/protos/DhtRpc.client'
6
- import { LeaveNotice, NodeType, PeerDescriptor, RouteMessageAck } from '../../src/proto/packages/dht/protos/DhtRpc'
7
- import type { FindDataRequest, FindDataResponse, PingResponse } from '../../src/proto/packages/dht/protos/DhtRpc'
8
- import type { PingRequest } from '../../src/proto/packages/dht/protos/DhtRpc'
9
- import type { ClosestPeersResponse } from '../../src/proto/packages/dht/protos/DhtRpc'
10
- import type { ClosestPeersRequest } from '../../src/proto/packages/dht/protos/DhtRpc'
11
- import { UnaryCall } from '@protobuf-ts/runtime-rpc'
12
- import type { RpcOptions } from '@protobuf-ts/runtime-rpc'
13
- import { DhtPeer } from '../../src/dht/DhtPeer'
14
- import { IMessageType } from '@protobuf-ts/runtime'
15
- import { Empty } from '../../src/proto/google/protobuf/empty'
16
3
 
17
- /* eslint-disable class-methods-use-this */
18
- class MockRpcClient implements IDhtRpcServiceClient, ServiceInfo {
19
- typeName = 'MockRpcClient'
20
- methods: MethodInfo<any, any> [] = [
21
- { name: 'getClosestPeers', O: {} as IMessageType<ClosestPeersResponse> } as MethodInfo<any, any>,
22
- { name: 'ping', O: {} as IMessageType<PingResponse> } as MethodInfo<any, any>,
23
- { name: 'findData', O: {} as IMessageType<RouteMessageAck> } as MethodInfo<any, any>,
24
- { name: 'leaveNotice', O: {} as IMessageType<Empty> } as MethodInfo<any, any>
25
- ]
26
- options = {}
27
- getClosestPeers(_input: ClosestPeersRequest, _options?: RpcOptions): UnaryCall<ClosestPeersRequest, ClosestPeersResponse> {
28
- return {} as UnaryCall<ClosestPeersRequest, ClosestPeersResponse>
29
- }
30
- ping(_input: PingRequest, _options?: RpcOptions): UnaryCall <PingRequest, PingResponse> {
31
- return {} as UnaryCall<PingRequest, PingResponse>
32
- }
33
-
34
- // eslint-disable-next-line class-methods-use-this
35
- findData(_input: FindDataRequest, _options?: RpcOptions): UnaryCall<FindDataRequest, FindDataResponse> {
36
- return {} as UnaryCall<FindDataRequest, FindDataResponse>
37
- }
38
-
39
- leaveNotice(_input: LeaveNotice, _options?: RpcOptions): UnaryCall<LeaveNotice, Empty> {
40
- return {} as UnaryCall<LeaveNotice, Empty>
41
- }
42
- }
43
-
44
- const getId = (descriptor: PeerDescriptor): PeerID => {
45
- return PeerID.fromValue(descriptor.kademliaId)
4
+ const createItem = (kademliaId: Uint8Array): { getPeerId: () => PeerID } => {
5
+ return { getPeerId: () => PeerID.fromValue(kademliaId) }
46
6
  }
47
7
 
48
8
  describe('SortedContactList', () => {
49
- const serviceId = 'sorted'
50
- const descriptor0: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 0]), type: NodeType.NODEJS }
51
- const descriptor1: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 1]), type: NodeType.NODEJS }
52
- const descriptor2: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 2]), type: NodeType.NODEJS }
53
- const descriptor3: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 3]), type: NodeType.NODEJS }
54
- const descriptor4: PeerDescriptor = { kademliaId: new Uint8Array([0, 0, 0, 4]), type: NodeType.NODEJS }
55
- const peer1 = new DhtPeer(descriptor0, descriptor1, toProtoRpcClient(new MockRpcClient()), serviceId)
56
- const peer2 = new DhtPeer(descriptor0, descriptor2, toProtoRpcClient(new MockRpcClient()), serviceId)
57
- const peer3 = new DhtPeer(descriptor0, descriptor3, toProtoRpcClient(new MockRpcClient()), serviceId)
58
- const peer4 = new DhtPeer(descriptor0, descriptor4, toProtoRpcClient(new MockRpcClient()), serviceId)
9
+ const item0 = createItem(new Uint8Array([0, 0, 0, 0]))
10
+ const item1 = createItem(new Uint8Array([0, 0, 0, 1]))
11
+ const item2 = createItem(new Uint8Array([0, 0, 0, 2]))
12
+ const item3 = createItem(new Uint8Array([0, 0, 0, 3]))
13
+ const item4 = createItem(new Uint8Array([0, 0, 0, 4]))
59
14
 
60
15
  it('compares Ids correctly', async () => {
61
- const list = new SortedContactList(getId(descriptor0), 10)
62
- expect(list.compareIds(getId(descriptor0), getId(descriptor0))).toBe(0)
63
- expect(list.compareIds(getId(descriptor1), getId(descriptor1))).toBe(0)
64
- expect(list.compareIds(getId(descriptor0), getId(descriptor1))).toBe(-1)
65
- expect(list.compareIds(getId(descriptor0), getId(descriptor2))).toBe(-2)
66
- expect(list.compareIds(getId(descriptor1), getId(descriptor0))).toBe(1)
67
- expect(list.compareIds(getId(descriptor2), getId(descriptor0))).toBe(2)
68
- expect(list.compareIds(getId(descriptor2), getId(descriptor3))).toBe(-1)
69
- expect(list.compareIds(getId(descriptor1), getId(descriptor4))).toBe(-3)
16
+ const list = new SortedContactList(item0.getPeerId(), 10)
17
+ expect(list.compareIds(item0.getPeerId(), item0.getPeerId())).toBe(0)
18
+ expect(list.compareIds(item1.getPeerId(), item1.getPeerId())).toBe(0)
19
+ expect(list.compareIds(item0.getPeerId(), item1.getPeerId())).toBe(-1)
20
+ expect(list.compareIds(item0.getPeerId(), item2.getPeerId())).toBe(-2)
21
+ expect(list.compareIds(item1.getPeerId(), item0.getPeerId())).toBe(1)
22
+ expect(list.compareIds(item2.getPeerId(), item0.getPeerId())).toBe(2)
23
+ expect(list.compareIds(item2.getPeerId(), item3.getPeerId())).toBe(-1)
24
+ expect(list.compareIds(item1.getPeerId(), item4.getPeerId())).toBe(-3)
70
25
  })
71
26
 
72
27
  it('orders itself correctly', async () => {
73
-
74
- const list = new SortedContactList(getId(descriptor0), 10)
75
-
76
- list.addContact(peer3)
77
- list.addContact(peer2)
78
- list.addContact(peer1)
79
-
28
+ const list = new SortedContactList(item0.getPeerId(), 10)
29
+ list.addContact(item3)
30
+ list.addContact(item2)
31
+ list.addContact(item1)
80
32
  const contacts = list.getUncontactedContacts(3)
81
33
  expect(contacts.length).toEqual(3)
82
- expect(contacts[0]).toEqual(peer1)
83
- expect(contacts[1]).toEqual(peer2)
84
- expect(contacts[2]).toEqual(peer3)
34
+ expect(contacts[0]).toEqual(item1)
35
+ expect(contacts[1]).toEqual(item2)
36
+ expect(contacts[2]).toEqual(item3)
85
37
  })
86
38
 
87
39
  it('handles contacted nodes correctly', async () => {
88
- const list = new SortedContactList(getId(descriptor0), 10)
89
-
90
- list.addContact(peer3)
91
- list.addContact(peer2)
92
- list.addContact(peer1)
93
-
94
- list.setContacted(getId(descriptor2))
40
+ const list = new SortedContactList(item0.getPeerId(), 10)
41
+ list.addContact(item3)
42
+ list.addContact(item2)
43
+ list.addContact(item1)
44
+ list.setContacted(item2.getPeerId())
95
45
  const contacts = list.getUncontactedContacts(3)
96
46
  expect(contacts.length).toEqual(2)
97
- expect(contacts[0]).toEqual(peer1)
98
- expect(contacts[1]).toEqual(peer3)
47
+ expect(contacts[0]).toEqual(item1)
48
+ expect(contacts[1]).toEqual(item3)
99
49
  })
100
50
 
101
51
  it('cannot exceed maxSize', async () => {
102
- const list = new SortedContactList(getId(descriptor0), 3)
52
+ const list = new SortedContactList(item0.getPeerId(), 3)
103
53
  const onContactRemoved = jest.fn()
104
54
  list.on('contactRemoved', onContactRemoved)
105
- list.addContact(peer1)
106
- list.addContact(peer4)
107
- list.addContact(peer3)
108
- list.addContact(peer2)
55
+ list.addContact(item1)
56
+ list.addContact(item4)
57
+ list.addContact(item3)
58
+ list.addContact(item2)
109
59
  expect(list.getSize()).toEqual(3)
110
- expect(onContactRemoved).toBeCalledWith(descriptor4, [descriptor1, descriptor2, descriptor3])
111
- expect(list.getContact(getId(descriptor4))).toBeFalsy()
60
+ expect(onContactRemoved).toBeCalledWith(item4, [item1, item2, item3])
61
+ expect(list.getContact(item4.getPeerId())).toBeFalsy()
112
62
  })
113
63
 
114
64
  it('removing contacts', async () => {
115
- const list = new SortedContactList(getId(descriptor0), 8)
65
+ const list = new SortedContactList(item0.getPeerId(), 8)
116
66
  const onContactRemoved = jest.fn()
117
67
  list.on('contactRemoved', onContactRemoved)
118
- list.addContact(peer4)
119
- list.addContact(peer3)
120
- list.addContact(peer2)
121
- list.addContact(peer1)
122
- list.removeContact(getId(descriptor2))
68
+ list.addContact(item4)
69
+ list.addContact(item3)
70
+ list.addContact(item2)
71
+ list.addContact(item1)
72
+ list.removeContact(item2.getPeerId())
123
73
  expect(list.getSize()).toEqual(3)
124
- expect(list.getContact(getId(descriptor2))).toBeFalsy()
74
+ expect(list.getContact(item2.getPeerId())).toBeFalsy()
125
75
  expect(list.getContactIds()).toEqual(list.getContactIds().sort(list.compareIds))
126
- expect(list.getAllContacts()).toEqual([peer1, peer3, peer4])
127
- expect(onContactRemoved).toBeCalledWith(descriptor2, [descriptor1, descriptor3, descriptor4])
76
+ expect(list.getAllContacts()).toEqual([item1, item3, item4])
77
+ expect(onContactRemoved).toBeCalledWith(item2, [item1, item3, item4])
128
78
  const ret = list.removeContact(PeerID.fromValue(Buffer.from([0, 0, 0, 6])))
129
79
  expect(ret).toEqual(false)
130
80
  })
131
81
 
132
82
  it('get closes contacts', () => {
133
- const list = new SortedContactList(getId(descriptor0), 8)
134
- list.addContact(peer1)
135
- list.addContact(peer3)
136
- list.addContact(peer4)
137
- list.addContact(peer2)
138
- expect(list.getClosestContacts(2)).toEqual([peer1, peer2])
139
- expect(list.getClosestContacts()).toEqual([peer1, peer2, peer3, peer4])
83
+ const list = new SortedContactList(item0.getPeerId(), 8)
84
+ list.addContact(item1)
85
+ list.addContact(item3)
86
+ list.addContact(item4)
87
+ list.addContact(item2)
88
+ expect(list.getClosestContacts(2)).toEqual([item1, item2])
89
+ expect(list.getClosestContacts()).toEqual([item1, item2, item3, item4])
140
90
  })
141
91
 
142
92
  it('get active contacts', () => {
143
- const list = new SortedContactList(getId(descriptor0), 8)
144
- list.addContact(peer1)
145
- list.addContact(peer3)
146
- list.addContact(peer4)
147
- list.addContact(peer2)
148
- list.setActive(getId(descriptor2))
149
- list.setActive(getId(descriptor3))
150
- list.setActive(getId(descriptor4))
151
- expect(list.getActiveContacts()).toEqual([peer2, peer3, peer4])
93
+ const list = new SortedContactList(item0.getPeerId(), 8)
94
+ list.addContact(item1)
95
+ list.addContact(item3)
96
+ list.addContact(item4)
97
+ list.addContact(item2)
98
+ list.setActive(item2.getPeerId())
99
+ list.setActive(item3.getPeerId())
100
+ list.setActive(item4.getPeerId())
101
+ expect(list.getActiveContacts()).toEqual([item2, item3, item4])
152
102
  })
153
103
  })