Skip to main content

dusk_vm/execute/
feature.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7use std::fmt::{self, Display, Formatter};
8
9use serde::{Deserialize, Serialize};
10
11/// Represents the activation condition for a feature or host query.
12///
13/// This enum defines when a specific feature or host query becomes active
14/// based on block heights. It can either be activated at a specific height
15/// or within specified ranges of block heights.
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17#[serde(untagged)]
18pub enum Activation {
19    /// Activation at a specific block height.
20    Height(u64),
21    /// Activation within specified ranges (including the lower and upper
22    /// bound) of block heights.
23    Ranges(Vec<(u64, u64)>),
24}
25
26impl Activation {
27    /// Checks if the feature is active at the given block height.
28    pub fn is_active_at(&self, height: u64) -> bool {
29        match self {
30            Activation::Height(activation_height) => {
31                height >= *activation_height
32            }
33            Activation::Ranges(ranges) => ranges
34                .iter()
35                .any(|(start, end)| height >= *start && height <= *end),
36        }
37    }
38
39    /// Unwraps the activation height.
40    ///
41    /// Panics if the activation is of type `Activation::Ranges`.
42    pub fn unwrap_height(&self) -> u64 {
43        match self {
44            Activation::Height(height) => *height,
45            Activation::Ranges(_) => {
46                panic!("Called unwrap_height on Activation::Ranges")
47            }
48        }
49    }
50
51    /// Unwraps the activation ranges.
52    ///
53    /// Panics if the activation is of type `Activation::Height`.
54    pub fn unwrap_ranges(&self) -> &[(u64, u64)] {
55        match self {
56            Activation::Height(_) => {
57                panic!("Called unwrap_height on Activation::Height")
58            }
59            Activation::Ranges(ranges) => &ranges[..],
60        }
61    }
62}
63
64impl From<u64> for Activation {
65    fn from(height: u64) -> Self {
66        Activation::Height(height)
67    }
68}
69
70impl From<Vec<(u64, u64)>> for Activation {
71    fn from(ranges: Vec<(u64, u64)>) -> Self {
72        Activation::Ranges(ranges)
73    }
74}
75
76impl Display for Activation {
77    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
78        match self {
79            Activation::Height(height) => {
80                write!(f, "Height({})", height)
81            }
82            Activation::Ranges(ranges) => {
83                let ranges_str = ranges
84                    .iter()
85                    .map(|(start, end)| format!("({start},{end})"))
86                    .collect::<Vec<_>>()
87                    .join(", ");
88                write!(f, "Ranges([{ranges_str}])")
89            }
90        }
91    }
92}