Abstraction

Abstraction #

In this section, we go through the abstraction layer and what needs to be implemented in order for this API to work.

Node ID #

You should make a decision about size of your node IDs. This API supports Integer, Long and BigInteger by default. How a node ID is chosen can completely be different per use case. For example, this article suggests why it’s a good idea to have the hash of your node’s public key as your Node ID.

Connection Info #

This is just a Serializable interface that determines how nodes can communicate with each other. For example, one implementation can be a simple ip and port of a TCP socket.

Node #

Each kademlia node only sees other nodes as combination of Node ID and Connection Info.

RoutingTable #

RoutingTable and its buckets are Serializable. So you will easily be able to write it to a file. When you are creating an instance of your node, you can pass a new routing table or use one from disk. At this stage, there is no helper class for writing routing table on disk.

You can get proper implementation of routing table based on the ID type of your nodes. Available ones are: BigIntegerRoutingTable, LongRoutingTable and IntegerRoutingTable.

Protocol #

Kademlia Message #

These are objects that represent a message that should be sent and delivered to other nodes. The default package where messages exist is io.ep2p.kademlia.protocol.message. Each message has certain type of serializable data attached to it, and it includes repliers’ Node and status of the replier (if it’s alive or not).

Each message has a type as well, which helps you during the serialization/deserialization process to determine which object should be created from the message.

TypeKademliaMessage ClassPurpose
EMPTYEmptyKademliaMessageJust proves another message was delivered/accepted
PINGPingKademliaMessagePing data to be sent to other nodes
PONGPongKademliaMessagePing response
FIND_NODE_REQFindNodeRequestMessageRequest to find nodes close to current node
FIND_NODE_RESFindNodeResponseMessageResponse to find node request
SHUTDOWNShutdownKademliaMessageTo tell other nodes that current node is shutting down
DHT_LOOKUPDHTLookupKademliaMessageLookup for data in DHT
DHT_LOOKUP_RESULTDHTLookupResultKademliaMessageResult of lookup in DHT
DHT_STOREDHTStoreKademliaMessageStore data in DHT
DHT_STORE_RESULTDHTStoreResultKademliaMessageResult of storing data in DHT

Message Sender #

This is the networking layer. Should be implemented to send message (KademliaMessage) from the caller kademlia-node to receiver node. Serialization, Validation, and request sending are the basic things that shall be done here. The output of the API call probably has a response which should still be converted to the proper KademliaMessage and returned to the caller.

Custom Message handler #

In case you want to extend the protocol or change behaviours, you should add new or extend messages, and write custom handlers. You can then register your message handler on your KademliaNodes using kademliaNode.registerMessageHandler(type, handler)

Key Hash Generator #

The purpose of KeyHashGenerator interface is to bound DHT key size to network GUID size.

For example: when node IDs are BigInteger but DHT keys are String, a KeyHashGenerator implementation is needed to return hash of the String key as BigInteger value.

Kademlia Repository #

This is simply DHT repository where keys and values are stored.