revme/cmd/bench/
burntpix.rs1pub mod static_data;
2
3use context::TxEnv;
4use criterion::Criterion;
5use primitives::{StorageKey, StorageValue};
6use static_data::{
7 BURNTPIX_ADDRESS_ONE, BURNTPIX_ADDRESS_THREE, BURNTPIX_ADDRESS_TWO, BURNTPIX_BYTECODE_FOUR,
8 BURNTPIX_BYTECODE_ONE, BURNTPIX_BYTECODE_THREE, BURNTPIX_BYTECODE_TWO, BURNTPIX_MAIN_ADDRESS,
9 STORAGE_ONE, STORAGE_TWO, STORAGE_ZERO,
10};
11
12use alloy_sol_types::{sol, SolCall};
13use database::{CacheDB, BENCH_CALLER};
14use revm::{
15 database_interface::EmptyDB,
16 primitives::{hex, keccak256, Address, Bytes, TxKind, B256, U256},
17 state::{AccountInfo, Bytecode},
18 Context, ExecuteEvm, MainBuilder, MainContext,
19};
20
21use std::{error::Error, fs::File, io::Write};
22
23use std::str::FromStr;
24
25sol! {
26 #[derive(Debug, PartialEq, Eq)]
27 interface IBURNTPIX {
28 function run( uint32 seed, uint256 iterations) returns (string);
29 }
30}
31
32pub fn run(criterion: &mut Criterion) {
33 let (seed, iterations) = try_init_env_vars().expect("Failed to parse env vars");
34
35 let run_call_data = IBURNTPIX::runCall { seed, iterations }.abi_encode();
36
37 let db = init_db();
38
39 let mut evm = Context::mainnet()
40 .with_db(db)
41 .modify_cfg_chained(|c| c.disable_nonce_check = true)
42 .build_mainnet();
43
44 let tx = TxEnv {
45 caller: BENCH_CALLER,
46 kind: TxKind::Call(BURNTPIX_MAIN_ADDRESS),
47 data: run_call_data.clone().into(),
48 gas_limit: u64::MAX,
49 ..Default::default()
50 };
51
52 criterion.bench_function("burntpix", |b| {
53 b.iter(|| {
54 evm.transact(tx.clone()).unwrap();
55 })
56 });
57
58 }
87
88pub fn svg(filename: String, svg_data: &[u8]) -> Result<(), Box<dyn Error>> {
90 let current_dir = std::env::current_dir()?;
91 let svg_dir = current_dir.join("burntpix").join("svgs");
92 std::fs::create_dir_all(&svg_dir)?;
93
94 let file_path = svg_dir.join(format!("{}.svg", filename));
95 let mut file = File::create(file_path)?;
96 file.write_all(svg_data)?;
97
98 Ok(())
99}
100
101const DEFAULT_SEED: &str = "0";
102const DEFAULT_ITERATIONS: &str = "0x4E20"; fn try_init_env_vars() -> Result<(u32, U256), Box<dyn Error>> {
104 let seed_from_env = std::env::var("SEED").unwrap_or(DEFAULT_SEED.to_string());
105 let seed: u32 = try_from_hex_to_u32(&seed_from_env)?;
106 let iterations_from_env = std::env::var("ITERATIONS").unwrap_or(DEFAULT_ITERATIONS.to_string());
107 let iterations = U256::from_str(&iterations_from_env)?;
108 Ok((seed, iterations))
109}
110
111fn try_from_hex_to_u32(hex: &str) -> Result<u32, Box<dyn Error>> {
112 let trimmed = hex.strip_prefix("0x").unwrap_or(hex);
113 u32::from_str_radix(trimmed, 16).map_err(|e| format!("Failed to parse hex: {}", e).into())
114}
115
116fn insert_account_info(cache_db: &mut CacheDB<EmptyDB>, addr: Address, code: &str) {
117 let code = Bytes::from(hex::decode(code).unwrap());
118 let code_hash = hex::encode(keccak256(&code));
119 let account_info = AccountInfo::new(
120 U256::from(0),
121 0,
122 B256::from_str(&code_hash).unwrap(),
123 Bytecode::new_raw(code),
124 );
125 cache_db.insert_account_info(addr, account_info);
126}
127
128fn init_db() -> CacheDB<EmptyDB> {
129 let mut cache_db = CacheDB::new(EmptyDB::default());
130
131 insert_account_info(&mut cache_db, BURNTPIX_ADDRESS_ONE, BURNTPIX_BYTECODE_ONE);
132 insert_account_info(&mut cache_db, BURNTPIX_MAIN_ADDRESS, BURNTPIX_BYTECODE_TWO);
133 insert_account_info(&mut cache_db, BURNTPIX_ADDRESS_TWO, BURNTPIX_BYTECODE_THREE);
134 insert_account_info(
135 &mut cache_db,
136 BURNTPIX_ADDRESS_THREE,
137 BURNTPIX_BYTECODE_FOUR,
138 );
139
140 cache_db
141 .insert_account_storage(
142 BURNTPIX_MAIN_ADDRESS,
143 StorageKey::from(0),
144 StorageValue::from_be_bytes(*STORAGE_ZERO),
145 )
146 .unwrap();
147
148 cache_db
149 .insert_account_storage(
150 BURNTPIX_MAIN_ADDRESS,
151 StorageKey::from(1),
152 StorageValue::from_be_bytes(*STORAGE_ONE),
153 )
154 .unwrap();
155
156 cache_db
157 .insert_account_storage(
158 BURNTPIX_MAIN_ADDRESS,
159 StorageValue::from(2),
160 StorageKey::from_be_bytes(*STORAGE_TWO),
161 )
162 .unwrap();
163
164 cache_db
165}