From b2a304e214715e806952ff22c6049d2eebed452f Mon Sep 17 00:00:00 2001 From: Tomas Fabrizio Orsi Date: Thu, 23 Jan 2025 15:37:26 -0300 Subject: [PATCH] feat(levm): implement EIP7691 - Blob throughput increase (#1782) **Motivation** LEVM needs to support the changes introduced in [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691). **Description** This EIP introduces changes to some of the blob hashes' constants values. With this PR, the values for blob hash calculations in LEVM will depend on the spec being used. Closes #1783 Closes #1776 --- crates/common/types/block.rs | 6 +++++- crates/vm/levm/README.md | 8 +++++--- crates/vm/levm/src/constants.rs | 13 ++++++++++++- crates/vm/levm/src/vm.rs | 30 ++++++++++++++++++++++++++++-- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/crates/common/types/block.rs b/crates/common/types/block.rs index fb4b3eaf9d..eb98b58888 100644 --- a/crates/common/types/block.rs +++ b/crates/common/types/block.rs @@ -340,7 +340,11 @@ fn check_gas_limit(gas_limit: u64, parent_gas_limit: u64) -> bool { && gas_limit >= GAS_LIMIT_MINIMUM } -// Calculates the base fee per blob gas for the current block based on it's parent excess blob gas +/// Calculates the base fee per blob gas for the current block based on +/// it's parent excess blob gas. +/// NOTE: BLOB_BASE_FEE_UPDATE_FRACTION has a different value after +/// prague fork. See +/// [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691#specification). pub fn calculate_base_fee_per_blob_gas(parent_excess_blob_gas: u64) -> u64 { fake_exponential( MIN_BASE_FEE_PER_BLOB_GAS, diff --git a/crates/vm/levm/README.md b/crates/vm/levm/README.md index 2cc86247c7..bb8c2e3025 100644 --- a/crates/vm/levm/README.md +++ b/crates/vm/levm/README.md @@ -6,7 +6,7 @@ Implementation of a simple Ethereum Virtual Machine in Rust. | Fork | Status | | -------------- | ------ | -| Prague | 🏗️ | +| Prague | ✅️ | | Cancun | ✅ | | Shanghai | ✅ | | Paris (Merge) | ✅ | @@ -78,14 +78,16 @@ There are a lot of EIPs schedule to include in this upgrade but for `levm` we'll - EIP-2537: Precompile for BLS12-381 curve operations - EIP-7623: Increase calldata cost +- EIP-7691: Blob throughput increase - EIP-7702: Set EOA account code | Task Description | Status | | ------------------------- | ------ | | Implement EIP-2537 | ✅ | | Implement EIP-7623 | ✅ | -| Implement EIP-7702 | ✅ | -| Make Prague EF tests pass | ❌ | +| Implement EIP-7691 | ✅️ | +| Implement EIP-7702 | ✅️ | +| Make Prague EF tests pass | ✅ | ### Milestone 5: Integrate `ethrex L2` <> `levm` diff --git a/crates/vm/levm/src/constants.rs b/crates/vm/levm/src/constants.rs index 0d27ec1cad..02cd6d5915 100644 --- a/crates/vm/levm/src/constants.rs +++ b/crates/vm/levm/src/constants.rs @@ -43,13 +43,24 @@ pub mod create_opcode { } pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01; -pub const MAX_BLOB_NUMBER_PER_BLOCK: usize = 6; // Blob constants pub const TARGET_BLOB_GAS_PER_BLOCK: U256 = U256([393216, 0, 0, 0]); // TARGET_BLOB_NUMBER_PER_BLOCK * GAS_PER_BLOB +pub const TARGET_BLOB_GAS_PER_BLOCK_PECTRA: U256 = U256([786432, 0, 0, 0]); // TARGET_BLOB_NUMBER_PER_BLOCK * GAS_PER_BLOB + pub const MIN_BASE_FEE_PER_BLOB_GAS: U256 = U256::one(); + +// WARNING: Do _not_ use the BLOB_BASE_FEE_UPDATE_FRACTION_* family of +// constants as is. Use the `get_blob_base_fee_update_fraction_value` +// function instead pub const BLOB_BASE_FEE_UPDATE_FRACTION: U256 = U256([3338477, 0, 0, 0]); +pub const BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE: U256 = U256([5007716, 0, 0, 0]); // Defined in [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691) + +// WARNING: Do _not_ use the MAX_BLOB_COUNT_* family of constants as +// is. Use the `max_blobs_per_block` function instead pub const MAX_BLOB_COUNT: usize = 6; +pub const MAX_BLOB_COUNT_ELECTRA: usize = 9; + pub const VALID_BLOB_PREFIXES: [u8; 2] = [0x01, 0x02]; // Block constants diff --git a/crates/vm/levm/src/vm.rs b/crates/vm/levm/src/vm.rs index a69b865633..ebf8ca675b 100644 --- a/crates/vm/levm/src/vm.rs +++ b/crates/vm/levm/src/vm.rs @@ -741,7 +741,7 @@ impl VM { fake_exponential( MIN_BASE_FEE_PER_BLOB_GAS, self.env.block_excess_blob_gas.unwrap_or_default(), - BLOB_BASE_FEE_UPDATE_FRACTION, + get_blob_base_fee_update_fraction_value(self.env.spec_id), ) } @@ -934,7 +934,7 @@ impl VM { } // (14) TYPE_3_TX_BLOB_COUNT_EXCEEDED - if blob_hashes.len() > MAX_BLOB_COUNT { + if blob_hashes.len() > max_blobs_per_block(self.env.spec_id) { return Err(VMError::TxValidation( TxValidationError::Type3TxBlobCountExceeded, )); @@ -1684,3 +1684,29 @@ fn eip7702_recover_address(auth_tuple: &AuthorizationTuple) -> Result usize { + match specid { + SpecId::PRAGUE => MAX_BLOB_COUNT_ELECTRA, + SpecId::PRAGUE_EOF => MAX_BLOB_COUNT_ELECTRA, + _ => MAX_BLOB_COUNT, + } +} + +/// According to EIP-7691 +/// (https://eips.ethereum.org/EIPS/eip-7691#specification): +/// +/// "These changes imply that get_base_fee_per_blob_gas and +/// calc_excess_blob_gas functions defined in EIP-4844 use the new +/// values for the first block of the fork (and for all subsequent +/// blocks)." +pub const fn get_blob_base_fee_update_fraction_value(specid: SpecId) -> U256 { + match specid { + SpecId::PRAGUE => BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE, + SpecId::PRAGUE_EOF => BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE, + _ => BLOB_BASE_FEE_UPDATE_FRACTION, + } +}