Skip to main content

solana_message/
inline_nonce.rs

1//! Inlined nonce instruction information to avoid a dependency on bincode and
2//! solana-system-interface
3use {
4    alloc::vec,
5    solana_address::Address,
6    solana_instruction::{AccountMeta, Instruction},
7    solana_sdk_ids::{system_program, sysvar},
8};
9
10/// Inlined `SystemInstruction::AdvanceNonceAccount` instruction data to avoid
11/// solana_system_interface and bincode deps
12const ADVANCE_NONCE_DATA: [u8; 4] = [4, 0, 0, 0];
13
14/// Check if the given instruction data is the same as
15/// `SystemInstruction::AdvanceNonceAccount`.
16///
17/// NOTE: It's possible for additional data to exist after the 4th byte, but
18/// users of this function only look at the first 4 bytes.
19pub fn is_advance_nonce_instruction_data(data: &[u8]) -> bool {
20    data.get(0..4) == Some(&ADVANCE_NONCE_DATA)
21}
22
23/// Inlined `advance_nonce_account` instruction creator to avoid
24/// solana_system_interface and bincode deps
25pub(crate) fn advance_nonce_account_instruction(
26    nonce_pubkey: &Address,
27    nonce_authority_pubkey: &Address,
28) -> Instruction {
29    Instruction::new_with_bytes(
30        system_program::id(),
31        &ADVANCE_NONCE_DATA,
32        vec![
33            AccountMeta::new(*nonce_pubkey, false),
34            #[allow(deprecated)]
35            AccountMeta::new_readonly(sysvar::recent_blockhashes::id(), false),
36            AccountMeta::new_readonly(*nonce_authority_pubkey, true),
37        ],
38    )
39}
40
41#[cfg(test)]
42mod test {
43    use {
44        super::*,
45        solana_system_interface::instruction::{advance_nonce_account, SystemInstruction},
46    };
47
48    #[test]
49    fn inline_instruction_data_matches_program() {
50        let nonce = Address::new_unique();
51        let nonce_authority = Address::new_unique();
52        assert_eq!(
53            advance_nonce_account_instruction(&nonce, &nonce_authority),
54            advance_nonce_account(&nonce, &nonce_authority),
55        );
56    }
57
58    #[test]
59    fn test_advance_nonce_ix_prefix() {
60        let advance_nonce_ix: SystemInstruction =
61            bincode::deserialize(&ADVANCE_NONCE_DATA).unwrap();
62        assert_eq!(advance_nonce_ix, SystemInstruction::AdvanceNonceAccount);
63    }
64}