@@ -17,12 +17,20 @@ use alloy::{
1717} ;
1818use config:: Config ;
1919use ethrex_common:: {
20- types:: { BlobsBundle , Fork } ,
21- H256 ,
20+ constants:: MIN_BASE_FEE_PER_BLOB_GAS ,
21+ types:: { fake_exponential_checked, BlobsBundle , Fork , BLOB_BASE_FEE_UPDATE_FRACTION } ,
22+ H256 , U256 ,
2223} ;
2324use ethrex_l2_rpc:: signer:: LocalSigner as EthrexLocalSigner ;
24- use ethrex_rpc:: { clients:: Overrides , EthClient } ;
25- use ethrex_sdk:: { build_generic_tx, calldata:: encode_calldata, send_generic_transaction} ;
25+ use ethrex_rpc:: {
26+ clients:: {
27+ eth:: { BACKOFF_FACTOR , MAX_NUMBER_OF_RETRIES , MAX_RETRY_DELAY , MIN_RETRY_DELAY } ,
28+ Overrides ,
29+ } ,
30+ types:: block_identifier:: { BlockIdentifier , BlockTag } ,
31+ EthClient ,
32+ } ;
33+ use ethrex_sdk:: { build_generic_tx, calldata:: encode_calldata, send_generic_transaction, transfer} ;
2634use fetcher:: { ProofsFetcher , ProofsFetcherError } ;
2735use merkle_tree:: compute_proofs_merkle_root;
2836use risc0_ethereum_contracts:: encode_seal;
@@ -56,6 +64,41 @@ pub struct ProofAggregator {
5664 ethrex_signer : ethrex_l2_rpc:: signer:: Signer ,
5765}
5866
67+ async fn estimate_blob_gas (
68+ eth_client : & EthClient ,
69+ arbitrary_base_blob_gas_price : u64 ,
70+ headroom : u64 ,
71+ ) -> u64 {
72+ let latest_block = eth_client
73+ . get_block_by_number ( BlockIdentifier :: Tag ( BlockTag :: Latest ) , false )
74+ . await
75+ . unwrap ( ) ;
76+
77+ let blob_gas_used = latest_block. header . blob_gas_used . unwrap_or ( 0 ) ;
78+ let excess_blob_gas = latest_block. header . excess_blob_gas . unwrap_or ( 0 ) ;
79+
80+ // Check if adding the blob gas used and excess blob gas would overflow
81+ let total_blob_gas = excess_blob_gas. checked_add ( blob_gas_used) . unwrap ( ) ;
82+
83+ // If the blob's market is in high demand, the equation may give a really big number.
84+ // This function doesn't panic, it performs checked/saturating operations.
85+ let blob_gas = fake_exponential_checked (
86+ MIN_BASE_FEE_PER_BLOB_GAS ,
87+ total_blob_gas,
88+ BLOB_BASE_FEE_UPDATE_FRACTION ,
89+ )
90+ . unwrap ( ) ;
91+
92+ let gas_with_headroom = ( blob_gas * ( 100 + headroom) ) / 100 ;
93+
94+ // Check if we have an overflow when we take the headroom into account.
95+ let blob_gas = arbitrary_base_blob_gas_price
96+ . checked_add ( gas_with_headroom)
97+ . unwrap ( ) ;
98+
99+ blob_gas
100+ }
101+
59102impl ProofAggregator {
60103 pub fn new ( config : Config ) -> Self {
61104 let rpc_url = config. eth_rpc_url . parse ( ) . expect ( "RPC URL should be valid" ) ;
@@ -75,8 +118,17 @@ impl ProofAggregator {
75118 let engine =
76119 ZKVMEngine :: from_env ( ) . expect ( "AGGREGATOR env variable to be set to one of sp1|risc0" ) ;
77120 let fetcher = ProofsFetcher :: new ( & config) ;
78- let ethrex_eth_client =
79- ethrex_rpc:: EthClient :: new ( & config. eth_rpc_url ) . expect ( "rpc url to be valid" ) ;
121+ let ethrex_eth_client = ethrex_rpc:: EthClient :: new_with_config (
122+ vec ! [ & config. eth_rpc_url] ,
123+ MAX_NUMBER_OF_RETRIES ,
124+ BACKOFF_FACTOR ,
125+ MIN_RETRY_DELAY ,
126+ MAX_RETRY_DELAY ,
127+ Some ( 10000000000 ) ,
128+ Some ( 10000000000 ) ,
129+ )
130+ . expect ( "rpc url to be valid" ) ;
131+
80132 let secret_key =
81133 SecretKey :: from_str ( & config. ecdsa . private_key ) . expect ( "private key to be valid" ) ;
82134 let ethrex_signer =
@@ -169,9 +221,6 @@ impl ProofAggregator {
169221 blob_versioned_hash : [ u8 ; 32 ] ,
170222 aggregated_proof : AlignedProof ,
171223 ) -> Result < H256 , AggregatedProofSubmissionError > {
172- // TODO: see how to get this
173- self . ethrex_eth_client . maximum_allowed_max_fee_per_blob_gas = Some ( 1 ) ;
174-
175224 match aggregated_proof {
176225 AlignedProof :: SP1 ( proof) => {
177226 let calldata = encode_calldata (
@@ -190,6 +239,11 @@ impl ProofAggregator {
190239 )
191240 . map_err ( |e| AggregatedProofSubmissionError :: BuildingCalldata ( e. to_string ( ) ) ) ?;
192241
242+ let le_bytes = estimate_blob_gas ( & self . ethrex_eth_client , 1000000000 , 20 )
243+ . await
244+ . to_le_bytes ( ) ;
245+ let gas_price_per_blob = U256 :: from_little_endian ( & le_bytes) ;
246+
193247 let tx = build_generic_tx (
194248 & self . ethrex_eth_client ,
195249 ethrex_common:: types:: TxType :: EIP4844 ,
@@ -198,6 +252,7 @@ impl ProofAggregator {
198252 calldata. into ( ) ,
199253 Overrides {
200254 blobs_bundle : Some ( blob_bundle) ,
255+ gas_price_per_blob : Some ( gas_price_per_blob) ,
201256 ..Default :: default ( )
202257 } ,
203258 )
@@ -234,6 +289,11 @@ impl ProofAggregator {
234289 )
235290 . map_err ( |e| AggregatedProofSubmissionError :: BuildingCalldata ( e. to_string ( ) ) ) ?;
236291
292+ let le_bytes = estimate_blob_gas ( & self . ethrex_eth_client , 1000000000 , 20 )
293+ . await
294+ . to_le_bytes ( ) ;
295+ let gas_price_per_blob = U256 :: from_little_endian ( & le_bytes) ;
296+
237297 let tx = build_generic_tx (
238298 & self . ethrex_eth_client ,
239299 ethrex_common:: types:: TxType :: EIP4844 ,
@@ -242,6 +302,7 @@ impl ProofAggregator {
242302 calldata. into ( ) ,
243303 Overrides {
244304 blobs_bundle : Some ( blob_bundle) ,
305+ gas_price_per_blob : Some ( gas_price_per_blob) ,
245306 ..Default :: default ( )
246307 } ,
247308 )
0 commit comments