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

Verify as a light client

A light client follows the chain without executing it. It pins one value, the chain identity, and checks everything else against it with proofs.

Pin the chain identity

The chain identity is a digest of everything that decides who certifies the chain’s first epoch: the genesis specification, the genesis validators with their stake and public keys, and the shard layout. Later committees are in the state, and the client follows them from there. sion devnet prints the identity at startup:

chain identity (pin it: sion verify --chain …): 6345655cfd2a714ed1dab69c0660f2f48f429ce2981e25629d0467d7b7ee97b7

A real client gets it from a source it trusts (a release, a friend, a second node), like an SSH host key. Without a pin, the client learns the identity from the node it is checking, and the node vouches for itself.

Verify a Pulse

$ sion verify --chain 6345655cfd2a714ed1dab69c0660f2f48f429ce2981e25629d0467d7b7ee97b7
chain: 6345655c matches the pinned identity; 4 validators, keys derive their identifiers ✓
Pulse 5 header fc972683 (state root 04ed71f4, knowledge root b3950ae7, 0 claims)
certificate: 300000 of 400000 stake signed (quorum 266667), each signature ML-DSA-44 + SLH-DSA-SHA2-128f ✓
forced inclusion: no overdue intents (0 pending within their deadline) ✓
receipts: 1 of 1 transactions proven against the receipts root, in the certified order ✓
state: proof skipped (node already at Pulse 7)
availability: 16 of 16 random shares of the 32×32 square verified; a withholding would go unnoticed with probability < 4.7e-3 ✓
world proof: 2 leaves re-verified by stack ["A", "B"]; the published data is what executed and encodes to the certified data root (113 KB; replay proofs simulate succinct ones) ✓
lane certificates: all 1 executed transactions locked their inputs with a quorum of their shard's committee, taken from the proven validator set ✓

Line by line:

LineWhat was checked
chainThe node’s chain specification hashes to the pinned identity, every validator is listed once with positive stake, and every validator identifier derives from its two public keys
Pulse … headerThe Pulse chosen: by default the most recent certified (and, unless --no-world, proven) Pulse that executed transactions, looking back up to 32 Pulses; otherwise the latest certified one
committeesOnly for a Pulse after epoch 0: the client followed the committee from the pinned epoch 0 to the header’s epoch, one certified boundary and validator-set proof at a time (Epochs and committees)
certificateValidators holding more than two thirds of the epoch’s committee stake signed this header, each with both signatures. Epoch 0’s committee comes from the pinned specification, later ones from the boundary proofs, never from the node’s word
forced inclusionWhat the certified header says the shards owe
receiptsThe node’s list of executed transactions hashes to the order the header committed to; up to three receipts are proven at their positions against the receipts root
stateAn account object proven against the header’s state root, when the node’s latest state is this Pulse; otherwise skipped
availabilityRandom shares of the Pulse’s extended data square, at positions the node cannot predict, verified against the certified data root
world proofThe World Proof matches the header, and every leaf re-verifies under both proof stacks
lane certificatesEvery executed transaction carried a lane certificate from a quorum of its shard’s committee, derived from the validator set the World Proof carries

If any check fails, sion verify stops with verification failed: … and exits with status 1.

Options:

  • --pulse <n>: verify a specific Pulse. The node keeps Pulse headers for the last 256 Pulses, data shares for the last 64 and World Proofs for the last 32.
  • --samples <s>: data-availability samples (default 16).
  • --no-world: skip the World Proof. A World Proof is a replay proof, so checking it costs as much as executing the Pulse.

Without a pin

$ sion verify
chain: 6345655c (NOT PINNED: learned from the node itself; pass --chain 6345655cfd2a714ed1dab69c0660f2f48f429ce2981e25629d0467d7b7ee97b7 to pin it)
...

Everything else is checked the same way, but against a committee the node chose. Set SION_CHAIN to pin it for every command.

A lying node is caught

The light demo builds the attack a lying node would need: serving its own keys under a real validator’s identifier. The pin catches it:

a node serving substituted validator keys is caught: header chain: the node serves chain 6fc4795f, not the pinned chain 6345655c ✗

The substituted keys change the specification the node serves, so it no longer hashes to the pinned identity.

What a light client still trusts

  • Fewer than a third of the committee’s stake is Byzantine, for the certificate.
  • The World Proof is a replay proof (impl:replay-proofs): verifying it is not cheap, and a phone cannot do it for a busy Pulse.
  • The forced-inclusion summary in the header is committee-certified; the World Proof proves the obligations themselves but does not check the summary against them.

See Light-client verification for receipts, claims and objects, and Trust model.