dusk_node_data/
hard_fork.rs1use std::sync::OnceLock;
8
9use dusk_core::signatures::bls::BlsVersion;
10
11const NEVER: u64 = u64::MAX;
13
14#[derive(Debug, Clone, Copy, Eq, PartialEq)]
16pub enum HardFork {
17 PreFork,
19 Aegis,
21}
22
23impl HardFork {
24 pub fn bls_version(&self) -> BlsVersion {
26 match self {
27 HardFork::Aegis => BlsVersion::V2,
28 HardFork::PreFork => BlsVersion::V1,
29 }
30 }
31}
32
33pub fn bls_version_at(block_height: u64) -> BlsVersion {
35 hard_fork_at(block_height).bls_version()
36}
37
38static AEGIS_ACTIVATION_HEIGHT: OnceLock<u64> = OnceLock::new();
39
40pub fn set_aegis_activation_height(block_height: u64) {
42 if let Some(existing) = AEGIS_ACTIVATION_HEIGHT.get() {
43 debug_assert_eq!(
44 *existing, block_height,
45 "Aegis activation height changed after initialization"
46 );
47 return;
48 }
49
50 let _ = AEGIS_ACTIVATION_HEIGHT.set(block_height);
51}
52
53fn aegis_activation_height() -> u64 {
55 *AEGIS_ACTIVATION_HEIGHT.get().unwrap_or(&NEVER)
56}
57
58pub fn hard_fork_at(block_height: u64) -> HardFork {
60 if block_height >= aegis_activation_height() {
61 HardFork::Aegis
62 } else {
63 HardFork::PreFork
64 }
65}
66
67#[cfg(test)]
69pub(crate) const fn hard_fork_at_with_activation(
70 block_height: u64,
71 aegis_activation_height: u64,
72) -> HardFork {
73 if block_height >= aegis_activation_height {
74 HardFork::Aegis
75 } else {
76 HardFork::PreFork
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn aegis_activation_boundary() {
86 assert_eq!(hard_fork_at_with_activation(99, 100), HardFork::PreFork);
87 assert_eq!(hard_fork_at_with_activation(100, 100), HardFork::Aegis);
88 assert_eq!(hard_fork_at_with_activation(101, 100), HardFork::Aegis);
89 assert_eq!(hard_fork_at_with_activation(101, NEVER), HardFork::PreFork);
90 }
91}