@@ -25,14 +25,13 @@ use signet_zenith::{
2525 Zenith :: { self , IncorrectHostBlock } ,
2626} ;
2727use std:: time:: { Instant , UNIX_EPOCH } ;
28- use tokio:: { sync:: mpsc, task:: JoinHandle } ;
28+ use tokio:: {
29+ sync:: mpsc:: { self } ,
30+ task:: JoinHandle ,
31+ } ;
32+ use trevm:: revm:: context:: BlockEnv ;
2933
30- /// Base maximum fee per gas to use as a starting point for retry bumps
31- pub const BASE_FEE_PER_GAS : u128 = 10 * GWEI_TO_WEI as u128 ;
32- /// Base max priority fee per gas to use as a starting point for retry bumps
33- pub const BASE_MAX_PRIORITY_FEE_PER_GAS : u128 = 2 * GWEI_TO_WEI as u128 ;
34- /// Base maximum fee per blob gas to use as a starting point for retry bumps
35- pub const BASE_MAX_FEE_PER_BLOB_GAS : u128 = GWEI_TO_WEI as u128 ;
34+ use super :: block:: sim:: SimResult ;
3635
3736macro_rules! spawn_provider_send {
3837 ( $provider: expr, $tx: expr) => {
@@ -95,7 +94,7 @@ impl SubmitTask {
9594 } )
9695 }
9796
98- /// Builds blob transaction and encodes the sidecar for it from the provided header and signature values
97+ /// Encodes the sidecar and then builds the 4844 blob transaction from the provided header and signature values.
9998 fn build_blob_tx (
10099 & self ,
101100 fills : Vec < FillPermit2 > ,
@@ -118,8 +117,9 @@ impl SubmitTask {
118117 retry_count : usize ,
119118 resp : & SignResponse ,
120119 block : & BuiltBlock ,
120+ block_env : & BlockEnv ,
121121 ) -> eyre:: Result < ControlFlow > {
122- let tx = self . prepare_tx ( retry_count, resp, block) . await ?;
122+ let tx = self . prepare_tx ( retry_count, resp, block, block_env ) . await ?;
123123
124124 self . send_transaction ( resp, tx) . await
125125 }
@@ -131,9 +131,11 @@ impl SubmitTask {
131131 retry_count : usize ,
132132 resp : & SignResponse ,
133133 block : & BuiltBlock ,
134+ block_env : & BlockEnv ,
134135 ) -> Result < TransactionRequest , eyre:: Error > {
135136 // Create the transaction request with the signature values
136- let tx: TransactionRequest = self . new_tx_request ( retry_count, resp, block) . await ?;
137+ let tx: TransactionRequest =
138+ self . new_tx_request ( retry_count, resp, block, block_env) . await ?;
137139
138140 // Simulate the transaction with a call to the host provider and report any errors
139141 if let Err ( err) = self . sim_with_call ( & tx) . await {
@@ -191,6 +193,7 @@ impl SubmitTask {
191193 retry_count : usize ,
192194 resp : & SignResponse ,
193195 block : & BuiltBlock ,
196+ block_env : & BlockEnv ,
194197 ) -> Result < TransactionRequest , eyre:: Error > {
195198 // manually retrieve nonce
196199 let nonce =
@@ -200,14 +203,8 @@ impl SubmitTask {
200203 // Extract the signature components from the response
201204 let ( v, r, s) = extract_signature_components ( & resp. sig ) ;
202205
203- // Calculate gas limits based on retry attempts
204206 let ( max_fee_per_gas, max_priority_fee_per_gas, max_fee_per_blob_gas) =
205- calculate_gas_limits (
206- retry_count,
207- BASE_FEE_PER_GAS ,
208- BASE_MAX_PRIORITY_FEE_PER_GAS ,
209- BASE_MAX_FEE_PER_BLOB_GAS ,
210- ) ;
207+ calculate_gas ( retry_count, block_env) ;
211208
212209 // Build the block header
213210 let header: BlockHeader = BlockHeader {
@@ -289,6 +286,7 @@ impl SubmitTask {
289286 & self ,
290287 retry_count : usize ,
291288 block : & BuiltBlock ,
289+ block_env : & BlockEnv ,
292290 ) -> eyre:: Result < ControlFlow > {
293291 info ! ( retry_count, txns = block. tx_count( ) , "handling inbound block" ) ;
294292 let Ok ( sig_request) = self . construct_sig_request ( block) . await . inspect_err ( |e| {
@@ -305,13 +303,14 @@ impl SubmitTask {
305303
306304 let signed = self . quincey . get_signature ( & sig_request) . await ?;
307305
308- self . submit_transaction ( retry_count, & signed, block) . await
306+ self . submit_transaction ( retry_count, & signed, block, block_env ) . await
309307 }
310308
311309 /// Handles the retry logic for the inbound block.
312310 async fn retrying_handle_inbound (
313311 & self ,
314312 block : & BuiltBlock ,
313+ block_env : & BlockEnv ,
315314 retry_limit : usize ,
316315 ) -> eyre:: Result < ControlFlow > {
317316 let mut retries = 0 ;
@@ -325,7 +324,8 @@ impl SubmitTask {
325324 let span = debug_span ! ( "SubmitTask::retrying_handle_inbound" , retries) ;
326325
327326 let inbound_result =
328- match self . handle_inbound ( retries, block) . instrument ( span. clone ( ) ) . await {
327+ match self . handle_inbound ( retries, block, block_env) . instrument ( span. clone ( ) ) . await
328+ {
329329 Ok ( control_flow) => control_flow,
330330 Err ( err) => {
331331 // Delay until next slot if we get a 403 error
@@ -403,66 +403,86 @@ impl SubmitTask {
403403 /// Task future for the submit task
404404 /// NB: This task assumes that the simulator will only send it blocks for
405405 /// slots that it's assigned.
406- async fn task_future ( self , mut inbound : mpsc:: UnboundedReceiver < BuiltBlock > ) {
406+ async fn task_future ( self , mut inbound : mpsc:: UnboundedReceiver < SimResult > ) {
407407 // Holds a reference to the last block we attempted to submit
408408 let mut last_block_attempted: u64 = 0 ;
409409
410410 loop {
411411 // Wait to receive a new block
412- let Some ( block ) = inbound. recv ( ) . await else {
412+ let Some ( result ) = inbound. recv ( ) . await else {
413413 debug ! ( "upstream task gone" ) ;
414414 break ;
415415 } ;
416- debug ! ( block_number = block. block_number( ) , ?block, "submit channel received block" ) ;
416+
417+ debug ! ( block_number = result. block. block_number( ) , "submit channel received block" ) ;
417418
418419 // Only attempt each block number once
419- if block. block_number ( ) == last_block_attempted {
420+ if result . block . block_number ( ) == last_block_attempted {
420421 debug ! ( "block number is unchanged from last attempt - skipping" ) ;
421422 continue ;
422423 }
423424
424425 // This means we have encountered a new block, so reset the last block attempted
425- last_block_attempted = block. block_number ( ) ;
426+ last_block_attempted = result . block . block_number ( ) ;
426427 debug ! ( last_block_attempted, "resetting last block attempted" ) ;
427428
428- if self . retrying_handle_inbound ( & block, 3 ) . await . is_err ( ) {
429+ if self . retrying_handle_inbound ( & result . block , & result . env , 3 ) . await . is_err ( ) {
429430 debug ! ( "error handling inbound block" ) ;
430431 continue ;
431432 } ;
432433 }
433434 }
434435
435436 /// Spawns the in progress block building task
436- pub fn spawn ( self ) -> ( mpsc:: UnboundedSender < BuiltBlock > , JoinHandle < ( ) > ) {
437- let ( sender, inbound) = mpsc:: unbounded_channel ( ) ;
437+ pub fn spawn ( self ) -> ( mpsc:: UnboundedSender < SimResult > , JoinHandle < ( ) > ) {
438+ let ( sender, inbound) = mpsc:: unbounded_channel :: < SimResult > ( ) ;
438439 let handle = tokio:: spawn ( self . task_future ( inbound) ) ;
439440
440441 ( sender, handle)
441442 }
442443}
443444
444- // Returns gas parameters based on retry counts.
445- fn calculate_gas_limits (
445+ /// Calculates gas parameters based on the block environment and retry count.
446+ fn calculate_gas ( retry_count : usize , block_env : & BlockEnv ) -> ( u128 , u128 , u128 ) {
447+ if let Some ( blob_excess) = block_env. blob_excess_gas_and_price {
448+ debug ! ( ?blob_excess, "using blob excess gas and price from block env" ) ;
449+ let blob_basefee = blob_excess. blob_gasprice ;
450+
451+ let ( max_fee_per_gas, max_priority_fee_per_gas, max_fee_per_blob_gas) =
452+ bump_gas_from_retries ( retry_count, block_env. basefee , blob_basefee) ;
453+
454+ ( max_fee_per_gas as u128 , max_priority_fee_per_gas as u128 , max_fee_per_blob_gas as u128 )
455+ } else {
456+ warn ! ( "no blob excess gas and price in block env, using defaults" ) ;
457+ let ( max_fee_per_gas, max_priority_fee_per_gas, max_fee_per_blob_gas) =
458+ bump_gas_from_retries ( retry_count, block_env. basefee , 500 ) ;
459+
460+ ( max_fee_per_gas as u128 , max_priority_fee_per_gas as u128 , max_fee_per_blob_gas)
461+ }
462+ }
463+
464+ /// Bumps the gas parameters based on the retry count, base fee, and blob base fee.
465+ pub fn bump_gas_from_retries (
446466 retry_count : usize ,
447- base_max_fee_per_gas : u128 ,
448- base_max_priority_fee_per_gas : u128 ,
449- base_max_fee_per_blob_gas : u128 ,
450- ) -> ( u128 , u128 , u128 ) {
451- let bump_multiplier = 1150u128 . pow ( retry_count as u32 ) ; // 15% bump
452- let blob_bump_multiplier = 2000u128 . pow ( retry_count as u32 ) ; // 100% bump (double each time) for blob gas
453- let bump_divisor = 1000u128 . pow ( retry_count as u32 ) ;
454-
455- let max_fee_per_gas = base_max_fee_per_gas * bump_multiplier / bump_divisor;
456- let max_priority_fee_per_gas = base_max_priority_fee_per_gas * bump_multiplier / bump_divisor;
457- let max_fee_per_blob_gas = base_max_fee_per_blob_gas * blob_bump_multiplier / bump_divisor;
467+ basefee : u64 ,
468+ blob_basefee : u128 ,
469+ ) -> ( u64 , u64 , u128 ) {
470+ const PRIORITY_FEE_BASE : u64 = 2 * GWEI_TO_WEI ;
471+ const BASE_MULTIPLIER : u64 = 2 ;
472+ const BLOB_MULTIPLIER : u128 = 2 ;
473+
474+ // Increase priority fee by 20% per retry
475+ let priority_fee =
476+ PRIORITY_FEE_BASE * ( 12u64 . pow ( retry_count as u32 ) / 10u64 . pow ( retry_count as u32 ) ) ;
477+
478+ // Max fee includes basefee + priority + headroom (double basefee, etc.)
479+ let max_fee_per_gas = basefee * BASE_MULTIPLIER + priority_fee;
480+ let max_fee_per_blob_gas = blob_basefee * BLOB_MULTIPLIER * ( retry_count as u128 + 1 ) ;
458481
459482 debug ! (
460483 retry_count,
461- max_fee_per_gas,
462- max_priority_fee_per_gas,
463- max_fee_per_blob_gas,
464- "calculated bumped gas parameters"
484+ max_fee_per_gas, priority_fee, max_fee_per_blob_gas, "calculated bumped gas parameters"
465485 ) ;
466486
467- ( max_fee_per_gas, max_priority_fee_per_gas , max_fee_per_blob_gas)
487+ ( max_fee_per_gas, priority_fee , max_fee_per_blob_gas)
468488}
0 commit comments