Network & P2P
calimero-network + calimero-network-primitives
Purpose
NetworkManager is an Actix actor that owns and drives the libp2p Swarm with 10+ composed behaviours. It handles gossipsub pub/sub, Kademlia DHT, mDNS discovery, relay circuits, rendezvous registration, hole punching, and multiplexed streams.
The network layer only moves opaque bytes — message decoding happens in the node layer. This clean boundary means calimero-network never imports application-level types; it simply ferries Vec<u8> payloads between peers and hands them up through NetworkEvent variants.
libp2p Behaviour Stack
All behaviours are composed into a single #[derive(NetworkBehaviour)] struct. Each behaviour manages one protocol concern, and the swarm dispatches events through pattern-matched handlers.
Topic Management
Gossipsub uses IdentTopic for two distinct topic namespaces. The network crate only sees opaque topic strings — the semantic meaning is defined at the node layer.
Context Topics
// Carries: StateDelta, HashHeartbeat
// One topic per context — peers subscribe on context join
Group Topics
// Carries: SignedGroupOpV1, GroupGovernanceDelta,
// GroupStateHeartbeat, GroupMutationNotification
// One topic per group — cross-context governance traffic
Important boundary
BroadcastMessage is not defined in the network crate — it lives in calimero-node-primitives. The network layer only sees raw bytes; deserialization into BroadcastMessage variants happens in NodeManager.
Stream Protocols
Two multiplexed stream protocols ride on the same libp2p::Stream infrastructure. Both use length-delimited framing for reliable message boundaries.
/calimero/stream/0.0.2
General-purpose sync stream for delta exchange, key sharing, and state negotiation.
- Length-delimited frames
- 8 MiB max frame size
- StreamMessage → InitPayload dispatch
- Used by sync engine for catch-up & real-time replication
/calimero/blob/0.0.2
Blob transfer protocol for large binary payloads (WASM, application data).
- JSON BlobRequest / BlobResponse handshake
- Borsh-encoded BlobChunk stream
- Chunked transfer for large payloads
- Announce / query / request lifecycle
NetworkClient
NetworkClient is the async handle held by other actors to communicate with NetworkManager. Each method sends a typed message and awaits the response.
Connection
fn listen_on(addr) → Result
fn bootstrap() → Result
Pub/Sub
fn unsubscribe(topic) → Result
fn publish(topic, data) → Result
Streams
Mesh Info
fn mesh_peer_count(topic) → usize
fn mesh_peers(topic) → Vec
Blob Transfer
fn query_blob(hash) → Providers
fn request_blob(peer, hash) → Blob
Specialized Node
verification_request(..) → Result
fn send_specialized_node_
invitation_response(..) → Result
Discovery
The discovery subsystem combines multiple libp2p mechanisms into a state machine that progressively establishes connectivity with the mesh.
Transport
The transport layer supports multiple stacks for different network conditions. All connections are authenticated and encrypted.
TCP Stack
Primary transport for reliable connections.
TCP → TLS (libp2p-tls) → Noise (XX handshake)
→ Yamux (stream multiplexing)
QUIC Stack
UDP-based transport with built-in encryption and muxing.
QUIC (UDP + TLS 1.3 built-in)
→ native stream multiplexing
// No separate Noise/Yamux needed
Dependencies
Key crate dependencies and their roles in the network layer.