Gathering detailed insights and metrics for xor-routing-table
Gathering detailed insights and metrics for xor-routing-table
XOR distance based routing table used for P2P networks such as a Kademlia DHT.
npm install xor-routing-table
Typescript
Module System
Node Version
NPM Version
70
Supply Chain
98.7
Quality
75
Maintenance
100
Vulnerability
100
License
JavaScript (100%)
Verify real, reachable, and deliverable emails with instant MX records, SMTP checks, and disposable email detection.
Total Downloads
689
Last Day
1
Last Week
5
Last Month
17
Last Year
148
MIT License
32 Stars
21 Commits
5 Forks
3 Watchers
1 Branches
1 Contributors
Updated on Jan 15, 2025
Minified
Minified + Gzipped
Latest Version
0.0.0
Package Id
xor-routing-table@0.0.0
Unpacked Size
11.06 kB
Size
4.29 kB
File Count
6
NPM Version
6.4.1
Node Version
10.15.1
Cumulative downloads
Total Downloads
Last Day
0%
1
Compared to previous day
Last Week
66.7%
5
Compared to previous week
Last Month
21.4%
17
Compared to previous month
Last Year
37%
148
Compared to previous year
XOR based routing table used for P2P networks such as a Kademlia DHT.
npm install xor-routing-table
Similar to k-buckets, but implemented using the simplifications described in https://github.com/ethereum/wiki/wiki/Kademlia-Peer-Selection
To understand the concept behind peer routing, DHTs, and the terms used here, I recommend reading the Kademlia DHT paper as well.
1const RoutingTable = require('xor-routing-table') 2const { randomBytes } = require('crypto') 3 4// Create a new table that stores nodes "close" to the passed in id. 5// The id should be uniformily distributed, ie a hash, random bytes etc. 6const table = new RoutingTable(randomBytes(32)) 7 8// Add a node to the routing table 9table.add({ 10 id: randomBytes(32), // this field is required 11 // populate with any other data you want to store 12}) 13 14table.on('row', function (row) { 15 // A new row has been added to the routing table 16 // This row represents row.index similar bits to the table.id 17 18 row.on('full', function (node) { 19 // The row is full and cannot be split, so node cannot be added. 20 // If any of the nodes in the row are "worse", based on 21 // some application specific metric then we should remove 22 // the worst node from the row and re-add the node. 23 }) 24}) 25 26// Get the 20 nodes "closest" to a passed in id 27const closest = table.closest(randomBytes(32), 20)
table = new RoutingTable(id, [options])
Create a new routing table.
id
should be a Buffer that is uniformily distributed. options
include:
1{ 2 k: 20 // The max row size 3}
bool = table.add(node)
Insert a new node. node.id
must be a Buffer of same length as table.id
.
When inserting a node the XOR distance between the node and the table.id is
calculated and used to figure which table row this node should be inserted into.
Returns true
if the node could be added to the corresponding row or false
if not.
If false
is returned the onfullrow function is invoked for the corresponding row and node.
node = table.get(id)
Get a node from the table using its id. Returns null
if no node has the passed in id
.
bool = table.has(id)
Returns true
if a node exists for the passed in id
and false
otherwise.
nodes = table.closest(id, [maxNodes])
Returns an array of the closest (in XOR distance) nodes to the passed in id.
id
should be Buffer of same length as table.id
. Per default at max k
nodes are returned, but this can be configured using the maxNodes
argument.
This method is normally used in a routing context, i.e. figuring out which nodes in a DHT should store a value based on its id.
bool = table.remove(id)
Remove a node using its id. Returns true
if a node existed for the id and
was removed and false
otherwise.
nodes = table.toArray()
Returns all nodes from table as an array. If you create a new routing table from these nodes it will be identical to the used here.
table.on('row', row)
Emitted when a new row is added to the routing table. At max, bitLength(table.id)
will exist.
table.rows
A fixed size array of all rows in the table. Normally you would not need to worry about accessing rows directly outside the row event.
For the row passed in the the onfullrow
function the following API exists.
row.index
The row index. Represents how many prefix bits are shared between nodes in the row and the table id.
row.nodes
A list of all the nodes in the row, sorted by their id
.
row.data
Property set to null initially you can use if you want to store optional data on the row.
bool = row.add(node)
Same as table.add
but for a specific row. Only use this to add the newNode
passed in onfullrow
function.
bool = row.remove(node)
Same as table.remove
but for a specific row. Only use this to remove the
"worst" node from the row when wanting to add the newNode.
row.on('add', node)
Emitted when a new node is added to this row.
row.on('remove', node)
Emitted when a node has been removed from this row.
row.on('full', node)
Emitted when a node wants to be added to this row, but the row is full (stores k
nodes).
When this happens you should check if any of the nodes already in the row (row.nodes
) are
"worse" than the passed node. If that is the case, remove the "worst" one and re-add the node passed in the arguments.
Various algorithms can be implemented to handle full rows, which is why the routing table leaves most of this logic up to the user. These kind of algorithms include adding the rejected node to a cache and wait for another node in the row to be removed before trying to insert it again, or using an LRU cache to determine which node already in the row has been heard from yet.
MIT
No vulnerabilities found.
No security vulnerabilities found.