Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure the mandatory checkpoint includes Canopy activation #2235

Merged
merged 3 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion book/src/dev/rfcs/0005-state-updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down
2 changes: 1 addition & 1 deletion book/src/dev/zebra-checkpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
13 changes: 11 additions & 2 deletions zebra-chain/src/block/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),

Expand All @@ -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.
Expand Down
13 changes: 7 additions & 6 deletions zebra-consensus/src/checkpoint/README.md
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
Expand All @@ -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`.
Expand All @@ -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.
5 changes: 3 additions & 2 deletions zebra-consensus/src/checkpoint/list/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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(())
Expand Down
2 changes: 1 addition & 1 deletion zebra-consensus/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions zebra-state/src/service/non_finalized_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
);
}

Expand Down