use fuels::prelude::*;
use regex::Regex;
use serde::Serialize;
use std::io::Write;
pub const MAINNET_MAX_GAS_PER_TX: u64 = 30_000_000;
pub const MAINNET_MAX_TX_SIZE: u64 = 112_640;
pub const MAINNET_CONTRACT_MAX_SIZE: u64 = 112_640;
pub const MAINNET_MAX_STORAGE_SLOTS: u64 = 1_760;
pub const MAINNET_GAS_PRICE_FACTOR: u64 = 1_150_000;
pub const MAINNET_GAS_PER_BYTE: u64 = 1;
pub const MAINNET_MAX_PREDICATE_LENGTH: u64 = 24_576;
pub const MAINNET_MAX_PREDICATE_DATA_LENGTH: u64 = 24_576;
pub const MAINNET_MAX_MESSAGE_DATA_LENGTH: u64 = 102_400;
pub const MAINNET_MAX_GAS_PER_PREDICATE: u64 = 1_000_000;
pub const MAINNET_BLOCK_GAS_LIMIT: u64 = 42_000_000;
pub fn bench_is_list_only() -> bool {
std::env::var("BENCH_LIST_ONLY").as_deref() == Ok("1")
}
pub fn bench_filter() -> Option<Regex> {
std::env::var("BENCH_FILTER")
.ok()
.map(|s| Regex::new(&s).expect("BENCH_FILTER: invalid regex"))
}
#[macro_export]
macro_rules! run_bench {
($desc:expr, $body:block) => {{
let desc: &str = $desc;
if $crate::bench::bench_is_list_only() {
println!("{desc}");
} else if $crate::bench::bench_filter()
.as_ref()
.map_or(true, |re| re.is_match(desc))
{
println!("Running {desc}...");
let __t0 = std::time::Instant::now();
$body
println!("Duration {:.2?}", __t0.elapsed());
}
}};
}
#[derive(Serialize, Clone, Debug)]
pub struct BenchmarkEntry {
pub name: String,
pub unit: String,
pub value: f64,
}
pub fn extract_gas_used<T>(
response: &fuels::programs::responses::CallResponse<T>,
) -> u64 {
response.tx_status.total_gas
}
pub fn apply_mainnet_consensus_params(chain_config: &mut ChainConfig) {
let cp = &mut chain_config.consensus_parameters;
let mut tx_params = cp.tx_params().with_max_gas_per_tx(MAINNET_MAX_GAS_PER_TX);
tx_params.set_max_size(MAINNET_MAX_TX_SIZE);
cp.set_tx_params(tx_params);
let contract_params = cp
.contract_params()
.with_contract_max_size(MAINNET_CONTRACT_MAX_SIZE)
.with_max_storage_slots(MAINNET_MAX_STORAGE_SLOTS);
cp.set_contract_params(contract_params);
let fee_params = cp
.fee_params()
.with_gas_price_factor(MAINNET_GAS_PRICE_FACTOR)
.with_gas_per_byte(MAINNET_GAS_PER_BYTE);
cp.set_fee_params(fee_params);
let predicate_params = cp
.predicate_params()
.with_max_predicate_length(MAINNET_MAX_PREDICATE_LENGTH)
.with_max_predicate_data_length(MAINNET_MAX_PREDICATE_DATA_LENGTH)
.with_max_message_data_length(MAINNET_MAX_MESSAGE_DATA_LENGTH)
.with_max_gas_per_predicate(MAINNET_MAX_GAS_PER_PREDICATE);
cp.set_predicate_params(predicate_params);
cp.set_block_gas_limit(MAINNET_BLOCK_GAS_LIMIT);
}
pub fn write_bench_results(gas: &[BenchmarkEntry], matches: &[BenchmarkEntry]) {
let gas_path = std::env::var("BENCH_OUTPUT_GAS")
.unwrap_or_else(|_| "benchmark-results-gas.json".to_string());
let mut f = std::fs::File::create(&gas_path).unwrap();
f.write_all(serde_json::to_string_pretty(gas).unwrap().as_bytes())
.unwrap();
let matches_path = std::env::var("BENCH_OUTPUT_MATCHES")
.unwrap_or_else(|_| "benchmark-results-matches.json".to_string());
let mut f = std::fs::File::create(&matches_path).unwrap();
f.write_all(serde_json::to_string_pretty(matches).unwrap().as_bytes())
.unwrap();
println!("\nGas results written to {gas_path}");
println!("Matches results written to {matches_path}");
}