Account Management Methods#
These methods provide functionality for managing accounts in the fuzzing environment, including retrieving, setting, and manipulating account data.
Account Data Methods#
get_account#
Retrieves account data for the specified public key.
Parameters:
key- The public key of the account to retrieve
Returns: Account data or default empty account if not found.
get_account_with_type#
Gets account data and converts it to a specific data type for use in your tests. The discriminator size is automatically determined from the type's AccountDiscriminator implementation, unless overridden.
pub fn get_account_with_type<T: BorshDeserialize + AccountDiscriminator>(
&mut self,
key: &Pubkey,
discriminator_size_override: Option<usize>,
) -> Option<T>
Parameters:
key- The public key of the account to retrievediscriminator_size_override- Optional override for discriminator size to skip. IfNone, uses the length from the type'sAccountDiscriminatorimplementation.
Returns: Deserialized account data or None if deserialization fails.
Account Type
Use account types contained in the types.rs file. These types implement AccountDiscriminator trait which provides the discriminator bytes from the IDL.
Discriminator Handling
This method does not verify the discriminator. It only uses the discriminator length to skip those bytes during deserialization.
Lamport Management#
airdrop#
Adds lamports to the specified account address.
Parameters:
address- The account to receive the lamportsamount- The number of lamports to add
transfer#
Creates an instruction to transfer SOL from one account to another.
Parameters:
from- The public key of the account to transfer fromto- The public key of the account to transfer toamount- The number of lamports to transfer
Returns: An instruction that needs to be executed with process_transaction.
Utility Methods#
payer#
Returns the default payer keypair for transactions.
Returns: The payer keypair used for transaction fees.
get_sysvar#
Retrieves a sysvar of the specified type.
Returns: The requested sysvar data.
get_program_data_address_v3#
Derives the program data address for an upgradeable program.
Parameters:
program_address- The public key of the upgradeable program
Returns: The derived program data address (PDA).
Description: Finds the program data account address for an upgradeable BPF loader program. This is useful when you need to access or verify the program data account associated with an upgradeable program.
create_program_address#
Creates a program address (PDA) from seeds and a program ID.
Parameters:
seeds- Array of seed byte slices used to derive the addressprogram_id- The program ID to use for derivation
Returns: Some(Pubkey) if the seeds produce a valid PDA, None otherwise.
Description: Attempts to create a valid program-derived address using the provided seeds and program ID. Unlike find_program_address, this does not search for a valid bump seed and will return None if the provided seeds don't produce a valid PDA.
find_program_address#
Finds a valid program address (PDA) and its bump seed.
Parameters:
seeds- Array of seed byte slices used to derive the addressprogram_id- The program ID to use for derivation
Returns: A tuple containing the derived PDA and the bump seed used to generate it.
Description: Searches for a valid program-derived address by trying different bump seeds (starting from 255 and counting down) until a valid PDA is found. This is the canonical way to derive PDAs in Solana programs.
Direct Account Manipulation#
Testing Environment Only
The following methods allow direct manipulation of account state without going through program instructions. This behavior does not reflect normal mainnet conditions where accounts can only be modified by their owning program through proper transaction execution. Use these methods for test setup and specific fuzzing scenarios only.
set_account_with_type#
Sets account data for a specific type at the specified address. The data is serialized with its discriminator prepended and stored as a rent-exempt account.
pub fn set_account_with_type<T: BorshSerialize + AccountDiscriminator>(
&mut self,
address: &Pubkey,
owner: &Pubkey,
data: &T,
discriminator_override: Option<&[u8]>,
)
Parameters:
address- The public key where the account should be storedowner- The program ID that will own this accountdata- The account data to serialize and storediscriminator_override- Optional custom discriminator bytes to use. IfNone, uses the discriminator from the type'sAccountDiscriminatorimplementation.
Discriminator Compatibility
For older Anchor versions where the IDL does not contain discriminator data, an 8-byte zero discriminator ([0, 0, 0, 0, 0, 0, 0, 0]) is used by default. This is typically not a problem for get_account_with_type as it only skips the discriminator bytes without validation. However, set_account_with_type will serialize this zero discriminator, which will cause issues when the program attempts to deserialize the account since it won't match the expected discriminator. Use discriminator_override to provide the correct discriminator if your IDL lacks this data.
set_account_custom#
Sets custom account data for the specified address.
Parameters:
address- The account address to setaccount- The account data to set
Example Usage#
use trident_fuzz::fuzzing::*;
#[flow]
fn test_account_management(&mut self) {
let user_account = self.trident.random_pubkey();
let token_account = self.trident.random_pubkey();
let program_id = Pubkey::new_unique();
// Airdrop lamports to an account
self.trident.airdrop(&user_account, 10 * LAMPORTS_PER_SOL);
// Get account data and verify balance
let account_data = self.trident.get_account(&user_account);
// Get account with specific type (discriminator handled automatically)
if let Some(my_data) = self.trident.get_account_with_type::<MyAccountData>(&token_account, None) {
println!("Account data: {:?}", my_data);
}
// Set account with specific type (discriminator and rent handled automatically)
let new_data = MyAccountData::new(1000, user_account);
self.trident.set_account_with_type(&token_account, &program_id, &new_data, None);
// Get current clock
let clock = self.trident.get_sysvar::<Clock>();
println!("Current timestamp: {}", clock.unix_timestamp);
// Get the default payer
let payer = self.trident.payer();
println!("Payer pubkey: {}", payer.pubkey());
// Find a PDA
let seeds = &[b"my-seed", user_account.as_ref()];
let (pda, bump) = self.trident.find_program_address(seeds, &program_id);
// Create a PDA with known bump
let seeds_with_bump = &[b"my-seed", user_account.as_ref(), &[bump]];
if let Some(pda_verified) = self.trident.create_program_address(seeds_with_bump, &program_id) {
assert_eq!(pda, pda_verified);
}
}