-
Notifications
You must be signed in to change notification settings - Fork 207
Expand file tree
/
Copy pathhelpers.rs
More file actions
127 lines (115 loc) · 4.55 KB
/
Copy pathhelpers.rs
File metadata and controls
127 lines (115 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use ethrex_common::types::{ChainConfig, Fork};
use ethrex_common::{
Address, H256,
types::{BlockHeader, GenericTransaction, INITIAL_BASE_FEE, tx_fields::AccessList},
};
use revm::{
Evm, inspector_handle_register,
primitives::{BlockEnv, TxEnv},
};
// Rename imported types for clarity
use revm_primitives::{AccessList as RevmAccessList, SpecId};
use crate::{backends::revm::db::EvmState, errors::EvmError, execution_result::ExecutionResult};
use super::{access_list_inspector, block_env, run_without_commit, tx_env_from_generic};
// Executes a single GenericTransaction, doesn't commit the result or perform state transitions
pub fn simulate_tx_from_generic(
tx: &GenericTransaction,
header: &BlockHeader,
state: &mut EvmState,
spec_id: SpecId,
) -> Result<ExecutionResult, EvmError> {
let block_env = block_env(header, spec_id);
let tx_env = tx_env_from_generic(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE));
run_without_commit(tx_env, block_env, state, spec_id)
}
/// Runs the transaction and returns the access list and estimated gas use (when running the tx with said access list)
pub fn create_access_list(
tx: &GenericTransaction,
header: &BlockHeader,
state: &mut EvmState,
spec_id: SpecId,
) -> Result<(ExecutionResult, AccessList), EvmError> {
let mut tx_env = tx_env_from_generic(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE));
let block_env = block_env(header, spec_id);
// Run tx with access list inspector
let (execution_result, access_list) =
create_access_list_inner(tx_env.clone(), block_env.clone(), state, spec_id)?;
// Run the tx with the resulting access list and estimate its gas used
let execution_result = if execution_result.is_success() {
tx_env.access_list.extend(access_list.0.clone());
run_without_commit(tx_env, block_env, state, spec_id)?
} else {
execution_result
};
let access_list: Vec<(Address, Vec<H256>)> = access_list
.iter()
.map(|item| {
(
Address::from_slice(item.address.0.as_slice()),
item.storage_keys
.iter()
.map(|v| H256::from_slice(v.as_slice()))
.collect(),
)
})
.collect();
Ok((execution_result, access_list))
}
/// Runs the transaction and returns the access list for it
fn create_access_list_inner(
tx_env: TxEnv,
block_env: BlockEnv,
state: &mut EvmState,
spec_id: SpecId,
) -> Result<(ExecutionResult, RevmAccessList), EvmError> {
let mut access_list_inspector = access_list_inspector(&tx_env)?;
#[allow(unused_mut)]
let mut evm_builder = Evm::builder()
.with_block_env(block_env)
.with_tx_env(tx_env)
.with_spec_id(spec_id)
.modify_cfg_env(|env| {
env.disable_base_fee = true;
env.disable_block_gas_limit = true
})
.with_external_context(&mut access_list_inspector);
let tx_result = {
let mut evm = evm_builder
.with_db(&mut state.inner)
.append_handler_register(inspector_handle_register)
.build();
evm.transact()?
};
let access_list = access_list_inspector.into_access_list();
Ok((tx_result.result.into(), access_list))
}
/// Returns the spec id according to the block timestamp and the stored chain config
/// WARNING: Assumes at least Merge fork is active
pub fn spec_id(chain_config: &ChainConfig, block_timestamp: u64) -> SpecId {
fork_to_spec_id(chain_config.get_fork(block_timestamp))
}
pub fn fork_to_spec_id(fork: Fork) -> SpecId {
match fork {
Fork::Frontier => SpecId::FRONTIER,
Fork::FrontierThawing => SpecId::FRONTIER_THAWING,
Fork::Homestead => SpecId::HOMESTEAD,
Fork::DaoFork => SpecId::DAO_FORK,
Fork::Tangerine => SpecId::TANGERINE,
Fork::SpuriousDragon => SpecId::SPURIOUS_DRAGON,
Fork::Byzantium => SpecId::BYZANTIUM,
Fork::Constantinople => SpecId::CONSTANTINOPLE,
Fork::Petersburg => SpecId::PETERSBURG,
Fork::Istanbul => SpecId::ISTANBUL,
Fork::MuirGlacier => SpecId::MUIR_GLACIER,
Fork::Berlin => SpecId::BERLIN,
Fork::London => SpecId::LONDON,
Fork::ArrowGlacier => SpecId::ARROW_GLACIER,
Fork::GrayGlacier => SpecId::GRAY_GLACIER,
Fork::Paris => SpecId::MERGE,
Fork::Shanghai => SpecId::SHANGHAI,
Fork::Cancun => SpecId::CANCUN,
Fork::Prague => SpecId::PRAGUE,
Fork::Osaka => SpecId::OSAKA,
_ => SpecId::LATEST,
}
}