33//!
44//! See also [the EIP-4844 helpers](https://eips.ethereum.org/EIPS/eip-4844#helpers).
55//!
6- //! [`calc_blob_gasprice`] and [`calc_excess_blob_gas`] are used to calculate the blob gas price and
7- //! excess blob gas.
86//!
97//! [`BlobExcessGasAndPrice`] is used to store the blob gas price and excess blob gas.s
10- use primitives:: {
11- eip4844:: { GAS_PER_BLOB , MIN_BLOB_GASPRICE } ,
12- eip7918,
13- } ;
8+ use primitives:: eip4844:: MIN_BLOB_GASPRICE ;
149
1510/// Structure holding block blob excess gas and it calculates blob fee
1611///
@@ -31,102 +26,14 @@ pub struct BlobExcessGasAndPrice {
3126impl BlobExcessGasAndPrice {
3227 /// Creates a new instance by calculating the blob gas price with [`calc_blob_gasprice`].
3328 ///
34- /// `excess_blob_gas` is the excess blob gas of the block, it can be calculated with [ `calc_excess_blob_gas`] .
29+ /// `excess_blob_gas` is the excess blob gas of the block, it can be calculated with `calc_excess_blob_gas` function from alloy-eips .
3530 pub fn new ( excess_blob_gas : u64 , blob_base_fee_update_fraction : u64 ) -> Self {
3631 let blob_gasprice = calc_blob_gasprice ( excess_blob_gas, blob_base_fee_update_fraction) ;
3732 Self {
3833 excess_blob_gas,
3934 blob_gasprice,
4035 }
4136 }
42-
43- /// Calculate this block excess gas and price from the parent excess gas and gas used
44- /// and the target blob gas per block.
45- ///
46- /// These fields will be used to calculate `excess_blob_gas` with [`calc_excess_blob_gas`] func.
47- #[ deprecated(
48- note = "Use `calc_excess_blob_gas` and `BlobExcessGasAndPrice::new` instead. Only works for forks before Osaka."
49- ) ]
50- pub fn from_parent_and_target (
51- parent_excess_blob_gas : u64 ,
52- parent_blob_gas_used : u64 ,
53- parent_target_blob_gas_per_block : u64 ,
54- blob_base_fee_update_fraction : u64 ,
55- ) -> Self {
56- Self :: new (
57- calc_excess_blob_gas (
58- parent_excess_blob_gas,
59- parent_blob_gas_used,
60- parent_target_blob_gas_per_block,
61- ) ,
62- blob_base_fee_update_fraction,
63- )
64- }
65- }
66-
67- /// Calculates the `excess_blob_gas` from the parent header's `blob_gas_used` and `excess_blob_gas`.
68- /// Uses [`calc_excess_blob_gas_osaka`] internally.
69- #[ inline]
70- pub fn calc_excess_blob_gas (
71- parent_excess_blob_gas : u64 ,
72- parent_blob_gas_used : u64 ,
73- parent_target_blob_gas_per_block : u64 ,
74- ) -> u64 {
75- calc_excess_blob_gas_osaka (
76- parent_excess_blob_gas,
77- parent_blob_gas_used,
78- parent_target_blob_gas_per_block,
79- false ,
80- 0 ,
81- 0 ,
82- 0 ,
83- 0 ,
84- 0 ,
85- )
86- }
87-
88- /// Calculates the `excess_blob_gas` from the parent header's `blob_gas_used` and `excess_blob_gas`.
89- ///
90- /// See also [the EIP-4844 helpers]<https://eips.ethereum.org/EIPS/eip-4844#helpers>
91- /// (`calc_excess_blob_gas`).
92- ///
93- /// [EIP-7918: Blob base fee bounded by execution cost](https://eips.ethereum.org/EIPS/eip-7918)
94- ///
95- /// `blob_base_cost` is introduced in EIP-7918 in Osaka fork. All fields after is_osaka input are not needed before Osaka.
96- #[ allow( clippy:: too_many_arguments) ]
97- #[ inline]
98- pub fn calc_excess_blob_gas_osaka (
99- parent_excess_blob_gas : u64 ,
100- parent_blob_gas_used : u64 ,
101- parent_target_blob_gas_per_block : u64 ,
102- is_osaka : bool ,
103- parent_base_fee_per_gas : u64 ,
104- parent_blob_base_fee_per_gas : u64 ,
105- parent_blob_base_fee_update_fraction : u64 ,
106- max_blob_count : u64 ,
107- target_blob_count : u64 ,
108- ) -> u64 {
109- let excess_and_used = parent_excess_blob_gas. saturating_add ( parent_blob_gas_used) ;
110-
111- if is_osaka {
112- if excess_and_used < parent_target_blob_gas_per_block {
113- return 0 ;
114- }
115-
116- if ( eip7918:: BLOB_BASE_COST . saturating_mul ( parent_base_fee_per_gas) as u128 )
117- > ( GAS_PER_BLOB as u128 ) . saturating_mul ( get_base_fee_per_blob_gas (
118- parent_blob_base_fee_per_gas,
119- parent_blob_base_fee_update_fraction,
120- ) )
121- {
122- return excess_and_used. saturating_add (
123- parent_blob_gas_used. saturating_mul ( max_blob_count - target_blob_count)
124- / max_blob_count,
125- ) ;
126- }
127- }
128-
129- excess_and_used. saturating_sub ( parent_target_blob_gas_per_block)
13037}
13138
13239/// Calculates the blob gas price from the header's excess blob gas field.
@@ -181,92 +88,7 @@ pub fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> u128 {
18188#[ cfg( test) ]
18289mod tests {
18390 use super :: * ;
184- use primitives:: eip4844:: {
185- self , BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN , GAS_PER_BLOB ,
186- TARGET_BLOB_GAS_PER_BLOCK_CANCUN as TARGET_BLOB_GAS_PER_BLOCK ,
187- } ;
188-
189- // https://github.com/ethereum/go-ethereum/blob/28857080d732857030eda80c69b9ba2c8926f221/consensus/misc/eip4844/eip4844_test.go#L27
190- #[ test]
191- fn test_calc_excess_blob_gas ( ) {
192- for t @ & ( excess, blobs, expected) in & [
193- // The excess blob gas should not increase from zero if the used blob
194- // slots are below - or equal - to the target.
195- ( 0 , 0 , 0 ) ,
196- ( 0 , 1 , 0 ) ,
197- ( 0 , TARGET_BLOB_GAS_PER_BLOCK / GAS_PER_BLOB , 0 ) ,
198- // If the target blob gas is exceeded, the excessBlobGas should increase
199- // by however much it was overshot
200- (
201- 0 ,
202- ( TARGET_BLOB_GAS_PER_BLOCK / GAS_PER_BLOB ) + 1 ,
203- GAS_PER_BLOB ,
204- ) ,
205- (
206- 1 ,
207- ( TARGET_BLOB_GAS_PER_BLOCK / GAS_PER_BLOB ) + 1 ,
208- GAS_PER_BLOB + 1 ,
209- ) ,
210- (
211- 1 ,
212- ( TARGET_BLOB_GAS_PER_BLOCK / GAS_PER_BLOB ) + 2 ,
213- 2 * GAS_PER_BLOB + 1 ,
214- ) ,
215- // The excess blob gas should decrease by however much the target was
216- // under-shot, capped at zero.
217- (
218- TARGET_BLOB_GAS_PER_BLOCK ,
219- TARGET_BLOB_GAS_PER_BLOCK / GAS_PER_BLOB ,
220- TARGET_BLOB_GAS_PER_BLOCK ,
221- ) ,
222- (
223- TARGET_BLOB_GAS_PER_BLOCK ,
224- ( TARGET_BLOB_GAS_PER_BLOCK / GAS_PER_BLOB ) - 1 ,
225- TARGET_BLOB_GAS_PER_BLOCK - GAS_PER_BLOB ,
226- ) ,
227- (
228- TARGET_BLOB_GAS_PER_BLOCK ,
229- ( TARGET_BLOB_GAS_PER_BLOCK / GAS_PER_BLOB ) - 2 ,
230- TARGET_BLOB_GAS_PER_BLOCK - ( 2 * GAS_PER_BLOB ) ,
231- ) ,
232- (
233- GAS_PER_BLOB - 1 ,
234- ( TARGET_BLOB_GAS_PER_BLOCK / GAS_PER_BLOB ) - 1 ,
235- 0 ,
236- ) ,
237- ] {
238- let actual = calc_excess_blob_gas (
239- excess,
240- blobs * GAS_PER_BLOB ,
241- eip4844:: TARGET_BLOB_GAS_PER_BLOCK_CANCUN ,
242- ) ;
243- assert_eq ! ( actual, expected, "test: {t:?}" ) ;
244- }
245- }
246-
247- // https://github.com/ethereum/go-ethereum/blob/28857080d732857030eda80c69b9ba2c8926f221/consensus/misc/eip4844/eip4844_test.go#L60
248- #[ test]
249- fn test_calc_blob_fee_cancun ( ) {
250- let blob_fee_vectors = & [
251- ( 0 , 1 ) ,
252- ( 2314057 , 1 ) ,
253- ( 2314058 , 2 ) ,
254- ( 10 * 1024 * 1024 , 23 ) ,
255- // `calc_blob_gasprice` approximates `e ** (excess_blob_gas / BLOB_BASE_FEE_UPDATE_FRACTION)` using Taylor expansion
256- //
257- // to roughly find where boundaries will be hit:
258- // 2 ** bits = e ** (excess_blob_gas / BLOB_BASE_FEE_UPDATE_FRACTION)
259- // excess_blob_gas = ln(2 ** bits) * BLOB_BASE_FEE_UPDATE_FRACTION
260- ( 148099578 , 18446739238971471609 ) , // output is just below the overflow
261- ( 148099579 , 18446744762204311910 ) , // output is just after the overflow
262- ( 161087488 , 902580055246494526580 ) ,
263- ] ;
264-
265- for & ( excess, expected) in blob_fee_vectors {
266- let actual = calc_blob_gasprice ( excess, BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN ) ;
267- assert_eq ! ( actual, expected, "test: {excess}" ) ;
268- }
269- }
91+ use primitives:: eip4844:: BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN ;
27092
27193 // https://github.com/ethereum/go-ethereum/blob/28857080d732857030eda80c69b9ba2c8926f221/consensus/misc/eip4844/eip4844_test.go#L78
27294 #[ test]
0 commit comments