Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ and this library adheres to Rust's notion of

## Unreleased

### Added
- `service.MMRNode`
- `service.BlockInclusionProof`
- `service.BlockInclusionProof.tip_height`: height of the block whose header
commits to `mmr_root` and `auth_data_root`. The client should fetch this
block's header (via `GetBlock`) and verify `hashBlockCommitments` against it.
- `service.CompactTxStreamer.GetBlockInclusionProof`: returns an MMR inclusion
proof for a specific block (ZIP-221), enabling light clients to verify that
a block is included in the committed chain history. The proof includes the
MMR root, auth data root (ZIP-244), the MMR leaf entry for the requested
block, sibling nodes along the Merkle path from leaf to root, and the
`tip_height` identifying the committing block. For FlyClient verification
(ZIP-307), the client selects blocks to challenge using the sampling
distribution from https://eprint.iacr.org/2019/226.

## [v0.4.1] - 2026-02-20

### Added
Expand Down
50 changes: 50 additions & 0 deletions walletrpc/service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,42 @@ message GetAddressUtxosReplyList {
repeated GetAddressUtxosReply addressUtxos = 1;
}

// A node in the MMR tree, identified by its position in the
// flat array representation of the tree (see ZIP-221).
message MMRNode {
// Position in the MMR flat array representation
uint32 position = 1;
// Serialized zcash_history::Entry bytes for this node
bytes data = 2;
}

// An MMR inclusion proof for a block in the chain history tree (ZIP-221).
//
// Contains the MMR root and auth data root for a specific chain tip,
// plus the Merkle path proving the requested block is in the committed chain.
// The client can verify:
// hashBlockCommitments = BLAKE2b-256("ZcashBlockCommit" || mmr_root || auth_data_root || [0u8;32])
// against the block header at `tip_height` (obtainable via GetBlock) to
// authenticate the MMR root, then verify the inclusion proof against it.
//
// Future optimization: a range variant could batch multiple proofs sharing
// common MMR subtree nodes.
message BlockInclusionProof {
// hashLightClientRoot: the MMR root committed in the block at tip_height (32 bytes).
bytes mmr_root = 1;
// hashAuthDataRoot: the transaction auth data commitment from ZIP-244
// for the block at tip_height (32 bytes).
bytes auth_data_root = 2;
// The MMR leaf entry for the requested block.
MMRNode leaf = 3;
// Sibling nodes along the path from leaf to root (bottom-up order).
repeated MMRNode siblings = 4;
// Height of the block whose header commits to mmr_root and auth_data_root.
// The client should fetch this block's header (via GetBlock) and verify
// hashBlockCommitments against the returned mmr_root and auth_data_root.
uint32 tip_height = 5;
}

service CompactTxStreamer {
// Return the BlockID of the block at the tip of the best chain
rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
Expand Down Expand Up @@ -323,4 +359,18 @@ service CompactTxStreamer {

// Testing-only, requires lightwalletd --ping-very-insecure (do not enable in production)
rpc Ping(Duration) returns (PingResponse) {}

// Get an MMR inclusion proof for a specific block (ZIP-221).
//
// Returns the MMR root, auth data root, and a Merkle path proving
// the block is included in the current chain tip's committed history.
// The client should:
// 1. Get the tip block header via GetBlock.
// 2. Call this RPC to get the MMR root and inclusion proof.
// 3. Verify hashBlockCommitments in the header against mmr_root + auth_data_root.
// 4. Verify the Merkle path against the MMR root.
//
// For FlyClient verification, the client selects blocks to challenge
// using the sampling distribution from https://eprint.iacr.org/2019/226.
rpc GetBlockInclusionProof(BlockID) returns (BlockInclusionProof) {}
}