reth_bench/bench/
helpers.rs1use alloy_eips::{eip7928::BlockAccessList, BlockNumberOrTag};
4use alloy_provider::{network::AnyNetwork, Provider, RootProvider};
5use eyre::Result;
6use std::{
7 io::{BufReader, Read},
8 time::Duration,
9};
10
11pub(crate) fn read_input(path: Option<&str>) -> Result<String> {
13 Ok(match path {
14 Some(path) => reth_fs_util::read_to_string(path)?,
15 None => String::from_utf8(
16 BufReader::new(std::io::stdin()).bytes().collect::<Result<Vec<_>, _>>()?,
17 )?,
18 })
19}
20
21pub(crate) fn load_jwt_secret(jwt_secret: Option<&str>) -> Result<Option<String>> {
23 match jwt_secret {
24 Some(secret) => {
25 match std::fs::read_to_string(secret) {
27 Ok(contents) => Ok(Some(contents.trim().to_string())),
28 Err(_) => Ok(Some(secret.to_string())),
30 }
31 }
32 None => Ok(None),
33 }
34}
35
36pub(crate) fn parse_gas_limit(s: &str) -> eyre::Result<u64> {
40 let s = s.trim();
41 if s.is_empty() {
42 return Err(eyre::eyre!("empty value"));
43 }
44
45 let (num_str, multiplier) = if let Some(prefix) = s.strip_suffix(['G', 'g']) {
46 (prefix, 1_000_000_000u64)
47 } else if let Some(prefix) = s.strip_suffix(['M', 'm']) {
48 (prefix, 1_000_000u64)
49 } else if let Some(prefix) = s.strip_suffix(['K', 'k']) {
50 (prefix, 1_000u64)
51 } else {
52 (s, 1u64)
53 };
54
55 let base: u64 = num_str.trim().parse()?;
56 base.checked_mul(multiplier).ok_or_else(|| eyre::eyre!("value overflow"))
57}
58
59pub(crate) fn parse_duration(s: &str) -> eyre::Result<Duration> {
64 match humantime::parse_duration(s) {
65 Ok(d) => Ok(d),
66 Err(_) => {
67 let millis: u64 =
68 s.trim().parse().map_err(|_| eyre::eyre!("invalid duration: {s:?}"))?;
69 Ok(Duration::from_millis(millis))
70 }
71 }
72}
73
74pub(crate) async fn fetch_block_access_list(
76 provider: &RootProvider<AnyNetwork>,
77 block_number: u64,
78) -> eyre::Result<BlockAccessList> {
79 provider
80 .client()
81 .request("eth_getBlockAccessListByBlockNumber", (BlockNumberOrTag::Number(block_number),))
82 .await
83 .map_err(Into::into)
84 .and_then(|block_access_list: Option<BlockAccessList>| {
85 block_access_list.ok_or_else(|| eyre::eyre!("BAL not found for block {block_number}"))
86 })
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_parse_gas_limit_plain_number() {
95 assert_eq!(parse_gas_limit("30000000").unwrap(), 30_000_000);
96 assert_eq!(parse_gas_limit("1").unwrap(), 1);
97 assert_eq!(parse_gas_limit("0").unwrap(), 0);
98 }
99
100 #[test]
101 fn test_parse_gas_limit_k_suffix() {
102 assert_eq!(parse_gas_limit("1K").unwrap(), 1_000);
103 assert_eq!(parse_gas_limit("30k").unwrap(), 30_000);
104 assert_eq!(parse_gas_limit("100K").unwrap(), 100_000);
105 }
106
107 #[test]
108 fn test_parse_gas_limit_m_suffix() {
109 assert_eq!(parse_gas_limit("1M").unwrap(), 1_000_000);
110 assert_eq!(parse_gas_limit("30m").unwrap(), 30_000_000);
111 assert_eq!(parse_gas_limit("100M").unwrap(), 100_000_000);
112 }
113
114 #[test]
115 fn test_parse_gas_limit_g_suffix() {
116 assert_eq!(parse_gas_limit("1G").unwrap(), 1_000_000_000);
117 assert_eq!(parse_gas_limit("2g").unwrap(), 2_000_000_000);
118 assert_eq!(parse_gas_limit("10G").unwrap(), 10_000_000_000);
119 }
120
121 #[test]
122 fn test_parse_gas_limit_with_whitespace() {
123 assert_eq!(parse_gas_limit(" 1G ").unwrap(), 1_000_000_000);
124 assert_eq!(parse_gas_limit("2 M").unwrap(), 2_000_000);
125 }
126
127 #[test]
128 fn test_parse_gas_limit_errors() {
129 assert!(parse_gas_limit("").is_err());
130 assert!(parse_gas_limit("abc").is_err());
131 assert!(parse_gas_limit("G").is_err());
132 assert!(parse_gas_limit("-1G").is_err());
133 }
134
135 #[test]
136 fn test_parse_duration_with_unit() {
137 assert_eq!(parse_duration("100ms").unwrap(), Duration::from_millis(100));
138 assert_eq!(parse_duration("2s").unwrap(), Duration::from_secs(2));
139 assert_eq!(parse_duration("1m").unwrap(), Duration::from_secs(60));
140 }
141
142 #[test]
143 fn test_parse_duration_bare_millis() {
144 assert_eq!(parse_duration("400").unwrap(), Duration::from_millis(400));
145 assert_eq!(parse_duration("0").unwrap(), Duration::from_millis(0));
146 assert_eq!(parse_duration("1000").unwrap(), Duration::from_millis(1000));
147 }
148
149 #[test]
150 fn test_parse_duration_errors() {
151 assert!(parse_duration("abc").is_err());
152 assert!(parse_duration("").is_err());
153 }
154}