Mempool, Mining, and the Wallet Ecosystem
Why This Chapter Exists
Zebra is a validator node. Wallets, miners, and explorers consume it. You must know where Zebra's responsibility ends and theirs begins, or you will accept PRs that drag those scopes into Zebra.
The operational realities at the boundaries of the validator node. Even though Zebra is "only" a validator, every interaction with wallets, mining pools, indexers, and lightclients flows through these three surfaces.
The Mempool
The spec is at book/src/dev/mempool-specification.md. Read it
end to end before reading this file.
Invariants the Mempool Must Maintain
- every transaction in the mempool must verify against the current chain tip context (anchor existence, nullifier non-revealedness, UTXO presence, transparent expiry).
- on reorg, mempool entries must be re-verified against the new tip. Some entries may become invalid.
- an unconfirmed nullifier or UTXO must not be reused. The mempool tracks unconfirmed spends to prevent inclusion of conflicting transactions in a block template.
- value-pool consistency: mempool entries must respect per-pool value constraints in aggregate.
- expiry: transactions with a height-based expiry past the current tip are evicted.
Admission Rules
A transaction is admitted to the mempool if it passes:
- structural validation (well-formed bytes).
- semantic validation (signatures, proofs, scripts, sigops).
- contextual validation (anchors, nullifiers, UTXOs).
- mempool-specific limits (fee minimums, size bounds, ZIP-401 weight limits).
- non-conflict with existing mempool entries.
ZIP-401 Anti-dos
ZIP-401 defines the weight-based admission rules that bound mempool memory and CPU costs. Each transaction has a weight (a function of size, sigops, proof count). The mempool maintains a total weight budget; when full, it evicts by lowest fee-per-weight. The exact formula is in the ZIP; verify against the current spec section.
Eviction Order
- expired transactions first.
- transactions made invalid by a reorg next.
- on-overflow, lowest-fee-per-weight last.
The "transaction queue" (zebra-rpc/src/queue/) is the staging
buffer in front of the mempool. New transactions arrive here from
sendrawtransaction or peer gossip, batch-verify, then flush into
the mempool.
Mempool Sources
In Zebra, the mempool is split between zebra-rpc/src/queue/ (the
RPC-facing queue) and zebrad/src/components/mempool/ (the
component running the rules). The split exists because the queue
needs to be reachable from the RPC handlers, while the mempool
proper is owned by the orchestrator.
The relevant diagram is at book/src/dev/diagrams/ mempool-architecture.md.
Mining and getblocktemplate
Mining pools and miners interact with Zebra through JSON-RPC. The key methods:
getblocktemplate(proposal mode and template mode).submitblock.getblocksubsidy,getmininginfo,getnetworkhashps.
The getblocktemplate Flow
The full sequence, end to end:
- miner calls
getblocktemplatewith optional long-poll ID. - Zebra builds a candidate block:
- selects transactions from the mempool by fee-per-weight, subject to size and sigop limits.
- constructs the coinbase transaction including the funding- stream / NSM payouts at the per-height required addresses.
- computes default roots (Merkle root, tree roots, history root, authdigest root for NU5+).
- serializes the template as JSON-RPC response.
- miner builds candidate blocks by varying the nonce, the ExtraNonce in coinbase, and (optionally) the Equihash solution.
- on finding a valid Equihash solution + difficulty, miner submits
via
submitblock. - Zebra validates the submission as a full block, commits if valid.
- long-poll: if the chain tip changes or mempool changes
significantly, miners polling
getblocktemplateare unblocked with a fresh template.
The relevant code is in zebra-rpc/src/methods/types/ get_block_template/. long_poll.rs is the long-poll mechanism.
Coinbase Math
Coinbase transactions carry:
- the block subsidy (from
zebra-consensus/src/block/subsidy/). - a height-based encoding in the scriptSig.
- the funding-stream payouts (Canopy through NU6).
- the NSM (Network Sustainability Mechanism) payouts (NU6+).
- the miner's payout (the residual).
The funding-stream addresses and percentages are in
zebra-chain/src/parameters/. Any miss in the coinbase math
produces an invalid block.
The Internal-miner Feature
Behind the internal-miner Cargo feature, Zebra can mine in-
process. Documented as testnet-only; not for production. Useful
for regtest and integration testing.
The Wallet Ecosystem
Zebra is a node, not a wallet. The wallet world consumes Zebra's APIs as follows.
Lightwalletd
The lightwalletd daemon (ECC) sits in front of zebrad or
zcashd and exposes a gRPC interface tailored for light clients.
It is the original light-client server.
What lightwalletd needs from Zebra:
- JSON-RPC: blocks by height, raw transactions, mempool, send.
- a stable stream of new blocks as they arrive.
The integration tests behind the lightwalletd-grpc-tests Cargo
feature run a real lightwalletd against zebrad.
Zaino
zingolabs/zaino is the successor light-client server, written in
Rust, designed to consume Zebra's indexer gRPC directly. Aimed at
replacing or supplementing lightwalletd long-term.
What zaino needs from Zebra:
- the indexer gRPC (behind the
indexerCargo feature). - block streams.
- spend-lookup-by-nullifier and other denormalized indexes.
Zallet
zcash/wallet (Zallet) is the official ECC wallet effort
post-zcashd. Consumes Zebra's indexer and JSON-RPC.
Other Wallets
YWallet, Nighthawk, Zashi, ZecWallet Lite (legacy), and others consume one of: lightwalletd, zaino, or direct JSON-RPC to Zebra.
The Indexer Surface
The indexer gRPC (Zebra crate zebra-rpc/src/indexer/) exposes:
- transparent address indexes.
- nullifier lookups.
- subtree roots.
- additional historical data not in standard JSON-RPC.
This is what wallet servers use to scan for incoming notes efficiently. The exact methods evolve; consult the proto definitions in the codebase.
What This Means for the Validator Side
Even though Zebra is a validator, every of these consumers is a constraint:
- mempool stability matters because wallets watch mempool.
- block template accuracy matters because miners' revenue depends on it.
- JSON-RPC compatibility with zcashd matters because every existing client expects zcashd-shaped responses.
- indexer correctness matters because wallets reconstruct user balances from it.
Bugs in any of these surfaces show up as wallet incidents long before they show up as consensus incidents.
See Also
- 09-threat-model.md (mempool DoS, mining-pool adversaries).
book/src/dev/mempool-specification.md.book/src/dev/diagrams/mempool-architecture.md.book/src/user/mining.mdandbook/src/user/mining-docker.md.- the
lightwalletd,zaino, andzalletrepositories.
Spec Pointers
- Zaino for the lightwalletd-compatible indexer.
- Zallet for the reference wallet.
librustzcashfor the wallet-side cryptography.
Exercises
- Identify one feature that Zebra deliberately does not implement (wallet, block explorer, etc.) and find a closed PR that proposed it.
- List the RPC methods Zebra exposes that Zaino consumes.
- Find the Stratum or
getblocktemplateentry point and explain in one sentence what it returns.