@detox/dht

DHT implementation for Detox project.

Usage no npm install needed!

<script type="module">
  import detoxDht from 'https://cdn.skypack.dev/@detox/dht';
</script>

README

Detox DHT Travis CI

DHT implementation for Detox project.

DHT with simple API that allows to make lookups and put immutable/mutable values into DHT. It is built on top of ES-DHT framework and uses @detox/crypto for cryptographic needs. Still agnostic to transport layer.

How to install

npm install @detox/dht

How to use

Node.js:

var detox_dht = require('@detox/dht')

detox_dht.ready(function () {
    // Do stuff
});

Browser:

requirejs(['@detox/dht'], function (detox_dht) {
    detox_dht.ready(function () {
        // Do stuff
    });
})

API

detox_dht.ready(callback)

  • callback - Callback function that is called when library is ready for use

detox_dht.DHT(dht_public_key : Uint8Array, bucket_size : number, state_history_size : number, values_cache_size : number, fraction_of_nodes_from_same_peer = 0.2 : number, timeouts = {} : Object) : detox_dht.DHT

Constructor for DHT object.

  • dht_public_key - ed25519 that corresponds to temporary user identity in DHT network
  • bucket_size - size of a bucket from Kademlia design
  • state_history_size - how many versions of local history will be kept
  • values_cache_size - how many values will be kept in cache
  • fraction_of_nodes_from_same_peer - max fraction of nodes originated from single peer allowed on lookup start
  • timeouts - various timeouts and intervals used internally

Following timeouts keys are supported, refer to source code for default values:

  • GET_PROOF_REQUEST_TIMEOUT
  • GET_STATE_REQUEST_TIMEOUT
  • GET_VALUE_TIMEOUT
  • PUT_VALUE_TIMEOUT
  • STATE_UPDATE_INTERVAL

detox_dht.DHT.receive(peer_id : Uint8Array, command : number, payload : Uint8Array)

Method needs to be called when DHT command is received from peer_id with payload.

detox_dht.DHT.lookup(node_id : Uint8Array, number = bucket_size : number) : Promise

Starts lookup for specified ID.

  • node_id - target ID
  • number - how many nodes to return in case lookup doesn't reach target ID (also impacts lookup performance in each round, defaults to bucket size)

Promise resolves with Uint8Array[], array will contain either node_id or up to number of IDs of nodes that are closest to it.

detox_dht.DHT.add_peer(peer_id : Uint8Array)

Add new peer on connection.

Peer would not necessarily be added to k-bucket though, depending on internal state.

detox_dht.DHT.del_peer(peer_id : Uint8Array)

Delete peer peer_id, for instance, when peer is disconnected.

detox_dht.DHT.get_value(key : Uint8Array, number = bucket_size : number) : Promise

  • key - key of the value being searched for
  • number - getting value involves lookup, this parameter is the same as number parameter in lookup() method, defaults to bucket size

Resolves with value on success.

detox_dht.DHT.make_immutable_value(key : Uint8Array) : Uint8Array[]

Returns [key, data], can be placed into DHT with put_value() method or null if value is too big to be stored in DHT.

detox_dht.DHT.make_mutable_value(public_key : Uint8Array, private_key : Uint8Array, version : number, value : Uint8Array) : Uint8Array[]

  • public_key - ed25519 public key, will be used as key for mutable data
  • private_key - corresponding ed25519 private key
  • version - up to 32-bit version, increasing this value allows to update older value
  • value - value to be placed into DHT

Returns [key, data], can be placed into DHT with put_value() method or null if value is too big to be stored in DHT.

detox_dht.DHT.verify_value(key : Uint8Array, data : Uint8Array) : Uint8Array

Allows to check whether key and data as returned by make_*_value() methods are valid.

Returns value if correct data and null otherwise.

detox_dht.DHT.put_value(key : Uint8Array, data : Uint8Array, number = bucket_size : number) : Promise

  • key - as returned by make_*_value()
  • data - as returned by make_*_value()
  • number - getting value involves lookup, this parameter is the same as number parameter in lookup() method, defaults to bucket size

detox_dht.DHT.destroy()

Destroy instance.

detox_dht.DHT.on(event: string, callback: Function) : detox_dht.DHT

Register event handler.

detox_dht.DHT.once(event: string, callback: Function) : detox_dht.DHT

Register one-time event handler (just on() + off() under the hood).

detox_dht.DHT.off(event: string[, callback: Function]) : detox_dht.DHT

Unregister event handler.

Event: peer_error

Payload consists of single Uint8Array argument peer_id.

Event is fired to notify higher level about peer error, error is a strong indication of malicious node, communication must be stopped immediately.

Event: peer_warning

Payload consists of single Uint8Array argument peer_id.

Event is fired to notify higher level about peer warning, warning is a potential indication of malicious node, but threshold must be implemented on higher level.

Event: connect_to

Payload consists of two Uint8Array arguments: peer_peer_id and peer_id.

Event is fired when connection needs to be established to peer_id's peer peer_peer_id.

Event: send

Payload consists of three arguments: peer_id (Uint8Array), command (number) and payload (Uint8Array).

Event is fired when DHT command needs to be sent to peer_id with payload.

Event: peer_updated

Payload consists of two arguments: peer_id (Uint8Array) and peer_peers (Uint8Array[]).

Event is fired when new state version was received from peer_id and peer_peers are their current peers.

detox_dht.MAX_VALUE_LENGTH : number

Constant that defines max size of a value that can be stored in DHT.

Contribution

Feel free to create issues and send pull requests (for big changes create an issue first and link it from the PR), they are highly appreciated!

When reading LiveScript code make sure to configure 1 tab to be 4 spaces (GitHub uses 8 by default), otherwise code might be hard to read.

License

Free Public License 1.0.0 / Zero Clause BSD License

https://opensource.org/licenses/FPL-1.0.0

https://tldrlegal.com/license/bsd-0-clause-license