dig-rpc-protocol 0.3.1

Canonical DIG-node JSON-RPC protocol: request/response types, the method enum + tier classification, the error-code taxonomy, and an OpenRPC 1.2.6 document generator. The single source of truth both DIG node implementations depend on. Pure types — no I/O, no async, no server logic. (Formerly dig-rpc-types.)
Documentation

dig-rpc-protocol

The canonical DIG-node JSON-RPC protocol (formerly dig-rpc-types) — the single source of truth both DIG node implementations (the digstore dig-node crate and the standalone dig-node binary) depend on instead of hand-rolling json!({…}) shapes and ad-hoc error codes.

Pure types: no I/O, no async, no server logic, no crypto. The dig-rpc server crate and the node implementations build on these types.

What's here

Module Contents
envelope JSON-RPC 2.0 request/response, RequestId, Version
error the canonical ErrorCode taxonomy, the RpcError envelope ({code, message, data:{code, origin}}), and the one constructor helper
method the Method enum — stable wire names, per-method Tier, the mTLS peer allowlist
tier the three access tiers (PublicRead / Peer / Control)
types every method's params + results, field-for-field with the canonical node
frames the shape-dispatched DHT + PEX peer wires
openrpc the OpenRPC 1.2.6 document generator (the single discovery source)

The full contract is in SPEC.md.

Full Protocol Interface (at-a-glance LLM reference)

All Methods (34 total)

Method Name Wire Name Tier Peer-Reachable Summary
GetContent dig.getContent PublicRead Read a verified window of a resource's ciphertext
GetCapsule dig.getCapsule PublicRead Fetch the whole .dig module for (store, root)
GetModule dig.getModule PublicRead Alias of dig.getCapsule
GetManifest dig.getManifest PublicRead Fetch the public discovery manifest resource
GetMetadata dig.getMetadata PublicRead Fetch the plaintext metadata manifest
ListCapsules dig.listCapsules PublicRead List a store's confirmed capsules
GetProof dig.getProof PublicRead Get the real inclusion proof + execution-proof status
GetProofStatus dig.getProofStatus PublicRead Poll a real execution-proof job by id
GetAnchoredRoot dig.getAnchoredRoot PublicRead Resolve a store's chain-anchored tip root
GetCollection dig.getCollection PublicRead Get collection-level facts for NFT launcher ids
ListCollectionItems dig.listCollectionItems PublicRead List resolved NFT collection items (paginated)
Health dig.health PublicRead Liveness and capability summary
Methods dig.methods PublicRead List the method names this node implements
GetNetworkInfo dig.getNetworkInfo Peer This node's peer-network posture
GetPeers dig.getPeers Peer The peers this node currently knows
Announce dig.announce Peer Accept a peer announcement (peer_id + addresses)
GetAvailability dig.getAvailability Peer Batch-check whether this node holds items
ListInventory dig.listInventory Peer Enumerate the stores / roots this node serves
FetchRange dig.fetchRange Peer Fetch a single verified range frame of a resource
Stage dig.stage Control Compile a local folder into a capsule .dig in-process
CacheGetConfig cache.getConfig Control Get the local-cache configuration
CacheSetCapBytes cache.setCapBytes Control Set the local-cache size cap
CacheClear cache.clear Control Clear the local cache
CacheListCached cache.listCached Control List the durable cached modules
CacheRemoveCached cache.removeCached Control Remove one cached capsule
CacheFetchAndCache cache.fetchAndCache Control Fetch and cache one capsule
CacheStats cache.stats Control Cache telemetry: cap + usage, entry count + bytes, eviction + hit/miss
ControlPeerStatus control.peerStatus Control Snapshot the node's peer network
ControlSubscribe control.subscribe Control Subscribe the node to a store (persisted watch + gap-fill)
ControlUnsubscribe control.unsubscribe Control Unsubscribe the node from a store
ControlListSubscriptions control.listSubscriptions Control List the node's persisted store subscriptions
ControlPeersConnect control.peers.connect Control Dial a peer into the connected pool
ControlPeersDisconnect control.peers.disconnect Control Drop a pooled peer by peer_id
RpcDiscover rpc.discover Control Return the OpenRPC self-describe document

Access Tiers: PublicRead = anonymous content reads (HTTPS / mTLS). Peer = mTLS peer surface (node↔node). Control = loopback / in-process only.

Peer-Reachable Methods (10 total): dig.getContent, dig.getNetworkInfo, dig.getPeers, dig.announce, dig.getAvailability, dig.listInventory, dig.fetchRange, dig.getAnchoredRoot, dig.getCollection, dig.listCollectionItems. All Control and non-peer PublicRead methods are never peer-reachable.

Error Codes (22 total)

Code Machine Code Origin Meaning
-32700 PARSE_ERROR Node Invalid JSON received
-32600 INVALID_REQUEST Node JSON is not a valid Request object
-32601 METHOD_NOT_FOUND Node Method does not exist / is not available
-32602 INVALID_PARAMS Node Invalid or missing method parameters
-32603 INTERNAL_ERROR Node Node failed to satisfy a well-formed call
-32000 SERVER_ERROR Node Generic server error (config/IO/chain failure)
-32004 RESOURCE_UNAVAILABLE Node Resource not available at requested root (genuine miss)
-32005 ROOT_NOT_ANCHORED Node Requested/served root is not chain-anchored (fail-closed)
-32006 PEER_UNREACHABLE Peer No NAT-traversal strategy reached the peer
-32007 RANGE_NOT_SATISFIABLE Node Byte range lies outside the resource
-32008 CONTENT_REDIRECT Node Content held elsewhere — data.redirect names holders
-32010 UPSTREAM_ERROR Upstream Upstream/proxy fetch failed
-32011 STAGE_INVALID_INPUT Node dig.stage: dir unreadable / walk budget exceeded
-32012 STAGE_NO_FILES Node dig.stage: no files to compile
-32013 STAGE_OVER_CAP Node dig.stage: input exceeds store cap
-32014 STAGE_COMPILE_FAILED Node dig.stage: compile / IO failure
-32020 ONION_CIRCUIT_UNAVAILABLE Onion Private read circuit could not be built/kept
-32021 PRIVACY_REQUIRES_LOCAL_NODE Onion Privacy mode requires local originator
-32022 ONION_HOPS_OUT_OF_RANGE Onion Hop count outside [2, 5]
-32030 UNAUTHORIZED Control Control-plane call not authorized (loopback gate failed)
-32031 NOT_SUPPORTED Control Control-plane method recognized but not supported
-32032 CONTROL_ERROR Control Control-plane runtime error

Error Origins: Node = node's own read/serve path. Peer = peer-network layer. Upstream = upstream fetch (proxy/whole-store sync). Onion = private-retrieval layer. Control = loopback control plane.

Request/Response Envelope

JSON-RPC 2.0 strict:

Request: {"jsonrpc":"2.0","id":<num|str>,"method":"<wire_name>","params":<object|null>}
Response: {"jsonrpc":"2.0","id":<num|str>,"result":<any>} | {"jsonrpc":"2.0","id":<num|str>,"error":{"code":<int>,"message":"<str>","data":{"code":"<UPPER_SNAKE>","origin":"<str>",...}}}

Error Envelope Structure:

{
  code: i32,                    // numeric wire code (e.g., -32004)
  message: String,              // human-readable summary
  data: {
    code: String,              // stable machine code (e.g., "RESOURCE_UNAVAILABLE")
    origin: String,            // subsystem (node/peer/upstream/onion/control)
    redirect?: RedirectInfo,   // present only on CONTENT_REDIRECT
    <extra fields>             // method-specific fields flattened
  }
}

Interface Version

INTERFACE_VERSION is not yet versioned in the wire (future work). The protocol evolves via additive Method variants and ErrorCode assignments; both are #[non_exhaustive] so a client match-arm default (_ => …) handles future extensions.

Error taxonomy at a glance

Standard JSON-RPC codes plus the DIG protocol codes. The onion codes -32020/-32021/-32022 are the published normative contract and keep their numbers; the control-plane codes are -32030/-32031/-32032.

use dig_rpc_protocol::{RpcError, ErrorCode, ErrorOrigin};

let e = RpcError::of(ErrorCode::ResourceUnavailable, "not at this root");
assert_eq!(e.code, ErrorCode::ResourceUnavailable);       // -32004
assert_eq!(e.data.code, "RESOURCE_UNAVAILABLE");          // stable branch key
assert_eq!(e.data.origin, ErrorOrigin::Node);

Method catalogue + discovery

use dig_rpc_protocol::{Method, Tier, openrpc_document};

assert_eq!(Method::GetContent.name(), "dig.getContent");
assert_eq!(Method::GetContent.tier(), Tier::PublicRead);
assert!(Method::GetContent.is_peer_reachable());
assert!(!Method::CacheClear.is_peer_reachable());          // control tier

let doc = openrpc_document(env!("CARGO_PKG_VERSION"));      // OpenRPC 1.2.6

Features

Flag Default Effect
schema-export off derive schemars::JsonSchema on every wire type (Go/TS codegen)

Testing

cargo test --all-features        # unit + conformance vectors
cargo llvm-cov --all-features    # coverage (CI-gated ≥80%)

Licensed under Apache-2.0 OR MIT.