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

feat(regtest): Add regtest halving interval and port test #8888

Merged
merged 17 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from 13 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
96 changes: 91 additions & 5 deletions zebra-chain/src/parameters/network/subsidy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ pub const BLOSSOM_POW_TARGET_SPACING_RATIO: u32 = 2;
/// `(60 * 60 * 24 * 365 * 4) / 150 = 840960`
pub const PRE_BLOSSOM_HALVING_INTERVAL: HeightDiff = 840_000;

/// The halving height interval in the regtest is 6 hours.
/// [zcashd regtest halving interval](https://github.com/zcash/zcash/blob/v5.10.0/src/consensus/params.h#L252)
pub(crate) const PRE_BLOSSOM_REGTEST_HALVING_INTERVAL: HeightDiff = 144;

/// After Blossom the block time is reduced to 75 seconds but halving period should remain around 4 years.
pub const POST_BLOSSOM_HALVING_INTERVAL: HeightDiff =
PRE_BLOSSOM_HALVING_INTERVAL * (BLOSSOM_POW_TARGET_SPACING_RATIO as HeightDiff);
Expand All @@ -48,7 +52,10 @@ pub const POST_BLOSSOM_HALVING_INTERVAL: HeightDiff =
/// as specified in [protocol specification §7.10.1][7.10.1]
///
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
pub const FIRST_HALVING_TESTNET: Height = Height(1_116_000);
pub(crate) const FIRST_HALVING_TESTNET: Height = Height(1_116_000);

/// The first halving height in the regtest is at block height `287`.
const FIRST_HALVING_REGTEST: Height = Height(287);

/// The funding stream receiver categories.
#[derive(Deserialize, Clone, Copy, Debug, Eq, Hash, PartialEq)]
Expand Down Expand Up @@ -379,6 +386,15 @@ pub trait ParameterSubsidy {
///
/// [7.10]: <https://zips.z.cash/protocol/protocol.pdf#fundingstreams>
fn height_for_first_halving(&self) -> Height;

/// Returns the halving interval after Blossom
fn post_blossom_halving_interval(&self) -> HeightDiff;

/// Returns the halving interval before Blossom
fn pre_blossom_halving_interval(&self) -> HeightDiff;

/// Returns the address change interval for funding streams
fn funding_stream_address_change_interval(&self) -> HeightDiff;
}

/// Network methods related to Block Subsidy and Funding Streams
Expand All @@ -391,10 +407,36 @@ impl ParameterSubsidy for Network {
Network::Mainnet => NetworkUpgrade::Canopy
.activation_height(self)
.expect("canopy activation height should be available"),
// TODO: Check what zcashd does here, consider adding a field to `testnet::Parameters` to make this configurable.
Network::Testnet(_params) => FIRST_HALVING_TESTNET,
Network::Testnet(params) => {
if params.is_regtest() {
FIRST_HALVING_REGTEST
} else if params.is_default_testnet() {
FIRST_HALVING_TESTNET
} else {
height_for_halving_index(1, self)
.expect("first halving height should be available")
}
}
}
}

fn post_blossom_halving_interval(&self) -> HeightDiff {
match self {
Network::Mainnet => POST_BLOSSOM_HALVING_INTERVAL,
Network::Testnet(params) => params.post_blossom_halving_interval(),
}
}

fn pre_blossom_halving_interval(&self) -> HeightDiff {
match self {
Network::Mainnet => PRE_BLOSSOM_HALVING_INTERVAL,
Network::Testnet(params) => params.pre_blossom_halving_interval(),
}
}

fn funding_stream_address_change_interval(&self) -> HeightDiff {
self.post_blossom_halving_interval() / 48
}
}

/// List of addresses for the Zcash Foundation funding stream in the Mainnet.
Expand Down Expand Up @@ -503,10 +545,54 @@ pub fn funding_stream_address_period<N: ParameterSubsidy>(height: Height, networ

let height_after_first_halving = height - network.height_for_first_halving();

let address_period = (height_after_first_halving + POST_BLOSSOM_HALVING_INTERVAL)
/ FUNDING_STREAM_ADDRESS_CHANGE_INTERVAL;
let address_period = (height_after_first_halving + network.post_blossom_halving_interval())
/ network.funding_stream_address_change_interval();

address_period
.try_into()
.expect("all values are positive and smaller than the input height")
}

