From 200b61b08b5c87d24abb3f5bac3813be2b6a5979 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 28 Mar 2024 00:23:58 +0100 Subject: [PATCH] feat: set max fee per blob gas with pending block fees --- crates/provider/src/layers/gas.rs | 28 ++++++++++++++++++++++++---- crates/rpc-types/src/eth/block.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/crates/provider/src/layers/gas.rs b/crates/provider/src/layers/gas.rs index 6651ea410b9..4daa40969e3 100644 --- a/crates/provider/src/layers/gas.rs +++ b/crates/provider/src/layers/gas.rs @@ -4,6 +4,7 @@ use crate::{ use alloy_json_rpc::RpcError; use alloy_network::{Network, TransactionBuilder}; use alloy_primitives::U256; +use alloy_rpc_types::BlockNumberOrTag; use alloy_transport::{Transport, TransportError, TransportResult}; use async_trait::async_trait; use futures::FutureExt; @@ -153,11 +154,27 @@ where /// * `eth_feeHistory`: Returns the same info as for the EIP-1559 fees. /// * retrieving it from the "pending" block directly. /// - /// At the time of this writing support for EIP-4844 fees is lacking, hence we're defaulting to requesting the fee from the "pending" block. - async fn handle_eip4844_tx(&self, tx: &mut N::TransactionRequest) -> Result<(), TransportError> { - // TODO fetch block and set blob fee + /// At the time of this writing support for EIP-4844 fees is lacking, hence we're defaulting to + /// requesting the fee from the "pending" block. + async fn handle_eip4844_tx( + &self, + tx: &mut N::TransactionRequest, + ) -> Result<(), TransportError> { + // TODO this can be optimized together with 1559 dynamic fees once blob fee support on + // eth_feeHistory is more widely supported + if tx.get_blob_sidecar().is_some() && tx.max_fee_per_blob_gas().is_none() { + let next_blob_fee = self + .inner + .get_block_by_number(BlockNumberOrTag::Latest, false) + .await? + .ok_or(RpcError::NullResp)? + .header + .next_block_blob_fee() + .ok_or(RpcError::UnsupportedFeature("eip4844"))?; + tx.set_max_fee_per_blob_gas(U256::from(next_blob_fee)); + } - todo!() + Ok(()) } } @@ -182,6 +199,9 @@ where // Populate the following gas_limit, max_fee_per_gas and max_priority_fee_per_gas fields // if unset. self.handle_eip1559_tx(&mut tx).await?; + // TODO: this can be done more elegantly once we can set EIP-1559 and EIP-4844 fields + // with a single eth_feeHistory request + self.handle_eip4844_tx(&mut tx).await?; } else { // Assume its a legacy tx // Populate only the gas_limit field if unset. diff --git a/crates/rpc-types/src/eth/block.rs b/crates/rpc-types/src/eth/block.rs index faca627c323..be394ecccc2 100644 --- a/crates/rpc-types/src/eth/block.rs +++ b/crates/rpc-types/src/eth/block.rs @@ -3,6 +3,7 @@ #![allow(unknown_lints, non_local_definitions)] use crate::{other::OtherFields, Transaction, Withdrawal}; +use alloy_eips::{calc_blob_gasprice, calc_excess_blob_gas}; use alloy_primitives::{ ruint::ParseError, Address, BlockHash, BlockNumber, Bloom, Bytes, B256, B64, U256, U64, }; @@ -117,6 +118,32 @@ pub struct Header { pub parent_beacon_block_root: Option, } +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 { + self.excess_blob_gas.map(|gas| calc_blob_gasprice(gas.to())) + } + + /// 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 { + self.next_block_excess_blob_gas().map(calc_blob_gasprice) + } + + /// Calculate excess blob gas for the next block according to the EIP-4844 + /// spec. + /// + /// Returns a `None` if no excess blob gas is set, no EIP-4844 support + pub fn next_block_excess_blob_gas(&self) -> Option { + Some(calc_excess_blob_gas(self.excess_blob_gas?.to(), self.blob_gas_used?.to())) + } +} + /// Block Transactions depending on the boolean attribute of `eth_getBlockBy*`, /// or if used by `eth_getUncle*` #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]