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

add(consensus): Add slow_start_{interval/shift} fields to testnet::Parameters #8477

Merged
merged 2 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions zebra-chain/src/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! Typically, consensus parameters are accessed via a function that takes a
//! `Network` and `block::Height`.

pub mod constants;
mod genesis;
mod network;
mod network_upgrade;
Expand Down
17 changes: 17 additions & 0 deletions zebra-chain/src/parameters/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! Definitions of Zebra chain constants, including:
//! - slow start interval,
//! - slow start shift

use crate::block::Height;

/// An initial period from Genesis to this Height where the block subsidy is gradually incremented. [What is slow-start mining][slow-mining]
///
/// [slow-mining]: https://z.cash/support/faq/#what-is-slow-start-mining
pub const SLOW_START_INTERVAL: Height = Height(20_000);

/// `SlowStartShift()` as described in [protocol specification §7.8][7.8]
///
/// [7.8]: https://zips.z.cash/protocol/protocol.pdf#subsidies
///
/// This calculation is exact, because `SLOW_START_INTERVAL` is divisible by 2.
pub const SLOW_START_SHIFT: Height = Height(SLOW_START_INTERVAL.0 / 2);
8 changes: 0 additions & 8 deletions zebra-chain/src/parameters/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,6 @@ impl Network {
}
}

/// Returns true if proof-of-work validation should be disabled for this network
pub fn disable_pow(&self) -> bool {
if let Self::Testnet(params) = self {
params.disable_pow()
} else {
false
}
}
/// Returns the [`NetworkKind`] for this network.
pub fn kind(&self) -> NetworkKind {
match self {
Expand Down
65 changes: 63 additions & 2 deletions zebra-chain/src/parameters/network/testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ use zcash_primitives::constants as zp_constants;
use crate::{
block::{self, Height},
parameters::{
network_upgrade::TESTNET_ACTIVATION_HEIGHTS, Network, NetworkUpgrade,
NETWORK_UPGRADES_IN_ORDER,
constants::{SLOW_START_INTERVAL, SLOW_START_SHIFT},
network_upgrade::TESTNET_ACTIVATION_HEIGHTS,
Network, NetworkUpgrade, NETWORK_UPGRADES_IN_ORDER,
},
};

Expand Down Expand Up @@ -71,6 +72,8 @@ pub struct ParametersBuilder {
hrp_sapling_extended_full_viewing_key: String,
/// Sapling payment address human-readable prefix for this network
hrp_sapling_payment_address: String,
/// Slow start interval for this network
slow_start_interval: Height,
/// A flag for disabling proof-of-work checks when Zebra is validating blocks
disable_pow: bool,
}
Expand All @@ -93,6 +96,7 @@ impl Default for ParametersBuilder {
genesis_hash: TESTNET_GENESIS_HASH
.parse()
.expect("hard-coded hash parses"),
slow_start_interval: SLOW_START_INTERVAL,
disable_pow: false,
}
}
Expand Down Expand Up @@ -234,6 +238,12 @@ impl ParametersBuilder {
self
}

/// Sets the slow start interval to be used in the [`Parameters`] being built.
pub fn with_slow_start_interval(mut self, slow_start_interval: Height) -> Self {
self.slow_start_interval = slow_start_interval;
self
}

/// Sets the `disable_pow` flag to be used in the [`Parameters`] being built.
pub fn with_disable_pow(mut self, disable_pow: bool) -> Self {
self.disable_pow = disable_pow;
Expand All @@ -249,6 +259,7 @@ impl ParametersBuilder {
hrp_sapling_extended_spending_key,
hrp_sapling_extended_full_viewing_key,
hrp_sapling_payment_address,
slow_start_interval,
disable_pow,
} = self;
Parameters {
Expand All @@ -258,6 +269,8 @@ impl ParametersBuilder {
hrp_sapling_extended_spending_key,
hrp_sapling_extended_full_viewing_key,
hrp_sapling_payment_address,
slow_start_interval,
slow_start_shift: Height(slow_start_interval.0 / 2),
disable_pow,
}
}
Expand Down Expand Up @@ -287,6 +300,10 @@ pub struct Parameters {
hrp_sapling_extended_full_viewing_key: String,
/// Sapling payment address human-readable prefix for this network
hrp_sapling_payment_address: String,
/// Slow start interval for this network
slow_start_interval: Height,
/// Slow start shift for this network, always half the slow start interval
slow_start_shift: Height,
/// A flag for disabling proof-of-work checks when Zebra is validating blocks
disable_pow: bool,
}
Expand Down Expand Up @@ -316,6 +333,7 @@ impl Parameters {
..Self::build()
.with_genesis_hash(REGTEST_GENESIS_HASH)
.with_disable_pow(true)
.with_slow_start_interval(Height::MIN)
.with_sapling_hrps(
zp_constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
Expand Down Expand Up @@ -346,6 +364,8 @@ impl Parameters {
hrp_sapling_extended_spending_key,
hrp_sapling_extended_full_viewing_key,
hrp_sapling_payment_address,
slow_start_interval,
slow_start_shift,
disable_pow,
} = Self::new_regtest();

Expand All @@ -354,6 +374,8 @@ impl Parameters {
&& self.hrp_sapling_extended_spending_key == hrp_sapling_extended_spending_key
&& self.hrp_sapling_extended_full_viewing_key == hrp_sapling_extended_full_viewing_key
&& self.hrp_sapling_payment_address == hrp_sapling_payment_address
&& self.slow_start_interval == slow_start_interval
&& self.slow_start_shift == slow_start_shift
&& self.disable_pow == disable_pow
}

Expand Down Expand Up @@ -387,8 +409,47 @@ impl Parameters {
&self.hrp_sapling_payment_address
}

/// Returns slow start interval for this network
pub fn slow_start_interval(&self) -> Height {
self.slow_start_interval
}

/// Returns slow start shift for this network
pub fn slow_start_shift(&self) -> Height {
self.slow_start_shift
}

/// Returns true if proof-of-work validation should be disabled for this network
pub fn disable_pow(&self) -> bool {
self.disable_pow
}
}

impl Network {
/// Returns true if proof-of-work validation should be disabled for this network
pub fn disable_pow(&self) -> bool {
if let Self::Testnet(params) = self {
params.disable_pow()
} else {
false
}
}

/// Returns slow start interval for this network
pub fn slow_start_interval(&self) -> Height {
if let Self::Testnet(params) = self {
params.slow_start_interval()
} else {
SLOW_START_INTERVAL
}
}

/// Returns slow start shift for this network
pub fn slow_start_shift(&self) -> Height {
if let Self::Testnet(params) = self {
params.slow_start_shift()
} else {
SLOW_START_SHIFT
}
}
}
4 changes: 2 additions & 2 deletions zebra-consensus/src/block/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use zebra_chain::{
},
};

use crate::{error::*, parameters::SLOW_START_INTERVAL};
use crate::error::*;

use super::subsidy;

Expand Down Expand Up @@ -162,7 +162,7 @@ pub fn subsidy_is_valid(block: &Block, network: &Network) -> Result<(), BlockErr
let slow_start_interval = if network.disable_pow() {
Height(0)
} else {
SLOW_START_INTERVAL
network.slow_start_interval()
};

if height < slow_start_interval {
Expand Down
28 changes: 11 additions & 17 deletions zebra-consensus/src/block/subsidy/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,13 @@ pub fn halving_divisor(height: Height, network: &Network) -> Option<u64> {
.activation_height(network)
.expect("blossom activation height should be available");

// 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:?}",
if height < network.slow_start_shift() {
panic!(
"unsupported block height {height:?}: checkpoints should handle blocks below {:?}",
network.slow_start_shift()
)
} else if height < blossom_height {
let pre_blossom_height = height - slow_start_shift;
let pre_blossom_height = height - network.slow_start_shift();
let halving_shift = pre_blossom_height / PRE_BLOSSOM_HALVING_INTERVAL;

let halving_div = 1u64
Expand All @@ -51,7 +44,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 - network.slow_start_shift();
let scaled_pre_blossom_height =
pre_blossom_height * HeightDiff::from(BLOSSOM_POW_TARGET_SPACING_RATIO);

Expand Down Expand Up @@ -87,9 +80,10 @@ pub fn block_subsidy(height: Height, network: &Network) -> Result<Amount<NonNega

// 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() {
if height < network.slow_start_interval() && !network.disable_pow() {
unreachable!(
"unsupported block height {height:?}: callers should handle blocks below {SLOW_START_INTERVAL:?}",
"unsupported block height {height:?}: callers should handle blocks below {:?}",
network.slow_start_interval()
)
} else if height < blossom_height {
// this calculation is exact, because the halving divisor is 1 here
Expand Down Expand Up @@ -145,7 +139,7 @@ mod test {

assert_eq!(
1,
halving_divisor((SLOW_START_INTERVAL + 1).unwrap(), network).unwrap()
halving_divisor((network.slow_start_interval() + 1).unwrap(), network).unwrap()
);
assert_eq!(
1,
Expand Down Expand Up @@ -274,7 +268,7 @@ mod test {
// https://z.cash/support/faq/#what-is-slow-start-mining
assert_eq!(
Amount::try_from(1_250_000_000),
block_subsidy((SLOW_START_INTERVAL + 1).unwrap(), network)
block_subsidy((network.slow_start_interval() + 1).unwrap(), network)
);
assert_eq!(
Amount::try_from(1_250_000_000),
Expand Down
4 changes: 2 additions & 2 deletions zebra-consensus/src/block/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use zebra_chain::{
use zebra_script::CachedFfiTransaction;
use zebra_test::transcript::{ExpectedTranscriptError, Transcript};

use crate::{parameters::SLOW_START_SHIFT, transaction};
use crate::transaction;

use super::*;

Expand Down Expand Up @@ -470,7 +470,7 @@ fn miner_fees_validation_for_network(network: Network) -> Result<(), Report> {
let block_iter = network.block_iter();

for (&height, block) in block_iter {
if Height(height) > SLOW_START_SHIFT {
if Height(height) > network.slow_start_shift() {
let block = Block::zcash_deserialize(&block[..]).expect("block should deserialize");

// fake the miner fee to a big amount
Expand Down
12 changes: 0 additions & 12 deletions zebra-consensus/src/parameters/subsidy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@ use zebra_chain::{
parameters::{Network, NetworkKind, NetworkUpgrade},
};

/// An initial period from Genesis to this Height where the block subsidy is gradually incremented. [What is slow-start mining][slow-mining]
///
/// [slow-mining]: https://z.cash/support/faq/#what-is-slow-start-mining
pub const SLOW_START_INTERVAL: Height = Height(20_000);

/// `SlowStartShift()` as described in [protocol specification §7.8][7.8]
///
/// [7.8]: https://zips.z.cash/protocol/protocol.pdf#subsidies
///
/// This calculation is exact, because `SLOW_START_INTERVAL` is divisible by 2.
pub const SLOW_START_SHIFT: Height = Height(SLOW_START_INTERVAL.0 / 2);

/// The largest block subsidy, used before the first halving.
///
/// We use `25 / 2` instead of `12.5`, so that we can calculate the correct value without using floating-point.
Expand Down
Loading