feat: add blob fee calc functions (#4440)

This commit is contained in:
Matthias Seitz
2023-08-31 13:47:07 -07:00
committed by GitHub
parent a76da98316
commit 97cf35673e
2 changed files with 74 additions and 3 deletions

View File

@ -1,6 +1,6 @@
//! [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844#parameters) protocol constants for shard Blob Transactions.
//! [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844#parameters) protocol constants and utils for shard Blob Transactions.
use crate::kzg::KzgSettings;
use crate::{kzg::KzgSettings, U256};
use once_cell::sync::Lazy;
use std::{io::Write, sync::Arc};
@ -25,9 +25,12 @@ pub const MAX_BLOBS_PER_BLOCK: u64 = MAX_DATA_GAS_PER_BLOCK / DATA_GAS_PER_BLOB;
/// Target number of data blobs in a single block.
pub const TARGET_BLOBS_PER_BLOCK: u64 = TARGET_DATA_GAS_PER_BLOCK / DATA_GAS_PER_BLOB; // 393216 / 131072 = 3
/// Used to determine the price for next data blob
/// Determines the maximum rate of change for blob fee
pub const BLOB_GASPRICE_UPDATE_FRACTION: u64 = 3_338_477u64; // 3338477
/// Minimum gas price for a data blob
pub const BLOB_TX_MIN_BLOB_GASPRICE: u64 = 1u64;
/// Commitment version of a KZG commitment
pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01;
@ -63,6 +66,32 @@ pub enum LoadKzgSettingsError {
KzgError(c_kzg::Error),
}
/// Calculates the blob fee for the given excess blob gas.
pub fn blob_fee(excess_blob_gas: u64) -> U256 {
fake_exponential(
U256::from(BLOB_TX_MIN_BLOB_GASPRICE),
U256::from(excess_blob_gas),
U256::from(BLOB_GASPRICE_UPDATE_FRACTION),
)
}
/// Approximates factor * e ** (numerator / denominator) using Taylor expansion.
///
/// This is used to calculate the blob price.
///
/// See also <https://eips.ethereum.org/EIPS/eip-4844#helpers>
pub fn fake_exponential(factor: U256, numerator: U256, denominator: U256) -> U256 {
let mut output = U256::ZERO;
let mut numerator_accum = factor.saturating_mul(denominator);
let mut i = U256::from(1u64);
while numerator_accum > U256::ZERO {
output += numerator_accum;
numerator_accum = numerator_accum * numerator / (denominator * i);
i += U256::from(1u64);
}
output / denominator
}
#[cfg(test)]
mod tests {
use super::*;
@ -71,4 +100,29 @@ mod tests {
fn ensure_load_kzg_settings() {
let _settings = Arc::clone(&MAINNET_KZG_TRUSTED_SETUP);
}
#[test]
fn test_fake_exp() {
// <https://github.com/ethereum/go-ethereum/blob/28857080d732857030eda80c69b9ba2c8926f221/consensus/misc/eip4844/eip4844_test.go#L78-L78>
for (factor, num, denom, expected) in &[
(1u64, 0u64, 1u64, 1u64),
(38493, 0, 1000, 38493),
(0, 1234, 2345, 0),
(1, 2, 1, 6), // approximate 7.389
(1, 4, 2, 6),
(1, 3, 1, 16), // approximate 20.09
(1, 6, 2, 18),
(1, 4, 1, 49), // approximate 54.60
(1, 8, 2, 50),
(10, 8, 2, 542), // approximate 540.598
(11, 8, 2, 596), // approximate 600.58
(1, 5, 1, 136), // approximate 148.4
(1, 5, 2, 11), // approximate 12.18
(2, 5, 2, 23), // approximate 24.36
(1, 50000000, 2225652, 5709098764),
] {
let res = fake_exponential(U256::from(*factor), U256::from(*num), U256::from(*denom));
assert_eq!(res, U256::from(*expected));
}
}
}

View File

@ -8,6 +8,7 @@ use crate::{
};
use bytes::{Buf, BufMut, BytesMut};
use crate::constants::eip4844::blob_fee;
use reth_codecs::{add_arbitrary_tests, derive_arbitrary, main_codec, Compact};
use reth_rlp::{length_of_length, Decodable, Encodable, EMPTY_LIST_CODE, EMPTY_STRING_CODE};
use serde::{Deserialize, Serialize};
@ -183,6 +184,22 @@ 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<U256> {
self.excess_blob_gas.map(blob_fee)
}
/// Returns the blob fee for the next block according to the EIP-4844 spec.
///
/// Returns `None` if `excess_blob_gas` is None.
///
/// See also [Self::next_block_excess_blob_gas]
pub fn next_block_blob_fee(&self) -> Option<U256> {
self.next_block_excess_blob_gas().map(blob_fee)
}
/// Calculate base fee for next block according to the EIP-1559 spec.
///
/// Returns a `None` if no base fee is set, no EIP-1559 support