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
| Feature | Description |
|---|---|
smol | Use smol async runtime (default) |
tokio | Use tokio async runtime |
quic | Enable QUIC transport |
serde | Enable 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 theDiscoverytrait 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
Peerstate and broadcasts lifecycle events. - Peer / Protocol: per-peer read loop dispatching to the registered
protocols. Custom protocols implement the
Protocoltrait.
§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.
- Discovered
Peer - Represents a discovered peer that the discovery protocol wants the Node to connect to.
- Kademlia
Discovery - Node
- Central entry point for the p2p network.
- Peer
- A connected peer. Holds a
PeerConnectionthat hides the wire shape (single framed pipe vs. per-protocol streams). - Peer
Addr - A peer address with protocol and priority. Lower priority number means higher preference.
- PeerID
- Represents a unique identifier for a peer.
- Peer
Pool - Version
- Represents the network version and protocol version used in karyon p2p.
Enums§
- Error
- Represents karyon’s p2p Error.
- Peer
Event - 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.