Make sure the mandatory checkpoint includes Canopy activation (#2235)

* Make sure the Canopy activation block is a finalized checkpoint block

This enables ZIP-221 chain history from Canopy activation onwards.

* Clarify that the mandatory checkpoint test includes Canopy activation

The test was correct, but the docs and assertion message did not include activation.

* Document that the mandatory checkpoint includes Canopy activation

Co-authored-by: teor <teor@riseup.net>
This commit is contained in:
Alfredo Garcia 2021-06-02 21:24:08 -03:00 committed by GitHub
parent 81f2df9f36
commit a9fe0d9d3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 27 additions and 16 deletions

View File

@ -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 Zebra's [validation architecture](#architecture) supports future work on a
full validating node: full validating node:
- block and transaction structure - block and transaction structure
- checkpoint-based verification up to Canopy - checkpoint-based verification up to and including Canopy activation
- transaction validation (incomplete) - transaction validation (incomplete)
- transaction cryptography (incomplete) - transaction cryptography (incomplete)
- transaction scripts (incomplete) - transaction scripts (incomplete)

View File

@ -420,7 +420,7 @@ chain and updates all side chains to match.
Commit `block` to the non-finalized state. 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` 2. If any chains tip hash equal `block.header.previous_block_hash` remove that chain from `self.chain_set`

View File

@ -3,6 +3,6 @@
`zebra-checkpoints` uses a local `zcashd` instance to generate a list of checkpoints for Zebra's checkpoint verifier. `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. 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) 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)

View File

@ -63,6 +63,13 @@ pub enum Commitment {
/// chain history hash in their activation block, via the previous block /// chain history hash in their activation block, via the previous block
/// hash field.) /// 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 /// TODO: this field is verified during contextual verification
ChainHistoryRoot(ChainHistoryMmrRootHash), ChainHistoryRoot(ChainHistoryMmrRootHash),
@ -71,8 +78,10 @@ pub enum Commitment {
/// - the auth data merkle tree covering this block. /// - the auth data merkle tree covering this block.
/// ///
/// The chain history Merkle Mountain Range tree commits to the previous /// The chain history Merkle Mountain Range tree commits to the previous
/// block and all ancestors in the current network upgrade. The auth data /// block and all ancestors in the current network upgrade. (A new chain
/// merkle tree commits to this block. /// 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 /// This commitment supports the FlyClient protocol and non-malleable
/// transaction IDs. See ZIP-221 and ZIP-244 for details. /// transaction IDs. See ZIP-221 and ZIP-244 for details.

View File

@ -1,15 +1,16 @@
# Zebra checkpoints # 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) - [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) - [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] [consensus]
checkpoint_sync = true checkpoint_sync = true
``` ```
## Update checkpoints ## 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. 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: 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 106517 00000000659a1034bcbf7abafced7db1d413244bd2d02fceb6f6100b93925c9d
106556 000000000321575aa7d91c0db15413ad47451a9d185ccb43927acabeff715f6d 106556 000000000321575aa7d91c0db15413ad47451a9d185ccb43927acabeff715f6d
106604 00000000293cea40c781a3c8a23d45ae53aa6f18739d310e03bd745f7ec71b14 106604 00000000293cea40c781a3c8a23d45ae53aa6f18739d310e03bd745f7ec71b14
@ -40,7 +41,7 @@ $ ../target/release/zebra-checkpoints -l 106474
107037 000000006ad5ccc970853e8b96fe5351fcf8c9428e7c3bf6376b1edbe115db37 107037 000000006ad5ccc970853e8b96fe5351fcf8c9428e7c3bf6376b1edbe115db37
107088 000000005d71664dc23bcc71482b773de106c46b6ade43eb9618126308a91618 107088 000000005d71664dc23bcc71482b773de106c46b6ade43eb9618126308a91618
107149 000000002adb0de730ec66e120f8b77b9f8d05989b7a305a0c7e42b7f1db202a 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`. 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 ### 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. - 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. - Open a pull request with the updated lists into the zebra `main` branch.

View File

@ -250,7 +250,8 @@ fn checkpoint_list_hard_coded_canopy_testnet() -> Result<(), BoxError> {
checkpoint_list_hard_coded_canopy(Testnet) 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> { fn checkpoint_list_hard_coded_canopy(network: Network) -> Result<(), BoxError> {
zebra_test::init(); zebra_test::init();
@ -262,7 +263,7 @@ fn checkpoint_list_hard_coded_canopy(network: Network) -> Result<(), BoxError> {
assert!( assert!(
list.max_height() >= canopy_activation, 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(()) Ok(())

View File

@ -7,7 +7,7 @@ pub struct Config {
/// Should Zebra sync using checkpoints? /// Should Zebra sync using checkpoints?
/// ///
/// Setting this option to true enables post-Canopy 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 /// Future versions of Zebra may change the mandatory checkpoint
/// height. /// height.

View File

@ -81,9 +81,9 @@ impl NonFinalizedState {
let (height, hash) = (prepared.height, prepared.hash); let (height, hash) = (prepared.height, prepared.hash);
let canopy_activation_height = Canopy.activation_height(self.network).unwrap(); let canopy_activation_height = Canopy.activation_height(self.network).unwrap();
if height < canopy_activation_height { if height <= canopy_activation_height {
panic!( 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"
); );
} }