Skip to main content

atlas_vote_interface/state/
vote_instruction_data.rs

1#[cfg(feature = "frozen-abi")]
2use atlas_frozen_abi_macro::{frozen_abi, AbiExample};
3use {
4    crate::state::{
5        Lockout, BLS_PROOF_OF_POSSESSION_COMPRESSED_SIZE, BLS_PUBLIC_KEY_COMPRESSED_SIZE,
6        MAX_LOCKOUT_HISTORY,
7    },
8    atlas_clock::{Slot, UnixTimestamp},
9    atlas_hash::Hash,
10    atlas_pubkey::Pubkey,
11    std::{collections::VecDeque, fmt::Debug},
12};
13#[cfg(feature = "serde")]
14use {
15    serde_derive::{Deserialize, Serialize},
16    serde_with::serde_as,
17};
18
19#[cfg_attr(
20    feature = "frozen-abi",
21    frozen_abi(digest = "GvUzgtcxhKVVxPAjSntXGPqjLZK5ovgZzCiUP1tDpB9q"),
22    derive(AbiExample)
23)]
24#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
25#[derive(Default, Debug, PartialEq, Eq, Clone)]
26pub struct Vote {
27    /// A stack of votes starting with the oldest vote
28    pub slots: Vec<Slot>,
29    /// signature of the bank's state at the last slot
30    pub hash: Hash,
31    /// processing timestamp of last slot
32    pub timestamp: Option<UnixTimestamp>,
33}
34
35impl Vote {
36    pub fn new(slots: Vec<Slot>, hash: Hash) -> Self {
37        Self {
38            slots,
39            hash,
40            timestamp: None,
41        }
42    }
43
44    pub fn last_voted_slot(&self) -> Option<Slot> {
45        self.slots.last().copied()
46    }
47}
48
49#[cfg_attr(
50    feature = "frozen-abi",
51    frozen_abi(digest = "CxyuwbaEdzP7jDCZyxjgQvLGXadBUZF3LoUvbSpQ6tYN"),
52    derive(AbiExample)
53)]
54#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
55#[derive(Default, Debug, PartialEq, Eq, Clone)]
56pub struct VoteStateUpdate {
57    /// The proposed tower
58    pub lockouts: VecDeque<Lockout>,
59    /// The proposed root
60    pub root: Option<Slot>,
61    /// signature of the bank's state at the last slot
62    pub hash: Hash,
63    /// processing timestamp of last slot
64    pub timestamp: Option<UnixTimestamp>,
65}
66
67impl From<Vec<(Slot, u32)>> for VoteStateUpdate {
68    fn from(recent_slots: Vec<(Slot, u32)>) -> Self {
69        let lockouts: VecDeque<Lockout> = recent_slots
70            .into_iter()
71            .map(|(slot, confirmation_count)| {
72                Lockout::new_with_confirmation_count(slot, confirmation_count)
73            })
74            .collect();
75        Self {
76            lockouts,
77            root: None,
78            hash: Hash::default(),
79            timestamp: None,
80        }
81    }
82}
83
84impl VoteStateUpdate {
85    pub fn new(lockouts: VecDeque<Lockout>, root: Option<Slot>, hash: Hash) -> Self {
86        Self {
87            lockouts,
88            root,
89            hash,
90            timestamp: None,
91        }
92    }
93
94    pub fn slots(&self) -> Vec<Slot> {
95        self.lockouts.iter().map(|lockout| lockout.slot()).collect()
96    }
97
98    pub fn last_voted_slot(&self) -> Option<Slot> {
99        self.lockouts.back().map(|l| l.slot())
100    }
101}
102
103#[cfg_attr(
104    feature = "frozen-abi",
105    frozen_abi(digest = "6UDiQMH4wbNwkMHosPMtekMYu2Qa6CHPZ2ymK4mc6FGu"),
106    derive(AbiExample)
107)]
108#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
109#[derive(Default, Debug, PartialEq, Eq, Clone)]
110pub struct TowerSync {
111    /// The proposed tower
112    pub lockouts: VecDeque<Lockout>,
113    /// The proposed root
114    pub root: Option<Slot>,
115    /// signature of the bank's state at the last slot
116    pub hash: Hash,
117    /// processing timestamp of last slot
118    pub timestamp: Option<UnixTimestamp>,
119    /// the unique identifier for the chain up to and
120    /// including this block. Does not require replaying
121    /// in order to compute.
122    pub block_id: Hash,
123}
124
125impl From<Vec<(Slot, u32)>> for TowerSync {
126    fn from(recent_slots: Vec<(Slot, u32)>) -> Self {
127        let lockouts: VecDeque<Lockout> = recent_slots
128            .into_iter()
129            .map(|(slot, confirmation_count)| {
130                Lockout::new_with_confirmation_count(slot, confirmation_count)
131            })
132            .collect();
133        Self {
134            lockouts,
135            root: None,
136            hash: Hash::default(),
137            timestamp: None,
138            block_id: Hash::default(),
139        }
140    }
141}
142
143impl TowerSync {
144    pub fn new(
145        lockouts: VecDeque<Lockout>,
146        root: Option<Slot>,
147        hash: Hash,
148        block_id: Hash,
149    ) -> Self {
150        Self {
151            lockouts,
152            root,
153            hash,
154            timestamp: None,
155            block_id,
156        }
157    }
158
159    /// Creates a tower with consecutive votes for `slot - MAX_LOCKOUT_HISTORY + 1` to `slot` inclusive.
160    /// If `slot >= MAX_LOCKOUT_HISTORY`, sets the root to `(slot - MAX_LOCKOUT_HISTORY)`
161    /// Sets the hash to `hash` and leaves `block_id` unset.
162    pub fn new_from_slot(slot: Slot, hash: Hash) -> Self {
163        let lowest_slot = slot
164            .saturating_add(1)
165            .saturating_sub(MAX_LOCKOUT_HISTORY as u64);
166        let slots: Vec<_> = (lowest_slot..slot.saturating_add(1)).collect();
167        Self::new_from_slots(
168            slots,
169            hash,
170            (lowest_slot > 0).then(|| lowest_slot.saturating_sub(1)),
171        )
172    }
173
174    /// Creates a tower with consecutive confirmation for `slots`
175    pub fn new_from_slots(slots: Vec<Slot>, hash: Hash, root: Option<Slot>) -> Self {
176        let lockouts: VecDeque<Lockout> = slots
177            .into_iter()
178            .rev()
179            .enumerate()
180            .map(|(cc, s)| Lockout::new_with_confirmation_count(s, cc.saturating_add(1) as u32))
181            .rev()
182            .collect();
183        Self {
184            lockouts,
185            hash,
186            root,
187            timestamp: None,
188            block_id: Hash::default(),
189        }
190    }
191
192    pub fn slots(&self) -> Vec<Slot> {
193        self.lockouts.iter().map(|lockout| lockout.slot()).collect()
194    }
195
196    pub fn last_voted_slot(&self) -> Option<Slot> {
197        self.lockouts.back().map(|l| l.slot())
198    }
199}
200
201#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
202#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
203pub struct VoteInit {
204    pub node_pubkey: Pubkey,
205    pub authorized_voter: Pubkey,
206    pub authorized_withdrawer: Pubkey,
207    pub commission: u8,
208}
209
210#[cfg_attr(feature = "serde", cfg_eval::cfg_eval, serde_as)]
211#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
212#[derive(Debug, PartialEq, Eq, Clone, Copy)]
213pub struct VoteInitV2 {
214    pub node_pubkey: Pubkey,
215    pub authorized_voter: Pubkey,
216    #[cfg_attr(
217        feature = "serde",
218        serde_as(as = "[_; BLS_PUBLIC_KEY_COMPRESSED_SIZE]")
219    )]
220    pub authorized_voter_bls_pubkey: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
221    #[cfg_attr(
222        feature = "serde",
223        serde_as(as = "[_; BLS_PROOF_OF_POSSESSION_COMPRESSED_SIZE]")
224    )]
225    pub authorized_voter_bls_proof_of_possession: [u8; BLS_PROOF_OF_POSSESSION_COMPRESSED_SIZE],
226    pub authorized_withdrawer: Pubkey,
227    pub inflation_rewards_commission_bps: u16,
228    pub inflation_rewards_collector: Pubkey,
229    pub block_revenue_commission_bps: u16,
230    pub block_revenue_collector: Pubkey,
231}
232
233impl Default for VoteInitV2 {
234    fn default() -> Self {
235        Self {
236            node_pubkey: Pubkey::default(),
237            authorized_voter: Pubkey::default(),
238            authorized_voter_bls_pubkey: [0u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
239            authorized_voter_bls_proof_of_possession: [0u8;
240                BLS_PROOF_OF_POSSESSION_COMPRESSED_SIZE],
241            authorized_withdrawer: Pubkey::default(),
242            inflation_rewards_commission_bps: 0,
243            inflation_rewards_collector: Pubkey::default(),
244            block_revenue_commission_bps: 0,
245            block_revenue_collector: Pubkey::default(),
246        }
247    }
248}
249
250#[cfg_attr(feature = "serde", cfg_eval::cfg_eval, serde_as)]
251#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
252#[derive(Debug, PartialEq, Eq, Clone, Copy)]
253pub struct VoterWithBLSArgs {
254    #[cfg_attr(
255        feature = "serde",
256        serde_as(as = "[_; BLS_PUBLIC_KEY_COMPRESSED_SIZE]")
257    )]
258    pub bls_pubkey: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
259    #[cfg_attr(
260        feature = "serde",
261        serde_as(as = "[_; BLS_PROOF_OF_POSSESSION_COMPRESSED_SIZE]")
262    )]
263    pub bls_proof_of_possession: [u8; BLS_PROOF_OF_POSSESSION_COMPRESSED_SIZE],
264}
265
266impl Default for VoterWithBLSArgs {
267    fn default() -> Self {
268        Self {
269            bls_pubkey: [0u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
270            bls_proof_of_possession: [0u8; BLS_PROOF_OF_POSSESSION_COMPRESSED_SIZE],
271        }
272    }
273}
274
275#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
276#[derive(Debug, PartialEq, Eq, Clone, Copy)]
277pub enum VoteAuthorize {
278    Voter,
279    Withdrawer,
280    VoterWithBLS(VoterWithBLSArgs),
281}
282
283#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
284#[derive(Debug, PartialEq, Eq, Clone)]
285pub struct VoteAuthorizeWithSeedArgs {
286    pub authorization_type: VoteAuthorize,
287    pub current_authority_derived_key_owner: Pubkey,
288    pub current_authority_derived_key_seed: String,
289    pub new_authority: Pubkey,
290}
291
292#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
293#[derive(Debug, PartialEq, Eq, Clone)]
294pub struct VoteAuthorizeCheckedWithSeedArgs {
295    pub authorization_type: VoteAuthorize,
296    pub current_authority_derived_key_owner: Pubkey,
297    pub current_authority_derived_key_seed: String,
298}