The Zcash ArboretumWallet Guide PDF

13 The transaction lifecycle

This section states what a wallet does with a transaction between its creation and a terminal state: the encoding it submits and the identifier by which it tracks the transaction; the rule that a transaction is recorded before it is released, with the completeness of the record that follows; submission and rebroadcast; the status observations that update the record; and the terminal states, re-sending and the consensus branch. A transaction is created when it is built, proved and authorised from one step of a plan (Definition 11.2; Constructions 11.18 and 11.20). The record is that of Definition 9.11.

13.1 Submission and the transaction identifier

The wallet serialises a created transaction in the encoding of its version: version 5 (ZIP 225, “Transaction Format”) or version 6 (ZIP 229, “Transaction Format”), the only versions in force; a transaction with Ironwood-pool Actions has version 6 (Ironwood Guide, §“The transaction format”, Construction “Version-6 transaction”; protocol specification, §“Transaction Encoding and Consensus”). The argument of 𝖲𝗎𝖻𝗆𝗂𝗍 (Definition 5.10) is this byte string. The encoding is cited, not restated.

The wallet tracks a transaction t by its transaction identifier 𝗍𝗑𝗂𝖽⁢(t): the root of the BLAKE2b-256 digest tree of ZIP 244 over the effecting data of t,

𝗍𝗑𝗂𝖽(t)=𝗁(ZcashTxHash_∥β,d𝗁𝖽𝗋∥d𝗍𝗋∥d𝖲𝖺𝗉∥d𝖮𝗋𝖼∥d𝖨𝗋𝗐),

where 𝗁⁢(P,x) is BLAKE2b-256 of x under the 16-byte personalisation P, β is the 4-byte little-endian consensus branch identifier, and the child d𝖨𝗋𝗐 is absent in version 5 (Ironwood Guide, §“Transaction digests and signatures”, Definition “Transaction identifier”, for version 6, and Remark “Version 5”; ZIP 244, “txid_digest”; ZIP 229, “Transaction Identifiers, Auth Digests, and Signature Digests”; protocol specification, §“Transaction Identifiers”). The header digest d𝗁𝖽𝗋 hashes, under ZTxIdHeadersHash, the 4-byte little-endian encodings of 𝗁𝖾𝖺𝖽𝖾𝗋, 𝗇𝖵𝖾𝗋𝗌𝗂𝗈𝗇𝖦𝗋𝗈𝗎𝗉𝖨𝖽, 𝗇𝖢𝗈𝗇𝗌𝖾𝗇𝗌𝗎𝗌𝖡𝗋𝖺𝗇𝖼𝗁𝖨𝖽, 𝗅𝗈𝖼𝗄⁢_⁢𝗍𝗂𝗆𝖾 and 𝗇𝖤𝗑𝗉𝗂𝗋𝗒𝖧𝖾𝗂𝗀𝗁𝗍 (ZIP 244, “T.1: header_digest”), so the expiry height N of Definition 9.8 is effecting data. The wallet computes 𝗍𝗑𝗂𝖽⁢(t) from t and needs no response of the server to know it.

Lemma 13.1 (Non-malleability of the identifier).

Let t be a transaction of version 5 or 6.

  1. (i)

    Replacing the authorising data of t, namely its proofs, signatures and transparent scripts and, in version 6, its anchors (𝖺𝗇𝖼𝗁𝗈𝗋𝖲𝖺𝗉𝗅𝗂𝗇𝗀, 𝖺𝗇𝖼𝗁𝗈𝗋𝖮𝗋𝖼𝗁𝖺𝗋𝖽 and 𝖺𝗇𝖼𝗁𝗈𝗋𝖨𝗋𝗈𝗇𝗐𝗈𝗈𝖽, ZIP 229, “Anchor commitment (version 6)”; Ironwood Guide, §“Transaction digests and signatures”, Definition “Authorising-data digest; effecting and authorising data”), leaves 𝗍𝗑𝗂𝖽⁢(t) unchanged.

  2. (ii)

    Under the Ironwood Guide’s Assumption “Collision resistance of BLAKE2b” (§“Transaction digests and signatures”), no efficient algorithm outputs, except with negligible probability, two transactions with different effecting data and equal identifiers.

  3. (iii)

    Under the same assumption, a transaction built for one consensus branch and the same payment built for another have different identifiers, except with negligible probability.

