p2p

package
v1.0.0-beta.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2025 License: Apache-2.0 Imports: 27 Imported by: 0

README

P2P Package

This document provides an overview of the P2P (peer-to-peer) networking system used in Evolve. The P2P package leverages go-libp2p stack for establishing peer connections, gossiping transactions, and synchronizing headers and blocks across the network.

Overview

Every node (both full and light) runs a P2P client for participating in the P2P network. The client handles the following key functions:

  • Establishing and managing peer connections
  • Gossiping transactions through the network
  • Supporting header and block synchronization services
  • Validating gossiped messages (different for full and light nodes)

Architecture

graph TB
    subgraph "Evolve Node"
        P2PClient["P2P Client"]
        TxValidator["Transaction Validator"]
        Mempool["Mempool"]
        SyncServices["Header/Block Sync Services"]
    end

    P2PClient -- "Uses" --> Libp2p["libp2p Stack"]
    Libp2p -- "Components" --> DHT["Kademlia DHT"]
    Libp2p -- "Components" --> PubSub["GossipSub"]
    Libp2p -- "Components" --> ConnGater["Connection Gater"]
    Libp2p -- "Components" --> PeerDiscovery["Peer Discovery"]

    P2PClient -- "Configures" --> TxValidator
    TxValidator -- "Adds valid txs" --> Mempool
    P2PClient -- "Supports" --> SyncServices

    P2PClient -- "Connects to" --> SeedNodes["Seed Nodes"]
    P2PClient -- "Connects to" --> OtherPeers["Other Peers"]

Configuration

The P2P client is configured using the P2PConfig struct:

type P2PConfig struct {
    ListenAddress string // Address to listen for incoming connections
    Seeds         string // Comma separated list of seed nodes to connect to
    BlockedPeers  string // Comma separated list of nodes to ignore
    AllowedPeers  string // Comma separated list of nodes to whitelist
}
Configuration Parameters
Parameter Description Default Example
ListenAddress The address where the node listens for incoming P2P connections /ip4/0.0.0.0/tcp/7676 /ip4/0.0.0.0/tcp/7676
Seeds Comma-separated list of seed nodes (bootstrap nodes) "" /ip4/1.2.3.4/tcp/7676/p2p/12D3KooWA8EXV3KjBxEU...,/ip4/5.6.7.8/tcp/7676/p2p/12D3KooWJN9ByvD...
BlockedPeers Comma-separated list of peer IDs to block "" 12D3KooWA8EXV3KjBxEU...,12D3KooWJN9ByvD...
AllowedPeers Comma-separated list of peer IDs to explicitly allow "" 12D3KooWA8EXV3KjBxEU...,12D3KooWJN9ByvD...

libp2p Components

The P2P client leverages several key components from the libp2p stack:

graph LR
    Client["P2P Client"]
    Client --> Host["libp2p Host"]
    Client --> DHT["Kademlia DHT"]
    Client --> Discovery["Routing Discovery"]
    Client --> Gater["Connection Gater"]
    Client --> PubSub["GossipSub PubSub"]

    Host --> Transport["Transport Protocols"]
    Host --> Security["Security Protocols"]
    Host --> Muxer["Stream Multiplexers"]

    DHT --> PeerRouting["Peer Routing"]
    DHT --> ContentRouting["Content Routing"]

    Discovery --> FindPeers["Find Peers"]
    Discovery --> Advertise["Advertise"]

    PubSub --> Topics["Topics by ChainID"]
    PubSub --> Validation["Message Validation"]
Key libp2p Technologies
  1. Host: The basic libp2p node that provides connectivity to the P2P network

    • Handles connections and streams
    • Manages identity (using a private key)
    • Listens on specified multiaddresses
  2. Kademlia DHT: Distributed Hash Table for peer discovery and routing

    • Used for finding other peers within the same network
    • Bootstrapped with seed nodes defined in configuration
  3. GossipSub: Publish-subscribe protocol for message dissemination

    • Used for gossiping transactions, headers, and blocks
    • Provides efficient message propagation with reduced bandwidth overhead
    • Supports message validation through custom validators
  4. Connection Gater: Controls which peers can connect

    • Implements peer filtering based on blocked and allowed peer lists
    • Provides security by blocking unwanted connections
  5. Peer Discovery: Mechanisms for finding peers on the network

    • Uses DHT for peer routing
    • Advertises presence on the network using chain ID as namespace
    • Actively searches for peers in the same namespace

