@streamr/dht 0.0.1-tatum.4 → 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 (97) 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/connection/ConnectivityChecker.js +27 -17
  5. package/dist/src/connection/ConnectivityChecker.js.map +1 -1
  6. package/dist/src/connection/Handshaker.js +18 -13
  7. package/dist/src/connection/Handshaker.js.map +1 -1
  8. package/dist/src/connection/WebSocket/ServerWebSocket.js +0 -1
  9. package/dist/src/connection/WebSocket/ServerWebSocket.js.map +1 -1
  10. package/dist/src/dht/DhtNode.d.ts +2 -3
  11. package/dist/src/dht/DhtNode.js +24 -42
  12. package/dist/src/dht/DhtNode.js.map +1 -1
  13. package/dist/src/dht/DhtPeer.d.ts +2 -1
  14. package/dist/src/dht/DhtPeer.js +18 -25
  15. package/dist/src/dht/DhtPeer.js.map +1 -1
  16. package/dist/src/dht/RemoteExternalApi.d.ts +3 -1
  17. package/dist/src/dht/RemoteExternalApi.js +20 -6
  18. package/dist/src/dht/RemoteExternalApi.js.map +1 -1
  19. package/dist/src/dht/contact/Contact.d.ts +1 -15
  20. package/dist/src/dht/contact/Contact.js +1 -9
  21. package/dist/src/dht/contact/Contact.js.map +1 -1
  22. package/dist/src/dht/contact/ContactList.d.ts +27 -0
  23. package/dist/src/dht/contact/ContactList.js +44 -0
  24. package/dist/src/dht/contact/ContactList.js.map +1 -0
  25. package/dist/src/dht/contact/RandomContactList.d.ts +8 -16
  26. package/dist/src/dht/contact/RandomContactList.js +11 -36
  27. package/dist/src/dht/contact/RandomContactList.js.map +1 -1
  28. package/dist/src/dht/contact/Remote.d.ts +10 -10
  29. package/dist/src/dht/contact/Remote.js +17 -9
  30. package/dist/src/dht/contact/Remote.js.map +1 -1
  31. package/dist/src/dht/contact/SortedContactList.d.ts +11 -20
  32. package/dist/src/dht/contact/SortedContactList.js +17 -39
  33. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  34. package/dist/src/dht/find/RecursiveFinder.js +1 -1
  35. package/dist/src/dht/find/RecursiveFinder.js.map +1 -1
  36. package/dist/src/dht/find/RemoteRecursiveFindSession.js +1 -5
  37. package/dist/src/dht/find/RemoteRecursiveFindSession.js.map +1 -1
  38. package/dist/src/dht/registerExternalApiRpcMethods.d.ts +2 -0
  39. package/dist/src/dht/{registerExternalApiRpcMethod.js → registerExternalApiRpcMethods.js} +13 -5
  40. package/dist/src/dht/registerExternalApiRpcMethods.js.map +1 -0
  41. package/dist/src/dht/routing/RemoteRouter.js +13 -19
  42. package/dist/src/dht/routing/RemoteRouter.js.map +1 -1
  43. package/dist/src/dht/routing/RoutingSession.d.ts +0 -1
  44. package/dist/src/dht/routing/RoutingSession.js +15 -10
  45. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  46. package/dist/src/dht/store/DataStore.js +3 -3
  47. package/dist/src/dht/store/DataStore.js.map +1 -1
  48. package/dist/src/dht/store/RemoteStore.js +13 -17
  49. package/dist/src/dht/store/RemoteStore.js.map +1 -1
  50. package/dist/src/exports.d.ts +1 -1
  51. package/dist/src/exports.js +3 -3
  52. package/dist/src/exports.js.map +1 -1
  53. package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +10 -0
  54. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +7 -0
  55. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
  56. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +36 -0
  57. package/dist/src/proto/packages/dht/protos/DhtRpc.js +29 -2
  58. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  59. package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +6 -0
  60. package/package.json +6 -6
  61. package/protos/DhtRpc.proto +10 -0
  62. package/src/connection/ConnectionManager.ts +17 -4
  63. package/src/connection/ConnectivityChecker.ts +26 -17
  64. package/src/connection/Handshaker.ts +18 -13
  65. package/src/connection/WebSocket/ServerWebSocket.ts +0 -1
  66. package/src/dht/DhtNode.ts +36 -25
  67. package/src/dht/DhtPeer.ts +20 -27
  68. package/src/dht/RemoteExternalApi.ts +22 -8
  69. package/src/dht/contact/Contact.ts +1 -18
  70. package/src/dht/contact/ContactList.ts +59 -0
  71. package/src/dht/contact/RandomContactList.ts +17 -43
  72. package/src/dht/contact/Remote.ts +27 -20
  73. package/src/dht/contact/SortedContactList.ts +29 -58
  74. package/src/dht/find/RecursiveFinder.ts +3 -3
  75. package/src/dht/find/RemoteRecursiveFindSession.ts +1 -8
  76. package/src/dht/registerExternalApiRpcMethods.ts +41 -0
  77. package/src/dht/routing/RemoteRouter.ts +13 -20
  78. package/src/dht/routing/RoutingSession.ts +29 -20
  79. package/src/dht/store/DataStore.ts +6 -6
  80. package/src/dht/store/RemoteStore.ts +13 -20
  81. package/src/exports.ts +1 -1
  82. package/src/proto/packages/dht/protos/DhtRpc.client.ts +13 -0
  83. package/src/proto/packages/dht/protos/DhtRpc.server.ts +6 -0
  84. package/src/proto/packages/dht/protos/DhtRpc.ts +49 -1
  85. package/test/benchmark/KademliaCorrectness.test.ts +2 -1
  86. package/test/end-to-end/Layer0-Layer1.test.ts +10 -10
  87. package/test/integration/DhtNodeExternalAPI.test.ts +9 -0
  88. package/test/integration/DhtWithMockConnectionLatencies.test.ts +1 -1
  89. package/test/integration/DhtWithMockConnections.test.ts +1 -1
  90. package/test/integration/DhtWithRealConnectionLatencies.test.ts +1 -1
  91. package/test/integration/RemoteRouter.test.ts +1 -1
  92. package/test/integration/RemoteStore.test.ts +1 -1
  93. package/test/unit/RandomContactList.test.ts +31 -73
  94. package/test/unit/SortedContactList.test.ts +72 -96
  95. package/dist/src/dht/registerExternalApiRpcMethod.d.ts +0 -2
  96. package/dist/src/dht/registerExternalApiRpcMethod.js.map +0 -1
  97. package/src/dht/registerExternalApiRpcMethod.ts +0 -26
