use std::sync::OnceLock;
use dusk_core::signatures::bls::BlsVersion;
const NEVER: u64 = u64::MAX;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum HardFork {
PreFork,
Aegis,
}
impl HardFork {
pub fn bls_version(&self) -> BlsVersion {
match self {
HardFork::Aegis => BlsVersion::V2,
HardFork::PreFork => BlsVersion::V1,
}
}
}
pub fn bls_version_at(block_height: u64) -> BlsVersion {
hard_fork_at(block_height).bls_version()
}
static AEGIS_ACTIVATION_HEIGHT: OnceLock<u64> = OnceLock::new();
pub fn set_aegis_activation_height(block_height: u64) {
if let Some(existing) = AEGIS_ACTIVATION_HEIGHT.get() {
debug_assert_eq!(
*existing, block_height,
"Aegis activation height changed after initialization"
);
return;
}
let _ = AEGIS_ACTIVATION_HEIGHT.set(block_height);
}
fn aegis_activation_height() -> u64 {
*AEGIS_ACTIVATION_HEIGHT.get().unwrap_or(&NEVER)
}
pub fn hard_fork_at(block_height: u64) -> HardFork {
if block_height >= aegis_activation_height() {
HardFork::Aegis
} else {
HardFork::PreFork
}
}
#[cfg(test)]
pub(crate) const fn hard_fork_at_with_activation(
block_height: u64,
aegis_activation_height: u64,
) -> HardFork {
if block_height >= aegis_activation_height {
HardFork::Aegis
} else {
HardFork::PreFork
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn aegis_activation_boundary() {
assert_eq!(hard_fork_at_with_activation(99, 100), HardFork::PreFork);
assert_eq!(hard_fork_at_with_activation(100, 100), HardFork::Aegis);
assert_eq!(hard_fork_at_with_activation(101, 100), HardFork::Aegis);
assert_eq!(hard_fork_at_with_activation(101, NEVER), HardFork::PreFork);
}
}