Skip to content

Commit

Permalink
✨ Allow direct accounts manipulation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ikrk committed Mar 11, 2024
1 parent 36ed252 commit b601de3
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
12 changes: 9 additions & 3 deletions crates/client/src/fuzzer/accounts_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use solana_sdk::{pubkey::Pubkey, signature::Keypair};
use crate::{data_builder::FuzzClient, AccountId};

pub struct PdaStore {
pubkey: Pubkey,
pub pubkey: Pubkey,
pub seeds: Vec<Vec<u8>>,
}
impl PdaStore {
Expand All @@ -28,21 +28,27 @@ pub struct ProgramStore {

pub struct AccountsStorage<T> {
accounts: HashMap<AccountId, T>,
pub max_accounts: u8,
_max_accounts: u8,
}

impl<T> AccountsStorage<T> {
pub fn new(max_accounts: u8) -> Self {
let accounts: HashMap<AccountId, T> = HashMap::new();
Self {
accounts,
max_accounts,
_max_accounts: max_accounts,
}
}

/// Gets a reference to the account with the given account ID
pub fn get(&self, account_id: AccountId) -> Option<&T> {
self.accounts.get(&account_id)
}

/// Returns a mutable reference to the underlying HashMap that stores accounts with IDs as keys
pub fn storage(&mut self) -> &mut HashMap<AccountId, T> {
&mut self.accounts
}
}

impl<T> Default for AccountsStorage<T> {
Expand Down
28 changes: 22 additions & 6 deletions crates/client/src/fuzzer/data_builder.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use anchor_client::anchor_lang::solana_program::account_info::{Account as Acc, AccountInfo};
use anchor_client::anchor_lang::solana_program::hash::Hash;
use anchor_lang::prelude::Rent;
use arbitrary::Arbitrary;
use arbitrary::Unstructured;
use solana_sdk::account::Account;
use solana_sdk::account::{Account, AccountSharedData};
use solana_sdk::instruction::AccountMeta;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::Keypair;
Expand Down Expand Up @@ -156,11 +157,15 @@ pub trait FuzzDeserialize<'info> {
) -> Result<Self::Ix, FuzzingError>;
}

/// A trait providing methods to read and write (manipulate) accounts
pub trait FuzzClient {
// TODO add method to add another program
// TODO add methods to modify current accounts
// TODO check if self must be mutable
/// Create an empty account and add lamports to it
fn set_account(&mut self, lamports: u64) -> Keypair;

/// Create or overwrite a custom account, subverting normal runtime checks.
fn set_account_custom(&mut self, address: &Pubkey, account: &AccountSharedData);

/// Create an SPL token account
#[allow(clippy::too_many_arguments)]
fn set_token_account(
&mut self,
Expand All @@ -172,23 +177,34 @@ pub trait FuzzClient {
delegated_amount: u64,
close_authority: Option<Pubkey>,
) -> Pubkey;

/// Create an SPL mint account
fn set_mint_account(
&mut self,
decimals: u8,
owner: &Pubkey,
freeze_authority: Option<Pubkey>,
) -> Pubkey;

/// Get the Keypair of the client's payer account
fn payer(&self) -> Keypair;

fn get_account(&mut self, key: &Pubkey) -> Result<Option<Account>, FuzzClientError>; // TODO support dynamic errors
// TODO add interface to modify existing accounts
/// Get the account at the given address
fn get_account(&mut self, key: &Pubkey) -> Result<Option<Account>, FuzzClientError>;

/// Get accounts based on the supplied meta information
fn get_accounts(
&mut self,
metas: &[AccountMeta],
) -> Result<Vec<Option<Account>>, FuzzClientErrorWithOrigin>;

/// Get last blockhash
fn get_last_blockhash(&self) -> Hash;

/// Get the cluster rent
fn get_rent(&mut self) -> Result<Rent, FuzzClientError>;

/// Send a transaction and return until the transaction has been finalized or rejected.
fn process_transaction(
&mut self,
transaction: impl Into<VersionedTransaction>,
Expand Down
8 changes: 8 additions & 0 deletions crates/client/src/fuzzer/program_test_client_blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,12 @@ impl FuzzClient for ProgramTestClientBlocking {
.rt
.block_on(self.ctx.banks_client.process_transaction(transaction))?)
}

fn set_account_custom(&mut self, address: &Pubkey, account: &AccountSharedData) {
self.ctx.set_account(address, account);
}

fn get_rent(&mut self) -> Result<Rent, FuzzClientError> {
Ok(self.rt.block_on(self.ctx.banks_client.get_rent())?)
}
}

0 comments on commit b601de3

Please sign in to comment.