trident_client::fuzzing

Trait IxOps

source
pub trait IxOps<'info> {
    type IxData: InstructionData;
    type IxAccounts;
    type IxSnapshot: FuzzDeserialize<'info>;

    // Required methods
    fn get_program_id(&self) -> Pubkey;
    fn get_data(
        &self,
        client: &mut impl FuzzClient,
        fuzz_accounts: &mut Self::IxAccounts,
    ) -> Result<Self::IxData, FuzzingError>;
    fn get_accounts(
        &self,
        client: &mut impl FuzzClient,
        fuzz_accounts: &mut Self::IxAccounts,
    ) -> Result<(Vec<Keypair>, Vec<AccountMeta>), FuzzingError>;

    // Provided methods
    fn check(
        &self,
        pre_ix: Self::IxSnapshot,
        post_ix: Self::IxSnapshot,
        ix_data: Self::IxData,
    ) -> Result<(), FuzzingError> { ... }
    fn tx_error_handler(
        &self,
        e: FuzzClientErrorWithOrigin,
        ix_data: Self::IxData,
        pre_ix_acc_infos: &mut &'info [Option<AccountInfo<'info>>],
    ) -> Result<(), FuzzClientErrorWithOrigin> { ... }
    fn deserialize_accounts(
        &self,
        accounts: &mut &'info [Option<AccountInfo<'info>>],
    ) -> Result<Self::IxSnapshot, FuzzingError> { ... }
}
Expand description

A trait providing methods to prepare data and accounts for the fuzzed instructions and allowing users to implement custom invariants checks and transactions error handling.

Required Associated Types§

source

type IxData: InstructionData

The data to be passed as instruction data parameter

source

type IxAccounts

The accounts to be passed as instruction accounts

source

type IxSnapshot: FuzzDeserialize<'info>

The structure to which the instruction accounts will be deserialized

Required Methods§

source

fn get_program_id(&self) -> Pubkey

Specify Program ID to which the Instruction corresponds. This is particularly helpful when using multiple programs in the workspace, to differentiate between possible program calls.

source

fn get_data( &self, client: &mut impl FuzzClient, fuzz_accounts: &mut Self::IxAccounts, ) -> Result<Self::IxData, FuzzingError>

Provides instruction data for the fuzzed instruction. It is assumed that the instruction data will be based on the fuzzer input stored in the self.data variable. However it is on the developer to decide and it can be also for example a hardcoded constant. You should only avoid any non-deterministic random values to preserve reproducibility of the tests.

source

fn get_accounts( &self, client: &mut impl FuzzClient, fuzz_accounts: &mut Self::IxAccounts, ) -> Result<(Vec<Keypair>, Vec<AccountMeta>), FuzzingError>

Provides accounts required for the fuzzed instruction. The method returns a tuple of signers and account metas.

Provided Methods§

source

fn check( &self, pre_ix: Self::IxSnapshot, post_ix: Self::IxSnapshot, ix_data: Self::IxData, ) -> Result<(), FuzzingError>

A method to implement custom invariants checks for a given instruction. This method is called after each successfully executed instruction and by default does nothing. You can override this behavior by providing your own implementation. You can access the snapshots of account states before and after the transaction for comparison.

If you want to detect a crash, you have to return a FuzzingError (or alternativelly panic).

If you want to perform checks also on a failed instruction execution, you can do so using the tx_error_handler method.

source

fn tx_error_handler( &self, e: FuzzClientErrorWithOrigin, ix_data: Self::IxData, pre_ix_acc_infos: &mut &'info [Option<AccountInfo<'info>>], ) -> Result<(), FuzzClientErrorWithOrigin>

A method to implement custom error handler for failed transactions.

The fuzzer might generate a sequence of one or more instructions that are executed sequentially. By default, if the execution of one of the instructions fails, the remaining instructions are skipped and are not executed. This can be overriden by implementing this method and returning Ok(()) instead of propagating the error.

You can also check the kind of the transaction error by inspecting the e parameter. If you would like to detect a crash on a specific error, call panic!().

If your accounts are malformed and the fuzzed program is unable to deserialize it, the transaction execution will fail. In that case also the deserialization of accounts snapshot before executing the instruction would fail. You are provided with the raw account infos snapshots and you are free to deserialize the accounts by yourself and therefore also handling potential errors. To deserialize the pre_ix_acc_infos raw accounts to a snapshot structure, you can call:

self.deserialize_accounts(pre_ix_acc_infos)
source

fn deserialize_accounts( &self, accounts: &mut &'info [Option<AccountInfo<'info>>], ) -> Result<Self::IxSnapshot, FuzzingError>

A method implemented for each instruction variant. This method calls the corresponding deserialize_option, which is defined by deriving the AccountsSnapshot macro. No changes are needed for this function.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§