Skip to content

Commit 8bab682

Browse files
authored
fix: use blobparams for blob fee calc (#12056)
* fix: use blobparams for blob fee calc * clippy
1 parent e2c8186 commit 8bab682

File tree

5 files changed

+98
-18
lines changed

5 files changed

+98
-18
lines changed

crates/anvil/src/config.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::{
1717
};
1818
use alloy_chains::Chain;
1919
use alloy_consensus::BlockHeader;
20+
use alloy_eips::eip7840::BlobParams;
2021
use alloy_genesis::Genesis;
2122
use alloy_network::{AnyNetwork, TransactionResponse};
2223
use alloy_op_hardforks::OpHardfork;
@@ -65,7 +66,10 @@ use tokio::sync::RwLock as TokioRwLock;
6566
use yansi::Paint;
6667

6768
pub use foundry_common::version::SHORT_VERSION as VERSION_MESSAGE;
68-
use foundry_evm::traces::{CallTraceDecoderBuilder, identifier::SignaturesIdentifier};
69+
use foundry_evm::{
70+
traces::{CallTraceDecoderBuilder, identifier::SignaturesIdentifier},
71+
utils::get_blob_params,
72+
};
6973
use foundry_evm_networks::NetworkConfigs;
7074

7175
/// Default port the rpc will open
@@ -533,6 +537,14 @@ impl NodeConfig {
533537
}
534538
}
535539

