Peerster refers to a gossip-based P2P system composed of multiple peers interacting with each other

Peerster design

Peerster refers to a gossip-based P2P system composed of multiple peers interacting with each other. A peer refers to an autonomous entity in the Peerster system. Note that we use the terms "peer", "node", "gossiper", and "participant" interchangeably, but they all refer to the same notion of "peer".

It features 4 specific features:

  • P2P messaging
  • Message Gossiping
  • File sharing following the bittorrent algorithm
  • Consensus on the file names using Paxos and Threshold Logical Clocks

Architecture

A peer is defined by a combination of interfaces, which will be added incrementally to augment the set of features throughout homeworks. We define a Peer interface in /peer/mod.go that is composed of multiple interfaces defined in the same folder. As homeworks progress, we augment the Peer interface with new additions.

The following stack diagram pictures the architecture of the system at the end of the course. This diagram provides the big picture of the system, which can help in understanding the expectations. However, it is not required, nor even expected, to understand it until the last homework. Furthermore, it only represents one of the possible architecture. Every implementation can use its own architecture, as long as it implements correctly the Peer interface.

┌──────┐  ┌───────────┬───────────┬───────────────────┐
│      │  │           │           │                   │
│      │  │           │           │ P2P Data naming   │
│      │  │           │           │                   │
│      │  │ P2P text  │ P2P data  ├───────────────────┤
│      │  │ messaging │ sharing   │                   │
│      │  │           │           │ TLC + Blockchain  │
│ Sto- │  │           │           │                   │
│ rage │  │           │           ├───────────────────┤
│      │  │           │           │                   │
│      │  │           │           │ Paxos             │
│      │  │           │           │                   │
│      │  ├───────────┴───────────┴───────────────────┤
│      │  │                                           │
│      │  │ Gossip protocol                           │
│      │  │                                           │
└──────┘  ├───────────────────────────────────────────┤
          │                                           │
          │ Network                                   │
          │                                           │
          └───────────────────────────────────────────┘

Scope of the implementation

You won't be responsible for implementing all aspects of the peer. Your peer will be passed a peer.Configuration object containing some elements that you will be asked to use. For example, you won't be responsible for handling the messages serialization yourself. Instead, the peer is provided a registry.Registry object that you must use to process messages and marshal them. This is the same for the provided transport.Socket, which provides function to send/receive message. We talk more about those later.

File organization

Emoji points to locations of particular interest for students.

├─docs    Documentation
|
├─gui
|  ├─httpnode    Wraps a peer with a REST API (handle a node with HTTP requests)
|  └─web         A Web front-end for an httpnode
|
├─internal       Used for testing/debugging
|
├─peer
|  ├─impl      👉👉👉 Where you will be working. Contains the peer implementation
|  ├─tests           All the tests
|  mod.go         🔎 The peer interface
|  *.go              Definition of interfaces
|
├─registry    
|  ├─proxy           Needed by the binnode for the integrations tests
|  ├─standard        Provided to the peer to handle messages
|  mod.go            The registry interface
|
├─transport     Defines the mean to exchange messages between peers
|  ├─channel    A socket implementation based on channels
|  ├─proxy      A special socket needed by the binnode for the integration tests
|  ├─udp     👉 Socket implementation, based on UDP
|  mod.go    🔎 Contains the Socket interface and packet/message definitions
|
├─types              Defines the types of messages exchanged between peers.
|  *_def.go        🔎 Message types sent/received between peers
|  registry.go        The message registry

Networking

A peer is not responsible for managing its connection from/to the other peers. For that purpose, the peer receives a transport.Socket object as an input argument, which precisely serves that purpose.

The socket object is defined in /transport/mod.go. A peer uses it to receive and send data to/from other peers. The first job of HW0 is to provide a socket implementation based on UDP. There is a provided socket implementation using go channels in /transport/channel/. This implementation is used in some tests.

You'll remark that Send() and Recv() both have timeouts. Those timeouts can be used to periodically (for example every second) unblock send/recv operations in order to perform some checks. For example, in case the node is shutting down, the node should stop receiving messages.

Marshal/Unmarshal packets

A socket works with transport.Packet elements. However, only raw bytes can be sent over the network. This is why transport.Packet offers marshal/unmarshal functions that must be used to transform a packet to/from a []byte buffer:

pkt := transport.Packet{}

buf, err := pkt.Marshal()
if err != nil {...}

var newPkt transport.Packet

