Skip to content

Commit

Permalink
Merge of #8475
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored May 2, 2024
2 parents d47acd0 + 2ad072a commit a3c5e27
Show file tree
Hide file tree
Showing 29 changed files with 332 additions and 179 deletions.
6 changes: 5 additions & 1 deletion zebra-chain/src/block/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ impl Commitment {
Ok(root) => Ok(FinalSaplingRoot(root)),
_ => Err(InvalidSapingRootBytes),
},
Heartwood if Some(height) == Heartwood.activation_height(network) => {
// NetworkUpgrade::current() returns the latest network upgrade that's activated at the provided height, so
// on Regtest for heights above height 0, it returns NU5, and it's possible for the current network upgrade
// to be NU5 (or Canopy, or any network upgrade above Heartwood) at the Heartwood activation height.
// TODO: Check Canopy too once Zebra can construct Canopy block templates.
Heartwood | Nu5 if Some(height) == Heartwood.activation_height(network) => {
if bytes == CHAIN_HISTORY_ACTIVATION_RESERVED {
Ok(ChainHistoryActivationReserved)
} else {
Expand Down
8 changes: 5 additions & 3 deletions zebra-chain/src/history_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,11 @@ impl HistoryTree {
sapling_root: &sapling::tree::Root,
orchard_root: &orchard::tree::Root,
) -> Result<Self, HistoryTreeError> {
let heartwood_height = NetworkUpgrade::Heartwood
.activation_height(network)
.expect("Heartwood height is known");
let Some(heartwood_height) = NetworkUpgrade::Heartwood.activation_height(network) else {
// Return early if there is no Heartwood activation height.
return Ok(HistoryTree(None));
};

match block
.coinbase_height()
.expect("must have height")
Expand Down
30 changes: 22 additions & 8 deletions zebra-chain/src/parameters/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use crate::{
parameters::NetworkUpgrade,
};

use self::testnet::ConfiguredActivationHeights;

pub mod testnet;

#[cfg(test)]
Expand Down Expand Up @@ -169,8 +167,8 @@ impl Network {
}

/// Creates a new [`Network::Testnet`] with `Regtest` parameters and the provided network upgrade activation heights.
pub fn new_regtest(activation_heights: ConfiguredActivationHeights) -> Self {
Self::new_configured_testnet(testnet::Parameters::new_regtest(activation_heights))
pub fn new_regtest() -> Self {
Self::new_configured_testnet(testnet::Parameters::new_regtest())
}

/// Returns true if the network is the default Testnet, or false otherwise.
Expand Down Expand Up @@ -203,14 +201,13 @@ impl Network {
pub fn kind(&self) -> NetworkKind {
match self {
Network::Mainnet => NetworkKind::Mainnet,
// TODO: Return `NetworkKind::Regtest` if the parameters match the default Regtest params
Network::Testnet(params) if params.is_regtest() => NetworkKind::Regtest,
Network::Testnet(_) => NetworkKind::Testnet,
}
}

/// Returns an iterator over [`Network`] variants.
pub fn iter() -> impl Iterator<Item = Self> {
// TODO: Use default values of `Testnet` variant when adding fields for #7845.
[Self::Mainnet, Self::new_default_testnet()].into_iter()
}

Expand Down Expand Up @@ -244,6 +241,12 @@ impl 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.
///
/// ZIP-212 grace period is only applied to default networks.
// TODO:
// - Support constructing pre-Canopy coinbase tx and block templates and return `Height::MAX` instead of panicking
// when Canopy activation height is `None` (#8434)
// - Add semantic block validation during the ZIP-212 grace period and update this method to always apply the ZIP-212 grace period
pub fn mandatory_checkpoint_height(&self) -> Height {
// Currently this is after the ZIP-212 grace period.
//
Expand All @@ -253,8 +256,19 @@ impl Network {
.activation_height(self)
.expect("Canopy activation height must be present for both networks");

(canopy_activation + ZIP_212_GRACE_PERIOD_DURATION)
.expect("ZIP-212 grace period ends at a valid block height")
let is_a_default_network = match self {
Network::Mainnet => true,
Network::Testnet(params) => params.is_default_testnet(),
};

if is_a_default_network {
(canopy_activation + ZIP_212_GRACE_PERIOD_DURATION)
.expect("ZIP-212 grace period ends at a valid block height")
} else {
canopy_activation
.previous()
.expect("Canopy activation must be above Genesis height")
}
}

/// Return the network name as defined in
Expand Down
9 changes: 6 additions & 3 deletions zebra-chain/src/parameters/network/testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ impl Parameters {
/// Accepts a [`ConfiguredActivationHeights`].
///
/// Creates an instance of [`Parameters`] with `Regtest` values.
pub fn new_regtest(activation_heights: ConfiguredActivationHeights) -> Self {
pub fn new_regtest() -> Self {
Self {
network_name: "Regtest".to_string(),
..Self::build()
Expand All @@ -323,7 +323,10 @@ impl Parameters {
)
// Removes default Testnet activation heights if not configured,
// most network upgrades are disabled by default for Regtest in zcashd
.with_activation_heights(activation_heights)
.with_activation_heights(ConfiguredActivationHeights {
nu5: Some(1),
..Default::default()
})
.finish()
}
}
Expand All @@ -344,7 +347,7 @@ impl Parameters {
hrp_sapling_extended_full_viewing_key,
hrp_sapling_payment_address,
disable_pow,
} = Self::new_regtest(ConfiguredActivationHeights::default());
} = Self::new_regtest();

self.network_name == network_name
&& self.genesis_hash == genesis_hash
Expand Down
6 changes: 3 additions & 3 deletions zebra-chain/src/parameters/network/tests/vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,14 @@ fn activates_network_upgrades_correctly() {

let expected_default_regtest_activation_heights = &[
(Height(0), NetworkUpgrade::Genesis),
(Height(1), NetworkUpgrade::BeforeOverwinter),
(Height(1), NetworkUpgrade::Nu5),
];

for (network, expected_activation_heights) in [
(Network::Mainnet, MAINNET_ACTIVATION_HEIGHTS),
(Network::new_default_testnet(), TESTNET_ACTIVATION_HEIGHTS),
(
Network::new_regtest(Default::default()),
Network::new_regtest(),
expected_default_regtest_activation_heights,
),
] {
Expand Down Expand Up @@ -193,7 +193,7 @@ fn check_configured_network_name() {
"Mainnet should be displayed as 'Mainnet'"
);
assert_eq!(
Network::new_regtest(Default::default()).to_string(),
Network::new_regtest().to_string(),
"Regtest",
"Regtest should be displayed as 'Regtest'"
);
Expand Down
10 changes: 3 additions & 7 deletions zebra-chain/src/parameters/network_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,10 @@ impl NetworkUpgrade {
),
]
.into_iter()
.map(move |(upgrade, spacing_seconds)| {
let activation_height = upgrade
.activation_height(network)
.expect("missing activation height for target spacing change");

.filter_map(move |(upgrade, spacing_seconds)| {
let activation_height = upgrade.activation_height(network)?;
let target_spacing = Duration::seconds(spacing_seconds);

(activation_height, target_spacing)
Some((activation_height, target_spacing))
})
}

Expand Down
2 changes: 1 addition & 1 deletion zebra-chain/src/work/difficulty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ impl ParameterDifficulty for Network {
/* 2^243 - 1 */
Network::Mainnet => (U256::one() << 243) - 1,
/* 2^251 - 1 */
// TODO: Add a `target_difficulty_limit` field to `testnet::Parameters` to return here.
// TODO: Add a `target_difficulty_limit` field to `testnet::Parameters` to return here. (`U256::from_big_endian(&[0x0f].repeat(8))` for Regtest)
Network::Testnet(_params) => (U256::one() << 251) - 1,
};

Expand Down
12 changes: 10 additions & 2 deletions zebra-consensus/src/block/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,18 @@ pub fn subsidy_is_valid(block: &Block, network: &Network) -> Result<(), BlockErr
.activation_height(network)
.expect("Canopy activation height is known");

if height < SLOW_START_INTERVAL {
// TODO: Add this as a field on `testnet::Parameters` instead of checking `disable_pow()`, this is 0 for Regtest in zcashd,
// see <https://github.com/zcash/zcash/blob/master/src/chainparams.cpp#L640>
let slow_start_interval = if network.disable_pow() {
Height(0)
} else {
SLOW_START_INTERVAL
};

if height < slow_start_interval {
unreachable!(
"unsupported block height: callers should handle blocks below {:?}",
SLOW_START_INTERVAL
slow_start_interval
)
} else if halving_div.count_ones() != 1 {
unreachable!("invalid halving divisor: the halving divisor must be a non-zero power of two")
Expand Down
20 changes: 15 additions & 5 deletions zebra-consensus/src/block/subsidy/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,20 @@ pub fn halving_divisor(height: Height, network: &Network) -> Option<u64> {
.activation_height(network)
.expect("blossom activation height should be available");

if height < SLOW_START_SHIFT {
// TODO: Add this as a field on `testnet::Parameters` instead of checking `disable_pow()`, this is 0 for Regtest in zcashd,
// see <https://github.com/zcash/zcash/blob/master/src/chainparams.cpp#L640>
let slow_start_shift = if network.disable_pow() {
Height(0)
} else {
SLOW_START_SHIFT
};

if height < slow_start_shift {
unreachable!(
"unsupported block height {height:?}: checkpoints should handle blocks below {SLOW_START_SHIFT:?}",
"unsupported block height {height:?}: checkpoints should handle blocks below {slow_start_shift:?}",
)
} else if height < blossom_height {
let pre_blossom_height = height - SLOW_START_SHIFT;
let pre_blossom_height = height - slow_start_shift;
let halving_shift = pre_blossom_height / PRE_BLOSSOM_HALVING_INTERVAL;

let halving_div = 1u64
Expand All @@ -43,7 +51,7 @@ pub fn halving_divisor(height: Height, network: &Network) -> Option<u64> {

Some(halving_div)
} else {
let pre_blossom_height = blossom_height - SLOW_START_SHIFT;
let pre_blossom_height = blossom_height - slow_start_shift;
let scaled_pre_blossom_height =
pre_blossom_height * HeightDiff::from(BLOSSOM_POW_TARGET_SPACING_RATIO);

Expand Down Expand Up @@ -77,7 +85,9 @@ pub fn block_subsidy(height: Height, network: &Network) -> Result<Amount<NonNega
return Ok(Amount::zero());
};

if height < SLOW_START_INTERVAL {
// TODO: Add this as a field on `testnet::Parameters` instead of checking `disable_pow()`, this is 0 for Regtest in zcashd,
// see <https://github.com/zcash/zcash/blob/master/src/chainparams.cpp#L640>
if height < SLOW_START_INTERVAL && !network.disable_pow() {
unreachable!(
"unsupported block height {height:?}: callers should handle blocks below {SLOW_START_INTERVAL:?}",
)
Expand Down
2 changes: 1 addition & 1 deletion zebra-consensus/src/checkpoint/list/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ fn checkpoint_list_load_hard_coded() -> Result<(), BoxError> {

let _ = Mainnet.checkpoint_list();
let _ = Network::new_default_testnet().checkpoint_list();
let _ = Network::new_regtest(Default::default()).checkpoint_list();
let _ = Network::new_regtest().checkpoint_list();

Ok(())
}
Expand Down
13 changes: 11 additions & 2 deletions zebra-consensus/src/parameters/subsidy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,11 @@ lazy_static! {
let mut hash_map = HashMap::new();
hash_map.insert(NetworkKind::Mainnet, Height(1_046_400)..Height(2_726_400));
hash_map.insert(NetworkKind::Testnet, Height(1_028_500)..Height(2_796_000));
hash_map.insert(NetworkKind::Regtest, Height(1_028_500)..Height(2_796_000));
hash_map
};

/// Convenient storage for all addresses, for all receivers and networks
// TODO: Move the value here to a field on `testnet::Parameters` (#8367)
// There are no funding stream addresses on Regtest in zcashd, zebrad should do the same for compatibility.
pub static ref FUNDING_STREAM_ADDRESSES: HashMap<NetworkKind, HashMap<FundingStreamReceiver, Vec<String>>> = {
let mut addresses_by_network = HashMap::with_capacity(2);

Expand All @@ -132,6 +131,16 @@ lazy_static! {
testnet_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(NetworkKind::Testnet, testnet_addresses);


// Regtest addresses
// TODO: Move the value here to a field on `testnet::Parameters` (#8367)
// There are no funding stream addresses on Regtest in zcashd, zebrad should do the same for compatibility.
let mut regtest_addresses = HashMap::with_capacity(3);
regtest_addresses.insert(FundingStreamReceiver::Ecc, FUNDING_STREAM_ECC_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
regtest_addresses.insert(FundingStreamReceiver::ZcashFoundation, FUNDING_STREAM_ZF_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
regtest_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(NetworkKind::Testnet, regtest_addresses);

addresses_by_network
};
}
Expand Down
1 change: 0 additions & 1 deletion zebra-consensus/src/transaction/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,6 @@ pub fn coinbase_expiry_height(
) -> Result<(), TransactionError> {
let expiry_height = coinbase.expiry_height();

// TODO: replace `if let` with `expect` after NU5 mainnet activation
if let Some(nu5_activation_height) = NetworkUpgrade::Nu5.activation_height(network) {
// # Consensus
//
Expand Down
9 changes: 2 additions & 7 deletions zebra-network/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,7 @@ impl Config {
Network::Testnet(params) if params.is_default_testnet() => {
self.initial_testnet_peers.clone()
}
// TODO: Check if the network is an incompatible custom testnet (_not_ Regtest), then panic if `initial_testnet_peers`
// contains any of the default testnet peers, or return `initial_testnet_peers` otherwise. See:
// <https://github.com/ZcashFoundation/zebra/pull/7924#discussion_r1385881828>
// TODO: Add a `disable_peers` field to `Network` to check instead of `is_default_testnet()` (#8361)
Network::Testnet(_params) => IndexSet::new(),
}
}
Expand Down Expand Up @@ -639,7 +637,6 @@ impl<'de> Deserialize<'de> for Config {
listen_addr: String,
network: NetworkKind,
testnet_parameters: Option<DTestnetParameters>,
regtest_activation_heights: ConfiguredActivationHeights,
initial_mainnet_peers: IndexSet<String>,
initial_testnet_peers: IndexSet<String>,
cache_dir: CacheDir,
Expand All @@ -656,7 +653,6 @@ impl<'de> Deserialize<'de> for Config {
listen_addr: "0.0.0.0".to_string(),
network: Default::default(),
testnet_parameters: None,
regtest_activation_heights: ConfiguredActivationHeights::default(),
initial_mainnet_peers: config.initial_mainnet_peers,
initial_testnet_peers: config.initial_testnet_peers,
cache_dir: config.cache_dir,
Expand All @@ -671,7 +667,6 @@ impl<'de> Deserialize<'de> for Config {
listen_addr,
network: network_kind,
testnet_parameters,
regtest_activation_heights,
initial_mainnet_peers,
initial_testnet_peers,
cache_dir,
Expand Down Expand Up @@ -700,7 +695,7 @@ impl<'de> Deserialize<'de> for Config {
let network = match (network_kind, testnet_parameters) {
(NetworkKind::Mainnet, _) => Network::Mainnet,
(NetworkKind::Testnet, None) => Network::new_default_testnet(),
(NetworkKind::Regtest, _) => Network::new_regtest(regtest_activation_heights),
(NetworkKind::Regtest, _) => Network::new_regtest(),
(
NetworkKind::Testnet,
Some(DTestnetParameters {
Expand Down
1 change: 1 addition & 0 deletions zebra-network/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ lazy_static! {

hash_map.insert(NetworkKind::Mainnet, Version::min_specified_for_upgrade(&Mainnet, Nu5));
hash_map.insert(NetworkKind::Testnet, Version::min_specified_for_upgrade(&Network::new_default_testnet(), Nu5));
hash_map.insert(NetworkKind::Regtest, Version::min_specified_for_upgrade(&Network::new_regtest(), Nu5));

hash_map
};
Expand Down
8 changes: 6 additions & 2 deletions zebra-rpc/src/methods/get_block_template_rpcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,8 +638,12 @@ where
//
// Optional TODO:
// - add `async changed()` method to ChainSyncStatus (like `ChainTip`)
check_synced_to_tip(&network, latest_chain_tip.clone(), sync_status.clone())?;

// TODO:
// - Add a `disable_peers` field to `Network` to check instead of `disable_pow()` (#8361)
// - Check the field in `sync_status` so it applies to the mempool as well.
if !network.disable_pow() {
check_synced_to_tip(&network, latest_chain_tip.clone(), sync_status.clone())?;
}
// TODO: return an error if we have no peers, like `zcashd` does,
// and add a developer config that mines regardless of how many peers we have.
// https://github.com/zcash/zcash/blob/6fdd9f1b81d3b228326c9826fa10696fc516444b/src/miner.cpp#L865-L880
Expand Down
Loading

0 comments on commit a3c5e27

Please sign in to comment.