/// The first block height of the halving at the provided halving index for a network.
///
/// See `Halving(height)`, as described in [protocol specification §7.8][7.8]
///
/// [7.8]: https://zips.z.cash/protocol/protocol.pdf#subsidies
pub fn height_for_halving_index(halving_index: u32, network: &Network) -> Option<Height> {
if halving_index == 0 {
return Some(Height(0));
}

let slow_start_shift = i64::from(network.slow_start_shift().0);
let blossom_height = i64::from(
NetworkUpgrade::Blossom
.activation_height(network)
.expect("blossom activation height should be available")
.0,
);
let pre_blossom_halving_interval = network.pre_blossom_halving_interval();
let halving_index = i64::from(halving_index);

let unscaled_height = halving_index
.checked_mul(pre_blossom_halving_interval)
.expect("Multiplication overflow: consider reducing the halving interval");

let pre_blossom_height = unscaled_height
.min(blossom_height)
.checked_add(slow_start_shift)
.expect("Addition overflow: consider reducing the halving interval");

let post_blossom_height = 0
.max(unscaled_height - blossom_height)
.checked_mul(i64::from(BLOSSOM_POW_TARGET_SPACING_RATIO))
.expect("Multiplication overflow: consider reducing the halving interval")
.checked_add(slow_start_shift)
.expect("Addition overflow: consider reducing the halving interval");

let height = pre_blossom_height
.checked_add(post_blossom_height)
.expect("Addition overflow: consider reducing the halving interval");

let height = u32::try_from(height).ok()?;
height.try_into().ok()
}
59 changes: 57 additions & 2 deletions zebra-chain/src/parameters/network/testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::{collections::BTreeMap, fmt};

