Skip to main content

Crate karyon_p2p

Crate karyon_p2p 

Source
Expand description

§Karyon p2p

A lightweight, extensible, and customizable peer-to-peer network stack. Multi-transport (TCP, TCP/TLS, QUIC) with pluggable custom protocols via the Protocol trait, pluggable discovery with a built-in Kademlia DHT.

§Install

$ cargo add karyon_p2p

§Feature Flags

FeatureDescription
smolUse smol async runtime (default)
tokioUse tokio async runtime
quicEnable QUIC transport
serdeEnable serde support for p2p types
# Default (smol + TCP/TLS)
karyon_p2p = "1.0"

# With QUIC
karyon_p2p = { version = "1.0", features = ["quic"] }

# With tokio
karyon_p2p = { version = "1.0", default-features = false, features = ["tokio", "quic"] }

§Architecture

                          Node
                            |
   +------------+-----------+-----------+
   |            |                       |
Discovery   PeerPool             Connector / Listener
   |            |                       |
Routing     Peers + Protocols       ConnQueue
table           |                       |
                +------- Handshake -----+
                             |
                          karyon_net (TCP / TLS / QUIC)
  • Node: top-level lifecycle. Creates the discovery, pool, connector, and listener; wires them together; exposes the public API.
  • Discovery: finds peers and yields them as DiscoveredPeer. Default is Kademlia DHT; custom implementations of the Discovery trait plug in.
  • Connector / Listener: dial and accept connections over the configured transports, then hand them to ConnQueue.
  • ConnQueue: short-lived bridge between accept/dial and handshake.
  • Handshake: version + protocol negotiation. Verifies peer identity bound to the secure transport’s certificate.
  • PeerPool: registry of post-handshake peers. Owns the per-peer Peer state and broadcasts lifecycle events.
  • Peer / Protocol: per-peer read loop dispatching to the registered protocols. Custom protocols implement the Protocol trait.

§Transport

Peers can listen and connect over multiple transports simultaneously. Configuration uses endpoint URLs (tcp://, tls://, quic://); TLS uses self-signed certs derived from the node’s keypair, and QUIC multiplexes one stream per protocol.

§Discovery

Implementations of the Discovery trait yield candidate peers; the Node dials them. The default is a Kademlia DHT; plug in your own (mDNS, static, …) by implementing the trait.

#[async_trait]
pub trait Discovery: Send + Sync {
    async fn start(self: Arc<Self>) -> Result<()>;
    async fn shutdown(&self);
    async fn recv(&self) -> DiscoveredPeer;
    fn on_event(&self, event: PeerConnectionEvent);
    fn find_peers_with(&self, item: &[u8]) -> Vec<DiscoveredPeer>;
}

§Protocols

A built-in Ping keep-alive runs on every connection; everything else is a custom protocol. For TCP/TLS, protocols share a single framed connection. For QUIC, each protocol gets its own bidirectional stream.

Protocol::kind() defaults to Optional. Override to Mandatory for protocols every peer must speak.

pub struct MyProtocol {
    peer: PeerConn,
}

impl MyProtocol {
    fn new(peer: PeerConn) -> Arc<dyn Protocol> {
        Arc::new(Self { peer })
    }
}

#[async_trait]
impl Protocol for MyProtocol {
    async fn start(self: Arc<Self>) -> Result<(), Error> {
        loop {
            match self.peer.recv().await {
                Ok(_msg) => { /* handle */ }
                Err(Error::PeerShutdown) => break,
                Err(e) => return Err(e),
            }
        }
        Ok(())
    }

    fn version() -> Result<Version, Error> {
        "0.1.0, >0.1.0".parse()
    }

    fn id() -> ProtocolID {
        "MYPROTO".into()
    }

    // Optional override (defaults to ProtocolKind::Optional)
    // fn kind() -> ProtocolKind { ProtocolKind::Mandatory }
}

§Monitor

Subscribe to node.monitor() to observe what the network is doing - connections opening and closing, peer add/remove, handshake failures, discovery lookups and refreshes. Each topic is a separate event type with its own listener; every subscriber gets every event independently.

let listener = node.monitor().register::<ConnectionEvent>();
while let Ok(ev) = listener.recv().await {
    println!("conn event: {} {:?}", ev.event, ev.endpoint);
}

Available event types: ConnectionEvent, PeerPoolEvent, DiscoveryEvent. Gated by Config::enable_monitor.

§Network Security

TLS is available for TCP connections. QUIC has built-in TLS 1.3. The p2p layer generates self-signed certificates from the node’s key pair for mutual authentication.

§Example

use karyon_core::async_runtime::global_executor;
use karyon_p2p::{
    Node, Config,
    keypair::{KeyPair, KeyPairType},
};

async {
    let key_pair = KeyPair::generate(&KeyPairType::Ed25519);

    let config = Config {
        listen_endpoints: vec![
            "tcp://0.0.0.0:8000".parse().unwrap(),
        ],
        discovery_endpoints: vec![
            "tcp://0.0.0.0:7000".parse().unwrap(),
            "udp://0.0.0.0:7000".parse().unwrap(),
        ],
        ..Config::default()
    };

    let node = Node::new(&key_pair, config, global_executor());

    node.run().await.expect("run node");

    // Register custom protocols, connect to peers, etc.

    node.shutdown().await;
};

§Examples

See examples/ for a basic peer node and a chat application.

Modules§

bloom 🔒
codec 🔒
config 🔒
conn_queue 🔒
connector 🔒
discovery 🔒
endpoint
error 🔒
handshake 🔒
keypair
listener 🔒
message 🔒
monitor
Responsible for network and system monitoring. Read More
node 🔒
peer 🔒
peer_pool 🔒
protocol
Defines the protocol trait. Read More
protocols 🔒
slots 🔒
tls_config 🔒
util
Bincode encode/decode helpers.
version 🔒

Structs§

Bloom
Two 128-bit bloom filters (k=2 hashes) bundled into one wire type.
Config
Configuration for the p2p network.
DiscoveredPeer
Represents a discovered peer that the discovery protocol wants the Node to connect to.
KademliaDiscovery
Node
Central entry point for the p2p network.
Peer
A connected peer. Holds a PeerConnection that hides the wire shape (single framed pipe vs. per-protocol streams).
PeerAddr
A peer address with protocol and priority. Lower priority number means higher preference.
PeerID
Represents a unique identifier for a peer.
PeerPool
Version
Represents the network version and protocol version used in karyon p2p.

Enums§

Error
Represents karyon’s p2p Error.
PeerEvent
Peer-lifecycle events. Each registered listener receives every event independently.
Protocol
Transport protocol used by a peer address.

Traits§

Discovery
Trait that any discovery protocol must implement.

Type Aliases§

BloomRef
Shared handle to the local bloom. Readers snapshot via *b.read(); writers (attach_protocol, swarm joins, …) update in place. Cheap to clone (Arc) and lock-free for short reads (parking_lot RwLock).
Result