Add and use a function for mandatory checkpoint (#2314)
* add `mandatory_checkpoint_height()` function * use mandatory checkpoint instead of canopy in acceptance tests
This commit is contained in:
parent
1cb10ec9e7
commit
544d182d25
|
@ -65,8 +65,8 @@ jobs:
|
|||
"git clone -b $BRANCH_NAME https://github.com/ZcashFoundation/zebra.git;
|
||||
cd zebra/;
|
||||
docker build --build-arg SHORT_SHA=$SHORT_SHA -f docker/Dockerfile.test -t zebrad-test .;
|
||||
docker run -i --mount type=bind,source=/mnt/disks/gce-containers-mounts/gce-persistent-disks/zebrad-cache-$SHORT_SHA-mainnet-1046400,target=/zebrad-cache zebrad-test:latest cargo test --verbose --features test_sync_past_canopy_mainnet --manifest-path zebrad/Cargo.toml sync_past_canopy_mainnet;
|
||||
docker run -i --mount type=bind,source=/mnt/disks/gce-containers-mounts/gce-persistent-disks/zebrad-cache-$SHORT_SHA-testnet-1028500,target=/zebrad-cache zebrad-test:latest cargo test --verbose --features test_sync_past_canopy_testnet --manifest-path zebrad/Cargo.toml sync_past_canopy_testnet;
|
||||
docker run -i --mount type=bind,source=/mnt/disks/gce-containers-mounts/gce-persistent-disks/zebrad-cache-$SHORT_SHA-mainnet-1046400,target=/zebrad-cache zebrad-test:latest cargo test --verbose --features test_sync_past_mandatory_checkpoint_mainnet --manifest-path zebrad/Cargo.toml sync_past_canopy_mainnet;
|
||||
docker run -i --mount type=bind,source=/mnt/disks/gce-containers-mounts/gce-persistent-disks/zebrad-cache-$SHORT_SHA-testnet-1028500,target=/zebrad-cache zebrad-test:latest cargo test --verbose --features test_sync_past_mandatory_checkpoint_testnet --manifest-path zebrad/Cargo.toml sync_past_canopy_testnet;
|
||||
"
|
||||
# Clean up
|
||||
- name: Delete test instance
|
||||
|
|
|
@ -69,7 +69,7 @@ jobs:
|
|||
cd zebra/;
|
||||
docker build --build-arg SHORT_SHA=$SHORT_SHA -f docker/Dockerfile.test -t zebrad-test .;
|
||||
docker run -i zebrad-test cargo test --workspace --no-fail-fast -- -Zunstable-options --include-ignored;
|
||||
docker run -i --mount type=bind,source=/mnt/disks/gce-containers-mounts/gce-persistent-disks/zebrad-cache-$SHORT_SHA-mainnet-1046400,target=/zebrad-cache zebrad-test:latest cargo test --verbose --features test_sync_past_canopy_mainnet --manifest-path zebrad/Cargo.toml sync_past_canopy_mainnet;
|
||||
docker run -i --mount type=bind,source=/mnt/disks/gce-containers-mounts/gce-persistent-disks/zebrad-cache-$SHORT_SHA-mainnet-1046400,target=/zebrad-cache zebrad-test:latest cargo test --verbose --features test_sync_past_mandatory_checkpoint_mainnet --manifest-path zebrad/Cargo.toml sync_past_canopy_mainnet;
|
||||
"
|
||||
# Clean up
|
||||
- name: Delete test instance
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::{convert::From, fmt};
|
||||
|
||||
use crate::{block::Height, parameters::NetworkUpgrade::Canopy};
|
||||
|
||||
#[cfg(any(test, feature = "proptest-impl"))]
|
||||
use proptest_derive::Arbitrary;
|
||||
|
||||
|
@ -42,6 +44,18 @@ impl Network {
|
|||
Network::Testnet => 18233,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the mandatory minimum checkpoint height for this network.
|
||||
///
|
||||
/// Mandatory checkpoints are a Zebra-specific feature.
|
||||
/// If a Zcash consensus rule only applies before the mandatory checkpoint,
|
||||
/// Zebra can skip validation of that rule.
|
||||
pub fn mandatory_checkpoint_height(&self) -> Height {
|
||||
// Currently this is the Canopy activation height for both networks.
|
||||
Canopy
|
||||
.activation_height(*self)
|
||||
.expect("Canopy activation height must be present for both networks")
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Network {
|
||||
|
|
|
@ -20,7 +20,7 @@ use tracing::instrument;
|
|||
|
||||
use zebra_chain::{
|
||||
block::{self, Block},
|
||||
parameters::{Network, NetworkUpgrade::Canopy},
|
||||
parameters::Network,
|
||||
};
|
||||
|
||||
use zebra_state as zs;
|
||||
|
@ -147,7 +147,7 @@ where
|
|||
let max_checkpoint_height = if config.checkpoint_sync {
|
||||
list.max_height()
|
||||
} else {
|
||||
list.min_height_in_range(Canopy.activation_height(network).unwrap()..)
|
||||
list.min_height_in_range(network.mandatory_checkpoint_height()..)
|
||||
.expect("hardcoded checkpoint list extends past canopy activation")
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::*;
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use zebra_chain::parameters::{Network, Network::*, NetworkUpgrade::*};
|
||||
use zebra_chain::parameters::{Network, Network::*};
|
||||
use zebra_chain::{
|
||||
block::{self, Block},
|
||||
serialization::ZcashDeserialize,
|
||||
|
@ -241,29 +241,26 @@ fn checkpoint_list_load_hard_coded() -> Result<(), BoxError> {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn checkpoint_list_hard_coded_canopy_mainnet() -> Result<(), BoxError> {
|
||||
checkpoint_list_hard_coded_canopy(Mainnet)
|
||||
fn checkpoint_list_hard_coded_mandatory_mainnet() -> Result<(), BoxError> {
|
||||
checkpoint_list_hard_coded_mandatory(Mainnet)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checkpoint_list_hard_coded_canopy_testnet() -> Result<(), BoxError> {
|
||||
checkpoint_list_hard_coded_canopy(Testnet)
|
||||
fn checkpoint_list_hard_coded_mandatory_testnet() -> Result<(), BoxError> {
|
||||
checkpoint_list_hard_coded_mandatory(Testnet)
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
/// Check that the hard-coded lists cover the mandatory checkpoint
|
||||
fn checkpoint_list_hard_coded_mandatory(network: Network) -> Result<(), BoxError> {
|
||||
zebra_test::init();
|
||||
|
||||
let canopy_activation = Canopy
|
||||
.activation_height(network)
|
||||
.expect("Unexpected network upgrade info: Canopy must have an activation height");
|
||||
let mandatory_checkpoint = network.mandatory_checkpoint_height();
|
||||
|
||||
let list = CheckpointList::new(network);
|
||||
|
||||
assert!(
|
||||
list.max_height() >= canopy_activation,
|
||||
"Pre-Canopy blocks and the Canopy activation block must be verified by checkpoints"
|
||||
list.max_height() >= mandatory_checkpoint,
|
||||
"Mandatory checkpoint block must be verified by checkpoints"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::{collections::BTreeSet, mem, ops::Deref, sync::Arc};
|
|||
|
||||
use zebra_chain::{
|
||||
block::{self, Block},
|
||||
parameters::{Network, NetworkUpgrade::Canopy},
|
||||
parameters::Network,
|
||||
transaction::{self, Transaction},
|
||||
transparent,
|
||||
};
|
||||
|
@ -80,8 +80,8 @@ impl NonFinalizedState {
|
|||
let parent_hash = prepared.block.header.previous_block_hash;
|
||||
let (height, hash) = (prepared.height, prepared.hash);
|
||||
|
||||
let canopy_activation_height = Canopy.activation_height(self.network).unwrap();
|
||||
if height <= canopy_activation_height {
|
||||
let mandatory_checkpoint = self.network.mandatory_checkpoint_height();
|
||||
if height <= mandatory_checkpoint {
|
||||
panic!(
|
||||
"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"
|
||||
);
|
||||
|
|
|
@ -60,7 +60,7 @@ zebra-test = { path = "../zebra-test" }
|
|||
|
||||
[features]
|
||||
enable-sentry = []
|
||||
test_sync_to_canopy_mainnet = []
|
||||
test_sync_to_canopy_testnet = []
|
||||
test_sync_past_canopy_mainnet = []
|
||||
test_sync_past_canopy_testnet = []
|
||||
test_sync_to_mandatory_checkpoint_mainnet = []
|
||||
test_sync_to_mandatory_checkpoint_testnet = []
|
||||
test_sync_past_mandatory_checkpoint_mainnet = []
|
||||
test_sync_past_mandatory_checkpoint_testnet = []
|
||||
|
|
|
@ -28,10 +28,7 @@ use std::{collections::HashSet, convert::TryInto, env, path::Path, path::PathBuf
|
|||
|
||||
use zebra_chain::{
|
||||
block::Height,
|
||||
parameters::{
|
||||
Network::{self, *},
|
||||
NetworkUpgrade,
|
||||
},
|
||||
parameters::Network::{self, *},
|
||||
};
|
||||
use zebra_network::constants::PORT_IN_USE_ERROR;
|
||||
use zebra_state::constants::LOCK_FILE_ERROR;
|
||||
|
@ -835,7 +832,7 @@ fn sync_until(
|
|||
Ok(child.dir)
|
||||
}
|
||||
|
||||
fn cached_canopy_test_config() -> Result<ZebradConfig> {
|
||||
fn cached_mandatory_checkpoint_test_config() -> Result<ZebradConfig> {
|
||||
let mut config = persistent_test_config()?;
|
||||
config.consensus.checkpoint_sync = true;
|
||||
config.state.cache_dir = "/zebrad-cache".into();
|
||||
|
@ -848,7 +845,7 @@ fn create_cached_database_height(network: Network, height: Height) -> Result<()>
|
|||
let timeout = Duration::from_secs(60 * 60 * 8);
|
||||
|
||||
// Use a persistent state, so we can handle large syncs
|
||||
let mut config = cached_canopy_test_config()?;
|
||||
let mut config = cached_mandatory_checkpoint_test_config()?;
|
||||
// TODO: add convenience methods?
|
||||
config.network.network = network;
|
||||
config.state.debug_stop_at_height = Some(height.0);
|
||||
|
@ -869,12 +866,12 @@ fn create_cached_database_height(network: Network, height: Height) -> Result<()>
|
|||
}
|
||||
|
||||
fn create_cached_database(network: Network) -> Result<()> {
|
||||
let height = NetworkUpgrade::Canopy.activation_height(network).unwrap();
|
||||
let height = network.mandatory_checkpoint_height();
|
||||
create_cached_database_height(network, height)
|
||||
}
|
||||
|
||||
fn sync_past_canopy(network: Network) -> Result<()> {
|
||||
let height = NetworkUpgrade::Canopy.activation_height(network).unwrap() + 1200;
|
||||
fn sync_past_mandatory_checkpoint(network: Network) -> Result<()> {
|
||||
let height = network.mandatory_checkpoint_height() + 1200;
|
||||
create_cached_database_height(network, height.unwrap())
|
||||
}
|
||||
|
||||
|
@ -885,48 +882,48 @@ fn sync_past_canopy(network: Network) -> Result<()> {
|
|||
// drives populated by the first two tests, snapshot those drives, and then use
|
||||
// those to more quickly run the second two tests.
|
||||
|
||||
/// Sync up to the canopy activation height on mainnet and stop.
|
||||
/// Sync up to the mandatory checkpoint height on mainnet and stop.
|
||||
#[allow(dead_code)]
|
||||
#[cfg_attr(feature = "test_sync_to_canopy_mainnet", test)]
|
||||
fn sync_to_canopy_mainnet() {
|
||||
#[cfg_attr(feature = "test_sync_to_mandatory_checkpoint_mainnet", test)]
|
||||
fn sync_to_mandatory_checkpoint_mainnet() {
|
||||
zebra_test::init();
|
||||
let network = Mainnet;
|
||||
create_cached_database(network).unwrap();
|
||||
}
|
||||
|
||||
/// Sync to the canopy activation height testnet and stop.
|
||||
/// Sync to the mandatory checkpoint height testnet and stop.
|
||||
#[allow(dead_code)]
|
||||
#[cfg_attr(feature = "test_sync_to_canopy_testnet", test)]
|
||||
fn sync_to_canopy_testnet() {
|
||||
#[cfg_attr(feature = "test_sync_to_mandatory_checkpoint_testnet", test)]
|
||||
fn sync_to_mandatory_checkpoint_testnet() {
|
||||
zebra_test::init();
|
||||
let network = Testnet;
|
||||
create_cached_database(network).unwrap();
|
||||
}
|
||||
|
||||
/// Test syncing 1200 blocks (3 checkpoints) past the last checkpoint on mainnet.
|
||||
/// Test syncing 1200 blocks (3 checkpoints) past the mandatory checkpoint on mainnet.
|
||||
///
|
||||
/// This assumes that the config'd state is already synced at or near Canopy
|
||||
/// activation on mainnet. If the state has already synced past Canopy
|
||||
/// This assumes that the config'd state is already synced at or near the mandatory checkpoint
|
||||
/// activation on mainnet. If the state has already synced past the mandatory checkpoint
|
||||
/// activation by 1200 blocks, it will fail.
|
||||
#[allow(dead_code)]
|
||||
#[cfg_attr(feature = "test_sync_past_canopy_mainnet", test)]
|
||||
fn sync_past_canopy_mainnet() {
|
||||
#[cfg_attr(feature = "test_sync_past_mandatory_checkpoint_mainnet", test)]
|
||||
fn sync_past_mandatory_checkpoint_mainnet() {
|
||||
zebra_test::init();
|
||||
let network = Mainnet;
|
||||
sync_past_canopy(network).unwrap();
|
||||
sync_past_mandatory_checkpoint(network).unwrap();
|
||||
}
|
||||
|
||||
/// Test syncing 1200 blocks (3 checkpoints) past the last checkpoint on testnet.
|
||||
/// Test syncing 1200 blocks (3 checkpoints) past the mandatory checkpoint on testnet.
|
||||
///
|
||||
/// This assumes that the config'd state is already synced at or near Canopy
|
||||
/// activation on testnet. If the state has already synced past Canopy
|
||||
/// This assumes that the config'd state is already synced at or near the mandatory checkpoint
|
||||
/// activation on testnet. If the state has already synced past the mandatory checkpoint
|
||||
/// activation by 1200 blocks, it will fail.
|
||||
#[allow(dead_code)]
|
||||
#[cfg_attr(feature = "test_sync_past_canopy_testnet", test)]
|
||||
fn sync_past_canopy_testnet() {
|
||||
#[cfg_attr(feature = "test_sync_past_mandatory_checkpoint_testnet", test)]
|
||||
fn sync_past_mandatory_checkpoint_testnet() {
|
||||
zebra_test::init();
|
||||
let network = Testnet;
|
||||
sync_past_canopy(network).unwrap();
|
||||
sync_past_mandatory_checkpoint(network).unwrap();
|
||||
}
|
||||
|
||||
/// Returns a random port number from the ephemeral port range.
|
||||
|
|
Loading…
Reference in New Issue