use crate::{
block::{self, Height},
block::{self, Height, HeightDiff},
parameters::{
constants::{magics, SLOW_START_INTERVAL, SLOW_START_SHIFT},
network_upgrade::TESTNET_ACTIVATION_HEIGHTS,
Expand All @@ -16,7 +16,10 @@ use super::{
magic::Magic,
subsidy::{
FundingStreamReceiver, FundingStreamRecipient, FundingStreams, ParameterSubsidy,
FIRST_HALVING_TESTNET, POST_NU6_FUNDING_STREAMS_MAINNET, POST_NU6_FUNDING_STREAMS_TESTNET,
BLOSSOM_POW_TARGET_SPACING_RATIO, FIRST_HALVING_TESTNET,
FUNDING_STREAM_ADDRESS_CHANGE_INTERVAL, POST_BLOSSOM_HALVING_INTERVAL,
POST_NU6_FUNDING_STREAMS_MAINNET, POST_NU6_FUNDING_STREAMS_TESTNET,
PRE_BLOSSOM_HALVING_INTERVAL, PRE_BLOSSOM_REGTEST_HALVING_INTERVAL,
PRE_NU6_FUNDING_STREAMS_MAINNET, PRE_NU6_FUNDING_STREAMS_TESTNET,
},
};
Expand Down Expand Up @@ -57,6 +60,17 @@ impl ParameterSubsidy for TestnetParameterSubsidyImpl {
fn height_for_first_halving(&self) -> Height {
FIRST_HALVING_TESTNET
}
fn post_blossom_halving_interval(&self) -> block::HeightDiff {
POST_BLOSSOM_HALVING_INTERVAL
}

fn pre_blossom_halving_interval(&self) -> block::HeightDiff {
PRE_BLOSSOM_HALVING_INTERVAL
}

fn funding_stream_address_change_interval(&self) -> HeightDiff {
FUNDING_STREAM_ADDRESS_CHANGE_INTERVAL
}
}

/// Configurable funding stream recipient for configured Testnets.
Expand Down Expand Up @@ -217,6 +231,10 @@ pub struct ParametersBuilder {
target_difficulty_limit: ExpandedDifficulty,
/// A flag for disabling proof-of-work checks when Zebra is validating blocks
disable_pow: bool,
/// The pre-Blossom halving interval for this network
pre_blossom_halving_interval: HeightDiff,
/// The post-Blossom halving interval for this network
post_blossom_halving_interval: HeightDiff,
}

impl Default for ParametersBuilder {
Expand Down Expand Up @@ -249,6 +267,8 @@ impl Default for ParametersBuilder {
disable_pow: false,
pre_nu6_funding_streams: PRE_NU6_FUNDING_STREAMS_TESTNET.clone(),
post_nu6_funding_streams: POST_NU6_FUNDING_STREAMS_TESTNET.clone(),
pre_blossom_halving_interval: PRE_BLOSSOM_HALVING_INTERVAL,
post_blossom_halving_interval: POST_BLOSSOM_HALVING_INTERVAL,
}
}
}
Expand Down Expand Up @@ -411,6 +431,14 @@ impl ParametersBuilder {
self
}

/// Sets the pre and post Blosssom halving intervals to be used in the [`Parameters`] being built.
pub fn with_halving_interval(mut self, pre_blossom_halving_interval: HeightDiff) -> Self {
self.pre_blossom_halving_interval = pre_blossom_halving_interval;
self.post_blossom_halving_interval =
self.pre_blossom_halving_interval * (BLOSSOM_POW_TARGET_SPACING_RATIO as HeightDiff);
self
}

/// Converts the builder to a [`Parameters`] struct
pub fn finish(self) -> Parameters {
let Self {
Expand All @@ -423,6 +451,8 @@ impl ParametersBuilder {
post_nu6_funding_streams,
target_difficulty_limit,
disable_pow,
pre_blossom_halving_interval,
post_blossom_halving_interval,
} = self;
Parameters {
network_name,
Expand All @@ -435,6 +465,8 @@ impl ParametersBuilder {
post_nu6_funding_streams,
target_difficulty_limit,
disable_pow,
pre_blossom_halving_interval,
post_blossom_halving_interval,
}
}

Expand All @@ -455,6 +487,8 @@ impl ParametersBuilder {
post_nu6_funding_streams,
target_difficulty_limit,
disable_pow,
pre_blossom_halving_interval,
post_blossom_halving_interval,
} = Self::default();

self.activation_heights == activation_heights
Expand All @@ -465,6 +499,8 @@ impl ParametersBuilder {
&& self.post_nu6_funding_streams == post_nu6_funding_streams
&& self.target_difficulty_limit == target_difficulty_limit
&& self.disable_pow == disable_pow
&& self.pre_blossom_halving_interval == pre_blossom_halving_interval
&& self.post_blossom_halving_interval == post_blossom_halving_interval
}
}

Expand Down Expand Up @@ -495,6 +531,10 @@ pub struct Parameters {
target_difficulty_limit: ExpandedDifficulty,
/// A flag for disabling proof-of-work checks when Zebra is validating blocks
disable_pow: bool,
/// Pre-Blossom halving interval for this network
pre_blossom_halving_interval: HeightDiff,
/// Post-Blossom halving interval for this network
post_blossom_halving_interval: HeightDiff,
}

impl Default for Parameters {
Expand Down Expand Up @@ -540,6 +580,7 @@ impl Parameters {
nu6: nu6_activation_height,
..Default::default()
})
.with_halving_interval(PRE_BLOSSOM_REGTEST_HALVING_INTERVAL)
.finish()
}
}
Expand Down Expand Up @@ -568,6 +609,8 @@ impl Parameters {
post_nu6_funding_streams,
target_difficulty_limit,
disable_pow,
pre_blossom_halving_interval,
post_blossom_halving_interval,
} = Self::new_regtest(None, None);

self.network_name == network_name
Expand All @@ -578,6 +621,8 @@ impl Parameters {
&& self.post_nu6_funding_streams == post_nu6_funding_streams
&& self.target_difficulty_limit == target_difficulty_limit
&& self.disable_pow == disable_pow
&& self.pre_blossom_halving_interval == pre_blossom_halving_interval
&& self.post_blossom_halving_interval == post_blossom_halving_interval
}

/// Returns the network name
Expand Down Expand Up @@ -629,6 +674,16 @@ impl Parameters {
pub fn disable_pow(&self) -> bool {
self.disable_pow
}

/// Returns the pre-Blossom halving interval for this network
pub fn pre_blossom_halving_interval(&self) -> HeightDiff {
self.pre_blossom_halving_interval
}

/// Returns the post-Blossom halving interval for this network
pub fn post_blossom_halving_interval(&self) -> HeightDiff {
self.post_blossom_halving_interval
}
}

impl Network {
Expand Down
1 change: 1 addition & 0 deletions zebra-chain/src/parameters/network_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub enum NetworkUpgrade {
#[serde(rename = "NU5")]
Nu5,
/// The Zcash protocol after the NU6 upgrade.
#[serde(rename = "NU6")]
Nu6,
}

Expand Down
Loading
Loading