@@ -39,6 +39,28 @@ export interface StoreDataResponse {
39
39
  */
40
40
  error: string;
41
41
  }
42
+ /**
43
+ * @generated from protobuf message dht.ExternalStoreDataRequest
44
+ */
45
+ export interface ExternalStoreDataRequest {
46
+ /**
47
+ * @generated from protobuf field: bytes key = 1;
48
+ */
49
+ key: Uint8Array;
50
+ /**
51
+ * @generated from protobuf field: google.protobuf.Any data = 2;
52
+ */
53
+ data?: Any;
54
+ }
55
+ /**
56
+ * @generated from protobuf message dht.ExternalStoreDataResponse
57
+ */
58
+ export interface ExternalStoreDataResponse {
59
+ /**
60
+ * @generated from protobuf field: repeated dht.PeerDescriptor storers = 1;
61
+ */
62
+ storers: PeerDescriptor[];
63
+ }
42
64
  /**
43
65
  * @generated from protobuf message dht.MigrateDataRequest
44
66
  */
@@ -806,6 +828,31 @@ class StoreDataResponse$Type extends MessageType$<StoreDataResponse> {
806
828
  */
807
829
  export const StoreDataResponse = new StoreDataResponse$Type();
808
830
  // @generated message type with reflection information, may provide speed optimized methods
831
+ class ExternalStoreDataRequest$Type extends MessageType$<ExternalStoreDataRequest> {
832
+ constructor() {
833
+ super("dht.ExternalStoreDataRequest", [
834
+ { no: 1, name: "key", kind: "scalar", T: 12 /*ScalarType.BYTES*/ },
835
+ { no: 2, name: "data", kind: "message", T: () => Any }
836
+ ]);
837
+ }
838
+ }
839
+ /**
840
+ * @generated MessageType for protobuf message dht.ExternalStoreDataRequest
841
+ */
842
+ export const ExternalStoreDataRequest = new ExternalStoreDataRequest$Type();
843
+ // @generated message type with reflection information, may provide speed optimized methods
844
+ class ExternalStoreDataResponse$Type extends MessageType$<ExternalStoreDataResponse> {
845
+ constructor() {
846
+ super("dht.ExternalStoreDataResponse", [
847
+ { no: 1, name: "storers", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => PeerDescriptor }
848
+ ]);
849
+ }
850
+ }
851
+ /**
852
+ * @generated MessageType for protobuf message dht.ExternalStoreDataResponse
853
+ */
854
+ export const ExternalStoreDataResponse = new ExternalStoreDataResponse$Type();
855
+ // @generated message type with reflection information, may provide speed optimized methods
809
856
  class MigrateDataRequest$Type extends MessageType$<MigrateDataRequest> {
810
857
  constructor() {
811
858
  super("dht.MigrateDataRequest", [
@@ -1348,5 +1395,6 @@ export const ConnectionLocker = new ServiceType("dht.ConnectionLocker", [
1348
1395
  * @generated ServiceType for protobuf service dht.ExternalApiService
1349
1396
  */
1350
1397
  export const ExternalApiService = new ServiceType("dht.ExternalApiService", [
1351
- { name: "findData", options: {}, I: FindDataRequest, O: FindDataResponse }
1398
+ { name: "findData", options: {}, I: FindDataRequest, O: FindDataResponse },
1399
+ { name: "externalStoreData", options: {}, I: ExternalStoreDataRequest, O: ExternalStoreDataResponse }
1352
1400
  ]);
@@ -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,5 +39,14 @@ describe('DhtNodeExternalApi', () => {
39
39
  const foundData = await remote.findDataViaPeer(PeerID.fromString('key').value, dhtNode1.getPeerDescriptor())
40
40
  expect(foundData).toEqual([])
41
41
  })
42
+
43
+ it('external store data happy path', async () => {
44
+ const data = Any.pack(dhtNode1.getPeerDescriptor(), PeerDescriptor)
45
+ const key = PeerID.fromString('key').value
46
+
47
+ await remote.storeDataViaPeer(key, data, dhtNode1.getPeerDescriptor())
48
+ const foundData = await remote.findDataViaPeer(key, dhtNode1.getPeerDescriptor())
49
+ expect(Any.unpack(foundData[0].data!, PeerDescriptor)).toEqual(dhtNode1.getPeerDescriptor())
50
+ })
42
51
 
43
52
  })
@@ -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)
@@ -32,7 +32,7 @@ describe('RemoteRouter', () => {
32
32
  clientRpcCommunicator.handleIncomingMessage(message)
33
33
  })
34
34
  const client = toProtoRpcClient(new RoutingServiceClient(clientRpcCommunicator.getRpcClientTransport()))
35
- remoteRouter = new RemoteRouter(clientPeerDescriptor, serverPeerDescriptor, client, serviceId)
35
+ remoteRouter = new RemoteRouter(clientPeerDescriptor, serverPeerDescriptor, serviceId, client)
36
36
  })
37
37
 
38
38
  it('routeMessage happy path', async () => {
@@ -44,7 +44,7 @@ describe('RemoteStore', () => {
44
44
  clientRpcCommunicator.handleIncomingMessage(message)
45
45
  })
46
46
  const client = toProtoRpcClient(new StoreServiceClient(clientRpcCommunicator.getRpcClientTransport()))
47
- remoteStore = new RemoteStore(clientPeerDescriptor, serverPeerDescriptor, client, serviceId)
47
+ remoteStore = new RemoteStore(clientPeerDescriptor, serverPeerDescriptor, serviceId, client)
48
48
  })
49
49
 
50
50
  it('storeData happy path', async () => {
@@ -1,87 +1,45 @@
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
- }
4
+ const createItem = (kademliaId: Uint8Array): { getPeerId: () => PeerID } => {
5
+ return { getPeerId: () => PeerID.fromValue(kademliaId) }
46
6
  }
47
7
 
48
8
  describe('RandomContactList', () => {
49
- const serviceId = 'random'
50
- const id0 = PeerID.fromValue(Buffer.from([0, 0, 0, 0]))
51
- const id1 = PeerID.fromValue(Buffer.from([0, 0, 0, 1]))
52
- const id2 = PeerID.fromValue(Buffer.from([0, 0, 0, 2]))
53
- const id3 = PeerID.fromValue(Buffer.from([0, 0, 0, 3]))
54
- const id4 = PeerID.fromValue(Buffer.from([0, 0, 0, 4]))
55
-
56
- const descriptor0: PeerDescriptor = { kademliaId: id0.value, type: NodeType.NODEJS }
57
- const descriptor1: PeerDescriptor = { kademliaId: id1.value, type: NodeType.NODEJS }
58
- const descriptor2: PeerDescriptor = { kademliaId: id2.value, type: NodeType.NODEJS }
59
- const descriptor3: PeerDescriptor = { kademliaId: id3.value, type: NodeType.NODEJS }
60
- const descriptor4: PeerDescriptor = { kademliaId: id4.value, type: NodeType.NODEJS }
61
-
62
- const peer1 = new DhtPeer(descriptor0, descriptor1, toProtoRpcClient(new MockRpcClient()), serviceId)
63
- const peer2 = new DhtPeer(descriptor0, descriptor2, toProtoRpcClient(new MockRpcClient()), serviceId)
64
- const peer3 = new DhtPeer(descriptor0, descriptor3, toProtoRpcClient(new MockRpcClient()), serviceId)
65
- 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]))
66
14
 
67
15
  it('adds contacts correctly', () => {
68
- const list = new RandomContactList(id0, 5, 1)
69
- list.addContact(peer1)
70
- list.addContact(peer2)
71
- list.addContact(peer3)
72
- list.addContact(peer3)
73
- list.addContact(peer4)
74
- 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)
75
23
  expect(list.getSize()).toEqual(4)
24
+ expect(list.getContacts()).toEqual(
25
+ [item1, item2, item3, item4]
26
+ )
76
27
  })
77
28
 
78
29
  it('removes contacts correctly', () => {
79
- const list = new RandomContactList(id0, 5, 1)
80
- list.addContact(peer1)
81
- list.addContact(peer2)
82
- list.removeContact(id2)
83
- expect(list.getContact(id1)).toBeTruthy()
84
- expect(list.getSize()).toEqual(1)
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()
39
+ expect(list.getContacts()).toEqual(
40
+ [item1, item3, item4]
41
+ )
42
+ expect(list.getSize()).toEqual(3)
85
43
  })
86
44
 
87
45
  })
