reth_bench/bench/
context.rs1use crate::{authenticated_transport::AuthenticatedTransportConnect, bench_mode::BenchMode};
5use alloy_eips::BlockNumberOrTag;
6use alloy_primitives::address;
7use alloy_provider::{network::AnyNetwork, Provider, RootProvider};
8use alloy_rpc_client::ClientBuilder;
9use alloy_rpc_types_engine::JwtSecret;
10use reqwest::Url;
11use reth_node_core::args::BenchmarkArgs;
12use tracing::info;
13
14pub(crate) struct BenchContext {
20 pub(crate) auth_provider: RootProvider<AnyNetwork>,
22 pub(crate) block_provider: RootProvider<AnyNetwork>,
24 pub(crate) benchmark_mode: BenchMode,
27 pub(crate) next_block: u64,
29 pub(crate) is_optimism: bool,
31}
32
33impl BenchContext {
34 pub(crate) async fn new(bench_args: &BenchmarkArgs, rpc_url: String) -> eyre::Result<Self> {
37 info!("Running benchmark using data from RPC URL: {}", rpc_url);
38
39 if let Some(output) = &bench_args.output {
41 if output.is_file() {
42 return Err(eyre::eyre!("Output path must be a directory"));
43 }
44 if !output.exists() {
46 std::fs::create_dir_all(output)?;
47 info!("Created output directory: {:?}", output);
48 }
49 }
50
51 let client = ClientBuilder::default().http(rpc_url.parse()?);
53 let block_provider = RootProvider::<AnyNetwork>::new(client);
54
55 let is_optimism = !block_provider
57 .get_code_at(address!("0x420000000000000000000000000000000000000F"))
58 .await?
59 .is_empty();
60
61 let auth_jwt = bench_args
63 .auth_jwtsecret
64 .clone()
65 .ok_or_else(|| eyre::eyre!("--jwt-secret must be provided for authenticated RPC"))?;
66
67 let jwt = std::fs::read_to_string(auth_jwt)?;
71 let jwt = JwtSecret::from_hex(jwt)?;
72
73 let auth_url = Url::parse(&bench_args.engine_rpc_url)?;
75
76 info!("Connecting to Engine RPC at {} for replay", auth_url);
78 let auth_transport = AuthenticatedTransportConnect::new(auth_url, jwt);
79 let client = ClientBuilder::default().connect_with(auth_transport).await?;
80 let auth_provider = RootProvider::<AnyNetwork>::new(client);
81
82 let (from, to) = if let Some(advance) = bench_args.advance {
89 if advance == 0 {
90 return Err(eyre::eyre!("--advance must be greater than 0"));
91 }
92
93 let head_block = auth_provider
94 .get_block_by_number(BlockNumberOrTag::Latest)
95 .await?
96 .ok_or_else(|| eyre::eyre!("Failed to fetch latest block for --advance"))?;
97 let head_number = head_block.header.number;
98 (Some(head_number), Some(head_number + advance))
99 } else {
100 (bench_args.from, bench_args.to)
101 };
102
103 let mut benchmark_mode = BenchMode::new(from, to)?;
106
107 let first_block = match benchmark_mode {
108 BenchMode::Continuous => {
109 block_provider.get_block_by_number(BlockNumberOrTag::Latest).full().await?.unwrap()
111 }
112 BenchMode::Range(ref mut range) => {
113 match range.next() {
114 Some(block_number) => {
115 block_provider
117 .get_block_by_number(block_number.into())
118 .full()
119 .await?
120 .unwrap()
121 }
122 None => {
123 return Err(eyre::eyre!(
124 "Benchmark mode range is empty, please provide a larger range"
125 ));
126 }
127 }
128 }
129 };
130
131 let next_block = first_block.header.number + 1;
132 Ok(Self { auth_provider, block_provider, benchmark_mode, next_block, is_optimism })
133 }
134}