Proof.

(i) Authorising data lie under the authorising-data digest and under no node of the tree whose root is 𝗍𝗑𝗂𝖽 (Ironwood Guide, §“Transaction digests and signatures”, Definition “Authorising-data digest; effecting and authorising data”). (ii) Each node of the tree hashes an injective encoding (fixed-size fields and length-prefixed scripts, concatenated in order) of effecting data or of the digests of its children (ZIP 244, “txid_digest”). If the effecting data differ, the inputs of some node differ. A node whose inputs differ either has equal digests, which is a collision, or passes different digests to its parent, whose inputs then differ; at the root, equal identifiers from different inputs are a collision. (iii) The branch identifier enters both the root personalisation ZcashTxHash_∥β and the header digest through 𝗇𝖢𝗈𝗇𝗌𝖾𝗇𝗌𝗎𝗌𝖡𝗋𝖺𝗇𝖼𝗁𝖨𝖽, so the two root pairs differ, and equal identifiers are a collision (Ironwood Guide, §“Transaction digests and signatures”, Remark “Consensus-branch binding”). □

By (i) and (ii), the identifier tracks a pending transaction from its creation on, before and after any re-signing or re-proving. The identifier of versions up to 4, the double SHA-256 of the encoding (protocol specification, §“Transaction Identifiers”), is malleable; it belongs to no version in force and is not used.

Construction 13.2 (Recording and submission).

The following rules are designed but unspecified (Definition 1.1).

  1. (L1)

    Recording before release. The wallet enters each transaction t it creates into its transaction record (Definition 9.11), which locks the notes t spends (Definition 9.12), in storage that survives restarts and rollbacks (Definition 7.23, item (v)), before it submits t or releases its bytes to any other party. It never removes an entry of the record.

  2. (L2)

    Multi-step plans. For a plan of ℓ>1 steps (Definitions 11.2 and 11.3), the wallet creates every step before it records any, records all ℓ transactions in one update of the record, and submits them after that update, in step order. A construction that fails at some step leaves no recorded, hence by (L1) no transmittable, prefix. Every step can be created before any is mined, since a well-formed plan chains steps only through transparent outputs (Proposition 11.4); the transfer to a TEX address of Construction 11.7 is the instance (ZIP 320, “Design considerations for Senders”).

  3. (L3)

    Submission. The wallet submits t by 𝖲𝗎𝖻𝗆𝗂𝗍⁢(𝑏𝑦𝑡𝑒𝑠), whose response is 𝖺𝖼𝖼𝖾𝗉𝗍𝖾𝖽⁢(𝗍𝗑𝗂𝖽) or 𝗋𝖾𝗃𝖾𝖼𝗍𝖾𝖽 (Definition 5.10). Neither response changes the record. It submits at a tip T that leaves a margin of blocks, a wallet parameter, before the last includable height N (Definition 9.8), rather than at T=N−1.

  4. (L4)

    Rebroadcast. While t is pending and unmined (Definition 13.8), the wallet resubmits it at intervals whenever, at its tip T, N=0 or T<N (Lemma 9.9) and no transaction included in its view of the chain spends an input of t. For N=0 this continues until t is mined or an input of t is spent by a mined transaction. The rule is motivated by ZIP 203, “Specification”, under which nodes drop a transaction from their mempools at its expiry.

The semantics of the two responses of 𝖲𝗎𝖻𝗆𝗂𝗍 are those of the server’s node and are fixed by no ZIP: 𝖺𝖼𝖼𝖾𝗉𝗍𝖾𝖽 means that the node admitted t to its mempool, 𝗋𝖾𝗃𝖾𝖼𝗍𝖾𝖽 that it refused it. Under clause (a) of Assumption 5.2, acceptance implies neither propagation to other nodes nor inclusion in a block, since relay policy is local to each node and may refuse a transaction that consensus still admits in the next block (Lemma 9.9); and rejection does not imply that t is invalid. Rule (L3) keeps a margin for this reason. Each submission is an observation of the server (Proposition 8.21).

