@streamr/dht 100.1.1 → 100.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/package.json +8 -10
  2. package/dist/src/connection/ConnectionManager.js +4 -6
  3. package/dist/src/connection/ConnectionManager.js.map +1 -1
  4. package/dist/src/dht/DhtNode.js +3 -1
  5. package/dist/src/dht/DhtNode.js.map +1 -1
  6. package/dist/src/dht/PeerManager.d.ts +4 -3
  7. package/dist/src/dht/PeerManager.js +54 -58
  8. package/dist/src/dht/PeerManager.js.map +1 -1
  9. package/dist/src/dht/contact/ContactList.d.ts +2 -8
  10. package/dist/src/dht/contact/ContactList.js +1 -10
  11. package/dist/src/dht/contact/ContactList.js.map +1 -1
  12. package/dist/src/dht/contact/RandomContactList.js +3 -10
  13. package/dist/src/dht/contact/RandomContactList.js.map +1 -1
  14. package/dist/src/dht/contact/RingContactList.d.ts +2 -2
  15. package/dist/src/dht/contact/RingContactList.js +6 -5
  16. package/dist/src/dht/contact/RingContactList.js.map +1 -1
  17. package/dist/src/dht/contact/SortedContactList.d.ts +4 -8
  18. package/dist/src/dht/contact/SortedContactList.js +24 -51
  19. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  20. package/dist/src/dht/discovery/PeerDiscovery.d.ts +2 -7
  21. package/dist/src/dht/discovery/PeerDiscovery.js +2 -2
  22. package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
  23. package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +1 -2
  24. package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
  25. package/dist/src/dht/recursive-operation/RecursiveOperationSession.js +2 -3
  26. package/dist/src/dht/recursive-operation/RecursiveOperationSession.js.map +1 -1
  27. package/dist/src/dht/routing/RoutingSession.js +2 -3
  28. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  29. package/dist/src/dht/routing/RoutingTablesCache.d.ts +1 -1
  30. package/dist/src/dht/routing/RoutingTablesCache.js.map +1 -1
  31. package/dist/src/dht/store/StoreManager.js +6 -7
  32. package/dist/src/dht/store/StoreManager.js.map +1 -1
  33. package/package.json +8 -10
  34. package/src/connection/ConnectionManager.ts +4 -6
  35. package/src/connection/webrtc/BrowserWebrtcConnection.ts +21 -28
  36. package/src/dht/DhtNode.ts +3 -1
  37. package/src/dht/PeerManager.ts +54 -58
  38. package/src/dht/contact/ContactList.ts +2 -12
  39. package/src/dht/contact/RandomContactList.ts +4 -11
  40. package/src/dht/contact/RingContactList.ts +7 -5
  41. package/src/dht/contact/SortedContactList.ts +27 -58
  42. package/src/dht/discovery/PeerDiscovery.ts +7 -3
  43. package/src/dht/recursive-operation/RecursiveOperationManager.ts +1 -2
  44. package/src/dht/recursive-operation/RecursiveOperationSession.ts +2 -3
  45. package/src/dht/routing/RoutingSession.ts +2 -3
  46. package/src/dht/routing/RoutingTablesCache.ts +3 -1
  47. package/src/dht/store/StoreManager.ts +7 -8
  48. package/test/benchmark/SortedContactListBenchmark.test.ts +9 -52
  49. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +1 -2
  50. package/test/integration/ReplicateData.test.ts +1 -2
  51. package/test/unit/PeerManager.test.ts +56 -7
  52. package/test/unit/SortedContactList.test.ts +17 -36
  53. package/test/benchmark/kademlia-simulation/Contact.ts +0 -32
  54. package/test/benchmark/kademlia-simulation/KademliaSimulation.ts +0 -94
  55. package/test/benchmark/kademlia-simulation/SimulationNode.ts +0 -129
  56. package/test/data/generateGroundTruthData.ts +0 -71
