use ethrex_common::{
Address, H256, U256,
types::{BlockHeader, ChainConfig, Fork, ForkBlobSchedule},
};
use crate::constants::{
BLOB_BASE_FEE_UPDATE_FRACTION, BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE, MAX_BLOB_COUNT,
MAX_BLOB_COUNT_ELECTRA, TARGET_BLOB_GAS_PER_BLOCK, TARGET_BLOB_GAS_PER_BLOCK_PECTRA,
};
use rustc_hash::FxHashMap;
pub type TransientStorage = FxHashMap<(Address, U256), U256>;
#[derive(Debug, Default, Clone)]
pub struct Environment {
pub origin: Address,
pub gas_limit: u64,
pub config: EVMConfig,
pub block_number: u64,
pub coinbase: Address,
pub timestamp: u64,
pub prev_randao: Option<H256>,
pub difficulty: U256,
pub slot_number: U256,
pub chain_id: U256,
pub base_fee_per_gas: U256,
pub base_blob_fee_per_gas: U256,
pub gas_price: U256, pub block_excess_blob_gas: Option<u64>,
pub block_blob_gas_used: Option<u64>,
pub tx_blob_hashes: Vec<H256>,
pub tx_max_priority_fee_per_gas: Option<U256>,
pub tx_max_fee_per_gas: Option<U256>,
pub tx_max_fee_per_blob_gas: Option<U256>,
pub tx_nonce: u64,
pub block_gas_limit: u64,
pub is_privileged: bool,
pub fee_token: Option<Address>,
pub disable_balance_check: bool,
pub is_system_call: bool,
}
#[derive(Debug, Clone, Copy)]
pub struct EVMConfig {
pub fork: Fork,
pub blob_schedule: ForkBlobSchedule,
}
impl EVMConfig {
pub fn new(fork: Fork, blob_schedule: ForkBlobSchedule) -> EVMConfig {
EVMConfig {
fork,
blob_schedule,
}
}
pub fn new_from_chain_config(chain_config: &ChainConfig, block_header: &BlockHeader) -> Self {
let fork = chain_config.fork(block_header.timestamp);
let blob_schedule = chain_config
.get_fork_blob_schedule(block_header.timestamp)
.unwrap_or_else(|| EVMConfig::canonical_values(fork));
EVMConfig::new(fork, blob_schedule)
}
pub fn canonical_values(fork: Fork) -> ForkBlobSchedule {
let max_blobs_per_block = Self::max_blobs_per_block(fork);
let target = Self::get_target_blob_gas_per_block_(fork);
let base_fee_update_fraction: u64 = Self::get_blob_base_fee_update_fraction_value(fork);
ForkBlobSchedule {
target,
max: max_blobs_per_block,
base_fee_update_fraction,
}
}
fn max_blobs_per_block(fork: Fork) -> u32 {
if fork >= Fork::Prague {
MAX_BLOB_COUNT_ELECTRA
} else {
MAX_BLOB_COUNT
}
}
fn get_blob_base_fee_update_fraction_value(fork: Fork) -> u64 {
if fork >= Fork::Prague {
BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE
} else {
BLOB_BASE_FEE_UPDATE_FRACTION
}
}
fn get_target_blob_gas_per_block_(fork: Fork) -> u32 {
if fork >= Fork::Prague {
TARGET_BLOB_GAS_PER_BLOCK_PECTRA
} else {
TARGET_BLOB_GAS_PER_BLOCK
}
}
}
impl Default for EVMConfig {
fn default() -> Self {
let fork = core::default::Default::default();
EVMConfig {
fork,
blob_schedule: Self::canonical_values(fork),
}
}
}