@@ -1,127 +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
- }
4
+ const createItem = (kademliaId: Uint8Array): { getPeerId: () => PeerID } => {
5
+ return { getPeerId: () => PeerID.fromValue(kademliaId) }
42
6
  }
43
7
 
44
8
  describe('SortedContactList', () => {
45
- const serviceId = 'sorted'
46
- const id0 = PeerID.fromValue(Buffer.from([0, 0, 0, 0]))
47
- const id1 = PeerID.fromValue(Buffer.from([0, 0, 0, 1]))
48
- const id2 = PeerID.fromValue(Buffer.from([0, 0, 0, 2]))
49
- const id3 = PeerID.fromValue(Buffer.from([0, 0, 0, 3]))
50
- const id4 = PeerID.fromValue(Buffer.from([0, 0, 0, 4]))
51
-
52
- const descriptor0: PeerDescriptor = { kademliaId: id0.value, type: NodeType.NODEJS }
53
- const descriptor1: PeerDescriptor = { kademliaId: id1.value, type: NodeType.NODEJS }
54
- const descriptor2: PeerDescriptor = { kademliaId: id2.value, type: NodeType.NODEJS }
55
- const descriptor3: PeerDescriptor = { kademliaId: id3.value, type: NodeType.NODEJS }
56
- const descriptor4: PeerDescriptor = { kademliaId: id4.value, type: NodeType.NODEJS }
57
-
58
- const peer1 = new DhtPeer(descriptor0, descriptor1, toProtoRpcClient(new MockRpcClient()), serviceId)
59
- const peer2 = new DhtPeer(descriptor0, descriptor2, toProtoRpcClient(new MockRpcClient()), serviceId)
60
- const peer3 = new DhtPeer(descriptor0, descriptor3, toProtoRpcClient(new MockRpcClient()), serviceId)
61
- 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]))
62
14
 
63
15
  it('compares Ids correctly', async () => {
64
- const list = new SortedContactList(id0, 10)
65
- expect(list.compareIds(id0, id0)).toBe(0)
66
- expect(list.compareIds(id1, id1)).toBe(0)
67
- expect(list.compareIds(id0, id1)).toBe(-1)
68
- expect(list.compareIds(id0, id2)).toBe(-2)
69
- expect(list.compareIds(id1, id0)).toBe(1)
70
- expect(list.compareIds(id2, id0)).toBe(2)
71
- expect(list.compareIds(id2, id3)).toBe(-1)
72
- expect(list.compareIds(id1, id4)).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)
73
25
  })
74
26
 
75
27
  it('orders itself correctly', async () => {
76
-
77
- const list = new SortedContactList(id0, 10)
78
-
79
- list.addContact(peer3)
80
- list.addContact(peer2)
81
- list.addContact(peer1)
82
-
28
+ const list = new SortedContactList(item0.getPeerId(), 10)
29
+ list.addContact(item3)
30
+ list.addContact(item2)
31
+ list.addContact(item1)
83
32
  const contacts = list.getUncontactedContacts(3)
84
33
  expect(contacts.length).toEqual(3)
85
- expect(contacts[0]).toEqual(peer1)
86
- expect(contacts[1]).toEqual(peer2)
87
- expect(contacts[2]).toEqual(peer3)
34
+ expect(contacts[0]).toEqual(item1)
35
+ expect(contacts[1]).toEqual(item2)
36
+ expect(contacts[2]).toEqual(item3)
88
37
  })
