@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.
- package/dist/src/connection/ConnectionManager.d.ts +1 -0
- package/dist/src/connection/ConnectionManager.js +14 -2
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectivityChecker.js +27 -17
- package/dist/src/connection/ConnectivityChecker.js.map +1 -1
- package/dist/src/connection/Handshaker.js +18 -13
- package/dist/src/connection/Handshaker.js.map +1 -1
- package/dist/src/connection/WebSocket/ServerWebSocket.js +0 -1
- package/dist/src/connection/WebSocket/ServerWebSocket.js.map +1 -1
- package/dist/src/dht/DhtNode.d.ts +2 -3
- package/dist/src/dht/DhtNode.js +24 -42
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtPeer.d.ts +2 -1
- package/dist/src/dht/DhtPeer.js +18 -25
- package/dist/src/dht/DhtPeer.js.map +1 -1
- package/dist/src/dht/RemoteExternalApi.d.ts +3 -1
- package/dist/src/dht/RemoteExternalApi.js +20 -6
- package/dist/src/dht/RemoteExternalApi.js.map +1 -1
- package/dist/src/dht/contact/Contact.d.ts +1 -15
- package/dist/src/dht/contact/Contact.js +1 -9
- package/dist/src/dht/contact/Contact.js.map +1 -1
- package/dist/src/dht/contact/ContactList.d.ts +27 -0
- package/dist/src/dht/contact/ContactList.js +44 -0
- package/dist/src/dht/contact/ContactList.js.map +1 -0
- package/dist/src/dht/contact/RandomContactList.d.ts +8 -16
- package/dist/src/dht/contact/RandomContactList.js +11 -36
- package/dist/src/dht/contact/RandomContactList.js.map +1 -1
- package/dist/src/dht/contact/Remote.d.ts +10 -10
- package/dist/src/dht/contact/Remote.js +17 -9
- package/dist/src/dht/contact/Remote.js.map +1 -1
- package/dist/src/dht/contact/SortedContactList.d.ts +11 -20
- package/dist/src/dht/contact/SortedContactList.js +17 -39
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- package/dist/src/dht/find/RecursiveFinder.js +1 -1
- package/dist/src/dht/find/RecursiveFinder.js.map +1 -1
- package/dist/src/dht/find/RemoteRecursiveFindSession.js +1 -5
- package/dist/src/dht/find/RemoteRecursiveFindSession.js.map +1 -1
- package/dist/src/dht/registerExternalApiRpcMethods.d.ts +2 -0
- package/dist/src/dht/{registerExternalApiRpcMethod.js → registerExternalApiRpcMethods.js} +13 -5
- package/dist/src/dht/registerExternalApiRpcMethods.js.map +1 -0
- package/dist/src/dht/routing/RemoteRouter.js +13 -19
- package/dist/src/dht/routing/RemoteRouter.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.d.ts +0 -1
- package/dist/src/dht/routing/RoutingSession.js +15 -10
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/store/DataStore.js +3 -3
- package/dist/src/dht/store/DataStore.js.map +1 -1
- package/dist/src/dht/store/RemoteStore.js +13 -17
- package/dist/src/dht/store/RemoteStore.js.map +1 -1
- package/dist/src/exports.d.ts +1 -1
- package/dist/src/exports.js +3 -3
- package/dist/src/exports.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +10 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +7 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +36 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +29 -2
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +6 -0
- package/package.json +6 -6
- package/protos/DhtRpc.proto +10 -0
- package/src/connection/ConnectionManager.ts +17 -4
- package/src/connection/ConnectivityChecker.ts +26 -17
- package/src/connection/Handshaker.ts +18 -13
- package/src/connection/WebSocket/ServerWebSocket.ts +0 -1
- package/src/dht/DhtNode.ts +36 -25
- package/src/dht/DhtPeer.ts +20 -27
- package/src/dht/RemoteExternalApi.ts +22 -8
- package/src/dht/contact/Contact.ts +1 -18
- package/src/dht/contact/ContactList.ts +59 -0
- package/src/dht/contact/RandomContactList.ts +17 -43
- package/src/dht/contact/Remote.ts +27 -20
- package/src/dht/contact/SortedContactList.ts +29 -58
- package/src/dht/find/RecursiveFinder.ts +3 -3
- package/src/dht/find/RemoteRecursiveFindSession.ts +1 -8
- package/src/dht/registerExternalApiRpcMethods.ts +41 -0
- package/src/dht/routing/RemoteRouter.ts +13 -20
- package/src/dht/routing/RoutingSession.ts +29 -20
- package/src/dht/store/DataStore.ts +6 -6
- package/src/dht/store/RemoteStore.ts +13 -20
- package/src/exports.ts +1 -1
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +13 -0
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +6 -0
- package/src/proto/packages/dht/protos/DhtRpc.ts +49 -1
- package/test/benchmark/KademliaCorrectness.test.ts +2 -1
- package/test/end-to-end/Layer0-Layer1.test.ts +10 -10
- package/test/integration/DhtNodeExternalAPI.test.ts +9 -0
- package/test/integration/DhtWithMockConnectionLatencies.test.ts +1 -1
- package/test/integration/DhtWithMockConnections.test.ts +1 -1
- package/test/integration/DhtWithRealConnectionLatencies.test.ts +1 -1
- package/test/integration/RemoteRouter.test.ts +1 -1
- package/test/integration/RemoteStore.test.ts +1 -1
- package/test/unit/RandomContactList.test.ts +31 -73
- package/test/unit/SortedContactList.test.ts +72 -96
- package/dist/src/dht/registerExternalApiRpcMethod.d.ts +0 -2
- package/dist/src/dht/registerExternalApiRpcMethod.js.map +0 -1
- 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].
|
|
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 {
|
|
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.
|
|
80
|
-
expect(stream1Node2.
|
|
81
|
-
expect(stream2Node1.
|
|
82
|
-
expect(stream2Node2.
|
|
83
|
-
|
|
84
|
-
expect(stream1Node1.
|
|
85
|
-
expect(stream1Node2.
|
|
86
|
-
expect(stream2Node1.
|
|
87
|
-
expect(stream2Node2.
|
|
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.
|
|
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.
|
|
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.
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
18
|
-
|
|
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
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
const
|
|
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(
|
|
69
|
-
list.addContact(
|
|
70
|
-
list.addContact(
|
|
71
|
-
list.addContact(
|
|
72
|
-
list.addContact(
|
|
73
|
-
list.addContact(
|
|
74
|
-
list.addContact(
|
|
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(
|
|
80
|
-
list.addContact(
|
|
81
|
-
list.addContact(
|
|
82
|
-
list.
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
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(
|
|
65
|
-
expect(list.compareIds(
|
|
66
|
-
expect(list.compareIds(
|
|
67
|
-
expect(list.compareIds(
|
|
68
|
-
expect(list.compareIds(
|
|
69
|
-
expect(list.compareIds(
|
|
70
|
-
expect(list.compareIds(
|
|
71
|
-
expect(list.compareIds(
|
|
72
|
-
expect(list.compareIds(
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
list.addContact(
|
|
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(
|
|
86
|
-
expect(contacts[1]).toEqual(
|
|
87
|
-
expect(contacts[2]).toEqual(
|
|
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(
|
|
92
|
-
|
|
93
|
-
list.addContact(
|
|
94
|
-
list.addContact(
|
|
95
|
-
list.
|
|
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(
|
|
101
|
-
expect(contacts[1]).toEqual(
|
|
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(
|
|
106
|
-
|
|
107
|
-
list.
|
|
108
|
-
list.addContact(
|
|
109
|
-
list.addContact(
|
|
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(
|
|
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(
|
|
116
|
-
|
|
117
|
-
list.
|
|
118
|
-
list.addContact(
|
|
119
|
-
list.addContact(
|
|
120
|
-
list.
|
|
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(
|
|
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 +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
|
-
}
|