trident_syn/codegen/
trident_flow_executor.rs1use proc_macro2::TokenStream;
2use quote::{quote, ToTokens};
3
4use crate::types::trident_flow_executor::TridentFlowExecutorImpl;
5
6impl ToTokens for TridentFlowExecutorImpl {
7 fn to_tokens(&self, tokens: &mut TokenStream) {
8 let type_name = &self.type_name;
9 let impl_items = &self.impl_block;
10 let methods = &self.flow_methods;
11 let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl();
12
13 let init_call = if let Some(init_method) = &self.init_method {
15 quote! {
16 self.#init_method();
17 }
18 } else {
19 quote! {}
20 };
21
22 let execute_impl = if methods.is_empty() {
24 quote! {
25 self.default_random_transactions(fuzzer_data, &mut accounts)?;
27 }
28 } else {
29 let random_tail = if self.args.random_tail {
30 quote! {
31 self.default_random_transactions(fuzzer_data, &mut accounts)?;
32 }
33 } else {
34 quote! {}
35 };
36
37 quote! {
38 #(self.#methods(fuzzer_data, &mut accounts)?;)*
40
41 #random_tail
43 }
44 };
45
46 let expanded = quote! {
47 impl #impl_generics #type_name #ty_generics #where_clause {
48 #(#impl_items)*
49 }
50
51 impl #impl_generics #type_name #ty_generics #where_clause {
52 pub fn execute_flows(
53 &mut self,
54 fuzzer_data: &mut FuzzerData,
55 ) -> std::result::Result<(), FuzzingError> {
56 let mut accounts = FuzzAccounts::default();
57
58 #init_call
59 #execute_impl
60 Ok(())
61 }
62
63 fn default_random_transactions(
64 &mut self,
65 fuzzer_data: &mut FuzzerData,
66 accounts: &mut FuzzAccounts,
67 ) -> std::result::Result<(), FuzzingError> {
68 let mut transactions = <Vec<FuzzTransactions>>::arbitrary(fuzzer_data)?;
69 for transaction in transactions.iter_mut() {
70 transaction.transaction_selector(&mut self.client, accounts)?
71 }
72 Ok(())
73 }
74
75 fn fuzz(&mut self) {
76 if cfg!(honggfuzz) {
77 loop {
78 fuzz_honggfuzz(|fuzzer_data| {
79 let mut buf = Unstructured::new(fuzzer_data);
80 let _ = self.execute_flows(&mut buf);
81 self.client.clear_accounts();
82 });
83 }
84 } else if cfg!(afl) {
85 fuzz_afl(true, |fuzzer_data| {
86 let mut buf = Unstructured::new(fuzzer_data);
87 let _ = self.execute_flows(&mut buf);
88 self.client.clear_accounts();
89 });
90 } else if cfg!(honggfuzz_debug) {
91 let mut crash_file = String::new();
92 std::io::stdin()
93 .read_line(&mut crash_file)
94 .expect("Failed to read crash file path from stdin");
95 let crash_file = crash_file.trim();
96
97 let fuzzer_data = std::fs::read(crash_file).expect("Failed to read crash file");
98 let mut buf = Unstructured::new(&fuzzer_data);
99 let _ = self.execute_flows(&mut buf);
100 self.client.clear_accounts();
101 } else {
102 panic!("Select Honggfuzz or AFL for fuzzing!!!")
103 }
104 }
105 }
106 };
107
108 tokens.extend(expanded);
109 }
110}