From 20ba16ee4713115fa3cfbd8123e459dcf01f5bfb Mon Sep 17 00:00:00 2001 From: Richard Patel Date: Fri, 27 Feb 2026 21:08:33 +0000 Subject: [PATCH] Fix firedancer-dev bench startup crash - Enable sandbox when watch is disabled - Add support for 'firedancer-dev mem --topo bench' - Fix segfault on startup - Work around invalid RPC tile responses on startup (status 500) --- src/app/fdctl/main.c | 2 - src/app/fddev/commands/bench.c | 4 +- src/app/firedancer-dev/commands/bench.c | 10 +---- src/app/firedancer/main.c | 2 - src/app/shared/commands/monitor/monitor.c | 1 - src/app/shared/fd_action.h | 1 + src/app/shared_dev/commands/bench/bench.c | 40 +++++++++++++------ src/app/shared_dev/commands/bench/bench.h | 4 +- src/app/shared_dev/commands/bench/fd_bencho.c | 4 +- src/app/shared_dev/commands/load.c | 1 - 10 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/app/fdctl/main.c b/src/app/fdctl/main.c index 0589b27490f..5e4ec8ea5c2 100644 --- a/src/app/fdctl/main.c +++ b/src/app/fdctl/main.c @@ -149,7 +149,6 @@ add_bench_topo( fd_topo_t * topo, uint send_to_ip_addr, ushort rpc_port, uint rpc_ip_addr, - int no_quic, int reserve_agave_cores ) { (void)topo; (void)affinity; @@ -164,6 +163,5 @@ add_bench_topo( fd_topo_t * topo, (void)send_to_ip_addr; (void)rpc_port; (void)rpc_ip_addr; - (void)no_quic; (void)reserve_agave_cores; } diff --git a/src/app/fddev/commands/bench.c b/src/app/fddev/commands/bench.c index 58d6cb5f19f..9203e4df5e1 100644 --- a/src/app/fddev/commands/bench.c +++ b/src/app/fddev/commands/bench.c @@ -20,7 +20,8 @@ agave_thread_main( void * _args ) { void fddev_bench_cmd_fn( args_t * args, config_t * config ) { - bench_cmd_fn( args, config, 0 ); + args->load.no_watch = 1; + bench_cmd_fn( args, config ); pthread_t agave; pthread_create( &agave, NULL, agave_thread_main, (void *)config ); @@ -32,6 +33,7 @@ fddev_bench_cmd_fn( args_t * args, action_t fd_action_bench = { .name = "bench", .args = bench_cmd_args, + .topo = bench_topo, .fn = fddev_bench_cmd_fn, .perm = dev_cmd_perm, .is_local_cluster = 1, diff --git a/src/app/firedancer-dev/commands/bench.c b/src/app/firedancer-dev/commands/bench.c index 1a66a662d8b..ef5a47dc69e 100644 --- a/src/app/firedancer-dev/commands/bench.c +++ b/src/app/firedancer-dev/commands/bench.c @@ -3,16 +3,10 @@ #include -static void -bench_cmd_topo( config_t * config ) { - config->development.sandbox = 0; - config->development.no_clone = 1; -} - void firedancer_dev_bench_cmd_fn( args_t * args, config_t * config ) { - bench_cmd_fn( args, config, 1 ); + bench_cmd_fn( args, config ); /* Sleep parent thread forever, Ctrl+C will terminate. */ for(;;) pause(); @@ -21,9 +15,9 @@ firedancer_dev_bench_cmd_fn( args_t * args, action_t fd_action_bench = { .name = "bench", .args = bench_cmd_args, + .topo = bench_topo, .fn = firedancer_dev_bench_cmd_fn, .perm = dev_cmd_perm, - .topo = bench_cmd_topo, .is_local_cluster = 1, .description = "Test validator TPS benchmark" }; diff --git a/src/app/firedancer/main.c b/src/app/firedancer/main.c index 33e84f4bc74..d338b8f284a 100644 --- a/src/app/firedancer/main.c +++ b/src/app/firedancer/main.c @@ -240,7 +240,6 @@ add_bench_topo( fd_topo_t * topo, uint send_to_ip_addr, ushort rpc_port, uint rpc_ip_addr, - int no_quic, int reserve_agave_cores ) { (void)topo; (void)affinity; @@ -255,6 +254,5 @@ add_bench_topo( fd_topo_t * topo, (void)send_to_ip_addr; (void)rpc_port; (void)rpc_ip_addr; - (void)no_quic; (void)reserve_agave_cores; } diff --git a/src/app/shared/commands/monitor/monitor.c b/src/app/shared/commands/monitor/monitor.c index 35c20a00b10..091feda8784 100644 --- a/src/app/shared/commands/monitor/monitor.c +++ b/src/app/shared/commands/monitor/monitor.c @@ -515,7 +515,6 @@ monitor_cmd_fn( args_t * args, 0U, 0, 0U, - 1, !config->is_firedancer ); } diff --git a/src/app/shared/fd_action.h b/src/app/shared/fd_action.h index 2cc14a16666..34e53f500af 100644 --- a/src/app/shared/fd_action.h +++ b/src/app/shared/fd_action.h @@ -103,6 +103,7 @@ union fdctl_args { ulong benchg; ulong benchs; int no_quic; + int no_watch; int transaction_mode; float contending_fraction; float cu_price_spread; diff --git a/src/app/shared_dev/commands/bench/bench.c b/src/app/shared_dev/commands/bench/bench.c index 2b7f0167658..9e5500640a6 100644 --- a/src/app/shared_dev/commands/bench/bench.c +++ b/src/app/shared_dev/commands/bench/bench.c @@ -1,4 +1,5 @@ #define _GNU_SOURCE +#include "bench.h" #include "../../../shared/commands/configure/configure.h" #include "../../../shared/commands/run/run.h" @@ -32,7 +33,8 @@ void bench_cmd_args( int * pargc, char *** pargv, args_t * args ) { - args->load.no_quic = fd_env_strip_cmdline_contains( pargc, pargv, "--no-quic" ); + args->load.no_quic = fd_env_strip_cmdline_contains( pargc, pargv, "--no-quic" ); + args->load.no_watch = fd_env_strip_cmdline_contains( pargc, pargv, "--no-watch" ); } void @@ -49,7 +51,6 @@ add_bench_topo( fd_topo_t * topo, uint send_to_ip_addr, ushort rpc_port, uint rpc_ip_addr, - int no_quic, int reserve_agave_cores ) { fd_topob_wksp( topo, "bench" ); @@ -101,7 +102,6 @@ add_bench_topo( fd_topo_t * topo, benchs->benchs.send_to_ip_addr = send_to_ip_addr; benchs->benchs.send_to_port = send_to_port; benchs->benchs.conn_cnt = conn_cnt; - benchs->benchs.no_quic = no_quic; } fd_topob_tile_out( topo, "bencho", 0UL, "bencho_out", 0UL ); @@ -123,13 +123,11 @@ add_bench_topo( fd_topo_t * topo, extern int * fd_log_private_shared_lock; void -bench_cmd_fn( args_t * args, - config_t * config, - int watch ) { +fd_topo_initialize( config_t * config ); - ushort dest_port = fd_ushort_if( args->load.no_quic, - config->tiles.quic.regular_transaction_listen_port, - config->tiles.quic.quic_transaction_listen_port ); +void +bench_topo( config_t * config ) { + fd_topo_initialize( config ); ushort rpc_port; uint rpc_ip_addr; @@ -166,12 +164,26 @@ bench_cmd_fn( args_t * args, config->development.genesis.fund_initial_accounts, 0, 0.0f, 0.0f, config->layout.quic_tile_count, - dest_port, + config->tiles.quic.quic_transaction_listen_port, config->net.ip_addr, rpc_port, rpc_ip_addr, - args->load.no_quic, !config->is_firedancer ); +} + +void +bench_cmd_fn( args_t * args, + config_t * config ) { + + if( args->load.no_quic ) { + ushort port = config->tiles.quic.regular_transaction_listen_port; + ulong benchs_tile_cnt = fd_topo_tile_name_cnt( &config->topo, "benchs" ); + for( ulong i=0UL; itopo.tiles[ fd_topo_find_tile( &config->topo, "benchs", i ) ]; + benchs->benchs.no_quic = 1; + benchs->benchs.send_to_port = port; + } + } args_t configure_args = { .configure.command = CONFIGURE_CMD_INIT, @@ -192,7 +204,11 @@ bench_cmd_fn( args_t * args, fd_log_private_shared_lock[ 1 ] = 0; fd_topo_join_workspaces( &config->topo, FD_SHMEM_JOIN_MODE_READ_WRITE, FD_TOPO_CORE_DUMP_LEVEL_DISABLED ); - if( watch ) { + if( !args->load.no_watch ) { + /* watch incompatible with sandbox */ + config->development.sandbox = 0; + config->development.no_clone = 1; + int pipefd[2]; if( FD_UNLIKELY( pipe2( pipefd, O_NONBLOCK ) ) ) FD_LOG_ERR(( "pipe2() failed (%i-%s)", errno, fd_io_strerror( errno ) )); diff --git a/src/app/shared_dev/commands/bench/bench.h b/src/app/shared_dev/commands/bench/bench.h index a0373596b6a..98c8629db91 100644 --- a/src/app/shared_dev/commands/bench/bench.h +++ b/src/app/shared_dev/commands/bench/bench.h @@ -6,7 +6,8 @@ FD_PROTOTYPES_BEGIN -void bench_cmd_fn( args_t * args, config_t * config, int watch ); +void bench_topo( config_t * config ); +void bench_cmd_fn( args_t * args, config_t * config ); void bench_cmd_args( int * pargc, char *** pargv, args_t * args ); void @@ -23,7 +24,6 @@ add_bench_topo( fd_topo_t * topo, uint send_to_ip_addr, ushort rpc_port, uint rpc_ip_addr, - int no_quic, int reserve_agave_cores ); FD_PROTOTYPES_END diff --git a/src/app/shared_dev/commands/bench/fd_bencho.c b/src/app/shared_dev/commands/bench/fd_bencho.c index 6acd0744558..162522f8331 100644 --- a/src/app/shared_dev/commands/bench/fd_bencho.c +++ b/src/app/shared_dev/commands/bench/fd_bencho.c @@ -74,7 +74,9 @@ service_block_hash( fd_bencho_ctx_t * ctx, return did_work; } - if( FD_UNLIKELY( fd_log_wallclock()rpc_ready_deadline && response->status==FD_RPC_CLIENT_ERR_NETWORK ) ) { + if( FD_UNLIKELY( fd_log_wallclock()rpc_ready_deadline && + ( response->status==FD_RPC_CLIENT_ERR_NETWORK || + response->status==FD_RPC_CLIENT_ERR_MALFORMED ) ) ) { /* RPC server not yet responding, give it some more time... */ ctx->blockhash_state = FD_BENCHO_STATE_WAIT; ctx->blockhash_deadline = fd_log_wallclock() + 100L * 1000L * 1000L; /* 100 millis to retry */ diff --git a/src/app/shared_dev/commands/load.c b/src/app/shared_dev/commands/load.c index 218f3433629..6835d59843b 100644 --- a/src/app/shared_dev/commands/load.c +++ b/src/app/shared_dev/commands/load.c @@ -118,7 +118,6 @@ load_cmd_fn( args_t * args, args->load.tpu_ip, args->load.rpc_port, args->load.rpc_ip, - args->load.no_quic, 0 ); config->topo = *topo;