feature: Add the MinimumDifficulty consensus parameter

This commit is contained in:
teor 2020-07-28 09:39:00 +10:00
parent 04044be6d1
commit 396d209638
3 changed files with 82 additions and 0 deletions

View File

@ -10,9 +10,11 @@
//! `Network` and `BlockHeight`.
pub mod genesis;
pub mod minimum_difficulty;
pub mod network_upgrade;
pub use genesis::*;
pub use minimum_difficulty::*;
pub use network_upgrade::*;
#[cfg(test)]

View File

@ -0,0 +1,39 @@
//! The minimum difficulty block rule for Zcash.
use zebra_chain::types::BlockHeight;
use zebra_chain::{Network, Network::*};
/// The testnet block height when minimum difficulty blocks start being
/// accepted.
pub(crate) const TESTNET_MINIMUM_DIFFICULTY_HEIGHT: BlockHeight = BlockHeight(299_188);
/// The Zcash Testnet consensus rules were changed to allow
/// minimum-difficulty blocks, shortly after Testnet Sapling activation.
/// See ZIP-205 and ZIP-208 for details.
///
/// This change represents a hard-fork on Testnet, but it doesn't appear on
/// Mainnet, so we handle it as an independent consensus rule change.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum MinimumDifficulty {
/// Minimum difficulty blocks are rejected.
///
/// Always returned for Mainnet blocks.
Rejected,
/// Minimum difficulty blocks are allowed.
///
/// Only allowed for Testnet blocks.
AllowedOnTestnet,
}
impl MinimumDifficulty {
/// Returns the current minimum difficulty rule for `network` and `height`.
pub fn current(network: Network, height: BlockHeight) -> MinimumDifficulty {
use MinimumDifficulty::*;
match network {
Mainnet => Rejected,
Testnet if (height >= TESTNET_MINIMUM_DIFFICULTY_HEIGHT) => AllowedOnTestnet,
Testnet => Rejected,
}
}
}

View File

@ -183,3 +183,44 @@ fn branch_id_consistent(network: Network) {
}
}
}
#[test]
fn minimum_difficulty_mainnet() {
minimum_difficulty(Mainnet)
}
#[test]
fn minimum_difficulty_testnet() {
minimum_difficulty(Testnet)
}
/// Test MinimumDifficulty
fn minimum_difficulty(network: Network) {
use MinimumDifficulty::*;
let allowed_if_testnet = match network {
Mainnet => Rejected,
Testnet => AllowedOnTestnet,
};
assert_eq!(
MinimumDifficulty::current(network, BlockHeight(0)),
Rejected
);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight(299_187)),
Rejected
);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight(299_188)),
allowed_if_testnet
);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight(299_189)),
allowed_if_testnet
);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight::MAX),
allowed_if_testnet
);
}