Peer to Peer networks are fundamental to the blockchain technology, they provide the base layer for a decentralized communication model between two peers , which can communicate with each other without the need for a central server. Using the correct technologies to implement this types of networks is essential for the success of any blockchain solution. As always Kubernetes, due its scalability and flexibility, is a must. Associated to a library, like rust-libp2p, that can support the requirements of a p2p application.
Peer to peer networks(P2P) is defined as the group of devices that are connected together to create a network. libp2p is a modular peer-to-peer networking framework.
Although libp2p was originally developed to work with IPFS, we want to use it to create p2p applications that have no relationship to IPFS at all.
In order to do that we need:
- A discovery service that is able to find peers. Multicast DNS (mDNS) protocol.
- A register service that is able store SHA256 (PeerID) in a data structure. Kademlia Distributed Hash Table.
The Multicast DNS (mDNS) protocol only can be used in local networks (containers within the same Pod). Multicast DNS (mDNS) does not process hostnames with other top-level domains (TLDs). Meaning we will need a implementation like Kademlia that is a data structure stored on multiple computers, scalable and fault-tolerant.
A distributed hash table (DHT) is a distributed system for mapping keys to values:
- PUT(key, value), which inserts a new element.
- GET(key), which returns the value of the element corresponding to that key.
There are some fundamental limitations here. If all computers leave at once, we have nowhere to store anything. We will need to replicate keys across different computers so that key-value pairs will be recoverable even if some of those computers leave at once.
libp2p was designed around the philosophy of creating small components that are easy to understand and test. These components should also be able to be swapped in order to accommodate different technologies or scenarios and also make it feasible to upgrade them over time.
The libp2p interface acts as a thin veneer over a multitude of subsystems that are required in order for peers to be able to communicate. The main areas where these subsystems fit are:
- Peer Routing - Mechanism to decide which peers to use for routing particular messages. This routing can be done recursively, iteratively or even in a broadcast/multicast mode.
- Swarm - Handles everything that touches the 'opening a stream' part of libp2p, from protocol muxing, stream muxing, NAT traversal and connection relaying, while being multi-transport.
- Distributed Record Store - A system to store and distribute records. Records are small entries used by other systems for signaling, establishing links, announcing peers or content, and so on. They have a similar role to DNS in the broader Internet.
- Discovery - Finding or identifying other peers in the network.
For demonstration purposes, three scenarios were created using kubernetes:
For the scenarios developed some network considerations need to be understood:
- Communication between pods on the same node
A network bridge connects two networks together. When a request hits the bridge, the bridge asks all the connected devices (i.e. pods) if they have the right IP address to handle the original request.
-
Communication between pods on different nodes
At the cluster level, there’s a table that maps IP address ranges to various nodes. Pods on those nodes will have been assigned IP addresses from those ranges.
The underlying objective is to leverages the power of p2p networks via the libp2p-rust to provide a shared and trusted ledger of transactions (blockchain technology).
Source code:
- p2p-app ping example.
- mdns-app mDNS example.
- dht-app mDNS/Kademlia(DHT) example.
- kubernetes-setup Kubernetes setup.
References:
Rust libp2p
libp2p documentation