@@ -1,94 +0,0 @@
1
- /* eslint-disable no-console */
2
-
3
- import { SimulationNode } from './SimulationNode'
4
- import fs from 'fs'
5
- import { getDhtAddressFromRaw } from '../../../src/identifiers'
6
-
7
- export class KademliaSimulation {
8
-
9
- private static readonly NUM_NODES = 1000
10
- private static readonly ID_LENGTH = 8
11
-
12
- private readonly nodeNamesById: Record<string, number> = {}
13
- private readonly nodes: SimulationNode[] = []
14
-
15
- private readonly dhtIds: Array<{ type: string, data: Array<number> }>
16
- private readonly groundTruth: Record<string, Array<{ name: string, distance: number, id: { type: string, data: Array<number> } }>>
17
-
18
- constructor() {
19
- if (!fs.existsSync('test/data/nodeids.json')) {
20
- throw new Error('Cannot find test/data/nodeids.json, please run "npm run prepare-kademlia-simulation first"')
21
- }
22
- this.dhtIds = JSON.parse(fs.readFileSync('test/data/nodeids.json').toString())
23
- this.groundTruth = JSON.parse(fs.readFileSync('test/data/orderedneighbors.json').toString())
24
- }
25
-
26
- public run(): void {
27
- for (let i = 0; i < KademliaSimulation.NUM_NODES; i++) {
28
- const node = new SimulationNode(getDhtAddressFromRaw(Buffer.from(this.dhtIds[i].data.slice(0, KademliaSimulation.ID_LENGTH))))
29
- this.nodeNamesById[JSON.stringify(node.getContact().id)] = i
30
- this.nodes.push(node)
31
- node.joinDht(this.nodes[0])
32
-
33
- process.stdout.write('.')
34
- }
35
-
36
- let minimumCorrectNeighbors = Number.MAX_SAFE_INTEGER
37
-
38
- let sumCorrectNeighbors = 0
39
- let sumKbucketSize = 1
40
- let sumOutgoingRpcCalls = 0
41
- let maxOutgoingRpcCalls = 0
42
-
43
- for (let i = this.nodes.length - 1; i >= 0; i--) {
44
-
45
- const outgoingRpcCallCount = this.nodes[i].getOutgoingRpcCallCount()
46
- console.log('-----------')
47
- console.log('Node: ' + i)
48
- console.log('Kbucket size: ' + this.nodes[i].getKBucketSize())
49
- console.log('Num incoming RPC calls: ' + this.nodes[i].getIncomingRpcCallCount())
50
- console.log('Num outgoing RPC calls: ' + outgoingRpcCallCount)
51
-
52
- sumOutgoingRpcCalls += outgoingRpcCallCount
53
-
54
- if (maxOutgoingRpcCalls < outgoingRpcCallCount) {
55
- maxOutgoingRpcCalls = outgoingRpcCallCount
56
- }
57
-
58
- const kademliaNeighbors = this.nodes[i].getNeightborList().getContactIds()
59
-
60
- let correctNeighbors = 0
61
- for (let j = 0; j < this.groundTruth[i + ''].length; j++) {
62
- if (this.groundTruth[i + ''][j].name != (this.nodeNamesById[JSON.stringify(kademliaNeighbors[j])] + '')) {
63
- break
64
- }
65
- correctNeighbors++
66
- }
67
-
68
- if (correctNeighbors < minimumCorrectNeighbors) {
69
- minimumCorrectNeighbors = correctNeighbors
70
- }
71
-
72
- console.log('Correct neighbors: ' + correctNeighbors)
73
-
74
- if (i > 0) {
75
- sumKbucketSize += this.nodes[i].getKBucketSize()
76
- sumCorrectNeighbors += correctNeighbors
77
- }
78
- }
79
-
80
- const avgCorrectNeighbors = sumCorrectNeighbors / (KademliaSimulation.NUM_NODES - 1)
81
- const avgKbucketSize = sumKbucketSize / (KademliaSimulation.NUM_NODES - 1)
82
- const avgOutgoingRpcCallCount = sumOutgoingRpcCalls / (KademliaSimulation.NUM_NODES - 1)
83
-
84
- console.log('----------- Simulation results ------------------')
85
- console.log('Minimum correct neighbors: ' + minimumCorrectNeighbors)
86
- console.log('Average correct neighbors: ' + avgCorrectNeighbors)
87
- console.log('Average Kbucket size: ' + avgKbucketSize)
88
- console.log('Average number of outgoing RPC calls: ' + avgOutgoingRpcCallCount)
89
- console.log('MAX number of outgoing RPC calls: ' + maxOutgoingRpcCalls)
90
- }
91
- }
92
-
93
- const simulation = new KademliaSimulation()
94
- simulation.run()
@@ -1,129 +0,0 @@
1
- import KBucket from 'k-bucket'
2
- import { Contact } from './Contact'
3
- import { SortedContactList } from '../../../src/dht/contact/SortedContactList'
4
- import { DhtAddress, getRawFromDhtAddress } from '../../../src/identifiers'
5
-
6
- export class SimulationNode {
7
-
8
- private numberOfNodesPerKBucket = 1
9
- private K = 8
10
- private ALPHA = 1
11
-
12
- private bucket: KBucket<Contact>
13
- private ownContact: Contact
14
-
15
- private incomingRpcCallCount = 0
16
- private outgoingRpcCallCount = 0
17
-
18
- private neighborList: SortedContactList<Contact>
19
- private ownId: DhtAddress
20
-
21
- constructor(ownId: DhtAddress) {
22
- this.ownId = ownId
23
- this.ownContact = new Contact(this.ownId, this)
24
- this.bucket = new KBucket({
25
- localNodeId: getRawFromDhtAddress(this.ownId),
26
- numberOfNodesPerKBucket: this.numberOfNodesPerKBucket
27
- })
28
-
29
- this.neighborList = new SortedContactList({
30
- referenceId: this.ownId,
31
- maxSize: 1000,
32
- allowToContainReferenceId: false,
33
- emitEvents: false
34
- })
35
- }
36
-
37
- // For simulation use
38
-
39
- public getNeightborList(): SortedContactList<Contact> {
40
- return this.neighborList
41
- }
42
- public getContact(): Contact {
43
- return this.ownContact
44
- }
45
-
46
- public getKBucketSize(): number {
47
- return this.bucket.count()
48
- }
49
-
50
- public getIncomingRpcCallCount(): number {
51
- return this.incomingRpcCallCount
52
- }
53
-
54
- public getOutgoingRpcCallCount(): number {
55
- return this.outgoingRpcCallCount
56
- }
57
-
58
- // RPC call
59
-
60
- public getClosestNodesTo(id: DhtAddress, caller: SimulationNode): Contact[] {
61
- this.incomingRpcCallCount++
62
- const idValue = getRawFromDhtAddress(id)
63
- const ret = this.bucket.closest(idValue)
64
- if (!this.bucket.get(idValue)) {
65
- const contact = new Contact(id, caller)
66
- this.bucket.add(contact)
67
- this.neighborList.addContact(contact)
68
- }
69
- return ret
70
- }
71
-
72
- private findMoreContacts(contactList: Contact[], shortlist: SortedContactList<Contact>) {
73
- contactList.forEach((contact) => {
74
- shortlist.setContacted(contact.getNodeId())
75
- shortlist.setActive(contact.getNodeId())
76
- this.outgoingRpcCallCount++
77
- const returnedContacts = contact.dhtNode!.getClosestNodesTo(this.ownId, this)
78
- shortlist.addContacts(returnedContacts)
79
- returnedContacts.forEach((returnedContact: Contact) => {
80
- if (!this.bucket.get(returnedContact.id)) {
81
- this.bucket.add(returnedContact)
82
- }
83
- })
84
- })
85
- }
86
-
87
- public joinDht(entryPoint: SimulationNode): void {
88
- if (entryPoint.getContact().getNodeId() === this.ownId) {
89
- return
90
- }
91
-
92
- this.bucket.add(entryPoint.getContact())
93
- const closest = this.bucket.closest(getRawFromDhtAddress(this.ownId), this.ALPHA)
94
-
95
- this.neighborList.addContacts(closest)
96
-
97
- /* eslint-disable no-constant-condition */
98
- while (true) {
99
- let oldClosestContactId = this.neighborList.getClosestContactId()
100
- let uncontacted = this.neighborList.getUncontactedContacts(this.ALPHA)
101
- if (uncontacted.length === 0) {
102
- return
103
- }
104
-
105
- this.findMoreContacts(uncontacted, this.neighborList)
106
-
107
- if (oldClosestContactId === this.neighborList.getClosestContactId()) {
108
- uncontacted = this.neighborList.getUncontactedContacts(this.K)
109
- if (uncontacted.length === 0) {
110
- return
111
- }
112
-
113
- while (true) {
114
- oldClosestContactId = this.neighborList.getClosestContactId()
115
- this.findMoreContacts(uncontacted, this.neighborList)
116
-
117
- if (this.neighborList.getActiveContacts().length >= this.K ||
118
- (oldClosestContactId === this.neighborList.getClosestContactId())) {
119
- return
120
- }
121
- uncontacted = this.neighborList.getUncontactedContacts(this.ALPHA)
122
- if (uncontacted.length === 0) {
123
- return
124
- }
125
- }
126
- }
127
- }
128
- }
129
- }
@@ -1,71 +0,0 @@
1
- import fs from 'fs'
2
- import crypto from 'crypto'
3
- import KBucket from 'k-bucket'
4
- import { DhtAddressRaw } from '../../src/identifiers'
5
-
6
- const ID_LENGTH = 20
7
- const NUM_NODES = 900
8
- const NUM_NEAREST = 10
9
-
10
- const generateId = function(): DhtAddressRaw {
11
- return crypto.randomBytes(ID_LENGTH)
12
- }
13
-
14
- const findNNearestNeighbors = function(ownIndex: number, ownId: DhtAddressRaw, nodes: Array<DhtAddressRaw>, n: number): Array<number> {
15
- const retIndex: Array<number> = []
16
-
17
- for (let i = 0; i < n; i++) {
18
- let closestIndex: number = Number.MAX_VALUE
19
- let closestDistance: number = Number.MAX_VALUE
20
-
21
- for (let j = 0; j < nodes.length; j++) {
22
- if (j == ownIndex || retIndex.includes(j)) {
23
- continue
24
- }
25
- const distance = KBucket.distance(ownId, nodes[j])
26
- if (distance < closestDistance) {
27
- closestDistance = distance
28
- closestIndex = j
29
- }
30
- }
31
- retIndex.push(closestIndex)
32
- }
33
- return retIndex
34
- }
35
-
36
- const writer = fs.createWriteStream('nodeids.json', {})
37
- const neighborWriter = fs.createWriteStream('orderedneighbors.json', {})
38
-
39
- neighborWriter.write('{\n')
40
-
41
- const nodes: Array<DhtAddressRaw> = []
42
-
43
- // generate nodeIds
44
-
45
- for (let i = 0; i < NUM_NODES; i++) {
46
- const id = generateId()
47
- nodes.push(id)
48
- }
49
-
50
- writer.write(JSON.stringify(nodes, null, 4))
51
- writer.end()
52
-
53
- for (let i = 0; i < NUM_NODES; i++) {
54
-
55
- const neighborIds = findNNearestNeighbors(i, nodes[i], nodes, NUM_NEAREST)
56
-
57
- const neighborNames: Array<{ name: number, distance: number, id: DhtAddressRaw }> = []
58
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
59
- for (let j = 0; j < neighborIds.length; j++) {
60
- neighborNames.push({ name: neighborIds[j], distance: KBucket.distance(nodes[i], nodes[neighborIds[j]]), id: nodes[neighborIds[j]] })
61
- }
62
- neighborWriter.write('"' + i + '": ' + JSON.stringify(neighborNames))
63
- process.stdout.write('.')
64
-
65
- if (i != NUM_NODES - 1) {
66
- neighborWriter.write(',\n')
67
- }
68
- }
69
-
70
- neighborWriter.write('}')
71
- neighborWriter.end()