solana_ledger/
staking_utils.rs

1#[cfg(test)]
2pub(crate) mod tests {
3    use {
4        rand::Rng,
5        solana_account::AccountSharedData,
6        solana_clock::Clock,
7        solana_instruction::Instruction,
8        solana_keypair::Keypair,
9        solana_pubkey::Pubkey,
10        solana_runtime::bank::Bank,
11        solana_signer::{signers::Signers, Signer},
12        solana_stake_interface::{
13            instruction as stake_instruction,
14            state::{Authorized, Lockup},
15        },
16        solana_transaction::Transaction,
17        solana_vote::vote_account::{VoteAccount, VoteAccounts},
18        solana_vote_program::{
19            vote_instruction,
20            vote_state::{VoteInit, VoteStateV3, VoteStateVersions},
21        },
22    };
23
24    pub(crate) fn setup_vote_and_stake_accounts(
25        bank: &Bank,
26        from_account: &Keypair,
27        vote_account: &Keypair,
28        validator_identity_account: &Keypair,
29        amount: u64,
30    ) {
31        let vote_pubkey = vote_account.pubkey();
32        fn process_instructions<T: Signers>(bank: &Bank, keypairs: &T, ixs: &[Instruction]) {
33            let tx = Transaction::new_signed_with_payer(
34                ixs,
35                Some(&keypairs.pubkeys()[0]),
36                keypairs,
37                bank.last_blockhash(),
38            );
39            bank.process_transaction(&tx).unwrap();
40        }
41
42        process_instructions(
43            bank,
44            &[from_account, vote_account, validator_identity_account],
45            &vote_instruction::create_account_with_config(
46                &from_account.pubkey(),
47                &vote_pubkey,
48                &VoteInit {
49                    node_pubkey: validator_identity_account.pubkey(),
50                    authorized_voter: vote_pubkey,
51                    authorized_withdrawer: vote_pubkey,
52                    commission: 0,
53                },
54                amount,
55                vote_instruction::CreateVoteAccountConfig {
56                    space: VoteStateVersions::vote_state_size_of(true) as u64,
57                    ..vote_instruction::CreateVoteAccountConfig::default()
58                },
59            ),
60        );
61
62        let stake_account_keypair = Keypair::new();
63        let stake_account_pubkey = stake_account_keypair.pubkey();
64
65        process_instructions(
66            bank,
67            &[from_account, &stake_account_keypair],
68            &stake_instruction::create_account_and_delegate_stake(
69                &from_account.pubkey(),
70                &stake_account_pubkey,
71                &vote_pubkey,
72                &Authorized::auto(&stake_account_pubkey),
73                &Lockup::default(),
74                amount,
75            ),
76        );
77    }
78
79    #[test]
80    fn test_to_staked_nodes() {
81        let mut stakes = Vec::new();
82        let node1 = solana_pubkey::new_rand();
83
84        // Node 1 has stake of 3
85        for i in 0..3 {
86            stakes.push((
87                i,
88                VoteStateV3::new(
89                    &VoteInit {
90                        node_pubkey: node1,
91                        ..VoteInit::default()
92                    },
93                    &Clock::default(),
94                ),
95            ));
96        }
97
98        // Node 1 has stake of 5
99        let node2 = solana_pubkey::new_rand();
100
101        stakes.push((
102            5,
103            VoteStateV3::new(
104                &VoteInit {
105                    node_pubkey: node2,
106                    ..VoteInit::default()
107                },
108                &Clock::default(),
109            ),
110        ));
111        let mut rng = rand::thread_rng();
112        let vote_accounts = stakes.into_iter().map(|(stake, vote_state)| {
113            let account = AccountSharedData::new_data(
114                rng.gen(), // lamports
115                &VoteStateVersions::new_v3(vote_state),
116                &solana_vote_program::id(), // owner
117            )
118            .unwrap();
119            let vote_pubkey = Pubkey::new_unique();
120            let vote_account = VoteAccount::try_from(account).unwrap();
121            (vote_pubkey, (stake, vote_account))
122        });
123        let result = vote_accounts.collect::<VoteAccounts>().staked_nodes();
124        assert_eq!(result.len(), 2);
125        assert_eq!(result[&node1], 3);
126        assert_eq!(result[&node2], 5);
127    }
128}