satd — A Guided Tour of the Codebase
A guided tour of the codebase
satd
A Bitcoin Core-compatible full node in Rust.
One process. One RocksDB. One systemd unit.
~219,000 lines of Rust across 19 workspace crates · +24k lines of Go SDK
Every code snippet is real, verbatim from master at 4874b537 (2026-08-19).
Navigate with ← → · press t for the table of contents
Part 1 · Orientation
The thesis: Core-compatible outside, different inside
satd holds four surfaces byte-compatible with Bitcoin Core v30 — consensus rules, P2P wire format, JSON-RPC method shapes, and bitcoin.conf syntax — and treats any unlisted deviation as a bug. Inside that envelope, it deliberately ships more.
Held compatible with Core
Consensus — full parity through Taproot; mainnet shadow-validated against libbitcoinconsensus from genesis to ~945k blocks with zero divergence.
P2P wire — BIP 152 compact blocks, BIP 155 addrv2, BIP 157/158 filters, BIP 339 wtxid relay, BIP 324 v2 transport.
JSON-RPC — 80 Core-named methods; field names and types preserved by default; extensions opt-in per request.
Config & CLI — a Core bitcoin.conf starts satd unedited; unknown keys rejected as typos, recognized-but-unsupported keys warn.
Deliberately different
Native serving surfaces — Esplora REST, Electrum, BIP 157/158 serving, Prometheus metrics, all in one process over one chainstate.
Structured streaming API — replaces Core's raw ZMQ topics with a cursor-replayable event envelope + Rust/Go SDKs.
Operator sovereignty — a total, cost-bounded relay-policy language; hot config reload on SIGHUP; native TLS everywhere.
No wallet — keyless by charter; PSBT construction/analysis served, signing pushed client-side.
The organizing tradeoff<br>Core optimizes for being the reference implementation: minimal surface, maximal caution. satd optimizes for the operator running wallet infrastructure: it spends disk (indexes), memory (RocksDB), and code (native surfaces) to collapse the bitcoind + electrs + esplora + nginx + exporter stack into one tip-consistent process.
Part 1 · Orientation
The workspace: 19 crates, one library at the center
Everything consensus- and node-shaped lives in the node library crate; satd and sat-cli are thin binaries over it. Protocol surfaces, indexes, and the policy language are separate crates so their dependencies stay out of the consensus build.
node 105k loc The node library: chain, storage, validation, net, mempool, mining, RPC, events, indexes.
satd 45k loc Daemon binary: config parsing, startup, SIGHUP reload, alert/notify hooks, integration tests.
consensus 9.6k loc Native Rust script-verification engine (the second engine beside bitcoinconsensus FFI).
events 13k loc Streaming Consumption API: gRPC/WebSocket/ZMQ carriers for the event envelope.
satd-events-client 9.3k loc Async Rust SDK: resilient reconnect, cursor replay, watch re-registration.
clients/go 24k loc Go SDK (satdevents) with a differential parity harness against the Rust SDK.
satd-policy 6.6k loc Relay-policy language: lexer, parser, typechecker, static cost model, fuel-metered evaluator.
electrum-proto 5.4k loc Electrum v1.4.5 protocol server, vendored from electrs, adapted to the AddressIndex trait.
esplora-handlers 4.0k loc Esplora REST wire-format handlers + SSE, parity with blockstream.info/mempool.space.
sat-tui 6.3k loc Ratatui ops TUI: IBD bitmap, per-peer stats, RPC explorer.
mcp 2.8k loc Model Context Protocol server exposing ops RPCs to AI agents over streamable HTTP(S).
sat-cli 2.4k loc Structured CLI (chain info, mempool top, psbt analyze…) + legacy raw-method passthrough.
satd-auth 2.4k loc Capability-scoped bearer tokens, TOML authfile, per-surface opt-in.
node-index 1.5k loc Address-history index: per-scripthash funding/spending over shared RocksDB.
node-sp-index 1.5k loc BIP 352 silent-payment tweak index; self-authenticating per-block rows.
satd-alert 1.5k loc Node-health detectors + signed outbound webhooks (alertfile TOML).
tls-config 0.9k loc Shared native TLS/mTLS config for RPC, Electrum, Esplora, events, MCP listeners.
node-filter-index 0.5k loc BIP 158 compact-filter index, built atomically with the chainstate.
block-analyzer 0.5k loc Offline block-file analysis tool.
fuzz/ is a separate cargo-fuzz workspace (nightly + sanitizers), kept out of the normal build. Toolchain pinned at Rust 1.93.0, edition 2024.
Part 1 · Orientation
Architecture at a glance
The spine is the same as any full node — P2P feeds validation, validation feeds storage — but every read surface hangs off the same RocksDB instance and updates ride the same write batch as block connection, so no surface can observe an index out of sync with the tip.
network<br>PeerManagerone tokio task per peer · BIP 324 v2 transport
AddrMantried/new buckets · SADR peers.dat
IBD schedulerparallel download windows + prefetch
↓ NetworkMessage
validation<br>Block/tx checksPoW, witness commitment, MTP, BIP 34/68
ScriptVerifierRust engine + bitcoinconsensus...