@@ -17,13 +17,23 @@ const BENCH_CONCURRENCY: &str = "64";
1717const MAX_INFLIGHT_PER_WORKER : & str = "96" ;
1818const SEED_ACCOUNTS : & str = "100000" ;
1919const SEED_INITIAL_BALANCE : & str = "1000000000000" ;
20+ const TRANSFER_REDUCER : & str = "transfer" ;
21+ const REDUCER_FUEL_METRIC : & str = "reducer_wasmtime_fuel_used" ;
22+ const REDUCER_FUEL_METRIC_PREFIX : & str = "reducer_wasmtime_fuel_used{" ;
23+ const REDUCER_FUEL_METRIC_TOTAL_PREFIX : & str = "reducer_wasmtime_fuel_used_total{" ;
24+ const MAX_FUEL_RATIO : f64 = 10.0 ;
2025
2126struct BenchmarkModule {
2227 label : & ' static str ,
2328 module_dir : & ' static str ,
2429 min_tps : f64 ,
2530}
2631
32+ struct BenchmarkResult {
33+ label : & ' static str ,
34+ transfer_fuel_total : f64 ,
35+ }
36+
2737const BENCHMARK_MODULES : & [ BenchmarkModule ] = & [
2838 BenchmarkModule {
2939 label : "TypeScript" ,
@@ -43,14 +53,26 @@ pub fn run() -> Result<()> {
4353 let cli_config_dir = tempfile:: tempdir ( ) . context ( "failed to create temporary CLI config directory" ) ?;
4454 let cli_config_path = cli_config_dir. path ( ) . join ( "config.toml" ) ;
4555
56+ let mut results = Vec :: with_capacity ( BENCHMARK_MODULES . len ( ) ) ;
4657 for module in BENCHMARK_MODULES {
47- run_module_benchmark ( module, & cli_path, & cli_config_path, & server. host_url ) ?;
58+ results. push ( run_module_benchmark (
59+ module,
60+ & cli_path,
61+ & cli_config_path,
62+ & server. host_url ,
63+ ) ?) ;
4864 }
65+ check_transfer_fuel_ratio ( & results) ?;
4966
5067 Ok ( ( ) )
5168}
5269
53- fn run_module_benchmark ( module : & BenchmarkModule , cli_path : & Path , config_path : & Path , server_url : & str ) -> Result < ( ) > {
70+ fn run_module_benchmark (
71+ module : & BenchmarkModule ,
72+ cli_path : & Path ,
73+ config_path : & Path ,
74+ server_url : & str ,
75+ ) -> Result < BenchmarkResult > {
5476 eprintln ! (
5577 "Running keynote benchmark against {} module ({})..." ,
5678 module. label, module. module_dir
@@ -60,7 +82,15 @@ fn run_module_benchmark(module: &BenchmarkModule, cli_path: &Path, config_path:
6082 generate_module_bindings ( module, cli_path, config_path) ?;
6183 seed_accounts ( cli_path, config_path, server_url) ?;
6284 let runs_dir = tempfile:: tempdir ( ) . context ( "failed to create temporary benchmark runs directory" ) ?;
85+ let transfer_fuel_before = transfer_fuel_total ( server_url) ?;
6386 run_benchmark ( module, server_url, runs_dir. path ( ) ) ?;
87+ let transfer_fuel_after = transfer_fuel_total ( server_url) ?;
88+ let transfer_fuel_total = transfer_fuel_after - transfer_fuel_before;
89+ ensure ! (
90+ transfer_fuel_total > 0.0 ,
91+ "{} keynote benchmark did not record any fuel for the {TRANSFER_REDUCER} reducer" ,
92+ module. label
93+ ) ;
6494
6595 let result_path = find_result_json ( runs_dir. path ( ) ) ?;
6696 let result_json = fs:: read_to_string ( & result_path)
@@ -79,12 +109,16 @@ fn run_module_benchmark(module: &BenchmarkModule, cli_path: &Path, config_path:
79109 }
80110
81111 println ! (
82- "Keynote perf check passed for {} module: throughput {tps:.0} TPS >= {:.0} TPS ({})" ,
112+ "Keynote perf check passed for {} module: throughput {tps:.0} TPS >= {:.0} TPS; \
113+ {TRANSFER_REDUCER} fuel total {transfer_fuel_total:.0} ({})",
83114 module. label,
84115 module. min_tps,
85116 result_path. display( )
86117 ) ;
87- Ok ( ( ) )
118+ Ok ( BenchmarkResult {
119+ label : module. label ,
120+ transfer_fuel_total,
121+ } )
88122}
89123
90124fn publish_module ( module : & BenchmarkModule , cli_path : & Path , config_path : & Path , server_url : & str ) -> Result < ( ) > {
@@ -214,3 +248,72 @@ fn result_tps(result_json: &str) -> Result<f64> {
214248 . and_then ( Value :: as_f64)
215249 . context ( "benchmark result JSON is missing results[0].res.tps" )
216250}
251+
252+ fn transfer_fuel_total ( server_url : & str ) -> Result < f64 > {
253+ let metrics_url = format ! ( "{}/v1/metrics" , server_url. trim_end_matches( '/' ) ) ;
254+ let metrics = reqwest:: blocking:: get ( & metrics_url)
255+ . with_context ( || format ! ( "failed to fetch metrics from {metrics_url}" ) ) ?
256+ . error_for_status ( )
257+ . with_context ( || format ! ( "metrics request to {metrics_url} failed" ) ) ?
258+ . text ( )
259+ . context ( "failed to read metrics response body" ) ?;
260+
261+ let transfer_label = format ! ( r#"reducer="{TRANSFER_REDUCER}""# ) ;
262+ let mut total = 0.0 ;
263+ for line in metrics. lines ( ) {
264+ if !is_reducer_fuel_metric_line ( line) || !line. contains ( & transfer_label) {
265+ continue ;
266+ }
267+ let value = line
268+ . split_whitespace ( )
269+ . nth ( 1 )
270+ . with_context ( || format ! ( "malformed {REDUCER_FUEL_METRIC} metric line: {line}" ) ) ?
271+ . parse :: < f64 > ( )
272+ . with_context ( || format ! ( "invalid {REDUCER_FUEL_METRIC} metric value in line: {line}" ) ) ?;
273+ total += value;
274+ }
275+ Ok ( total)
276+ }
277+
278+ fn is_reducer_fuel_metric_line ( line : & str ) -> bool {
279+ line. starts_with ( REDUCER_FUEL_METRIC_PREFIX ) || line. starts_with ( REDUCER_FUEL_METRIC_TOTAL_PREFIX )
280+ }
281+
282+ fn check_transfer_fuel_ratio ( results : & [ BenchmarkResult ] ) -> Result < ( ) > {
283+ ensure ! (
284+ results. len( ) == 2 ,
285+ "expected exactly two keynote benchmark results to compare fuel usage, got {}" ,
286+ results. len( )
287+ ) ;
288+ let [ first, second] = results else {
289+ unreachable ! ( "length was checked above" )
290+ } ;
291+
292+ let higher = first. transfer_fuel_total . max ( second. transfer_fuel_total ) ;
293+ let lower = first. transfer_fuel_total . min ( second. transfer_fuel_total ) ;
294+ ensure ! (
295+ lower > 0.0 ,
296+ "keynote benchmark fuel totals must be nonzero: {}={:.0}, {}={:.0}" ,
297+ first. label,
298+ first. transfer_fuel_total,
299+ second. label,
300+ second. transfer_fuel_total
301+ ) ;
302+
303+ let ratio = higher / lower;
304+ println ! (
305+ "Keynote transfer fuel comparison: {}={:.0}, {}={:.0}, relative difference {ratio:.2}x" ,
306+ first. label, first. transfer_fuel_total, second. label, second. transfer_fuel_total
307+ ) ;
308+ ensure ! (
309+ ratio < MAX_FUEL_RATIO ,
310+ "keynote benchmark transfer fuel totals differ by {ratio:.2}x, expected strictly less than {MAX_FUEL_RATIO}x: \
311+ {}={:.0}, {}={:.0}",
312+ first. label,
313+ first. transfer_fuel_total,
314+ second. label,
315+ second. transfer_fuel_total
316+ ) ;
317+
318+ Ok ( ( ) )
319+ }
0 commit comments