@streamr/dht 100.0.0-pretestnet.6 → 100.0.0-testnet-one.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/src/connection/ConnectionLockHandler.js +2 -2
- package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.d.ts +2 -2
- package/dist/src/connection/ConnectionLockRpcRemote.js +3 -27
- package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
- package/dist/src/connection/ConnectionManager.d.ts +0 -1
- package/dist/src/connection/ConnectionManager.js +11 -7
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.d.ts +2 -2
- package/dist/src/connection/ConnectorFacade.js +1 -2
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/ManagedConnection.js +1 -0
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/connectivityChecker.d.ts +9 -0
- package/dist/src/connection/connectivityChecker.js +122 -0
- package/dist/src/connection/connectivityChecker.js.map +1 -0
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -0
- package/dist/src/connection/connectivityRequestHandler.js +79 -0
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -0
- package/dist/src/connection/simulator/Simulator.js +3 -2
- package/dist/src/connection/simulator/Simulator.js.map +1 -1
- package/dist/src/connection/simulator/SimulatorConnection.js +1 -1
- package/dist/src/connection/simulator/SimulatorConnection.js.map +1 -1
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js +1 -1
- 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.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.d.ts +2 -2
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js +2 -2
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js.map +1 -1
- package/dist/src/connection/webrtc/iceServerAsString.js +1 -1
- package/dist/src/connection/webrtc/iceServerAsString.js.map +1 -1
- package/dist/src/connection/websocket/ClientWebsocket.d.ts +1 -0
- package/dist/src/connection/websocket/ClientWebsocket.js +7 -3
- package/dist/src/connection/websocket/ClientWebsocket.js.map +1 -1
- package/dist/src/connection/websocket/ServerWebsocket.d.ts +4 -0
- package/dist/src/connection/websocket/ServerWebsocket.js +32 -21
- package/dist/src/connection/websocket/ServerWebsocket.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnector.d.ts +0 -2
- package/dist/src/connection/websocket/WebsocketConnector.js +61 -16
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.d.ts +1 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js +8 -11
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.d.ts +4 -4
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js +5 -39
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServer.js +21 -4
- package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
- package/dist/src/dht/DhtNode.d.ts +13 -23
- package/dist/src/dht/DhtNode.js +97 -226
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +1 -4
- package/dist/src/dht/DhtNodeRpcLocal.js +1 -5
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcRemote.d.ts +3 -3
- package/dist/src/dht/DhtNodeRpcRemote.js +4 -4
- package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcLocal.d.ts +4 -4
- package/dist/src/dht/ExternalApiRpcLocal.js +5 -12
- package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.d.ts +3 -3
- package/dist/src/dht/ExternalApiRpcRemote.js +5 -5
- package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +52 -0
- package/dist/src/dht/PeerManager.js +273 -0
- package/dist/src/dht/PeerManager.js.map +1 -0
- package/dist/src/dht/contact/ContactList.d.ts +1 -1
- package/dist/src/dht/contact/ContactList.js +1 -0
- package/dist/src/dht/contact/ContactList.js.map +1 -1
- package/dist/src/dht/contact/{Remote.d.ts → RpcRemote.d.ts} +3 -3
- package/dist/src/dht/contact/{Remote.js → RpcRemote.js} +8 -8
- package/dist/src/dht/contact/RpcRemote.js.map +1 -0
- package/dist/src/dht/contact/SortedContactList.d.ts +20 -6
- package/dist/src/dht/contact/SortedContactList.js +55 -24
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- package/dist/src/dht/discovery/DiscoverySession.d.ts +4 -14
- package/dist/src/dht/discovery/DiscoverySession.js +15 -26
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +2 -9
- package/dist/src/dht/discovery/PeerDiscovery.js +11 -19
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/find/FindRpcLocal.js +2 -1
- package/dist/src/dht/find/FindRpcLocal.js.map +1 -1
- package/dist/src/dht/find/FindSession.d.ts +6 -6
- package/dist/src/dht/find/FindSession.js +18 -13
- package/dist/src/dht/find/FindSession.js.map +1 -1
- package/dist/src/dht/find/FindSessionRpcLocal.d.ts +1 -1
- package/dist/src/dht/find/FindSessionRpcRemote.d.ts +2 -2
- package/dist/src/dht/find/FindSessionRpcRemote.js +2 -2
- package/dist/src/dht/find/FindSessionRpcRemote.js.map +1 -1
- package/dist/src/dht/find/Finder.d.ts +4 -4
- package/dist/src/dht/find/Finder.js +55 -42
- package/dist/src/dht/find/Finder.js.map +1 -1
- package/dist/src/dht/routing/FindRpcRemote.d.ts +2 -2
- package/dist/src/dht/routing/FindRpcRemote.js +7 -5
- package/dist/src/dht/routing/FindRpcRemote.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +3 -7
- package/dist/src/dht/routing/Router.js +29 -22
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcLocal.d.ts +2 -2
- package/dist/src/dht/routing/RouterRpcLocal.js +4 -3
- package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcRemote.d.ts +2 -2
- package/dist/src/dht/routing/RouterRpcRemote.js +13 -8
- package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.d.ts +1 -1
- package/dist/src/dht/routing/RoutingSession.js +23 -11
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/routing/getPreviousPeer.js.map +1 -1
- package/dist/src/dht/store/LocalDataStore.d.ts +3 -3
- package/dist/src/dht/store/LocalDataStore.js +18 -17
- package/dist/src/dht/store/LocalDataStore.js.map +1 -1
- package/dist/src/dht/store/StoreRpcLocal.d.ts +10 -9
- package/dist/src/dht/store/StoreRpcLocal.js +108 -102
- package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
- package/dist/src/dht/store/StoreRpcRemote.d.ts +4 -5
- package/dist/src/dht/store/StoreRpcRemote.js +6 -15
- package/dist/src/dht/store/StoreRpcRemote.js.map +1 -1
- package/dist/src/exports.d.ts +1 -1
- package/dist/src/exports.js +4 -4
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/PeerID.d.ts +1 -0
- package/dist/src/helpers/PeerID.js +9 -4
- package/dist/src/helpers/PeerID.js.map +1 -1
- package/dist/src/helpers/UUID.js +1 -1
- package/dist/src/helpers/UUID.js.map +1 -1
- package/dist/src/helpers/nodeId.d.ts +1 -0
- package/dist/src/helpers/{kademliaId.js → nodeId.js} +4 -4
- package/dist/src/helpers/nodeId.js.map +1 -0
- package/dist/src/helpers/peerIdFromPeerDescriptor.js +4 -4
- package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +5 -16
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +2 -9
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +80 -95
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +67 -66
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +3 -10
- package/dist/src/transport/RoutingRpcCommunicator.js +2 -0
- package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
- package/karma.config.js +2 -2
- package/package.json +5 -5
- package/protos/DhtRpc.proto +36 -36
- package/src/connection/ConnectionLockHandler.ts +2 -2
- package/src/connection/ConnectionLockRpcRemote.ts +3 -4
- package/src/connection/ConnectionManager.ts +19 -17
- package/src/connection/ConnectorFacade.ts +5 -7
- package/src/connection/ManagedConnection.ts +1 -0
- package/src/connection/connectivityChecker.ts +102 -0
- package/src/connection/connectivityRequestHandler.ts +79 -0
- package/src/connection/simulator/Simulator.ts +3 -2
- package/src/connection/simulator/SimulatorConnection.ts +1 -1
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +10 -10
- package/src/connection/webrtc/NodeWebrtcConnection.ts +1 -1
- package/src/connection/webrtc/WebrtcConnector.ts +1 -1
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +1 -1
- package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +2 -2
- package/src/connection/webrtc/iceServerAsString.ts +1 -1
- package/src/connection/websocket/ClientWebsocket.ts +6 -2
- package/src/connection/websocket/ServerWebsocket.ts +40 -25
- package/src/connection/websocket/WebsocketConnector.ts +43 -22
- package/src/connection/websocket/WebsocketConnectorRpcLocal.ts +9 -11
- package/src/connection/websocket/WebsocketConnectorRpcRemote.ts +7 -16
- package/src/connection/websocket/WebsocketServer.ts +20 -5
- package/src/dht/DhtNode.ts +123 -280
- package/src/dht/DhtNodeRpcLocal.ts +2 -9
- package/src/dht/DhtNodeRpcRemote.ts +4 -4
- package/src/dht/ExternalApiRpcLocal.ts +8 -13
- package/src/dht/ExternalApiRpcRemote.ts +5 -5
- package/src/dht/PeerManager.ts +330 -0
- package/src/dht/contact/ContactList.ts +3 -2
- package/src/dht/contact/{Remote.ts → RpcRemote.ts} +7 -6
- package/src/dht/contact/SortedContactList.ts +87 -44
- package/src/dht/discovery/DiscoverySession.ts +19 -44
- package/src/dht/discovery/PeerDiscovery.ts +16 -28
- package/src/dht/find/FindRpcLocal.ts +2 -2
- package/src/dht/find/FindSession.ts +25 -20
- package/src/dht/find/FindSessionRpcLocal.ts +1 -1
- package/src/dht/find/FindSessionRpcRemote.ts +2 -2
- package/src/dht/find/Finder.ts +84 -64
- package/src/dht/routing/FindRpcRemote.ts +7 -5
- package/src/dht/routing/Router.ts +30 -25
- package/src/dht/routing/RouterRpcLocal.ts +5 -5
- package/src/dht/routing/RouterRpcRemote.ts +13 -10
- package/src/dht/routing/RoutingSession.ts +22 -17
- package/src/dht/routing/getPreviousPeer.ts +1 -1
- package/src/dht/store/LocalDataStore.ts +18 -17
- package/src/dht/store/StoreRpcLocal.ts +118 -113
- package/src/dht/store/StoreRpcRemote.ts +7 -23
- package/src/exports.ts +1 -1
- package/src/helpers/PeerID.ts +8 -4
- package/src/helpers/UUID.ts +1 -1
- package/src/helpers/{kademliaId.ts → nodeId.ts} +1 -1
- package/src/helpers/peerIdFromPeerDescriptor.ts +6 -6
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +6 -20
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +3 -10
- package/src/proto/packages/dht/protos/DhtRpc.ts +103 -135
- package/src/transport/RoutingRpcCommunicator.ts +2 -0
- package/test/benchmark/Find.test.ts +5 -5
- package/test/benchmark/KademliaCorrectness.test.ts +3 -3
- package/test/benchmark/SortedContactListBenchmark.test.ts +150 -0
- package/test/benchmark/WebsocketServerMemoryLeak.test.ts +41 -0
- package/test/benchmark/kademlia-simulation/Contact.ts +1 -1
- package/test/benchmark/kademlia-simulation/KademliaSimulation.ts +1 -1
- package/test/benchmark/kademlia-simulation/SimulationNode.ts +6 -1
- package/test/end-to-end/Layer0-Layer1.test.ts +1 -1
- package/test/end-to-end/Layer0.test.ts +4 -4
- package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +11 -11
- package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +6 -6
- package/test/end-to-end/Layer0Webrtc.test.ts +2 -2
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +3 -3
- package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +3 -3
- package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +1 -1
- package/test/end-to-end/WebsocketConnectionRequest.test.ts +1 -1
- package/test/end-to-end/memory-leak.test.ts +9 -12
- package/test/integration/ConnectionLocking.test.ts +2 -2
- package/test/integration/ConnectionManager.test.ts +14 -14
- package/test/integration/DhtJoinPeerDiscovery.test.ts +3 -3
- package/test/integration/DhtNodeExternalAPI.test.ts +10 -7
- package/test/integration/DhtNodeRpcRemote.test.ts +4 -4
- package/test/integration/DhtRpc.test.ts +6 -6
- package/test/integration/Find.test.ts +3 -3
- package/test/integration/Layer1-scale.test.ts +3 -3
- package/test/integration/Mock-Layer1-Layer0.test.ts +16 -16
- package/test/integration/MultipleEntryPointJoining.test.ts +7 -7
- package/test/integration/{MigrateData.test.ts → ReplicateData.test.ts} +15 -10
- package/test/integration/RouteMessage.test.ts +2 -2
- package/test/integration/RouterRpcRemote.test.ts +2 -2
- package/test/integration/RpcErrors.test.ts +2 -2
- package/test/integration/ScaleDownDht.test.ts +4 -2
- package/test/integration/SimultaneousConnections.test.ts +89 -57
- package/test/integration/Store.test.ts +33 -13
- package/test/integration/StoreAndDelete.test.ts +19 -17
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +21 -21
- package/test/integration/StoreRpcRemote.test.ts +3 -3
- package/test/integration/WebrtcConnectionManagement.test.ts +2 -2
- package/test/integration/WebrtcConnectorRpc.test.ts +1 -1
- package/test/integration/WebsocketConnectionManagement.test.ts +41 -3
- package/test/integration/WebsocketConnectorRpc.test.ts +5 -7
- package/test/unit/ConnectivityHelpers.test.ts +4 -4
- package/test/unit/Finder.test.ts +69 -23
- package/test/unit/LocalDataStore.test.ts +60 -43
- package/test/unit/RandomContactList.test.ts +2 -2
- package/test/unit/Router.test.ts +19 -11
- package/test/unit/RoutingSession.test.ts +76 -0
- package/test/unit/SortedContactList.test.ts +17 -12
- package/test/unit/WebsocketConnector.test.ts +1 -1
- package/test/unit/connectivityRequestHandler.test.ts +71 -0
- package/test/utils/mock/Router.ts +1 -1
- package/test/utils/utils.ts +24 -22
- package/dist/src/connection/ConnectivityChecker.d.ts +0 -17
- package/dist/src/connection/ConnectivityChecker.js +0 -208
- package/dist/src/connection/ConnectivityChecker.js.map +0 -1
- package/dist/src/dht/contact/Remote.js.map +0 -1
- package/dist/src/helpers/kademliaId.d.ts +0 -1
- package/dist/src/helpers/kademliaId.js.map +0 -1
- package/src/connection/ConnectivityChecker.ts +0 -199
|
@@ -23,23 +23,23 @@ interface LocalDataEntry {
|
|
|
23
23
|
export class LocalDataStore {
|
|
24
24
|
// A map into which each node can store one value per data key
|
|
25
25
|
// The first key is the key of the data, the second key is the
|
|
26
|
-
// PeerID of the
|
|
26
|
+
// PeerID of the creator of the data
|
|
27
27
|
private store: Map<PeerIDKey, Map<PeerIDKey, LocalDataEntry>> = new Map()
|
|
28
28
|
|
|
29
29
|
public storeEntry(dataEntry: DataEntry): boolean {
|
|
30
|
-
const publisherKey = PeerID.fromValue(dataEntry.
|
|
31
|
-
const dataKey = PeerID.fromValue(dataEntry.
|
|
30
|
+
const publisherKey = PeerID.fromValue(dataEntry.creator!.nodeId).toKey()
|
|
31
|
+
const dataKey = PeerID.fromValue(dataEntry.key).toKey()
|
|
32
32
|
|
|
33
33
|
if (!this.store.has(dataKey)) {
|
|
34
34
|
this.store.set(dataKey, new Map())
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
if (this.store.get(dataKey)!.has(publisherKey)) {
|
|
38
|
-
const storedMillis = (dataEntry.
|
|
38
|
+
const storedMillis = (dataEntry.createdAt!.seconds * 1000) + (dataEntry.createdAt!.nanos / 1000000)
|
|
39
39
|
const oldLocalEntry = this.store.get(dataKey)!.get(publisherKey)!
|
|
40
|
-
const oldStoredMillis = (oldLocalEntry.dataEntry.
|
|
40
|
+
const oldStoredMillis = (oldLocalEntry.dataEntry.createdAt!.seconds * 1000) + (oldLocalEntry.dataEntry.createdAt!.nanos / 1000000)
|
|
41
41
|
|
|
42
|
-
// do nothing if old entry is newer than the one being
|
|
42
|
+
// do nothing if old entry is newer than the one being replicated
|
|
43
43
|
if (oldStoredMillis >= storedMillis) {
|
|
44
44
|
return false
|
|
45
45
|
} else {
|
|
@@ -49,18 +49,19 @@ export class LocalDataStore {
|
|
|
49
49
|
this.store.get(dataKey)!.set(publisherKey, {
|
|
50
50
|
dataEntry,
|
|
51
51
|
ttlTimeout: setTimeout(() => {
|
|
52
|
-
this.deleteEntry(PeerID.fromValue(dataEntry.
|
|
52
|
+
this.deleteEntry(PeerID.fromValue(dataEntry.key), dataEntry.creator!)
|
|
53
53
|
}, createTtlValue(dataEntry.ttl))
|
|
54
54
|
})
|
|
55
55
|
return true
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
public markAsDeleted(id: Uint8Array,
|
|
58
|
+
public markAsDeleted(id: Uint8Array, creator: PeerID): boolean {
|
|
59
59
|
const dataKey = PeerID.fromValue(id).toKey()
|
|
60
|
-
|
|
60
|
+
const item = this.store.get(dataKey)
|
|
61
|
+
if ((item === undefined) || !item.has(creator.toKey())) {
|
|
61
62
|
return false
|
|
62
63
|
}
|
|
63
|
-
const storedEntry =
|
|
64
|
+
const storedEntry = item.get(creator.toKey())
|
|
64
65
|
storedEntry!.dataEntry.deleted = true
|
|
65
66
|
return true
|
|
66
67
|
}
|
|
@@ -77,9 +78,9 @@ export class LocalDataStore {
|
|
|
77
78
|
return dataEntries
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
public setStale(key: PeerID,
|
|
81
|
-
const
|
|
82
|
-
const storedEntry = this.store.get(key.toKey())?.get(
|
|
81
|
+
public setStale(key: PeerID, creator: PeerDescriptor, stale: boolean): void {
|
|
82
|
+
const creatorKey = keyFromPeerDescriptor(creator)
|
|
83
|
+
const storedEntry = this.store.get(key.toKey())?.get(creatorKey)
|
|
83
84
|
if (storedEntry) {
|
|
84
85
|
storedEntry.dataEntry.stale = stale
|
|
85
86
|
}
|
|
@@ -91,12 +92,12 @@ export class LocalDataStore {
|
|
|
91
92
|
})
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
public deleteEntry(key: PeerID,
|
|
95
|
-
const
|
|
96
|
-
const storedEntry = this.store.get(key.toKey())?.get(
|
|
95
|
+
public deleteEntry(key: PeerID, creator: PeerDescriptor): void {
|
|
96
|
+
const creatorKey = keyFromPeerDescriptor(creator)
|
|
97
|
+
const storedEntry = this.store.get(key.toKey())?.get(creatorKey)
|
|
97
98
|
if (storedEntry) {
|
|
98
99
|
clearTimeout(storedEntry.ttlTimeout)
|
|
99
|
-
this.store.get(key.toKey())?.delete(
|
|
100
|
+
this.store.get(key.toKey())?.delete(creatorKey)
|
|
100
101
|
if (this.store.get(key.toKey())?.size === 0) {
|
|
101
102
|
this.store.delete(key.toKey())
|
|
102
103
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DataEntry,
|
|
2
|
+
DataEntry, ReplicateDataRequest, PeerDescriptor,
|
|
3
3
|
StoreDataRequest, StoreDataResponse
|
|
4
4
|
} from '../../proto/packages/dht/protos/DhtRpc'
|
|
5
5
|
import { PeerID } from '../../helpers/PeerID'
|
|
@@ -10,7 +10,7 @@ import { toProtoRpcClient } from '@streamr/proto-rpc'
|
|
|
10
10
|
import { StoreRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
|
|
11
11
|
import { RoutingRpcCommunicator } from '../../transport/RoutingRpcCommunicator'
|
|
12
12
|
import { IFinder } from '../find/Finder'
|
|
13
|
-
import { areEqualPeerDescriptors
|
|
13
|
+
import { areEqualPeerDescriptors } from '../../helpers/peerIdFromPeerDescriptor'
|
|
14
14
|
import { Logger } from '@streamr/utils'
|
|
15
15
|
import { LocalDataStore } from './LocalDataStore'
|
|
16
16
|
import { IStoreRpc } from '../../proto/packages/dht/protos/DhtRpc.server'
|
|
@@ -22,6 +22,7 @@ import { SortedContactList } from '../contact/SortedContactList'
|
|
|
22
22
|
import { Contact } from '../contact/Contact'
|
|
23
23
|
import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote'
|
|
24
24
|
import { ServiceID } from '../../types/ServiceID'
|
|
25
|
+
import { Empty } from '../../proto/google/protobuf/empty'
|
|
25
26
|
|
|
26
27
|
interface DataStoreConfig {
|
|
27
28
|
rpcCommunicator: RoutingRpcCommunicator
|
|
@@ -66,46 +67,53 @@ export class StoreRpcLocal implements IStoreRpc {
|
|
|
66
67
|
this.rpcRequestTimeout = config.rpcRequestTimeout
|
|
67
68
|
this.getNodesClosestToIdFromBucket = config.getNodesClosestToIdFromBucket
|
|
68
69
|
this.rpcCommunicator.registerRpcMethod(StoreDataRequest, StoreDataResponse, 'storeData',
|
|
69
|
-
(request: StoreDataRequest
|
|
70
|
-
this.rpcCommunicator.
|
|
71
|
-
(request:
|
|
72
|
-
this.rpcCommunicator.registerRpcMethod(DeleteDataRequest, DeleteDataResponse, 'deleteData',
|
|
73
|
-
(request: DeleteDataRequest, context: ServerCallContext) => this.deleteData(request, context))
|
|
70
|
+
(request: StoreDataRequest) => this.storeData(request))
|
|
71
|
+
this.rpcCommunicator.registerRpcNotification(ReplicateDataRequest, 'replicateData',
|
|
72
|
+
(request: ReplicateDataRequest, context: ServerCallContext) => this.replicateData(request, context))
|
|
74
73
|
|
|
75
74
|
this.dhtNodeEmitter.on('newContact', (peerDescriptor: PeerDescriptor) => {
|
|
76
75
|
this.localDataStore.getStore().forEach((dataMap, _dataKey) => {
|
|
77
|
-
dataMap.forEach((dataEntry) => {
|
|
78
|
-
if (this.
|
|
79
|
-
|
|
76
|
+
dataMap.forEach(async (dataEntry) => {
|
|
77
|
+
if (this.shouldReplicateDataToNewNode(dataEntry.dataEntry, peerDescriptor)) {
|
|
78
|
+
try {
|
|
79
|
+
await this.replicateDataToContact(dataEntry.dataEntry, peerDescriptor)
|
|
80
|
+
} catch (e) {
|
|
81
|
+
logger.trace('replicateDataToContact() failed', { error: e })
|
|
82
|
+
}
|
|
80
83
|
}
|
|
81
84
|
})
|
|
82
85
|
})
|
|
83
86
|
})
|
|
84
87
|
}
|
|
85
88
|
|
|
86
|
-
private
|
|
89
|
+
private shouldReplicateDataToNewNode(dataEntry: DataEntry, newNode: PeerDescriptor): boolean {
|
|
87
90
|
|
|
88
|
-
const dataId = PeerID.fromValue(dataEntry.
|
|
89
|
-
const newNodeId = PeerID.fromValue(newNode.
|
|
90
|
-
const localPeerId = PeerID.fromValue(this.localPeerDescriptor.
|
|
91
|
+
const dataId = PeerID.fromValue(dataEntry.key)
|
|
92
|
+
const newNodeId = PeerID.fromValue(newNode.nodeId)
|
|
93
|
+
const localPeerId = PeerID.fromValue(this.localPeerDescriptor.nodeId)
|
|
91
94
|
|
|
92
|
-
const closestToData = this.getNodesClosestToIdFromBucket(dataEntry.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
const closestToData = this.getNodesClosestToIdFromBucket(dataEntry.key, 10)
|
|
96
|
+
const sortedList = new SortedContactList<Contact>({
|
|
97
|
+
referenceId: PeerID.fromValue(dataEntry.key),
|
|
98
|
+
maxSize: 20, // TODO use config option or named constant?
|
|
99
|
+
allowToContainReferenceId: true,
|
|
100
|
+
emitEvents: false
|
|
101
|
+
})
|
|
95
102
|
sortedList.addContact(new Contact(this.localPeerDescriptor))
|
|
96
103
|
|
|
97
104
|
closestToData.forEach((con) => {
|
|
98
|
-
if (!newNodeId.equals(PeerID.fromValue(con.getPeerDescriptor().
|
|
105
|
+
if (!newNodeId.equals(PeerID.fromValue(con.getPeerDescriptor().nodeId))) {
|
|
99
106
|
sortedList.addContact(new Contact(con.getPeerDescriptor()))
|
|
100
107
|
}
|
|
101
108
|
})
|
|
102
109
|
|
|
103
110
|
if (!sortedList.getAllContacts()[0].getPeerId().equals(localPeerId)) {
|
|
104
|
-
// If we are not the closes node to the data, do not
|
|
111
|
+
// If we are not the closes node to the data, do not replicate
|
|
105
112
|
return false
|
|
106
113
|
}
|
|
107
114
|
|
|
108
|
-
|
|
115
|
+
this.localDataStore.setStale(dataId, dataEntry.creator!, false)
|
|
116
|
+
const newPeerId = PeerID.fromValue(newNode.nodeId)
|
|
109
117
|
sortedList.addContact(new Contact(newNode))
|
|
110
118
|
|
|
111
119
|
const sorted = sortedList.getAllContacts()
|
|
@@ -119,18 +127,16 @@ export class StoreRpcLocal implements IStoreRpc {
|
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
// if new node is within the storageRedundancyFactor closest nodes to the data
|
|
122
|
-
// do
|
|
130
|
+
// do replicate data to it
|
|
123
131
|
|
|
124
132
|
if (index < this.redundancyFactor) {
|
|
125
|
-
this.localDataStore.setStale(dataId, dataEntry.storer!, false)
|
|
126
133
|
return true
|
|
127
134
|
} else {
|
|
128
|
-
this.localDataStore.setStale(dataId, dataEntry.storer!, true)
|
|
129
135
|
return false
|
|
130
136
|
}
|
|
131
137
|
}
|
|
132
138
|
|
|
133
|
-
private async
|
|
139
|
+
private async replicateDataToContact(dataEntry: DataEntry, contact: PeerDescriptor, doNotConnect: boolean = false): Promise<void> {
|
|
134
140
|
const rpcRemote = new StoreRpcRemote(
|
|
135
141
|
this.localPeerDescriptor,
|
|
136
142
|
contact,
|
|
@@ -139,33 +145,30 @@ export class StoreRpcLocal implements IStoreRpc {
|
|
|
139
145
|
this.rpcRequestTimeout
|
|
140
146
|
)
|
|
141
147
|
try {
|
|
142
|
-
|
|
143
|
-
if (response.error) {
|
|
144
|
-
logger.trace('migrateData() returned error: ' + response.error)
|
|
145
|
-
}
|
|
148
|
+
await rpcRemote.replicateData({ entry: dataEntry }, doNotConnect)
|
|
146
149
|
} catch (e) {
|
|
147
|
-
logger.trace('
|
|
150
|
+
logger.trace('replicateData() threw an exception ' + e)
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
153
|
|
|
151
|
-
public async storeDataToDht(key: Uint8Array, data: Any): Promise<PeerDescriptor[]> {
|
|
154
|
+
public async storeDataToDht(key: Uint8Array, data: Any, creator: PeerDescriptor): Promise<PeerDescriptor[]> {
|
|
152
155
|
logger.debug(`Storing data to DHT ${this.serviceId}`)
|
|
153
156
|
const result = await this.finder.startFind(key)
|
|
154
157
|
const closestNodes = result.closestNodes
|
|
155
158
|
const successfulNodes: PeerDescriptor[] = []
|
|
156
159
|
const ttl = this.highestTtl // ToDo: make TTL decrease according to some nice curve
|
|
157
|
-
const
|
|
160
|
+
const createdAt = Timestamp.now()
|
|
158
161
|
for (let i = 0; i < closestNodes.length && successfulNodes.length < this.redundancyFactor; i++) {
|
|
159
162
|
if (areEqualPeerDescriptors(this.localPeerDescriptor, closestNodes[i])) {
|
|
160
163
|
this.localDataStore.storeEntry({
|
|
161
|
-
|
|
162
|
-
storer: this.localPeerDescriptor,
|
|
163
|
-
ttl,
|
|
164
|
-
storedAt: Timestamp.now(),
|
|
164
|
+
key,
|
|
165
165
|
data,
|
|
166
|
+
creator,
|
|
167
|
+
createdAt,
|
|
168
|
+
storedAt: Timestamp.now(),
|
|
169
|
+
ttl,
|
|
166
170
|
stale: false,
|
|
167
171
|
deleted: false,
|
|
168
|
-
storerTime
|
|
169
172
|
})
|
|
170
173
|
successfulNodes.push(closestNodes[i])
|
|
171
174
|
continue
|
|
@@ -178,7 +181,13 @@ export class StoreRpcLocal implements IStoreRpc {
|
|
|
178
181
|
this.rpcRequestTimeout
|
|
179
182
|
)
|
|
180
183
|
try {
|
|
181
|
-
const response = await rpcRemote.storeData({
|
|
184
|
+
const response = await rpcRemote.storeData({
|
|
185
|
+
key,
|
|
186
|
+
data,
|
|
187
|
+
creator,
|
|
188
|
+
createdAt,
|
|
189
|
+
ttl
|
|
190
|
+
})
|
|
182
191
|
if (!response.error) {
|
|
183
192
|
successfulNodes.push(closestNodes[i])
|
|
184
193
|
logger.trace('remote.storeData() returned success')
|
|
@@ -193,104 +202,100 @@ export class StoreRpcLocal implements IStoreRpc {
|
|
|
193
202
|
}
|
|
194
203
|
|
|
195
204
|
private selfIsOneOfClosestPeers(dataId: Uint8Array): boolean {
|
|
196
|
-
const localPeerId = PeerID.fromValue(this.localPeerDescriptor.
|
|
205
|
+
const localPeerId = PeerID.fromValue(this.localPeerDescriptor.nodeId)
|
|
197
206
|
const closestPeers = this.getNodesClosestToIdFromBucket(dataId, this.redundancyFactor)
|
|
198
|
-
const sortedList = new SortedContactList<Contact>(
|
|
207
|
+
const sortedList = new SortedContactList<Contact>({
|
|
208
|
+
referenceId: localPeerId,
|
|
209
|
+
maxSize: this.redundancyFactor,
|
|
210
|
+
allowToContainReferenceId: true,
|
|
211
|
+
emitEvents: false
|
|
212
|
+
})
|
|
199
213
|
sortedList.addContact(new Contact(this.localPeerDescriptor))
|
|
200
214
|
closestPeers.forEach((con) => sortedList.addContact(new Contact(con.getPeerDescriptor())))
|
|
201
215
|
return sortedList.getClosestContacts().some((node) => node.getPeerId().equals(localPeerId))
|
|
202
216
|
}
|
|
203
217
|
|
|
204
|
-
public async deleteDataFromDht(key: Uint8Array): Promise<void> {
|
|
205
|
-
logger.debug(`Deleting data from DHT ${this.serviceId}`)
|
|
206
|
-
const result = await this.finder.startFind(key)
|
|
207
|
-
const closestNodes = result.closestNodes
|
|
208
|
-
const successfulNodes: PeerDescriptor[] = []
|
|
209
|
-
for (let i = 0; i < closestNodes.length && successfulNodes.length < this.redundancyFactor; i++) {
|
|
210
|
-
if (areEqualPeerDescriptors(this.localPeerDescriptor, closestNodes[i])) {
|
|
211
|
-
this.localDataStore.markAsDeleted(key, peerIdFromPeerDescriptor(this.localPeerDescriptor))
|
|
212
|
-
successfulNodes.push(closestNodes[i])
|
|
213
|
-
continue
|
|
214
|
-
}
|
|
215
|
-
const rpcRemote = new StoreRpcRemote(
|
|
216
|
-
this.localPeerDescriptor,
|
|
217
|
-
closestNodes[i],
|
|
218
|
-
this.serviceId,
|
|
219
|
-
toProtoRpcClient(new StoreRpcClient(this.rpcCommunicator.getRpcClientTransport())),
|
|
220
|
-
this.rpcRequestTimeout
|
|
221
|
-
)
|
|
222
|
-
try {
|
|
223
|
-
const response = await rpcRemote.deleteData({ kademliaId: key })
|
|
224
|
-
if (response.deleted) {
|
|
225
|
-
logger.trace('remote.deleteData() returned success')
|
|
226
|
-
} else {
|
|
227
|
-
logger.trace('could not delete data from ' + getNodeIdFromPeerDescriptor(closestNodes[i]))
|
|
228
|
-
}
|
|
229
|
-
successfulNodes.push(closestNodes[i])
|
|
230
|
-
} catch (e) {
|
|
231
|
-
logger.trace('remote.deleteData() threw an exception ' + e)
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
218
|
// RPC service implementation
|
|
237
|
-
async storeData(request: StoreDataRequest
|
|
219
|
+
async storeData(request: StoreDataRequest): Promise<StoreDataResponse> {
|
|
238
220
|
const ttl = Math.min(request.ttl, this.maxTtl)
|
|
239
|
-
const {
|
|
240
|
-
const { kademliaId, data, storerTime } = request
|
|
221
|
+
const { key, data, createdAt, creator } = request
|
|
241
222
|
this.localDataStore.storeEntry({
|
|
242
|
-
|
|
243
|
-
storer: incomingSourceDescriptor!,
|
|
244
|
-
ttl,
|
|
245
|
-
storedAt: Timestamp.now(),
|
|
246
|
-
storerTime,
|
|
223
|
+
key,
|
|
247
224
|
data,
|
|
248
|
-
|
|
225
|
+
creator,
|
|
226
|
+
createdAt,
|
|
227
|
+
storedAt: Timestamp.now(),
|
|
228
|
+
ttl,
|
|
229
|
+
stale: !this.selfIsOneOfClosestPeers(key),
|
|
249
230
|
deleted: false
|
|
250
231
|
})
|
|
251
232
|
|
|
252
|
-
if (!this.selfIsOneOfClosestPeers(
|
|
253
|
-
this.localDataStore.setAllEntriesAsStale(PeerID.fromValue(
|
|
233
|
+
if (!this.selfIsOneOfClosestPeers(key)) {
|
|
234
|
+
this.localDataStore.setAllEntriesAsStale(PeerID.fromValue(key))
|
|
254
235
|
}
|
|
255
236
|
|
|
256
237
|
logger.trace('storeData()')
|
|
257
238
|
return StoreDataResponse.create()
|
|
258
239
|
}
|
|
259
240
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
241
|
+
async destroy(): Promise<void> {
|
|
242
|
+
await this.replicateDataToClosestNodes()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private async replicateDataToClosestNodes(): Promise<void> {
|
|
246
|
+
const dataEntries = Array.from(this.localDataStore.getStore().values())
|
|
247
|
+
.flatMap((dataMap) => Array.from(dataMap.values()))
|
|
248
|
+
.map((localData) => localData.dataEntry)
|
|
249
|
+
|
|
250
|
+
await Promise.all(dataEntries.map(async (dataEntry) => {
|
|
251
|
+
const dhtNodeRemotes = this.getNodesClosestToIdFromBucket(dataEntry.key, this.redundancyFactor)
|
|
252
|
+
await Promise.all(dhtNodeRemotes.map(async (remoteDhtNode) => {
|
|
253
|
+
const rpcRemote = new StoreRpcRemote(
|
|
254
|
+
this.localPeerDescriptor,
|
|
255
|
+
remoteDhtNode.getPeerDescriptor(),
|
|
256
|
+
this.serviceId,
|
|
257
|
+
toProtoRpcClient(new StoreRpcClient(this.rpcCommunicator.getRpcClientTransport())),
|
|
258
|
+
this.rpcRequestTimeout
|
|
259
|
+
)
|
|
260
|
+
try {
|
|
261
|
+
await rpcRemote.replicateData({ entry: dataEntry })
|
|
262
|
+
} catch (err) {
|
|
263
|
+
logger.trace('Failed to replicate data in replicateDataToClosestNodes', { error: err })
|
|
264
|
+
}
|
|
265
|
+
}))
|
|
266
|
+
}))
|
|
266
267
|
}
|
|
267
268
|
|
|
268
269
|
// RPC service implementation
|
|
269
|
-
public async
|
|
270
|
-
logger.trace('server-side
|
|
271
|
-
const dataEntry = request.
|
|
270
|
+
public async replicateData(request: ReplicateDataRequest, context: ServerCallContext): Promise<Empty> {
|
|
271
|
+
logger.trace('server-side replicateData()')
|
|
272
|
+
const dataEntry = request.entry!
|
|
272
273
|
|
|
273
274
|
const wasStored = this.localDataStore.storeEntry(dataEntry)
|
|
274
275
|
|
|
275
276
|
if (wasStored) {
|
|
276
|
-
this.
|
|
277
|
+
this.replicateDataToNeighborsIfNeeded((context as DhtCallContext).incomingSourceDescriptor!, request.entry!)
|
|
277
278
|
}
|
|
278
|
-
if (!this.selfIsOneOfClosestPeers(dataEntry.
|
|
279
|
-
this.localDataStore.setAllEntriesAsStale(PeerID.fromValue(dataEntry.
|
|
279
|
+
if (!this.selfIsOneOfClosestPeers(dataEntry.key)) {
|
|
280
|
+
this.localDataStore.setAllEntriesAsStale(PeerID.fromValue(dataEntry.key))
|
|
280
281
|
}
|
|
281
|
-
logger.trace('server-side
|
|
282
|
-
return
|
|
282
|
+
logger.trace('server-side replicateData() at end')
|
|
283
|
+
return {}
|
|
283
284
|
}
|
|
284
285
|
|
|
285
|
-
private
|
|
286
|
+
private replicateDataToNeighborsIfNeeded(incomingPeer: PeerDescriptor, dataEntry: DataEntry): void {
|
|
286
287
|
|
|
287
288
|
// sort own contact list according to data id
|
|
288
|
-
const localPeerId = PeerID.fromValue(this.localPeerDescriptor.
|
|
289
|
-
const dataId = PeerID.fromValue(dataEntry.
|
|
290
|
-
const incomingPeerId = PeerID.fromValue(incomingPeer.
|
|
291
|
-
const closestToData = this.getNodesClosestToIdFromBucket(dataEntry.
|
|
292
|
-
|
|
293
|
-
|
|
289
|
+
const localPeerId = PeerID.fromValue(this.localPeerDescriptor.nodeId)
|
|
290
|
+
const dataId = PeerID.fromValue(dataEntry.key)
|
|
291
|
+
const incomingPeerId = PeerID.fromValue(incomingPeer.nodeId)
|
|
292
|
+
const closestToData = this.getNodesClosestToIdFromBucket(dataEntry.key, 10)
|
|
293
|
+
const sortedList = new SortedContactList<Contact>({
|
|
294
|
+
referenceId: dataId,
|
|
295
|
+
maxSize: this.redundancyFactor,
|
|
296
|
+
allowToContainReferenceId: true,
|
|
297
|
+
emitEvents: false
|
|
298
|
+
})
|
|
294
299
|
sortedList.addContact(new Contact(this.localPeerDescriptor))
|
|
295
300
|
|
|
296
301
|
closestToData.forEach((con) => {
|
|
@@ -298,33 +303,33 @@ export class StoreRpcLocal implements IStoreRpc {
|
|
|
298
303
|
})
|
|
299
304
|
|
|
300
305
|
if (!sortedList.getAllContacts()[0].getPeerId().equals(localPeerId)) {
|
|
301
|
-
// If we are not the closest node to the data,
|
|
306
|
+
// If we are not the closest node to the data, replicate only to the
|
|
302
307
|
// closest one to the data
|
|
303
308
|
|
|
304
309
|
const contact = sortedList.getAllContacts()[0]
|
|
305
|
-
const contactPeerId = PeerID.fromValue(contact.getPeerDescriptor().
|
|
310
|
+
const contactPeerId = PeerID.fromValue(contact.getPeerDescriptor().nodeId)
|
|
306
311
|
if (!incomingPeerId.equals(contactPeerId) && !localPeerId.equals(contactPeerId)) {
|
|
307
312
|
setImmediate(async () => {
|
|
308
313
|
try {
|
|
309
|
-
await this.
|
|
310
|
-
logger.trace('
|
|
314
|
+
await this.replicateDataToContact(dataEntry, contact.getPeerDescriptor())
|
|
315
|
+
logger.trace('replicateDataToContact() returned when migrating to only the closest contact')
|
|
311
316
|
} catch (e) {
|
|
312
|
-
logger.error('
|
|
317
|
+
logger.error('replicating data to only the closest contact failed ' + e)
|
|
313
318
|
}
|
|
314
319
|
})
|
|
315
320
|
}
|
|
316
321
|
} else {
|
|
317
|
-
// if we are the closest to the data,
|
|
322
|
+
// if we are the closest to the data, replicate to all storageRedundancyFactor nearest
|
|
318
323
|
sortedList.getAllContacts().forEach((contact) => {
|
|
319
|
-
const contactPeerId = PeerID.fromValue(contact.getPeerDescriptor().
|
|
324
|
+
const contactPeerId = PeerID.fromValue(contact.getPeerDescriptor().nodeId)
|
|
320
325
|
if (!incomingPeerId.equals(contactPeerId) && !localPeerId.equals(contactPeerId)) {
|
|
321
326
|
if (!incomingPeerId.equals(contactPeerId) && !localPeerId.equals(contactPeerId)) {
|
|
322
327
|
setImmediate(async () => {
|
|
323
328
|
try {
|
|
324
|
-
await this.
|
|
325
|
-
logger.trace('
|
|
329
|
+
await this.replicateDataToContact(dataEntry, contact.getPeerDescriptor())
|
|
330
|
+
logger.trace('replicateDataToContact() returned')
|
|
326
331
|
} catch (e) {
|
|
327
|
-
logger.error('
|
|
332
|
+
logger.error('replicating data to one of the closest contacts failed ' + e)
|
|
328
333
|
}
|
|
329
334
|
})
|
|
330
335
|
}
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import { EXISTING_CONNECTION_TIMEOUT,
|
|
1
|
+
import { EXISTING_CONNECTION_TIMEOUT, RpcRemote } from '../contact/RpcRemote'
|
|
2
2
|
import { IStoreRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
DeleteDataResponse,
|
|
6
|
-
MigrateDataRequest,
|
|
7
|
-
MigrateDataResponse,
|
|
3
|
+
import {
|
|
4
|
+
ReplicateDataRequest,
|
|
8
5
|
StoreDataRequest,
|
|
9
6
|
StoreDataResponse
|
|
10
7
|
} from '../../proto/packages/dht/protos/DhtRpc'
|
|
11
8
|
import { getNodeIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
|
|
12
9
|
|
|
13
|
-
export class StoreRpcRemote extends
|
|
10
|
+
export class StoreRpcRemote extends RpcRemote<IStoreRpcClient> {
|
|
14
11
|
|
|
15
12
|
async storeData(request: StoreDataRequest): Promise<StoreDataResponse> {
|
|
16
13
|
const options = this.formDhtRpcOptions()
|
|
@@ -19,29 +16,16 @@ export class StoreRpcRemote extends Remote<IStoreRpcClient> {
|
|
|
19
16
|
} catch (err) {
|
|
20
17
|
const to = getNodeIdFromPeerDescriptor(this.getPeerDescriptor())
|
|
21
18
|
const from = getNodeIdFromPeerDescriptor(this.getLocalPeerDescriptor())
|
|
22
|
-
throw Error(
|
|
23
|
-
`Could not store data to ${to} from ${from} ${err}`
|
|
24
|
-
)
|
|
19
|
+
throw new Error(`Could not store data to ${to} from ${from} ${err}`)
|
|
25
20
|
}
|
|
26
21
|
}
|
|
27
22
|
|
|
28
|
-
async
|
|
29
|
-
const options = this.formDhtRpcOptions()
|
|
30
|
-
try {
|
|
31
|
-
return await this.getClient().deleteData(request, options)
|
|
32
|
-
} catch (err) {
|
|
33
|
-
throw Error(
|
|
34
|
-
`Could not call delete data to ${getNodeIdFromPeerDescriptor(this.getPeerDescriptor())} ${err}`
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async migrateData(request: MigrateDataRequest, doNotConnect: boolean = false): Promise<MigrateDataResponse> {
|
|
23
|
+
async replicateData(request: ReplicateDataRequest, doNotConnect: boolean = false): Promise<void> {
|
|
40
24
|
const options = this.formDhtRpcOptions({
|
|
41
25
|
timeout: EXISTING_CONNECTION_TIMEOUT,
|
|
42
26
|
doNotConnect
|
|
43
27
|
})
|
|
44
|
-
return this.getClient().
|
|
28
|
+
return this.getClient().replicateData(request, options)
|
|
45
29
|
}
|
|
46
30
|
|
|
47
31
|
}
|
package/src/exports.ts
CHANGED
|
@@ -9,7 +9,7 @@ export { ITransport } from './transport/ITransport'
|
|
|
9
9
|
export { ConnectionManager, ConnectionLocker, PortRange, TlsCertificate } from './connection/ConnectionManager'
|
|
10
10
|
export { DefaultConnectorFacade } from './connection/ConnectorFacade'
|
|
11
11
|
export { DhtRpcOptions } from './rpc-protocol/DhtRpcOptions'
|
|
12
|
-
export {
|
|
12
|
+
export { RpcRemote, EXISTING_CONNECTION_TIMEOUT } from './dht/contact/RpcRemote'
|
|
13
13
|
export { areEqualPeerDescriptors } from './helpers/peerIdFromPeerDescriptor'
|
|
14
14
|
export { IceServer } from './connection/webrtc/WebrtcConnector'
|
|
15
15
|
export { DhtCallContext } from './rpc-protocol/DhtCallContext'
|
package/src/helpers/PeerID.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { BrandedString } from '@streamr/utils'
|
|
1
|
+
import { BrandedString, binaryToHex } from '@streamr/utils'
|
|
2
2
|
import { UUID } from './UUID'
|
|
3
3
|
import { IllegalArguments } from './errors'
|
|
4
4
|
import crypto from 'crypto'
|
|
5
5
|
|
|
6
6
|
export type PeerIDKey = BrandedString<'PeerIDKey'>
|
|
7
7
|
|
|
8
|
+
export const createPeerIDKey = (nodeId: Uint8Array): PeerIDKey => {
|
|
9
|
+
return binaryToHex(nodeId) as PeerIDKey
|
|
10
|
+
}
|
|
11
|
+
|
|
8
12
|
export class PeerID {
|
|
9
13
|
// avoid creating a new instance for every operation
|
|
10
14
|
private static readonly textEncoder = new TextEncoder()
|
|
@@ -14,7 +18,7 @@ export class PeerID {
|
|
|
14
18
|
private readonly key: PeerIDKey // precompute often-used form of data
|
|
15
19
|
|
|
16
20
|
protected constructor({ ip, value, stringValue }: { ip?: string, value?: Uint8Array, stringValue?: string } = {}) {
|
|
17
|
-
if (ip) {
|
|
21
|
+
if (ip !== undefined) {
|
|
18
22
|
this.data = new Uint8Array(20)
|
|
19
23
|
const ipNum = this.ip2Int(ip)
|
|
20
24
|
const view = new DataView(this.data.buffer)
|
|
@@ -23,14 +27,14 @@ export class PeerID {
|
|
|
23
27
|
this.data.set((new UUID()).value, 4)
|
|
24
28
|
} else if (value) {
|
|
25
29
|
this.data = new Uint8Array(value.slice(0))
|
|
26
|
-
} else if (stringValue) {
|
|
30
|
+
} else if (stringValue !== undefined) {
|
|
27
31
|
const ab = PeerID.textEncoder.encode(stringValue) //toUTF8Array(stringValue)
|
|
28
32
|
this.data = ab
|
|
29
33
|
} else {
|
|
30
34
|
throw new IllegalArguments('Constructor of PeerID must be given either ip, value or stringValue')
|
|
31
35
|
}
|
|
32
36
|
|
|
33
|
-
this.key =
|
|
37
|
+
this.key = createPeerIDKey(this.data)
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
static fromIp(ip: string): PeerID {
|
package/src/helpers/UUID.ts
CHANGED
|
@@ -3,6 +3,6 @@ import crypto from 'crypto'
|
|
|
3
3
|
// https://www.scs.stanford.edu/~dm/home/papers/kpos.pdf
|
|
4
4
|
const KADEMLIA_ID_LENGTH_IN_BYTES = 20
|
|
5
5
|
|
|
6
|
-
export const
|
|
6
|
+
export const createRandomNodeId = (): Uint8Array => {
|
|
7
7
|
return crypto.randomBytes(KADEMLIA_ID_LENGTH_IN_BYTES)
|
|
8
8
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { binaryToHex } from '@streamr/utils'
|
|
1
|
+
import { areEqualBinaries, binaryToHex } from '@streamr/utils'
|
|
2
2
|
import { PeerDescriptor } from '../proto/packages/dht/protos/DhtRpc'
|
|
3
|
-
import { PeerID, PeerIDKey } from './PeerID'
|
|
3
|
+
import { PeerID, PeerIDKey, createPeerIDKey } from './PeerID'
|
|
4
4
|
|
|
5
5
|
export const peerIdFromPeerDescriptor = (peerDescriptor: PeerDescriptor): PeerID => {
|
|
6
|
-
return PeerID.fromValue(peerDescriptor.
|
|
6
|
+
return PeerID.fromValue(peerDescriptor.nodeId)
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
// TODO could move getNodeIdFromPeerDescriptor (and NodeID) from trackerless-network
|
|
10
10
|
export const getNodeIdFromPeerDescriptor = (peerDescriptor: PeerDescriptor): string => {
|
|
11
|
-
return binaryToHex(peerDescriptor.
|
|
11
|
+
return binaryToHex(peerDescriptor.nodeId)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export const keyFromPeerDescriptor = (peerDescriptor: PeerDescriptor): PeerIDKey => {
|
|
15
|
-
return
|
|
15
|
+
return createPeerIDKey(peerDescriptor.nodeId)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export const areEqualPeerDescriptors = (peerDescriptor1: PeerDescriptor, peerDescriptor2: PeerDescriptor): boolean => {
|
|
19
|
-
return
|
|
19
|
+
return areEqualBinaries(peerDescriptor1.nodeId, peerDescriptor2.nodeId)
|
|
20
20
|
}
|