fix(testnet): look back up to 10,000 blocks on testnet for a legacy chain (#5133)

* Look back 10,000 blocks on testnet for a legacy chain

* Use a smaller number of legacy chain blocks in the tests

* Fix test assertion error message

* Clarify legacy chain check comment

* cargo fmt --all

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
teor 2022-09-20 21:31:24 +10:00 committed by GitHub
parent b122052d3e
commit 0db014da40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 13 deletions

View File

@ -22,7 +22,9 @@ pub const DATABASE_FORMAT_VERSION: u32 = 25;
/// The maximum number of blocks to check for NU5 transactions, /// The maximum number of blocks to check for NU5 transactions,
/// before we assume we are on a pre-NU5 legacy chain. /// 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;
/// The maximum number of block hashes allowed in `getblocks` responses in the Zcash network protocol. /// The maximum number of block hashes allowed in `getblocks` responses in the Zcash network protocol.
pub const MAX_FIND_BLOCK_HASHES_RESULTS: u32 = 500; pub const MAX_FIND_BLOCK_HASHES_RESULTS: u32 = 500;

View File

@ -38,7 +38,10 @@ use zebra_chain::{
}; };
use crate::{ use crate::{
constants::{MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA}, constants::{
MAX_FIND_BLOCK_HASHES_RESULTS, MAX_FIND_BLOCK_HEADERS_RESULTS_FOR_ZEBRA,
MAX_LEGACY_CHAIN_BLOCKS,
},
service::{ service::{
chain_tip::{ChainTipBlock, ChainTipChange, ChainTipSender, LatestChainTip}, chain_tip::{ChainTipBlock, ChainTipChange, ChainTipSender, LatestChainTip},
finalized_state::{FinalizedState, ZebraDb}, finalized_state::{FinalizedState, ZebraDb},
@ -251,6 +254,7 @@ impl StateService {
nu5_activation_height, nu5_activation_height,
state.any_ancestor_blocks(tip.1), state.any_ancestor_blocks(tip.1),
state.network, state.network,
MAX_LEGACY_CHAIN_BLOCKS,
) { ) {
let legacy_db_path = state.disk.path().to_path_buf(); let legacy_db_path = state.disk.path().to_path_buf();
panic!( panic!(

View File

@ -12,7 +12,7 @@ use zebra_chain::{
work::difficulty::CompactDifficulty, work::difficulty::CompactDifficulty,
}; };
use crate::{constants, BoxError, PreparedBlock, ValidateContextError}; use crate::{BoxError, PreparedBlock, ValidateContextError};
// use self as check // use self as check
use super::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. /// 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 changed from the defaults for testing.
pub(crate) fn legacy_chain<I>( pub(crate) fn legacy_chain<I>(
nu5_activation_height: block::Height, nu5_activation_height: block::Height,
ancestors: I, ancestors: I,
network: Network, network: Network,
max_legacy_chain_blocks: usize,
) -> Result<(), BoxError> ) -> Result<(), BoxError>
where where
I: Iterator<Item = Arc<Block>>, I: Iterator<Item = Arc<Block>>,
@ -315,8 +320,8 @@ where
} }
// If we are past our NU5 activation height, but there are no V5 transactions in recent blocks, // 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 >= constants::MAX_LEGACY_CHAIN_BLOCKS { if index >= max_legacy_chain_blocks {
return Err(format!( return Err(format!(
"could not find any transactions in recent blocks: \ "could not find any transactions in recent blocks: \
checked {index} blocks back from {:?}", checked {index} blocks back from {:?}",

View File

@ -20,7 +20,6 @@ use zebra_test::{prelude::*, transcript::Transcript};
use crate::{ use crate::{
arbitrary::Prepare, arbitrary::Prepare,
constants::{self, MAX_LEGACY_CHAIN_BLOCKS},
init_test, init_test,
service::{arbitrary::populated_state, chain_tip::TipAction, StateService}, service::{arbitrary::populated_state, chain_tip::TipAction, StateService},
tests::setup::{partial_nu5_chain_strategy, transaction_v4_from_coinbase}, tests::setup::{partial_nu5_chain_strategy, transaction_v4_from_coinbase},
@ -277,11 +276,14 @@ fn state_behaves_when_blocks_are_committed_in_order() -> Result<()> {
const DEFAULT_PARTIAL_CHAIN_PROPTEST_CASES: u32 = 2; 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. /// 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. /// 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! {
#![proptest_config( #![proptest_config(
@ -304,7 +306,7 @@ proptest! {
fn some_block_less_than_network_upgrade( 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) (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()); .map_err(|error| error.to_string());
prop_assert_eq!(response, Ok(())); prop_assert_eq!(response, Ok(()));
@ -321,13 +323,13 @@ proptest! {
.coinbase_height() .coinbase_height()
.expect("chain contains valid blocks"); .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()); .map_err(|error| error.to_string());
prop_assert_eq!( prop_assert_eq!(
response, response,
Err(format!( 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:?}",
)) ))
); );
} }
@ -360,7 +362,8 @@ proptest! {
let response = crate::service::check::legacy_chain( let response = crate::service::check::legacy_chain(
nu_activation_height, nu_activation_height,
chain.clone().into_iter().rev(), chain.clone().into_iter().rev(),
network network,
TEST_LEGACY_CHAIN_LIMIT,
).map_err(|error| error.to_string()); ).map_err(|error| error.to_string());
prop_assert_eq!( prop_assert_eq!(
@ -377,7 +380,7 @@ proptest! {
fn at_least_one_transaction_with_valid_network_upgrade( 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) (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()); .map_err(|error| error.to_string());
prop_assert_eq!(response, Ok(())); prop_assert_eq!(response, Ok(()));