DOCS / PROTOCOL / ARCHITECTURE
Architecture
ShardoChain is a Rust core wrapped by a Go API layer. The two communicate through a stable C ABI generated from the Rust side, giving the Go layer zero-copy access to the consensus state without compromising the single-source-of-truth nature of the Rust code.
Layered view
┌─────────────────────────────────────────────────────────────┐
│ Go API Layer │
│ ────────────────────── │
│ • JSON-RPC :8545 (public) • REST + Explorer :8080 │
│ • gRPC :9090 • WebSocket :8546 │
└──────────────────────┬──────────────────────────────────────┘
│ CGo / FFI (libshardo_ffi.so)
┌──────────────────────┴──────────────────────────────────────┐
│ Rust Core (13 crates, ~42 K LOC) │
│ ────────────────────── │
│ shardo-node — producer + importer + sync + fork-det. │
│ shardo-consensus — PoH engine, slot schedule, slashing │
│ shardo-execution — parallel exec, mempool, sig-cache, WASM │
│ shardo-storage — RocksDB wrapper, block_db, state_db │
│ shardo-p2p — libp2p QUIC, gossipsub, peer-cache │
│ shardo-poh — SHA-256 verifiable delay function │
│ shardo-light — light-client header + QC verifier │
│ shardo-wallet — CLI wallet │
│ shardo-sdk — WASM contract macros │
│ shardo-ffi — C ABI for Go bridge │
│ shardo-core — types, crypto, config, consensus_types │
│ shardo-tools — stress, soak, smooth-load tools │
│ shardo-bench — criterion benchmarks │
└─────────────────────────────────────────────────────────────┘
Lifecycle of a transaction
- Submit. Client signs
SignedTransaction(Ed25519) and POSTsshard_sendRawTransactionto the JSON-RPC endpoint. - Mempool admission. Go API forwards to the embedded RPC at :8547. Rust mempool verifies signature, chain_id, fee floor, sender quota, then appends to the in-memory pool.
- Gossip. A
GossipMessage::Txis published on libp2p gossipsub; peers replay the same admission checks. - Block production. Slot leader (computed from
(height + view) % active_set.len()) drains TX from mempool, executes them in parallel via Union-Find conflict tracking, and broadcasts aCompactBlock. - Validation. Each peer verifies the block header (parent_hash, state_root, transactions_root, leader_signature, justify_qc), then re-executes locally and confirms the same state_root.
- Vote. Each validator emits a
PohVote(slot, block_hash, view)Ed25519-signed over the payload. - Quorum + finality. The next block carries the previous block's QC in its
justify_qcfield. With 2f+1 votes accumulated, the parent is committed.
Storage layout
RocksDB with 25 column families, atomic write batches. Key tables:
| Table | Key | Value |
|---|---|---|
blocks | height (u64 BE) | borsh(BlockHeader) |
block_headers_by_hash | block_hash (32 B) | borsh(BlockHeader) — append-only |
block_bodies | block_hash (32 B) | borsh(transactions) |
state | address (20 B) | borsh(AccountState) |
transactions | tx_hash (32 B) | borsh(SignedTransaction) |
receipts | tx_hash (32 B) | borsh(TxReceipt) |
validators | epoch (u64 BE) | borsh(ValidatorSet) |
contract_code | address (20 B) | raw WASM |
contract_state | address + key | raw bytes |
metadata | const keys | chain_tip, state_root_xor, … |
P2P networking
libp2p QUIC transport on port 30303. Key behaviours:
- Gossipsub for block, TX, and consensus messages. Peer scoring discourages spam.
- Request-response for block sync, state-sync, and checkpoint pulls.
- Kademlia DHT for peer discovery beyond the bootstrap list.
- PEX peer-exchange every 2 min between connected peers.
- Persistent peer-cache (v5.1.6) writes connected-peer multiaddrs to disk every 5 min for bootstrap fallback.
- DNS seed resolution for
/dns4/bootstrap multiaddrs.
Consensus
HotStuff-2-style BFT with Proof-of-History clock — see the dedicated pages for full detail:
- Proof of History — the SHA-256 verifiable delay function used as a shared clock.
- HotStuff-2 — header v4, view-change, lock-on-QC, recovery paths.
Determinism guarantees
- State root computed via XOR of BLAKE3 leaves over address-sorted non-zero accounts.
- RocksDB iteration is lexicographic by key, identical across all platforms.
- BLAKE3 is platform-independent.
- Account writes sorted by
address.as_bytes()before commit. - u128 little-endian for storage values, big-endian for sortable keys.
- Four guard tests in
state_db.rsprotect this invariant.