solana_program/stake/
stake_flags.rs

1#[cfg(feature = "borsh")]
2use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
3
4/// Additional flags for stake state.
5#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
6#[cfg_attr(
7    feature = "borsh",
8    derive(BorshSerialize, BorshDeserialize, BorshSchema),
9    borsh(crate = "borsh")
10)]
11#[derive(Serialize, Deserialize, Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Debug)]
12pub struct StakeFlags {
13    bits: u8,
14}
15
16#[cfg(feature = "borsh")]
17impl borsh0_10::de::BorshDeserialize for StakeFlags {
18    fn deserialize_reader<R: borsh0_10::maybestd::io::Read>(
19        reader: &mut R,
20    ) -> ::core::result::Result<Self, borsh0_10::maybestd::io::Error> {
21        Ok(Self {
22            bits: borsh0_10::BorshDeserialize::deserialize_reader(reader)?,
23        })
24    }
25}
26
27#[cfg(feature = "borsh")]
28impl borsh0_10::BorshSchema for StakeFlags {
29    fn declaration() -> borsh0_10::schema::Declaration {
30        "StakeFlags".to_string()
31    }
32    fn add_definitions_recursively(
33        definitions: &mut borsh0_10::maybestd::collections::HashMap<
34            borsh0_10::schema::Declaration,
35            borsh0_10::schema::Definition,
36        >,
37    ) {
38        let fields = borsh0_10::schema::Fields::NamedFields(<[_]>::into_vec(
39            borsh0_10::maybestd::boxed::Box::new([(
40                "bits".to_string(),
41                <u8 as borsh0_10::BorshSchema>::declaration(),
42            )]),
43        ));
44        let definition = borsh0_10::schema::Definition::Struct { fields };
45        Self::add_definition(
46            <Self as borsh0_10::BorshSchema>::declaration(),
47            definition,
48            definitions,
49        );
50        <u8 as borsh0_10::BorshSchema>::add_definitions_recursively(definitions);
51    }
52}
53
54#[cfg(feature = "borsh")]
55impl borsh0_10::ser::BorshSerialize for StakeFlags {
56    fn serialize<W: borsh0_10::maybestd::io::Write>(
57        &self,
58        writer: &mut W,
59    ) -> ::core::result::Result<(), borsh0_10::maybestd::io::Error> {
60        borsh0_10::BorshSerialize::serialize(&self.bits, writer)?;
61        Ok(())
62    }
63}
64
65/// Currently, only bit 1 is used. The other 7 bits are reserved for future usage.
66impl StakeFlags {
67    ///  Stake must be fully activated before deactivation is allowed (bit 1).
68    #[deprecated(
69        since = "2.1.0",
70        note = "This flag will be removed because it was only used for `redelegate`, which will not be enabled."
71    )]
72    pub const MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED: Self =
73        Self { bits: 0b0000_0001 };
74
75    pub const fn empty() -> Self {
76        Self { bits: 0 }
77    }
78
79    pub const fn contains(&self, other: Self) -> bool {
80        (self.bits & other.bits) == other.bits
81    }
82
83    pub fn remove(&mut self, other: Self) {
84        self.bits &= !other.bits;
85    }
86
87    pub fn set(&mut self, other: Self) {
88        self.bits |= other.bits;
89    }
90
91    pub const fn union(self, other: Self) -> Self {
92        Self {
93            bits: self.bits | other.bits,
94        }
95    }
96}
97
98impl Default for StakeFlags {
99    fn default() -> Self {
100        StakeFlags::empty()
101    }
102}
103
104#[cfg(test)]
105mod test {
106    use super::*;
107
108    #[test]
109    #[allow(deprecated)]
110    fn test_stake_flags() {
111        let mut f = StakeFlags::empty();
112        assert!(!f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
113
114        f.set(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED);
115        assert!(f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
116
117        f.remove(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED);
118        assert!(!f.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
119
120        let f1 = StakeFlags::empty();
121        let f2 = StakeFlags::empty();
122        let f3 = f1.union(f2);
123        assert!(!f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
124
125        let f1 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
126        let f2 = StakeFlags::empty();
127        let f3 = f1.union(f2);
128        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
129
130        let f1 = StakeFlags::empty();
131        let f2 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
132        let f3 = f1.union(f2);
133        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
134
135        let f1 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
136        let f2 = StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED;
137        let f3 = f1.union(f2);
138        assert!(f3.contains(StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED));
139    }
140}