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 alloy_transport::layers::RetryBackoffLayer;
11use reqwest::Url;
12use reth_node_core::args::BenchmarkArgs;
13use tracing::info;
14
15pub(crate) struct BenchContext {
21 pub(crate) auth_provider: RootProvider<AnyNetwork>,
23 pub(crate) block_provider: RootProvider<AnyNetwork>,
25 pub(crate) benchmark_mode: BenchMode,
28 pub(crate) next_block: u64,
30 pub(crate) is_optimism: bool,
32 pub(crate) use_reth_namespace: bool,
34 pub(crate) rlp_blocks: bool,
36}
37
38impl BenchContext {
39 pub(crate) async fn new(bench_args: &BenchmarkArgs, rpc_url: String) -> eyre::Result<Self> {
42 info!(target: "reth-bench", "Running benchmark using data from RPC URL: {}", rpc_url);
43
44 if let Some(output) = &bench_args.output {
46 if output.is_file() {
47 return Err(eyre::eyre!("Output path must be a directory"));
48 }
49 if !output.exists() {
51 std::fs::create_dir_all(output)?;
52 info!(target: "reth-bench", "Created output directory: {:?}", output);
53 }
54 }
55
56 let client = ClientBuilder::default()
58 .layer(RetryBackoffLayer::new(10, 800, u64::MAX))
59 .http(rpc_url.parse()?);
60 let block_provider = RootProvider::<AnyNetwork>::new(client);
61
62 let is_optimism = !block_provider
64 .get_code_at(address!("0x420000000000000000000000000000000000000F"))
65 .await?
66 .is_empty();
67
68 let auth_jwt = bench_args
70 .auth_jwtsecret
71 .clone()
72 .ok_or_else(|| eyre::eyre!("--jwt-secret must be provided for authenticated RPC"))?;
73
74 let jwt = std::fs::read_to_string(auth_jwt)?;
78 let jwt = JwtSecret::from_hex(jwt)?;
79
80 let auth_url = Url::parse(&bench_args.engine_rpc_url)?;
82
83 info!(target: "reth-bench", "Connecting to Engine RPC at {} for replay", auth_url);
85 let auth_transport = AuthenticatedTransportConnect::new(auth_url, jwt);
86 let client = ClientBuilder::default().connect_with(auth_transport).await?;
87 let auth_provider = RootProvider::<AnyNetwork>::new(client);
88
89 let (from, to) = if let Some(advance) = bench_args.advance {
98 if advance == 0 {
99 return Err(eyre::eyre!("--advance must be greater than 0"));
100 }
101
102 let head_block = auth_provider
103 .get_block_by_number(BlockNumberOrTag::Latest)
104 .await?
105 .ok_or_else(|| eyre::eyre!("Failed to fetch latest block for --advance"))?;
106 let head_number = head_block.header.number;
107 (Some(head_number), Some(head_number + advance))
108 } else if bench_args.from.is_none() && bench_args.to.is_some() {
109 let head_block = auth_provider
110 .get_block_by_number(BlockNumberOrTag::Latest)
111 .await?
112 .ok_or_else(|| eyre::eyre!("Failed to fetch latest block from engine"))?;
113 let head_number = head_block.header.number;
114 info!(target: "reth-bench", "No --from provided, derived from engine head: {}", head_number);
115 (Some(head_number), bench_args.to)
116 } else {
117 (bench_args.from, bench_args.to)
118 };
119
120 let latest_block = block_provider
123 .get_block_by_number(BlockNumberOrTag::Latest)
124 .full()
125 .await?
126 .ok_or_else(|| eyre::eyre!("Failed to fetch latest block from RPC"))?;
127 let mut benchmark_mode = BenchMode::new(from, to, latest_block.into_inner().number());
128
129 let first_block = match benchmark_mode {
130 BenchMode::Continuous(start) => {
131 block_provider.get_block_by_number(start.into()).full().await?.ok_or_else(|| {
132 eyre::eyre!("Failed to fetch block {} from RPC for continuous mode", start)
133 })?
134 }
135 BenchMode::Range(ref mut range) => {
136 match range.next() {
137 Some(block_number) => {
138 block_provider
140 .get_block_by_number(block_number.into())
141 .full()
142 .await?
143 .ok_or_else(|| {
144 eyre::eyre!("Failed to fetch block {} from RPC", block_number)
145 })?
146 }
147 None => {
148 return Err(eyre::eyre!(
149 "Benchmark mode range is empty, please provide a larger range"
150 ));
151 }
152 }
153 }
154 };
155
156 let next_block = first_block.header.number + 1;
157 let rlp_blocks = bench_args.rlp_blocks;
158 let use_reth_namespace = bench_args.reth_new_payload || rlp_blocks;
159 Ok(Self {
160 auth_provider,
161 block_provider,
162 benchmark_mode,
163 next_block,
164 is_optimism,
165 use_reth_namespace,
166 rlp_blocks,
167 })
168 }
169}