Proposition 13.3 (Completeness of the transaction record).

Let the wallet follow rule (L1), and let no party other than the wallet hold the bytes of a created transaction t before the wallet submits them. Then, if a block of any chain includes a transaction with the effecting data of t, the record contains t, and the included transaction has identifier 𝗍𝗑𝗂𝖽⁢(t), except with negligible probability. The converse fails: a recorded transaction that the network never received is stale, not lost, and, for N≠0, reaches the terminal state expired unmined of Definition 13.8; for N=0 it stays pending by item (c) until the end of its consensus branch is known, and then reaches expired unmined with the bound N∗ (“Consensus-branch bound” below).

Proof.

A block includes a transaction only if the party that assembled the block held its bytes. The first party other than the wallet to hold bytes of t received them by the wallet’s submission, by hypothesis; by (L1) the wallet recorded t before that event, and the entry survives restarts and rollbacks and is never removed. A valid transaction with the effecting data of t carries, for each spend of t other than a dummy, a signature under a key of the wallet on the signature digest those data fix; except with negligible probability no party obtains such a signature except from bytes the wallet released (Ironwood Guide, §“RedPallas unforgeability”, Proposition “Unforgeability under re-randomisation”, for Orchard-protocol spends; for transparent and Sapling spends the unforgeability of those schemes is assumed, as in §11.8, where no lower volume proves it). Bytes derived from those of t by another party with the effecting data of t differ from t at most in authorising data, so the included transaction has identifier 𝗍𝗑𝗂𝖽⁢(t) by part (i) of the lemma above. The converse fails because recording does not imply delivery. □

Where a partially created transaction is extracted by another party (“Spend finalisation and extraction”, §12.10), that party holds the bytes of t before any submission, and the hypothesis is arranged differently: the wallet records 𝗍𝗑𝗂𝖽⁢(t), N and the inputs of t, locking them, before it releases the partially created transaction to any party that may extract it, and at a point where the effecting data of t are final. After IO finalisation (Construction 12.14) of a partially created transaction with shielded spends or outputs, or, for one that is transparent-only, once signatures without 𝖲𝖨𝖦𝖧𝖠𝖲𝖧⁢_⁢𝖠𝖭𝖸𝖮𝖭𝖤𝖢𝖠𝖭𝖯𝖠𝖸 and without 𝖲𝖨𝖦𝖧𝖠𝖲𝖧⁢_⁢𝖭𝖮𝖭𝖤 have cleared bits 0 and 1 of 𝗍𝗑⁢_⁢𝗆𝗈𝖽𝗂𝖿𝗂𝖺𝖻𝗅𝖾 (ZIP 374, “Global”), the inputs and outputs are final, the lock time is determined by Definition 12.24, and the proofs and signatures still to be added are authorising data; by part (i) of the lemma the extracted transaction then has the recorded identifier, and the proof above applies with release in place of submission. The entry acquires the encoding of t when the wallet obtains it.

Remark 13.4 (Retained data).

From creation until it is mined, t exists only in the wallet’s record, in remote mempools and, for an extracted partially created transaction, at the extracting party. Once the wallet holds the encoding of t (Definition 9.11, item (i)) the record keeps it, and rule (L4) needs it; before that the wallet does not rebroadcast t. It may hold data that the chain never will: a transaction that ends expired and unmined lies on no chain that agrees with the server’s up to N (Lemma 13.7), and its entry may be the only trace of it.

13.2 Status tracking and terminal states

Remark 13.5 (Scope of scanning).

Scanning detects a transaction only through a nullifier of the watched set W (Definition 9.15) or an output accepted under the wallet’s scanning keys (Construction 6.8). A recorded transaction that spends no note of W and has no such output, every fully transparent transaction among them, is invisible to scanning. Its fate is learnt only by queries 𝖲𝗍𝖺𝗍𝗎𝗌⁢(𝗍𝗑𝗂𝖽) (Definition 5.9), each of which puts its identifier into the view of the server (Proposition 8.18).

