mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat: add blob fee calc functions (#4440)
This commit is contained in:
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user