Skip to content

Commit

Permalink
feat(levm): implement EIP7691 - Blob throughput increase (#1782)
Browse files Browse the repository at this point in the history
**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
  • Loading branch information
lima-limon-inc authored Jan 23, 2025
1 parent e340bd9 commit b2a304e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 7 deletions.
6 changes: 5 additions & 1 deletion crates/common/types/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 5 additions & 3 deletions crates/vm/levm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Implementation of a simple Ethereum Virtual Machine in Rust.

| Fork | Status |
| -------------- | ------ |
| Prague | 🏗|
| Prague | |
| Cancun ||
| Shanghai ||
| Paris (Merge) ||
Expand Down Expand Up @@ -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`

Expand Down
13 changes: 12 additions & 1 deletion crates/vm/levm/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 28 additions & 2 deletions crates/vm/levm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
)
}

Expand Down Expand Up @@ -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,
));
Expand Down Expand Up @@ -1684,3 +1684,29 @@ fn eip7702_recover_address(auth_tuple: &AuthorizationTuple) -> Result<Option<Add
.map_err(|_| VMError::Internal(InternalError::ConversionError))?;
Ok(Some(Address::from_slice(&authority_address_bytes)))
}

/// After EIP-7691 the maximum number of blob hashes changes. For more
/// information see
/// [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691#specification).
pub const fn max_blobs_per_block(specid: SpecId) -> 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,
}
}

0 comments on commit b2a304e

Please sign in to comment.