solana_commitment_config/
lib.rs

1//! Definitions of commitment levels.
2#![no_std]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4use core::{fmt, str::FromStr};
5
6#[cfg_attr(
7    feature = "serde",
8    derive(serde_derive::Serialize, serde_derive::Deserialize),
9    serde(rename_all = "camelCase")
10)]
11#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)]
12pub struct CommitmentConfig {
13    pub commitment: CommitmentLevel,
14}
15
16impl CommitmentConfig {
17    pub const fn finalized() -> Self {
18        Self {
19            commitment: CommitmentLevel::Finalized,
20        }
21    }
22
23    pub const fn confirmed() -> Self {
24        Self {
25            commitment: CommitmentLevel::Confirmed,
26        }
27    }
28
29    pub const fn processed() -> Self {
30        Self {
31            commitment: CommitmentLevel::Processed,
32        }
33    }
34
35    pub fn ok(self) -> Option<Self> {
36        if self == Self::default() {
37            None
38        } else {
39            Some(self)
40        }
41    }
42
43    pub fn is_finalized(&self) -> bool {
44        self.commitment == CommitmentLevel::Finalized
45    }
46
47    pub fn is_confirmed(&self) -> bool {
48        self.commitment == CommitmentLevel::Confirmed
49    }
50
51    pub fn is_processed(&self) -> bool {
52        self.commitment == CommitmentLevel::Processed
53    }
54
55    pub fn is_at_least_confirmed(&self) -> bool {
56        self.is_confirmed() || self.is_finalized()
57    }
58}
59
60impl FromStr for CommitmentConfig {
61    type Err = ParseCommitmentLevelError;
62
63    fn from_str(s: &str) -> Result<Self, Self::Err> {
64        CommitmentLevel::from_str(s).map(|commitment| Self { commitment })
65    }
66}
67
68#[cfg_attr(
69    feature = "serde",
70    derive(serde_derive::Serialize, serde_derive::Deserialize),
71    serde(rename_all = "camelCase")
72)]
73#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
74/// An attribute of a slot. It describes how finalized a block is at some point in time. For example, a slot
75/// is said to be at the max level immediately after the cluster recognizes the block at that slot as
76/// finalized. When querying the ledger state, use lower levels of commitment to report progress and higher
77/// levels to ensure state changes will not be rolled back.
78pub enum CommitmentLevel {
79    /// The highest slot of the heaviest fork processed by the node. Ledger state at this slot is
80    /// not derived from a confirmed or finalized block, but if multiple forks are present, is from
81    /// the fork the validator believes is most likely to finalize.
82    Processed,
83
84    /// The highest slot that has been voted on by supermajority of the cluster, ie. is confirmed.
85    /// Confirmation incorporates votes from gossip and replay. It does not count votes on
86    /// descendants of a block, only direct votes on that block, and upholds "optimistic
87    /// confirmation" guarantees in release 1.3 and onwards.
88    Confirmed,
89
90    /// The highest slot having reached max vote lockout, as recognized by a supermajority of the
91    /// cluster.
92    Finalized,
93}
94
95impl Default for CommitmentLevel {
96    fn default() -> Self {
97        Self::Finalized
98    }
99}
100
101impl FromStr for CommitmentLevel {
102    type Err = ParseCommitmentLevelError;
103
104    fn from_str(s: &str) -> Result<Self, Self::Err> {
105        match s {
106            "processed" => Ok(CommitmentLevel::Processed),
107            "confirmed" => Ok(CommitmentLevel::Confirmed),
108            "finalized" => Ok(CommitmentLevel::Finalized),
109            _ => Err(ParseCommitmentLevelError::Invalid),
110        }
111    }
112}
113
114impl fmt::Display for CommitmentLevel {
115    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116        let s = match self {
117            CommitmentLevel::Processed => "processed",
118            CommitmentLevel::Confirmed => "confirmed",
119            CommitmentLevel::Finalized => "finalized",
120        };
121        write!(f, "{s}")
122    }
123}
124
125#[derive(Debug)]
126pub enum ParseCommitmentLevelError {
127    Invalid,
128}
129
130impl core::error::Error for ParseCommitmentLevelError {}
131
132impl fmt::Display for ParseCommitmentLevelError {
133    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134        match self {
135            Self::Invalid => f.write_str("invalid variant"),
136        }
137    }
138}