err = pkt.Unmarshal()
if err != nil {...}

Peer's address

A peer's address is defined by its socket, which is provided in the configuration the peer receives:

func NewPeer(conf peer.Configuration) peer.Peer {
    ...
    myAddr := conf.Socket.GetAddress()
    ...
}

Note that when we refer the the peer's address, we actually mean the peer's socket address. For simplicity we most of the time don't add that extra precision. Using port 0 makes the system randomly choose a free port. 127.0.0.1:0 is extensively used in tests.

Data over the network

In order to support interoperability between implementations we provide the strict definition of data exchanged on the network. Each element sent/received on the network is defined as a transport.Packet element. It is the combination of a transport.Header and a transport.Message (see /transport/mod.go):

transport.Packet
┌─────────────────────┐
│                     │
│ transport.Header    │
│ ┌────────────────┐  │
│ │                │  │
│ └────────────────┘  │
│                     │
│ transport.Message   │
│ ┌────────────────┐  │
│ │                │  │
│ └────────────────┘  │
│                     │
└─────────────────────┘

A transport.Message contains the marshaled representation of a types.Message (see /types/mod.go). Two representations are needed to support a message being sent on the network. types.Message (/types/mod.go) is the "rich" representation used by the peer internally, and transport.Message (/transport/mod.go) is used over the network.

To make the conversion from a transport.Message to its corresponding types.Message you must use a registry. See next section.

The following illustration shows what type of message each element of the system use:

Peer A                                                    Peer B
┌──────────────┐         Socket A       Socket B          ┌──────────────┐
│              │         ┌───────┐      ┌───────┐         │              │
│              │◄───────►│       │◄────►│       │◄───────►│              │
│              │         └───────┘      └───────┘         │              │
└──────────────┘                                          └──────────────┘

│            │                 │          │                 │            │
└────────────┴─────────────────┴──────────┴─────────────────┴────────────┘
types.Message  transport.Packet   []byte   transport.Packet  types.Message
                      ---                         ---
               transport.Header            transport.Header
               transport.Message           transport.Message

Message registry

When a transport.Packet is received, the transport.Message it contains needs to be unmarshalled from a buffer (the Payload: json.RawMessage) to an actual meaningful types.Message message (ie. transform a json.RawMessage payload to, for example, a types.ChatMessage). To ease this process, we provide a Registry, which automatically maps a packet (transport.Packet) to a callback that will be invoked when using a provided function on the registry. This registry is provided as input argument to a peer and is defined in /registry/mod.go.

When you create your gossiper, you must call RegisterMessageCallback for all types of different (types.Message) messages you can receive. Each homework will tell you the new messages to include. The Exec argument is a function that is part of your peer implementation. When you receive a packet from the socket, you must call ProcessPacket with the packet received, which will call the callback registered with RegisterMessageCallback for that message. Here is an example:

// The handler. This function will be called when a chat message is received.
func (m XXX) ExecChatMessage(msg types.Message, pkt transport.Packet) error {
    // cast the message to its actual type. You assume it is the right type.
    chatMsg, ok := msg.(*types.ChatMessage)
    if !ok {
        return xerrors.Errorf("wrong type: %T", msg)
    }

    // do your stuff here with chatMsg...
    
    return nil
}

// The part where you register the handler. Must be done when you initialize
// your peer with every type of message expected.
conf.MessageRegistry.RegisterMessageCallback(types.ChatMessage{}, XXX.ExecChatMessage)

// The part where you call the handler. When you receive a message on the socket
// and want to process it on your peer, use the registry.
pkt, err := conf.Socket.Recv(time.Second * 1)
if err {...}

// if this is a chat message, calls ExecChatMessage()
conf.MessageRegistry.ProcessPacket(pkt)

When you need to do the opposite, ie. transform a types.Message to a transport.Message, you must use MarshalMessage() from the registry and pass a pointer to the types.Message message you want to marshal:

// I want to send a chat message to a peer.
msg := types.ChatMessage{...}

remotePeer := XXX
myAddr := conf.Socket.GetAddress()

transpMsg, err := conf.MessageRegistry.MarshalMessage(&msg)
if err != nil {...}

header := transport.NewHeader(
    myAddr,   // source
    myAddr,   // relay
    neighbor, // destination
    0,        // TTL
)
pkt := transport.Packet{
    Header: &header,
    Msg:    &transpMsg,
}

err = socket.Send(remotePeer, pkt)
if err != nil {...}

