solana_vote_interface/state/
vote_instruction_data.rs1#[cfg(feature = "serde")]
2use serde_derive::{Deserialize, Serialize};
3#[cfg(feature = "frozen-abi")]
4use solana_frozen_abi_macro::{frozen_abi, AbiExample};
5use {
6 crate::state::{Lockout, MAX_LOCKOUT_HISTORY},
7 solana_clock::{Slot, UnixTimestamp},
8 solana_hash::Hash,
9 solana_pubkey::Pubkey,
10 std::{collections::VecDeque, fmt::Debug},
11};
12
13#[cfg_attr(
14 feature = "frozen-abi",
15 frozen_abi(digest = "GvUzgtcxhKVVxPAjSntXGPqjLZK5ovgZzCiUP1tDpB9q"),
16 derive(AbiExample)
17)]
18#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
19#[derive(Default, Debug, PartialEq, Eq, Clone)]
20pub struct Vote {
21 pub slots: Vec<Slot>,
23 pub hash: Hash,
25 pub timestamp: Option<UnixTimestamp>,
27}
28
29impl Vote {
30 pub fn new(slots: Vec<Slot>, hash: Hash) -> Self {
31 Self {
32 slots,
33 hash,
34 timestamp: None,
35 }
36 }
37
38 pub fn last_voted_slot(&self) -> Option<Slot> {
39 self.slots.last().copied()
40 }
41}
42
43#[cfg_attr(
44 feature = "frozen-abi",
45 frozen_abi(digest = "CxyuwbaEdzP7jDCZyxjgQvLGXadBUZF3LoUvbSpQ6tYN"),
46 derive(AbiExample)
47)]
48#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
49#[derive(Default, Debug, PartialEq, Eq, Clone)]
50pub struct VoteStateUpdate {
51 pub lockouts: VecDeque<Lockout>,
53 pub root: Option<Slot>,
55 pub hash: Hash,
57 pub timestamp: Option<UnixTimestamp>,
59}
60
61impl From<Vec<(Slot, u32)>> for VoteStateUpdate {
62 fn from(recent_slots: Vec<(Slot, u32)>) -> Self {
63 let lockouts: VecDeque<Lockout> = recent_slots
64 .into_iter()
65 .map(|(slot, confirmation_count)| {
66 Lockout::new_with_confirmation_count(slot, confirmation_count)
67 })
68 .collect();
69 Self {
70 lockouts,
71 root: None,
72 hash: Hash::default(),
73 timestamp: None,
74 }
75 }
76}
77
78impl VoteStateUpdate {
79 pub fn new(lockouts: VecDeque<Lockout>, root: Option<Slot>, hash: Hash) -> Self {
80 Self {
81 lockouts,
82 root,
83 hash,
84 timestamp: None,
85 }
86 }
87
88 pub fn slots(&self) -> Vec<Slot> {
89 self.lockouts.iter().map(|lockout| lockout.slot()).collect()
90 }
91
92 pub fn last_voted_slot(&self) -> Option<Slot> {
93 self.lockouts.back().map(|l| l.slot())
94 }
95}
96
97#[cfg_attr(
98 feature = "frozen-abi",
99 frozen_abi(digest = "6UDiQMH4wbNwkMHosPMtekMYu2Qa6CHPZ2ymK4mc6FGu"),
100 derive(AbiExample)
101)]
102#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
103#[derive(Default, Debug, PartialEq, Eq, Clone)]
104pub struct TowerSync {
105 pub lockouts: VecDeque<Lockout>,
107 pub root: Option<Slot>,
109 pub hash: Hash,
111 pub timestamp: Option<UnixTimestamp>,
113 pub block_id: Hash,
117}
118
119impl From<Vec<(Slot, u32)>> for TowerSync {
120 fn from(recent_slots: Vec<(Slot, u32)>) -> Self {
121 let lockouts: VecDeque<Lockout> = recent_slots
122 .into_iter()
123 .map(|(slot, confirmation_count)| {
124 Lockout::new_with_confirmation_count(slot, confirmation_count)
125 })
126 .collect();
127 Self {
128 lockouts,
129 root: None,
130 hash: Hash::default(),
131 timestamp: None,
132 block_id: Hash::default(),
133 }
134 }
135}
136
137impl TowerSync {
138 pub fn new(
139 lockouts: VecDeque<Lockout>,
140 root: Option<Slot>,
141 hash: Hash,
142 block_id: Hash,
143 ) -> Self {
144 Self {
145 lockouts,
146 root,
147 hash,
148 timestamp: None,
149 block_id,
150 }
151 }
152
153 pub fn new_from_slot(slot: Slot, hash: Hash) -> Self {
157 let lowest_slot = slot
158 .saturating_add(1)
159 .saturating_sub(MAX_LOCKOUT_HISTORY as u64);
160 let slots: Vec<_> = (lowest_slot..slot.saturating_add(1)).collect();
161 Self::new_from_slots(
162 slots,
163 hash,
164 (lowest_slot > 0).then(|| lowest_slot.saturating_sub(1)),
165 )
166 }
167
168 pub fn new_from_slots(slots: Vec<Slot>, hash: Hash, root: Option<Slot>) -> Self {
170 let lockouts: VecDeque<Lockout> = slots
171 .into_iter()
172 .rev()
173 .enumerate()
174 .map(|(cc, s)| Lockout::new_with_confirmation_count(s, cc.saturating_add(1) as u32))
175 .rev()
176 .collect();
177 Self {
178 lockouts,
179 hash,
180 root,
181 timestamp: None,
182 block_id: Hash::default(),
183 }
184 }
185
186 pub fn slots(&self) -> Vec<Slot> {
187 self.lockouts.iter().map(|lockout| lockout.slot()).collect()
188 }
189
190 pub fn last_voted_slot(&self) -> Option<Slot> {
191 self.lockouts.back().map(|l| l.slot())
192 }
193}
194
195#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
196#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
197pub struct VoteInit {
198 pub node_pubkey: Pubkey,
199 pub authorized_voter: Pubkey,
200 pub authorized_withdrawer: Pubkey,
201 pub commission: u8,
202}
203
204#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
205#[derive(Debug, PartialEq, Eq, Clone, Copy)]
206pub enum VoteAuthorize {
207 Voter,
208 Withdrawer,
209}
210
211#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
212#[derive(Debug, PartialEq, Eq, Clone)]
213pub struct VoteAuthorizeWithSeedArgs {
214 pub authorization_type: VoteAuthorize,
215 pub current_authority_derived_key_owner: Pubkey,
216 pub current_authority_derived_key_seed: String,
217 pub new_authority: Pubkey,
218}
219
220#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
221#[derive(Debug, PartialEq, Eq, Clone)]
222pub struct VoteAuthorizeCheckedWithSeedArgs {
223 pub authorization_type: VoteAuthorize,
224 pub current_authority_derived_key_owner: Pubkey,
225 pub current_authority_derived_key_seed: String,
226}