trident_derive_fuzz_test_executor/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput};
#[proc_macro_derive(FuzzTestExecutor)]
pub fn fuzz_test_executor(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let enum_name = &input.ident;
let display_impl = match &input.data {
Data::Enum(enum_data) => {
let display_match_arms = enum_data.variants.iter().map(|variant| {
let variant_name = &variant.ident;
quote! {
#enum_name::#variant_name (ix) => {
if cfg!(honggfuzz){
TransactionExecutor::process_transaction_honggfuzz(
&self.to_context_string(),
client,
ix,
sent_txs,
config,
accounts
)?;
}else if cfg!(afl){
TransactionExecutor::process_transaction_afl(
&self.to_context_string(),
client,
ix,
sent_txs,
config,
accounts
)?;
}
}
}
});
quote! {
impl FuzzTestExecutor<FuzzAccounts> for FuzzInstruction {
fn run_fuzzer(
&self,
accounts: &RefCell<FuzzAccounts>,
client: &mut impl FuzzClient,
sent_txs: &mut HashMap<Hash, ()>,
config: &Config,
) -> core::result::Result<(), FuzzClientErrorWithOrigin> {
match self {
#(#display_match_arms)*
}
Ok(())
}
}
}
}
_ => panic!("FuzzTestExecutor can only be derived for enums"),
};
TokenStream::from(display_impl)
}