waffles_solana_sdk/
commitment_config.rs

1//! Definitions of commitment levels.
2
3#![allow(deprecated)]
4#![cfg(feature = "full")]
5
6use {std::str::FromStr, thiserror::Error};
7
8#[derive(Serialize, Deserialize, Default, Clone, Copy, Debug, PartialEq, Eq, Hash)]
9#[serde(rename_all = "camelCase")]
10pub struct CommitmentConfig {
11    pub commitment: CommitmentLevel,
12}
13
14impl CommitmentConfig {
15    #[deprecated(
16        since = "1.5.5",
17        note = "Please use CommitmentConfig::processed() instead"
18    )]
19    pub fn recent() -> Self {
20        Self {
21            commitment: CommitmentLevel::Recent,
22        }
23    }
24
25    #[deprecated(
26        since = "1.5.5",
27        note = "Please use CommitmentConfig::finalized() instead"
28    )]
29    pub fn max() -> Self {
30        Self {
31            commitment: CommitmentLevel::Max,
32        }
33    }
34
35    #[deprecated(
36        since = "1.5.5",
37        note = "Please use CommitmentConfig::finalized() instead"
38    )]
39    pub fn root() -> Self {
40        Self {
41            commitment: CommitmentLevel::Root,
42        }
43    }
44
45    #[deprecated(
46        since = "1.5.5",
47        note = "Please use CommitmentConfig::confirmed() instead"
48    )]
49    pub fn single() -> Self {
50        Self {
51            commitment: CommitmentLevel::Single,
52        }
53    }
54
55    #[deprecated(
56        since = "1.5.5",
57        note = "Please use CommitmentConfig::confirmed() instead"
58    )]
59    pub fn single_gossip() -> Self {
60        Self {
61            commitment: CommitmentLevel::SingleGossip,
62        }
63    }
64
65    pub const fn finalized() -> Self {
66        Self {
67            commitment: CommitmentLevel::Finalized,
68        }
69    }
70
71    pub const fn confirmed() -> Self {
72        Self {
73            commitment: CommitmentLevel::Confirmed,
74        }
75    }
76
77    pub const fn processed() -> Self {
78        Self {
79            commitment: CommitmentLevel::Processed,
80        }
81    }
82
83    pub fn ok(self) -> Option<Self> {
84        if self == Self::default() {
85            None
86        } else {
87            Some(self)
88        }
89    }
90
91    pub fn is_finalized(&self) -> bool {
92        matches!(
93            &self.commitment,
94            CommitmentLevel::Finalized | CommitmentLevel::Max | CommitmentLevel::Root
95        )
96    }
97
98    pub fn is_confirmed(&self) -> bool {
99        matches!(
100            &self.commitment,
101            CommitmentLevel::Confirmed | CommitmentLevel::SingleGossip | CommitmentLevel::Single
102        )
103    }
104
105    pub fn is_processed(&self) -> bool {
106        matches!(
107            &self.commitment,
108            CommitmentLevel::Processed | CommitmentLevel::Recent
109        )
110    }
111
112    pub fn is_at_least_confirmed(&self) -> bool {
113        self.is_confirmed() || self.is_finalized()
114    }
115
116    pub fn use_deprecated_commitment(commitment: CommitmentConfig) -> Self {
117        match commitment.commitment {
118            CommitmentLevel::Finalized => CommitmentConfig::max(),
119            CommitmentLevel::Confirmed => CommitmentConfig::single_gossip(),
120            CommitmentLevel::Processed => CommitmentConfig::recent(),
121            _ => commitment,
122        }
123    }
124}
125
126impl FromStr for CommitmentConfig {
127    type Err = ParseCommitmentLevelError;
128
129    fn from_str(s: &str) -> Result<Self, Self::Err> {
130        CommitmentLevel::from_str(s).map(|commitment| Self { commitment })
131    }
132}
133
134#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash)]
135#[serde(rename_all = "camelCase")]
136/// An attribute of a slot. It describes how finalized a block is at some point in time. For example, a slot
137/// is said to be at the max level immediately after the cluster recognizes the block at that slot as
138/// finalized. When querying the ledger state, use lower levels of commitment to report progress and higher
139/// levels to ensure state changes will not be rolled back.
140pub enum CommitmentLevel {
141    /// (DEPRECATED) The highest slot having reached max vote lockout, as recognized by a supermajority of the cluster.
142    #[deprecated(
143        since = "1.5.5",
144        note = "Please use CommitmentLevel::Finalized instead"
145    )]
146    Max,
147
148    /// (DEPRECATED) The highest slot of the heaviest fork. Ledger state at this slot is not derived from a finalized
149    /// block, but if multiple forks are present, is from the fork the validator believes is most likely
150    /// to finalize.
151    #[deprecated(
152        since = "1.5.5",
153        note = "Please use CommitmentLevel::Processed instead"
154    )]
155    Recent,
156
157    /// (DEPRECATED) The highest slot having reached max vote lockout.
158    #[deprecated(
159        since = "1.5.5",
160        note = "Please use CommitmentLevel::Finalized instead"
161    )]
162    Root,
163
164    /// (DEPRECATED) The highest slot having reached 1 confirmation by supermajority of the cluster.
165    #[deprecated(
166        since = "1.5.5",
167        note = "Please use CommitmentLevel::Confirmed instead"
168    )]
169    Single,
170
171    /// (DEPRECATED) The highest slot that has been voted on by supermajority of the cluster
172    /// This differs from `single` in that:
173    /// 1) It incorporates votes from gossip and replay.
174    /// 2) It does not count votes on descendants of a block, only direct votes on that block.
175    /// 3) This confirmation level also upholds "optimistic confirmation" guarantees in
176    /// release 1.3 and onwards.
177    #[deprecated(
178        since = "1.5.5",
179        note = "Please use CommitmentLevel::Confirmed instead"
180    )]
181    SingleGossip,
182
183    /// The highest slot of the heaviest fork processed by the node. Ledger state at this slot is
184    /// not derived from a confirmed or finalized block, but if multiple forks are present, is from
185    /// the fork the validator believes is most likely to finalize.
186    Processed,
187
188    /// The highest slot that has been voted on by supermajority of the cluster, ie. is confirmed.
189    /// Confirmation incorporates votes from gossip and replay. It does not count votes on
190    /// descendants of a block, only direct votes on that block, and upholds "optimistic
191    /// confirmation" guarantees in release 1.3 and onwards.
192    Confirmed,
193
194    /// The highest slot having reached max vote lockout, as recognized by a supermajority of the
195    /// cluster.
196    Finalized,
197}
198
199impl Default for CommitmentLevel {
200    fn default() -> Self {
201        Self::Finalized
202    }
203}
204
205impl FromStr for CommitmentLevel {
206    type Err = ParseCommitmentLevelError;
207
208    fn from_str(s: &str) -> Result<Self, Self::Err> {
209        match s {
210            "max" => Ok(CommitmentLevel::Max),
211            "recent" => Ok(CommitmentLevel::Recent),
212            "root" => Ok(CommitmentLevel::Root),
213            "single" => Ok(CommitmentLevel::Single),
214            "singleGossip" => Ok(CommitmentLevel::SingleGossip),
215            "processed" => Ok(CommitmentLevel::Processed),
216            "confirmed" => Ok(CommitmentLevel::Confirmed),
217            "finalized" => Ok(CommitmentLevel::Finalized),
218            _ => Err(ParseCommitmentLevelError::Invalid),
219        }
220    }
221}
222
223impl std::fmt::Display for CommitmentLevel {
224    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
225        let s = match self {
226            CommitmentLevel::Max => "max",
227            CommitmentLevel::Recent => "recent",
228            CommitmentLevel::Root => "root",
229            CommitmentLevel::Single => "single",
230            CommitmentLevel::SingleGossip => "singleGossip",
231            CommitmentLevel::Processed => "processed",
232            CommitmentLevel::Confirmed => "confirmed",
233            CommitmentLevel::Finalized => "finalized",
234        };
235        write!(f, "{s}")
236    }
237}
238
239#[derive(Error, Debug)]
240pub enum ParseCommitmentLevelError {
241    #[error("invalid variant")]
242    Invalid,
243}