revme/cmd/bench/
burntpix.rs1pub mod static_data;
2
3use static_data::{
4 BURNTPIX_ADDRESS_ONE, BURNTPIX_ADDRESS_THREE, BURNTPIX_ADDRESS_TWO, BURNTPIX_BYTECODE_FOUR,
5 BURNTPIX_BYTECODE_ONE, BURNTPIX_BYTECODE_THREE, BURNTPIX_BYTECODE_TWO, BURNTPIX_MAIN_ADDRESS,
6 STORAGE_ONE, STORAGE_TWO, STORAGE_ZERO,
7};
8
9use alloy_sol_types::{sol, SolCall};
10use database::{CacheDB, BENCH_CALLER};
11use revm::{
12 context_interface::result::{ExecutionResult, Output},
13 database_interface::EmptyDB,
14 primitives::{hex, keccak256, Address, Bytes, TxKind, B256, U256},
15 state::{AccountInfo, Bytecode},
16 Context, ExecuteEvm, MainBuilder, MainContext,
17};
18
19use std::fs::File;
20use std::{error::Error, time::Instant};
21
22use std::{io::Write, str::FromStr};
23
24sol! {
25 #[derive(Debug, PartialEq, Eq)]
26 interface IBURNTPIX {
27 function run( uint32 seed, uint256 iterations) returns (string);
28 }
29}
30
31pub fn run() {
32 let (seed, iterations) = try_init_env_vars().expect("Failed to parse env vars");
33
34 let run_call_data = IBURNTPIX::runCall { seed, iterations }.abi_encode();
35
36 let db = init_db();
37
38 let mut evm = Context::mainnet()
39 .with_db(db)
40 .modify_tx_chained(|tx| {
41 tx.caller = BENCH_CALLER;
42 tx.kind = TxKind::Call(BURNTPIX_MAIN_ADDRESS);
43 tx.data = run_call_data.clone().into();
44 tx.gas_limit = u64::MAX;
45 })
46 .build_mainnet();
47
48 let started = Instant::now();
49 let tx_result = evm.transact_previous().unwrap().result;
50 let return_data = match tx_result {
51 ExecutionResult::Success {
52 output, gas_used, ..
53 } => {
54 println!("Gas used: {:?}", gas_used);
55 println!("Time elapsed: {:?}", started.elapsed());
56 match output {
57 Output::Call(value) => value,
58 _ => unreachable!("Unexpected output type"),
59 }
60 }
61 _ => unreachable!("Execution failed: {:?}", tx_result),
62 };
63
64 let returndata_offset = 64;
66 let data = &return_data[returndata_offset..];
67
68 let trimmed_data = data
70 .split_at(data.len() - data.iter().rev().filter(|&x| *x == 0).count())
71 .0;
72 let file_name = format!("{}_{}", seed, iterations);
73
74 svg(file_name, trimmed_data).expect("Failed to store svg");
75}
76
77fn svg(filename: String, svg_data: &[u8]) -> Result<(), Box<dyn Error>> {
78 let current_dir = std::env::current_dir()?;
79 let svg_dir = current_dir.join("burntpix").join("svgs");
80 std::fs::create_dir_all(&svg_dir)?;
81
82 let file_path = svg_dir.join(format!("{}.svg", filename));
83 let mut file = File::create(file_path)?;
84 file.write_all(svg_data)?;
85
86 Ok(())
87}
88
89const DEFAULT_SEED: &str = "0";
90const DEFAULT_ITERATIONS: &str = "0x7A120";
91fn try_init_env_vars() -> Result<(u32, U256), Box<dyn Error>> {
92 let seed_from_env = std::env::var("SEED").unwrap_or(DEFAULT_SEED.to_string());
93 let seed: u32 = try_from_hex_to_u32(&seed_from_env)?;
94 let iterations_from_env = std::env::var("ITERATIONS").unwrap_or(DEFAULT_ITERATIONS.to_string());
95 let iterations = U256::from_str(&iterations_from_env)?;
96 Ok((seed, iterations))
97}
98
99fn try_from_hex_to_u32(hex: &str) -> Result<u32, Box<dyn Error>> {
100 let trimmed = hex.strip_prefix("0x").unwrap_or(hex);
101 u32::from_str_radix(trimmed, 16).map_err(|e| format!("Failed to parse hex: {}", e).into())
102}
103
104fn insert_account_info(cache_db: &mut CacheDB<EmptyDB>, addr: Address, code: &str) {
105 let code = Bytes::from(hex::decode(code).unwrap());
106 let code_hash = hex::encode(keccak256(&code));
107 let account_info = AccountInfo::new(
108 U256::from(0),
109 0,
110 B256::from_str(&code_hash).unwrap(),
111 Bytecode::new_raw(code),
112 );
113 cache_db.insert_account_info(addr, account_info);
114}
115
116fn init_db() -> CacheDB<EmptyDB> {
117 let mut cache_db = CacheDB::new(EmptyDB::default());
118
119 insert_account_info(&mut cache_db, BURNTPIX_ADDRESS_ONE, BURNTPIX_BYTECODE_ONE);
120 insert_account_info(&mut cache_db, BURNTPIX_MAIN_ADDRESS, BURNTPIX_BYTECODE_TWO);
121 insert_account_info(&mut cache_db, BURNTPIX_ADDRESS_TWO, BURNTPIX_BYTECODE_THREE);
122 insert_account_info(
123 &mut cache_db,
124 BURNTPIX_ADDRESS_THREE,
125 BURNTPIX_BYTECODE_FOUR,
126 );
127
128 cache_db
129 .insert_account_storage(
130 BURNTPIX_MAIN_ADDRESS,
131 U256::from(0),
132 U256::from_be_bytes(*STORAGE_ZERO),
133 )
134 .unwrap();
135
136 cache_db
137 .insert_account_storage(
138 BURNTPIX_MAIN_ADDRESS,
139 U256::from(1),
140 U256::from_be_bytes(*STORAGE_ONE),
141 )
142 .unwrap();
143
144 cache_db
145 .insert_account_storage(
146 BURNTPIX_MAIN_ADDRESS,
147 U256::from(2),
148 U256::from_be_bytes(*STORAGE_TWO),
149 )
150 .unwrap();
151
152 cache_db
153}