snark_verifier/loader/evm/util/
executor.rs
1use revm::primitives::TxKind;
2use revm::{
3 primitives::{ExecutionResult, Output, TransactTo, TxEnv},
4 Context, Evm, Handler, InMemoryDB,
5};
6
7pub fn deploy_and_call(deployment_code: Vec<u8>, calldata: Vec<u8>) -> Result<u64, String> {
10 let mut evm =
11 Evm::new(Context::new_with_db(InMemoryDB::default()), Handler::new(Default::default()));
12
13 *evm.tx_mut() = TxEnv {
14 gas_limit: u64::MAX,
15 transact_to: TxKind::Create,
16 data: deployment_code.into(),
17 ..Default::default()
18 };
19
20 let result = evm.transact_commit().unwrap();
21 let contract = match result {
22 ExecutionResult::Success {
23 output: Output::Create(_, Some(contract)),
24 ..
25 } => contract,
26 ExecutionResult::Revert { gas_used, output } => {
27 return Err(format!(
28 "Contract deployment transaction reverts with gas_used {gas_used} and output {:#x}",
29 output
30 ))
31 }
32 ExecutionResult::Halt { reason, gas_used } => return Err(format!(
33 "Contract deployment transaction halts unexpectedly with gas_used {gas_used} and reason {:?}",
34 reason
35 )),
36 _ => unreachable!(),
37 };
38
39 *evm.tx_mut() = TxEnv {
40 gas_limit: u64::MAX,
41 transact_to: TransactTo::Call(contract),
42 data: calldata.into(),
43 ..Default::default()
44 };
45
46 let result = evm.transact_commit().unwrap();
47 match result {
48 ExecutionResult::Success { gas_used, .. } => Ok(gas_used),
49 ExecutionResult::Revert { gas_used, output } => Err(format!(
50 "Contract call transaction reverts with gas_used {gas_used} and output {:#x}",
51 output
52 )),
53 ExecutionResult::Halt { reason, gas_used } => Err(format!(
54 "Contract call transaction halts unexpectedly with gas_used {gas_used} and reason {:?}",
55 reason
56 )),
57 }
58}