@streamr/dht 100.2.4-beta.0 → 100.2.4
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/package.json +8 -9
- package/dist/src/connection/ConnectionManager.d.ts +2 -1
- package/dist/src/connection/ConnectionManager.js +2 -10
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectionsView.d.ts +7 -0
- package/dist/src/connection/ConnectionsView.js +3 -0
- package/dist/src/connection/ConnectionsView.js.map +1 -0
- package/dist/src/connection/ConnectorFacade.d.ts +2 -1
- package/dist/src/connection/ConnectorFacade.js +5 -4
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -1
- package/dist/src/connection/connectivityRequestHandler.js +12 -5
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
- package/dist/src/connection/{ManagedWebrtcConnection.d.ts → webrtc/ManagedWebrtcConnection.d.ts} +3 -3
- package/dist/src/connection/{ManagedWebrtcConnection.js → webrtc/ManagedWebrtcConnection.js} +2 -2
- package/dist/src/connection/webrtc/ManagedWebrtcConnection.js.map +1 -0
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js +3 -26
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnector.d.ts +2 -0
- package/dist/src/connection/websocket/WebsocketConnector.js +21 -13
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServerConnection.d.ts +2 -1
- package/dist/src/connection/websocket/WebsocketServerConnection.js +4 -0
- package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -1
- package/dist/src/dht/DhtNode.d.ts +14 -11
- package/dist/src/dht/DhtNode.js +74 -61
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +3 -3
- package/dist/src/dht/DhtNodeRpcLocal.js +5 -2
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +14 -14
- package/dist/src/dht/PeerManager.js +51 -42
- package/dist/src/dht/PeerManager.js.map +1 -1
- package/dist/src/dht/contact/ContactList.d.ts +1 -2
- package/dist/src/dht/contact/ContactList.js +1 -3
- package/dist/src/dht/contact/ContactList.js.map +1 -1
- package/dist/src/dht/contact/RandomContactList.d.ts +1 -1
- package/dist/src/dht/contact/RandomContactList.js +7 -4
- package/dist/src/dht/contact/RandomContactList.js.map +1 -1
- package/dist/src/dht/contact/getClosestNodes.d.ts +6 -0
- package/dist/src/dht/contact/{getClosestContacts.js → getClosestNodes.js} +7 -6
- package/dist/src/dht/contact/getClosestNodes.js.map +1 -0
- package/dist/src/dht/discovery/DiscoverySession.d.ts +4 -0
- package/dist/src/dht/discovery/DiscoverySession.js +27 -21
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +8 -5
- package/dist/src/dht/discovery/PeerDiscovery.js +34 -24
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/discovery/RingDiscoverySession.d.ts +4 -4
- package/dist/src/dht/discovery/RingDiscoverySession.js +10 -19
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +2 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +3 -3
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
- package/dist/src/dht/store/StoreManager.d.ts +5 -6
- package/dist/src/dht/store/StoreManager.js +21 -76
- package/dist/src/dht/store/StoreManager.js.map +1 -1
- package/dist/src/dht/store/StoreRpcLocal.d.ts +5 -2
- package/dist/src/dht/store/StoreRpcLocal.js +22 -5
- package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
- package/dist/src/exports.d.ts +2 -1
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/version.d.ts +1 -1
- package/dist/src/helpers/version.js +1 -1
- package/dist/src/proto/google/protobuf/any.d.ts +8 -5
- package/dist/src/proto/google/protobuf/any.js.map +1 -1
- package/dist/src/proto/google/protobuf/empty.d.ts +0 -1
- package/dist/src/proto/google/protobuf/empty.js.map +1 -1
- package/dist/src/proto/google/protobuf/timestamp.d.ts +10 -1
- package/dist/src/proto/google/protobuf/timestamp.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +8 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +3 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/transport/ITransport.d.ts +0 -4
- package/dist/src/transport/ITransport.js.map +1 -1
- package/karma.config.js +2 -2
- package/package.json +8 -9
- package/protos/DhtRpc.proto +2 -0
- package/src/connection/ConnectionManager.ts +4 -10
- package/src/connection/ConnectionsView.ts +8 -0
- package/src/connection/ConnectorFacade.ts +7 -5
- package/src/connection/connectivityRequestHandler.ts +18 -5
- package/src/connection/{ManagedWebrtcConnection.ts → webrtc/ManagedWebrtcConnection.ts} +4 -4
- package/src/connection/webrtc/NodeWebrtcConnection.ts +3 -3
- package/src/connection/webrtc/WebrtcConnector.ts +1 -1
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +1 -1
- package/src/connection/websocket/WebsocketConnector.ts +26 -16
- package/src/connection/websocket/WebsocketServerConnection.ts +6 -1
- package/src/dht/DhtNode.ts +102 -74
- package/src/dht/DhtNodeRpcLocal.ts +12 -5
- package/src/dht/PeerManager.ts +58 -49
- package/src/dht/contact/ContactList.ts +1 -4
- package/src/dht/contact/RandomContactList.ts +7 -5
- package/src/dht/contact/{getClosestContacts.ts → getClosestNodes.ts} +8 -6
- package/src/dht/discovery/DiscoverySession.ts +34 -22
- package/src/dht/discovery/PeerDiscovery.ts +44 -30
- package/src/dht/discovery/RingDiscoverySession.ts +15 -29
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +5 -3
- package/src/dht/store/StoreManager.ts +46 -84
- package/src/dht/store/StoreRpcLocal.ts +32 -9
- package/src/exports.ts +2 -1
- package/src/helpers/version.ts +1 -1
- package/src/proto/google/protobuf/any.ts +8 -5
- package/src/proto/google/protobuf/empty.ts +0 -1
- package/src/proto/google/protobuf/timestamp.ts +10 -1
- package/src/proto/packages/dht/protos/DhtRpc.ts +11 -1
- package/src/transport/ITransport.ts +0 -4
- package/test/benchmark/Find.test.ts +1 -1
- package/test/end-to-end/GeoIpLayer0.test.ts +55 -0
- package/test/end-to-end/Layer0-Layer1.test.ts +4 -4
- package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +11 -5
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +7 -1
- package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +11 -2
- package/test/integration/ConnectionLocking.test.ts +1 -1
- package/test/integration/ConnectionManager.test.ts +3 -3
- package/test/integration/ConnectivityChecking.test.ts +2 -2
- package/test/integration/DhtNode.test.ts +5 -20
- package/test/integration/GeoIpConnectivityChecking.test.ts +71 -0
- package/test/integration/Layer1-scale.test.ts +6 -6
- package/test/integration/RouteMessage.test.ts +4 -0
- package/test/integration/ScaleDownDht.test.ts +1 -1
- package/test/integration/SimultaneousConnections.test.ts +2 -2
- package/test/integration/WebrtcConnectionManagement.test.ts +1 -1
- package/test/integration/WebsocketConnectionManagement.test.ts +1 -1
- package/test/integration/rpc-connections-over-webrpc.test.ts +1 -1
- package/test/unit/AutoCertifierClientFacade.test.ts +1 -1
- package/test/unit/DiscoverySession.test.ts +4 -2
- package/test/unit/PeerManager.test.ts +45 -51
- package/test/unit/RandomContactList.test.ts +10 -0
- package/test/unit/RecursiveOperationManager.test.ts +4 -2
- package/test/unit/StoreManager.test.ts +42 -34
- package/test/unit/StoreRpcLocal.test.ts +167 -0
- package/test/unit/WebsocketConnector.test.ts +1 -1
- package/test/unit/connectivityRequestHandler.test.ts +1 -1
- package/test/unit/getClosestNodes.test.ts +30 -0
- package/test/utils/FakeTransport.ts +4 -2
- package/test/utils/mock/MockConnectionsView.ts +18 -0
- package/test/utils/mock/{Transport.ts → MockTransport.ts} +0 -15
- package/test/utils/utils.ts +4 -1
- package/tsconfig.jest.json +2 -1
- package/tsconfig.node.json +2 -1
- package/dist/src/connection/ManagedWebrtcConnection.js.map +0 -1
- package/dist/src/dht/contact/getClosestContacts.d.ts +0 -7
- package/dist/src/dht/contact/getClosestContacts.js.map +0 -1
- package/test/unit/getClosestContacts.test.ts +0 -28
- /package/test/utils/mock/{Router.ts → MockRouter.ts} +0 -0
|
@@ -1,44 +1,46 @@
|
|
|
1
1
|
import { wait, waitForCondition } from '@streamr/utils'
|
|
2
|
-
import { range,
|
|
3
|
-
import {
|
|
2
|
+
import { range, without } from 'lodash'
|
|
3
|
+
import { getClosestNodes } from '../../src/dht/contact/getClosestNodes'
|
|
4
4
|
import { StoreManager } from '../../src/dht/store/StoreManager'
|
|
5
5
|
import {
|
|
6
6
|
DhtAddress,
|
|
7
7
|
createRandomDhtAddress,
|
|
8
8
|
getDhtAddressFromRaw,
|
|
9
|
-
getRawFromDhtAddress
|
|
9
|
+
getRawFromDhtAddress
|
|
10
10
|
} from '../../src/identifiers'
|
|
11
|
-
import {
|
|
11
|
+
import { PeerDescriptor, ReplicateDataRequest } from '../../src/proto/packages/dht/protos/DhtRpc'
|
|
12
|
+
import { createMockPeerDescriptor } from '../utils/utils'
|
|
13
|
+
|
|
14
|
+
const NODE_COUNT = 10
|
|
12
15
|
|
|
13
16
|
const DATA_ENTRY = {
|
|
14
17
|
key: getRawFromDhtAddress(createRandomDhtAddress()),
|
|
15
18
|
creator: getRawFromDhtAddress(createRandomDhtAddress())
|
|
16
19
|
}
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
20
|
+
const ALL_NODES = range(NODE_COUNT).map(() => createMockPeerDescriptor())
|
|
21
|
+
|
|
22
|
+
const getNodeCloseToData = (distanceIndex: number) => {
|
|
23
|
+
const dataKey = getDhtAddressFromRaw(DATA_ENTRY.key)
|
|
24
|
+
return getClosestNodes(dataKey, ALL_NODES)[distanceIndex]
|
|
25
|
+
}
|
|
21
26
|
|
|
22
27
|
describe('StoreManager', () => {
|
|
23
28
|
|
|
24
29
|
describe('new contact', () => {
|
|
25
30
|
|
|
26
31
|
const createStoreManager = (
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
localPeerDescriptor: PeerDescriptor,
|
|
33
|
+
redundancyFactor: number,
|
|
29
34
|
replicateData: (request: ReplicateDataRequest) => unknown,
|
|
30
35
|
setAllEntriesAsStale: (key: DhtAddress) => unknown
|
|
31
36
|
): StoreManager => {
|
|
32
|
-
const getClosestNeighborsTo = () => {
|
|
33
|
-
return closestNeighbors.map((nodeId) => ({ nodeId: getRawFromDhtAddress(nodeId), type: NodeType.NODEJS }))
|
|
34
|
-
}
|
|
35
37
|
return new StoreManager({
|
|
36
38
|
rpcCommunicator: {
|
|
37
39
|
registerRpcMethod: () => {},
|
|
38
40
|
registerRpcNotification: () => {}
|
|
39
41
|
} as any,
|
|
40
42
|
recursiveOperationManager: undefined as any,
|
|
41
|
-
localPeerDescriptor
|
|
43
|
+
localPeerDescriptor,
|
|
42
44
|
localDataStore: {
|
|
43
45
|
keys: () => [getDhtAddressFromRaw(DATA_ENTRY.key)],
|
|
44
46
|
values: () => [DATA_ENTRY],
|
|
@@ -46,24 +48,25 @@ describe('StoreManager', () => {
|
|
|
46
48
|
} as any,
|
|
47
49
|
serviceId: undefined as any,
|
|
48
50
|
highestTtl: undefined as any,
|
|
49
|
-
redundancyFactor
|
|
50
|
-
|
|
51
|
+
redundancyFactor,
|
|
52
|
+
getNeighbors: () => without(ALL_NODES, localPeerDescriptor),
|
|
51
53
|
createRpcRemote: () => ({ replicateData } as any)
|
|
52
54
|
})
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
describe('this node
|
|
57
|
+
describe('this node was primary storer', () => {
|
|
56
58
|
|
|
57
59
|
it('new node is within redundancy factor', async () => {
|
|
58
60
|
const replicateData = jest.fn<undefined, [ReplicateDataRequest]>()
|
|
59
61
|
const setAllEntriesAsStale = jest.fn<undefined, [DhtAddress]>()
|
|
62
|
+
const localNode = getNodeCloseToData(0)
|
|
60
63
|
const manager = createStoreManager(
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
localNode,
|
|
65
|
+
3,
|
|
63
66
|
replicateData,
|
|
64
67
|
setAllEntriesAsStale
|
|
65
68
|
)
|
|
66
|
-
manager.onContactAdded(
|
|
69
|
+
manager.onContactAdded(getNodeCloseToData(2))
|
|
67
70
|
await waitForCondition(() => replicateData.mock.calls.length === 1)
|
|
68
71
|
expect(replicateData).toHaveBeenCalledWith({
|
|
69
72
|
entry: DATA_ENTRY
|
|
@@ -74,61 +77,66 @@ describe('StoreManager', () => {
|
|
|
74
77
|
it('new node is not within redundancy factor', async () => {
|
|
75
78
|
const replicateData = jest.fn<undefined, [ReplicateDataRequest]>()
|
|
76
79
|
const setAllEntriesAsStale = jest.fn<undefined, [DhtAddress]>()
|
|
80
|
+
const localNode = getNodeCloseToData(0)
|
|
77
81
|
const manager = createStoreManager(
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
localNode,
|
|
83
|
+
3,
|
|
80
84
|
replicateData,
|
|
81
85
|
setAllEntriesAsStale
|
|
82
86
|
)
|
|
83
|
-
manager.onContactAdded(
|
|
87
|
+
manager.onContactAdded(getNodeCloseToData(4))
|
|
84
88
|
await wait(50)
|
|
85
89
|
expect(replicateData).not.toHaveBeenCalled()
|
|
86
90
|
expect(setAllEntriesAsStale).not.toHaveBeenCalled()
|
|
87
91
|
})
|
|
88
92
|
})
|
|
89
93
|
|
|
90
|
-
describe('this node
|
|
94
|
+
describe('this node was not primary storer', () => {
|
|
91
95
|
|
|
92
96
|
it('this node is within redundancy factor', async () => {
|
|
93
97
|
const replicateData = jest.fn<undefined, [ReplicateDataRequest]>()
|
|
94
98
|
const setAllEntriesAsStale = jest.fn<undefined, [DhtAddress]>()
|
|
99
|
+
const localNode = getNodeCloseToData(1)
|
|
95
100
|
const manager = createStoreManager(
|
|
96
|
-
|
|
97
|
-
|
|
101
|
+
localNode,
|
|
102
|
+
3,
|
|
98
103
|
replicateData,
|
|
99
104
|
setAllEntriesAsStale
|
|
100
105
|
)
|
|
101
|
-
manager.onContactAdded(
|
|
106
|
+
manager.onContactAdded(getNodeCloseToData(4))
|
|
102
107
|
await wait(50)
|
|
103
108
|
expect(replicateData).not.toHaveBeenCalled()
|
|
109
|
+
expect(setAllEntriesAsStale).toHaveBeenCalledTimes(0)
|
|
104
110
|
})
|
|
105
111
|
|
|
106
112
|
it('this node is not within redundancy factor', async () => {
|
|
107
113
|
const replicateData = jest.fn<undefined, [ReplicateDataRequest]>()
|
|
108
114
|
const setAllEntriesAsStale = jest.fn<undefined, [DhtAddress]>()
|
|
115
|
+
const localNode = getNodeCloseToData(3)
|
|
109
116
|
const manager = createStoreManager(
|
|
110
|
-
|
|
111
|
-
|
|
117
|
+
localNode,
|
|
118
|
+
3,
|
|
112
119
|
replicateData,
|
|
113
120
|
setAllEntriesAsStale
|
|
114
121
|
)
|
|
115
|
-
manager.onContactAdded(
|
|
122
|
+
manager.onContactAdded(getNodeCloseToData(4))
|
|
116
123
|
await wait(50)
|
|
117
124
|
expect(replicateData).not.toHaveBeenCalled()
|
|
118
125
|
expect(setAllEntriesAsStale).toHaveBeenCalledTimes(1)
|
|
119
126
|
expect(setAllEntriesAsStale).toHaveBeenCalledWith(getDhtAddressFromRaw(DATA_ENTRY.key))
|
|
120
127
|
})
|
|
121
128
|
|
|
122
|
-
it('this node has less than redundancyFactor neighbors', async () => {
|
|
129
|
+
it('this node is within redundancy factor, the node has less than redundancyFactor neighbors', async () => {
|
|
123
130
|
const replicateData = jest.fn<undefined, [ReplicateDataRequest]>()
|
|
124
131
|
const setAllEntriesAsStale = jest.fn<undefined, [DhtAddress]>()
|
|
132
|
+
const localNode = getNodeCloseToData(3)
|
|
125
133
|
const manager = createStoreManager(
|
|
126
|
-
|
|
127
|
-
|
|
134
|
+
localNode,
|
|
135
|
+
100,
|
|
128
136
|
replicateData,
|
|
129
137
|
setAllEntriesAsStale
|
|
130
138
|
)
|
|
131
|
-
manager.onContactAdded(
|
|
139
|
+
manager.onContactAdded(getNodeCloseToData(4))
|
|
132
140
|
await wait(50)
|
|
133
141
|
expect(replicateData).not.toHaveBeenCalled()
|
|
134
142
|
expect(setAllEntriesAsStale).toHaveBeenCalledTimes(0)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { range } from 'lodash'
|
|
2
|
+
import { StoreRpcLocal } from '../../src/dht/store/StoreRpcLocal'
|
|
3
|
+
import { areEqualPeerDescriptors, createRandomDhtAddress, DhtAddress, getDhtAddressFromRaw, getRawFromDhtAddress } from '../../src/identifiers'
|
|
4
|
+
import { DataEntry, PeerDescriptor, StoreDataRequest } from '../../src/proto/packages/dht/protos/DhtRpc'
|
|
5
|
+
import { createMockPeerDescriptor } from '../utils/utils'
|
|
6
|
+
import { getClosestNodes } from '../../src/dht/contact/getClosestNodes'
|
|
7
|
+
import { wait } from '@streamr/utils'
|
|
8
|
+
|
|
9
|
+
describe('StoreRpcLocal', () => {
|
|
10
|
+
|
|
11
|
+
const NODE_COUNT = 5
|
|
12
|
+
const DATA_ENTRY = {
|
|
13
|
+
key: getRawFromDhtAddress(createRandomDhtAddress()),
|
|
14
|
+
creator: getRawFromDhtAddress(createRandomDhtAddress())
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const ALL_NODES = range(NODE_COUNT).map(() => createMockPeerDescriptor())
|
|
18
|
+
|
|
19
|
+
const getNodeCloseToData = (distanceIndex: number) => {
|
|
20
|
+
const dataKey = getDhtAddressFromRaw(DATA_ENTRY.key)
|
|
21
|
+
return getClosestNodes(dataKey, ALL_NODES)[distanceIndex]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let storeRpcLocal: StoreRpcLocal
|
|
25
|
+
let setAllEntriesAsStale: jest.Mock<undefined, [DhtAddress]>
|
|
26
|
+
let replicateDataToContact: jest.Mock<Promise<void>, [DataEntry, PeerDescriptor]>
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
setAllEntriesAsStale = jest.fn<undefined, [DhtAddress]>()
|
|
30
|
+
replicateDataToContact = jest.fn<Promise<void>, [DataEntry, PeerDescriptor]>()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('local node is primary storer', () => {
|
|
34
|
+
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
const localPeerDescriptor = getNodeCloseToData(0)
|
|
37
|
+
storeRpcLocal = new StoreRpcLocal({
|
|
38
|
+
localDataStore: {
|
|
39
|
+
storeEntry: () => true,
|
|
40
|
+
setAllEntriesAsStale
|
|
41
|
+
} as any,
|
|
42
|
+
localPeerDescriptor,
|
|
43
|
+
replicateDataToContact,
|
|
44
|
+
getStorers: () => getClosestNodes(getDhtAddressFromRaw(DATA_ENTRY.key), ALL_NODES)
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('storeData', async () => {
|
|
49
|
+
const request = StoreDataRequest.create({
|
|
50
|
+
key: DATA_ENTRY.key,
|
|
51
|
+
})
|
|
52
|
+
await storeRpcLocal.storeData(request)
|
|
53
|
+
expect(setAllEntriesAsStale).not.toHaveBeenCalled()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('replicateData', async () => {
|
|
57
|
+
const request = {
|
|
58
|
+
entry: DATA_ENTRY
|
|
59
|
+
}
|
|
60
|
+
await storeRpcLocal.replicateData(request as any, { incomingSourceDescriptor: createMockPeerDescriptor() } as any)
|
|
61
|
+
expect(setAllEntriesAsStale).not.toHaveBeenCalled()
|
|
62
|
+
// Wait for setImmediate
|
|
63
|
+
await wait(50)
|
|
64
|
+
expect(replicateDataToContact).toHaveBeenCalledTimes(NODE_COUNT - 1)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('local node is storer', () => {
|
|
70
|
+
beforeEach(() => {
|
|
71
|
+
const localPeerDescriptor = getNodeCloseToData(1)
|
|
72
|
+
storeRpcLocal = new StoreRpcLocal({
|
|
73
|
+
localDataStore: {
|
|
74
|
+
storeEntry: () => true,
|
|
75
|
+
setAllEntriesAsStale
|
|
76
|
+
} as any,
|
|
77
|
+
localPeerDescriptor,
|
|
78
|
+
replicateDataToContact,
|
|
79
|
+
getStorers: () => getClosestNodes(getDhtAddressFromRaw(DATA_ENTRY.key), ALL_NODES)
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('storeData', async () => {
|
|
84
|
+
const request = StoreDataRequest.create({
|
|
85
|
+
key: DATA_ENTRY.key
|
|
86
|
+
})
|
|
87
|
+
await storeRpcLocal.storeData(request)
|
|
88
|
+
expect(setAllEntriesAsStale).not.toHaveBeenCalled()
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('replicateData', async () => {
|
|
92
|
+
const request = {
|
|
93
|
+
entry: DATA_ENTRY
|
|
94
|
+
}
|
|
95
|
+
await storeRpcLocal.replicateData(request as any, { incomingSourceDescriptor: createMockPeerDescriptor() } as any)
|
|
96
|
+
expect(setAllEntriesAsStale).not.toHaveBeenCalled()
|
|
97
|
+
// Wait for setImmediate
|
|
98
|
+
await wait(50)
|
|
99
|
+
expect(replicateDataToContact).toHaveBeenCalledTimes(1)
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
describe('local node is not storer', () => {
|
|
104
|
+
beforeEach(() => {
|
|
105
|
+
const localPeerDescriptor = getNodeCloseToData(NODE_COUNT - 1)
|
|
106
|
+
storeRpcLocal = new StoreRpcLocal({
|
|
107
|
+
localDataStore: {
|
|
108
|
+
storeEntry: () => true,
|
|
109
|
+
setAllEntriesAsStale
|
|
110
|
+
} as any,
|
|
111
|
+
localPeerDescriptor,
|
|
112
|
+
replicateDataToContact,
|
|
113
|
+
getStorers: () => getClosestNodes(getDhtAddressFromRaw(DATA_ENTRY.key), ALL_NODES)
|
|
114
|
+
.filter((peerDescriptor) => !areEqualPeerDescriptors(peerDescriptor, localPeerDescriptor))
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('storeData', async () => {
|
|
119
|
+
const request = StoreDataRequest.create({
|
|
120
|
+
key: DATA_ENTRY.key
|
|
121
|
+
})
|
|
122
|
+
await storeRpcLocal.storeData(request)
|
|
123
|
+
expect(setAllEntriesAsStale).toHaveBeenCalled()
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('replicateData', async () => {
|
|
127
|
+
const request = {
|
|
128
|
+
entry: DATA_ENTRY
|
|
129
|
+
}
|
|
130
|
+
await storeRpcLocal.replicateData(request as any, { incomingSourceDescriptor: createMockPeerDescriptor() } as any)
|
|
131
|
+
expect(setAllEntriesAsStale).toHaveBeenCalledTimes(1)
|
|
132
|
+
// Wait for setImmediate
|
|
133
|
+
await wait(50)
|
|
134
|
+
expect(replicateDataToContact).toHaveBeenCalledTimes(1)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
describe('data was not stored', () => {
|
|
140
|
+
|
|
141
|
+
beforeEach(() => {
|
|
142
|
+
const localPeerDescriptor = getNodeCloseToData(1)
|
|
143
|
+
storeRpcLocal = new StoreRpcLocal({
|
|
144
|
+
localDataStore: {
|
|
145
|
+
storeEntry: () => false,
|
|
146
|
+
setAllEntriesAsStale
|
|
147
|
+
} as any,
|
|
148
|
+
localPeerDescriptor,
|
|
149
|
+
replicateDataToContact,
|
|
150
|
+
getStorers: () => getClosestNodes(getDhtAddressFromRaw(DATA_ENTRY.key), ALL_NODES)
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it('replicateData', async () => {
|
|
155
|
+
const request = {
|
|
156
|
+
entry: DATA_ENTRY
|
|
157
|
+
}
|
|
158
|
+
await storeRpcLocal.replicateData(request as any, { incomingSourceDescriptor: createMockPeerDescriptor() } as any)
|
|
159
|
+
expect(setAllEntriesAsStale).toHaveBeenCalledTimes(0)
|
|
160
|
+
// Wait for setImmediate
|
|
161
|
+
await wait(50)
|
|
162
|
+
expect(replicateDataToContact).toHaveBeenCalledTimes(0)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
2
|
import { WebsocketConnector } from '../../src/connection/websocket/WebsocketConnector'
|
|
3
3
|
import { NodeType } from '../../src/proto/packages/dht/protos/DhtRpc'
|
|
4
|
-
import { MockTransport } from '../utils/mock/
|
|
4
|
+
import { MockTransport } from '../utils/mock/MockTransport'
|
|
5
5
|
import { createMockPeerDescriptor } from '../utils/utils'
|
|
6
6
|
|
|
7
7
|
describe('WebsocketConnector', () => {
|
|
@@ -27,7 +27,7 @@ describe('connectivityRequestHandler', () => {
|
|
|
27
27
|
await once(httpServer, 'listening')
|
|
28
28
|
connection = new EventEmitter()
|
|
29
29
|
connection.send = jest.fn()
|
|
30
|
-
connection.
|
|
30
|
+
connection.getRemoteIpAddress = () => HOST
|
|
31
31
|
})
|
|
32
32
|
|
|
33
33
|
afterEach(async () => {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { range, sampleSize, sortBy } from 'lodash'
|
|
2
|
+
import { getDistance } from '../../src/dht/PeerManager'
|
|
3
|
+
import { getClosestNodes } from '../../src/dht/contact/getClosestNodes'
|
|
4
|
+
import { DhtAddress, createRandomDhtAddress, getNodeIdFromPeerDescriptor, getRawFromDhtAddress } from '../../src/identifiers'
|
|
5
|
+
import { createMockPeerDescriptor } from '../utils/utils'
|
|
6
|
+
import { PeerDescriptor } from '../../src/exports'
|
|
7
|
+
|
|
8
|
+
describe('getClosestNodes', () => {
|
|
9
|
+
|
|
10
|
+
it('happy path', () => {
|
|
11
|
+
const peerDescriptors = range(10).map(() => createMockPeerDescriptor())
|
|
12
|
+
const referenceId = createRandomDhtAddress()
|
|
13
|
+
const excluded = new Set<DhtAddress>(sampleSize(peerDescriptors.map((n) => getNodeIdFromPeerDescriptor(n), 2)))
|
|
14
|
+
|
|
15
|
+
const actual = getClosestNodes(
|
|
16
|
+
referenceId,
|
|
17
|
+
peerDescriptors,
|
|
18
|
+
{
|
|
19
|
+
maxCount: 5,
|
|
20
|
+
excludedNodeIds: excluded
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
const expected = sortBy(
|
|
25
|
+
peerDescriptors.filter((n) => !excluded.has(getNodeIdFromPeerDescriptor(n))),
|
|
26
|
+
(peerDescriptor: PeerDescriptor) => getDistance(peerDescriptor.nodeId, getRawFromDhtAddress(referenceId))
|
|
27
|
+
).slice(0, 5)
|
|
28
|
+
expect(actual).toEqual(expected)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
@@ -2,8 +2,10 @@ import { EventEmitter } from 'eventemitter3'
|
|
|
2
2
|
import { DhtAddress, getDhtAddressFromRaw, getNodeIdFromPeerDescriptor } from '../../src/identifiers'
|
|
3
3
|
import { Message, PeerDescriptor } from '../../src/proto/packages/dht/protos/DhtRpc'
|
|
4
4
|
import { DEFAULT_SEND_OPTIONS, ITransport, SendOptions, TransportEvents } from '../../src/transport/ITransport'
|
|
5
|
+
import { ConnectionsView } from '../../src/exports'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
// TODO extract ConnectionsView functionality to FakeConnectionsView
|
|
8
|
+
class FakeTransport extends EventEmitter<TransportEvents> implements ITransport, ConnectionsView {
|
|
7
9
|
|
|
8
10
|
private onSend: (msg: Message) => void
|
|
9
11
|
private readonly localPeerDescriptor: PeerDescriptor
|
|
@@ -60,7 +62,7 @@ export class FakeEnvironment {
|
|
|
60
62
|
|
|
61
63
|
private transports: FakeTransport[] = []
|
|
62
64
|
|
|
63
|
-
createTransport(peerDescriptor: PeerDescriptor):
|
|
65
|
+
createTransport(peerDescriptor: PeerDescriptor): FakeTransport {
|
|
64
66
|
const transport = new FakeTransport(peerDescriptor, (msg) => {
|
|
65
67
|
const targetNode = getDhtAddressFromRaw(msg.targetDescriptor!.nodeId)
|
|
66
68
|
const targetTransport = this.transports.find((t) => getNodeIdFromPeerDescriptor(t.getLocalPeerDescriptor()) === targetNode)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PeerDescriptor } from '../../../src/proto/packages/dht/protos/DhtRpc'
|
|
2
|
+
|
|
3
|
+
export class MockConnectionsView {
|
|
4
|
+
// eslint-disable-next-line class-methods-use-this
|
|
5
|
+
getConnections(): PeerDescriptor[] {
|
|
6
|
+
return []
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line class-methods-use-this
|
|
10
|
+
getConnectionCount(): number {
|
|
11
|
+
return 0
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// eslint-disable-next-line class-methods-use-this
|
|
15
|
+
hasConnection(): boolean {
|
|
16
|
+
return false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -14,21 +14,6 @@ export class MockTransport extends EventEmitter<TransportEvents> implements ITra
|
|
|
14
14
|
return PeerDescriptor.create()
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
// eslint-disable-next-line class-methods-use-this
|
|
18
|
-
getConnections(): PeerDescriptor[] {
|
|
19
|
-
return []
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// eslint-disable-next-line class-methods-use-this
|
|
23
|
-
getConnectionCount(): number {
|
|
24
|
-
return 0
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// eslint-disable-next-line class-methods-use-this
|
|
28
|
-
hasConnection(): boolean {
|
|
29
|
-
return false
|
|
30
|
-
}
|
|
31
|
-
|
|
32
17
|
// eslint-disable-next-line class-methods-use-this
|
|
33
18
|
stop(): void {
|
|
34
19
|
|
package/test/utils/utils.ts
CHANGED
|
@@ -89,6 +89,7 @@ export const createMockConnectionDhtNode = async (
|
|
|
89
89
|
const opts = {
|
|
90
90
|
peerDescriptor: peerDescriptor,
|
|
91
91
|
transport: mockConnectionManager,
|
|
92
|
+
connectionsView: mockConnectionManager,
|
|
92
93
|
connectionLocker: mockConnectionManager,
|
|
93
94
|
numberOfNodesPerKBucket,
|
|
94
95
|
maxConnections: maxConnections,
|
|
@@ -115,7 +116,9 @@ export const createMockConnectionLayer1Node = async (
|
|
|
115
116
|
type: NodeType.NODEJS,
|
|
116
117
|
}
|
|
117
118
|
const node = new DhtNode({
|
|
118
|
-
peerDescriptor: descriptor,
|
|
119
|
+
peerDescriptor: descriptor,
|
|
120
|
+
transport: layer0Node,
|
|
121
|
+
connectionsView: layer0Node.getConnectionsView(),
|
|
119
122
|
serviceId: serviceId ? serviceId : 'layer1', numberOfNodesPerKBucket,
|
|
120
123
|
rpcRequestTimeout: 10000
|
|
121
124
|
})
|
package/tsconfig.jest.json
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
{ "path": "../test-utils/tsconfig.node.json" },
|
|
19
19
|
{ "path": "../proto-rpc/tsconfig.node.json" },
|
|
20
20
|
{ "path": "../autocertifier-client/tsconfig.node.json" },
|
|
21
|
-
{ "path": "../cdn-location/tsconfig.node.json" }
|
|
21
|
+
{ "path": "../cdn-location/tsconfig.node.json" },
|
|
22
|
+
{ "path": "../geoip-location/tsconfig.node.json" }
|
|
22
23
|
]
|
|
23
24
|
}
|
package/tsconfig.node.json
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
{ "path": "../test-utils/tsconfig.node.json" },
|
|
18
18
|
{ "path": "../proto-rpc/tsconfig.node.json" },
|
|
19
19
|
{ "path": "../autocertifier-client/tsconfig.node.json" },
|
|
20
|
-
{ "path": "../cdn-location/tsconfig.node.json" }
|
|
20
|
+
{ "path": "../cdn-location/tsconfig.node.json" },
|
|
21
|
+
{ "path": "../geoip-location/tsconfig.node.json" }
|
|
21
22
|
]
|
|
22
23
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ManagedWebrtcConnection.js","sourceRoot":"","sources":["../../../src/connection/ManagedWebrtcConnection.ts"],"names":[],"mappings":";;;AACA,+CAA8C;AAC9C,2DAAuD;AAGvD,MAAa,uBAAwB,SAAQ,qCAAiB;IAE1D,YAAY,mBAAmC,EAC3C,oBAA2C,EAC3C,mBAA0C;QAE1C,KAAK,CACD,mBAAmB,EACnB,4BAAc,CAAC,MAAM,EACrB,oBAAoB,EACpB,mBAAmB,CACtB,CAAA;IACL,CAAC;IAEM,mBAAmB;QACtB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,kBAAqD,CAAA;QACrE,CAAC;aAAM,CAAC;YACJ,OAAO,IAAI,CAAC,kBAAqD,CAAA;QACrE,CAAC;IACL,CAAC;CACJ;AArBD,0DAqBC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getClosestContacts.js","sourceRoot":"","sources":["../../../../src/dht/contact/getClosestContacts.ts"],"names":[],"mappings":";;;AACA,2DAAuD;AAEhD,MAAM,kBAAkB,GAAG,CAC9B,WAAuB,EACvB,QAAqB,EACrB,IAGC,EACE,EAAE;IACL,MAAM,IAAI,GAAG,IAAI,qCAAiB,CAAI;QAClC,WAAW;QACX,yBAAyB,EAAE,IAAI;QAC/B,eAAe,EAAE,IAAI,EAAE,eAAe;QACtC,OAAO,EAAE,IAAI,EAAE,QAAQ;KAC1B,CAAC,CAAA;IACF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAA;AACpC,CAAC,CAAA;AAlBY,QAAA,kBAAkB,sBAkB9B"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { range, sampleSize, sortBy, without } from 'lodash'
|
|
2
|
-
import { getDistance } from '../../src/dht/PeerManager'
|
|
3
|
-
import { getClosestContacts } from '../../src/dht/contact/getClosestContacts'
|
|
4
|
-
import { DhtAddress, createRandomDhtAddress, getRawFromDhtAddress } from '../../src/identifiers'
|
|
5
|
-
|
|
6
|
-
describe('getClosestContacts', () => {
|
|
7
|
-
|
|
8
|
-
it('happy path', () => {
|
|
9
|
-
const nodeIds = range(10).map(() => createRandomDhtAddress())
|
|
10
|
-
const referenceId = createRandomDhtAddress()
|
|
11
|
-
const excluded = new Set<DhtAddress>(sampleSize(nodeIds, 2))
|
|
12
|
-
|
|
13
|
-
const actual = getClosestContacts(
|
|
14
|
-
referenceId,
|
|
15
|
-
nodeIds.map((nodeId) => ({ getNodeId: () => nodeId })),
|
|
16
|
-
{
|
|
17
|
-
maxCount: 5,
|
|
18
|
-
excludedNodeIds: excluded
|
|
19
|
-
}
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
const expected = sortBy(
|
|
23
|
-
without(nodeIds, ...Array.from(excluded.values())),
|
|
24
|
-
(n: DhtAddress) => getDistance(getRawFromDhtAddress(n), getRawFromDhtAddress(referenceId))
|
|
25
|
-
).slice(0, 5)
|
|
26
|
-
expect(actual.map((n) => n.getNodeId())).toEqual(expected)
|
|
27
|
-
})
|
|
28
|
-
})
|
|
File without changes
|