# Consensus rule review ## Pull Requests With Rules Labeled * zcashd https://github.com/zcash/zcash/pull/5912 * librustzcash https://github.com/zcash/librustzcash/pull/548 * orchard https://github.com/zcash/orchard/pull/323 * reddsa https://github.com/ZcashFoundation/reddsa/pull/27 ## 7.1.2 Transaction Consensus Rules * [x] **TCR:tx-version-too-low** The transaction version number MUST be greater than or equal to 1. * [x] **TCR:tx-overwinter-not-active** [Pre-Overwinter] The fOverwintered flag MUST NOT be set. * [x] **TCR:tx-overwintered-flag-not-set** [Overwinter onward] The fOverwintered flag MUST be set. * [x] **TCR:bad-group-id** [Overwinter onward] The version group ID MUST be recognized. * [x] **TCR:bad-overwinter-tx-version-or-group-id** [Overwinter only, pre-Sapling] The transaction version number MUST be 3, and the version group ID MUST be 0x03C48270. * [x] **TCR:bad-sapling-tx-version-or-group-id** [Sapling to Canopy inclusive, pre-NU5] The transaction version number MUST be 4, and the version group ID MUST be 0x892F2085 . * [x] **TCR:bad-nu5-tx-version-or-group-id** [NU5 onward] The transaction version number MUST be 4 or 5. If the transaction version number is 4 then the version group ID MUST be 0x892F2085. If the transaction version number is 5 then the version group ID MUST be 0x26A7270A. * ~~Potential bug: NU5 active, v4 tx with v5 version group ID~~ * ~~Potential bug: NU5 active, v5 tx with v4 version group ID~~ * ^ These cases are excluded in the transaction parser. * [x] **TCR:bad-tx-consensus-branch-id-mismatch** [NU5 onward] The nConsensusBranchId field MUST match the consensus branch ID used for SIGHASH transaction hashes, as specified in [ZIP-244]. * [x] **TCR:tx-pre-sapling-oversize** [Pre-Sapling] The encoded size of the transaction MUST be less than or equal to 100000 bytes. * [x] [NU5 onward] * **TCR:bad-tx-too-many-sapling-spends** nSpendsSapling, * **TCR:bad-tx-too-many-sapling-outputs** nOutputsSapling, and * **TCR:bad-tx-too-many-orchard-actions** nActionsOrchard MUST all be less than 2<sup>16</sup>. * Note: zcashd enforces this even before NU5, which should be a no-op because fewer than 2<sup>16</sup> Spends or Outputs will fit in the largest possible transaction (imposed by the 2MB block size) * **TCR:bad-txns-no-source-of-funds** * [x] [Pre-Sapling] If effectiveVersion = 1 or nJoinSplit = 0, then tx_in_count MUST be nonzero. * [x] [Sapling onward] If effectiveVersion < 5, then at least one of tx_in_count, nSpendsSapling, and nJoinSplit MUST be nonzero. * [x] [NU5 onward] If effectiveVersion ≥ 5 then this condition MUST hold: tx_in_count > 0 or nSpendsSapling > 0 or (nActionsOrchard > 0 and enableSpendsOrchard = 1). * **TCR:bad-txns-no-sink-of-funds** * [x] [Pre-Sapling] If effectiveVersion = 1 or nJoinSplit = 0, then tx_out_count MUST be nonzero. * [x] [Sapling onward] If effectiveVersion < 5, then at least one of tx_out_count, nOutputsSapling, and nJoinSplit MUST be nonzero. * [x] [NU5 onward] If effectiveVersion ≥ 5 then this condition MUST hold: tx_out_count > 0 or nOutputsSapling > 0 or (nActionsOrchard > 0 and enableOutputsOrchard = 1). * [x] **TCR:bad-tx-orchard-flags-disable-actions** [NU5 onward] If effectiveVersion ≥ 5 and nActionsOrchard > 0, then at least one of enableSpendsOrchard and enableOutputsOrchard MUST be 1. * [x] **TCR:bad-txns-coinbase-spend-has-transparent-outputs** A transaction with one or more transparent inputs from coinbase transactions MUST have no transparent outputs (i.e. tx_out_count MUST be 0). Inputs from coinbase transactions include Founders’ Reward outputs and funding stream outputs. * [x] If effectiveVersion ≥ 2 and nJoinSplit > 0, then: * [x] **TCR:bad-joinsplit-public-key** joinSplitPubKey MUST be a valid encoding (see § 5.4.6 ‘Ed25519’ on p. 87) of an Ed25519 validating key. * [x] **TCR:bad-txns-invalid-joinsplit-signature** joinSplitSig MUST represent a valid signature under joinSplitPubKey of dataToBeSigned, as defined in § 4.11 ‘Non-malleability (Sprout)’ on p. 49. * [x] **TCR:bad-txns-sapling-binding-signature-invalid** [Sapling onward] If effectiveVersion ≥ 4 and nSpendsSapling + nOutputsSapling > 0, then: * [x] let $\mathsf{bvk^{Sapling}}$ and SigHash be as defined in § 4.13 ‘Balance and Binding Signature (Sapling)’ on p. 50; * [x] bindingSigSapling MUST represent a valid signature under the transaction binding validating key $\mathsf{bvk^{Sapling}}$ of SigHash — i.e. $\mathsf{BindingSig^{Sapling}.Validate_{bvk^{Sapling}}}(SigHash, bindingSigSapling) = 1$. * [x] **TCR:jubjub-canonical-encoding** [NU5 onward] In section 4.7.0, the validation of the R component of the signature changes to prohibit non-canonical encodings (rule on p. 90). * [x] **TCR:bad-txns-valuebalance-nonzero** [Sapling onward] If effectiveVersion = 4 and there are no Spend descriptions or Output descriptions, then valueBalanceSapling MUST be 0. * In v5 there is nothing to check because "The fields `valueBalanceSapling` and `bindingSigSapling` are present if and only if `nSpendsSapling` + `nOutputsSapling` > 0. If `valueBalanceSapling` is not present, then $\mathsf{v^{balanceSapling}}$ is defined to be 0." (first footnote to the v5 transaction encoding table in section 7.1). TODO add note to spec. —Daira * [x] **TCR:bad-txns-orchard-binding-signature-invalid** [NU5 onward] If effectiveVersion ≥ 5 and nActionsOrchard > 0, then: * [x] let $\mathsf{bvk^{Orchard}}$ and SigHash be as defined in § 4.14 ‘Balance and Binding Signature (Orchard)’ on p. 52; * [x] bindingSigOrchard MUST represent a valid signature under the transaction binding validating key $\mathsf{bvk^{Orchard}}$ of SigHash — i.e. $\mathsf{BindingSig^{Orchard}.Validate_{bvk^{Orchard}}}(SigHash, bindingSigOrchard) = 1$. As specified in § 5.4.7 ‘RedDSA, RedJubjub, and RedPallas’ on p. 88, validation of the R component of the signature prohibits non-canonical encodings. * [x] **TCR:bad-cb-amount** The total value in zatoshi of transparent outputs from a coinbase transaction, minus $\mathsf{v^{balanceSapling}}$, minus $\mathsf{v^{balanceOrchard}}$, MUST NOT be greater than the value in zatoshi of block subsidy plus the transaction fees paid by transactions in this block. * [x] **TCR:bad-cb-has-joinsplits** A coinbase transaction MUST NOT have any JoinSplit descriptions. * [x] **TCR:bad-cb-has-spend-description** A coinbase transaction MUST NOT have any Spend descriptions. * [x] **TCR:bad-cb-has-output-description** [Pre-Heartwood] A coinbase transaction MUST have any Output descriptions. * [x] **TCR:bad-cb-has-orchard-spend** [NU5 onward] In a version 5 coinbase transaction, the enableSpendsOrchard flag MUST be 0. * [x] **TCR:bad-txns-v5-reserved-bits-nonzero** [NU5 onward] In a version 5 transaction, the reserved bits 2 .. 7 of the flagsOrchard field MUST be zero. * [x] **TCR:bad-cb-height** A coinbase transaction for a block at block height greater than 0 MUST have a script that, as its first item, encodes the block height height as follows. For height in the range {1 .. 16}, the encoding is a single byte of value 0x50 + height. Otherwise, let heightBytes be the signed little-endian representation of height, using the minimum nonzero number of bytes such that the most significant byte is < 0x80 . The length of heightBytes MUST be in the range {1 .. 5}. Then the encoding is the length of heightBytes encoded as one byte, followed by heightBytes itself. This matches the encoding used by Bitcoin in the implementation of [BIP-34] (but the description here is to be considered normative). * [x] **TCR:bad-cb-length** A coinbase transaction script MUST have length in {2 .. 100} bytes. * [x] **TCR:bad-txns-prevout-null** A transparent input in a non -coinbase transaction MUST NOT have a null prevout. * [x] **TCR:bad-txns-inputs-missingorspent** Every non-null prevout MUST point to a unique UTXO in either a preceding block, or a previous transaction in the same block. * [x] TODO: this is not trivial to verify (did we label the right code?) * [x] **TCR:bad-txns-premature-spend-of-coinbase** A transaction MUST NOT spend a transparent output of a coinbase transaction from a block less than 100 blocks prior to the spend. Note that transparent outputs of coinbase transactions include Founders’ Reward outputs and transparent funding stream outputs. * [x] **TCR:bad-txns-spend-of-genesis-output** A transaction MUST NOT spend an output of the genesis block coinbase transaction. (There is one such zero-valued output, on each of Testnet and Mainnet.) * [x] **TCR:bad-tx-expiry-height-too-high-prenu5** [Overwinter to Canopy inclusive, pre-NU5] nExpiryHeight MUST be less than or equal to 499999999. * [x] **TCR:bad-tx-expiry-height-too-high-postnu5** [NU5 onward] nExpiryHeight MUST be less than or equal to 499999999 for non-coinbase transactions. * [x] **TCR:tx-overwinter-expired** [Overwinter onward] If a transaction is not a coinbase transaction and its nExpiryHeight field is nonzero, then it MUST NOT be mined at a block height greater than its nExpiryHeight. * [x] **TCR:bad-cb-expiryheight** [NU5 onward] The nExpiryHeight field of a coinbase transaction MUST be equal to its block height. * [x] **TCR:bad-txns-valuebalance-toolarge-sapling** [Sapling onward] valueBalanceSapling MUST be in the range {−MAX_MONEY .. MAX_MONEY}. * [x] **TCR:bad-txns-valuebalance-toolarge-orchard** [NU5 onward] valueBalanceOrchard MUST be in the range {−MAX_MONEY .. MAX_MONEY} for version 5 transactions. * [x] **TCR:bad-cb-output-decryption** [Heartwood onward] All Sapling and Orchard outputs in coinbase transactions MUST decrypt to a note plaintext, i.e. the procedure in § 4.19.3 ‘Decryption using a Full Viewing Key (Sapling and Orchard)’ on p. 66 does not return ⊥, using a sequence of 32 zero bytes as the outgoing viewing key. (This implies that before Canopy activation, Sapling outputs of a coinbase transaction MUST have note plaintext lead byte equal to 0x01.) * [ ] **TCR:bad-cb-output-decryption-canopy** [Canopy onward] Any Sapling or Orchard output of a coinbase transaction decrypted to a note plaintext according to the preceding rule MUST have note plaintext lead byte equal to 0x02. (This applies even during the “grace period” specified in [ZIP-212].) * TODO: The code for Sapling appears to allow 0x01 lead bytes during the grace period? https://github.com/zcash/zips/issues/630 * [ ] TODO: Other rules inherited from Bitcoin. * [ ] **TCR:bad-txns-inputs-duplicate** Within a transaction, every non-null prevout MUST point to a unique UTXO. * TODO: wording * TODO: is this a (partial) duplicate of TCR:bad-txns-inputs-missingorspent? * [ ] **TCR:bad-txns-fee-negative** * [ ] **TCR:bad-txns-fee-outofrange** Misc shielded rules * A nullifier MUST NOT repeat either within a transaction, or across transactions in a valid block chain. Sprout and Sapling and Orchard nullifiers are considered disjoint, even if they have the same bit pattern. * [x] **TCR:bad-joinsplits-nullifiers-duplicate** * [x] **TCR:bad-spend-description-nullifiers-duplicate** * [x] **TCR:bad-orchard-nullifiers-duplicate** * [ ] **TCR:bad-txns-sprout-duplicate-nullifier** * [ ] **TCR:bad-txns-sapling-duplicate-nullifier** * [ ] **TCR:bad-txns-orchard-duplicate-nullifier** * TODO: Make sure to label the place where the nullifiers are inserted * Unknown anchors * [ ] **JCR:bad-txns-sprout-unknown-anchor** * [ ] **SCR:bad-txns-sapling-unknown-anchor** * [ ] **ACR:bad-txns-orchard-unknown-anchor** Spend Description consensus rules * [x] **SCR:cv-not-small-order** $\mathsf{cv}$ MUST NOT be of small order, i.e. $[h_\mathbb{J}] \mathsf{cv}$ MUST NOT be $\mathcal{O}_\mathbb{J}$. * [x] **SCR:rk-not-small-order** $\mathsf{rk}$ MUST NOT be of small order, i.e. $[h_\mathbb{J}] \mathsf{rk}$ MUST NOT be $\mathcal{O}_\mathbb{J}$. * [x] **SCR:invalid-proof** The proof $\pi_\mathsf{ZKSpend}$ MUST be valid given a primary input formed from the other fields except spendAuthSig — i.e. $\mathsf{ZKSpend.Verify}(︀(\mathsf{cv}, \mathsf{rt^{Sapling}}, \mathsf{nf}, \mathsf{rk}), \pi_\mathsf{ZKSpend})︀ = 1$. * [x] **SCR:sapling-spend-auth-signature-invalid** Let $\mathsf{SigHash}$ be the SIGHASH transaction hash of this transaction, not associated with an input, as defined in § 4.10 ‘SIGHASH Transaction Hashing’ using SIGHASH_ALL. The spend authorization signature MUST be a valid \mathsf{SpendAuthSig^{Sapling}}$ signature over $\mathsf{SigHash}$ using $\mathsf{rk}$ as the validating key — i.e. $\mathsf{SpendAuthSig^{Sapling}.Validate_{rk}}(\mathsf{SigHash}, spendAuthSig) = 1$. Output Description consensus rules * [x] **OCR:cv-not-small-order** $\mathsf{cv}$ MUST NOT be of small order, i.e. $[h_\mathbb{J}] \mathsf{cv}$ MUST NOT be $\mathcal{O}_\mathbb{J}$. * [x] **OCR:epk-not-small-order** $\mathsf{epk}$ MUST NOT be of small order, i.e. $[h_\mathbb{J}] \mathsf{epk}$ MUST NOT be $\mathcal{O}_\mathbb{J}$. * [x] **OCR:invalid-proof** The proof $\pi_\mathsf{ZKOutput}$ MUST be valid given a primary input formed from the other fields except $\mathsf{C^{enc}}$ and $\mathsf{C^{out}}$ — i.e. $\mathsf{ZKOutput.Verify}(︀(\mathsf{cv}, \mathsf{cm}_u, \mathsf{epk}), \pi_\mathsf{ZKOutput})︀ = 1$. Action Description consensus rules * [ ] **ACR:orchard-spend-auth-signature-invalid** Let $\mathsf{SigHash}$ be the SIGHASH transaction hash of this transaction, not associated with an input, as defined in § 4.10 ‘SIGHASH Transaction Hashing’ using SIGHASH_ALL. The spend authorization signature MUST be a valid SpendAuthSig Orchard signature over SigHash using $\mathsf{rk}$ as the validating key — i.e. $\mathsf{SpendAuthSig^{Orchard}.Validate_{rk}}(\mathsf{SigHash}, spendAuthSig) = 1$. As specified in § 5.4.7 ‘RedDSA, RedJubjub, and RedPallas’, validation of the R component of the signature prohibits non-canonical encodings. * [ ] **ACR:invalid-proof** The proof $π$ MUST be valid given a primary input $(\mathsf{cv}, \mathsf{rt^{Orchard}}, \mathsf{nf}, \mathsf{rk}, \mathsf{cm}_x, enableSpends, enableOutputs)$ — i.e. $\mathsf{ZKAction.Verify}((\mathsf{cv}, \mathsf{rt^{Orchard}}, \mathsf{nf}, \mathsf{rk}, \mathsf{cm}_x, enableSpends, enableOutputs), π) = 1$.