1use fuels::prelude::*;
4use regex::Regex;
5use serde::Serialize;
6use std::io::Write;
7
8pub const MAINNET_MAX_GAS_PER_TX: u64 = 30_000_000;
17pub const MAINNET_MAX_TX_SIZE: u64 = 112_640;
18
19pub const MAINNET_CONTRACT_MAX_SIZE: u64 = 112_640;
21pub const MAINNET_MAX_STORAGE_SLOTS: u64 = 1_760;
22
23pub const MAINNET_GAS_PRICE_FACTOR: u64 = 1_150_000;
25pub const MAINNET_GAS_PER_BYTE: u64 = 1;
26
27pub const MAINNET_MAX_PREDICATE_LENGTH: u64 = 24_576;
29pub const MAINNET_MAX_PREDICATE_DATA_LENGTH: u64 = 24_576;
30pub const MAINNET_MAX_MESSAGE_DATA_LENGTH: u64 = 102_400;
31pub const MAINNET_MAX_GAS_PER_PREDICATE: u64 = 1_000_000;
32
33pub const MAINNET_BLOCK_GAS_LIMIT: u64 = 42_000_000;
35
36pub fn bench_is_list_only() -> bool {
40 std::env::var("BENCH_LIST_ONLY").as_deref() == Ok("1")
41}
42
43pub fn bench_filter() -> Option<Regex> {
46 std::env::var("BENCH_FILTER")
47 .ok()
48 .map(|s| Regex::new(&s).expect("BENCH_FILTER: invalid regex"))
49}
50
51#[macro_export]
56macro_rules! run_bench {
57 ($desc:expr, $body:block) => {{
58 let desc: &str = $desc;
59 if $crate::bench::bench_is_list_only() {
60 println!("{desc}");
61 } else if $crate::bench::bench_filter()
62 .as_ref()
63 .map_or(true, |re| re.is_match(desc))
64 {
65 println!("Running {desc}...");
66 let __t0 = std::time::Instant::now();
67 $body
68 println!("Duration {:.2?}", __t0.elapsed());
69 }
70 }};
71}
72
73#[derive(Serialize, Clone, Debug)]
75pub struct BenchmarkEntry {
76 pub name: String,
77 pub unit: String,
78 pub value: f64,
79}
80
81pub fn extract_gas_used<T>(
83 response: &fuels::programs::responses::CallResponse<T>,
84) -> u64 {
85 response.tx_status.total_gas
86}
87
88pub fn apply_mainnet_consensus_params(chain_config: &mut ChainConfig) {
92 let cp = &mut chain_config.consensus_parameters;
93
94 let mut tx_params = cp.tx_params().with_max_gas_per_tx(MAINNET_MAX_GAS_PER_TX);
95 tx_params.set_max_size(MAINNET_MAX_TX_SIZE);
96 cp.set_tx_params(tx_params);
97
98 let contract_params = cp
99 .contract_params()
100 .with_contract_max_size(MAINNET_CONTRACT_MAX_SIZE)
101 .with_max_storage_slots(MAINNET_MAX_STORAGE_SLOTS);
102 cp.set_contract_params(contract_params);
103
104 let fee_params = cp
105 .fee_params()
106 .with_gas_price_factor(MAINNET_GAS_PRICE_FACTOR)
107 .with_gas_per_byte(MAINNET_GAS_PER_BYTE);
108 cp.set_fee_params(fee_params);
109
110 let predicate_params = cp
111 .predicate_params()
112 .with_max_predicate_length(MAINNET_MAX_PREDICATE_LENGTH)
113 .with_max_predicate_data_length(MAINNET_MAX_PREDICATE_DATA_LENGTH)
114 .with_max_message_data_length(MAINNET_MAX_MESSAGE_DATA_LENGTH)
115 .with_max_gas_per_predicate(MAINNET_MAX_GAS_PER_PREDICATE);
116 cp.set_predicate_params(predicate_params);
117
118 cp.set_block_gas_limit(MAINNET_BLOCK_GAS_LIMIT);
119}
120
121pub fn write_bench_results(gas: &[BenchmarkEntry], matches: &[BenchmarkEntry]) {
130 let gas_path = std::env::var("BENCH_OUTPUT_GAS")
131 .unwrap_or_else(|_| "benchmark-results-gas.json".to_string());
132 let mut f = std::fs::File::create(&gas_path).unwrap();
133 f.write_all(serde_json::to_string_pretty(gas).unwrap().as_bytes())
134 .unwrap();
135
136 let matches_path = std::env::var("BENCH_OUTPUT_MATCHES")
137 .unwrap_or_else(|_| "benchmark-results-matches.json".to_string());
138 let mut f = std::fs::File::create(&matches_path).unwrap();
139 f.write_all(serde_json::to_string_pretty(matches).unwrap().as_bytes())
140 .unwrap();
141
142 println!("\nGas results written to {gas_path}");
143 println!("Matches results written to {matches_path}");
144}