alloy_eips/
eip7840.rs

1//! Contains constants and utility functions for [EIP-7840](https://github.com/ethereum/EIPs/tree/master/EIPS/eip-7840.md)
2
3use crate::{
4    eip4844::{self, DATA_GAS_PER_BLOB},
5    eip7594, eip7691,
6};
7
8// helpers for serde
9#[cfg(feature = "serde")]
10const DEFAULT_BLOB_FEE_GETTER: fn() -> u128 = || eip4844::BLOB_TX_MIN_BLOB_GASPRICE;
11#[cfg(feature = "serde")]
12const IS_DEFAULT_BLOB_FEE: fn(&u128) -> bool = |&x| x == eip4844::BLOB_TX_MIN_BLOB_GASPRICE;
13
14/// Configuration for the blob-related calculations.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct BlobParams {
18    /// Target blob count for the block.
19    #[cfg_attr(feature = "serde", serde(rename = "target"))]
20    pub target_blob_count: u64,
21    /// Max blob count for the block.
22    #[cfg_attr(feature = "serde", serde(rename = "max"))]
23    pub max_blob_count: u64,
24    /// Update fraction for excess blob gas calculation.
25    #[cfg_attr(feature = "serde", serde(rename = "baseFeeUpdateFraction"))]
26    pub update_fraction: u128,
27    /// Minimum gas price for a data blob.
28    ///
29    /// Not required per EIP-7840 and assumed to be the default
30    /// [`eip4844::BLOB_TX_MIN_BLOB_GASPRICE`] if not set.
31    #[cfg_attr(
32        feature = "serde",
33        serde(default = "DEFAULT_BLOB_FEE_GETTER", skip_serializing_if = "IS_DEFAULT_BLOB_FEE")
34    )]
35    pub min_blob_fee: u128,
36}
37
38impl BlobParams {
39    /// Returns [`BlobParams`] configuration activated with Cancun hardfork.
40    pub const fn cancun() -> Self {
41        Self {
42            target_blob_count: eip4844::TARGET_BLOBS_PER_BLOCK_DENCUN,
43            max_blob_count: eip4844::MAX_BLOBS_PER_BLOCK_DENCUN as u64,
44            update_fraction: eip4844::BLOB_GASPRICE_UPDATE_FRACTION,
45            min_blob_fee: eip4844::BLOB_TX_MIN_BLOB_GASPRICE,
46        }
47    }
48
49    /// Returns [`BlobParams`] configuration activated with Prague hardfork.
50    pub const fn prague() -> Self {
51        Self {
52            target_blob_count: eip7691::TARGET_BLOBS_PER_BLOCK_ELECTRA,
53            max_blob_count: eip7691::MAX_BLOBS_PER_BLOCK_ELECTRA,
54            update_fraction: eip7691::BLOB_GASPRICE_UPDATE_FRACTION_PECTRA,
55            min_blob_fee: eip4844::BLOB_TX_MIN_BLOB_GASPRICE,
56        }
57    }
58
59    /// Returns [`BlobParams`] configuration activated with Osaka hardfork.
60    pub const fn osaka() -> Self {
61        Self {
62            target_blob_count: eip7594::TARGET_BLOBS_PER_BLOCK_FULU,
63            max_blob_count: eip7594::MAX_BLOBS_PER_BLOCK_FULU,
64            update_fraction: eip7691::BLOB_GASPRICE_UPDATE_FRACTION_PECTRA,
65            min_blob_fee: eip4844::BLOB_TX_MIN_BLOB_GASPRICE,
66        }
67    }
68
69    /// Returns the maximum available blob gas in a block.
70    ///
71    /// This is `max blob count * DATA_GAS_PER_BLOB`
72    pub const fn max_blob_gas_per_block(&self) -> u64 {
73        self.max_blob_count * DATA_GAS_PER_BLOB
74    }
75
76    /// Returns the blob gas target per block.
77    ///
78    /// This is `target blob count * DATA_GAS_PER_BLOB`
79    pub const fn target_blob_gas_per_block(&self) -> u64 {
80        self.target_blob_count * DATA_GAS_PER_BLOB
81    }
82
83    /// Calculates the `excess_blob_gas` value for the next block based on the current block
84    /// `excess_blob_gas` and `blob_gas_used`.
85    #[inline]
86    pub const fn next_block_excess_blob_gas(
87        &self,
88        excess_blob_gas: u64,
89        blob_gas_used: u64,
90    ) -> u64 {
91        (excess_blob_gas + blob_gas_used)
92            .saturating_sub(eip4844::DATA_GAS_PER_BLOB * self.target_blob_count)
93    }
94
95    /// Calculates the blob fee for block based on its `excess_blob_gas`.
96    #[inline]
97    pub const fn calc_blob_fee(&self, excess_blob_gas: u64) -> u128 {
98        eip4844::fake_exponential(self.min_blob_fee, excess_blob_gas as u128, self.update_fraction)
99    }
100}