solana_runtime/
stake_utils.rs

1use {
2    solana_account::{state_traits::StateMut, AccountSharedData, ReadableAccount},
3    solana_clock::Epoch,
4    solana_native_token::LAMPORTS_PER_SOL,
5    solana_pubkey::Pubkey,
6    solana_rent::Rent,
7    solana_stake_interface::{
8        program as stake_program,
9        stake_flags::StakeFlags,
10        state::{Authorized, Delegation, Meta, Stake, StakeStateV2},
11    },
12    solana_vote_interface::state::VoteStateV4,
13};
14
15/// The minimum stake amount that can be delegated, in lamports.
16/// When this feature is added, it will be accompanied by an upgrade to the BPF Stake Program.
17/// NOTE: This is also used to calculate the minimum balance of a delegated stake account,
18/// which is the rent exempt reserve _plus_ the minimum stake delegation.
19#[inline(always)]
20pub fn get_minimum_delegation(is_stake_raise_minimum_delegation_to_1_sol_active: bool) -> u64 {
21    if is_stake_raise_minimum_delegation_to_1_sol_active {
22        const MINIMUM_DELEGATION_SOL: u64 = 1;
23        MINIMUM_DELEGATION_SOL * LAMPORTS_PER_SOL
24    } else {
25        1
26    }
27}
28
29/// Utility function for creating a stake account from basic parameters.
30/// Only used in tests and CLIs.
31pub fn create_stake_account(
32    authorized: &Pubkey,
33    voter_pubkey: &Pubkey,
34    vote_account: &AccountSharedData,
35    rent: &Rent,
36    lamports: u64,
37) -> AccountSharedData {
38    let mut stake_account =
39        AccountSharedData::new(lamports, StakeStateV2::size_of(), &stake_program::id());
40
41    let vote_state = VoteStateV4::deserialize(vote_account.data(), voter_pubkey).unwrap();
42    let credits_observed = vote_state.credits();
43
44    let rent_exempt_reserve = rent.minimum_balance(stake_account.data().len());
45    let stake_amount = lamports
46        .checked_sub(rent_exempt_reserve)
47        .expect("lamports >= rent_exempt_reserve");
48
49    let meta = Meta {
50        authorized: Authorized::auto(authorized),
51        rent_exempt_reserve,
52        ..Meta::default()
53    };
54
55    let stake = Stake {
56        delegation: Delegation::new(voter_pubkey, stake_amount, Epoch::MAX),
57        credits_observed,
58    };
59
60    stake_account
61        .set_state(&StakeStateV2::Stake(meta, stake, StakeFlags::empty()))
62        .expect("set_state");
63
64    stake_account
65}