11pub mod config;
2+ mod eth;
23pub mod fetcher;
34mod merkle_tree;
45mod retry;
56mod s3;
67mod types;
78
8- use crate :: aggregators:: { AlignedProof , ProofAggregationError , ZKVMEngine } ;
9+ use crate :: {
10+ aggregators:: { AlignedProof , ProofAggregationError , ZKVMEngine } ,
11+ backend:: eth:: {
12+ estimate_blob_gas, MAXIMUM_ALLOWED_MAX_FEE_PER_BLOB_GAS , MAXIMUM_ALLOWED_MAX_FEE_PER_GAS ,
13+ } ,
14+ } ;
915
1016use alloy:: {
1117 eips:: eip4844:: BYTES_PER_BLOB ,
@@ -17,20 +23,18 @@ use alloy::{
1723} ;
1824use config:: Config ;
1925use ethrex_common:: {
20- constants:: MIN_BASE_FEE_PER_BLOB_GAS ,
21- types:: { fake_exponential_checked, BlobsBundle , Fork , BLOB_BASE_FEE_UPDATE_FRACTION } ,
22- H256 , U256 ,
26+ types:: { BlobsBundle , Fork } ,
27+ H256 ,
2328} ;
2429use ethrex_l2_rpc:: signer:: LocalSigner as EthrexLocalSigner ;
2530use ethrex_rpc:: {
2631 clients:: {
2732 eth:: { BACKOFF_FACTOR , MAX_NUMBER_OF_RETRIES , MAX_RETRY_DELAY , MIN_RETRY_DELAY } ,
2833 Overrides ,
2934 } ,
30- types:: block_identifier:: { BlockIdentifier , BlockTag } ,
3135 EthClient ,
3236} ;
33- use ethrex_sdk:: { build_generic_tx, calldata:: encode_calldata, send_generic_transaction, transfer } ;
37+ use ethrex_sdk:: { build_generic_tx, calldata:: encode_calldata, send_generic_transaction} ;
3438use fetcher:: { ProofsFetcher , ProofsFetcherError } ;
3539use merkle_tree:: compute_proofs_merkle_root;
3640use risc0_ethereum_contracts:: encode_seal;
@@ -64,41 +68,6 @@ pub struct ProofAggregator {
6468 ethrex_signer : ethrex_l2_rpc:: signer:: Signer ,
6569}
6670
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-
10271impl ProofAggregator {
10372 pub fn new ( config : Config ) -> Self {
10473 let rpc_url = config. eth_rpc_url . parse ( ) . expect ( "RPC URL should be valid" ) ;
@@ -124,8 +93,8 @@ impl ProofAggregator {
12493 BACKOFF_FACTOR ,
12594 MIN_RETRY_DELAY ,
12695 MAX_RETRY_DELAY ,
127- Some ( 10000000000 ) ,
128- Some ( 10000000000 ) ,
96+ Some ( MAXIMUM_ALLOWED_MAX_FEE_PER_GAS ) ,
97+ Some ( MAXIMUM_ALLOWED_MAX_FEE_PER_BLOB_GAS ) ,
12998 )
13099 . expect ( "rpc url to be valid" ) ;
131100
@@ -221,61 +190,29 @@ impl ProofAggregator {
221190 blob_versioned_hash : [ u8 ; 32 ] ,
222191 aggregated_proof : AlignedProof ,
223192 ) -> Result < H256 , AggregatedProofSubmissionError > {
224- match aggregated_proof {
225- AlignedProof :: SP1 ( proof) => {
226- let calldata = encode_calldata (
227- "verifySP1(bytes32,bytes,bytes)" ,
228- & [
229- ethrex_l2_common:: calldata:: Value :: FixedBytes (
230- blob_versioned_hash. to_vec ( ) . into ( ) ,
231- ) ,
232- ethrex_l2_common:: calldata:: Value :: Bytes (
233- proof. proof_with_pub_values . public_values . to_vec ( ) . into ( ) ,
234- ) ,
235- ethrex_l2_common:: calldata:: Value :: Bytes (
236- proof. proof_with_pub_values . bytes ( ) . into ( ) ,
237- ) ,
238- ] ,
239- )
240- . map_err ( |e| AggregatedProofSubmissionError :: BuildingCalldata ( e. to_string ( ) ) ) ?;
193+ let calldata = match aggregated_proof {
194+ AlignedProof :: SP1 ( proof) => encode_calldata (
195+ "verifySP1(bytes32,bytes,bytes)" ,
196+ & [
197+ ethrex_l2_common:: calldata:: Value :: FixedBytes (
198+ blob_versioned_hash. to_vec ( ) . into ( ) ,
199+ ) ,
200+ ethrex_l2_common:: calldata:: Value :: Bytes (
201+ proof. proof_with_pub_values . public_values . to_vec ( ) . into ( ) ,
202+ ) ,
203+ ethrex_l2_common:: calldata:: Value :: Bytes (
204+ proof. proof_with_pub_values . bytes ( ) . into ( ) ,
205+ ) ,
206+ ] ,
207+ )
208+ . map_err ( |e| AggregatedProofSubmissionError :: BuildingCalldata ( e. to_string ( ) ) ) ?,
241209
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-
247- let tx = build_generic_tx (
248- & self . ethrex_eth_client ,
249- ethrex_common:: types:: TxType :: EIP4844 ,
250- self . proof_aggregation_service . address ( ) . 0 . 0 . into ( ) ,
251- self . ethrex_signer . address ( ) ,
252- calldata. into ( ) ,
253- Overrides {
254- blobs_bundle : Some ( blob_bundle) ,
255- gas_price_per_blob : Some ( gas_price_per_blob) ,
256- ..Default :: default ( )
257- } ,
258- )
259- . await
260- . map_err ( |e| AggregatedProofSubmissionError :: BuildingTx ( e. to_string ( ) ) ) ?;
261-
262- let tx_hash =
263- send_generic_transaction ( & self . ethrex_eth_client , tx, & self . ethrex_signer )
264- . await
265- . map_err ( |e| {
266- AggregatedProofSubmissionError :: SendVerifyAggregatedProofTransaction (
267- e. to_string ( ) ,
268- )
269- } ) ?;
270-
271- Ok ( tx_hash)
272- }
273210 AlignedProof :: Risc0 ( proof) => {
274211 let encoded_seal = encode_seal ( & proof. receipt ) . map_err ( |e| {
275212 AggregatedProofSubmissionError :: Risc0EncodingSeal ( e. to_string ( ) )
276213 } ) ?;
277214
278- let calldata = encode_calldata (
215+ encode_calldata (
279216 "verifyRisc0(bytes32,bytes,bytes)" ,
280217 & [
281218 ethrex_l2_common:: calldata:: Value :: FixedBytes (
@@ -287,40 +224,55 @@ impl ProofAggregator {
287224 ) ,
288225 ] ,
289226 )
290- . map_err ( |e| AggregatedProofSubmissionError :: BuildingCalldata ( e. to_string ( ) ) ) ?;
291-
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) ;
227+ . map_err ( |e| AggregatedProofSubmissionError :: BuildingCalldata ( e. to_string ( ) ) ) ?
228+ }
229+ } ;
296230
297- let tx = build_generic_tx (
298- & self . ethrex_eth_client ,
299- ethrex_common:: types:: TxType :: EIP4844 ,
300- self . proof_aggregation_service . address ( ) . 0 . 0 . into ( ) ,
301- self . ethrex_signer . address ( ) ,
302- calldata. into ( ) ,
303- Overrides {
304- blobs_bundle : Some ( blob_bundle) ,
305- gas_price_per_blob : Some ( gas_price_per_blob) ,
306- ..Default :: default ( )
307- } ,
231+ // ethrex auto calulates max_fee_per_gas and max_priority_fee_per_gas for us
232+ // but does not for max_fee_per_blob_gas but, so we need to estimate it ourselves
233+ let gas_price_per_blob = estimate_blob_gas ( & self . ethrex_eth_client , 20 )
234+ . await
235+ . map_err ( |e| {
236+ AggregatedProofSubmissionError :: SendVerifyAggregatedProofTransaction ( e. to_string ( ) )
237+ } ) ?;
238+ let gas_price = self
239+ . ethrex_eth_client
240+ . get_gas_price_with_extra ( 20 )
241+ . await
242+ . map_err ( |e| {
243+ AggregatedProofSubmissionError :: SendVerifyAggregatedProofTransaction ( e. to_string ( ) )
244+ } ) ?
245+ . try_into ( )
246+ . map_err ( |_| {
247+ AggregatedProofSubmissionError :: SendVerifyAggregatedProofTransaction (
248+ "Failed to convert gas price to u64" . into ( ) ,
308249 )
309- . await
310- . map_err ( |e| AggregatedProofSubmissionError :: BuildingTx ( e. to_string ( ) ) ) ?;
250+ } ) ?;
251+
252+ let tx = build_generic_tx (
253+ & self . ethrex_eth_client ,
254+ ethrex_common:: types:: TxType :: EIP4844 ,
255+ self . proof_aggregation_service . address ( ) . 0 . 0 . into ( ) ,
256+ self . ethrex_signer . address ( ) ,
257+ calldata. into ( ) ,
258+ Overrides {
259+ blobs_bundle : Some ( blob_bundle) ,
260+ gas_price_per_blob : Some ( gas_price_per_blob) ,
261+ max_fee_per_gas : Some ( gas_price) ,
262+ max_priority_fee_per_gas : Some ( gas_price) ,
263+ ..Default :: default ( )
264+ } ,
265+ )
266+ . await
267+ . map_err ( |e| AggregatedProofSubmissionError :: BuildingTx ( e. to_string ( ) ) ) ?;
311268
312- let tx_hash =
313- send_generic_transaction ( & self . ethrex_eth_client , tx, & self . ethrex_signer )
314- . await
315- . map_err ( |e| {
316- AggregatedProofSubmissionError :: SendVerifyAggregatedProofTransaction (
317- e. to_string ( ) ,
318- )
319- } ) ?;
269+ let tx_hash = send_generic_transaction ( & self . ethrex_eth_client , tx, & self . ethrex_signer )
270+ . await
271+ . map_err ( |e| {
272+ AggregatedProofSubmissionError :: SendVerifyAggregatedProofTransaction ( e. to_string ( ) )
273+ } ) ?;
320274
321- Ok ( tx_hash)
322- }
323- }
275+ Ok ( tx_hash)
324276 }
325277
326278 /// ### Blob capacity
0 commit comments