For a recorded transaction t write N for its expiry height, ht for its mined height (⊥ while unmined), htobs for its earliest observation height, and ut for the latest tip at which the server reported it unmined (⊥ initially): items (ii), (iv), (v) and (vi) of Definition 9.11. A status observation (s,T) is a response s of 𝖲𝗍𝖺𝗍𝗎𝗌⁢(𝗍𝗑𝗂𝖽⁢(t)) received while the wallet’s view of the chain has tip T.

Construction 13.6 (Status transitions).

The record entry of t changes only as follows.

  1. (i)

    On an observation (s,T) with s∈{𝗎𝗇𝗄𝗇𝗈𝗐𝗇,𝗎𝗇𝗆𝗂𝗇𝖾𝖽}: ut:=T.

  2. (ii)

    On an observation (𝗆𝗂𝗇𝖾𝖽⁢(h′),T): ht:=h′, htobs:=min⁡(htobs,h′) and ut:=⊥.

  3. (iii)

    Scanning a block of height h′ in which t is wallet-relevant (Construction 6.8) has the effect of (ii).

  4. (iv)

    A rollback to r (Definition 7.23) sets ht:=⊥ if ht>r, and ut:=min⁡(ut,r) if ut≠⊥, since a report at a tip above r concerned blocks that the rollback discards.

Query termination. The wallet issues 𝖲𝗍𝖺𝗍𝗎𝗌⁢(𝗍𝗑𝗂𝖽⁢(t)) for a pending transaction t with ht=⊥: if N≠0, until ut≥N, that is, until t is reported unmined at a tip of at least N; if N=0, for as long as t is pending and unmined. No rule stops at a first report of 𝗎𝗇𝗆𝗂𝗇𝖾𝖽 or at a fixed depth after first observation. A rollback that lowers ut below N, or sets ht:=⊥, resumes the queries. The transitions and the termination rule are designed but unspecified (Definition 1.1); the termination rule rests on the consensus rule of Definition 9.8 (ZIP 203, “Specification”). For an entry with Nt unknown (Definition 9.11), the wallet obtains the encoding by 𝖳𝗑⁢(𝗍𝗑𝗂𝖽) (Definition 5.10); until then it queries as for N=0, does not rebroadcast, and its inputs are locked by condition (d) of Definition 9.12.

Lemma 13.7 (Expired unmined is final on its chain).

Assume clause (a) of Assumption 5.2. Let t be a transaction created by the wallet, with expiry height N≠0, and let (s,T) be an observation with s∈{𝗎𝗇𝗄𝗇𝗈𝗐𝗇,𝗎𝗇𝗆𝗂𝗇𝖾𝖽} and T≥N, answered from a best chain C of the server (Consensus Guide, §“Work, and the best chain”) whose blocks at heights at most N are those of the wallet’s view. Then no chain whose blocks at heights at most N are those of C includes t.

Proof.

The wallet’s view has tip T≥N, so C has blocks at every height up to N. By clause (a), s is the status of 𝗍𝗑𝗂𝖽⁢(t) on C (Definition 5.9): no block of C contains t, so no block of height at most N of a chain that agrees with C up to N does. The transaction t is not a coinbase transaction, and by Lemma 9.9 the expiry rule permits it in no block of height greater than N (protocol specification, §“Transaction Consensus Rules”; ZIP 203, “Specification”). □

A reorganisation with fork point below N reopens the question, since the new chain need not agree with C up to N. The wallet meets it as a continuity error (Definition 6.10), and the rollback of Construction 7.24 to some r<N sets ut≤r<N by transition (iv), which resumes the queries.

Let B be the birthday of the wallet (Definition 6.2) and ℋ its retained block boundaries (Definition 7.12). Write rmin for the least element of ℋ∖{B−1}, the lowest rollback point of the rollback window, and rmin:=B−1 when that set is empty.

Definition 13.8 (Terminal states).

