From 78fff82bf59038987fe30c76cf9e2bdd7c4660f0 Mon Sep 17 00:00:00 2001 From: Arya Date: Wed, 19 Jun 2024 19:55:42 -0400 Subject: [PATCH] Lowers the mandatory checkpoint height to the block before Canopy activation --- zebra-chain/src/parameters/network.rs | 65 ++----------------- .../src/parameters/network/tests/prop.rs | 23 +++---- 2 files changed, 15 insertions(+), 73 deletions(-) diff --git a/zebra-chain/src/parameters/network.rs b/zebra-chain/src/parameters/network.rs index 054fb76f450..b727c6e551f 100644 --- a/zebra-chain/src/parameters/network.rs +++ b/zebra-chain/src/parameters/network.rs @@ -5,7 +5,7 @@ use std::{fmt, str::FromStr, sync::Arc}; use thiserror::Error; use crate::{ - block::{self, Height, HeightDiff}, + block::{self, Height}, parameters::NetworkUpgrade, }; @@ -15,42 +15,6 @@ pub mod testnet; #[cfg(test)] mod tests; -/// The ZIP-212 grace period length after the Canopy activation height. -/// -/// # Consensus -/// -/// ZIP-212 requires Zcash nodes to validate that Sapling spends and Orchard actions follows a -/// specific plaintext format after Canopy's activation. -/// -/// > [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. 67 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.) -/// -/// > [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].) -/// -/// -/// -/// Wallets have a grace period of 32,256 blocks after Canopy's activation to validate those blocks, -/// but nodes do not. -/// -/// > There is a "grace period" of 32256 blocks starting from the block at which this ZIP activates, -/// > during which note plaintexts with lead byte 0x01 MUST still be accepted [by wallets]. -/// > -/// > Let ActivationHeight be the activation height of this ZIP, and let GracePeriodEndHeight be -/// > ActivationHeight + 32256. -/// -/// -/// -/// Zebra uses `librustzcash` to validate that rule, but it won't validate it during the grace -/// period. Therefore Zebra must validate those blocks during the grace period using checkpoints. -/// Therefore the mandatory checkpoint height ([`Network::mandatory_checkpoint_height`]) must be -/// after the grace period. -const ZIP_212_GRACE_PERIOD_DURATION: HeightDiff = 32_256; - /// An enum describing the kind of network, whether it's the production mainnet or a testnet. // Note: The order of these variants is important for correct bincode (de)serialization // of history trees in the db format. @@ -235,33 +199,16 @@ impl Network { /// If a Zcash consensus rule only applies before the mandatory checkpoint, /// Zebra can skip validation of that rule. /// - /// ZIP-212 grace period is only applied to default networks. // TODO: // - Support constructing pre-Canopy coinbase tx and block templates and return `Height::MAX` instead of panicking // when Canopy activation height is `None` (#8434) - // - Add semantic block validation during the ZIP-212 grace period and update this method to always apply the ZIP-212 grace period pub fn mandatory_checkpoint_height(&self) -> Height { - // Currently this is after the ZIP-212 grace period. - // - // See the `ZIP_212_GRACE_PERIOD_DURATION` documentation for more information. - - let canopy_activation = NetworkUpgrade::Canopy + // Currently this is just before Canopy activation + NetworkUpgrade::Canopy .activation_height(self) - .expect("Canopy activation height must be present for both networks"); - - let is_a_default_network = match self { - Network::Mainnet => true, - Network::Testnet(params) => params.is_default_testnet(), - }; - - if is_a_default_network { - (canopy_activation + ZIP_212_GRACE_PERIOD_DURATION) - .expect("ZIP-212 grace period ends at a valid block height") - } else { - canopy_activation - .previous() - .expect("Canopy activation must be above Genesis height") - } + .expect("Canopy activation height must be present on all networks") + .previous() + .expect("Canopy activation height must be above min height") } /// Return the network name as defined in diff --git a/zebra-chain/src/parameters/network/tests/prop.rs b/zebra-chain/src/parameters/network/tests/prop.rs index c2b1e31e03f..3fd8b945685 100644 --- a/zebra-chain/src/parameters/network/tests/prop.rs +++ b/zebra-chain/src/parameters/network/tests/prop.rs @@ -1,32 +1,27 @@ use proptest::prelude::*; -use super::super::{Network, ZIP_212_GRACE_PERIOD_DURATION}; +use super::super::Network; use crate::{ block::Height, parameters::{NetworkUpgrade, TESTNET_MAX_TIME_START_HEIGHT}, }; proptest! { - /// Check that the mandatory checkpoint is after the ZIP-212 grace period. + /// Check that the mandatory checkpoint is immediately before Canopy activation. /// - /// This is necessary because Zebra can't fully validate the blocks during the grace period due - /// to a limitation of `librustzcash`. - /// - /// See [`ZIP_212_GRACE_PERIOD_DURATION`] for more information. + /// This is necessary because Zebra can't fully validate the blocks prior to Canopy. #[test] - fn mandatory_checkpoint_is_after_zip212_grace_period(network in any::()) { + fn mandatory_checkpoint_is_after_canopy(network in any::()) { let _init_guard = zebra_test::init(); - let canopy_activation = NetworkUpgrade::Canopy + let pre_canopy_activation = NetworkUpgrade::Canopy .activation_height(&network) - .expect("Canopy activation height is set"); - - let grace_period_end_height = (canopy_activation + ZIP_212_GRACE_PERIOD_DURATION) - .expect("ZIP-212 grace period ends in a valid block height"); + .expect("Canopy activation height is set") + .previous() + .expect("Canopy activation should be above min height"); - assert!(network.mandatory_checkpoint_height() >= grace_period_end_height); + assert!(network.mandatory_checkpoint_height() >= pre_canopy_activation); } - #[test] /// Asserts that the activation height is correct for the block /// maximum time rule on Testnet is correct.