540+
/// Returns the [`BlobParams`] that should be used.
541+
pub fn get_blob_params(&self) -> BlobParams {
542+
get_blob_params(
543+
self.chain_id.unwrap_or(Chain::mainnet().id()),
544+
self.get_genesis_timestamp(),
545+
)
546+
}
547+
536548
/// Returns the hardfork to use
537549
pub fn get_hardfork(&self) -> ChainHardfork {
538550
if let Some(hardfork) = self.hardfork {
@@ -1083,6 +1095,7 @@ impl NodeConfig {
10831095
!self.disable_min_priority_fee,
10841096
self.get_gas_price(),
10851097
self.get_blob_excess_gas_and_price(),
1098+
self.get_blob_params(),
10861099
);
10871100

10881101
let (db, fork): (Arc<TokioRwLock<Box<dyn Db>>>, Option<ClientFork>) =
@@ -1297,7 +1310,8 @@ latest block number: {latest_block}"
12971310
if let (Some(blob_excess_gas), Some(blob_gas_used)) =
12981311
(block.header.excess_blob_gas, block.header.blob_gas_used)
12991312
{
1300-
let blob_base_fee_update_fraction = get_blob_base_fee_update_fraction(
1313+
// derive the blobparams that are active at this timestamp
1314+
let blob_params = get_blob_params(
13011315
fork_chain_id
13021316
.unwrap_or_else(|| U256::from(Chain::mainnet().id()))
13031317
.saturating_to(),
@@ -1306,15 +1320,16 @@ latest block number: {latest_block}"
13061320

13071321
env.evm_env.block_env.blob_excess_gas_and_price = Some(BlobExcessGasAndPrice::new(
13081322
blob_excess_gas,
1309-
blob_base_fee_update_fraction,
1323+
blob_params.update_fraction as u64,
13101324
));
13111325

1326+
fees.set_blob_params(blob_params);
1327+
13121328
let next_block_blob_excess_gas =
13131329
fees.get_next_block_blob_excess_gas(blob_excess_gas, blob_gas_used);
1314-
13151330
fees.set_blob_excess_gas_and_price(BlobExcessGasAndPrice::new(
13161331
next_block_blob_excess_gas,
1317-
blob_base_fee_update_fraction,
1332+
blob_params.update_fraction as u64,
13181333
));
13191334
}
13201335
}

crates/anvil/src/eth/backend/mem/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,11 +1149,15 @@ impl Backend {
11491149
}
11501150

11511151
/// Returns the environment for the next block
1152+
///
1153+
/// This is used for obtaining the evm environment for the next (pending) block (e.g.
1154+
/// transaction validation in eth_sendrawTransaction)
11521155
fn next_env(&self) -> Env {
11531156
let mut env = self.env.read().clone();
11541157
// increase block number for this block
11551158
env.evm_env.block_env.number = env.evm_env.block_env.number.saturating_add(U256::from(1));
11561159
env.evm_env.block_env.basefee = self.base_fee();
1160+
env.evm_env.block_env.blob_excess_gas_and_price = self.excess_blob_gas_and_price();
11571161
env.evm_env.block_env.timestamp = U256::from(self.time.current_call_timestamp());
11581162
env
11591163
}

crates/anvil/src/eth/fees.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ pub fn default_elasticity() -> f64 {
4646
pub struct FeeManager {
4747
/// Hardfork identifier
4848
spec_id: SpecId,
49+
/// The blob params that determine blob fees
50+
blob_params: Arc<RwLock<BlobParams>>,
4951
/// Tracks the base fee for the next block post London
5052
///
5153
/// This value will be updated after a new block was mined
@@ -70,9 +72,11 @@ impl FeeManager {
7072
is_min_priority_fee_enforced: bool,
7173
gas_price: u128,
7274
blob_excess_gas_and_price: BlobExcessGasAndPrice,
75+
blob_params: BlobParams,
7376
) -> Self {
7477
Self {
7578
spec_id,
79+
blob_params: Arc::new(RwLock::new(blob_params)),
7680
base_fee: Arc::new(RwLock::new(base_fee)),
7781
is_min_priority_fee_enforced,
7882
gas_price: Arc::new(RwLock::new(gas_price)),
@@ -158,15 +162,27 @@ impl FeeManager {
158162

159163
/// Calculates the next block blob base fee.
160164
pub fn get_next_block_blob_base_fee_per_gas(&self) -> u128 {
161-
alloy_eips::eip4844::calc_blob_gasprice(
162-
self.blob_excess_gas_and_price.read().excess_blob_gas,
163-
)
165+
self.blob_params().calc_blob_fee(self.blob_excess_gas_and_price.read().excess_blob_gas)
164166
}
165167

166168
/// Calculates the next block blob excess gas, using the provided parent blob gas used and
167169
/// parent blob excess gas
168170
pub fn get_next_block_blob_excess_gas(&self, blob_gas_used: u64, blob_excess_gas: u64) -> u64 {
169-
alloy_eips::eip4844::calc_excess_blob_gas(blob_gas_used, blob_excess_gas)
171+
self.blob_params().next_block_excess_blob_gas_osaka(
172+
blob_excess_gas,
173+
blob_gas_used,
174+
self.base_fee(),
175+
)
176+
}
177+
178+
/// Configures the blob params
179+
pub fn set_blob_params(&self, blob_params: BlobParams) {
180+
*self.blob_params.write() = blob_params;
181+
}
182+
183+
/// Returns the active [`BlobParams`]
184+
pub fn blob_params(&self) -> BlobParams {
185+
*self.blob_params.read()
170186
}
171187
}
172188

crates/anvil/tests/it/eip4844.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use alloy_eips::{
77
use alloy_hardforks::EthereumHardfork;
88
use alloy_network::{EthereumWallet, ReceiptResponse, TransactionBuilder, TransactionBuilder4844};
99
use alloy_primitives::{Address, U256, b256};
10-
use alloy_provider::Provider;
10+
use alloy_provider::{Provider, ProviderBuilder};
1111
use alloy_rpc_types::{BlockId, TransactionRequest};
1212
use alloy_serde::WithOtherFields;
1313
use anvil::{NodeConfig, spawn};
@@ -76,6 +76,33 @@ async fn can_send_eip4844_transaction_fork() {
7676
let _blobs = api.anvil_get_blob_by_tx_hash(tx_hash).unwrap().unwrap();
7777
}
7878

79+
#[tokio::test(flavor = "multi_thread")]
80+
async fn can_send_eip4844_transaction_eth_send_transaction() {
81+
let node_config = NodeConfig::test()
82+
.with_eth_rpc_url(Some(rpc::next_http_archive_rpc_url()))
83+
.with_fork_block_number(Some(23552208u64))
84+
.with_hardfork(Some(EthereumHardfork::Cancun.into()));
85+
let (api, handle) = spawn(node_config).await;
86+
let provider = ProviderBuilder::new().connect(handle.http_endpoint().as_str()).await.unwrap();
87+
let accounts = provider.get_accounts().await.unwrap();
88+
let alice = accounts[0];
89+
let bob = accounts[1];
90+
91+
let sidecar: SidecarBuilder<SimpleCoder> = SidecarBuilder::from_slice(b"Blobs are fun!");
92+
let sidecar = sidecar.build().unwrap();
93+
94+
let tx = TransactionRequest::default()
95+
.with_from(alice)
96+
.with_to(bob)
97+
.with_blob_sidecar(sidecar.clone());
98+
99+
let pending_tx = provider.send_transaction(tx).await.unwrap();
100+
let receipt = pending_tx.get_receipt().await.unwrap();
101+
let tx_hash = receipt.transaction_hash;
102+
103+
let _blobs = api.anvil_get_blob_by_tx_hash(tx_hash).unwrap().unwrap();
104+
}
105+
79106
#[tokio::test(flavor = "multi_thread")]
80107
async fn can_send_multiple_blobs_in_one_tx() {
81108
let node_config = NodeConfig::test().with_hardfork(Some(EthereumHardfork::Cancun.into()));

crates/evm/core/src/utils.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::EnvMut;
22
use alloy_chains::Chain;
3-
use alloy_consensus::BlockHeader;
3+
use alloy_consensus::{BlockHeader, private::alloy_eips::eip7840::BlobParams};
44
use alloy_hardforks::EthereumHardfork;
55
use alloy_json_abi::{Function, JsonAbi};
66
use alloy_network::{AnyTxEnvelope, TransactionResponse};
@@ -84,19 +84,37 @@ pub fn apply_chain_and_block_specific_env_changes<N: Network>(
8484
}
8585
}
8686

87-
/// Derive the blob base fee update fraction based on the chain and timestamp by checking the
88-
/// hardfork.
89-
pub fn get_blob_base_fee_update_fraction(chain_id: ChainId, timestamp: u64) -> u64 {
87+
/// Derives the active [`BlobParams`] based on the given timestamp.
88+
///
89+
/// This falls back to regular ethereum blob params if no hardforks for the given chain id are
90+
/// detected.
91+
pub fn get_blob_params(chain_id: ChainId, timestamp: u64) -> BlobParams {
9092
let hardfork = EthereumHardfork::from_chain_and_timestamp(Chain::from_id(chain_id), timestamp)
9193
.unwrap_or_default();
9294

93-
if hardfork >= EthereumHardfork::Prague {
94-
BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE
95-
} else {
96-
BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN
95+
match hardfork {
96+
EthereumHardfork::Prague => BlobParams::prague(),
97+
EthereumHardfork::Osaka => BlobParams::osaka(),
98+
EthereumHardfork::Bpo1 => BlobParams::bpo1(),
99+
EthereumHardfork::Bpo2 => BlobParams::bpo2(),
100+
101+
// future hardforks/unknown settings: update once decided
102+
EthereumHardfork::Bpo3 => BlobParams::bpo2(),
103+
EthereumHardfork::Bpo4 => BlobParams::bpo2(),
104+
EthereumHardfork::Bpo5 => BlobParams::bpo2(),
105+
EthereumHardfork::Amsterdam => BlobParams::bpo2(),
106+
107+
// fallback
108+
_ => BlobParams::cancun(),
97109
}
98110
}
99111

112+
/// Derive the blob base fee update fraction based on the chain and timestamp by checking the
113+
/// hardfork.
114+
pub fn get_blob_base_fee_update_fraction(chain_id: ChainId, timestamp: u64) -> u64 {
115+
get_blob_params(chain_id, timestamp).update_fraction as u64
116+
}
117+
100118
/// Returns the blob base fee update fraction based on the spec id.
101119
pub fn get_blob_base_fee_update_fraction_by_spec_id(spec: SpecId) -> u64 {
102120
if spec >= SpecId::PRAGUE {

0 commit comments

Comments
 (0)