This section states the server from which a light wallet obtains chain data. It fixes the architecture and the one assumption on the server that the volume uses, states which checks a light client can make on the server’s responses and what the server can fabricate or omit undetected, and defines the service as an abstract interface of typed queries on the chain, the note commitment trees, transactions, submission and transparent addresses.
A light-client system has three components:
a full node, which validates the chain and is the root of trust for chain state;
a proxy, which extracts from the node’s view of the best chain the data of compact blocks (Definition 4.2) and answers queries;
a light client, which holds keys and no copy of the chain, queries the proxy, and maintains its own view of chain state and of its notes.
This volume calls the node and the proxy together the server. The wallet of “Parties, pools, and classifications” (§1.2) is the light client. The best chain is that of the Consensus Guide, §“Work, and the best chain” (ZIP 307, “High-Level Design”).
The server satisfies two clauses.
Integrity. It answers every query from a correct view of the current best chain, each response being the value that the interface of “The query interface” (§5.2) assigns to the query on that chain, and it transmits queries and responses faithfully.
Curiosity. It records every query with its arguments, order and timing, every response, and the transport metadata of every connection, and computes arbitrarily on that record.
Every correctness result of this volume that relies on the server cites clause (a); the privacy results of §8 take clause (b) as the power of the adversary. No other server model is used. ZIP 307, “Security Model”, states the same model: the node and proxy together are honest but curious, and are trusted to provide a correct view of the current best chain and to transmit queries and responses faithfully. Its goal is payment-detection privacy: the proxy does not learn which transactions are addressed to a given wallet and, given network privacy provided separately, does not link different connections or queries to one wallet; the goal is defined in “Payment-detection privacy” (§8.1). The ZIP does not address private spending.
Let a wallet receive responses of the service (§5.2), with compact blocks that carry no header, which the abstract format does not guarantee (Definition 4.2). Then every check the wallet can make compares two responses, or a response with a value the wallet computes from responses. The relations among response fields that the format fixes are the following:
height continuity and linkage of consecutive compact blocks, and of the first block of a range with the block the wallet has stored, the checks of ZIP 307, “Client-server interaction”, phases B and D, and “Block header validation”;
consistency of the per-block tree sizes with the commitments served (Lemma 4.12);
agreement of a served tree node (a frontier, a subtree root, a root) with its recomputation from commitments the wallet has scanned;
agreement of a fetched transaction with its queried identifier and with the compact records of that identifier (Remark “Checks of a fetched transaction”);
equality of a height, block hash or transaction identifier that several responses report.
No check relates a response to a block header or to proof of work: the wallet verifies no tree root, nullifier, transaction identifier or block hash against a header.
The fields of a compact block and of its elements (Definitions 4.2, 4.3 and 4.5) and the responses of the service are values of the chain or tree data derived from it; without no response carries a header, so no field, not even or , which the header determines, can be checked against one. A check is a predicate on the wallet’s inputs, which are these responses and its keys, so it compares responses with one another or with values computed from them. Items (i) to (vi) relate pairs of fields that the format makes functions of one another: the heights and hashes of adjacent blocks; a block’s commitment count and its sizes; a record’s commitment and its plaintext; a tree node and the leaves below it; a fetched transaction and its identifier and compact records; and a height, hash or identifier repeated across responses. Proof of work is a relation between a header and its solution and target (Consensus Guide, §“Equihash and the memoryless model”), which no response carries. □
ZIP 307, “Block header validation”, proposes checks against a header when a compact block carries one; the abstract format does not guarantee a header, and no result of this volume uses them.
Under clause (a) of Assumption 5.2, every compact candidate accepted by Definition 4.9 is a note of the best chain: its commitment is a leaf of its pool’s note commitment tree at the position that Definition 4.11 assigns. The fields a compact record omits (proofs, signatures, value commitments, anchors, full ciphertexts) are checked by consensus for every transaction of the best chain, so delegating their verification to the server loses no check a light client could make.
Without clause (a), no check authenticates the compact fields against the chain. A server that knows one of the wallet’s addresses can construct a note to it, compute its commitment and note ciphertext, choose the remaining compact fields ( of an Action, which is of the note), and serve the result as a compact output or Action, with tree sizes consistent with it; the result passes Definition 4.9. Unless a transaction of the chain appends the same commitment, no authentication path from it to an anchor of the chain can be found except with negligible probability, so the wallet displays a note whose every spend is rejected.
(a) By Proposition 4.10(a) an accepted candidate opens the commitment of its compact record. By clause (a) that record is the corresponding field of a transaction of the best chain, whose commitments are appended to the pool’s tree in the order that fixes the position (Ironwood Guide, §“The Merkle hash and the tree”, Definition “Note commitment tree”; Lemma 4.12(a)). The omitted fields are validated by the consensus rules for every transaction of the chain (Ironwood Guide, §“Transaction digests and signatures” and §“Anchors”).
(b) Acceptance checks only the lead byte, the field ranges, the commitment recomputed from the plaintext and (Definition 4.9), and an honestly constructed note to an address of the wallet satisfies all of them; the tree-size checks of Lemma 4.12 pass on sizes the server chooses consistently, by part (d) of that lemma. A spend proves a valid path from the commitment to an anchor of the chain (Ironwood Guide, §“Authentication paths”), and a valid path from a value that is not the leaf at its position yields a collision of the Merkle hash, found with at most negligible probability (Ironwood Guide, §“Anchors”, Proposition “Membership soundness”; protocol specification, §“Merkle Path Validity”, for Sapling). ZIP 307, “Output Compression”, grounds the commitment check on the same trust, in the entity that assembles transactions. □
Completeness of the served data is trusted, not verified. The size check of Lemma 4.12 detects the omission of a commitment only while the served sizes are correct. A server that omits compact outputs or Actions and serves tree sizes, frontiers, subtree roots and roots consistent with the omission, or omits or alters revealed nullifiers, of which a compact block carries no count, passes every check of Proposition 5.3. Omitted outputs hide receipts. Omitted nullifiers hide spends: the wallet shows spent notes as spendable, and a re-spend of such a note is rejected for a repeated nullifier (Ironwood Guide, §“Nullifier sets”) while it discloses to every party that receives it that it spends what an earlier transaction spent, the leak of repeated spends of ZIP 315, “Obtaining user consent for information leakage”. Only clause (a) of Assumption 5.2 excludes omission (ZIP 307, “Security Model”).
A response with a field outside its type (a nullifier not of bytes, a non-canonical encoding of a field element, a malformed compact output or Action, a block outside the requested range) is an error of the response: the results of the query are not applied, and the query may be repeated. It is not a continuity error and triggers no rollback (“Reorganisation detection and recovery”, §7.6). This rule is designed but unspecified (Definition 1.1).
A full transaction fetched by its identifier SHOULD be checked against the corresponding compact outputs, in addition to verification of its signatures (ZIP 307, “Block header validation”). The checks are: the identifier computed from the fetched transaction equals the queried one (Ironwood Guide, §“Transaction digests and signatures”, Definition “Transaction identifier”; protocol specification, §“Transaction Identifiers”); its outputs and Actions agree with the compact records; and its signatures verify over its signature digest (Ironwood Guide, §“Transaction digests and signatures”, Definition “Signature digest”). They bind the full transaction to the compact data and its authorisation to its effects. They bind neither to the chain: compact blocks carry too little to check an identifier against the block’s transaction tree, and that binding rests on clause (a) of Assumption 5.2.
A wallet holds keys and no chain state (Definition 5.1), so the interface delivers what the protocols below consume: every compact output and Action of every shielded pool, for trial decryption (Ironwood Guide, §“Trial decryption and note acceptance”); every revealed nullifier, for spend detection (Ironwood Guide, §“Nullifier sets”); for each pool, tree sizes, frontiers and the roots of complete subtrees, for positions and authentication paths (Ironwood Guide, §“Authentication paths”); the full transactions that concern the wallet; submission of its transactions and their status; and, for transparent receivers, the transparent outputs paid to its addresses.
Let , whose note commitment tree has depth and layers numbered from layer , the root, to layer , the leaves (Ironwood Guide, §“The Merkle hash and the tree”, Definition “Note commitment tree”; protocol specification, §“Note Commitment Trees”, for Sapling). For , subtree of the tree is the subtree whose leaves are the positions ; its root is the node , sixteen layers above the leaves. When the tree holds leaves, subtree is complete if , after which its root no longer changes; the complete subtrees are those with . The completing height of a complete subtree is the height of the block whose transactions append position .
The status of a transaction identifier on the server’s best chain, with tip height , is one of:
: the server knows no transaction with identifier ;
: the server knows the transaction, in its mempool or in a block off the best chain, and no block of the best chain contains it;
: the block of the best chain at height contains it.
The encoding of the status lies outside the abstract interface. The status is designed but unspecified (Definition 1.1).
The light-client service is the set of typed queries of Table 4, each answered from the server’s best chain under clause (a) of Assumption 5.2. A block identifier is a height or a -byte block hash. A pool set is a set of the pool selection of “The compact block and the compact transaction” (§4.1): shielded pools, with transparent data selectable alongside. The service serves every pool set and transparent data. A query whose argument names no block of the best chain, or a transaction that the server does not know, is answered with . Queries of the mempool and of server metadata are not part of the interface.
| Query | Arguments | Response |
| Chain | ||
| none | of the tip of the best chain; the tip input of every confirmation count (§9) | |
| block identifier | the compact block of , with all shielded pools and transparent data | |
|
heights ;
pool set |
the compact blocks at heights in ascending order, restricted to ; every height of present, a block left with no transaction carrying an empty list | |
| Trees | ||
| block identifier | height and hash of , and for each shielded pool the size and the frontier of its tree in the final treestate of ; an empty frontier denotes the empty tree | |
|
shielded pool ;
start index |
in index order, the pair (root, completing height) of every complete subtree of the tree of with index at least | |
| Transactions | ||
| -byte identifier | the full serialised transaction | |
| serialised transaction | if the server’s node admits it to its mempool, else | |
| -byte identifier | the status of Definition 5.9 | |
| Transparent | ||
| set of transparent addresses | the unspent outputs of the best chain paying to , each with outpoint, value, script and height | |
The frontier in a response of is that of the Crypto Guide, §“Append-only and incrementally updatable trees”, Definition “Frontier”: for a tree of leaves, the left-sibling nodes along the path of the next leaf, one for each set bit of , from which the root and every later append are computed. The empty frontier is the state before the pool’s first commitment. The final treestate of a block is that of the protocol specification, §“Transactions and Treestates” (Ironwood Guide, §“Anchors”, Definition “Treestate and anchor”). The serialisation of the frontier is fixed by no ZIP and is not restated. ZIP 307, “Proxy operation”, also identifies a transaction by its block and its index in the block; the interface uses the identifier alone.
ZIP 307, “Proxy operation”, specifies the queries , , and . No ZIP specifies , , , or the transparent query , and ZIP 307, “Client-server interaction”, leaves the acquisition of a starting tree state open: “Or, it has to set X to the block height at which Sapling activated, so as to be sent the entire commitment tree. [TODO: Decide which to specify.]” These queries, and pool selection in , are designed but unspecified (Definition 1.1).
A shielded synchronisation uses , for each shielded pool, and ; the full transactions that concern the wallet add . A wallet that watches transparent receivers adds , whose argument names its addresses in the clear (“Key independence of queries”, §8.2). This set is the requirement of the synchronisation protocols of “Note discovery” (§6) and “Commitment-tree synchronisation” (§7), not a deployed fact.