From 1fbe0a0a7cde57bf9413f89e188734410eaf4e01 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 12 Sep 2022 15:24:42 +1000 Subject: [PATCH 1/5] Look back 10,000 blocks on testnet for a legacy chain --- zebra-state/src/constants.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zebra-state/src/constants.rs b/zebra-state/src/constants.rs index f4cf6a431c2..cd4b2b63755 100644 --- a/zebra-state/src/constants.rs +++ b/zebra-state/src/constants.rs @@ -22,7 +22,9 @@ pub const DATABASE_FORMAT_VERSION: u32 = 25; /// The maximum number of blocks to check for NU5 transactions, /// before we assume we are on a pre-NU5 legacy chain. -pub const MAX_LEGACY_CHAIN_BLOCKS: usize = 1000; +/// +/// Zebra usually only has to check back a few blocks, but on testnet it can be a long time between v5 transactions. +pub const MAX_LEGACY_CHAIN_BLOCKS: usize = 10_000; use lazy_static::lazy_static; use regex::Regex; From 68ca962c5783607e8e4a48fb9ae70e29f0802cb2 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 12 Sep 2022 15:42:03 +1000 Subject: [PATCH 2/5] Use a smaller number of legacy chain blocks in the tests --- zebra-state/src/service.rs | 2 ++ zebra-state/src/service/check.rs | 9 +++++++-- zebra-state/src/service/tests.rs | 18 +++++++++++------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/zebra-state/src/service.rs b/zebra-state/src/service.rs index 7740fdda39d..3f45a845096 100644 --- a/zebra-state/src/service.rs +++ b/zebra-state/src/service.rs @@ -40,6 +40,7 @@ use zebra_chain::{ }; use crate::{ + constants::MAX_LEGACY_CHAIN_BLOCKS, service::{ chain_tip::{ChainTipBlock, ChainTipChange, ChainTipSender, LatestChainTip}, finalized_state::{FinalizedState, ZebraDb}, @@ -214,6 +215,7 @@ impl StateService { nu5_activation_height, state.any_ancestor_blocks(tip.1), state.network, + MAX_LEGACY_CHAIN_BLOCKS, ) { let legacy_db_path = state.disk.path().to_path_buf(); panic!( diff --git a/zebra-state/src/service/check.rs b/zebra-state/src/service/check.rs index aeb7b8281b5..24f9b099d27 100644 --- a/zebra-state/src/service/check.rs +++ b/zebra-state/src/service/check.rs @@ -12,7 +12,7 @@ use zebra_chain::{ work::difficulty::CompactDifficulty, }; -use crate::{constants, BoxError, PreparedBlock, ValidateContextError}; +use crate::{BoxError, PreparedBlock, ValidateContextError}; // use self as check use super::check; @@ -289,10 +289,15 @@ fn difficulty_threshold_is_valid( } /// Check if zebra is following a legacy chain and return an error if so. +/// +/// `nu5_activation_height` should be `NetworkUpgrade::Nu5.activation_height(network)`, and +/// `max_legacy_chain_blocks` should be [`MAX_LEGACY_CHAIN_BLOCKS`](crate::constants::MAX_LEGACY_CHAIN_BLOCKS). +/// They are only used for testing. pub(crate) fn legacy_chain( nu5_activation_height: block::Height, ancestors: I, network: Network, + max_legacy_chain_blocks: usize, ) -> Result<(), BoxError> where I: Iterator>, @@ -316,7 +321,7 @@ where // If we are past our NU5 activation height, but there are no V5 transactions in recent blocks, // the Zebra instance that verified those blocks had no NU5 activation height. - if index >= constants::MAX_LEGACY_CHAIN_BLOCKS { + if index >= max_legacy_chain_blocks { return Err(format!( "could not find any transactions in recent blocks: \ checked {index} blocks back from {:?}", diff --git a/zebra-state/src/service/tests.rs b/zebra-state/src/service/tests.rs index 4b9e47fd87f..0babfbb2898 100644 --- a/zebra-state/src/service/tests.rs +++ b/zebra-state/src/service/tests.rs @@ -20,7 +20,7 @@ use zebra_test::{prelude::*, transcript::Transcript}; use crate::{ arbitrary::Prepare, - constants::{self, MAX_LEGACY_CHAIN_BLOCKS}, + constants::MAX_LEGACY_CHAIN_BLOCKS, init_test, service::{arbitrary::populated_state, chain_tip::TipAction, StateService}, tests::setup::{partial_nu5_chain_strategy, transaction_v4_from_coinbase}, @@ -277,11 +277,14 @@ fn state_behaves_when_blocks_are_committed_in_order() -> Result<()> { const DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES: u32 = 2; +/// The legacy chain limit for tests. +const TEST_LEGACY_CHAIN_LIMIT: usize = 100; + /// Check more blocks than the legacy chain limit. -const OVER_LEGACY_CHAIN_LIMIT: u32 = constants::MAX_LEGACY_CHAIN_BLOCKS as u32 + 10; +const OVER_LEGACY_CHAIN_LIMIT: u32 = TEST_LEGACY_CHAIN_LIMIT as u32 + 10; /// Check fewer blocks than the legacy chain limit. -const UNDER_LEGACY_CHAIN_LIMIT: u32 = constants::MAX_LEGACY_CHAIN_BLOCKS as u32 - 10; +const UNDER_LEGACY_CHAIN_LIMIT: u32 = TEST_LEGACY_CHAIN_LIMIT as u32 - 10; proptest! { #![proptest_config( @@ -304,7 +307,7 @@ proptest! { fn some_block_less_than_network_upgrade( (network, nu_activation_height, chain) in partial_nu5_chain_strategy(4, true, UNDER_LEGACY_CHAIN_LIMIT, NetworkUpgrade::Canopy) ) { - let response = crate::service::check::legacy_chain(nu_activation_height, chain.into_iter().rev(), network) + let response = crate::service::check::legacy_chain(nu_activation_height, chain.into_iter().rev(), network, TEST_LEGACY_CHAIN_LIMIT) .map_err(|error| error.to_string()); prop_assert_eq!(response, Ok(())); @@ -321,7 +324,7 @@ proptest! { .coinbase_height() .expect("chain contains valid blocks"); - let response = crate::service::check::legacy_chain(nu_activation_height, chain.into_iter().rev(), network) + let response = crate::service::check::legacy_chain(nu_activation_height, chain.into_iter().rev(), network, TEST_LEGACY_CHAIN_LIMIT) .map_err(|error| error.to_string()); prop_assert_eq!( @@ -360,7 +363,8 @@ proptest! { let response = crate::service::check::legacy_chain( nu_activation_height, chain.clone().into_iter().rev(), - network + network, + TEST_LEGACY_CHAIN_LIMIT, ).map_err(|error| error.to_string()); prop_assert_eq!( @@ -377,7 +381,7 @@ proptest! { fn at_least_one_transaction_with_valid_network_upgrade( (network, nu_activation_height, chain) in partial_nu5_chain_strategy(5, true, UNDER_LEGACY_CHAIN_LIMIT, NetworkUpgrade::Canopy) ) { - let response = crate::service::check::legacy_chain(nu_activation_height, chain.into_iter().rev(), network) + let response = crate::service::check::legacy_chain(nu_activation_height, chain.into_iter().rev(), network, TEST_LEGACY_CHAIN_LIMIT) .map_err(|error| error.to_string()); prop_assert_eq!(response, Ok(())); From dda8e8700d632cfe4dbdd0e594a1f4c1ee31d607 Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 13 Sep 2022 10:28:13 +1000 Subject: [PATCH 3/5] Fix test assertion error message --- zebra-state/src/service/check.rs | 2 +- zebra-state/src/service/tests.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/zebra-state/src/service/check.rs b/zebra-state/src/service/check.rs index 24f9b099d27..25d5c98aad5 100644 --- a/zebra-state/src/service/check.rs +++ b/zebra-state/src/service/check.rs @@ -292,7 +292,7 @@ fn difficulty_threshold_is_valid( /// /// `nu5_activation_height` should be `NetworkUpgrade::Nu5.activation_height(network)`, and /// `max_legacy_chain_blocks` should be [`MAX_LEGACY_CHAIN_BLOCKS`](crate::constants::MAX_LEGACY_CHAIN_BLOCKS). -/// They are only used for testing. +/// They are only changed from the defaults for testing. pub(crate) fn legacy_chain( nu5_activation_height: block::Height, ancestors: I, diff --git a/zebra-state/src/service/tests.rs b/zebra-state/src/service/tests.rs index 0babfbb2898..b0987b48b43 100644 --- a/zebra-state/src/service/tests.rs +++ b/zebra-state/src/service/tests.rs @@ -20,7 +20,6 @@ use zebra_test::{prelude::*, transcript::Transcript}; use crate::{ arbitrary::Prepare, - constants::MAX_LEGACY_CHAIN_BLOCKS, init_test, service::{arbitrary::populated_state, chain_tip::TipAction, StateService}, tests::setup::{partial_nu5_chain_strategy, transaction_v4_from_coinbase}, @@ -330,7 +329,7 @@ proptest! { prop_assert_eq!( response, Err(format!( - "could not find any transactions in recent blocks: checked {MAX_LEGACY_CHAIN_BLOCKS} blocks back from {tip_height:?}", + "could not find any transactions in recent blocks: checked {TEST_LEGACY_CHAIN_LIMIT} blocks back from {tip_height:?}", )) ); } From 32183e2832d7d667b21ed0089ef4443c343b3f2b Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 19 Sep 2022 13:57:57 +1000 Subject: [PATCH 4/5] Clarify legacy chain check comment --- zebra-state/src/service/check.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra-state/src/service/check.rs b/zebra-state/src/service/check.rs index 25d5c98aad5..3372b588524 100644 --- a/zebra-state/src/service/check.rs +++ b/zebra-state/src/service/check.rs @@ -320,7 +320,7 @@ where } // If we are past our NU5 activation height, but there are no V5 transactions in recent blocks, - // the Zebra instance that verified those blocks had no NU5 activation height. + // the last Zebra instance that updated this cached state had no NU5 activation height. if index >= max_legacy_chain_blocks { return Err(format!( "could not find any transactions in recent blocks: \ From 9bc7a86eb6db4490ba10dd9a9e442d3816a16e38 Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 20 Sep 2022 16:04:32 +1000 Subject: [PATCH 5/5] cargo fmt --all --- zebra-state/src/service.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zebra-state/src/service.rs b/zebra-state/src/service.rs index 1b31311d365..5e7859bdb22 100644 --- a/zebra-state/src/service.rs +++ b/zebra-state/src/service.rs @@ -38,7 +38,10 @@ use zebra_chain::{ }; use crate::{ - constants::{MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA, MAX_LEGACY_CHAIN_BLOCKS}, + constants::{ + MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA, + MAX_LEGACY_CHAIN_BLOCKS, + }, service::{ chain_tip::{ChainTipBlock, ChainTipChange, ChainTipSender, LatestChainTip}, finalized_state::{FinalizedState, ZebraDb},