Client Lifecycle

sequenceDiagram
    participant A as Application
    participant P as P2P Client
    participant H as libp2p Host
    participant D as DHT
    participant G as GossipSub
    participant N as Network/Other Peers

    A->>P: NewClient(config, chainID, datastore, logger, metrics)
    P->>P: Initialize configuration
    A->>P: Start(ctx)
    P->>H: listen() (Create libp2p host)
    H-->>P: host
    P->>P: setupBlockedPeers()
    P->>P: setupAllowedPeers()
    P->>G: setupGossiping(ctx)
    G-->>P: pubsub instance
    P->>D: setupDHT(ctx)
    P->>D: Bootstrap(ctx)
    D->>N: Connect to seed nodes
    P->>P: setupPeerDiscovery(ctx)
    P->>N: advertise(ctx) (Advertise namespace)
    P->>N: findPeers(ctx) (Find peers in namespace)
    N-->>P: List of peers
    P->>N: Connect to discovered peers
    A->>P: SetTxValidator(validator)
    A->>P: BroadcastTx(tx)
    P->>G: Publish message to topic
    G->>N: Gossip message to peers
    N-->>G: Incoming message
    G->>P: Validate message
    P->>A: Add valid tx to mempool (if full node)

Full vs. Light Node Validators

The P2P clients in full and light nodes handle transaction validation differently:

  1. Full Node Validator:

    • Processes all gossiped transactions
    • Validates transactions before adding to mempool
    • Participates fully in the P2P network
  2. Light Node Validator:

    • Implements a "dummy" validator that doesn't process transactions
    • Doesn't maintain a mempool
    • Still participates in the P2P network for other purposes

Message Gossiping

Messages (transactions, blocks, etc.) are gossiped through the network using GossipSub topics. The topic format is:

<chainID>+<topicSuffix>

Where:

  • chainID is the chain identifier
  • topicSuffix is a suffix specific to the message type (e.g., "tx" for transactions)

This namespace approach ensures that messages only propagate within the intended network.

Key Functions

  • NewClient: Creates a new P2P client with the provided configuration
  • Start: Establishes P2P connectivity (sets up host, gossiping, DHT, and peer discovery)
  • Close: Gracefully stops the client
  • Peers: Returns a list of connected peers
  • BroadcastTx: Broadcasts a transaction to the P2P network

Metrics

The P2P client can collect and expose metrics about its operations, including:

  • Number of connected peers
  • Bytes sent/received per peer
  • Number of transactions submitted by each peer
  • Message bytes by message type

These metrics can be exposed via Prometheus for monitoring and alerting.

Examples

Creating and Starting a P2P Client
// Create configuration
conf := config.Config{
    RootDir: "/path/to/root",
    P2P: config.P2PConfig{
        ListenAddress: "/ip4/0.0.0.0/tcp/7676",
        Seeds: "/ip4/1.2.3.4/tcp/7676/p2p/12D3KooWXYZ...,/ip4/5.6.7.8/tcp/7676/p2p/12D3KooWABC...",
    },
}

// Create datastore
ds := datastore.NewMapDatastore()

// Create logger
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))

// Create metrics
metrics := p2p.PrometheusMetrics("evolve")

// Create client
client, err := p2p.NewClient(conf, "mychain-1", ds, logger, metrics)
if err != nil {
    // Handle error
}

// Start client
err = client.Start(context.Background())
if err != nil {
    // Handle error
}

// When done, close the client
defer client.Close()

Documentation

Index

Constants

