use crate::MonadSpecId;
use revm::{
context_interface::cfg::{GasId, GasParams},
handler::instructions::EthInstructions,
interpreter::{
instructions::instruction_table_gas_changes_spec, interpreter::EthInterpreter, Host,
},
};
pub type MonadInstructions<CTX> = EthInstructions<EthInterpreter, CTX>;
pub fn monad_gas_params(spec: MonadSpecId) -> GasParams {
let eth_spec = spec.into_eth_spec();
let mut params = GasParams::new_spec(eth_spec);
if MonadSpecId::MonadEight.is_enabled_in(spec) {
params.override_gas([
(GasId::cold_storage_cost(), COLD_SLOAD_COST),
(GasId::cold_storage_additional_cost(), COLD_SLOAD_COST - WARM_STORAGE_READ_COST),
(
GasId::cold_account_additional_cost(),
COLD_ACCOUNT_ACCESS_COST - WARM_STORAGE_READ_COST,
),
]);
}
params
}
pub fn monad_instructions<CTX: Host>(spec: MonadSpecId) -> MonadInstructions<CTX> {
let eth_spec = spec.into_eth_spec();
EthInstructions::new(instruction_table_gas_changes_spec(eth_spec), eth_spec)
}
pub const COLD_SLOAD_COST: u64 = 8100;
pub const COLD_ACCOUNT_ACCESS_COST: u64 = 10100;
pub const WARM_STORAGE_READ_COST: u64 = 100;
#[cfg(test)]
mod tests {
use super::*;
use revm::primitives::hardfork::SpecId;
#[test]
fn test_monad_gas_params_cold_storage_cost() {
let params = monad_gas_params(MonadSpecId::MonadEight);
assert_eq!(params.get(GasId::cold_storage_cost()), COLD_SLOAD_COST);
}
#[test]
fn test_monad_gas_params_cold_storage_additional_cost() {
let params = monad_gas_params(MonadSpecId::MonadEight);
assert_eq!(
params.get(GasId::cold_storage_additional_cost()),
COLD_SLOAD_COST - WARM_STORAGE_READ_COST
);
}
#[test]
fn test_monad_gas_params_cold_account_additional_cost() {
let params = monad_gas_params(MonadSpecId::MonadEight);
assert_eq!(
params.get(GasId::cold_account_additional_cost()),
COLD_ACCOUNT_ACCESS_COST - WARM_STORAGE_READ_COST
);
}
#[test]
fn test_monad_gas_params_warm_storage_unchanged() {
let params = monad_gas_params(MonadSpecId::MonadEight);
assert_eq!(params.get(GasId::warm_storage_read_cost()), WARM_STORAGE_READ_COST);
}
#[test]
fn test_monad_vs_ethereum_cold_costs() {
let monad = monad_gas_params(MonadSpecId::MonadEight);
let eth = GasParams::new_spec(SpecId::PRAGUE);
assert_eq!(monad.get(GasId::cold_storage_cost()), 8100);
assert_eq!(eth.get(GasId::cold_storage_cost()), 2100);
assert_eq!(monad.get(GasId::cold_account_additional_cost()), 10000);
assert_eq!(eth.get(GasId::cold_account_additional_cost()), 2500);
}
}