trident_config/
fuzz.rs

1use crate::utils::resolve_path;
2use base64::{prelude::BASE64_STANDARD, Engine};
3use serde::{Deserialize, Serialize};
4use solana_sdk::{
5    account::{AccountSharedData, WritableAccount},
6    pubkey::Pubkey,
7};
8use std::{fs, str::FromStr};
9
10#[derive(Debug, Deserialize, Clone, Default)]
11pub struct Fuzz {
12    pub fuzzing_with_stats: Option<bool>,
13    pub allow_duplicate_txs: Option<bool>,
14    pub programs: Option<Vec<_FuzzProgram>>,
15    pub accounts: Option<Vec<_FuzzAccount>>,
16}
17
18impl Fuzz {
19    pub fn get_fuzzing_with_stats(&self) -> bool {
20        self.fuzzing_with_stats.unwrap_or(false)
21    }
22    pub fn get_allow_duplicate_txs(&self) -> bool {
23        self.allow_duplicate_txs.unwrap_or(false)
24    }
25}
26
27#[derive(Debug, Deserialize, Clone)]
28pub struct _FuzzProgram {
29    pub address: String,
30    pub program: String,
31}
32
33#[derive(Debug, Deserialize, Clone)]
34pub struct _FuzzAccount {
35    pub address: String,
36    pub filename: String,
37}
38
39#[derive(Debug, Deserialize, Clone)]
40pub struct FuzzProgram {
41    pub address: Pubkey,
42    pub data: Vec<u8>,
43}
44
45impl From<&_FuzzProgram> for FuzzProgram {
46    fn from(_f: &_FuzzProgram) -> Self {
47        let program_path = &_f.program;
48        let program_address = &_f.address;
49
50        let path = resolve_path(program_path);
51
52        let program_data =
53            fs::read(path).unwrap_or_else(|_| panic!("Failed to read file: {}", program_path));
54
55        let pubkey = Pubkey::from_str(program_address)
56            .unwrap_or_else(|_| panic!("Cannot parse the program address: {}", program_address));
57
58        FuzzProgram {
59            address: pubkey,
60            data: program_data,
61        }
62    }
63}
64
65#[derive(Debug, Deserialize, Clone)]
66pub struct FuzzAccount {
67    pub pubkey: Pubkey,
68    pub account: AccountSharedData,
69}
70
71impl From<&_FuzzAccount> for FuzzAccount {
72    fn from(_f: &_FuzzAccount) -> Self {
73        let account_path = &_f.filename;
74
75        let path = resolve_path(account_path);
76
77        let file_content = fs::read_to_string(path)
78            .unwrap_or_else(|_| panic!("Failed to read file: {}", account_path));
79
80        let account_raw: FuzzAccountRaw = serde_json::from_str(&file_content)
81            .unwrap_or_else(|_| panic!("Failed to parse JSON from file: {}", account_path));
82
83        let pubkey = Pubkey::from_str(&account_raw.pubkey)
84            .unwrap_or_else(|_| panic!("Cannot convert address for: {}", account_raw.pubkey));
85
86        let owner_address = Pubkey::from_str(&account_raw.account.owner).unwrap_or_else(|_| {
87            panic!(
88                "Cannot convert address for owner: {}",
89                account_raw.account.owner
90            )
91        });
92
93        let data_base_64 = account_raw.account.data.first().unwrap_or_else(|| {
94            panic!(
95                "Cannot read base64 data for account: {}",
96                account_raw.pubkey
97            )
98        });
99
100        let account = AccountSharedData::create(
101            account_raw.account.lamports,
102            BASE64_STANDARD
103                .decode(data_base_64)
104                .unwrap_or_else(|_| panic!("Failed to decode base64 data of {}", account_path)),
105            owner_address,
106            account_raw.account.executable,
107            account_raw.account.rent_epoch,
108        );
109
110        FuzzAccount { pubkey, account }
111    }
112}
113
114#[derive(Debug, Deserialize, Clone)]
115pub struct FuzzAccountRaw {
116    pub pubkey: String,
117    pub account: AccountRaw,
118}
119
120#[derive(Debug, Serialize, Deserialize, Clone)]
121pub struct AccountRaw {
122    pub lamports: u64,
123    pub data: Vec<String>,
124    pub owner: String,
125    pub executable: bool,
126    #[serde(rename = "rentEpoch")]
127    pub rent_epoch: u64,
128}