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

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

Merged
merged 7 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 3 additions & 1 deletion zebra-state/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions zebra-state/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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!(
Expand Down
9 changes: 7 additions & 2 deletions zebra-state/src/service/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 changed from the defaults for testing.
pub(crate) fn legacy_chain<I>(
nu5_activation_height: block::Height,
ancestors: I,
network: Network,
max_legacy_chain_blocks: usize,
) -> Result<(), BoxError>
where
I: Iterator<Item = Arc<Block>>,
Expand All @@ -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.
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
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 {:?}",
Expand Down
19 changes: 11 additions & 8 deletions zebra-state/src/service/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use zebra_test::{prelude::*, transcript::Transcript};

use crate::{
arbitrary::Prepare,
constants::{self, MAX_LEGACY_CHAIN_BLOCKS},
init_test,
service::{arbitrary::populated_state, chain_tip::TipAction, StateService},
tests::setup::{partial_nu5_chain_strategy, transaction_v4_from_coinbase},
Expand Down Expand Up @@ -277,11 +276,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(
Expand All @@ -304,7 +306,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(()));
Expand All @@ -321,13 +323,13 @@ 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!(
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:?}",
))
);
}
Expand Down Expand Up @@ -360,7 +362,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!(
Expand All @@ -377,7 +380,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(()));
Expand Down