From dbed1f16d97300731df37d44d58fa6e631f0f3ef Mon Sep 17 00:00:00 2001 From: lukacan Date: Wed, 6 Nov 2024 23:45:15 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5=20Remove=20unnecessary=20fuzz=20de?= =?UTF-8?q?serialize?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/client/src/lib.rs | 1 - crates/fuzz/src/fuzz_deserialize.rs | 14 --- crates/fuzz/src/lib.rs | 1 - .../fuzz_tests/fuzz_1/fuzz_instructions.rs | 107 ++++++++++++++++++ 4 files changed, 107 insertions(+), 16 deletions(-) delete mode 100644 crates/fuzz/src/fuzz_deserialize.rs create mode 100644 examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_1/fuzz_instructions.rs diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index 260c44a4..c4e7a0c6 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -58,7 +58,6 @@ pub mod fuzzing { pub use trident_fuzz::fuzz_client::FuzzClient; pub use trident_fuzz::fuzz_data::build_ix_fuzz_data; pub use trident_fuzz::fuzz_data::*; - pub use trident_fuzz::fuzz_deserialize::FuzzDeserialize; pub use trident_fuzz::fuzz_stats::FuzzingStatistics; pub use trident_fuzz::fuzz_test_executor::FuzzTestExecutor; pub use trident_fuzz::ix_ops::IxOps; diff --git a/crates/fuzz/src/fuzz_deserialize.rs b/crates/fuzz/src/fuzz_deserialize.rs deleted file mode 100644 index fbc2724b..00000000 --- a/crates/fuzz/src/fuzz_deserialize.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow(dead_code)] - -use anchor_lang::solana_program::account_info::AccountInfo; - -use crate::error::FuzzingError; - -pub trait FuzzDeserialize<'info>: Sized { - // TODO return also remaining accounts - - fn deserialize_option( - _program_id: &anchor_lang::prelude::Pubkey, - accounts: &mut &'info [Option>], - ) -> Result; -} diff --git a/crates/fuzz/src/lib.rs b/crates/fuzz/src/lib.rs index 7fda9222..043b41c6 100644 --- a/crates/fuzz/src/lib.rs +++ b/crates/fuzz/src/lib.rs @@ -7,7 +7,6 @@ pub mod snapshot; pub type AccountId = u8; pub mod config; pub mod fuzz_client; -pub mod fuzz_deserialize; pub mod fuzz_test_executor; pub mod fuzz_trident; pub mod instructions_sequence; diff --git a/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_1/fuzz_instructions.rs b/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_1/fuzz_instructions.rs new file mode 100644 index 00000000..5df7ab32 --- /dev/null +++ b/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_1/fuzz_instructions.rs @@ -0,0 +1,107 @@ +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; +/// FuzzInstruction contains all available Instructions. +/// Below, the instruction arguments (accounts and data) are defined. +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor)] +pub enum FuzzInstruction { + InitializeFn(InitializeFn), +} +#[derive(Arbitrary, Debug)] +pub struct InitializeFn { + pub accounts: InitializeFnAccounts, + pub data: InitializeFnData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeFnAccounts { + pub author: AccountId, + pub hello_world_account: AccountId, + pub _system_program: AccountId, +} +/// Custom data types must derive `Debug` and `Arbitrary`. +/// To do this, redefine the type in the fuzz test and implement the `From` +/// trait +/// to convert it into the type defined in the program. +/// For more details, see: https://ackee.xyz/trident/docs/dev/features/arbitrary-data/#custom-data-types +#[derive(Arbitrary, Debug)] +pub struct InitializeFnData { + pub input: u8, +} +///IxOps implementation for `InitializeFn` with all required functions. +impl IxOps for InitializeFn { + type IxData = hello_world::instruction::InitializeFn; + type IxAccounts = FuzzAccounts; + /// Definition of the program ID that the Instruction is associated with. + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + hello_world::ID + } + /// Definition of the Instruction data. + /// Use randomly generated data from the fuzzer using `self.data.arg_name` + /// or customize the data as needed. + /// For more details, visit: https://ackee.xyz/trident/docs/dev/features/fuzz-instructions/#get-data + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = hello_world::instruction::InitializeFn { + input: self.data.input, + }; + Ok(data) + } + /// Definition of of the accounts required by the Instruction. + /// To utilize accounts stored in `FuzzAccounts`, use + /// `fuzz_accounts.account_name.get_or_create_account()`. + /// If no signers are required, leave the vector empty. + /// For AccountMetas use ::accounts:: + /// For more details, see: https://ackee.xyz/trident/docs/dev/features/fuzz-instructions/#get-accounts + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let author = fuzz_accounts.author.get_or_create_account( + self.accounts.author, + client, + 5 * LAMPORTS_PER_SOL, + ); + + let hello_world_account = fuzz_accounts.hello_world_account.get_or_create_account( + self.accounts.hello_world_account, + client, + &[b"hello_world_seed"], + &hello_world::ID, + ); + let signers = vec![author.clone()]; + let acc_meta = hello_world::accounts::InitializeContext { + author: author.pubkey(), + hello_world_account, + system_program: solana_sdk::system_program::ID, + } + .to_account_metas(None); + Ok((signers, acc_meta)) + } + fn check( + &self, + _pre_ix: &[SnapshotAccount], + post_ix: &[SnapshotAccount], + _ix_data: Self::IxData, + ) -> Result<(), FuzzingError> { + if let Ok(hello_world_account) = + hello_world::StoreHelloWorld::try_deserialize(&mut post_ix[1].data()) + { + if hello_world_account.input == 253 { + return Err(FuzzingError::Custom(1)); + } + } + Ok(()) + } +} +/// Use AccountsStorage where T can be one of: +/// Keypair, PdaStore, TokenStore, MintStore, ProgramStore +#[derive(Default)] +pub struct FuzzAccounts { + author: AccountsStorage, + hello_world_account: AccountsStorage, + // No need to fuzz system_program + // system_program: AccountsStorage, +}