revm_context_interface/block/
blob.rs1use primitives::{
9 eip4844::{
10 BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN, BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE,
11 MIN_BLOB_GASPRICE,
12 },
13 hardfork::SpecId,
14};
15
16#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23pub struct BlobExcessGasAndPrice {
24 pub excess_blob_gas: u64,
26 pub blob_gasprice: u128,
30}
31
32impl BlobExcessGasAndPrice {
33 pub fn new(excess_blob_gas: u64, blob_base_fee_update_fraction: u64) -> Self {
37 let blob_gasprice = calc_blob_gasprice(excess_blob_gas, blob_base_fee_update_fraction);
38 Self {
39 excess_blob_gas,
40 blob_gasprice,
41 }
42 }
43
44 pub fn new_with_spec(excess_blob_gas: u64, spec: SpecId) -> Self {
46 Self::new(
47 excess_blob_gas,
48 if spec.is_enabled_in(SpecId::PRAGUE) {
49 BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE
50 } else {
51 BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN
52 },
53 )
54 }
55}
56
57#[inline]
62pub fn calc_blob_gasprice(excess_blob_gas: u64, blob_base_fee_update_fraction: u64) -> u128 {
63 fake_exponential(
64 MIN_BLOB_GASPRICE,
65 excess_blob_gas,
66 blob_base_fee_update_fraction,
67 )
68}
69
70pub fn get_base_fee_per_blob_gas(excess_blob_gas: u64, blob_base_fee_update_fraction: u64) -> u128 {
73 calc_blob_gasprice(excess_blob_gas, blob_base_fee_update_fraction)
74}
75
76#[inline]
83pub fn fake_exponential(factor: u64, numerator: u64, denominator: u64) -> u128 {
84 assert_ne!(denominator, 0, "attempt to divide by zero");
85 let factor = factor as u128;
86 let numerator = numerator as u128;
87 let denominator = denominator as u128;
88
89 if denominator == 0 {
90 return 0;
91 }
92
93 let mut i = 1;
94 let mut output = 0;
95 let mut numerator_accum = factor * denominator;
96 while numerator_accum > 0 {
97 output += numerator_accum;
98
99 numerator_accum = (numerator_accum * numerator) / (denominator * i);
101 i += 1;
102 }
103 output / denominator
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109 use primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN;
110
111 #[test]
113 fn fake_exp() {
114 for t @ &(factor, numerator, denominator, expected) in &[
115 (1u64, 0u64, 1u64, 1u128),
116 (38493, 0, 1000, 38493),
117 (0, 1234, 2345, 0),
118 (1, 2, 1, 6), (1, 4, 2, 6),
120 (1, 3, 1, 16), (1, 6, 2, 18),
122 (1, 4, 1, 49), (1, 8, 2, 50),
124 (10, 8, 2, 542), (11, 8, 2, 596), (1, 5, 1, 136), (1, 5, 2, 11), (2, 5, 2, 23), (1, 50000000, 2225652, 5709098764),
130 (1, 380928, BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN, 1),
131 ] {
132 let actual = fake_exponential(factor, numerator, denominator);
133 assert_eq!(actual, expected, "test: {t:?}");
134 }
135 }
136}