A recorded transaction t is pending from its recording until it reaches one of the following states.

  1. (a)

    Mined: ht≠⊥ and ht≤rmin, so that no rollback to a point of the window unmines t. The state is terminal relative to the rollback window only, since consensus bounds no reorganisation depth (Remark 7.28); a deeper rollback, to B−1 or to a fetched chain state in steps (1) and (3) of Construction 7.24, returns t to pending by transition (iv).

  2. (b)

    Expired unmined: N≠0, ht=⊥ and ut≥N, which gives the conclusion of Lemma 13.7 when the server’s chain agrees with the wallet’s view up to N; a disagreement surfaces as a continuity error (Definition 6.10), whose rollback to r<N returns t to pending by transition (iv). Its inputs are released (Proposition 9.13, every later target height exceeding N), its entry is kept, and the user is notified.

  3. (c)

    For N=0, a value chosen explicitly: t remains pending until it is mined, rebroadcast by rule (L4), or, once the end of its consensus branch is known, until it reaches state (b) with the bound N∗ of that branch (“Consensus-branch bound” below). Its mining is detected by scanning through W, from which a spend, N=0 included, removes a nullifier only once mined (Definition 9.15), or by continued status queries.

The states and their transitions are designed but unspecified (Definition 1.1). The notification is specified: the wallet should notify the user of expired transactions that must be re-sent, and user interfaces and services must never rely on zero-confirmation transactions (ZIP 203, “Wallet behavior and UI”).

Refer to caption
Figure 6: The states of a recorded transaction t (Definition 13.8). Solid edges are transitions of the record: recording by rule (L1), which locks the inputs of t; submission, rebroadcast and reports 𝗎𝗇𝗆𝗂𝗇𝖾𝖽 or 𝗎𝗇𝗄𝗇𝗈𝗐𝗇 at a tip below N, which leave t pending; a report 𝗆𝗂𝗇𝖾𝖽⁢(h′) or the scan of a block containing t, transitions (ii) and (iii); burial below the lowest rollback point rmin of the window; and, for N≠0, a report of an unmined t at a tip T≥N, after which Lemma 13.7 excludes t from every chain that agrees with the server’s up to N. Dashed red edges are rollbacks, transition (iv): below ht from either mined state, from the terminal one only by a rollback deeper than the window, and below N from expired unmined. The green and amber states are terminal; a transaction with N=0 stays pending until mined, unless its consensus branch ends.
Remark 13.9 (Re-sending).

Re-sending an expired payment usually spends the same TXOs, and ZIP 315 lists which spends of given TXOs are repeated across transactions among the kinds of information leakage, the case arising when a previous transaction expired (ZIP 315, “Kinds of information leakage”): the repeated spends link the expired transaction to its replacement. Selecting other notes avoids that link, but the nullifiers that the expired transaction revealed still link it to any later transaction that spends those notes (ZIP 315, “Rationale for anchor selection”). A wallet that re-sends accepts one of the two links. ZIP 315, “Note selection”, records as a TODO, not as a rule, that such revealed nullifiers be spent in a note-management transaction; how to avoid both links is an open problem (Definition 1.1).

Consensus-branch bound. The consensus branch bounds a pending transaction as well as its expiry height does. An authorisation binds the consensus branch identifier through β and 𝗇𝖢𝗈𝗇𝗌𝖾𝗇𝗌𝗎𝗌𝖡𝗋𝖺𝗇𝖼𝗁𝖨𝖽, which must equal the identifier of the branch under which t is validated, so a transaction authorised for one branch is invalid under another whatever its expiry height (Ironwood Guide, §“Transaction digests and signatures”, Remark “Consensus-branch binding”, under its Assumption “Collision resistance of BLAKE2b”; ZIP 244, “txid_digest” and “T.1: header_digest”; ZIP 259, “Backward compatibility”; protocol specification, §“Transaction Consensus Rules”). A pending transaction built for a branch that ends at a height X, with N=0 or X≤N, can be mined only below X. Once X is known, write N∗:=X−1 if N=0 or N≥X, and N∗:=N otherwise. Rule (L4), the query termination of Construction “Status transitions”, state (b) of Definition 13.8 and conditions (b) and (c) of Definition 9.12 apply with N∗ in place of N, and Lemma 13.7 holds with N∗, by the branch binding in place of the expiry rule. Thus t becomes expired unmined from a report at a tip of at least N∗, and its inputs are released for the rebuild at every target height H≥X. This rule is designed but unspecified (Definition 1.1). To pay across the activation of the next branch, the wallet rebuilds and re-authorises the payment for the branch in force at its target height (Definition 9.4): a new transaction, with a new identifier by part (iii) of the lemma of §13.1 and a new entry of the record.