- -json on info, list, show, cert (+ -chain): emit structured JSON ready for jq / agent consumption - exit codes are now stable + documented: 0/1/2/3/4/5/130 with distinct meanings for network vs integrity vs signature failures - help text enumerates the contract - readme: machine-usage section explains both MCP stdio server (for Claude Code / Cursor etc.) planned, not wired yet
141 lines
5.2 KiB
Markdown
141 lines
5.2 KiB
Markdown
# mithril-go
|
|
|
|
Pure-Go client for the Cardano [Mithril](https://mithril.network) protocol.
|
|
|
|
Mithril is Cardano's stake-based certified-snapshot system — it lets a new
|
|
node bootstrap the chain from a cryptographically-verified snapshot
|
|
instead of replaying every block from genesis.
|
|
|
|
The official [`mithril-client`](https://github.com/input-output-hk/mithril)
|
|
is Rust. This project is a pure-Go reimplementation that produces a single
|
|
static binary with no runtime dependencies — useful for:
|
|
|
|
- Embedding a Mithril bootstrap into Go-based Cardano tooling
|
|
(alongside `gouroboros`, `dingo`, and friends)
|
|
- Running on constrained ARM/embedded targets where shipping the Rust
|
|
binary + its deps is overkill
|
|
- Operators who prefer a single `go install`-able helper
|
|
|
|
## Status
|
|
|
|
**Download + extract pipeline working. Verification is the next milestone.**
|
|
|
|
| Piece | Status |
|
|
|---|---|
|
|
| Aggregator REST client | ✅ list, get, cert, chain |
|
|
| `list` / `show` / `info` / `cert` commands | ✅ working against mainnet + preprod |
|
|
| Resumable HTTP download (single stream, SHA hook) | ✅ |
|
|
| Streamed zstd+tar extract (tar-slip defended) | ✅ |
|
|
| `download` — digests + ancillary | ✅ (immutables loop pending) |
|
|
| Genesis Ed25519 verification | ⚠️ stubbed, needs signed_message derivation wired |
|
|
| STM BLS12-381 aggregate verification | ❌ the sprint — see below |
|
|
|
|
## Usage
|
|
|
|
```
|
|
mithril-go info -network mainnet
|
|
mithril-go list -network mainnet
|
|
mithril-go show -network mainnet latest
|
|
mithril-go cert -network mainnet head
|
|
mithril-go cert -network mainnet -chain head # walk to genesis
|
|
mithril-go download -network preprod -out ./db latest # digests + ancillary
|
|
```
|
|
|
|
## Verification sprint plan
|
|
|
|
The verification story splits into two layers:
|
|
|
|
### 1. Genesis Ed25519 verification
|
|
|
|
The genesis certificate (terminates the chain; its `previous_hash` is
|
|
empty and `genesis_signature` is non-empty) is signed by a static
|
|
Ed25519 key baked into this client per network (`internal/networks`).
|
|
|
|
- Key encoding: the Mithril genesis key is serialized as an ASCII-
|
|
representation of a 32-byte array literal (e.g. `"[191,66,...]"`)
|
|
then hex-encoded. Decoder needs to unwrap both levels before handing
|
|
32 raw bytes to `ed25519.Verify`.
|
|
- Signed payload: `signed_message` field (32 bytes hex) is the output
|
|
of hashing the serialized `protocol_message` — the exact hash
|
|
function and canonicalization must match the Rust reference
|
|
(`mithril-common/src/protocol/` in the upstream repo). Likely
|
|
Blake2b-256 over a deterministic CBOR or JSON encoding; needs
|
|
confirming against upstream.
|
|
- Wire location: `internal/verify/verify.go` → `Genesis(...)`.
|
|
|
|
### 2. STM BLS12-381 aggregate verification
|
|
|
|
Every non-genesis certificate carries a `multi_signature` that is an
|
|
STM (Stake-based Threshold Multi-signature) aggregate proof over BLS12-381.
|
|
|
|
- Scheme: Chotard/Kiayias/Peters "Stake-based Threshold Multisignatures"
|
|
(Mithril paper §5-6).
|
|
- Library: `github.com/supranational/blst` Go bindings (IETF-draft
|
|
BLS12-381 operations; production-grade, consensus layers use it).
|
|
- Inputs:
|
|
- `next_aggregate_verification_key` from the previous-epoch cert's
|
|
`protocol_message` (the "trust handoff" between certs)
|
|
- `multi_signature` bytes (CBOR-encoded STM aggregate signature)
|
|
- `signed_message` (what was signed)
|
|
- Output: pass/fail, plus the epoch-boundary decision to promote
|
|
that cert's `next_aggregate_verification_key` for use by the NEXT
|
|
verification.
|
|
- Wire location: `internal/verify/verify.go` → `STM(...)`.
|
|
|
|
### Downstream once verification lands
|
|
|
|
- `verify` subcommand: takes a snapshot directory, walks the cert chain,
|
|
verifies genesis Ed25519 + each STM signature in order, validates the
|
|
`merkle_root` against the digests manifest's computed root, reports
|
|
per-stage pass/fail.
|
|
- Per-immutable SHA check against the `digests.json` manifest (already
|
|
downloaded — 16836 entries for preprod as of epoch 284).
|
|
- Full immutables loop for the `download -immutables` path.
|
|
|
|
## Machine / LLM usage
|
|
|
|
Every query command accepts `-json` for structured output:
|
|
|
|
```
|
|
mithril-go list -network mainnet -json # snapshot array
|
|
mithril-go show -network mainnet latest -json
|
|
mithril-go cert -network mainnet head -json
|
|
mithril-go cert -network mainnet head -chain -json
|
|
mithril-go info -network mainnet -json
|
|
```
|
|
|
|
Exit codes are stable:
|
|
|
|
| Code | Meaning |
|
|
|---|---|
|
|
| 0 | success |
|
|
| 1 | generic error |
|
|
| 2 | usage error |
|
|
| 3 | network / aggregator error |
|
|
| 4 | integrity failure (SHA, tar-slip, truncated archive) |
|
|
| 5 | signature verification failure (genesis or STM) |
|
|
| 130 | canceled (SIGINT) |
|
|
|
|
These are the contract — existing codes won't renumber.
|
|
|
|
Planned: `mithril-go mcp` stdio server (Model Context Protocol) so MCP-native
|
|
agents (Claude Code, Cursor, etc.) can discover + call commands without
|
|
shelling out. Not yet implemented.
|
|
|
|
## Dependencies
|
|
|
|
- `github.com/klauspost/compress/zstd` — pure Go zstd decoder
|
|
- (pending) BLS12-381: `github.com/supranational/blst` via its Go bindings
|
|
|
|
## Building
|
|
|
|
```
|
|
go build -o mithril-go ./cmd/mithril-go
|
|
```
|
|
|
|
Produces a single static binary (~9.5 MB). CGo is not used; cross-
|
|
compilation is `GOOS=linux GOARCH=arm64 go build ./cmd/mithril-go`.
|
|
|
|
## License
|
|
|
|
TBD
|