REST API

/gui/httpnode contains an http server that implements a REST API for a peer. It allows one to use the peer functionalities via HTTP requests. To start the http server there is a CLI in /gui/mod.go. To use this CLI, go to /gui/ and execute go run mod.go start -h to see the help.

CLI                   HTTP node          REST API
┌────────┐            ┌────────┐         ┌─────────┐
│        │ wrap(peer) │        │ listen  │         │
│        ├───────────►│        ├────────►│         │
└────────┘            └────────┘         └─────────┘

Binary node

/internal/binnode contains the implementation of a peer that uses an http binary (/gui/mod.go). The binnode starts an http node and wraps the peer functionalities with HTTP requests. This binary node is used in integration tests to mix the student's implementation with some reference implementations and check the interoperability.

 Binnode           CLI binary          HTTP node
┌─────────┐        ┌─────────┐         ┌─────────┐
│         │ 1:call │         │ 2:start │         │
│         ├───────►│         ├────────►│         │
└────┬────┘        └─────────┘         └─────┬───┘
     │                                       │
     │                                       │
     │            REST API                   │
     │ 4:use      ┌─────────┐    3:listen    │
     └───────────►│         │◄───────────────┘
                  │         │
                  └─────────┘
Owner
João Correia
CS Master's student @ EPFL.
João Correia
Similar Resources

Avalanche: a network composed of multiple blockchains

Subnet EVM Avalanche is a network composed of multiple blockchains. Each blockchain is an instance of a Virtual Machine (VM), much like an object in a

Dec 19, 2022

Simple tool to handle hosts file black lists that can remove comments, remove duplicates, compress to 9 domains per line, add IPv6 entries, as well as can convert black lists to multiple other black list formats compatible with other software.

Hosts-BL Simple tool to handle hosts file black lists that can remove comments, remove duplicates, compress to 9 domains per line, add IPv6 entries, a

Sep 23, 2022

Memberlist - Golang package for gossip based membership and failure detection

memberlist memberlist 是一个 Go 库,它使用基于 gossip 的协议来管理集群成员和成员故障检测。 这种库的用例影响深远:所有分布式系

Jan 26, 2022

A set of components that can be composed into a highly available metric system with unlimited storage capacity

A set of components that can be composed into a highly available metric system with unlimited storage capacity

Overview Thanos is a set of components that can be composed into a highly available metric system with unlimited storage capacity, which can be added

Oct 20, 2021

Dragonfly is an intelligent P2P based image and file distribution system.

Dragonfly is an intelligent P2P based image and file distribution system.

Dragonfly Note: The master branch may be in an unstable or even broken state during development. Please use releases instead of the master branch in o

Jan 9, 2023

Redwood is a highly-configurable, distributed, realtime database that manages a state tree shared among many peers

Redwood is a highly-configurable, distributed, realtime database that manages a state tree shared among many peers. Imagine something like a Redux store, but distributed across all users of an application, that offers offline editing and is resilient to poor connectivity.

Jan 8, 2023

A tool for checking the accessibility of your data by IPFS peers

ipfs-check Check if you can find your content on IPFS A tool for checking the accessibility of your data by IPFS peers Documentation Build go build wi

Dec 17, 2022

An anonymous, encrypted Point-to-Point (Layer 3) tunnel between two peers.

NKN-Link An anonymous, encrypted Point-to-Point (Layer 3) tunnel between two peers. NKN-Link Table of Contents Preface Description Install Setup Run P

Dec 20, 2022

Kiara is a Go equivalent of Phoenix PubSub that makes it easy for Go applications to communicate with each other.

Kiara is a Go equivalent of Phoenix PubSub that makes it easy for Go applications to communicate with each other.

Kiara is a Go equivalent of Phoenix PubSub that makes it easy for Go applications to communicate with each other. Examples Basic Usage Custom Co

Nov 1, 2022

Simple Bank is a simple REST API that allows users to perform transferences with each other.

Simple Bank is a simple REST API that allows users to perform transferences with each other. 🔧 Technologies Golang Docker PostgreSQ

Feb 15, 2022

Databases and dashboards loved each other so much that databoard was born.

databoard Work in progress tool to create API endpoints that executes queries on connected database. ⚠ The project is on early-development stage. Plan

Nov 23, 2021

kitex running in kubernetes cluster and discover each other in kubernetes Service way

