@streamr/trackerless-network 100.2.5-beta.1 → 101.0.0-beta.1
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 +6 -6
- package/dist/src/NetworkNode.js +1 -1
- package/dist/src/NetworkNode.js.map +1 -1
- package/dist/src/NetworkStack.d.ts +5 -5
- package/dist/src/NetworkStack.js +21 -21
- package/dist/src/NetworkStack.js.map +1 -1
- package/dist/src/exports.d.ts +2 -2
- package/dist/src/exports.js +2 -2
- package/dist/src/exports.js.map +1 -1
- package/dist/src/logic/ContentDeliveryLayerNode.d.ts +5 -5
- package/dist/src/logic/ContentDeliveryLayerNode.js +85 -85
- package/dist/src/logic/ContentDeliveryLayerNode.js.map +1 -1
- package/dist/src/logic/ContentDeliveryManager.d.ts +11 -12
- package/dist/src/logic/ContentDeliveryManager.js +65 -61
- package/dist/src/logic/ContentDeliveryManager.js.map +1 -1
- package/dist/src/logic/ContentDeliveryRpcLocal.d.ts +5 -5
- package/dist/src/logic/ContentDeliveryRpcLocal.js +9 -9
- package/dist/src/logic/ContentDeliveryRpcLocal.js.map +1 -1
- package/dist/src/logic/{Layer0Node.d.ts → ControlLayerNode.d.ts} +1 -1
- package/dist/src/logic/{Layer0Node.js → ControlLayerNode.js} +1 -1
- package/dist/src/logic/ControlLayerNode.js.map +1 -0
- package/dist/src/logic/{Layer1Node.d.ts → DiscoveryLayerNode.d.ts} +8 -8
- package/dist/src/logic/{Layer1Node.js → DiscoveryLayerNode.js} +1 -1
- package/dist/src/logic/DiscoveryLayerNode.js.map +1 -0
- package/dist/src/logic/PeerDescriptorStoreManager.d.ts +28 -0
- package/dist/src/logic/PeerDescriptorStoreManager.js +79 -0
- package/dist/src/logic/PeerDescriptorStoreManager.js.map +1 -0
- package/dist/src/logic/StreamPartNetworkSplitAvoidance.d.ts +5 -5
- package/dist/src/logic/StreamPartNetworkSplitAvoidance.js +8 -8
- package/dist/src/logic/StreamPartNetworkSplitAvoidance.js.map +1 -1
- package/dist/src/logic/StreamPartReconnect.d.ts +5 -5
- package/dist/src/logic/StreamPartReconnect.js +10 -10
- package/dist/src/logic/StreamPartReconnect.js.map +1 -1
- package/dist/src/logic/createContentDeliveryLayerNode.d.ts +3 -3
- package/dist/src/logic/createContentDeliveryLayerNode.js +34 -34
- package/dist/src/logic/createContentDeliveryLayerNode.js.map +1 -1
- package/dist/src/logic/inspect/InspectSession.d.ts +3 -3
- package/dist/src/logic/inspect/InspectSession.js +5 -5
- package/dist/src/logic/inspect/InspectSession.js.map +1 -1
- package/dist/src/logic/inspect/Inspector.d.ts +2 -2
- package/dist/src/logic/inspect/Inspector.js +8 -8
- package/dist/src/logic/inspect/Inspector.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.d.ts +4 -4
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js +24 -24
- package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.d.ts +1 -1
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js +4 -4
- package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/Handshaker.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/Handshaker.js +37 -37
- package/dist/src/logic/neighbor-discovery/Handshaker.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborFinder.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js +9 -9
- package/dist/src/logic/neighbor-discovery/NeighborFinder.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +12 -12
- package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.d.ts +3 -3
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js +14 -14
- package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js.map +1 -1
- package/dist/src/logic/proxy/ProxyClient.d.ts +3 -3
- package/dist/src/logic/proxy/ProxyClient.js +25 -25
- package/dist/src/logic/proxy/ProxyClient.js.map +1 -1
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.d.ts +3 -3
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js +10 -10
- package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js.map +1 -1
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.d.ts +3 -3
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js +11 -11
- package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +4 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +8 -8
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +11 -3
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +7 -5
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +2 -2
- package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js +1 -1
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js +1 -1
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.d.ts +6 -23
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js +5 -23
- package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js.map +1 -1
- package/dist/test/benchmark/first-message.js +7 -7
- package/dist/test/benchmark/first-message.js.map +1 -1
- package/dist/test/utils/utils.d.ts +2 -2
- package/dist/test/utils/utils.js +3 -3
- package/dist/test/utils/utils.js.map +1 -1
- package/package.json +6 -6
- package/protos/NetworkRpc.proto +3 -9
- package/src/NetworkNode.ts +1 -1
- package/src/NetworkStack.ts +24 -24
- package/src/exports.ts +2 -2
- package/src/logic/ContentDeliveryLayerNode.ts +112 -112
- package/src/logic/ContentDeliveryManager.ts +71 -67
- package/src/logic/ContentDeliveryRpcLocal.ts +12 -12
- package/src/logic/{Layer0Node.ts → ControlLayerNode.ts} +1 -1
- package/src/logic/{Layer1Node.ts → DiscoveryLayerNode.ts} +8 -8
- package/src/logic/PeerDescriptorStoreManager.ts +97 -0
- package/src/logic/StreamPartNetworkSplitAvoidance.ts +11 -11
- package/src/logic/StreamPartReconnect.ts +12 -12
- package/src/logic/createContentDeliveryLayerNode.ts +38 -38
- package/src/logic/inspect/InspectSession.ts +6 -6
- package/src/logic/inspect/Inspector.ts +9 -9
- package/src/logic/neighbor-discovery/HandshakeRpcLocal.ts +26 -26
- package/src/logic/neighbor-discovery/HandshakeRpcRemote.ts +6 -6
- package/src/logic/neighbor-discovery/Handshaker.ts +45 -45
- package/src/logic/neighbor-discovery/NeighborFinder.ts +10 -10
- package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +14 -14
- package/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.ts +17 -17
- package/src/logic/proxy/ProxyClient.ts +26 -26
- package/src/logic/proxy/ProxyConnectionRpcLocal.ts +12 -12
- package/src/logic/temporary-connection/TemporaryConnectionRpcLocal.ts +13 -13
- package/src/proto/google/protobuf/any.ts +1 -1
- package/src/proto/google/protobuf/empty.ts +1 -1
- package/src/proto/google/protobuf/timestamp.ts +1 -1
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +9 -9
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +3 -3
- package/src/proto/packages/dht/protos/DhtRpc.ts +15 -5
- package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +1 -1
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +1 -1
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +1 -1
- package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +10 -27
- package/test/benchmark/StreamPartIdDataKeyDistribution.test.ts +1 -1
- package/test/benchmark/first-message.ts +9 -9
- package/test/end-to-end/content-delivery-layer-node-with-real-connections.test.ts +12 -12
- package/test/end-to-end/proxy-and-full-node.test.ts +4 -4
- package/test/integration/ContentDeliveryLayerNode-Layer1Node-Latencies.test.ts +19 -19
- package/test/integration/ContentDeliveryLayerNode-Layer1Node.test.ts +19 -19
- package/test/integration/ContentDeliveryManager.test.ts +11 -11
- package/test/integration/Inspect.test.ts +1 -1
- package/test/integration/Propagation.test.ts +6 -6
- package/test/integration/joining-streams-on-offline-peers.test.ts +3 -3
- package/test/integration/stream-without-default-entrypoints.test.ts +2 -2
- package/test/integration/streamEntryPointReplacing.test.ts +2 -2
- package/test/unit/ContentDeliveryLayerNode.test.ts +11 -11
- package/test/unit/ContentDeliveryManager.test.ts +2 -2
- package/test/unit/{EntrypointDiscovery.test.ts → PeerDescriptorStoreManager.test.ts} +28 -29
- package/test/unit/StreamPartIDDataKey.test.ts +1 -1
- package/test/unit/StreamPartNetworkSplitAvoidance.test.ts +8 -8
- package/test/unit/StreamPartReconnect.test.ts +9 -9
- package/test/utils/fake/FakePeerDescriptorStoreManager.ts +29 -0
- package/test/utils/mock/{MockLayer0Node.ts → MockControlLayerNode.ts} +2 -2
- package/test/utils/mock/{MockLayer1Node.ts → MockDiscoveryLayerNode.ts} +2 -2
- package/test/utils/utils.ts +5 -5
- package/dist/src/logic/EntryPointDiscovery.d.ts +0 -27
- package/dist/src/logic/EntryPointDiscovery.js +0 -80
- package/dist/src/logic/EntryPointDiscovery.js.map +0 -1
- package/dist/src/logic/Layer0Node.js.map +0 -1
- package/dist/src/logic/Layer1Node.js.map +0 -1
- package/src/logic/EntryPointDiscovery.ts +0 -100
- package/test/utils/fake/FakeEntryPointDiscovery.ts +0 -29
|
@@ -3,7 +3,7 @@ import { NodeList } from '../../src/logic/NodeList'
|
|
|
3
3
|
import { ContentDeliveryLayerNode } from '../../src/logic/ContentDeliveryLayerNode'
|
|
4
4
|
import { createContentDeliveryLayerNode } from '../../src/logic/createContentDeliveryLayerNode'
|
|
5
5
|
import { MockHandshaker } from '../utils/mock/MockHandshaker'
|
|
6
|
-
import {
|
|
6
|
+
import { MockDiscoveryLayerNode } from '../utils/mock/MockDiscoveryLayerNode'
|
|
7
7
|
import { MockNeighborFinder } from '../utils/mock/MockNeighborFinder'
|
|
8
8
|
import { MockNeighborUpdateManager } from '../utils/mock/MockNeighborUpdateManager'
|
|
9
9
|
import { MockTransport } from '../utils/mock/MockTransport'
|
|
@@ -20,7 +20,7 @@ describe('ContentDeliveryLayerNode', () => {
|
|
|
20
20
|
let nearbyNodeView: NodeList
|
|
21
21
|
let randomNodeView: NodeList
|
|
22
22
|
|
|
23
|
-
let
|
|
23
|
+
let discoveryLayerNode: MockDiscoveryLayerNode
|
|
24
24
|
|
|
25
25
|
beforeEach(async () => {
|
|
26
26
|
const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
|
|
@@ -28,7 +28,7 @@ describe('ContentDeliveryLayerNode', () => {
|
|
|
28
28
|
neighbors = new NodeList(nodeId, 10)
|
|
29
29
|
randomNodeView = new NodeList(nodeId, 10)
|
|
30
30
|
nearbyNodeView = new NodeList(nodeId, 10)
|
|
31
|
-
|
|
31
|
+
discoveryLayerNode = new MockDiscoveryLayerNode()
|
|
32
32
|
|
|
33
33
|
contentDeliveryLayerNode = createContentDeliveryLayerNode({
|
|
34
34
|
neighbors,
|
|
@@ -36,7 +36,7 @@ describe('ContentDeliveryLayerNode', () => {
|
|
|
36
36
|
nearbyNodeView,
|
|
37
37
|
transport: new MockTransport(),
|
|
38
38
|
localPeerDescriptor: peerDescriptor,
|
|
39
|
-
|
|
39
|
+
discoveryLayerNode,
|
|
40
40
|
connectionLocker: mockConnectionLocker,
|
|
41
41
|
handshaker: new MockHandshaker() as any,
|
|
42
42
|
neighborUpdateManager: new MockNeighborUpdateManager() as any,
|
|
@@ -68,8 +68,8 @@ describe('ContentDeliveryLayerNode', () => {
|
|
|
68
68
|
it('Adds Closest Nodes from layer1 nearbyContactAdded event to nearbyNodeView', async () => {
|
|
69
69
|
const peerDescriptor1 = createMockPeerDescriptor()
|
|
70
70
|
const peerDescriptor2 = createMockPeerDescriptor()
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
discoveryLayerNode.setClosestContacts([peerDescriptor1, peerDescriptor2])
|
|
72
|
+
discoveryLayerNode.emit('nearbyContactAdded', peerDescriptor1)
|
|
73
73
|
await waitForCondition(() => nearbyNodeView.size() === 2)
|
|
74
74
|
expect(nearbyNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor1))).toBeTruthy()
|
|
75
75
|
expect(nearbyNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor2))).toBeTruthy()
|
|
@@ -78,8 +78,8 @@ describe('ContentDeliveryLayerNode', () => {
|
|
|
78
78
|
it('Adds Random Nodes from layer1 randomContactAdded event to randomNodeView', async () => {
|
|
79
79
|
const peerDescriptor1 = createMockPeerDescriptor()
|
|
80
80
|
const peerDescriptor2 = createMockPeerDescriptor()
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
discoveryLayerNode.setRandomContacts([peerDescriptor1, peerDescriptor2])
|
|
82
|
+
discoveryLayerNode.emit('randomContactAdded', peerDescriptor1)
|
|
83
83
|
await waitForCondition(() => randomNodeView.size() === 2)
|
|
84
84
|
expect(randomNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor1))).toBeTruthy()
|
|
85
85
|
expect(randomNodeView.get(getNodeIdFromPeerDescriptor(peerDescriptor2))).toBeTruthy()
|
|
@@ -88,9 +88,9 @@ describe('ContentDeliveryLayerNode', () => {
|
|
|
88
88
|
it('Adds Nodes from layer1 neighbors to nearbyNodeView if its size is below nodeViewSize', async () => {
|
|
89
89
|
const peerDescriptor1 = createMockPeerDescriptor()
|
|
90
90
|
const peerDescriptor2 = createMockPeerDescriptor()
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
discoveryLayerNode.addNewRandomPeerToKBucket()
|
|
92
|
+
discoveryLayerNode.setClosestContacts([peerDescriptor1, peerDescriptor2])
|
|
93
|
+
discoveryLayerNode.emit('nearbyContactAdded', peerDescriptor1)
|
|
94
94
|
await waitForCondition(() => {
|
|
95
95
|
return nearbyNodeView.size() === 3
|
|
96
96
|
}, 20000)
|
|
@@ -3,7 +3,7 @@ import { StreamPartIDUtils } from '@streamr/protocol'
|
|
|
3
3
|
import { randomEthereumAddress } from '@streamr/test-utils'
|
|
4
4
|
import { waitForCondition } from '@streamr/utils'
|
|
5
5
|
import { ContentDeliveryManager } from '../../src/logic/ContentDeliveryManager'
|
|
6
|
-
import {
|
|
6
|
+
import { MockControlLayerNode } from '../utils/mock/MockControlLayerNode'
|
|
7
7
|
import { MockTransport } from '../utils/mock/MockTransport'
|
|
8
8
|
import { createMockPeerDescriptor, createStreamMessage, mockConnectionLocker } from '../utils/utils'
|
|
9
9
|
import { ProxyDirection } from '../../src/proto/packages/trackerless-network/protos/NetworkRpc'
|
|
@@ -15,7 +15,7 @@ describe('ContentDeliveryManager', () => {
|
|
|
15
15
|
|
|
16
16
|
beforeEach(async () => {
|
|
17
17
|
manager = new ContentDeliveryManager({})
|
|
18
|
-
const mockLayer0 = new
|
|
18
|
+
const mockLayer0 = new MockControlLayerNode(peerDescriptor)
|
|
19
19
|
await manager.start(mockLayer0, new MockTransport(), mockConnectionLocker)
|
|
20
20
|
})
|
|
21
21
|
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { PeerDescriptor, areEqualPeerDescriptors } from '@streamr/dht'
|
|
2
|
-
import { StreamPartIDUtils } from '@streamr/protocol'
|
|
1
|
+
import { PeerDescriptor, areEqualPeerDescriptors, createRandomDhtAddress } from '@streamr/dht'
|
|
3
2
|
import { wait } from '@streamr/utils'
|
|
4
|
-
import {
|
|
3
|
+
import { PeerDescriptorStoreManager } from '../../src/logic/PeerDescriptorStoreManager'
|
|
5
4
|
import { Any } from '../../src/proto/google/protobuf/any'
|
|
6
5
|
import { DataEntry } from '../../src/proto/packages/dht/protos/DhtRpc'
|
|
7
6
|
import { createMockPeerDescriptor } from '../utils/utils'
|
|
8
7
|
|
|
9
|
-
const
|
|
8
|
+
const KEY = createRandomDhtAddress()
|
|
10
9
|
|
|
11
|
-
describe('
|
|
10
|
+
describe('PeerDescriptorStoreManager', () => {
|
|
12
11
|
|
|
13
|
-
let
|
|
14
|
-
let
|
|
12
|
+
let withData: PeerDescriptorStoreManager
|
|
13
|
+
let withoutData: PeerDescriptorStoreManager
|
|
15
14
|
let storeCalled: number
|
|
16
15
|
|
|
17
16
|
const peerDescriptor = createMockPeerDescriptor()
|
|
@@ -35,68 +34,68 @@ describe('EntryPointDiscovery', () => {
|
|
|
35
34
|
deleted: true
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
const
|
|
37
|
+
const fakeFetchDataFromDht = async (): Promise<DataEntry[]> => {
|
|
39
38
|
return [fakeData, fakeDeletedData]
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
const
|
|
41
|
+
const fakeStoreDataToDht = async (): Promise<PeerDescriptor[]> => {
|
|
43
42
|
storeCalled++
|
|
44
43
|
return [peerDescriptor]
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
const
|
|
46
|
+
const fakeEmptyFetchDataFromDht = async (): Promise<DataEntry[]> => {
|
|
48
47
|
return []
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
const
|
|
50
|
+
const fakeDeleteDataFromDht = async (): Promise<void> => {}
|
|
52
51
|
|
|
53
52
|
beforeEach(() => {
|
|
54
53
|
storeCalled = 0
|
|
55
|
-
|
|
54
|
+
withData = new PeerDescriptorStoreManager({
|
|
56
55
|
localPeerDescriptor: peerDescriptor,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
key: KEY,
|
|
57
|
+
fetchDataFromDht: fakeFetchDataFromDht,
|
|
58
|
+
storeDataToDht: fakeStoreDataToDht,
|
|
59
|
+
deleteDataFromDht: fakeDeleteDataFromDht,
|
|
61
60
|
storeInterval: 2000
|
|
62
61
|
})
|
|
63
|
-
|
|
62
|
+
withoutData = new PeerDescriptorStoreManager({
|
|
64
63
|
localPeerDescriptor: peerDescriptor,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
key: KEY,
|
|
65
|
+
fetchDataFromDht: fakeEmptyFetchDataFromDht,
|
|
66
|
+
storeDataToDht: fakeStoreDataToDht,
|
|
67
|
+
deleteDataFromDht: fakeDeleteDataFromDht,
|
|
69
68
|
storeInterval: 2000
|
|
70
69
|
})
|
|
71
70
|
})
|
|
72
71
|
|
|
73
72
|
afterEach(() => {
|
|
74
|
-
|
|
73
|
+
withData.destroy()
|
|
75
74
|
})
|
|
76
75
|
|
|
77
76
|
it('discoverEntryPoints filters deleted data', async () => {
|
|
78
|
-
const res = await
|
|
77
|
+
const res = await withData.fetchNodes()
|
|
79
78
|
expect(res.length).toBe(1)
|
|
80
79
|
expect(areEqualPeerDescriptors(res[0], peerDescriptor)).toBe(true)
|
|
81
80
|
})
|
|
82
81
|
|
|
83
82
|
it('discoverEntryPoints without results', async () => {
|
|
84
|
-
const res = await
|
|
83
|
+
const res = await withoutData.fetchNodes()
|
|
85
84
|
expect(res.length).toBe(0)
|
|
86
85
|
})
|
|
87
86
|
|
|
88
87
|
it('store on stream without saturated entrypoint count', async () => {
|
|
89
|
-
await
|
|
88
|
+
await withData.storeAndKeepLocalNode()
|
|
90
89
|
expect(storeCalled).toEqual(1)
|
|
91
|
-
expect(
|
|
90
|
+
expect(withData.isLocalNodeStored()).toEqual(true)
|
|
92
91
|
})
|
|
93
92
|
|
|
94
93
|
it('will keep stored until destroyed', async () => {
|
|
95
|
-
await
|
|
94
|
+
await withData.storeAndKeepLocalNode()
|
|
96
95
|
expect(storeCalled).toEqual(1)
|
|
97
|
-
expect(
|
|
96
|
+
expect(withData.isLocalNodeStored()).toEqual(true)
|
|
98
97
|
await wait(4500)
|
|
99
|
-
await
|
|
98
|
+
await withData.destroy()
|
|
100
99
|
// we have configured storeInterval to 2 seconds, i.e. after 4.5 seconds it should have been called 2 more items
|
|
101
100
|
expect(storeCalled).toEqual(3)
|
|
102
101
|
})
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
import { MIN_NEIGHBOR_COUNT } from '../../src/logic/StreamPartNetworkSplitAvoidance'
|
|
2
2
|
import { StreamPartNetworkSplitAvoidance } from '../../src/logic/StreamPartNetworkSplitAvoidance'
|
|
3
|
-
import {
|
|
3
|
+
import { MockDiscoveryLayerNode } from '../utils/mock/MockDiscoveryLayerNode'
|
|
4
4
|
|
|
5
5
|
describe('StreamPartNetworkSplitAvoidance', () => {
|
|
6
6
|
|
|
7
7
|
let avoidance: StreamPartNetworkSplitAvoidance
|
|
8
|
-
let
|
|
8
|
+
let discoveryLayerNode: MockDiscoveryLayerNode
|
|
9
9
|
|
|
10
10
|
beforeEach(() => {
|
|
11
|
-
|
|
11
|
+
discoveryLayerNode = new MockDiscoveryLayerNode()
|
|
12
12
|
avoidance = new StreamPartNetworkSplitAvoidance({
|
|
13
|
-
|
|
13
|
+
discoveryLayerNode,
|
|
14
14
|
discoverEntryPoints: async () => {
|
|
15
|
-
|
|
16
|
-
return
|
|
15
|
+
discoveryLayerNode.addNewRandomPeerToKBucket()
|
|
16
|
+
return discoveryLayerNode.getNeighbors()
|
|
17
17
|
},
|
|
18
18
|
exponentialRunOfBaseDelay: 1
|
|
19
19
|
})
|
|
20
20
|
})
|
|
21
21
|
|
|
22
22
|
afterEach(() => {
|
|
23
|
-
|
|
23
|
+
discoveryLayerNode.stop()
|
|
24
24
|
avoidance.destroy()
|
|
25
25
|
})
|
|
26
26
|
|
|
27
27
|
it('runs avoidance until number of neighbors is above MIN_NEIGHBOR_COUNT', async () => {
|
|
28
28
|
await avoidance.avoidNetworkSplit()
|
|
29
|
-
expect(
|
|
29
|
+
expect(discoveryLayerNode.getNeighborCount()).toBeGreaterThan(MIN_NEIGHBOR_COUNT)
|
|
30
30
|
})
|
|
31
31
|
|
|
32
32
|
})
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PeerDescriptorStoreManager } from '../../src/logic/PeerDescriptorStoreManager'
|
|
2
2
|
import { StreamPartReconnect } from '../../src/logic/StreamPartReconnect'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { MockDiscoveryLayerNode } from '../utils/mock/MockDiscoveryLayerNode'
|
|
4
|
+
import { createFakePeerDescriptorStoreManager } from '../utils/fake/FakePeerDescriptorStoreManager'
|
|
5
5
|
import { waitForCondition } from '@streamr/utils'
|
|
6
6
|
|
|
7
7
|
describe('StreamPartReconnect', () => {
|
|
8
8
|
|
|
9
|
-
let
|
|
10
|
-
let
|
|
9
|
+
let peerDescriptorSoreManager: PeerDescriptorStoreManager
|
|
10
|
+
let discoveryLayerNode: MockDiscoveryLayerNode
|
|
11
11
|
let streamPartReconnect: StreamPartReconnect
|
|
12
12
|
|
|
13
13
|
beforeEach(() => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
streamPartReconnect = new StreamPartReconnect(
|
|
14
|
+
peerDescriptorSoreManager = createFakePeerDescriptorStoreManager()
|
|
15
|
+
discoveryLayerNode = new MockDiscoveryLayerNode()
|
|
16
|
+
streamPartReconnect = new StreamPartReconnect(discoveryLayerNode, peerDescriptorSoreManager)
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
afterEach(() => {
|
|
@@ -23,7 +23,7 @@ describe('StreamPartReconnect', () => {
|
|
|
23
23
|
it('Happy path', async () => {
|
|
24
24
|
await streamPartReconnect.reconnect(1000)
|
|
25
25
|
expect(streamPartReconnect.isRunning()).toEqual(true)
|
|
26
|
-
|
|
26
|
+
discoveryLayerNode.addNewRandomPeerToKBucket()
|
|
27
27
|
await waitForCondition(() => streamPartReconnect.isRunning() === false)
|
|
28
28
|
})
|
|
29
29
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { PeerDescriptor } from '@streamr/dht'
|
|
2
|
+
import { PeerDescriptorStoreManager } from '../../../src/logic/PeerDescriptorStoreManager'
|
|
3
|
+
|
|
4
|
+
export const createFakePeerDescriptorStoreManager = (): PeerDescriptorStoreManager => {
|
|
5
|
+
return new FakePeerDescriptorStoreManager() as unknown as PeerDescriptorStoreManager
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class FakePeerDescriptorStoreManager {
|
|
9
|
+
|
|
10
|
+
private nodes: PeerDescriptor[] = []
|
|
11
|
+
|
|
12
|
+
setNodes(nodes: PeerDescriptor[]): void {
|
|
13
|
+
this.nodes = nodes
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async fetchNodes(): Promise<PeerDescriptor[]> {
|
|
17
|
+
return this.nodes
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line class-methods-use-this
|
|
21
|
+
async storeAndKeepLocalNode(): Promise<void> {
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// eslint-disable-next-line class-methods-use-this
|
|
25
|
+
isLocalNodeStored(): boolean {
|
|
26
|
+
return true
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PeerDescriptor, DataEntry, ITransport, TransportEvents, ConnectionsView } from '@streamr/dht'
|
|
2
|
-
import {
|
|
2
|
+
import { ControlLayerNode } from '../../../src/logic/ControlLayerNode'
|
|
3
3
|
import { EventEmitter } from 'eventemitter3'
|
|
4
4
|
import { MockConnectionsView } from './MockConnectionsView'
|
|
5
5
|
|
|
6
|
-
export class
|
|
6
|
+
export class MockControlLayerNode extends EventEmitter<TransportEvents> implements ControlLayerNode {
|
|
7
7
|
|
|
8
8
|
private readonly peerDescriptor: PeerDescriptor
|
|
9
9
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PeerDescriptor, RingContacts } from '@streamr/dht'
|
|
2
2
|
import { EventEmitter } from 'eventemitter3'
|
|
3
|
-
import {
|
|
3
|
+
import { DiscoveryLayerNode, DiscoveryLayerNodeEvents } from '../../../src/logic/DiscoveryLayerNode'
|
|
4
4
|
import { createMockPeerDescriptor } from '../utils'
|
|
5
5
|
|
|
6
|
-
export class
|
|
6
|
+
export class MockDiscoveryLayerNode extends EventEmitter<DiscoveryLayerNodeEvents> implements DiscoveryLayerNode {
|
|
7
7
|
|
|
8
8
|
private readonly kbucketPeers: PeerDescriptor[] = []
|
|
9
9
|
private closestContacts: PeerDescriptor[] = []
|
package/test/utils/utils.ts
CHANGED
|
@@ -23,7 +23,7 @@ import { HandshakeRpcRemote } from '../../src/logic/neighbor-discovery/Handshake
|
|
|
23
23
|
import { NetworkNode, createNetworkNode } from '../../src/NetworkNode'
|
|
24
24
|
import { EthereumAddress, hexToBinary, utf8ToBinary } from '@streamr/utils'
|
|
25
25
|
import { StreamPartID, StreamPartIDUtils } from '@streamr/protocol'
|
|
26
|
-
import {
|
|
26
|
+
import { DiscoveryLayerNode } from '../../src/logic/DiscoveryLayerNode'
|
|
27
27
|
import { ContentDeliveryRpcClient, HandshakeRpcClient } from '../../src/proto/packages/trackerless-network/protos/NetworkRpc.client'
|
|
28
28
|
import { RpcCommunicator } from '@streamr/proto-rpc'
|
|
29
29
|
|
|
@@ -42,10 +42,10 @@ export const createMockContentDeliveryLayerNodeAndDhtNode = async (
|
|
|
42
42
|
entryPointDescriptor: PeerDescriptor,
|
|
43
43
|
streamPartId: StreamPartID,
|
|
44
44
|
simulator: Simulator
|
|
45
|
-
): Promise<[
|
|
45
|
+
): Promise<[ DiscoveryLayerNode, ContentDeliveryLayerNode ]> => {
|
|
46
46
|
const mockCm = new SimulatorTransport(localPeerDescriptor, simulator)
|
|
47
47
|
await mockCm.start()
|
|
48
|
-
const
|
|
48
|
+
const discoveryLayerNode = new DhtNode({
|
|
49
49
|
transport: mockCm,
|
|
50
50
|
connectionsView: mockCm,
|
|
51
51
|
peerDescriptor: localPeerDescriptor,
|
|
@@ -56,13 +56,13 @@ export const createMockContentDeliveryLayerNodeAndDhtNode = async (
|
|
|
56
56
|
const contentDeliveryLayerNode = createContentDeliveryLayerNode({
|
|
57
57
|
streamPartId,
|
|
58
58
|
transport: mockCm,
|
|
59
|
-
|
|
59
|
+
discoveryLayerNode,
|
|
60
60
|
connectionLocker: mockCm,
|
|
61
61
|
localPeerDescriptor,
|
|
62
62
|
rpcRequestTimeout: 5000,
|
|
63
63
|
isLocalNodeEntryPoint: () => false
|
|
64
64
|
})
|
|
65
|
-
return [
|
|
65
|
+
return [discoveryLayerNode, contentDeliveryLayerNode]
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export const createStreamMessage = (
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { DataEntry, DhtAddress, PeerDescriptor } from '@streamr/dht';
|
|
2
|
-
import { StreamPartID } from '@streamr/protocol';
|
|
3
|
-
import { Any } from '../proto/google/protobuf/any';
|
|
4
|
-
export declare const streamPartIdToDataKey: (streamPartId: StreamPartID) => DhtAddress;
|
|
5
|
-
export declare const ENTRYPOINT_STORE_LIMIT = 8;
|
|
6
|
-
interface EntryPointDiscoveryConfig {
|
|
7
|
-
streamPartId: StreamPartID;
|
|
8
|
-
localPeerDescriptor: PeerDescriptor;
|
|
9
|
-
fetchEntryPointData: (key: DhtAddress) => Promise<DataEntry[]>;
|
|
10
|
-
storeEntryPointData: (key: DhtAddress, data: Any) => Promise<PeerDescriptor[]>;
|
|
11
|
-
deleteEntryPointData: (key: DhtAddress) => Promise<void>;
|
|
12
|
-
storeInterval?: number;
|
|
13
|
-
}
|
|
14
|
-
export declare class EntryPointDiscovery {
|
|
15
|
-
private readonly abortController;
|
|
16
|
-
private readonly config;
|
|
17
|
-
private readonly storeInterval;
|
|
18
|
-
private isLocalNodeStoredAsEntryPoint;
|
|
19
|
-
constructor(config: EntryPointDiscoveryConfig);
|
|
20
|
-
discoverEntryPoints(): Promise<PeerDescriptor[]>;
|
|
21
|
-
storeAndKeepLocalNodeAsEntryPoint(): Promise<void>;
|
|
22
|
-
private storeLocalNodeAsEntryPoint;
|
|
23
|
-
private keepSelfAsEntryPoint;
|
|
24
|
-
isLocalNodeEntryPoint(): boolean;
|
|
25
|
-
destroy(): Promise<void>;
|
|
26
|
-
}
|
|
27
|
-
export {};
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EntryPointDiscovery = exports.ENTRYPOINT_STORE_LIMIT = exports.streamPartIdToDataKey = void 0;
|
|
4
|
-
const dht_1 = require("@streamr/dht");
|
|
5
|
-
const utils_1 = require("@streamr/utils");
|
|
6
|
-
const crypto_1 = require("crypto");
|
|
7
|
-
const any_1 = require("../proto/google/protobuf/any");
|
|
8
|
-
const streamPartIdToDataKey = (streamPartId) => {
|
|
9
|
-
return (0, dht_1.getDhtAddressFromRaw)(new Uint8Array(((0, crypto_1.createHash)('sha1').update(streamPartId).digest())));
|
|
10
|
-
};
|
|
11
|
-
exports.streamPartIdToDataKey = streamPartIdToDataKey;
|
|
12
|
-
const parseEntryPointData = (dataEntries) => {
|
|
13
|
-
return dataEntries.filter((entry) => !entry.deleted).map((entry) => any_1.Any.unpack(entry.data, dht_1.PeerDescriptor));
|
|
14
|
-
};
|
|
15
|
-
const logger = new utils_1.Logger(module);
|
|
16
|
-
exports.ENTRYPOINT_STORE_LIMIT = 8;
|
|
17
|
-
class EntryPointDiscovery {
|
|
18
|
-
abortController;
|
|
19
|
-
config;
|
|
20
|
-
storeInterval;
|
|
21
|
-
isLocalNodeStoredAsEntryPoint = false;
|
|
22
|
-
constructor(config) {
|
|
23
|
-
this.config = config;
|
|
24
|
-
this.abortController = new AbortController();
|
|
25
|
-
this.storeInterval = this.config.storeInterval ?? 60000;
|
|
26
|
-
}
|
|
27
|
-
async discoverEntryPoints() {
|
|
28
|
-
const dataKey = (0, exports.streamPartIdToDataKey)(this.config.streamPartId);
|
|
29
|
-
logger.trace(`Discovering entry points for key ${dataKey}`);
|
|
30
|
-
try {
|
|
31
|
-
const result = await this.config.fetchEntryPointData(dataKey);
|
|
32
|
-
return parseEntryPointData(result);
|
|
33
|
-
}
|
|
34
|
-
catch (err) {
|
|
35
|
-
return [];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
async storeAndKeepLocalNodeAsEntryPoint() {
|
|
39
|
-
if (this.abortController.signal.aborted) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
this.isLocalNodeStoredAsEntryPoint = true;
|
|
43
|
-
await this.storeLocalNodeAsEntryPoint();
|
|
44
|
-
await this.keepSelfAsEntryPoint();
|
|
45
|
-
}
|
|
46
|
-
async storeLocalNodeAsEntryPoint() {
|
|
47
|
-
const localPeerDescriptor = this.config.localPeerDescriptor;
|
|
48
|
-
const dataToStore = any_1.Any.pack(localPeerDescriptor, dht_1.PeerDescriptor);
|
|
49
|
-
try {
|
|
50
|
-
await this.config.storeEntryPointData((0, exports.streamPartIdToDataKey)(this.config.streamPartId), dataToStore);
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
logger.warn(`Failed to store self as entrypoint for ${this.config.streamPartId}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
async keepSelfAsEntryPoint() {
|
|
57
|
-
await (0, utils_1.scheduleAtInterval)(async () => {
|
|
58
|
-
logger.trace(`Attempting to keep self as entrypoint for ${this.config.streamPartId}`);
|
|
59
|
-
try {
|
|
60
|
-
const discovered = await this.discoverEntryPoints();
|
|
61
|
-
if (discovered.length < exports.ENTRYPOINT_STORE_LIMIT
|
|
62
|
-
|| discovered.some((peerDescriptor) => (0, dht_1.areEqualPeerDescriptors)(peerDescriptor, this.config.localPeerDescriptor))) {
|
|
63
|
-
await this.storeLocalNodeAsEntryPoint();
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
logger.debug(`Failed to keep self as entrypoint for ${this.config.streamPartId}`);
|
|
68
|
-
}
|
|
69
|
-
}, this.storeInterval, false, this.abortController.signal);
|
|
70
|
-
}
|
|
71
|
-
isLocalNodeEntryPoint() {
|
|
72
|
-
return this.isLocalNodeStoredAsEntryPoint;
|
|
73
|
-
}
|
|
74
|
-
async destroy() {
|
|
75
|
-
this.abortController.abort();
|
|
76
|
-
await this.config.deleteEntryPointData((0, exports.streamPartIdToDataKey)(this.config.streamPartId));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
exports.EntryPointDiscovery = EntryPointDiscovery;
|
|
80
|
-
//# sourceMappingURL=EntryPointDiscovery.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EntryPointDiscovery.js","sourceRoot":"","sources":["../../../src/logic/EntryPointDiscovery.ts"],"names":[],"mappings":";;;AAAA,sCAMqB;AAErB,0CAA2D;AAC3D,mCAAmC;AACnC,sDAAkD;AAE3C,MAAM,qBAAqB,GAAG,CAAC,YAA0B,EAAc,EAAE;IAC5E,OAAO,IAAA,0BAAoB,EAAC,IAAI,UAAU,CAAC,CAAC,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;AACnG,CAAC,CAAA;AAFY,QAAA,qBAAqB,yBAEjC;AAED,MAAM,mBAAmB,GAAG,CAAC,WAAwB,EAAoB,EAAE;IACvE,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAK,EAAE,oBAAc,CAAC,CAAC,CAAA;AAChH,CAAC,CAAA;AAED,MAAM,MAAM,GAAG,IAAI,cAAM,CAAC,MAAM,CAAC,CAAA;AAEpB,QAAA,sBAAsB,GAAG,CAAC,CAAA;AAWvC,MAAa,mBAAmB;IAEX,eAAe,CAAiB;IAChC,MAAM,CAA2B;IACjC,aAAa,CAAQ;IAC9B,6BAA6B,GAAG,KAAK,CAAA;IAE7C,YAAY,MAAiC;QACzC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;QAC5C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,KAAK,CAAA;IAC3D,CAAC;IAED,KAAK,CAAC,mBAAmB;QACrB,MAAM,OAAO,GAAG,IAAA,6BAAqB,EAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;QAC/D,MAAM,CAAC,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAA;QAC3D,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAA;YAC7D,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAA;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,OAAO,EAAE,CAAA;QACb,CAAC;IACL,CAAC;IAED,KAAK,CAAC,iCAAiC;QACnC,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtC,OAAM;QACV,CAAC;QACD,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAA;QACzC,MAAM,IAAI,CAAC,0BAA0B,EAAE,CAAA;QACvC,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAA;IACrC,CAAC;IAEO,KAAK,CAAC,0BAA0B;QACpC,MAAM,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAA;QAC3D,MAAM,WAAW,GAAG,SAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,oBAAc,CAAC,CAAA;QACjE,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,IAAA,6BAAqB,EAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,CAAA;QACvG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,0CAA0C,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;QACrF,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,oBAAoB;QAC9B,MAAM,IAAA,0BAAkB,EAAC,KAAK,IAAI,EAAE;YAChC,MAAM,CAAC,KAAK,CAAC,6CAA6C,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;YACrF,IAAI,CAAC;gBACD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAA;gBACnD,IAAI,UAAU,CAAC,MAAM,GAAG,8BAAsB;uBACvC,UAAU,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,IAAA,6BAAuB,EAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC;oBACnH,MAAM,IAAI,CAAC,0BAA0B,EAAE,CAAA;gBAC3C,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,yCAAyC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;YACrF,CAAC;QACL,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;IAC9D,CAAC;IAEM,qBAAqB;QACxB,OAAO,IAAI,CAAC,6BAA6B,CAAA;IAC7C,CAAC;IAED,KAAK,CAAC,OAAO;QACT,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;QAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAA,6BAAqB,EAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAA;IAC3F,CAAC;CACJ;AAlED,kDAkEC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Layer0Node.js","sourceRoot":"","sources":["../../../src/logic/Layer0Node.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Layer1Node.js","sourceRoot":"","sources":["../../../src/logic/Layer1Node.ts"],"names":[],"mappings":""}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DataEntry,
|
|
3
|
-
DhtAddress,
|
|
4
|
-
PeerDescriptor,
|
|
5
|
-
areEqualPeerDescriptors,
|
|
6
|
-
getDhtAddressFromRaw
|
|
7
|
-
} from '@streamr/dht'
|
|
8
|
-
import { StreamPartID } from '@streamr/protocol'
|
|
9
|
-
import { Logger, scheduleAtInterval } from '@streamr/utils'
|
|
10
|
-
import { createHash } from 'crypto'
|
|
11
|
-
import { Any } from '../proto/google/protobuf/any'
|
|
12
|
-
|
|
13
|
-
export const streamPartIdToDataKey = (streamPartId: StreamPartID): DhtAddress => {
|
|
14
|
-
return getDhtAddressFromRaw(new Uint8Array((createHash('sha1').update(streamPartId).digest())))
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const parseEntryPointData = (dataEntries: DataEntry[]): PeerDescriptor[] => {
|
|
18
|
-
return dataEntries.filter((entry) => !entry.deleted).map((entry) => Any.unpack(entry.data!, PeerDescriptor))
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const logger = new Logger(module)
|
|
22
|
-
|
|
23
|
-
export const ENTRYPOINT_STORE_LIMIT = 8
|
|
24
|
-
|
|
25
|
-
interface EntryPointDiscoveryConfig {
|
|
26
|
-
streamPartId: StreamPartID
|
|
27
|
-
localPeerDescriptor: PeerDescriptor
|
|
28
|
-
fetchEntryPointData: (key: DhtAddress) => Promise<DataEntry[]>
|
|
29
|
-
storeEntryPointData: (key: DhtAddress, data: Any) => Promise<PeerDescriptor[]>
|
|
30
|
-
deleteEntryPointData: (key: DhtAddress) => Promise<void>
|
|
31
|
-
storeInterval?: number
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export class EntryPointDiscovery {
|
|
35
|
-
|
|
36
|
-
private readonly abortController: AbortController
|
|
37
|
-
private readonly config: EntryPointDiscoveryConfig
|
|
38
|
-
private readonly storeInterval: number
|
|
39
|
-
private isLocalNodeStoredAsEntryPoint = false
|
|
40
|
-
|
|
41
|
-
constructor(config: EntryPointDiscoveryConfig) {
|
|
42
|
-
this.config = config
|
|
43
|
-
this.abortController = new AbortController()
|
|
44
|
-
this.storeInterval = this.config.storeInterval ?? 60000
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async discoverEntryPoints(): Promise<PeerDescriptor[]> {
|
|
48
|
-
const dataKey = streamPartIdToDataKey(this.config.streamPartId)
|
|
49
|
-
logger.trace(`Discovering entry points for key ${dataKey}`)
|
|
50
|
-
try {
|
|
51
|
-
const result = await this.config.fetchEntryPointData(dataKey)
|
|
52
|
-
return parseEntryPointData(result)
|
|
53
|
-
} catch (err) {
|
|
54
|
-
return []
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async storeAndKeepLocalNodeAsEntryPoint(): Promise<void> {
|
|
59
|
-
if (this.abortController.signal.aborted) {
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
this.isLocalNodeStoredAsEntryPoint = true
|
|
63
|
-
await this.storeLocalNodeAsEntryPoint()
|
|
64
|
-
await this.keepSelfAsEntryPoint()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private async storeLocalNodeAsEntryPoint(): Promise<void> {
|
|
68
|
-
const localPeerDescriptor = this.config.localPeerDescriptor
|
|
69
|
-
const dataToStore = Any.pack(localPeerDescriptor, PeerDescriptor)
|
|
70
|
-
try {
|
|
71
|
-
await this.config.storeEntryPointData(streamPartIdToDataKey(this.config.streamPartId), dataToStore)
|
|
72
|
-
} catch (err) {
|
|
73
|
-
logger.warn(`Failed to store self as entrypoint for ${this.config.streamPartId}`)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
private async keepSelfAsEntryPoint(): Promise<void> {
|
|
78
|
-
await scheduleAtInterval(async () => {
|
|
79
|
-
logger.trace(`Attempting to keep self as entrypoint for ${this.config.streamPartId}`)
|
|
80
|
-
try {
|
|
81
|
-
const discovered = await this.discoverEntryPoints()
|
|
82
|
-
if (discovered.length < ENTRYPOINT_STORE_LIMIT
|
|
83
|
-
|| discovered.some((peerDescriptor) => areEqualPeerDescriptors(peerDescriptor, this.config.localPeerDescriptor))) {
|
|
84
|
-
await this.storeLocalNodeAsEntryPoint()
|
|
85
|
-
}
|
|
86
|
-
} catch (err) {
|
|
87
|
-
logger.debug(`Failed to keep self as entrypoint for ${this.config.streamPartId}`)
|
|
88
|
-
}
|
|
89
|
-
}, this.storeInterval, false, this.abortController.signal)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
public isLocalNodeEntryPoint(): boolean {
|
|
93
|
-
return this.isLocalNodeStoredAsEntryPoint
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async destroy(): Promise<void> {
|
|
97
|
-
this.abortController.abort()
|
|
98
|
-
await this.config.deleteEntryPointData(streamPartIdToDataKey(this.config.streamPartId))
|
|
99
|
-
}
|
|
100
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { PeerDescriptor } from '@streamr/dht'
|
|
2
|
-
import { EntryPointDiscovery } from '../../../src/logic/EntryPointDiscovery'
|
|
3
|
-
|
|
4
|
-
export const createFakeEntryPointDiscovery = (): EntryPointDiscovery => {
|
|
5
|
-
return new FakeEntryPointDiscovery() as unknown as EntryPointDiscovery
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
class FakeEntryPointDiscovery {
|
|
9
|
-
|
|
10
|
-
private entryPoints: PeerDescriptor[] = []
|
|
11
|
-
|
|
12
|
-
setEntryPoints(nodes: PeerDescriptor[]): void {
|
|
13
|
-
this.entryPoints = nodes
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async discoverEntryPoints(): Promise<PeerDescriptor[]> {
|
|
17
|
-
return this.entryPoints
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// eslint-disable-next-line class-methods-use-this
|
|
21
|
-
async storeAndKeepLocalNodeAsEntryPoint(): Promise<void> {
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// eslint-disable-next-line class-methods-use-this
|
|
25
|
-
isLocalNodeEntryPoint(): boolean {
|
|
26
|
-
return true
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
}
|