From 87711435e9df64213b41f0cf49a9850d063e63c5 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 23 Dec 2024 15:59:58 +0400 Subject: [PATCH 1/7] wip --- crates/consensus/src/block/header.rs | 7 ++-- crates/eips/src/eip4844/mod.rs | 10 ++--- crates/eips/src/eip7840.rs | 56 ++++++++++++++++++++++++++++ crates/eips/src/lib.rs | 2 + crates/rpc-types-eth/src/block.rs | 9 +++-- 5 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 crates/eips/src/eip7840.rs diff --git a/crates/consensus/src/block/header.rs b/crates/consensus/src/block/header.rs index fd0a5e5048c..48f0b6a4d8c 100644 --- a/crates/consensus/src/block/header.rs +++ b/crates/consensus/src/block/header.rs @@ -8,6 +8,7 @@ use alloy_eips::{ merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS, BlockNumHash, }; +use alloy_eips::eip7840::BlobParams; use alloy_primitives::{ keccak256, Address, BlockNumber, Bloom, Bytes, Sealable, Sealed, B256, B64, U256, }; @@ -610,7 +611,7 @@ pub trait BlockHeader { /// spec. /// /// Returns a `None` if no excess blob gas is set, no EIP-4844 support - fn next_block_excess_blob_gas(&self) -> Option { + fn next_block_excess_blob_gas(&self, blob_params: BlobParams) -> Option { let excess_blob_gas = self.excess_blob_gas()?; let blob_gas_used = self.blob_gas_used()?; @@ -622,8 +623,8 @@ pub trait BlockHeader { /// Returns `None` if `excess_blob_gas` is None. /// /// See also [BlockHeader::next_block_excess_blob_gas] - fn next_block_blob_fee(&self) -> Option { - Some(eip4844::calc_blob_gasprice(self.next_block_excess_blob_gas()?)) + fn next_block_blob_fee(&self, blob_params: BlobParams) -> Option { + Some(eip4844::calc_blob_gasprice(self.next_block_excess_blob_gas(blob_params)?)) } /// Calculate base fee for next block according to the EIP-1559 spec. diff --git a/crates/eips/src/eip4844/mod.rs b/crates/eips/src/eip4844/mod.rs index e88ad503447..5028e3ab605 100644 --- a/crates/eips/src/eip4844/mod.rs +++ b/crates/eips/src/eip4844/mod.rs @@ -24,6 +24,8 @@ pub use sidecar::*; use alloy_primitives::{b256, FixedBytes, B256, U256}; +use crate::eip7840; + /// The modulus of the BLS group used in the KZG commitment scheme. All field /// elements contained in a blob MUST be STRICTLY LESS than this value. pub const BLS_MODULUS_BYTES: B256 = @@ -125,7 +127,7 @@ pub fn kzg_to_versioned_hash(commitment: &[u8]) -> B256 { /// (`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_DATA_GAS_PER_BLOCK) + eip7840::BlobParams::cancun().next_block_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used) } /// Calculates the blob gas price from the header's excess blob gas field. @@ -134,11 +136,7 @@ pub const fn calc_excess_blob_gas(parent_excess_blob_gas: u64, parent_blob_gas_u /// (`get_blob_gasprice`). #[inline] pub const fn calc_blob_gasprice(excess_blob_gas: u64) -> u128 { - fake_exponential( - BLOB_TX_MIN_BLOB_GASPRICE, - excess_blob_gas as u128, - BLOB_GASPRICE_UPDATE_FRACTION, - ) + eip7840::BlobParams::cancun().calc_blob_fee(excess_blob_gas) } /// Approximates `factor * e ** (numerator / denominator)` using Taylor expansion. diff --git a/crates/eips/src/eip7840.rs b/crates/eips/src/eip7840.rs new file mode 100644 index 00000000000..1ccea48a2a0 --- /dev/null +++ b/crates/eips/src/eip7840.rs @@ -0,0 +1,56 @@ +//! Contains constants and utility functions for [EIP-7840](https://github.com/ethereum/EIPs/tree/master/EIPS/eip-7840.md) + +use crate::{eip4844, eip7691}; + +/// Configuration for the blob-related calculations. +#[derive(Debug)] +pub struct BlobParams { + /// Target blob count for the block. + pub target_blob_count: u64, + /// Max blob count for the block. + pub max_blob_count: u64, + /// Update fraction for excess blob gas calculation. + pub update_fraction: u128, + /// Minimum gas price for a data blob. + pub min_blob_fee: u128, +} + +impl BlobParams { + /// Returns [`BlobParams`] configuration activated with Cancun hardfork. + pub const fn cancun() -> Self { + Self { + target_blob_count: eip4844::TARGET_BLOBS_PER_BLOCK, + max_blob_count: eip4844::MAX_BLOBS_PER_BLOCK as u64, + update_fraction: eip4844::BLOB_GASPRICE_UPDATE_FRACTION, + min_blob_fee: eip4844::BLOB_TX_MIN_BLOB_GASPRICE, + } + } + + /// Returns [`BlobParams`] configuration activated with Prague hardfork. + pub const fn prague() -> Self { + Self { + target_blob_count: eip7691::TARGET_BLOBS_PER_BLOCK_ELECTRA, + max_blob_count: eip7691::MAX_BLOBS_PER_BLOCK_ELECTRA, + update_fraction: eip7691::BLOB_GASPRICE_UPDATE_FRACTION_PECTRA, + min_blob_fee: eip4844::BLOB_TX_MIN_BLOB_GASPRICE, + } + } + + /// Calculates the `excess_blob_gas` value for the next block based on the current block + /// `excess_blob_gas` and `blob_gas_used`. + #[inline] + pub const fn next_block_excess_blob_gas( + &self, + excess_blob_gas: u64, + blob_gas_used: u64, + ) -> u64 { + (excess_blob_gas + blob_gas_used) + .saturating_sub(eip4844::DATA_GAS_PER_BLOB * self.target_blob_count) + } + + /// Calculates the blob fee for block based on its `excess_blob_gas`. + #[inline] + pub const fn calc_blob_fee(&self, excess_blob_gas: u64) -> u128 { + eip4844::fake_exponential(self.min_blob_fee, excess_blob_gas as u128, self.update_fraction) + } +} diff --git a/crates/eips/src/lib.rs b/crates/eips/src/lib.rs index 39ad47ba50c..091cf418fb2 100644 --- a/crates/eips/src/lib.rs +++ b/crates/eips/src/lib.rs @@ -45,3 +45,5 @@ pub mod eip7685; pub mod eip7691; pub mod eip7702; + +pub mod eip7840; diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 1883a7ec640..6efeb91dca2 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -15,6 +15,7 @@ pub use alloy_eips::{ calc_blob_gasprice, calc_excess_blob_gas, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash, }; +use alloy_eips::eip7840::BlobParams; /// Block representation #[derive(Clone, Debug, PartialEq, Eq)] @@ -165,16 +166,16 @@ impl Header { /// Returns `None` if `excess_blob_gas` is None. /// /// See also [Self::next_block_excess_blob_gas] - pub fn next_block_blob_fee(&self) -> Option { - self.inner.next_block_blob_fee() + pub fn next_block_blob_fee(&self, blob_params: BlobParams) -> Option { + self.inner.next_block_blob_fee(blob_params) } /// Calculate excess blob gas for the next block according to the EIP-4844 /// spec. /// /// Returns a `None` if no excess blob gas is set, no EIP-4844 support - pub fn next_block_excess_blob_gas(&self) -> Option { - self.inner.next_block_excess_blob_gas() + pub fn next_block_excess_blob_gas(&self, blob_params: BlobParams) -> Option { + self.inner.next_block_excess_blob_gas(blob_params) } } From d235768e41c7eb7c89d3ddd090231a3fbdb7ed60 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 23 Dec 2024 16:36:06 +0400 Subject: [PATCH 2/7] wip --- crates/consensus/src/block/header.rs | 25 +++++++++---------------- crates/eips/src/eip4844/mod.rs | 3 ++- crates/eips/src/eip7840.rs | 12 +++++++++++- crates/genesis/Cargo.toml | 1 + crates/genesis/src/lib.rs | 6 ++++++ crates/rpc-types-eth/src/block.rs | 2 +- 6 files changed, 30 insertions(+), 19 deletions(-) diff --git a/crates/consensus/src/block/header.rs b/crates/consensus/src/block/header.rs index 48f0b6a4d8c..fe4302a24ca 100644 --- a/crates/consensus/src/block/header.rs +++ b/crates/consensus/src/block/header.rs @@ -4,11 +4,10 @@ use alloy_eips::{ calc_blob_gasprice, eip1559::{calc_next_block_base_fee, BaseFeeParams}, eip1898::BlockWithParent, - eip4844::{self}, + eip7840::BlobParams, merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS, BlockNumHash, }; -use alloy_eips::eip7840::BlobParams; use alloy_primitives::{ keccak256, Address, BlockNumber, Bloom, Bytes, Sealable, Sealed, B256, B64, U256, }; @@ -192,8 +191,8 @@ impl Header { /// Returns the blob fee for _this_ block according to the EIP-4844 spec. /// /// Returns `None` if `excess_blob_gas` is None - pub fn blob_fee(&self) -> Option { - self.excess_blob_gas.map(calc_blob_gasprice) + pub fn blob_fee(&self, blob_params: BlobParams) -> Option { + Some(blob_params.calc_blob_fee(self.excess_blob_gas?)) } /// Returns the blob fee for the next block according to the EIP-4844 spec. @@ -201,8 +200,8 @@ impl Header { /// Returns `None` if `excess_blob_gas` is None. /// /// See also [Self::next_block_excess_blob_gas] - pub fn next_block_blob_fee(&self) -> Option { - Some(eip4844::calc_blob_gasprice(self.next_block_excess_blob_gas()?)) + pub fn next_block_blob_fee(&self, blob_params: BlobParams) -> Option { + Some(blob_params.calc_blob_fee(self.next_block_excess_blob_gas(blob_params)?)) } /// Calculate base fee for next block according to the EIP-1559 spec. @@ -221,11 +220,8 @@ impl Header { /// spec. /// /// Returns a `None` if no excess blob gas is set, no EIP-4844 support - pub fn next_block_excess_blob_gas(&self) -> Option { - let excess_blob_gas = self.excess_blob_gas?; - let blob_gas_used = self.blob_gas_used?; - - Some(eip4844::calc_excess_blob_gas(excess_blob_gas, blob_gas_used)) + pub fn next_block_excess_blob_gas(&self, blob_params: BlobParams) -> Option { + Some(blob_params.next_block_excess_blob_gas(self.excess_blob_gas?, self.blob_gas_used?)) } /// Calculate a heuristic for the in-memory size of the [Header]. @@ -612,10 +608,7 @@ pub trait BlockHeader { /// /// Returns a `None` if no excess blob gas is set, no EIP-4844 support fn next_block_excess_blob_gas(&self, blob_params: BlobParams) -> Option { - let excess_blob_gas = self.excess_blob_gas()?; - let blob_gas_used = self.blob_gas_used()?; - - Some(eip4844::calc_excess_blob_gas(excess_blob_gas, blob_gas_used)) + Some(blob_params.next_block_excess_blob_gas(self.excess_blob_gas()?, self.blob_gas_used()?)) } /// Returns the blob fee for the next block according to the EIP-4844 spec. @@ -624,7 +617,7 @@ pub trait BlockHeader { /// /// See also [BlockHeader::next_block_excess_blob_gas] fn next_block_blob_fee(&self, blob_params: BlobParams) -> Option { - Some(eip4844::calc_blob_gasprice(self.next_block_excess_blob_gas(blob_params)?)) + Some(blob_params.calc_blob_fee(self.next_block_excess_blob_gas(blob_params)?)) } /// Calculate base fee for next block according to the EIP-1559 spec. diff --git a/crates/eips/src/eip4844/mod.rs b/crates/eips/src/eip4844/mod.rs index 5028e3ab605..3e685ea2b10 100644 --- a/crates/eips/src/eip4844/mod.rs +++ b/crates/eips/src/eip4844/mod.rs @@ -127,7 +127,8 @@ pub fn kzg_to_versioned_hash(commitment: &[u8]) -> B256 { /// (`calc_excess_blob_gas`). #[inline] pub const fn calc_excess_blob_gas(parent_excess_blob_gas: u64, parent_blob_gas_used: u64) -> u64 { - eip7840::BlobParams::cancun().next_block_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used) + eip7840::BlobParams::cancun() + .next_block_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used) } /// Calculates the blob gas price from the header's excess blob gas field. diff --git a/crates/eips/src/eip7840.rs b/crates/eips/src/eip7840.rs index 1ccea48a2a0..a82b9b50517 100644 --- a/crates/eips/src/eip7840.rs +++ b/crates/eips/src/eip7840.rs @@ -2,8 +2,18 @@ use crate::{eip4844, eip7691}; +/// A single item of `blobSchedule` defined in EIP-7840. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct BlobScheduleItem { + #[cfg_attr(feature = "serde", serde(rename = "target"))] + target_blob_count: u64, + #[cfg_attr(feature = "serde", serde(rename = "max"))] + max_blob_count: u64, +} + /// Configuration for the blob-related calculations. -#[derive(Debug)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BlobParams { /// Target blob count for the block. pub target_blob_count: u64, diff --git a/crates/genesis/Cargo.toml b/crates/genesis/Cargo.toml index b15cc8d825b..3cda698f5b1 100644 --- a/crates/genesis/Cargo.toml +++ b/crates/genesis/Cargo.toml @@ -19,6 +19,7 @@ rustdoc-args = ["--cfg", "docsrs"] workspace = true [dependencies] +alloy-eips = { workspace = true, features = ["serde"] } alloy-primitives.workspace = true alloy-serde.workspace = true alloy-trie = { workspace = true, features = ["ethereum"] } diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs index f0ad68397c2..6271d1d73e0 100644 --- a/crates/genesis/src/lib.rs +++ b/crates/genesis/src/lib.rs @@ -14,6 +14,7 @@ extern crate alloc; use alloc::{collections::BTreeMap, string::String}; use alloy_primitives::{keccak256, Address, Bytes, B256, U256}; use alloy_serde::{storage::deserialize_storage_map, ttd::deserialize_json_ttd_opt, OtherFields}; +use alloy_eips::eip7840::BlobScheduleItem; use alloy_trie::{TrieAccount, EMPTY_ROOT_HASH, KECCAK_EMPTY}; use core::str::FromStr; use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize}; @@ -479,6 +480,10 @@ pub struct ChainConfig { /// The deposit contract address #[serde(default, skip_serializing_if = "Option::is_none")] pub deposit_contract_address: Option
, + + /// The blob schedule for the chain. + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] + pub blob_schedule: BTreeMap, } impl ChainConfig { @@ -604,6 +609,7 @@ impl Default for ChainConfig { parlia: None, extra_fields: Default::default(), deposit_contract_address: None, + blob_schedule: Default::default(), } } } diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 6efeb91dca2..7162c62df4a 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -11,11 +11,11 @@ use alloy_primitives::{Address, BlockHash, Bloom, Bytes, Sealable, B256, B64, U2 use alloy_rlp::Encodable; use core::ops::{Deref, DerefMut}; +use alloy_eips::eip7840::BlobParams; pub use alloy_eips::{ calc_blob_gasprice, calc_excess_blob_gas, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash, }; -use alloy_eips::eip7840::BlobParams; /// Block representation #[derive(Clone, Debug, PartialEq, Eq)] From 6e5e5b752b393969fcd895f92c4e53e0ba86411e Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 23 Dec 2024 16:44:57 +0400 Subject: [PATCH 3/7] fix --- crates/consensus/src/block/header.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/consensus/src/block/header.rs b/crates/consensus/src/block/header.rs index fe4302a24ca..fb2f8a1eb70 100644 --- a/crates/consensus/src/block/header.rs +++ b/crates/consensus/src/block/header.rs @@ -1,7 +1,6 @@ use crate::constants::{EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; use alloc::vec::Vec; use alloy_eips::{ - calc_blob_gasprice, eip1559::{calc_next_block_base_fee, BaseFeeParams}, eip1898::BlockWithParent, eip7840::BlobParams, @@ -599,8 +598,8 @@ pub trait BlockHeader { /// Returns the blob fee for _this_ block according to the EIP-4844 spec. /// /// Returns `None` if `excess_blob_gas` is None - fn blob_fee(&self) -> Option { - self.excess_blob_gas().map(calc_blob_gasprice) + fn blob_fee(&self, blob_params: BlobParams) -> Option { + Some(blob_params.calc_blob_fee(self.excess_blob_gas()?)) } /// Calculate excess blob gas for the next block according to the EIP-4844 From db70b19c64948268332a51fb18ae24033d0fcc1e Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 23 Dec 2024 16:45:27 +0400 Subject: [PATCH 4/7] fmt --- crates/genesis/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs index 6271d1d73e0..333ca761b92 100644 --- a/crates/genesis/src/lib.rs +++ b/crates/genesis/src/lib.rs @@ -12,9 +12,9 @@ extern crate alloc; use alloc::{collections::BTreeMap, string::String}; +use alloy_eips::eip7840::BlobScheduleItem; use alloy_primitives::{keccak256, Address, Bytes, B256, U256}; use alloy_serde::{storage::deserialize_storage_map, ttd::deserialize_json_ttd_opt, OtherFields}; -use alloy_eips::eip7840::BlobScheduleItem; use alloy_trie::{TrieAccount, EMPTY_ROOT_HASH, KECCAK_EMPTY}; use core::str::FromStr; use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize}; From 7d87d5a9ec6669d28b5b10d717b32ce3c50d8741 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 23 Dec 2024 21:06:02 +0400 Subject: [PATCH 5/7] fix --- crates/eips/src/eip7840.rs | 6 ++++-- crates/genesis/src/lib.rs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/eips/src/eip7840.rs b/crates/eips/src/eip7840.rs index a82b9b50517..7ac456855da 100644 --- a/crates/eips/src/eip7840.rs +++ b/crates/eips/src/eip7840.rs @@ -6,10 +6,12 @@ use crate::{eip4844, eip7691}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BlobScheduleItem { + /// Target blob count for the block. #[cfg_attr(feature = "serde", serde(rename = "target"))] - target_blob_count: u64, + pub target_blob_count: u64, + /// Max blob count for the block. #[cfg_attr(feature = "serde", serde(rename = "max"))] - max_blob_count: u64, + pub max_blob_count: u64, } /// Configuration for the blob-related calculations. diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs index 333ca761b92..627cfbf35c6 100644 --- a/crates/genesis/src/lib.rs +++ b/crates/genesis/src/lib.rs @@ -481,7 +481,7 @@ pub struct ChainConfig { #[serde(default, skip_serializing_if = "Option::is_none")] pub deposit_contract_address: Option
, - /// The blob schedule for the chain. + /// The blob schedule for the chain, indexed by hardfork name. #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub blob_schedule: BTreeMap, } From b74d763814ddc551a62c6f2df0f3aaafeb8da058 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 23 Dec 2024 21:10:53 +0400 Subject: [PATCH 6/7] add eip link --- crates/genesis/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs index 627cfbf35c6..2676dae7909 100644 --- a/crates/genesis/src/lib.rs +++ b/crates/genesis/src/lib.rs @@ -482,6 +482,8 @@ pub struct ChainConfig { pub deposit_contract_address: Option
, /// The blob schedule for the chain, indexed by hardfork name. + /// + /// See [EIP-7840](https://github.com/ethereum/EIPs/tree/master/EIPS/eip-7840.md). #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub blob_schedule: BTreeMap, } From 5f60dec06528c8a568326c2d7c84908ac3bc0f57 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 23 Dec 2024 21:33:35 +0400 Subject: [PATCH 7/7] fmt --- crates/genesis/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs index 2676dae7909..40fb8f3d87a 100644 --- a/crates/genesis/src/lib.rs +++ b/crates/genesis/src/lib.rs @@ -482,7 +482,7 @@ pub struct ChainConfig { pub deposit_contract_address: Option
, /// The blob schedule for the chain, indexed by hardfork name. - /// + /// /// See [EIP-7840](https://github.com/ethereum/EIPs/tree/master/EIPS/eip-7840.md). #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub blob_schedule: BTreeMap,