solana_vote_interface/
instruction.rs

1//! Vote program instructions
2
3use {
4    super::state::TowerSync,
5    crate::state::{
6        Vote, VoteAuthorize, VoteAuthorizeCheckedWithSeedArgs, VoteAuthorizeWithSeedArgs, VoteInit,
7        VoteInitV2, VoteStateUpdate, VoteStateV4,
8    },
9    solana_clock::{Slot, UnixTimestamp},
10    solana_hash::Hash,
11    solana_pubkey::Pubkey,
12};
13#[cfg(feature = "bincode")]
14use {
15    crate::program::id,
16    solana_instruction::{AccountMeta, Instruction},
17    solana_sdk_ids::sysvar,
18};
19#[cfg(feature = "serde")]
20use {
21    crate::state::{serde_compact_vote_state_update, serde_tower_sync},
22    serde_derive::{Deserialize, Serialize},
23};
24
25#[repr(u8)]
26#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
27#[derive(Debug, PartialEq, Eq, Clone)]
28pub enum CommissionKind {
29    InflationRewards = 0,
30    BlockRevenue = 1,
31}
32
33#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
34#[derive(Debug, PartialEq, Eq, Clone)]
35pub enum VoteInstruction {
36    /// Initialize a vote account
37    ///
38    /// # Account references
39    ///   0. `[WRITE]` Uninitialized vote account
40    ///   1. `[]` Rent sysvar
41    ///   2. `[]` Clock sysvar
42    ///   3. `[SIGNER]` New validator identity (node_pubkey)
43    InitializeAccount(VoteInit),
44
45    /// Authorize a key to send votes or issue a withdrawal
46    ///
47    /// # Account references
48    ///   0. `[WRITE]` Vote account to be updated with the Pubkey for authorization
49    ///   1. `[]` Clock sysvar
50    ///   2. `[SIGNER]` Vote or withdraw authority
51    ///
52    /// When SIMD-0387 is enabled, the `VoteAuthorize::Voter` variant is
53    /// disallowed for any vote accounts whose BLS pubkey is set to `Some`.
54    Authorize(Pubkey, VoteAuthorize),
55
56    /// A Vote instruction with recent votes
57    ///
58    /// # Account references
59    ///   0. `[WRITE]` Vote account to vote with
60    ///   1. `[]` Slot hashes sysvar
61    ///   2. `[]` Clock sysvar
62    ///   3. `[SIGNER]` Vote authority
63    Vote(Vote),
64
65    /// Withdraw some amount of funds
66    ///
67    /// # Account references
68    ///   0. `[WRITE]` Vote account to withdraw from
69    ///   1. `[WRITE]` Recipient account
70    ///   2. `[SIGNER]` Withdraw authority
71    Withdraw(u64),
72
73    /// Update the vote account's validator identity (node_pubkey)
74    ///
75    /// # Account references
76    ///   0. `[WRITE]` Vote account to be updated with the given authority public key
77    ///   1. `[SIGNER]` New validator identity (node_pubkey)
78    ///   2. `[SIGNER]` Withdraw authority
79    UpdateValidatorIdentity,
80
81    /// Update the commission for the vote account
82    ///
83    /// # Account references
84    ///   0. `[WRITE]` Vote account to be updated
85    ///   1. `[SIGNER]` Withdraw authority
86    UpdateCommission(u8),
87
88    /// A Vote instruction with recent votes
89    ///
90    /// # Account references
91    ///   0. `[WRITE]` Vote account to vote with
92    ///   1. `[]` Slot hashes sysvar
93    ///   2. `[]` Clock sysvar
94    ///   3. `[SIGNER]` Vote authority
95    VoteSwitch(Vote, Hash),
96
97    /// Authorize a key to send votes or issue a withdrawal
98    ///
99    /// This instruction behaves like `Authorize` with the additional requirement that the new vote
100    /// or withdraw authority must also be a signer.
101    ///
102    /// # Account references
103    ///   0. `[WRITE]` Vote account to be updated with the Pubkey for authorization
104    ///   1. `[]` Clock sysvar
105    ///   2. `[SIGNER]` Vote or withdraw authority
106    ///   3. `[SIGNER]` New vote or withdraw authority
107    ///
108    /// When SIMD-0387 is enabled, the `VoteAuthorize::Voter` variant is
109    /// disallowed for any vote accounts whose BLS pubkey is set to `Some`.
110    AuthorizeChecked(VoteAuthorize),
111
112    /// Update the onchain vote state for the signer.
113    ///
114    /// # Account references
115    ///   0. `[Write]` Vote account to vote with
116    ///   1. `[SIGNER]` Vote authority
117    UpdateVoteState(VoteStateUpdate),
118
119    /// Update the onchain vote state for the signer along with a switching proof.
120    ///
121    /// # Account references
122    ///   0. `[Write]` Vote account to vote with
123    ///   1. `[SIGNER]` Vote authority
124    UpdateVoteStateSwitch(VoteStateUpdate, Hash),
125
126    /// Given that the current Voter or Withdrawer authority is a derived key,
127    /// this instruction allows someone who can sign for that derived key's
128    /// base key to authorize a new Voter or Withdrawer for a vote account.
129    ///
130    /// # Account references
131    ///   0. `[Write]` Vote account to be updated
132    ///   1. `[]` Clock sysvar
133    ///   2. `[SIGNER]` Base key of current Voter or Withdrawer authority's derived key
134    ///
135    /// When SIMD-0387 is enabled, the `VoteAuthorize::Voter` variant in
136    /// `authorization_type` is disallowed for any vote accounts whose BLS
137    /// pubkey is set to `Some`.
138    AuthorizeWithSeed(VoteAuthorizeWithSeedArgs),
139
140    /// Given that the current Voter or Withdrawer authority is a derived key,
141    /// this instruction allows someone who can sign for that derived key's
142    /// base key to authorize a new Voter or Withdrawer for a vote account.
143    ///
144    /// This instruction behaves like `AuthorizeWithSeed` with the additional requirement
145    /// that the new vote or withdraw authority must also be a signer.
146    ///
147    /// # Account references
148    ///   0. `[Write]` Vote account to be updated
149    ///   1. `[]` Clock sysvar
150    ///   2. `[SIGNER]` Base key of current Voter or Withdrawer authority's derived key
151    ///   3. `[SIGNER]` New vote or withdraw authority
152    ///
153    /// When SIMD-0387 is enabled, the `VoteAuthorize::Voter` variant in
154    /// `authorization_type` is disallowed for any vote accounts whose BLS
155    /// pubkey is set to `Some`.
156    AuthorizeCheckedWithSeed(VoteAuthorizeCheckedWithSeedArgs),
157
158    /// Update the onchain vote state for the signer.
159    ///
160    /// # Account references
161    ///   0. `[Write]` Vote account to vote with
162    ///   1. `[SIGNER]` Vote authority
163    #[cfg_attr(feature = "serde", serde(with = "serde_compact_vote_state_update"))]
164    CompactUpdateVoteState(VoteStateUpdate),
165
166    /// Update the onchain vote state for the signer along with a switching proof.
167    ///
168    /// # Account references
169    ///   0. `[Write]` Vote account to vote with
170    ///   1. `[SIGNER]` Vote authority
171    CompactUpdateVoteStateSwitch(
172        #[cfg_attr(feature = "serde", serde(with = "serde_compact_vote_state_update"))]
173        VoteStateUpdate,
174        Hash,
175    ),
176
177    /// Sync the onchain vote state with local tower
178    ///
179    /// # Account references
180    ///   0. `[Write]` Vote account to vote with
181    ///   1. `[SIGNER]` Vote authority
182    #[cfg_attr(feature = "serde", serde(with = "serde_tower_sync"))]
183    TowerSync(TowerSync),
184
185    /// Sync the onchain vote state with local tower along with a switching proof
186    ///
187    /// # Account references
188    ///   0. `[Write]` Vote account to vote with
189    ///   1. `[SIGNER]` Vote authority
190    TowerSyncSwitch(
191        #[cfg_attr(feature = "serde", serde(with = "serde_tower_sync"))] TowerSync,
192        Hash,
193    ),
194
195    // Initialize a vote account using VoteInitV2
196    ///
197    /// # Account references
198    ///   0. `[WRITE]` Uninitialized vote account
199    ///   1. `[SIGNER]` New validator identity (node_pubkey)
200    InitializeAccountV2(VoteInitV2),
201
202    /// Update the commission collector for the vote account
203    ///
204    /// # Account references
205    ///   0. `[WRITE]` Vote account to be updated with the new collector public key
206    ///   1. `[WRITE]` New collector account. Must be set to the vote account or
207    ///      a system program owned account. Must be writable to ensure the
208    ///      account is not reserved.
209    ///   2. `[SIGNER]` Vote account withdraw authority
210    UpdateCommissionCollector(CommissionKind),
211
212    /// Update the commission rate in basis points for the specified commission
213    /// rate kind in a vote account.
214    ///
215    /// # Account references
216    ///   0. `[WRITE]` Vote account to be updated with the new commission
217    ///   1. `[SIGNER]` Vote account withdraw authority
218    UpdateCommissionBps {
219        commission_bps: u16,
220        kind: CommissionKind,
221    },
222
223    /// Deposit lamports for distribution to stake delegators
224    ///
225    /// # Account references
226    ///   0. `[WRITE]` Vote account to be updated with the deposit
227    ///   1. `[SIGNER, WRITE]` Source account for deposit funds
228    DepositDelegatorRewards { deposit: u64 },
229}
230
231impl VoteInstruction {
232    pub fn is_simple_vote(&self) -> bool {
233        matches!(
234            self,
235            Self::Vote(_)
236                | Self::VoteSwitch(_, _)
237                | Self::UpdateVoteState(_)
238                | Self::UpdateVoteStateSwitch(_, _)
239                | Self::CompactUpdateVoteState(_)
240                | Self::CompactUpdateVoteStateSwitch(_, _)
241                | Self::TowerSync(_)
242                | Self::TowerSyncSwitch(_, _),
243        )
244    }
245
246    pub fn is_single_vote_state_update(&self) -> bool {
247        matches!(
248            self,
249            Self::UpdateVoteState(_)
250                | Self::UpdateVoteStateSwitch(_, _)
251                | Self::CompactUpdateVoteState(_)
252                | Self::CompactUpdateVoteStateSwitch(_, _)
253                | Self::TowerSync(_)
254                | Self::TowerSyncSwitch(_, _),
255        )
256    }
257
258    /// Only to be used on vote instructions (guard with is_simple_vote),  panics otherwise
259    pub fn last_voted_slot(&self) -> Option<Slot> {
260        assert!(self.is_simple_vote());
261        match self {
262            Self::Vote(v) | Self::VoteSwitch(v, _) => v.last_voted_slot(),
263            Self::UpdateVoteState(vote_state_update)
264            | Self::UpdateVoteStateSwitch(vote_state_update, _)
265            | Self::CompactUpdateVoteState(vote_state_update)
266            | Self::CompactUpdateVoteStateSwitch(vote_state_update, _) => {
267                vote_state_update.last_voted_slot()
268            }
269            Self::TowerSync(tower_sync) | Self::TowerSyncSwitch(tower_sync, _) => {
270                tower_sync.last_voted_slot()
271            }
272            _ => panic!("Tried to get slot on non simple vote instruction"),
273        }
274    }
275
276    /// Only to be used on vote instructions (guard with is_simple_vote), panics otherwise
277    pub fn hash(&self) -> Hash {
278        assert!(self.is_simple_vote());
279        let hash = match self {
280            Self::Vote(v) | Self::VoteSwitch(v, _) => &v.hash,
281            Self::UpdateVoteState(vote_state_update)
282            | Self::UpdateVoteStateSwitch(vote_state_update, _)
283            | Self::CompactUpdateVoteState(vote_state_update)
284            | Self::CompactUpdateVoteStateSwitch(vote_state_update, _) => &vote_state_update.hash,
285            Self::TowerSync(tower_sync) | Self::TowerSyncSwitch(tower_sync, _) => &tower_sync.hash,
286            _ => panic!("Tried to get hash on non simple vote instruction"),
287        };
288        Hash::new_from_array(hash.to_bytes())
289    }
290    /// Only to be used on vote instructions (guard with is_simple_vote),  panics otherwise
291    pub fn timestamp(&self) -> Option<UnixTimestamp> {
292        assert!(self.is_simple_vote());
293        match self {
294            Self::Vote(v) | Self::VoteSwitch(v, _) => v.timestamp,
295            Self::UpdateVoteState(vote_state_update)
296            | Self::UpdateVoteStateSwitch(vote_state_update, _)
297            | Self::CompactUpdateVoteState(vote_state_update)
298            | Self::CompactUpdateVoteStateSwitch(vote_state_update, _) => {
299                vote_state_update.timestamp
300            }
301            Self::TowerSync(tower_sync) | Self::TowerSyncSwitch(tower_sync, _) => {
302                tower_sync.timestamp
303            }
304            _ => panic!("Tried to get timestamp on non simple vote instruction"),
305        }
306    }
307}
308
309#[cfg(feature = "bincode")]
310fn initialize_account(vote_pubkey: &Pubkey, vote_init: &VoteInit) -> Instruction {
311    let account_metas = vec![
312        AccountMeta::new(*vote_pubkey, false),
313        AccountMeta::new_readonly(sysvar::rent::id(), false),
314        AccountMeta::new_readonly(sysvar::clock::id(), false),
315        AccountMeta::new_readonly(vote_init.node_pubkey, true),
316    ];
317
318    Instruction::new_with_bincode(
319        id(),
320        &VoteInstruction::InitializeAccount(*vote_init),
321        account_metas,
322    )
323}
324
325#[cfg(feature = "bincode")]
326fn initialize_account_v2(vote_pubkey: &Pubkey, vote_init: &VoteInitV2) -> Instruction {
327    let account_metas = vec![
328        AccountMeta::new(*vote_pubkey, false),
329        AccountMeta::new_readonly(vote_init.node_pubkey, true),
330    ];
331
332    Instruction::new_with_bincode(
333        id(),
334        &VoteInstruction::InitializeAccountV2(*vote_init),
335        account_metas,
336    )
337}
338
339pub struct CreateVoteAccountConfig<'a> {
340    pub space: u64,
341    pub with_seed: Option<(&'a Pubkey, &'a str)>,
342}
343
344impl Default for CreateVoteAccountConfig<'_> {
345    fn default() -> Self {
346        Self {
347            // Create new vote accounts with size for V4.
348            space: VoteStateV4::size_of() as u64,
349            with_seed: None,
350        }
351    }
352}
353
354#[cfg(feature = "bincode")]
355pub fn create_account_with_config(
356    from_pubkey: &Pubkey,
357    vote_pubkey: &Pubkey,
358    vote_init: &VoteInit,
359    lamports: u64,
360    config: CreateVoteAccountConfig,
361) -> Vec<Instruction> {
362    let create_ix = if let Some((base, seed)) = config.with_seed {
363        solana_system_interface::instruction::create_account_with_seed(
364            from_pubkey,
365            vote_pubkey,
366            base,
367            seed,
368            lamports,
369            config.space,
370            &id(),
371        )
372    } else {
373        solana_system_interface::instruction::create_account(
374            from_pubkey,
375            vote_pubkey,
376            lamports,
377            config.space,
378            &id(),
379        )
380    };
381    let init_ix = initialize_account(vote_pubkey, vote_init);
382    vec![create_ix, init_ix]
383}
384
385#[cfg(feature = "bincode")]
386pub fn create_account_with_config_v2(
387    from_pubkey: &Pubkey,
388    vote_pubkey: &Pubkey,
389    vote_init: &VoteInitV2,
390    lamports: u64,
391    config: CreateVoteAccountConfig,
392) -> Vec<Instruction> {
393    let create_ix = if let Some((base, seed)) = config.with_seed {
394        solana_system_interface::instruction::create_account_with_seed(
395            from_pubkey,
396            vote_pubkey,
397            base,
398            seed,
399            lamports,
400            config.space,
401            &id(),
402        )
403    } else {
404        solana_system_interface::instruction::create_account(
405            from_pubkey,
406            vote_pubkey,
407            lamports,
408            config.space,
409            &id(),
410        )
411    };
412    let init_ix = initialize_account_v2(vote_pubkey, vote_init);
413    vec![create_ix, init_ix]
414}
415
416#[cfg(feature = "bincode")]
417pub fn authorize(
418    vote_pubkey: &Pubkey,
419    authorized_pubkey: &Pubkey, // currently authorized
420    new_authorized_pubkey: &Pubkey,
421    vote_authorize: VoteAuthorize,
422) -> Instruction {
423    let account_metas = vec![
424        AccountMeta::new(*vote_pubkey, false),
425        AccountMeta::new_readonly(sysvar::clock::id(), false),
426        AccountMeta::new_readonly(*authorized_pubkey, true),
427    ];
428
429    Instruction::new_with_bincode(
430        id(),
431        &VoteInstruction::Authorize(*new_authorized_pubkey, vote_authorize),
432        account_metas,
433    )
434}
435
436#[cfg(feature = "bincode")]
437pub fn authorize_checked(
438    vote_pubkey: &Pubkey,
439    authorized_pubkey: &Pubkey, // currently authorized
440    new_authorized_pubkey: &Pubkey,
441    vote_authorize: VoteAuthorize,
442) -> Instruction {
443    let account_metas = vec![
444        AccountMeta::new(*vote_pubkey, false),
445        AccountMeta::new_readonly(sysvar::clock::id(), false),
446        AccountMeta::new_readonly(*authorized_pubkey, true),
447        AccountMeta::new_readonly(*new_authorized_pubkey, true),
448    ];
449
450    Instruction::new_with_bincode(
451        id(),
452        &VoteInstruction::AuthorizeChecked(vote_authorize),
453        account_metas,
454    )
455}
456
457#[cfg(feature = "bincode")]
458pub fn authorize_with_seed(
459    vote_pubkey: &Pubkey,
460    current_authority_base_key: &Pubkey,
461    current_authority_derived_key_owner: &Pubkey,
462    current_authority_derived_key_seed: &str,
463    new_authority: &Pubkey,
464    authorization_type: VoteAuthorize,
465) -> Instruction {
466    let account_metas = vec![
467        AccountMeta::new(*vote_pubkey, false),
468        AccountMeta::new_readonly(sysvar::clock::id(), false),
469        AccountMeta::new_readonly(*current_authority_base_key, true),
470    ];
471
472    Instruction::new_with_bincode(
473        id(),
474        &VoteInstruction::AuthorizeWithSeed(VoteAuthorizeWithSeedArgs {
475            authorization_type,
476            current_authority_derived_key_owner: *current_authority_derived_key_owner,
477            current_authority_derived_key_seed: current_authority_derived_key_seed.to_string(),
478            new_authority: *new_authority,
479        }),
480        account_metas,
481    )
482}
483
484#[cfg(feature = "bincode")]
485pub fn authorize_checked_with_seed(
486    vote_pubkey: &Pubkey,
487    current_authority_base_key: &Pubkey,
488    current_authority_derived_key_owner: &Pubkey,
489    current_authority_derived_key_seed: &str,
490    new_authority: &Pubkey,
491    authorization_type: VoteAuthorize,
492) -> Instruction {
493    let account_metas = vec![
494        AccountMeta::new(*vote_pubkey, false),
495        AccountMeta::new_readonly(sysvar::clock::id(), false),
496        AccountMeta::new_readonly(*current_authority_base_key, true),
497        AccountMeta::new_readonly(*new_authority, true),
498    ];
499
500    Instruction::new_with_bincode(
501        id(),
502        &VoteInstruction::AuthorizeCheckedWithSeed(VoteAuthorizeCheckedWithSeedArgs {
503            authorization_type,
504            current_authority_derived_key_owner: *current_authority_derived_key_owner,
505            current_authority_derived_key_seed: current_authority_derived_key_seed.to_string(),
506        }),
507        account_metas,
508    )
509}
510
511#[cfg(feature = "bincode")]
512pub fn update_validator_identity(
513    vote_pubkey: &Pubkey,
514    authorized_withdrawer_pubkey: &Pubkey,
515    node_pubkey: &Pubkey,
516) -> Instruction {
517    let account_metas = vec![
518        AccountMeta::new(*vote_pubkey, false),
519        AccountMeta::new_readonly(*node_pubkey, true),
520        AccountMeta::new_readonly(*authorized_withdrawer_pubkey, true),
521    ];
522
523    Instruction::new_with_bincode(
524        id(),
525        &VoteInstruction::UpdateValidatorIdentity,
526        account_metas,
527    )
528}
529
530#[cfg(feature = "bincode")]
531pub fn update_commission(
532    vote_pubkey: &Pubkey,
533    authorized_withdrawer_pubkey: &Pubkey,
534    commission: u8,
535) -> Instruction {
536    let account_metas = vec![
537        AccountMeta::new(*vote_pubkey, false),
538        AccountMeta::new_readonly(*authorized_withdrawer_pubkey, true),
539    ];
540
541    Instruction::new_with_bincode(
542        id(),
543        &VoteInstruction::UpdateCommission(commission),
544        account_metas,
545    )
546}
547
548#[cfg(feature = "bincode")]
549pub fn update_commission_collector(
550    vote_pubkey: &Pubkey,
551    authorized_withdrawer_pubkey: &Pubkey,
552    new_collector_pubkey: &Pubkey,
553    kind: CommissionKind,
554) -> Instruction {
555    let account_metas = vec![
556        AccountMeta::new(*vote_pubkey, false),
557        AccountMeta::new(*new_collector_pubkey, false),
558        AccountMeta::new_readonly(*authorized_withdrawer_pubkey, true),
559    ];
560
561    Instruction::new_with_bincode(
562        id(),
563        &VoteInstruction::UpdateCommissionCollector(kind),
564        account_metas,
565    )
566}
567
568#[cfg(feature = "bincode")]
569pub fn update_commission_bps(
570    vote_pubkey: &Pubkey,
571    authorized_withdrawer_pubkey: &Pubkey,
572    kind: CommissionKind,
573    commission_bps: u16,
574) -> Instruction {
575    let account_metas = vec![
576        AccountMeta::new(*vote_pubkey, false),
577        AccountMeta::new_readonly(*authorized_withdrawer_pubkey, true),
578    ];
579
580    Instruction::new_with_bincode(
581        id(),
582        &VoteInstruction::UpdateCommissionBps {
583            kind,
584            commission_bps,
585        },
586        account_metas,
587    )
588}
589
590#[cfg(feature = "bincode")]
591pub fn deposit_delegator_rewards(
592    vote_pubkey: &Pubkey,
593    source_pubkey: &Pubkey,
594    deposit: u64,
595) -> Instruction {
596    let account_metas = vec![
597        AccountMeta::new(*vote_pubkey, false),
598        AccountMeta::new(*source_pubkey, true),
599    ];
600
601    Instruction::new_with_bincode(
602        id(),
603        &VoteInstruction::DepositDelegatorRewards { deposit },
604        account_metas,
605    )
606}
607
608#[cfg(feature = "bincode")]
609pub fn vote(vote_pubkey: &Pubkey, authorized_voter_pubkey: &Pubkey, vote: Vote) -> Instruction {
610    let account_metas = vec![
611        AccountMeta::new(*vote_pubkey, false),
612        AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
613        AccountMeta::new_readonly(sysvar::clock::id(), false),
614        AccountMeta::new_readonly(*authorized_voter_pubkey, true),
615    ];
616
617    Instruction::new_with_bincode(id(), &VoteInstruction::Vote(vote), account_metas)
618}
619
620#[cfg(feature = "bincode")]
621pub fn vote_switch(
622    vote_pubkey: &Pubkey,
623    authorized_voter_pubkey: &Pubkey,
624    vote: Vote,
625    proof_hash: Hash,
626) -> Instruction {
627    let account_metas = vec![
628        AccountMeta::new(*vote_pubkey, false),
629        AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
630        AccountMeta::new_readonly(sysvar::clock::id(), false),
631        AccountMeta::new_readonly(*authorized_voter_pubkey, true),
632    ];
633
634    Instruction::new_with_bincode(
635        id(),
636        &VoteInstruction::VoteSwitch(vote, proof_hash),
637        account_metas,
638    )
639}
640
641#[cfg(feature = "bincode")]
642pub fn update_vote_state(
643    vote_pubkey: &Pubkey,
644    authorized_voter_pubkey: &Pubkey,
645    vote_state_update: VoteStateUpdate,
646) -> Instruction {
647    let account_metas = vec![
648        AccountMeta::new(*vote_pubkey, false),
649        AccountMeta::new_readonly(*authorized_voter_pubkey, true),
650    ];
651
652    Instruction::new_with_bincode(
653        id(),
654        &VoteInstruction::UpdateVoteState(vote_state_update),
655        account_metas,
656    )
657}
658
659#[cfg(feature = "bincode")]
660pub fn update_vote_state_switch(
661    vote_pubkey: &Pubkey,
662    authorized_voter_pubkey: &Pubkey,
663    vote_state_update: VoteStateUpdate,
664    proof_hash: Hash,
665) -> Instruction {
666    let account_metas = vec![
667        AccountMeta::new(*vote_pubkey, false),
668        AccountMeta::new_readonly(*authorized_voter_pubkey, true),
669    ];
670
671    Instruction::new_with_bincode(
672        id(),
673        &VoteInstruction::UpdateVoteStateSwitch(vote_state_update, proof_hash),
674        account_metas,
675    )
676}
677
678#[cfg(feature = "bincode")]
679pub fn compact_update_vote_state(
680    vote_pubkey: &Pubkey,
681    authorized_voter_pubkey: &Pubkey,
682    vote_state_update: VoteStateUpdate,
683) -> Instruction {
684    let account_metas = vec![
685        AccountMeta::new(*vote_pubkey, false),
686        AccountMeta::new_readonly(*authorized_voter_pubkey, true),
687    ];
688
689    Instruction::new_with_bincode(
690        id(),
691        &VoteInstruction::CompactUpdateVoteState(vote_state_update),
692        account_metas,
693    )
694}
695
696#[cfg(feature = "bincode")]
697pub fn compact_update_vote_state_switch(
698    vote_pubkey: &Pubkey,
699    authorized_voter_pubkey: &Pubkey,
700    vote_state_update: VoteStateUpdate,
701    proof_hash: Hash,
702) -> Instruction {
703    let account_metas = vec![
704        AccountMeta::new(*vote_pubkey, false),
705        AccountMeta::new_readonly(*authorized_voter_pubkey, true),
706    ];
707
708    Instruction::new_with_bincode(
709        id(),
710        &VoteInstruction::CompactUpdateVoteStateSwitch(vote_state_update, proof_hash),
711        account_metas,
712    )
713}
714
715#[cfg(feature = "bincode")]
716pub fn tower_sync(
717    vote_pubkey: &Pubkey,
718    authorized_voter_pubkey: &Pubkey,
719    tower_sync: TowerSync,
720) -> Instruction {
721    let account_metas = vec![
722        AccountMeta::new(*vote_pubkey, false),
723        AccountMeta::new_readonly(*authorized_voter_pubkey, true),
724    ];
725
726    Instruction::new_with_bincode(id(), &VoteInstruction::TowerSync(tower_sync), account_metas)
727}
728
729#[cfg(feature = "bincode")]
730pub fn tower_sync_switch(
731    vote_pubkey: &Pubkey,
732    authorized_voter_pubkey: &Pubkey,
733    tower_sync: TowerSync,
734    proof_hash: Hash,
735) -> Instruction {
736    let account_metas = vec![
737        AccountMeta::new(*vote_pubkey, false),
738        AccountMeta::new_readonly(*authorized_voter_pubkey, true),
739    ];
740
741    Instruction::new_with_bincode(
742        id(),
743        &VoteInstruction::TowerSyncSwitch(tower_sync, proof_hash),
744        account_metas,
745    )
746}
747
748#[cfg(feature = "bincode")]
749pub fn withdraw(
750    vote_pubkey: &Pubkey,
751    authorized_withdrawer_pubkey: &Pubkey,
752    lamports: u64,
753    to_pubkey: &Pubkey,
754) -> Instruction {
755    let account_metas = vec![
756        AccountMeta::new(*vote_pubkey, false),
757        AccountMeta::new(*to_pubkey, false),
758        AccountMeta::new_readonly(*authorized_withdrawer_pubkey, true),
759    ];
760
761    Instruction::new_with_bincode(id(), &VoteInstruction::Withdraw(lamports), account_metas)
762}