Skip to main content

solana_stake_interface/
stake_flags.rs

1#[cfg(feature = "borsh")]
2use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
3
4/// Additional flags for stake state.
5#[repr(transparent)]
6#[cfg_attr(feature = "codama", derive(codama_macros::CodamaType))]
7#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Debug)]
8#[cfg_attr(
9    feature = "frozen-abi",
10    derive(
11        solana_frozen_abi_macro::AbiExample,
12        solana_frozen_abi_macro::StableAbi,
13        solana_frozen_abi_macro::StableAbiSample
14    )
15)]
16#[cfg_attr(
17    feature = "borsh",
18    derive(BorshSerialize, BorshDeserialize, BorshSchema),
19    borsh(crate = "borsh")
20)]
21#[cfg_attr(
22    feature = "serde",
23    derive(serde_derive::Deserialize, serde_derive::Serialize)
24)]
25#[cfg_attr(feature = "wincode", derive(wincode::SchemaRead, wincode::SchemaWrite))]
26pub struct StakeFlags {
27    bits: u8,
28}
29
30/// Currently, only bit 1 is used. The other 7 bits are reserved for future usage.
31impl StakeFlags {
32    ///  Stake must be fully activated before deactivation is allowed (bit 1).
33    #[deprecated(
34        since = "2.1.0",
35        note = "This flag will be removed because it was only used for `redelegate`, which will not be enabled."
36    )]
37    pub const MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED: Self =
38        Self { bits: 0b0000_0001 };
39
40    pub const fn empty() -> Self {
41        Self { bits: 0 }
42    }
43
44    pub const fn contains(&self, other: Self) -> bool {
45        (self.bits & other.bits) == other.bits
46    }
47
48    pub fn remove(&mut self, other: Self) {
49        self.bits &= !other.bits;
50    }
51
52    pub fn set(&mut self, other: Self) {
53        self.bits |= other.bits;
54    }
55
56    pub const fn union(self, other: Self) -> Self {
57        Self {
58            bits: self.bits | other.bits,
59        }
60    }
61}
62
63impl Default for StakeFlags {
64    fn default() -> Self {
65        StakeFlags::empty()
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    #[allow(deprecated)]
75    fn test_stake_flags() {
76        let mut f = StakeFlags::empty();
77        assert!(!f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
78
79        f.set(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED);
80        assert!(f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
81
82        f.remove(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED);
83        assert!(!f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
84
85        let f1 = StakeFlags::empty();
86        let f2 = StakeFlags::empty();
87        let f3 = f1.union(f2);
88        assert!(!f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
89
90        let f1 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
91        let f2 = StakeFlags::empty();
92        let f3 = f1.union(f2);
93        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
94
95        let f1 = StakeFlags::empty();
96        let f2 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
97        let f3 = f1.union(f2);
98        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
99
100        let f1 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
101        let f2 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
102        let f3 = f1.union(f2);
103        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
104    }
105}