89
38
 
90
39
  it('handles contacted nodes correctly', async () => {
91
- const list = new SortedContactList(id0, 10)
92
-
93
- list.addContact(peer3)
94
- list.addContact(peer2)
95
- list.addContact(peer1)
96
-
97
- list.setContacted(id2)
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())
98
45
  const contacts = list.getUncontactedContacts(3)
99
46
  expect(contacts.length).toEqual(2)
100
- expect(contacts[0]).toEqual(peer1)
101
- expect(contacts[1]).toEqual(peer3)
47
+ expect(contacts[0]).toEqual(item1)
48
+ expect(contacts[1]).toEqual(item3)
102
49
  })
103
50
 
104
51
  it('cannot exceed maxSize', async () => {
105
- const list = new SortedContactList(id0, 3)
106
- list.addContact(peer4)
107
- list.addContact(peer3)
108
- list.addContact(peer2)
109
- list.addContact(peer1)
52
+ const list = new SortedContactList(item0.getPeerId(), 3)
53
+ const onContactRemoved = jest.fn()
54
+ list.on('contactRemoved', onContactRemoved)
55
+ list.addContact(item1)
56
+ list.addContact(item4)
57
+ list.addContact(item3)
58
+ list.addContact(item2)
110
59
  expect(list.getSize()).toEqual(3)
111
- expect(list.getContact(id4)).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(id0, 8)
116
- list.addContact(peer4)
117
- list.addContact(peer3)
118
- list.addContact(peer2)
119
- list.addContact(peer1)
120
- list.removeContact(id2)
65
+ const list = new SortedContactList(item0.getPeerId(), 8)
66
+ const onContactRemoved = jest.fn()
67
+ list.on('contactRemoved', onContactRemoved)
68
+ list.addContact(item4)
69
+ list.addContact(item3)
70
+ list.addContact(item2)
71
+ list.addContact(item1)
72
+ list.removeContact(item2.getPeerId())
121
73
  expect(list.getSize()).toEqual(3)
122
- expect(list.getContact(id2)).toBeFalsy()
74
+ expect(list.getContact(item2.getPeerId())).toBeFalsy()
123
75
  expect(list.getContactIds()).toEqual(list.getContactIds().sort(list.compareIds))
76
+ expect(list.getAllContacts()).toEqual([item1, item3, item4])
77
+ expect(onContactRemoved).toBeCalledWith(item2, [item1, item3, item4])
124
78
  const ret = list.removeContact(PeerID.fromValue(Buffer.from([0, 0, 0, 6])))
125
79
  expect(ret).toEqual(false)
126
80
  })
