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 let mut i = 1;
90 let mut output = 0;
91 let mut numerator_accum = factor * denominator;
92 while numerator_accum > 0 {
93 output += numerator_accum;
94
95 numerator_accum = (numerator_accum * numerator) / (denominator * i);
97 i += 1;
98 }
99 output / denominator
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105 use primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN;
106
107 #[test]
109 fn fake_exp() {
110 for t @ &(factor, numerator, denominator, expected) in &[
111 (1u64, 0u64, 1u64, 1u128),
112 (38493, 0, 1000, 38493),
113 (0, 1234, 2345, 0),
114 (1, 2, 1, 6), (1, 4, 2, 6),
116 (1, 3, 1, 16), (1, 6, 2, 18),
118 (1, 4, 1, 49), (1, 8, 2, 50),
120 (10, 8, 2, 542), (11, 8, 2, 596), (1, 5, 1, 136), (1, 5, 2, 11), (2, 5, 2, 23), (1, 50000000, 2225652, 5709098764),
126 (1, 380928, BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN, 1),
127 ] {
128 let actual = fake_exponential(factor, numerator, denominator);
129 assert_eq!(actual, expected, "test: {t:?}");
130 }
131 }
132}