Skip to main content

solana_stake_program/
stake_state.rs

1//! Stake state: helper functions for creating and parsing account data
2
3#[deprecated(
4    since = "1.8.0",
5    note = "Please use `solana_stake_interface::state` instead"
6)]
7pub use solana_stake_interface::state::*;
8use {
9    solana_account::{state_traits::StateMut, AccountSharedData, ReadableAccount},
10    solana_clock::Epoch,
11    solana_pubkey::Pubkey,
12    solana_rent::Rent,
13    solana_sdk_ids::stake::id,
14    solana_stake_interface::stake_flags::StakeFlags,
15    solana_vote_interface::state::VoteStateV4,
16};
17
18// utility function, used by Stakes, tests
19pub fn from<T: ReadableAccount + StateMut<StakeStateV2>>(account: &T) -> Option<StakeStateV2> {
20    account.state().ok()
21}
22
23pub fn stake_from<T: ReadableAccount + StateMut<StakeStateV2>>(account: &T) -> Option<Stake> {
24    from(account).and_then(|state: StakeStateV2| state.stake())
25}
26
27pub fn delegation_from(account: &AccountSharedData) -> Option<Delegation> {
28    from(account).and_then(|state: StakeStateV2| state.delegation())
29}
30
31pub fn authorized_from(account: &AccountSharedData) -> Option<Authorized> {
32    from(account).and_then(|state: StakeStateV2| state.authorized())
33}
34
35pub fn lockup_from<T: ReadableAccount + StateMut<StakeStateV2>>(account: &T) -> Option<Lockup> {
36    from(account).and_then(|state: StakeStateV2| state.lockup())
37}
38
39pub fn meta_from(account: &AccountSharedData) -> Option<Meta> {
40    from(account).and_then(|state: StakeStateV2| state.meta())
41}
42
43fn new_stake(stake: u64, voter_pubkey: &Pubkey, credits: u64, activation_epoch: Epoch) -> Stake {
44    Stake {
45        delegation: Delegation::new(voter_pubkey, stake, activation_epoch),
46        credits_observed: credits,
47    }
48}
49
50// genesis investor accounts
51pub fn create_lockup_stake_account(
52    authorized: &Authorized,
53    lockup: &Lockup,
54    rent: &Rent,
55    lamports: u64,
56) -> AccountSharedData {
57    let mut stake_account = AccountSharedData::new(lamports, StakeStateV2::size_of(), &id());
58
59    let rent_exempt_reserve = rent.minimum_balance(stake_account.data().len());
60    assert!(
61        lamports >= rent_exempt_reserve,
62        "lamports: {lamports} is less than rent_exempt_reserve {rent_exempt_reserve}"
63    );
64
65    stake_account
66        .set_state(&StakeStateV2::Initialized(Meta {
67            authorized: *authorized,
68            lockup: *lockup,
69            rent_exempt_reserve,
70        }))
71        .expect("set_state");
72
73    stake_account
74}
75
76// utility function, used by Bank, tests, genesis for bootstrap
77pub fn create_account(
78    authorized: &Pubkey,
79    voter_pubkey: &Pubkey,
80    vote_account: &AccountSharedData,
81    rent: &Rent,
82    lamports: u64,
83) -> AccountSharedData {
84    do_create_account(
85        authorized,
86        voter_pubkey,
87        vote_account,
88        rent,
89        lamports,
90        Epoch::MAX,
91    )
92}
93
94fn do_create_account(
95    authorized: &Pubkey,
96    voter_pubkey: &Pubkey,
97    vote_account: &AccountSharedData,
98    rent: &Rent,
99    lamports: u64,
100    activation_epoch: Epoch,
101) -> AccountSharedData {
102    let mut stake_account = AccountSharedData::new(lamports, StakeStateV2::size_of(), &id());
103
104    let vote_state = VoteStateV4::deserialize(vote_account.data(), voter_pubkey).unwrap();
105    let credits = vote_state.credits();
106
107    let rent_exempt_reserve = rent.minimum_balance(stake_account.data().len());
108
109    stake_account
110        .set_state(&StakeStateV2::Stake(
111            Meta {
112                authorized: Authorized::auto(authorized),
113                rent_exempt_reserve,
114                ..Meta::default()
115            },
116            new_stake(
117                lamports - rent_exempt_reserve, // underflow is an error, is basically: assert!(lamports > rent_exempt_reserve);
118                voter_pubkey,
119                credits,
120                activation_epoch,
121            ),
122            StakeFlags::empty(),
123        ))
124        .expect("set_state");
125
126    stake_account
127}