agave_transaction_view/
static_account_keys_frame.rsuse {
crate::{
bytes::{advance_offset_for_array, read_byte},
result::{Result, TransactionViewError},
},
solana_sdk::{packet::PACKET_DATA_SIZE, pubkey::Pubkey},
};
pub const MAX_STATIC_ACCOUNTS_PER_PACKET: u8 =
(PACKET_DATA_SIZE / core::mem::size_of::<Pubkey>()) as u8;
#[derive(Debug, Default)]
pub(crate) struct StaticAccountKeysFrame {
pub(crate) num_static_accounts: u8,
pub(crate) offset: u16,
}
impl StaticAccountKeysFrame {
#[inline(always)]
pub(crate) fn try_new(bytes: &[u8], offset: &mut usize) -> Result<Self> {
const _: () = assert!(MAX_STATIC_ACCOUNTS_PER_PACKET & 0b1000_0000 == 0);
let num_static_accounts = read_byte(bytes, offset)?;
if num_static_accounts == 0 || num_static_accounts > MAX_STATIC_ACCOUNTS_PER_PACKET {
return Err(TransactionViewError::ParseError);
}
let static_accounts_offset = *offset as u16;
advance_offset_for_array::<Pubkey>(bytes, offset, u16::from(num_static_accounts))?;
Ok(Self {
num_static_accounts,
offset: static_accounts_offset,
})
}
}
#[cfg(test)]
mod tests {
use {super::*, solana_sdk::short_vec::ShortVec};
#[test]
fn test_zero_accounts() {
let bytes = bincode::serialize(&ShortVec(Vec::<Pubkey>::new())).unwrap();
let mut offset = 0;
assert!(StaticAccountKeysFrame::try_new(&bytes, &mut offset).is_err());
}
#[test]
fn test_one_account() {
let bytes = bincode::serialize(&ShortVec(vec![Pubkey::default()])).unwrap();
let mut offset = 0;
let frame = StaticAccountKeysFrame::try_new(&bytes, &mut offset).unwrap();
assert_eq!(frame.num_static_accounts, 1);
assert_eq!(frame.offset, 1);
assert_eq!(offset, 1 + core::mem::size_of::<Pubkey>());
}
#[test]
fn test_max_accounts() {
let signatures = vec![Pubkey::default(); usize::from(MAX_STATIC_ACCOUNTS_PER_PACKET)];
let bytes = bincode::serialize(&ShortVec(signatures)).unwrap();
let mut offset = 0;
let frame = StaticAccountKeysFrame::try_new(&bytes, &mut offset).unwrap();
assert_eq!(frame.num_static_accounts, 38);
assert_eq!(frame.offset, 1);
assert_eq!(offset, 1 + 38 * core::mem::size_of::<Pubkey>());
}
#[test]
fn test_too_many_accounts() {
let signatures = vec![Pubkey::default(); usize::from(MAX_STATIC_ACCOUNTS_PER_PACKET) + 1];
let bytes = bincode::serialize(&ShortVec(signatures)).unwrap();
let mut offset = 0;
assert!(StaticAccountKeysFrame::try_new(&bytes, &mut offset).is_err());
}
#[test]
fn test_u16_max_accounts() {
let signatures = vec![Pubkey::default(); u16::MAX as usize];
let bytes = bincode::serialize(&ShortVec(signatures)).unwrap();
let mut offset = 0;
assert!(StaticAccountKeysFrame::try_new(&bytes, &mut offset).is_err());
}
}