use super::{Network, NetworkExt as _};
#[cfg(doc)]
use crate::pow::CompactTarget;
use crate::pow::Target;
use crate::BlockHeight;
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct Params {
pub network: Network,
pub bip34_height: BlockHeight,
pub bip65_height: BlockHeight,
pub bip66_height: BlockHeight,
pub csv_height: BlockHeight,
pub segwit_height: BlockHeight,
pub auxpow_start_height: Option<BlockHeight>,
pub auxpow_chain_id: u32,
pub strict_auxpow_chain_id: bool,
pub subsidy_initial_interval: u32,
pub enforce_bip94: bool,
pub max_attainable_target: Target,
pub pow_target_spacing: u32,
pub pow_target_timespan: u32,
pub allow_min_difficulty_blocks: bool,
pub pow_allow_min_difficulty_blocks_after_height: Option<BlockHeight>,
pub pow_averaging_window: u32,
pub pow_max_adjust_down: u32,
pub pow_max_adjust_up: u32,
pub no_pow_retargeting: bool,
}
pub static MAINNET: Params = Params::MAINNET;
pub static TESTNET: Params = Params::TESTNET;
pub static REGTEST: Params = Params::REGTEST;
impl Params {
pub const MAINNET: Self = Self {
network: Network::Tidecoin,
bip34_height: BlockHeight::from_u32(1),
bip65_height: BlockHeight::from_u32(1),
bip66_height: BlockHeight::from_u32(1),
csv_height: BlockHeight::from_u32(1),
segwit_height: BlockHeight::from_u32(1),
auxpow_start_height: None,
auxpow_chain_id: 8,
strict_auxpow_chain_id: true,
subsidy_initial_interval: crate::blockdata::constants::SUBSIDY_INITIAL_INTERVAL,
enforce_bip94: false,
max_attainable_target: Target::MAX_ATTAINABLE_MAINNET,
pow_target_spacing: 60,
pow_target_timespan: 432_000,
allow_min_difficulty_blocks: false,
pow_allow_min_difficulty_blocks_after_height: None,
pow_averaging_window: 17,
pow_max_adjust_down: 32,
pow_max_adjust_up: 16,
no_pow_retargeting: false,
};
pub const TESTNET: Self = Self {
network: Network::Testnet,
bip34_height: BlockHeight::from_u32(1),
bip65_height: BlockHeight::from_u32(1),
bip66_height: BlockHeight::from_u32(1),
csv_height: BlockHeight::from_u32(1),
segwit_height: BlockHeight::from_u32(1),
auxpow_start_height: Some(BlockHeight::from_u32(1000)),
auxpow_chain_id: 8,
strict_auxpow_chain_id: true,
subsidy_initial_interval: crate::blockdata::constants::SUBSIDY_INITIAL_INTERVAL,
enforce_bip94: false,
max_attainable_target: Target::MAX_ATTAINABLE_MAINNET,
pow_target_spacing: 60,
pow_target_timespan: 432_000,
allow_min_difficulty_blocks: true,
pow_allow_min_difficulty_blocks_after_height: None,
pow_averaging_window: 17,
pow_max_adjust_down: 32,
pow_max_adjust_up: 16,
no_pow_retargeting: false,
};
pub const REGTEST: Self = Self {
network: Network::Regtest,
bip34_height: BlockHeight::from_u32(1),
bip65_height: BlockHeight::from_u32(1),
bip66_height: BlockHeight::from_u32(1),
csv_height: BlockHeight::from_u32(1),
segwit_height: BlockHeight::from_u32(0),
auxpow_start_height: Some(BlockHeight::from_u32(0)),
auxpow_chain_id: 8,
strict_auxpow_chain_id: true,
subsidy_initial_interval: 20,
enforce_bip94: true,
max_attainable_target: Target::MAX_ATTAINABLE_REGTEST,
pow_target_spacing: 60,
pow_target_timespan: 14_400,
allow_min_difficulty_blocks: true,
pow_allow_min_difficulty_blocks_after_height: None,
pow_averaging_window: 17,
pow_max_adjust_down: 0,
pow_max_adjust_up: 0,
no_pow_retargeting: true,
};
pub const fn new(network: Network) -> Self {
match network {
Network::Tidecoin => Self::MAINNET,
Network::Testnet => Self::TESTNET,
Network::Regtest => Self::REGTEST,
}
}
pub fn difficulty_adjustment_interval(&self) -> u32 {
self.pow_target_timespan / self.pow_target_spacing
}
}
impl From<Network> for Params {
fn from(value: Network) -> Self {
Self::new(value)
}
}
impl From<&Network> for Params {
fn from(value: &Network) -> Self {
Self::new(*value)
}
}
impl From<Network> for &'static Params {
fn from(value: Network) -> Self {
value.params()
}
}
impl From<&Network> for &'static Params {
fn from(value: &Network) -> Self {
value.params()
}
}
impl AsRef<Self> for Params {
fn as_ref(&self) -> &Self {
self
}
}
impl AsRef<Params> for Network {
fn as_ref(&self) -> &Params {
Self::params(*self)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::blockdata::constants::genesis_block;
use crate::pow::Target;
fn assert_chainparam_sanity(params: &'static Params) {
assert_eq!(params.pow_target_timespan % params.pow_target_spacing, 0);
assert_ne!(params.subsidy_initial_interval, 0);
let genesis_target = Target::from(genesis_block(params).header().bits);
assert!(genesis_target <= params.max_attainable_target);
}
#[test]
fn mainnet_chainparams_sanity() {
assert_chainparam_sanity(&Params::MAINNET);
}
#[test]
fn testnet_chainparams_sanity() {
assert_chainparam_sanity(&Params::TESTNET);
}
#[test]
fn regtest_chainparams_sanity() {
assert_chainparam_sanity(&Params::REGTEST);
}
}