Skip to content

Commit

Permalink
Added evm-core utility function for BLOBBASEFEE and refactored EVM Ba…
Browse files Browse the repository at this point in the history
…cked for blob_gasprice
  • Loading branch information
mrLSD committed Apr 2, 2024
1 parent 214aa99 commit 5cb066a
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 13 deletions.
2 changes: 1 addition & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mod external;
mod memory;
mod opcode;
mod stack;
mod utils;
pub mod utils;
mod valids;

pub use crate::error::{Capture, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed, Trap};
Expand Down
74 changes: 72 additions & 2 deletions core/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,78 @@ use core::cmp::Ordering;
use core::ops::{Div, Rem};
use primitive_types::U256;

/// EIP-4844 constants
/// Gas consumption of a single data blob (== blob byte size).
pub const GAS_PER_BLOB: u64 = 1 << 17;
/// Target number of the blob per block.
pub const TARGET_BLOB_NUMBER_PER_BLOCK: u64 = 3;
/// Max number of blobs per block
pub const MAX_BLOB_NUMBER_PER_BLOCK: u64 = 2 * TARGET_BLOB_NUMBER_PER_BLOCK;
/// Maximum consumable blob gas for data blobs per block.
pub const MAX_BLOB_GAS_PER_BLOCK: u64 = MAX_BLOB_NUMBER_PER_BLOCK * GAS_PER_BLOB;
/// Target consumable blob gas for data blobs per block (for 1559-like pricing).
pub const TARGET_BLOB_GAS_PER_BLOCK: u64 = TARGET_BLOB_NUMBER_PER_BLOCK * GAS_PER_BLOB;
/// Minimum gas price for data blobs.
pub const MIN_BLOB_GASPRICE: u64 = 1;
/// Controls the maximum rate of change for blob gas price.
pub const BLOB_GASPRICE_UPDATE_FRACTION: u64 = 3338477;
/// First version of the blob.
pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01;

/// Calculates the `excess_blob_gas` from the parent header's `blob_gas_used` and `excess_blob_gas`.
///
/// See also [the EIP-4844 helpers]<https://eips.ethereum.org/EIPS/eip-4844#helpers>
/// (`calc_excess_blob_gas`).
#[inline]
pub const fn calc_excess_blob_gas(parent_excess_blob_gas: u64, parent_blob_gas_used: u64) -> u64 {
(parent_excess_blob_gas + parent_blob_gas_used).saturating_sub(TARGET_BLOB_GAS_PER_BLOCK)
}

/// Approximates `factor * e ** (numerator / denominator)` using Taylor expansion.
///
/// This is used to calculate the blob price.
///
/// See also [the EIP-4844 helpers](https://eips.ethereum.org/EIPS/eip-4844#helpers)
/// (`fake_exponential`).
///
/// # Panics
///
/// This function panics if `denominator` is zero.
#[inline]
pub fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> u128 {
assert_ne!(denominator, 0, "attempt to divide by zero");
let factor = factor as u128;
let numerator = numerator as u128;
let denominator = denominator as u128;

let mut i = 1;
let mut output = 0;
let mut numerator_accum = factor * denominator;
while numerator_accum > 0 {
output += numerator_accum;

// Denominator is asserted as not zero at the start of the function.
numerator_accum = (numerator_accum * numerator) / (denominator * i);
i += 1;
}
output / denominator
}

/// Calculates the blob gas price from the header's excess blob gas field.
///
/// See also [the EIP-4844 helpers](https://eips.ethereum.org/EIPS/eip-4844#helpers)
/// (`get_blob_gasprice`).
#[inline]
pub fn calc_blob_gasprice(excess_blob_gas: u64) -> u128 {
fake_exponential(
MIN_BLOB_GASPRICE,
excess_blob_gas,
BLOB_GASPRICE_UPDATE_FRACTION,
)
}

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Sign {
pub(crate) enum Sign {
Plus,
Minus,
Zero,
Expand All @@ -17,7 +87,7 @@ const SIGN_BIT_MASK: U256 = U256([
]);

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct I256(pub Sign, pub U256);
pub(crate) struct I256(pub Sign, pub U256);

impl I256 {
/// Zero value of I256.
Expand Down
7 changes: 2 additions & 5 deletions runtime/src/eval/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,15 @@ pub fn gasprice<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
}

pub fn base_fee<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
// let mut ret = H256::default();
// handler.block_base_fee_per_gas().to_big_endian(&mut ret[..]);
push_u256!(runtime, handler.block_base_fee_per_gas());
Control::Continue
}

/// CANCUN hard fork
/// EIP-7516: BLOBBASEFEE opcode
pub fn blob_base_fee<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
let x = handler.blob_base_fee().unwrap_or_default();
let ret = U256::from(x);
push_u256!(runtime, ret);
let blob_base_fee = U256::from(handler.blob_base_fee().unwrap_or_default());
push_u256!(runtime, blob_base_fee);
Control::Continue
}

Expand Down
2 changes: 1 addition & 1 deletion src/backend/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl<'vicinity> Backend for MemoryBackend<'vicinity> {
fn original_storage(&self, address: H160, index: H256) -> Option<H256> {
Some(self.storage(address, index))
}
fn blob_base_fee(&self) -> Option<u128> {
fn blob_gasprice(&self) -> Option<u128> {
self.vicinity.blob_base_fee
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,12 @@ pub trait Backend {
fn storage(&self, address: H160, index: H256) -> H256;
/// Get original storage value of address at index, if available.
fn original_storage(&self, address: H160, index: H256) -> Option<H256>;
/// CANCUN hard fork
/// [EIP-4844]: Shard Blob Transactions
/// [EIP-7516]: BLOBBASEFEE instruction
fn blob_base_fee(&self) -> Option<u128>;
/// NOTE: `blob_gasprice` should precalculated via [evm_core::utils::calc_blob_gasprice]
/// with `excess_blob_gas` parameter in [Backend] as described in EIP-4844.
fn blob_gasprice(&self) -> Option<u128>;
}

/// EVM backend that can apply changes.
Expand Down
2 changes: 1 addition & 1 deletion src/executor/stack/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1471,7 +1471,7 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Handler
/// [EIP-7516]: BLOBBASEFEE instruction
fn blob_base_fee(&self) -> Option<u128> {
if self.config.has_blob_base_fee {
self.state.blob_base_fee()
self.state.blob_gasprice()
} else {
None
}
Expand Down
4 changes: 2 additions & 2 deletions src/executor/stack/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,8 +485,8 @@ impl<'backend, 'config, B: Backend> Backend for MemoryStackState<'backend, 'conf

self.backend.original_storage(address, key)
}
fn blob_base_fee(&self) -> Option<u128> {
self.backend.blob_base_fee()
fn blob_gasprice(&self) -> Option<u128> {
self.backend.blob_gasprice()
}
}

Expand Down

0 comments on commit 5cb066a

Please sign in to comment.