Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Module IPC Protocol

Overview

The Module IPC (Inter-Process Communication) protocol enables secure communication between process-isolated modules and the base node. Modules run in separate processes and communicate via Unix domain sockets using a length-delimited binary message protocol.

Architecture

┌─────────────────────────────────────┐
│         blvm-node Process          │
│  ┌───────────────────────────────┐ │
│  │    Module IPC Server          │ │
│  │    (Unix Domain Socket)       │ │
│  └───────────────────────────────┘ │
└─────────────────────────────────────┘
              │ IPC Protocol
              │ (Unix Domain Socket)
              │
┌─────────────┴─────────────────────┐
│      Module Process (Isolated)     │
│  ┌───────────────────────────────┐ │
│  │    Module IPC Client          │ │
│  │    (Unix Domain Socket)       │ │
│  └───────────────────────────────┘ │
└─────────────────────────────────────┘

Protocol Format

Message Encoding

Messages use length-delimited binary encoding:

[4-byte length][message payload]
  • Length: 4-byte little-endian integer (message size)
  • Payload: Binary-encoded message (bincode serialization)

Code: mod.rs

Message Types

The protocol supports four message types:

  1. Request: Module → Node (API calls)
  2. Response: Node → Module (API responses)
  3. Event: Node → Module (event notifications)
  4. Log: Module → Node (logging)

Code: protocol.rs

Message Structure

Request Message

#![allow(unused)]
fn main() {
pub struct RequestMessage {
    pub correlation_id: CorrelationId,
    pub request_type: MessageType,
    pub payload: RequestPayload,
}
}

Request types (representative):

Reads and subscriptions include GetBlock, GetBlockHeader, GetTransaction, GetChainTip, GetBlockHeight, GetUTXO, SubscribeEvents, GetMempoolTransactions, GetNetworkStats, GetNetworkPeers, GetChainInfo, and many others (mining, storage, RPC, timers, …).

P2P serve policy & sync (module → node):

MessageTypeRole
MergeBlockServeDenylistAdd block hashes that must not receive full block on getdata (notfound instead).
GetBlockServeDenylistSnapshotBounded snapshot of the block denylist.
ClearBlockServeDenylist / ReplaceBlockServeDenylistClear or replace the full set.
MergeTxServeDenylistSame pattern for full tx on getdata.
GetTxServeDenylistSnapshotBounded snapshot of the tx denylist.
ClearTxServeDenylist / ReplaceTxServeDenylistClear or replace the tx set.
GetSyncStatusSync coordinator status (SyncStatus).
BanPeerBan peer by address; optional duration.
SetBlockServeMaintenanceModeRefuse all full-block getdata answers when enabled.

These affect relay/serving only, not consensus validation. See NodeAPI for the Rust surface.

Code: protocol.rs

Response Message

#![allow(unused)]
fn main() {
pub struct ResponseMessage {
    pub correlation_id: CorrelationId,
    pub payload: ResponsePayload,
}
}

Response payload variants carry typed data (blocks, templates, snapshots, booleans, errors, etc.); denylist merges return dedicated merged/snapshot payloads where applicable.

Code: protocol.rs

Event Message

#![allow(unused)]
fn main() {
pub struct EventMessage {
    pub event_type: EventType,
    pub payload: EventPayload,
}
}

Event Types (46+ event types):

  • Network events: PeerConnected, MessageReceived, PeerDisconnected
  • Payment events: PaymentRequestCreated, PaymentVerified, PaymentSettled
  • Chain events: NewBlock, ChainTipUpdated, BlockDisconnected
  • Mempool events: MempoolTransactionAdded, FeeRateChanged, MempoolTransactionRemoved

Code: protocol.rs

Log Message

#![allow(unused)]
fn main() {
pub struct LogMessage {
    pub level: LogLevel,
    pub message: String,
    pub module_id: String,
}
}

Log Levels: Error, Warn, Info, Debug, Trace

Code: protocol.rs

Communication Flow

Request-Response Pattern

  1. Module sends Request: Module sends request message with correlation ID
  2. Node processes Request: Node processes request and generates response
  3. Node sends Response: Node sends response with matching correlation ID
  4. Module receives Response: Module matches response to request using correlation ID

Code: server.rs

Event Subscription Pattern

  1. Module subscribes: Module sends SubscribeEvents request with event types
  2. Node confirms: Node sends subscription confirmation
  3. Node publishes Events: Node sends event messages as they occur
  4. Module receives Events: Module processes events asynchronously

Code: server.rs

Connection Management

Handshake

On connection, modules send a handshake message:

#![allow(unused)]
fn main() {
pub struct HandshakeMessage {
    pub module_id: String,
    pub capabilities: Vec<String>,
    pub version: String,
}
}

Code: server.rs

Connection Lifecycle

  1. Connect: Module connects to Unix domain socket
  2. Handshake: Module sends handshake, node validates
  3. Active: Connection active, ready for requests/events
  4. Disconnect: Connection closed (graceful or error)

Code: server.rs

Security

Process Isolation

  • Modules run in separate processes with isolated memory
  • No shared memory between node and modules
  • Module crashes don’t affect the base node

Code: spawner.rs

Permission System

Modules request capabilities that are validated before API access:

  • ReadBlockchain - Read-only blockchain access
  • ReadUTXO - Query UTXO set (read-only)
  • ReadChainState - Query chain state (height, tip)
  • SubscribeEvents - Subscribe to node events
  • SendTransactions - Submit transactions to mempool

Code: permissions.rs

Sandboxing

Modules run in sandboxed environments with:

  • Resource limits (CPU, memory, file descriptors)
  • Filesystem restrictions
  • Network restrictions (modules cannot open network connections)
  • Permission-based API access

Code: mod.rs

Error Handling

Error Types

#![allow(unused)]
fn main() {
pub enum ModuleError {
    ConnectionError(String),
    ProtocolError(String),
    PermissionDenied(String),
    ResourceExhausted(String),
    Timeout(String),
}
}

Code: traits.rs

Error Recovery

  • Connection Errors: Automatic reconnection with exponential backoff
  • Protocol Errors: Clear error messages, connection termination
  • Permission Errors: Detailed error messages, request rejection
  • Timeout Errors: Request timeout, connection remains active

Code: client.rs

Performance

Message Serialization

  • Format: bincode (binary encoding)
  • Size: Compact binary representation
  • Speed: Fast serialization/deserialization

Code: protocol.rs

Connection Pooling

  • Persistent Connections: Connections remain open for multiple requests
  • Concurrent Requests: Multiple requests can be in-flight simultaneously
  • Correlation IDs: Match responses to requests asynchronously

Code: client.rs

Implementation Details

IPC Server

The node-side IPC server:

  • Listens on Unix domain socket
  • Accepts module connections
  • Routes requests to NodeAPI implementation
  • Publishes events to subscribed modules

Code: server.rs

IPC Client

The module-side IPC client:

  • Connects to Unix domain socket
  • Sends requests and receives responses
  • Subscribes to events
  • Handles connection errors

Code: client.rs

See Also