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