revm/handler/mainnet/
validation.rs

1use revm_interpreter::gas;
2
3use crate::{
4    primitives::{db::Database, EVMError, Env, InvalidTransaction, Spec},
5    Context,
6};
7
8/// Validate environment for the mainnet.
9pub fn validate_env<SPEC: Spec, DB: Database>(env: &Env) -> Result<(), EVMError<DB::Error>> {
10    // Important: validate block before tx.
11    env.validate_block_env::<SPEC>()?;
12    env.validate_tx::<SPEC>()?;
13    Ok(())
14}
15
16/// Validates transaction against the state.
17pub fn validate_tx_against_state<SPEC: Spec, EXT, DB: Database>(
18    context: &mut Context<EXT, DB>,
19) -> Result<(), EVMError<DB::Error>> {
20    // load acc
21    let tx_caller = context.evm.env.tx.caller;
22    let caller_account = context
23        .evm
24        .inner
25        .journaled_state
26        .load_code(tx_caller, &mut context.evm.inner.db)?;
27
28    context
29        .evm
30        .inner
31        .env
32        .validate_tx_against_state::<SPEC>(caller_account.data)
33        .map_err(EVMError::Transaction)?;
34
35    Ok(())
36}
37
38/// Validate initial transaction gas.
39pub fn validate_initial_tx_gas<SPEC: Spec, DB: Database>(
40    env: &Env,
41) -> Result<u64, EVMError<DB::Error>> {
42    let input = &env.tx.data;
43    let is_create = env.tx.transact_to.is_create();
44    let access_list = &env.tx.access_list;
45    let authorization_list_num = env
46        .tx
47        .authorization_list
48        .as_ref()
49        .map(|l| l.len() as u64)
50        .unwrap_or_default();
51
52    let initial_gas_spend = gas::validate_initial_tx_gas(
53        SPEC::SPEC_ID,
54        input,
55        is_create,
56        access_list,
57        authorization_list_num,
58    );
59
60    // Additional check to see if limit is big enough to cover initial gas.
61    if initial_gas_spend > env.tx.gas_limit {
62        return Err(InvalidTransaction::CallGasCostMoreThanGasLimit.into());
63    }
64    Ok(initial_gas_spend)
65}