Using kitex in kubernetes Kitex [kaɪt'eks] is a high-performance and strong-extensibility Golang RPC framework. This go module helps you to build mult

Feb 21, 2022

individual wallet where each wallet may has multiple cards

individual wallet where each wallet may has multiple cards

Summary This project was made especially as a requirement for passing the technical test in Spenmo. It is a simple golang application that allows us t

Nov 6, 2021

Distributed cache with gossip peer membership enrollment.

Autocache Groupcache enhanced with memberlist for distributed peer discovery. TL;DR See /_example/ for usage. Run docker-compose -f _example/docker-co

Dec 8, 2022

Eunomia is a distributed application framework that support Gossip protocol, QuorumNWR algorithm, PBFT algorithm, PoW algorithm, and ZAB protocol and so on.

Introduction Eunomia is a distributed application framework that facilitates developers to quickly develop distributed applications and supports distr

Sep 28, 2021

golang implement gossip algorithm

golang implement gossip algorithm

golang implement gossip algorithm

Dec 1, 2022

Priority queue with message-group based partitioning and equal attention guarantee for each message group based on Redis

redis-ordered-queue-go Priority queue with message-group based partitioning and equal attention guarantee for each message group based on Redis What i

Oct 21, 2022

A distributed Configuration Center server that manages config in a container. The container is composed of fields (abstract layer includes: KV, LIST, DICT type). The Field contains basic datatypes (int, float, bool, string, list, dict).

A distributed Configuration Center server that manages config in a container. The container is composed of fields (abstract layer includes: KV, LIST, DICT type). The Field contains basic datatypes (int, float, bool, string, list, dict).

cassem config assembler from key-value pairs' container which include basic datatypes, such as int, string, float, bool, list, dict Features HTTP Rest

Nov 1, 2022

gophertunnel is composed of several packages that may be of use for creating Minecraft related tools

gophertunnel is composed of several packages that may be of use for creating Minecraft related tools

gophertunnel is composed of several packages that may be of use for creating Minecraft related tools. A brief overview of all packages may be found here.

Dec 31, 2022
Handshake Query is a cross-platform library to trustlessly resolve and verify Handshake names using a p2p light client

Handshake Query ⚠️ Usage of this library is not currently recommended in your application as the API will likely change. Handshake Query is a cross-pl

Dec 22, 2022
An experimental project to build a framework for naming and sharing files and other data securely
An experimental project to build a framework for naming and sharing files and other data securely

Upspin Documentation: upspin.io About the project Upspin is an experimental project to build a framework for naming and sharing files and other data s

Oct 20, 2021
JuiceFS is a distributed POSIX file system built on top of Redis and S3.
JuiceFS is a distributed POSIX file system built on top of Redis and S3.

JuiceFS is an open-source POSIX file system built on top of Redis and object storage

Jan 5, 2023
Delta : File Sharing system for golang

delta is File Sharing system its good for Local networks or small teams Cross-platform delta runs anywhere Go can compile for: Windows, Mac, Linux, AR

Nov 29, 2021
Built in user interface, LAN file transfer, such as mobile phone, computer, tablet, different operating system
Built in user interface, LAN file transfer, such as mobile phone, computer, tablet, different operating system

Modao Built in user interface, LAN file transfer, such as mobile phone, computer, tablet, different operating systems, etc., as well as text transfer

May 7, 2022
pcp - 📦 Command line peer-to-peer data transfer tool based on libp2p.
pcp - 📦 Command line peer-to-peer data transfer tool based on libp2p.

pcp - Command line peer-to-peer data transfer tool based on libp2p.

Jan 5, 2023
A web based drag and drop file transfer tool for sending files across the internet.

DnD A file transfer tool. Demo Usage Get go get github.com/0xcaff/dnd or download the latest release (you don't need go to run it) Run dnd Now navig

Dec 16, 2022
Open-Local is a local disk management system composed of multiple components.
Open-Local is a local disk management system composed of multiple components.

Open-Local is a local disk management system composed of multiple components. With Open-Local, using local storage in Kubernetes will be as simple as centralized storage.

Dec 30, 2022
Avalanche : a network composed of multiple blockchains

Timestamp Virtual Machine Avalanche is a network composed of multiple blockchains. Each blockchain is an instance of a Virtual Machine (VM), much like

Dec 15, 2021
Avalanche: a network composed of multiple blockchains

Coreth and the C-Chain Avalanche is a network composed of multiple blockchains.

Dec 14, 2022