81
+
82
+ it('get closes contacts', () => {
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])
90
+ })
91
+
92
+ it('get active contacts', () => {
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])
102
+ })
127
103
  })
@@ -1,2 +0,0 @@
1
- import { DhtNode } from '../exports';
2
- export declare const registerExternalApiRpcMethod: (thisNode: DhtNode) => void;
@@ -1 +0,0 @@
1
- {"version":3,"file":"registerExternalApiRpcMethod.js","sourceRoot":"","sources":["../../../src/dht/registerExternalApiRpcMethod.ts"],"names":[],"mappings":";;;AACA,gEAAiG;AAE1F,MAAM,4BAA4B,GAAG,CAAC,QAAiB,EAAQ,EAAE;IACpE,MAAM,eAAe,GAAG,QAAQ,CAAC,kBAAkB,EAAE,CAAA;IACrD,eAAe,CAAC,iBAAiB,CAC7B,wBAAe,EACf,yBAAgB,EAChB,UAAU,EACV,CAAC,GAAoB,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,EACjD,EAAE,OAAO,EAAE,KAAK,EAAE,CACrB,CAAA;AACL,CAAC,CAAA;AATY,QAAA,4BAA4B,gCASxC;AAED,yDAAyD;AACzD,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAiB,EAAE,eAAgC,EAA6B,EAAE;IACtG,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,eAAe,CAAC,UAAU,EAAE,iBAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAA;IACtH,IAAI,MAAM,CAAC,WAAW,EAAE;QACpB,OAAO,yBAAgB,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;KACtE;SAAM;QACH,OAAO,yBAAgB,CAAC,MAAM,CAAC;YAC3B,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,wCAAwC;SAClD,CAAC,CAAA;KACL;AACL,CAAC,CAAA"}
@@ -1,26 +0,0 @@
1
- import { DhtNode } from '../exports'
2
- import { FindDataRequest, FindDataResponse, FindMode } from '../proto/packages/dht/protos/DhtRpc'
3
-
4
- export const registerExternalApiRpcMethod = (thisNode: DhtNode): void => {
5
- const rpcCommunicator = thisNode.getRpcCommunicator()
6
- rpcCommunicator.registerRpcMethod(
7
- FindDataRequest,
8
- FindDataResponse,
9
- 'findData',
10
- (req: FindDataRequest) => findData(thisNode, req),
11
- { timeout: 15000 }
12
- )
13
- }
14
-
15
- // IDHTRpcService method for external findRecursive calls
16
- const findData = async (thisNode: DhtNode, findDataRequest: FindDataRequest): Promise<FindDataResponse> => {
17
- const result = await thisNode.startRecursiveFind(findDataRequest.kademliaId, FindMode.DATA, findDataRequest.requestor)
18
- if (result.dataEntries) {
19
- return FindDataResponse.create({ dataEntries: result.dataEntries })
20
- } else {
21
- return FindDataResponse.create({
22
- dataEntries: [],
23
- error: 'Could not find data with the given key'
24
- })
25
- }
26
- }