Skip to content

Commit

Permalink
✨ Introduce AccountsSnapshots derive Macro
Browse files Browse the repository at this point in the history
  • Loading branch information
lukacan committed Jul 6, 2024
1 parent 3bf8287 commit 8686c36
Show file tree
Hide file tree
Showing 27 changed files with 1,423 additions and 464 deletions.
802 changes: 568 additions & 234 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions crates/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pretty_assertions = "1.1.0"
trident-derive-displayix = { path = "../fuzz/derive/display_ix", version = "0.0.1" }
trident-derive-fuzz-deserialize = { path = "../fuzz/derive/fuzz_deserialize", version = "0.0.1" }
trident-derive-fuzz-test-executor = { path = "../fuzz/derive/fuzz_test_executor", version = "0.0.1" }
trident-derive-accounts-snapshots = { path = "../fuzz/derive/accounts_snapshots", version = "0.0.1" }

trident-test = { path = "../test", version = "0.3.2" }
trident-fuzz = { path = "../fuzz", version = "0.1.0" }

Expand Down
1 change: 1 addition & 0 deletions crates/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub mod fuzzing {
pub use honggfuzz::fuzz;

/// trident derive
pub use trident_derive_accounts_snapshots::AccountsSnapshots;
pub use trident_derive_displayix::DisplayIx;
pub use trident_derive_fuzz_deserialize::FuzzDeserialize;
pub use trident_derive_fuzz_test_executor::FuzzTestExecutor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ fn deserialize_ctx_struct_anchor(
let generated_deser_impl: syn::Item = parse_quote! {
impl<'info> #snapshot_name<'info> {
pub fn deserialize_option(
_program_id: &anchor_lang::prelude::Pubkey,
accounts: &'info mut [Option<AccountInfo<'info>>],
) -> core::result::Result<Self, FuzzingError> {
let mut accounts_iter = accounts.iter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct WithdrawUnlockedSnapshot<'info> {
}
impl<'info> InitVestingSnapshot<'info> {
pub fn deserialize_option(
_program_id: &anchor_lang::prelude::Pubkey,
accounts: &'info mut [Option<AccountInfo<'info>>],
) -> core::result::Result<Self, FuzzingError> {
let mut accounts_iter = accounts.iter();
Expand Down Expand Up @@ -114,6 +115,7 @@ impl<'info> InitVestingSnapshot<'info> {
}
impl<'info> WithdrawUnlockedSnapshot<'info> {
pub fn deserialize_option(
_program_id: &anchor_lang::prelude::Pubkey,
accounts: &'info mut [Option<AccountInfo<'info>>],
) -> core::result::Result<Self, FuzzingError> {
let mut accounts_iter = accounts.iter();
Expand Down
1 change: 1 addition & 0 deletions crates/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ prettytable = "0.10.0"
serde = { version = "1.0.136", default-features = false }
serde_json = "1.0.72"
tokio = "1"
convert_case = "0.6.0"
19 changes: 19 additions & 0 deletions crates/fuzz/derive/accounts_snapshots/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "trident-derive-accounts-snapshots"
version = "0.0.1"
rust-version = "1.60"
edition = "2021"
license-file = "../../../../LICENSE"
readme = "../../../../README.md"
description = "trident-accounts-snapshots"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1"
quote = "1"
syn = "1"
trident-fuzz = { path = "../../", version = "0.1.0" }
10 changes: 10 additions & 0 deletions crates/fuzz/derive/accounts_snapshots/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use proc_macro::TokenStream;
use quote::ToTokens;
use syn::parse_macro_input;

#[proc_macro_derive(AccountsSnapshots)]
pub fn derive_accounts_snapshots(item: TokenStream) -> TokenStream {
parse_macro_input!(item as trident_fuzz::trident_accounts_struct::TridentAccountsStruct)
.to_token_stream()
.into()
}
3 changes: 2 additions & 1 deletion crates/fuzz/derive/fuzz_deserialize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ pub fn fuzz_deserialize(input: TokenStream) -> TokenStream {
type Ix = #snapshot_name<'info>;
fn deserialize_option(
&self,
_program_id: &anchor_lang::prelude::Pubkey,
accounts: &'info mut [Option<AccountInfo<'info>>],
) -> Result<Self::Ix, FuzzingError> {
Self::Ix::deserialize_option(accounts)
Self::Ix::deserialize_option(_program_id,accounts)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/fuzz/derive/fuzz_test_executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub fn fuzz_test_executor(input: TokenStream) -> TokenStream {
stats_logger.increase_successful(self.to_context_string());

snaphot.capture_after(client).unwrap();
let (acc_before, acc_after) = snaphot.get_snapshot()
let (acc_before, acc_after) = snaphot.get_snapshot(&program_id)
.map_err(|e| e.with_origin(Origin::Instruction(self.to_context_string())))
.expect("Snapshot deserialization expect"); // we want to panic if we cannot unwrap to cause a crash

Expand Down
1 change: 1 addition & 0 deletions crates/fuzz/src/data_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ pub trait FuzzDeserialize<'info> {

fn deserialize_option(
&self,
_program_id: &anchor_lang::prelude::Pubkey,
accounts: &'info mut [Option<AccountInfo<'info>>],
) -> Result<Self::Ix, FuzzingError>;
}
Expand Down
1 change: 1 addition & 0 deletions crates/fuzz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ pub mod fuzzing_stats;
pub mod program_test_client_blocking;
pub mod snapshot;
pub type AccountId = u8;
pub mod trident_accounts_struct;
9 changes: 6 additions & 3 deletions crates/fuzz/src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ where
Self::calculate_account_info(&mut self.before, self.metas)
}

pub fn get_snapshot(&'info mut self) -> Result<(T::Ix, T::Ix), FuzzingErrorWithOrigin> {
pub fn get_snapshot(
&'info mut self,
program_id: &solana_sdk::pubkey::Pubkey,
) -> Result<(T::Ix, T::Ix), FuzzingErrorWithOrigin> {
// When user passes an account that is not initialized, the runtime will provide
// a default empty account to the program. If the uninitialized account is of type
// AccountInfo, Signer or UncheckedAccount, Anchor will not return an error. However
Expand All @@ -114,11 +117,11 @@ where

let pre_ix = self
.ix
.deserialize_option(&mut self.before_acc_inf)
.deserialize_option(program_id, &mut self.before_acc_inf)
.map_err(|e| e.with_context(Context::Pre))?;
let post_ix = self
.ix
.deserialize_option(&mut self.after_acc_inf)
.deserialize_option(program_id, &mut self.after_acc_inf)
.map_err(|e| e.with_context(Context::Post))?;
Ok((pre_ix, post_ix))
}
Expand Down
Loading

0 comments on commit 8686c36

Please sign in to comment.