diff --git a/README.md b/README.md index 77a7f089cab..9b3d6853c72 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ This release also implements some other Zcash consensus rules, to check that Zebra's [validation architecture](#architecture) supports future work on a full validating node: - block and transaction structure -- checkpoint-based verification up to Canopy +- checkpoint-based verification up to and including Canopy activation - transaction validation (incomplete) - transaction cryptography (incomplete) - transaction scripts (incomplete) diff --git a/book/src/dev/rfcs/0005-state-updates.md b/book/src/dev/rfcs/0005-state-updates.md index e169a33d5cd..cd5c41021f6 100644 --- a/book/src/dev/rfcs/0005-state-updates.md +++ b/book/src/dev/rfcs/0005-state-updates.md @@ -420,7 +420,7 @@ chain and updates all side chains to match. Commit `block` to the non-finalized state. -1. If the block is a pre-Canopy block, panic. +1. If the block is a pre-Canopy block, or the canopy activation block, panic. 2. If any chains tip hash equal `block.header.previous_block_hash` remove that chain from `self.chain_set` diff --git a/book/src/dev/zebra-checkpoints.md b/book/src/dev/zebra-checkpoints.md index 57b364c9342..b941c7451fa 100644 --- a/book/src/dev/zebra-checkpoints.md +++ b/book/src/dev/zebra-checkpoints.md @@ -3,6 +3,6 @@ `zebra-checkpoints` uses a local `zcashd` instance to generate a list of checkpoints for Zebra's checkpoint verifier. Developers should run this tool every few months to add new checkpoints for the `checkpoint_sync = true` mode. -(By default, Zebra syncs up to Canopy using checkpoints. These checkpoints don't need to be updated.) +(By default, Zebra syncs to Canopy activation using checkpoints. These checkpoints don't need to be updated.) For more information on how to run this program visit [Zebra checkpoints document](https://github.com/ZcashFoundation/zebra/tree/main/zebra-consensus/src/checkpoint/README.md) diff --git a/zebra-chain/src/block/commitment.rs b/zebra-chain/src/block/commitment.rs index 7d01a95bc2c..7fc1f21c788 100644 --- a/zebra-chain/src/block/commitment.rs +++ b/zebra-chain/src/block/commitment.rs @@ -63,6 +63,13 @@ pub enum Commitment { /// chain history hash in their activation block, via the previous block /// hash field.) /// + /// Since Zebra's mandatory checkpoint includes Canopy activation, we only + /// need to verify the chain history root from `Canopy + 1 block` onwards, + /// using a new history tree based on the `Canopy` activation block. + /// + /// NU5 and later upgrades use the [`ChainHistoryBlockTxAuthCommitment`] + /// variant. + /// /// TODO: this field is verified during contextual verification ChainHistoryRoot(ChainHistoryMmrRootHash), @@ -71,8 +78,10 @@ pub enum Commitment { /// - the auth data merkle tree covering this block. /// /// The chain history Merkle Mountain Range tree commits to the previous - /// block and all ancestors in the current network upgrade. The auth data - /// merkle tree commits to this block. + /// block and all ancestors in the current network upgrade. (A new chain + /// history tree starts from each network upgrade's activation block.) + /// + /// The auth data merkle tree commits to this block. /// /// This commitment supports the FlyClient protocol and non-malleable /// transaction IDs. See ZIP-221 and ZIP-244 for details. diff --git a/zebra-consensus/src/checkpoint/README.md b/zebra-consensus/src/checkpoint/README.md index 402d2445576..9da8a77699f 100644 --- a/zebra-consensus/src/checkpoint/README.md +++ b/zebra-consensus/src/checkpoint/README.md @@ -1,15 +1,16 @@ # Zebra checkpoints -Zebra validates pre-Canopy blocks using a list of `Mainnet` and `Testnet` block hash checkpoints: +Zebra validates pre-Canopy blocks, and the Canopy activation block, using a list of `Mainnet` and `Testnet` block hash checkpoints: - [Mainnet checkpoints](https://github.com/ZcashFoundation/zebra/blob/main/zebra-consensus/src/checkpoint/main-checkpoints.txt) - [Testnet checkpoints](https://github.com/ZcashFoundation/zebra/blob/main/zebra-consensus/src/checkpoint/test-checkpoints.txt) -Zebra can also be configured to use these checkpoints after Canopy: +Zebra can also be configured to use these checkpoints after Canopy activation: ``` [consensus] checkpoint_sync = true ``` + ## Update checkpoints Checkpoint lists are distributed with Zebra, maintainers should update them about every few months to get newer hashes. Here we explain how this process is done. @@ -27,7 +28,7 @@ It is easier if `zcash-cli` is in your execution path however you can specify th Lets pretend `106474` is the last height from the mainnet list, to get the next ones we will run: ``` -$ ../target/release/zebra-checkpoints -l 106474 +$ ../target/release/zebra-checkpoints -l 106474 106517 00000000659a1034bcbf7abafced7db1d413244bd2d02fceb6f6100b93925c9d 106556 000000000321575aa7d91c0db15413ad47451a9d185ccb43927acabeff715f6d 106604 00000000293cea40c781a3c8a23d45ae53aa6f18739d310e03bd745f7ec71b14 @@ -40,7 +41,7 @@ $ ../target/release/zebra-checkpoints -l 106474 107037 000000006ad5ccc970853e8b96fe5351fcf8c9428e7c3bf6376b1edbe115db37 107088 000000005d71664dc23bcc71482b773de106c46b6ade43eb9618126308a91618 107149 000000002adb0de730ec66e120f8b77b9f8d05989b7a305a0c7e42b7f1db202a -... +... ``` If we are looking to update the testnet hashes we must make sure the cli is connected with a testnet chain. If we have our `zcashd` running locally we can make this by starting with `zcashd -testnet`. @@ -61,5 +62,5 @@ $ ../target/release/zebra-checkpoints -- -testnet ``` ### Submit new hashes as pull request -- If you started from a block different than the genesis append the obtained list of hashes at the end of the existing files. If you started from genesis you can replace the entire list files. -- Open a pull request with the updated lists into the zebra `main` branch. +- If you started from a block different than the genesis append the obtained list of hashes at the end of the existing files. If you started from genesis you can replace the entire list files. +- Open a pull request with the updated lists into the zebra `main` branch. diff --git a/zebra-consensus/src/checkpoint/list/tests.rs b/zebra-consensus/src/checkpoint/list/tests.rs index fa19a6294f9..8116a376321 100644 --- a/zebra-consensus/src/checkpoint/list/tests.rs +++ b/zebra-consensus/src/checkpoint/list/tests.rs @@ -250,7 +250,8 @@ fn checkpoint_list_hard_coded_canopy_testnet() -> Result<(), BoxError> { checkpoint_list_hard_coded_canopy(Testnet) } -/// Check that the hard-coded lists cover the Canopy network upgrade +/// Check that the hard-coded lists cover the Canopy network upgrade, and the +/// Canopy activation block fn checkpoint_list_hard_coded_canopy(network: Network) -> Result<(), BoxError> { zebra_test::init(); @@ -262,7 +263,7 @@ fn checkpoint_list_hard_coded_canopy(network: Network) -> Result<(), BoxError> { assert!( list.max_height() >= canopy_activation, - "Pre-Canopy blocks must be verified by checkpoints" + "Pre-Canopy blocks and the Canopy activation block must be verified by checkpoints" ); Ok(()) diff --git a/zebra-consensus/src/config.rs b/zebra-consensus/src/config.rs index 0ad6ac8f75a..ba03da9935b 100644 --- a/zebra-consensus/src/config.rs +++ b/zebra-consensus/src/config.rs @@ -7,7 +7,7 @@ pub struct Config { /// Should Zebra sync using checkpoints? /// /// Setting this option to true enables post-Canopy checkpoints. - /// (Zebra always checkpoints on Canopy activation.) + /// (Zebra always checkpoints up to and including Canopy activation.) /// /// Future versions of Zebra may change the mandatory checkpoint /// height. diff --git a/zebra-state/src/service/non_finalized_state.rs b/zebra-state/src/service/non_finalized_state.rs index 5e695b067b4..0de26391799 100644 --- a/zebra-state/src/service/non_finalized_state.rs +++ b/zebra-state/src/service/non_finalized_state.rs @@ -81,9 +81,9 @@ impl NonFinalizedState { let (height, hash) = (prepared.height, prepared.hash); let canopy_activation_height = Canopy.activation_height(self.network).unwrap(); - if height < canopy_activation_height { + if height <= canopy_activation_height { panic!( - "invalid non-finalized block height: the canopy checkpoint is mandatory, pre-canopy blocks must be committed to the state as finalized blocks" + "invalid non-finalized block height: the canopy checkpoint is mandatory, pre-canopy blocks, and the canopy activation block, must be committed to the state as finalized blocks" ); }