Skip to content

Commit

Permalink
Refactor block target spacing into NetworkUpgrade methods
Browse files Browse the repository at this point in the history
And add a method for the minimum difficulty time gap threshold.
  • Loading branch information
teor2345 committed Nov 10, 2020
1 parent 7179321 commit a0bbca4
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 10 deletions.
60 changes: 60 additions & 0 deletions zebra-chain/src/parameters/network_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::parameters::{Network, Network::*};
use std::collections::{BTreeMap, HashMap};
use std::ops::Bound::*;

use chrono::Duration;

/// A Zcash network upgrade.
///
/// Network upgrades can change the Zcash network protocol or consensus rules in
Expand Down Expand Up @@ -96,6 +98,23 @@ pub(crate) const CONSENSUS_BRANCH_IDS: &[(NetworkUpgrade, ConsensusBranchId)] =
(Canopy, ConsensusBranchId(0xe9ff75a6)),
];

/// The target block spacing before Blossom.
const PRE_BLOSSOM_POW_TARGET_SPACING: i64 = 150;

/// The target block spacing after Blossom activation.
const POST_BLOSSOM_POW_TARGET_SPACING: i64 = 75;

/// The multiplier used to derive the testnet minimum difficulty block time gap
/// threshold.
///
/// Based on https://zips.z.cash/zip-0208#minimum-difficulty-blocks-on-the-test-network
const TESTNET_MINIMUM_DIFFICULTY_GAP_MULTIPLIER: i32 = 6;

/// The start height for the testnet minimum difficulty consensus rule.
///
/// Based on https://zips.z.cash/zip-0208#minimum-difficulty-blocks-on-the-test-network
const TESTNET_MINIMUM_DIFFICULTY_START_HEIGHT: block::Height = block::Height(299_188);

impl NetworkUpgrade {
/// Returns a BTreeMap of activation heights and network upgrades for
/// `network`.
Expand Down Expand Up @@ -163,6 +182,47 @@ impl NetworkUpgrade {
pub fn branch_id(&self) -> Option<ConsensusBranchId> {
NetworkUpgrade::branch_id_list().get(&self).cloned()
}

/// Returns the target block spacing for the network upgrade.
///
/// Based on `PRE_BLOSSOM_POW_TARGET_SPACING` and
/// `POST_BLOSSOM_POW_TARGET_SPACING` from the Zcash specification.
pub fn target_spacing(&self) -> Duration {
let spacing_seconds = match self {
Genesis | BeforeOverwinter | Overwinter | Sapling => PRE_BLOSSOM_POW_TARGET_SPACING,
Blossom | Heartwood | Canopy => POST_BLOSSOM_POW_TARGET_SPACING,
};

Duration::seconds(spacing_seconds)
}

/// Returns the target block spacing for `network` and `height`.
///
/// See `target_spacing` for details.
pub fn target_spacing_for_height(network: Network, height: block::Height) -> Duration {
NetworkUpgrade::current(network, height).target_spacing()
}

/// Returns the minimum difficulty block spacing for `network` and `height`.
/// Returns `None` if the testnet minimum difficulty consensus rule is not active.
///
/// Based on https://zips.z.cash/zip-0208#minimum-difficulty-blocks-on-the-test-network
///
/// `zcashd` requires a gap that's strictly greater than 6 times the target
/// threshold, but ZIP-205 and ZIP-208 are ambiguous. See bug #1276.
pub fn minimum_difficulty_spacing_for_height(
network: Network,
height: block::Height,
) -> Option<Duration> {
match (network, height) {
(_, height) if height < TESTNET_MINIMUM_DIFFICULTY_START_HEIGHT => None,
(Network::Mainnet, _) => None,
(Network::Testnet, _) => {
let network_upgrade = NetworkUpgrade::current(network, height);
Some(network_upgrade.target_spacing() * TESTNET_MINIMUM_DIFFICULTY_GAP_MULTIPLIER)
}
}
}
}

impl ConsensusBranchId {
Expand Down
14 changes: 4 additions & 10 deletions zebra-consensus/src/parameters/subsidy.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! Constants for Block Subsidy, Funding Streams, and Founders’ Reward
use std::time::Duration;

use zebra_chain::{amount::COIN, block::Height};

/// An initial period from Genesis to this Height where the block subsidy is gradually incremented. [What is slow-start mining][slow-mining]
Expand All @@ -22,15 +20,11 @@ pub const SLOW_START_SHIFT: Height = Height(SLOW_START_INTERVAL.0 / 2);
/// This calculation is exact, because COIN is divisible by 2, and the division is done last.
pub const MAX_BLOCK_SUBSIDY: u64 = ((25 * COIN) / 2) as u64;

/// The blocktime before Blossom, used to calculate ratio.
pub const PRE_BLOSSOM_POW_TARGET_SPACING: Duration = Duration::from_secs(150);

/// The blocktime after Blossom, used to calculate ratio.
pub const POST_BLOSSOM_POW_TARGET_SPACING: Duration = Duration::from_secs(75);

/// Used as a multiplier to get the new halving interval after Blossom.
pub const BLOSSOM_POW_TARGET_SPACING_RATIO: u64 =
PRE_BLOSSOM_POW_TARGET_SPACING.as_secs() / POST_BLOSSOM_POW_TARGET_SPACING.as_secs();
///
/// Calculated as `PRE_BLOSSOM_POW_TARGET_SPACING / POST_BLOSSOM_POW_TARGET_SPACING`
/// in the Zcash specification.
pub const BLOSSOM_POW_TARGET_SPACING_RATIO: u64 = 2;

/// Halving is at about every 4 years, before Blossom block time is 150 seconds.
///
Expand Down

0 comments on commit a0bbca4

Please sign in to comment.