add(consensus): Add `slow_start_{interval/shift}` fields to `testnet::Parameters` (#8477)
* - Adds `slow_start_interval` field to `testnet::Parameters` - Moves SLOW_START_INTERVAL/SLOW_START_SHIFT constants to zebra-chain * Apply suggestions from code review Co-authored-by: Marek <mail@marek.onl> --------- Co-authored-by: Marek <mail@marek.onl>
This commit is contained in:
parent
15e1096826
commit
d2d1a18d81
|
@ -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;
|
||||
|
|
|
@ -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);
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -76,6 +77,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,
|
||||
}
|
||||
|
@ -98,6 +101,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,
|
||||
}
|
||||
}
|
||||
|
@ -237,6 +241,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;
|
||||
|
@ -252,6 +262,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 {
|
||||
|
@ -261,6 +272,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,
|
||||
}
|
||||
}
|
||||
|
@ -290,6 +303,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,
|
||||
}
|
||||
|
@ -322,6 +339,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,
|
||||
|
@ -353,6 +371,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(None);
|
||||
|
||||
|
@ -361,6 +381,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
|
||||
}
|
||||
|
||||
|
@ -394,8 +416,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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use zebra_chain::{
|
|||
},
|
||||
};
|
||||
|
||||
use crate::{error::*, parameters::SLOW_START_INTERVAL};
|
||||
use crate::error::*;
|
||||
|
||||
use super::subsidy;
|
||||
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
|
|
@ -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::*;
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue