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 5 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
53 changes: 50 additions & 3 deletions zebra-chain/src/parameters/network/subsidy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,27 @@ 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 const PRE_BLOSSOM_REGTEST_HALVING_INTERVAL: HeightDiff = 144;
arya2 marked this conversation as resolved.
Show resolved Hide resolved

/// 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);

/// After Blossom the block time is reduced to 75 seconds but halving period should remain 6 hours.
pub const POST_BLOSSOM_REGTEST_HALVING_INTERVAL: HeightDiff =
PRE_BLOSSOM_REGTEST_HALVING_INTERVAL * (BLOSSOM_POW_TARGET_SPACING_RATIO as HeightDiff);

/// The first halving height in the testnet is at block height `1_116_000`
/// 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);

/// The first halving height in the regtest is at block height `287`.
pub const FIRST_HALVING_REGTEST: Height = Height(287);
arya2 marked this conversation as resolved.
Show resolved Hide resolved

/// The funding stream receiver categories.
#[derive(Deserialize, Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum FundingStreamReceiver {
Expand Down Expand Up @@ -379,6 +390,12 @@ 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;
}

/// Network methods related to Block Subsidy and Funding Streams
Expand All @@ -391,8 +408,38 @@ 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(
self.post_blossom_halving_interval()
.try_into()
.expect("post blossom halving interval should fit in a Height"),
)
arya2 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}

fn post_blossom_halving_interval(&self) -> HeightDiff {
self.pre_blossom_halving_interval() * (BLOSSOM_POW_TARGET_SPACING_RATIO as HeightDiff)
arya2 marked this conversation as resolved.
Show resolved Hide resolved
}

fn pre_blossom_halving_interval(&self) -> HeightDiff {
match self {
Network::Mainnet => PRE_BLOSSOM_HALVING_INTERVAL,
Network::Testnet(params) => {
if params.is_regtest() {
PRE_BLOSSOM_REGTEST_HALVING_INTERVAL
} else if params.is_default_testnet() {
PRE_BLOSSOM_HALVING_INTERVAL
} else {
params.pre_blossom_halving_interval()
}
}
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down Expand Up @@ -503,7 +550,7 @@ 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)
let address_period = (height_after_first_halving + network.post_blossom_halving_interval())
/ FUNDING_STREAM_ADDRESS_CHANGE_INTERVAL;

address_period
Expand Down
41 changes: 38 additions & 3 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,8 +16,10 @@ use super::{
magic::Magic,
subsidy::{
FundingStreamReceiver, FundingStreamRecipient, FundingStreams, ParameterSubsidy,
FIRST_HALVING_TESTNET, POST_NU6_FUNDING_STREAMS_MAINNET, POST_NU6_FUNDING_STREAMS_TESTNET,
PRE_NU6_FUNDING_STREAMS_MAINNET, PRE_NU6_FUNDING_STREAMS_TESTNET,
FIRST_HALVING_TESTNET, 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 +59,13 @@ 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
}
}

/// Configurable funding stream recipient for configured Testnets.
Expand Down Expand Up @@ -217,6 +226,8 @@ 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,
}

impl Default for ParametersBuilder {
Expand Down Expand Up @@ -249,6 +260,7 @@ 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,
}
}
}
Expand Down Expand Up @@ -411,6 +423,15 @@ impl ParametersBuilder {
self
}

/// Sets the halving interval to be used in the [`Parameters`] being built.
pub fn with_pre_blossom_halving_interval(
mut self,
pre_blossom_halving_interval: HeightDiff,
) -> Self {
self.pre_blossom_halving_interval = pre_blossom_halving_interval;
self
}

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

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

self.activation_heights == activation_heights
Expand All @@ -465,6 +489,7 @@ 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
}
}

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

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

self.network_name == network_name
Expand All @@ -578,6 +607,7 @@ 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
}

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

/// Returns the halving interval for this network
pub fn pre_blossom_halving_interval(&self) -> HeightDiff {
self.pre_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
6 changes: 3 additions & 3 deletions zebra-consensus/src/block/subsidy/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn halving_divisor(height: Height, network: &Network) -> Option<u64> {

if height < blossom_height {
let pre_blossom_height = height - network.slow_start_shift();
let halving_shift = pre_blossom_height / PRE_BLOSSOM_HALVING_INTERVAL;
let halving_shift = pre_blossom_height / network.pre_blossom_halving_interval();

let halving_div = 1u64
.checked_shl(
Expand All @@ -47,8 +47,8 @@ pub fn halving_divisor(height: Height, network: &Network) -> Option<u64> {

let post_blossom_height = height - blossom_height;

let halving_shift =
(scaled_pre_blossom_height + post_blossom_height) / POST_BLOSSOM_HALVING_INTERVAL;
let halving_shift = (scaled_pre_blossom_height + post_blossom_height)
/ network.post_blossom_halving_interval();

// Some far-future shifts can be more than 63 bits
1u64.checked_shl(
Expand Down
7 changes: 7 additions & 0 deletions zebra-network/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ impl<'de> Deserialize<'de> for Config {
activation_heights: Option<ConfiguredActivationHeights>,
pre_nu6_funding_streams: Option<ConfiguredFundingStreams>,
post_nu6_funding_streams: Option<ConfiguredFundingStreams>,
pre_blossom_halving_interval: Option<u32>,
}

#[derive(Deserialize)]
Expand Down Expand Up @@ -686,6 +687,7 @@ impl<'de> Deserialize<'de> for Config {
activation_heights,
pre_nu6_funding_streams,
post_nu6_funding_streams,
pre_blossom_halving_interval,
}),
) => {
let mut params_builder = testnet::Parameters::build();
Expand Down Expand Up @@ -733,6 +735,11 @@ impl<'de> Deserialize<'de> for Config {
params_builder = params_builder.with_activation_heights(activation_heights)
}

if let Some(halving_interval) = pre_blossom_halving_interval {
params_builder =
params_builder.with_pre_blossom_halving_interval(halving_interval.into())
}

// Return an error if the initial testnet peers includes any of the default initial Mainnet or Testnet
// peers and the configured network parameters are incompatible with the default public Testnet.
if !params_builder.is_compatible_with_default_parameters()
Expand Down
4 changes: 4 additions & 0 deletions zebra-rpc/qa/base_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ listen_addr = "127.0.0.1:0"

[state]
cache_dir = ""

[network.testnet_parameters.activation_heights]
NU5 = 290
NU6 = 291
3 changes: 2 additions & 1 deletion zebra-rpc/qa/pull-tester/rpc-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
# Scripts that are run by the travis build process
# Longest test should go first, to favor running tests in parallel
'reindex.py',
'getmininginfo.py']
'getmininginfo.py',
'nuparams.py']

ZMQ_SCRIPTS = [
# ZMQ test can only be run if bitcoin was built with zmq-enabled.
Expand Down
Loading
Loading