Skip to content

Commit

Permalink
feat: align Block trait (#1957)
Browse files Browse the repository at this point in the history
* chore: relax some impl and exec_with_tx

* add helper created_address

* add error to database error

* ext journal with state

* fix: handle inspector final return

* call final_return

* expose precompile addresses to Journal

* precompile addresses fn for journal

* feat: align Block trait

* fix mul
  • Loading branch information
rakita authored Dec 30, 2024
1 parent 7d060e1 commit 543b4bb
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 92 deletions.
13 changes: 9 additions & 4 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,16 @@ pub fn execute_test_suite(
cfg.chain_id = 1;

// Block env
block.number = unit.env.current_number;
block.number = unit.env.current_number.try_into().unwrap_or(u64::MAX);
block.beneficiary = unit.env.current_coinbase;
block.timestamp = unit.env.current_timestamp;
block.gas_limit = unit.env.current_gas_limit;
block.basefee = unit.env.current_base_fee.unwrap_or_default();
block.timestamp = unit.env.current_timestamp.try_into().unwrap_or(u64::MAX);
block.gas_limit = unit.env.current_gas_limit.try_into().unwrap_or(u64::MAX);
block.basefee = unit
.env
.current_base_fee
.unwrap_or_default()
.try_into()
.unwrap_or(u64::MAX);
block.difficulty = unit.env.current_difficulty;
// After the Merge prevrandao replaces mix_hash field in block and replaced difficulty opcode in EVM.
block.prevrandao = unit.env.current_random;
Expand Down
16 changes: 8 additions & 8 deletions crates/context/interface/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@ use std::boxed::Box;
#[auto_impl(&, &mut, Box, Arc)]
pub trait Block {
/// The number of ancestor blocks of this block (block height).
fn number(&self) -> &U256;
fn number(&self) -> u64;

/// Beneficiary (Coinbase, miner) is a address that have signed the block.
///
/// This is the receiver address of priority gas rewards.
fn beneficiary(&self) -> &Address;
fn beneficiary(&self) -> Address;

/// The timestamp of the block in seconds since the UNIX epoch.
fn timestamp(&self) -> &U256;
fn timestamp(&self) -> u64;

/// The gas limit of the block.
fn gas_limit(&self) -> &U256;
fn gas_limit(&self) -> u64;

/// The base fee per gas, added in the London upgrade with [EIP-1559].
///
/// [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559
fn basefee(&self) -> &U256;
fn basefee(&self) -> u64;

/// The difficulty of the block.
///
/// Unused after the Paris (AKA the merge) upgrade, and replaced by `prevrandao`.
fn difficulty(&self) -> &U256;
fn difficulty(&self) -> U256;

/// The output of the randomness beacon provided by the beacon chain.
///
Expand All @@ -40,7 +40,7 @@ pub trait Block {
/// Note: `prevrandao` can be found in a block in place of `mix_hash`.
///
/// [EIP-4399]: https://eips.ethereum.org/EIPS/eip-4399
fn prevrandao(&self) -> Option<&B256>;
fn prevrandao(&self) -> Option<B256>;

/// Excess blob gas and blob gasprice.
/// See also [`calc_excess_blob_gas`]
Expand All @@ -49,7 +49,7 @@ pub trait Block {
/// Incorporated as part of the Cancun upgrade via [EIP-4844].
///
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
fn blob_excess_gas_and_price(&self) -> Option<&BlobExcessGasAndPrice>;
fn blob_excess_gas_and_price(&self) -> Option<BlobExcessGasAndPrice>;

/// See [EIP-4844] and [`calc_blob_gasprice`].
///
Expand Down
2 changes: 1 addition & 1 deletion crates/context/interface/src/block/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use specification::eip4844::{
/// Incorporated as part of the Cancun upgrade via [EIP-4844].
///
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BlobExcessGasAndPrice {
/// The excess blob gas of the block
Expand Down
10 changes: 5 additions & 5 deletions crates/context/interface/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use transaction_type::TransactionType;
use auto_impl::auto_impl;
use core::cmp::min;
use core::fmt::Debug;
use primitives::{TxKind, U256};
use primitives::TxKind;
use std::boxed::Box;

/// Transaction validity error types.
Expand Down Expand Up @@ -105,11 +105,11 @@ pub trait Transaction {
/// Returns effective gas price is gas price field for Legacy and Eip2930 transaction.
///
/// While for transactions after Eip1559 it is minimum of max_fee and `base + max_priority_fee`.
fn effective_gas_price(&self, base_fee: U256) -> U256 {
fn effective_gas_price(&self, base_fee: u128) -> u128 {
let tx_type = self.tx_type().into();
let (max_fee, max_priority_fee) = match tx_type {
TransactionType::Legacy => return U256::from(self.legacy().gas_price()),
TransactionType::Eip2930 => return U256::from(self.eip2930().gas_price()),
TransactionType::Legacy => return self.legacy().gas_price(),
TransactionType::Eip2930 => return self.eip2930().gas_price(),
TransactionType::Eip1559 => (
self.eip1559().max_fee_per_gas(),
self.eip1559().max_priority_fee_per_gas(),
Expand All @@ -125,7 +125,7 @@ pub trait Transaction {
TransactionType::Custom => unimplemented!("Custom tx not supported"),
};

min(U256::from(max_fee), base_fee + U256::from(max_priority_fee))
min(max_fee, base_fee.saturating_add(max_priority_fee))
}

/// Returns transaction kind.
Expand Down
48 changes: 24 additions & 24 deletions crates/context/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ use primitives::{Address, B256, U256};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BlockEnv {
/// The number of ancestor blocks of this block (block height)
pub number: U256,
pub number: u64,
/// Beneficiary (Coinbase or miner) is a address that have signed the block
///
/// This is the receiver address of all the gas spent in the block.
pub beneficiary: Address,

/// The timestamp of the block in seconds since the UNIX epoch
pub timestamp: U256,
pub timestamp: u64,
/// The gas limit of the block
pub gas_limit: U256,
pub gas_limit: u64,
/// The base fee per gas, added in the London upgrade with [EIP-1559]
///
/// [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559
pub basefee: U256,
pub basefee: u64,
/// The difficulty of the block
///
/// Unused after the Paris (AKA the merge) upgrade, and replaced by `prevrandao`.
Expand Down Expand Up @@ -53,54 +53,54 @@ impl BlockEnv {

impl Block for BlockEnv {
#[inline]
fn number(&self) -> &U256 {
&self.number
fn number(&self) -> u64 {
self.number
}

#[inline]
fn beneficiary(&self) -> &Address {
&self.beneficiary
fn beneficiary(&self) -> Address {
self.beneficiary
}

#[inline]
fn timestamp(&self) -> &U256 {
&self.timestamp
fn timestamp(&self) -> u64 {
self.timestamp
}

#[inline]
fn gas_limit(&self) -> &U256 {
&self.gas_limit
fn gas_limit(&self) -> u64 {
self.gas_limit
}

#[inline]
fn basefee(&self) -> &U256 {
&self.basefee
fn basefee(&self) -> u64 {
self.basefee
}

#[inline]
fn difficulty(&self) -> &U256 {
&self.difficulty
fn difficulty(&self) -> U256 {
self.difficulty
}

#[inline]
fn prevrandao(&self) -> Option<&B256> {
self.prevrandao.as_ref()
fn prevrandao(&self) -> Option<B256> {
self.prevrandao
}

#[inline]
fn blob_excess_gas_and_price(&self) -> Option<&BlobExcessGasAndPrice> {
self.blob_excess_gas_and_price.as_ref()
fn blob_excess_gas_and_price(&self) -> Option<BlobExcessGasAndPrice> {
self.blob_excess_gas_and_price
}
}

impl Default for BlockEnv {
fn default() -> Self {
Self {
number: U256::ZERO,
number: 0,
beneficiary: Address::ZERO,
timestamp: U256::from(1),
gas_limit: U256::MAX,
basefee: U256::ZERO,
timestamp: 1,
gas_limit: u64::MAX,
basefee: 0,
difficulty: U256::ZERO,
prevrandao: Some(B256::ZERO),
blob_excess_gas_and_price: Some(BlobExcessGasAndPrice::new(0)),
Expand Down
4 changes: 2 additions & 2 deletions crates/context/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use context_interface::{
};
use database_interface::{Database, EmptyDB};
use derive_where::derive_where;
use interpreter::{as_u64_saturated, Host, SStoreResult, SelfDestructResult, StateLoad};
use interpreter::{Host, SStoreResult, SelfDestructResult, StateLoad};
use primitives::{Address, Bytes, Log, B256, BLOCK_HASH_HISTORY, U256};
use specification::hardfork::SpecId;

Expand Down Expand Up @@ -381,7 +381,7 @@ where
JOURNAL: Journal<Database = DB>,
{
fn block_hash(&mut self, requested_number: u64) -> Option<B256> {
let block_number = as_u64_saturated!(*self.block().number());
let block_number = self.block().number();

let Some(diff) = block_number.checked_sub(requested_number) else {
return Some(B256::ZERO);
Expand Down
26 changes: 17 additions & 9 deletions crates/handler/src/post_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,21 @@ where
context: &mut Self::Context,
exec_result: &mut Self::ExecResult,
) -> Result<(), Self::Error> {
let basefee = *context.block().basefee();
let basefee = context.block().basefee() as u128;
let caller = context.tx().common_fields().caller();
let effective_gas_price = context.tx().effective_gas_price(basefee);
let gas = exec_result.gas();

// Return balance of not spend gas.
let caller_account = context.journal().load_account(caller)?;

let reimbursed = effective_gas_price * U256::from(gas.remaining() + gas.refunded() as u64);
caller_account.data.info.balance =
caller_account.data.info.balance.saturating_add(reimbursed);
let reimbursed =
effective_gas_price.saturating_mul((gas.remaining() + gas.refunded() as u64) as u128);
caller_account.data.info.balance = caller_account
.data
.info
.balance
.saturating_add(U256::from(reimbursed));

Ok(())
}
Expand All @@ -87,8 +91,8 @@ where
) -> Result<(), Self::Error> {
let block = context.block();
let tx = context.tx();
let beneficiary = *block.beneficiary();
let basefee = *block.basefee();
let beneficiary = block.beneficiary();
let basefee = block.basefee() as u128;
let effective_gas_price = tx.effective_gas_price(basefee);
let gas = exec_result.gas();

Expand All @@ -104,9 +108,13 @@ where

coinbase_account.data.mark_touch();
coinbase_account.data.info.balance =
coinbase_account.data.info.balance.saturating_add(
coinbase_gas_price * U256::from(gas.spent() - gas.refunded() as u64),
);
coinbase_account
.data
.info
.balance
.saturating_add(U256::from(
coinbase_gas_price * (gas.spent() - gas.refunded() as u64) as u128,
));

Ok(())
}
Expand Down
19 changes: 11 additions & 8 deletions crates/handler/src/pre_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ where
// Load coinbase
// EIP-3651: Warm COINBASE. Starts the `COINBASE` address warm
if spec.is_enabled_in(SpecId::SHANGHAI) {
let coinbase = *context.block().beneficiary();
let coinbase = context.block().beneficiary();
context.journal().warm_account(coinbase);
}

Expand Down Expand Up @@ -83,17 +83,17 @@ where

#[inline]
fn deduct_caller(&self, context: &mut Self::Context) -> Result<(), Self::Error> {
let basefee = *context.block().basefee();
let blob_price = U256::from(context.block().blob_gasprice().unwrap_or_default());
let effective_gas_price = context.tx().effective_gas_price(basefee);
let basefee = context.block().basefee();
let blob_price = context.block().blob_gasprice().unwrap_or_default();
let effective_gas_price = context.tx().effective_gas_price(basefee as u128);
// Subtract gas costs from the caller's account.
// We need to saturate the gas cost to prevent underflow in case that `disable_balance_check` is enabled.
let mut gas_cost = U256::from(context.tx().common_fields().gas_limit())
.saturating_mul(effective_gas_price);
let mut gas_cost =
(context.tx().common_fields().gas_limit() as u128).saturating_mul(effective_gas_price);

// EIP-4844
if context.tx().tx_type().into() == TransactionType::Eip4844 {
let blob_gas = U256::from(context.tx().eip4844().total_blob_gas());
let blob_gas = context.tx().eip4844().total_blob_gas() as u128;
gas_cost = gas_cost.saturating_add(blob_price.saturating_mul(blob_gas));
}

Expand All @@ -103,7 +103,10 @@ where
// Load caller's account.
let caller_account = context.journal().load_account(caller)?.data;
// Set new caller account balance.
caller_account.info.balance = caller_account.info.balance.saturating_sub(gas_cost);
caller_account.info.balance = caller_account
.info
.balance
.saturating_sub(U256::from(gas_cost));

// Bump the nonce for calls. Nonce for CREATE will be bumped in `handle_create`.
if is_call {
Expand Down
15 changes: 6 additions & 9 deletions crates/handler/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ where
pub fn validate_priority_fee_tx(
max_fee: u128,
max_priority_fee: u128,
base_fee: Option<U256>,
base_fee: Option<u128>,
) -> Result<(), InvalidTransaction> {
if max_priority_fee > max_fee {
// Or gas_max_fee for eip1559
Expand All @@ -92,10 +92,7 @@ pub fn validate_priority_fee_tx(

// Check minimal cost against basefee
if let Some(base_fee) = base_fee {
let effective_gas_price = cmp::min(
U256::from(max_fee),
base_fee.saturating_add(U256::from(max_priority_fee)),
);
let effective_gas_price = cmp::min(max_fee, base_fee.saturating_add(max_priority_fee));
if effective_gas_price < base_fee {
return Err(InvalidTransaction::GasPriceLessThanBasefee);
}
Expand Down Expand Up @@ -153,7 +150,7 @@ where
let base_fee = if context.cfg().is_base_fee_check_disabled() {
None
} else {
Some(*context.block().basefee())
Some(context.block().basefee() as u128)
};

match tx_type {
Expand All @@ -168,7 +165,7 @@ where
}
// Gas price must be at least the basefee.
if let Some(base_fee) = base_fee {
if U256::from(tx.gas_price()) < base_fee {
if tx.gas_price() < base_fee {
return Err(InvalidTransaction::GasPriceLessThanBasefee.into());
}
}
Expand All @@ -186,7 +183,7 @@ where

// Gas price must be at least the basefee.
if let Some(base_fee) = base_fee {
if U256::from(tx.gas_price()) < base_fee {
if tx.gas_price() < base_fee {
return Err(InvalidTransaction::GasPriceLessThanBasefee.into());
}
}
Expand Down Expand Up @@ -266,7 +263,7 @@ where

// Check if gas_limit is more than block_gas_limit
if !context.cfg().is_block_gas_limit_disabled()
&& U256::from(common_field.gas_limit()) > *context.block().gas_limit()
&& common_field.gas_limit() > context.block().gas_limit()
{
return Err(InvalidTransaction::CallerGasLimitMoreThanBlock.into());
}
Expand Down
Loading

0 comments on commit 543b4bb

Please sign in to comment.