View Source
const (
	// MetricsSubsystem is a subsystem shared by all metrics exposed by this
	// package.
	MetricsSubsystem = "p2p"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a P2P client, implemented with libp2p.

Initially, client connects to predefined seed nodes (aka bootnodes, bootstrap nodes). Those seed nodes serve Kademlia DHT protocol, and are agnostic to ORU chain. Using DHT peer routing and discovery clients find other peers within ORU network.

func NewClient

func NewClient(
	conf config.P2PConfig,
	privKey crypto.PrivKey,
	ds datastore.Datastore,
	chainID string,
	logger zerolog.Logger,
	metrics *Metrics,
) (*Client, error)

NewClient creates new Client object.

Basic checks on parameters are done, and default parameters are provided for unset-configuration

func NewClientWithHost

func NewClientWithHost(
	conf config.P2PConfig,
	privKey crypto.PrivKey,
	ds datastore.Datastore,
	chainID string,
	logger zerolog.Logger,
	metrics *Metrics,
	h host.Host,
) (*Client, error)

func (*Client) Addrs

func (c *Client) Addrs() []multiaddr.Multiaddr

Addrs returns listen addresses of Client.

func (*Client) Close

func (c *Client) Close() error

Close gently stops Client.

func (*Client) ConnectionGater

func (c *Client) ConnectionGater() *conngater.BasicConnectionGater

ConnectionGater returns the client's connection gater

func (*Client) GetNetworkInfo

func (c *Client) GetNetworkInfo() (NetworkInfo, error)

func (*Client) GetPeers

func (c *Client) GetPeers() ([]peer.AddrInfo, error)

func (*Client) Host

func (c *Client) Host() host.Host

Host returns the libp2p node in a peer-to-peer network

func (*Client) Info

func (c *Client) Info() (string, string, string, error)

Info returns client ID, ListenAddr, and Network info

func (*Client) PeerIDs

func (c *Client) PeerIDs() []peer.ID

PeerIDs returns list of peer IDs of connected peers excluding self and inactive

func (*Client) Peers

func (c *Client) Peers() []PeerConnection

Peers returns list of peers connected to Client.

func (*Client) PubSub

func (c *Client) PubSub() *pubsub.PubSub

PubSub returns the libp2p node pubsub for adding future subscriptions

func (*Client) Start

func (c *Client) Start(ctx context.Context) error

Start establish Client's P2P connectivity.

Following steps are taken: 1. Setup libp2p host, start listening for incoming connections. 2. Setup gossibsub. 3. Setup DHT, establish connection to seed nodes and initialize peer discovery. 4. Use active peer discovery to look for peers from same ORU network.

type Metrics

type Metrics struct {
	// Number of peers.
	Peers metrics.Gauge
	// Number of bytes received from a given peer.
	PeerReceiveBytesTotal metrics.Counter `metrics_labels:"peer_id,chID"`
	// Number of bytes sent to a given peer.
	PeerSendBytesTotal metrics.Counter `metrics_labels:"peer_id,chID"`
	// Pending bytes to be sent to a given peer.
	PeerPendingSendBytes metrics.Gauge `metrics_labels:"peer_id"`
	// Number of transactions submitted by each peer.
	NumTxs metrics.Gauge `metrics_labels:"peer_id"`
	// Number of bytes of each message type received.
	MessageReceiveBytesTotal metrics.Counter `metrics_labels:"message_type"`
	// Number of bytes of each message type sent.
	MessageSendBytesTotal metrics.Counter `metrics_labels:"message_type"`
}

Metrics contains metrics exposed by this package.

func NopMetrics

func NopMetrics() *Metrics

NopMetrics returns no-op Metrics.

func PrometheusMetrics

func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics

PrometheusMetrics returns Metrics build using Prometheus client library. Optionally, labels can be provided along with their values ("foo", "fooValue").

type NetworkInfo

type NetworkInfo struct {
	ID             string
	ListenAddress  []string
	ConnectedPeers []peer.ID
}

NetworkInfo represents network information

type NodeInfo

type NodeInfo struct {
	NodeID     string `json:"id"`          // authenticated identifier
	ListenAddr string `json:"listen_addr"` // accepting incoming

	// Check compatibility.
	Network string `json:"network"` // network/chain ID
}

NodeInfo is the basic node information exchanged between two peers

type P2PRPC

type P2PRPC interface {
	// GetPeers returns information about connected peers
	GetPeers() ([]peer.AddrInfo, error)
	// GetNetworkInfo returns network information
	GetNetworkInfo() (NetworkInfo, error)
}

P2PRPC defines the interface for managing peer connections

type PeerConnection

type PeerConnection struct {
	NodeInfo   NodeInfo `json:"node_info"`
	IsOutbound bool     `json:"is_outbound"`
	RemoteIP   string   `json:"remote_ip"`
}

PeerConnection describe basic information about P2P connection.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL