Light client
The light client cryptographically verifies the chain header sequence without storing the full state or executing transactions. It's the right choice for SDKs, mobile clients, bridge relayers, and explorers that want a trustless tip — at a fraction of the resource cost of a full node.
Status
| Phase | Status | What it covers |
|---|---|---|
| Phase 1 | ✅ Done | Header sync + Ed25519 signature verification against trusted genesis validator set. Supports header v3 and v4 (view-change). |
| Phase 2 | ⏳ Planned | Checkpoint-based fast bootstrap — skip the initial header replay, start from a recent quorum-signed snapshot. |
| Phase 3 | ⏳ Planned | Merkle-proof-authenticated state queries — verify balances and receipts without trusting the RPC's response. |
How verification works
The light client maintains a TrustedState:
- The current trusted height + hash.
- The active validator set (Ed25519 public keys + addresses).
For each new header from the RPC, it verifies:
previous_hashmatches the trusted hash atheight - 1.- The leader's Ed25519 signature over
height || previous_hash. - The
leader_pubkeybelongs to a validator in the trusted active set. - If
view ≥ 1: the embeddednew_view_qchas 2f+1 distinct valid signatures from active validators over the QC payload (per-signer lock). - If
justify_qc.is_some(): parent's QC is valid and signed by the active set at the parent's epoch.
On epoch boundary, the trusted set rotates. The new set is read from the next header's chain — when at least 2f+1 signatures over the new set come in, the light client adopts it.
Run the light client
Download the binary from the homepage, then:
# 1. Bootstrap from genesis (or a trusted recent checkpoint)
./shardo-light \
--rpc-url /rpc \
--chain-id 590 \
--genesis path/to/genesis-testnet.json \
--data-dir ./light-data \
sync
The binary persists its trusted state to light-data/trusted_state.json
so subsequent runs resume from the last verified header.
Trust model
You must trust:
- The genesis JSON (defines initial validator set + chain config).
- The Ed25519 + BLAKE3 + SHA-256 cryptographic primitives.
- That < f Byzantine validators have ever colluded simultaneously on the chain you're verifying.
You do not need to trust:
- The RPC server you're connected to. Bad headers fail signature verification.
- Network adversaries replaying or reordering headers — each header has a unique
(height, slot, hash)tuple.
Use cases
- Mobile wallets — verify balance queries by walking the header chain and asking for Merkle proofs (Phase 3).
- Bridge relayers — submit ShardoChain-state proofs to other chains, with the relayer's stake guaranteeing it submits only canonical heights.
- Block explorers — show a trustless "Verified up to height N" badge.
- Watchdog services — alert when a node serves a header with a bad signature, surfacing operator errors or attacks.
Library API
The light client is also published as the shardo-light Rust crate:
use shardo_light::{LightClient, LightConfig, FileStore}; let config = LightConfig::testnet() .with_rpc("/rpc") .with_chain_id(590); let store = FileStore::open("./light-data")?; let mut client = LightClient::new(config, store); client.sync_to_tip().await?; println!("verified tip: {}", client.trusted_height());
See the JSON-RPC API for the full set of methods the light client wraps.