Source Code

  • dht - The distributed hash table module.
  • logos - The simple Lisp like language used for computation.
  • net - The low level network functionality.
  • constants.py - defines constants used by the Kademlia DHT network.
  • crypto.py - contains functions used for cryptographically validating / signing messages.
  • utils.py - generic utillity functions used in various different parts of the implementation of the distributed hash table.
  • version.py - defines the current version of this source code.

Please remember:

  • Use pep8 coding standards (see: http://www.python.org/dev/peps/pep-0008/ for more information about what this means).
  • Use the pep8 and pyflakes commands to ensure you stick to the code standards and produce correct Python.
  • If in doubt, read the docs.

drogulus.constants

Defines constants used by the Kademlia DHT network. Where possible naming is derived from the original Kademlia paper as are the suggested default values.

drogulus.constants.ALLOWED_RPC_FAILS = 5

The number of failed remote procedure calls allowed for a contact. If this is equalled or exceeded then the contact is removed from the routing table.

drogulus.constants.ALPHA = 3

Represents the degree of parallelism in network calls.

drogulus.constants.DUPLICATION_COUNT = 20

The number of nodes to attempt to use to store a value in the DHT.

drogulus.constants.ERRORS = {1: 'Bad request', 2: 'Unknown request', 3: 'Internal error', 4: 'Request too big', 5: 'Unsupported protocol', 6: 'Unverifiable provenance', 7: 'Key mismatch', 8: 'Superceded value'}

Defines the errors that can be reported between nodes in the DHT.

drogulus.constants.EXPIRY_DURATION = -1

The duration (in seconds) that is added to a value’s creation time in order to work out its expiry timestamp. -1 denotes no expiry point.

drogulus.constants.K = 20

The maximum number of contacts stored in a k-bucket. Must be an even number.

drogulus.constants.LOOKUP_TIMEOUT = 600

The default maximum time a NodeLookup is allowed to take (in seconds).

drogulus.constants.REFRESH_INTERVAL = 600

How long to wait before a node checks whether any buckets need refreshing or data needs republishing (in seconds).

drogulus.constants.REFRESH_TIMEOUT = 3600

How long to wait before an unused k-bucket is refreshed (in seconds).

drogulus.constants.REPLICATE_INTERVAL = 3600

How long to wait before a node replicates any data it stores (in seconds).

drogulus.constants.RESPONSE_TIMEOUT = 1800

The timeout for receiving complete message once a connection is made (in seconds). Ensures there are no stale deferreds in the node’s _pending dictionary.

drogulus.constants.RPC_TIMEOUT = 5

The timeout for network connections (in seconds).

drogulus.crypto

Contains functions for cryptographically signing / verifying items stored in the DHT.

drogulus.crypto.construct_hash(value, timestamp, expires, name, meta, created_with)[source]

The hash is a SHA512 hash of the concatenated SHA512 hashes of the msgpack encoded ‘value’, ‘timetamp, ‘expires’, ‘name’, ‘meta’ and ‘created_with’ fields (in that order).

It ensures that the ‘value’, ‘timestamp’, ‘expires’, ‘name’, ‘meta’ and ‘created_with’ fields have not been tampered with.

drogulus.crypto.construct_key(public_key, name='')[source]

Given a string representation of a user’s public key and the human readable string to use as a key in the DHT this function will return a digest of the SHA512 hash to use as the actual key to use within the DHT.

This ensures that the provenance (public key) and meaning of the key determine its value in the DHT.

drogulus.crypto.generate_signature(value, timestamp, expires, name, meta, created_with, private_key)[source]

Given the value, timestamp, expires, name, meta and created_with values of an outgoing value carrying message will use the private key to generate a cryptographic hash to the message to be used to sign / validate the message.

This ensures that the ‘value’, ‘timestamp’, ‘expires’, ‘name’, ‘meta’ and ‘created_with’ fields have not been tampered with.

The hash is created with the private key of the person storing the key/value pair. It is, in turn, based upon the SHA512 hash of the SHA512 hashes of the ‘value’, ‘timestamp’, ‘expires’, ‘name’, ‘meta’ and ‘created_with’ fields.

drogulus.crypto.validate_message(message)[source]

Given an item stored within the DHT this function will return a tuple containing two fields:

  • a boolean to indicate its validity,
  • an error number based upon constants.ERRORS (in the case of a fail) or None (if success).

The message contains a public_key field which is used to validate the message’s ‘sig’ field with a list of SHA512 hashes of the message’s ‘value’, ‘timestamp’, ‘name’, ‘meta’ and ‘created_with’ fields. This proves the provenance of the data and ensures that these fields have not been tampered with.

Furthermore, once the validity of the public_key field is proven through the proceeding check, the ‘key’ field is verified to be a SHA512 hash of the SHA512 hashes of the ‘public_key’ and ‘name’ fields. This ensures the correct key is used to locate the data in the DHT.

drogulus.crypto.validate_signature(value, timestamp, expires, name, meta, created_with, signature, public_key)[source]

Uses the public key to validate the cryptographic signature based upon a hash of the values in the ‘value’, ‘timestamp’, ‘expires’, ‘name’, ‘meta’ and ‘created_with’ fields of a value carrying message.

drogulus.node

Encapsulates a node in the drogulus.

class drogulus.node.Drogulus(private_key, public_key, alias=None)[source]

Represents a node in the Drogulus distributed hash table. This is the class that generally should be instantiated.

get(public_key, key_name)[source]

Gets the value associated with a compound key made of the passed in public key and meaningful key name. Returns a deferred that fires when the value is retrieved.

join()[source]

Causes the node to join the distributed hash table. Returns a deferred that fires when the operation is complete.

set(key_name, value, duplicate=20, meta=None, expires=-1)[source]

Stores a value at a compound key made from the local node’s public key and the passed in meaningful key name. Returns a deferred that fires when the value has been stored to duplicate number of nodes. An optional meta dictionary and expires duration (to be added to the current time) can also be specified.

whois(public_key)[source]

Given the public key of an entity that uses the drogulus will return a deferred that fires when information about them stored in the DHT is retrieved.

drogulus.utils

Contains generic utillity functions used in various different parts of Drogulus.

drogulus.utils.distance(key_one, key_two)[source]

Calculate the XOR result between two string variables returned as a long type value.

drogulus.utils.hex_to_long(raw)[source]

Given a hexadecimal string representation of a number (like a key or node’s ID for example) returns the numeric (long) value.

drogulus.utils.long_to_hex(raw)[source]

Given a raw numeric value (like a node’s ID for example) returns it expressed as a hexadecimal string.

drogulus.utils.sort_contacts(contacts, target_key)[source]

Given a list of contacts, efficiently sorts it so that the contacts closest to the target key are at the head. If the list is longer than K then only the K closest contacts will be returned.

drogulus.version

An over engineered way of setting the version. Based upon a simplification of how Django (http://djangoproject.com/) does it. ;-)

drogulus.version.VERSION = (0, 0, 0, 'alpha', 0)

MAJOR, MINOR, RELEASE, STATUS [alpha, beta, final], VERSION

drogulus.version.get_version()[source]

Returns a string representation of the version information of this project.