@@ -13,7 +13,7 @@ use crate::{
1313use alloy_provider:: Provider ;
1414use clap:: Parser ;
1515use csv:: Writer ;
16- use eyre:: Context ;
16+ use eyre:: { Context , OptionExt } ;
1717use reth_cli_runner:: CliContext ;
1818use reth_node_core:: args:: BenchmarkArgs ;
1919use std:: time:: { Duration , Instant } ;
@@ -26,6 +26,16 @@ pub struct Command {
2626 #[ arg( long, value_name = "RPC_URL" , verbatim_doc_comment) ]
2727 rpc_url : String ,
2828
29+ /// The size of the block buffer (channel capacity) for prefetching blocks from the RPC
30+ /// endpoint.
31+ #[ arg(
32+ long = "rpc-block-buffer-size" ,
33+ value_name = "RPC_BLOCK_BUFFER_SIZE" ,
34+ default_value = "20" ,
35+ verbatim_doc_comment
36+ ) ]
37+ rpc_block_buffer_size : usize ,
38+
2939 #[ command( flatten) ]
3040 benchmark : BenchmarkArgs ,
3141}
@@ -41,21 +51,43 @@ impl Command {
4151 is_optimism,
4252 } = BenchContext :: new ( & self . benchmark , self . rpc_url ) . await ?;
4353
44- let ( sender, mut receiver) = tokio:: sync:: mpsc:: channel ( 1000 ) ;
54+ let buffer_size = self . rpc_block_buffer_size ;
55+
56+ // Use a oneshot channel to propagate errors from the spawned task
57+ let ( error_sender, mut error_receiver) = tokio:: sync:: oneshot:: channel ( ) ;
58+ let ( sender, mut receiver) = tokio:: sync:: mpsc:: channel ( buffer_size) ;
59+
4560 tokio:: task:: spawn ( async move {
4661 while benchmark_mode. contains ( next_block) {
4762 let block_res = block_provider
4863 . get_block_by_number ( next_block. into ( ) )
4964 . full ( )
5065 . await
5166 . wrap_err_with ( || format ! ( "Failed to fetch block by number {next_block}" ) ) ;
52- let block = block_res. unwrap ( ) . unwrap ( ) ;
67+ let block = match block_res. and_then ( |opt| opt. ok_or_eyre ( "Block not found" ) ) {
68+ Ok ( block) => block,
69+ Err ( e) => {
70+ tracing:: error!( "Failed to fetch block {next_block}: {e}" ) ;
71+ let _ = error_sender. send ( e) ;
72+ break ;
73+ }
74+ } ;
5375 let header = block. header . clone ( ) ;
5476
55- let ( version, params) = block_to_new_payload ( block, is_optimism) . unwrap ( ) ;
77+ let ( version, params) = match block_to_new_payload ( block, is_optimism) {
78+ Ok ( result) => result,
79+ Err ( e) => {
80+ tracing:: error!( "Failed to convert block to new payload: {e}" ) ;
81+ let _ = error_sender. send ( e) ;
82+ break ;
83+ }
84+ } ;
5685
5786 next_block += 1 ;
58- sender. send ( ( header, version, params) ) . await . unwrap ( ) ;
87+ if let Err ( e) = sender. send ( ( header, version, params) ) . await {
88+ tracing:: error!( "Failed to send block data: {e}" ) ;
89+ break ;
90+ }
5991 }
6092 } ) ;
6193
@@ -96,6 +128,11 @@ impl Command {
96128 results. push ( ( row, new_payload_result) ) ;
97129 }
98130
131+ // Check if the spawned task encountered an error
132+ if let Ok ( error) = error_receiver. try_recv ( ) {
133+ return Err ( error) ;
134+ }
135+
99136 let ( gas_output_results, new_payload_results) : ( _ , Vec < NewPayloadResult > ) =
100137 results. into_iter ( ) . unzip ( ) ;
101138
0 commit comments