LCOV - code coverage report
Current view: top level - app/shared - fd_config_json.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 459 467 98.3 %
Date: 2026-11-09 04:27:00 Functions: 23 23 100.0 %

          Line data    Source code
       1             : #include "fd_config_json.h"
       2             : 
       3             : #include "../../util/fd_boolau.h"
       4             : #include "../../ballet/toml/fd_toml.h"
       5             : 
       6             : #include <stdarg.h>
       7             : #include <stdio.h>
       8             : #include <string.h>
       9             : 
      10             : /* Renders every member of the config; a config layout change breaks
      11             :    this assert so the new field is considered here (rendered, redacted,
      12             :    or knowingly skipped) before the constant is bumped.  String keys of
      13             :    the user's own file are separately forced through the classification
      14             :    lists below. */
      15             : FD_STATIC_ASSERT( sizeof(fd_config_t)==24464608UL, update_fd_config_to_json_for_the_layout_change );
      16             : 
      17         573 : #define REDACTED "[redacted]"
      18             : 
      19             : struct jw {
      20             :   char * buf;
      21             :   char * cur;
      22             :   ulong  rem;
      23             :   int    fail;
      24             :   int    first; /* no comma needed before the next member */
      25             : };
      26             : 
      27             : typedef struct jw jw_t;
      28             : 
      29             : static void
      30             : jw_raw( jw_t * w, char const * fmt, ... ) __attribute__((format(printf,2,3)));
      31             : 
      32             : static void
      33      127485 : jw_raw( jw_t * w, char const * fmt, ... ) {
      34      127485 :   if( FD_UNLIKELY( w->fail ) ) return;
      35      127485 :   va_list ap;
      36      127485 :   va_start( ap, fmt );
      37      127485 :   int n = vsnprintf( w->cur, w->rem, fmt, ap );
      38      127485 :   va_end( ap );
      39      127485 :   if( FD_UNLIKELY( n<0 || (ulong)n>=w->rem ) ) { w->fail = 1; return; }
      40      127485 :   w->cur += n; w->rem -= (ulong)n;
      41      127485 : }
      42             : 
      43             : static void
      44        6291 : jw_comma( jw_t * w ) {
      45        6291 :   if( !w->first ) jw_raw( w, "," );
      46        6291 :   w->first = 0;
      47        6291 : }
      48             : 
      49             : static void
      50        7959 : jw_cstr( jw_t * w, char const * s ) {
      51        7959 :   if( FD_UNLIKELY( w->fail ) ) return;
      52        7959 :   jw_raw( w, "\"" );
      53      105108 :   for( ; *s && !w->fail; s++ ) {
      54       97149 :     uchar c = (uchar)*s;
      55       97149 :     if(      c=='"' || c=='\\' ) jw_raw( w, "\\%c", (char)c );
      56       97149 :     else if( c<0x20 )            jw_raw( w, "\\u%04x", (uint)c );
      57       97149 :     else                         jw_raw( w, "%c", (char)c );
      58       97149 :   }
      59        7959 :   jw_raw( w, "\"" );
      60        7959 : }
      61             : 
      62         918 : static void jw_obj_open ( jw_t * w, char const * key ) { jw_comma( w ); if( key ) { jw_cstr( w, key ); jw_raw( w, ":" ); } jw_raw( w, "{" ); w->first = 1; }
      63         918 : static void jw_obj_close( jw_t * w )                   { jw_raw( w, "}" ); w->first = 0; }
      64         162 : static void jw_arr_open ( jw_t * w, char const * key ) { jw_comma( w ); jw_cstr( w, key ); jw_raw( w, ":[" ); w->first = 1; }
      65         162 : static void jw_arr_close( jw_t * w )                   { jw_raw( w, "]" ); w->first = 0; }
      66             : 
      67        1260 : static void jw_str   ( jw_t * w, char const * key, char const * val ) { jw_comma( w ); jw_cstr( w, key ); jw_raw( w, ":" ); jw_cstr( w, val ); }
      68        1944 : static void jw_ulong ( jw_t * w, char const * key, ulong val )        { jw_comma( w ); jw_cstr( w, key ); jw_raw( w, ":%lu", val ); }
      69          18 : static void jw_long  ( jw_t * w, char const * key, long val )         { jw_comma( w ); jw_cstr( w, key ); jw_raw( w, ":%ld", val ); }
      70          36 : static void jw_f64   ( jw_t * w, char const * key, double val )       { jw_comma( w ); jw_cstr( w, key ); jw_raw( w, ":%.17g", val ); }
      71         792 : static void jw_bool  ( jw_t * w, char const * key, int val )          { jw_comma( w ); jw_cstr( w, key ); jw_raw( w, ":%s", val ? "true" : "false" ); }
      72             : /* Only "auto" is a string; true and false stay JSON booleans so that
      73             :    a config not using "auto" serializes as it did before boolau. */
      74          18 : static void jw_boolau( jw_t * w, char const * key, int val )          { jw_comma( w ); jw_cstr( w, key ); jw_raw( w, ":" ); if( val==FD_BOOLAU_AUTO ) jw_cstr( w, "auto" ); else jw_raw( w, "%s", val ? "true" : "false" ); }
      75             : 
      76             : /* a path (or other host-identifying string) is reported only as
      77             :    present-or-empty */
      78         666 : static void jw_path ( jw_t * w, char const * key, char const * val ) { jw_str( w, key, val[ 0 ] ? REDACTED : "" ); }
      79             : 
      80             : /* external service URLs (bundle, event, snapshot servers) can carry
      81             :    secrets anywhere in them (credentials, path tokens, query api keys),
      82             :    so they are reported only as present-or-empty, like paths */
      83          36 : static void jw_url( jw_t * w, char const * key, char const * val ) { jw_path( w, key, val ); }
      84             : 
      85             : static void
      86          72 : jw_str_arr( jw_t * w, char const * key, char const * vals, ulong stride, ulong cnt ) {
      87          72 :   jw_arr_open( w, key );
      88          72 :   for( ulong i=0UL; i<cnt; i++ ) { jw_comma( w ); jw_cstr( w, vals+i*stride ); }
      89          72 :   jw_arr_close( w );
      90          72 : }
      91             : 
      92             : static void
      93          90 : jw_path_arr( jw_t * w, char const * key, ulong cnt ) {
      94          90 :   jw_arr_open( w, key );
      95          90 :   for( ulong i=0UL; i<cnt; i++ ) { jw_comma( w ); jw_cstr( w, REDACTED ); }
      96          90 :   jw_arr_close( w );
      97          90 : }
      98             : 
      99             : /* generic pod rendering for the user's override TOML: every
     100             :    string-valued key must appear in exactly one of the lists below,
     101             :    either redacted (the value could identify the host or carry a
     102             :    secret) or reported verbatim.  A string key in neither list aborts,
     103             :    so a new config setting must be classified before it ships in the
     104             :    boot event; test_config_json renders the full default.toml
     105             :    vocabulary through this, so an unclassified key fails the unit test
     106             :    rather than an operator's boot. */
     107             : 
     108             : static char const * const jw_redacted_keys[] = {
     109             :   "user",
     110             :   "paths.base",
     111             :   "paths.identity_key",
     112             :   "paths.vote_account",
     113             :   "paths.authorized_voter_paths",
     114             :   "paths.snapshots",
     115             :   "paths.genesis",
     116             :   "paths.accounts",
     117             :   "paths.stake_delegations",
     118             :   "paths.epoch_credits",
     119             :   "paths.cost_tracker",
     120             :   "paths.vote_stakes",
     121             :   "paths.txncache",
     122             :   "paths.shredb",
     123             :   "paths.guidb",
     124             :   "paths.vote_history",
     125             :   "log.path",
     126             :   "gossip.host",
     127             :   "snapshots.sources.servers",
     128             :   "snapshots.server.http_listen_address",
     129             :   "hugetlbfs.mount_path",
     130             :   "failover.listen_address",
     131             :   "net.bind_address",
     132             :   "tiles.quic.ssl_key_log_file",
     133             :   "tiles.bundle.url",
     134             :   "tiles.event.url",
     135             :   "tiles.shred.additional_shred_destinations_retransmit",
     136             :   "tiles.shred.additional_shred_destinations_leader",
     137             :   "tiles.metric.prometheus_listen_address",
     138             :   "gossip.entrypoints",
     139             :   "tiles.gui.gui_listen_address",
     140             :   "tiles.rpc.rpc_listen_address",
     141             :   "development.bundle.ssl_key_log_file",
     142             :   "development.ledger_input.path",
     143             :   "capture.dump_proto_dir",
     144             :   "capture.dump_syscall_name_filter",
     145             :   "capture.solcap_capture",
     146             : };
     147             : 
     148             : static char const * const jw_reported_keys[] = {
     149             :   "name",
     150             :   "layout.mode",
     151             :   "log.colorize",
     152             :   "log.level_logfile",
     153             :   "log.level_stderr",
     154             :   "log.level_flush",
     155             :   "snapshots.sources.gossip.allow_list",
     156             :   "snapshots.sources.gossip.block_list",
     157             :   "consensus.expected_genesis_hash",
     158             :   "consensus.wait_for_vote_to_start_leader",
     159             :   "consensus.wait_for_supermajority_with_bank_hash",
     160             :   "layout.affinity",
     161             :   "layout.blocklist_cores",
     162             :   "hugetlbfs.max_page_size",
     163             :   "net.provider",
     164             :   "net.interface",
     165             :   "net.xdp.xdp_mode",
     166             :   "net.xdp.xdp_zero_copy",
     167             :   "net.xdp.poll_mode",
     168             :   "net.xdp.rss_queue_mode",
     169             :   "net.xdp.listen_gre",
     170             :   "net.xdp.native_bond",
     171             :   "tiles.bundle.tls_domain_name",
     172             :   "tiles.bundle.tip_distribution_program_addr",
     173             :   "tiles.bundle.tip_payment_program_addr",
     174             :   "tiles.bundle.tip_distribution_authority",
     175             :   "tiles.pack.schedule_strategy",
     176             :   "tiles.pack.account_blocklist",
     177             :   "tiles.replay.enable_features",
     178             :   "development.core_dump",
     179             :   "development.bench.affinity",
     180             :   "development.bench.transaction_mode",
     181             :   "development.pktgen.affinity",
     182             :   "development.pktgen.fake_dst_ip",
     183             :   "development.udpecho.affinity",
     184             :   "development.ledger_input.format",
     185             :   "development.backtest.affinity",
     186             :   "capture.dump_instr_program_id_filter",
     187             : };
     188             : 
     189             : static int
     190         426 : jw_key_redacted( char const * path ) {
     191       12003 :   for( ulong i=0UL; i<sizeof(jw_redacted_keys)/sizeof(jw_redacted_keys[0]); i++ ) if( !strcmp( path, jw_redacted_keys[ i ] ) ) return 1;
     192        4119 :   for( ulong i=0UL; i<sizeof(jw_reported_keys)/sizeof(jw_reported_keys[0]); i++ ) if( !strcmp( path, jw_reported_keys[ i ] ) ) return 0;
     193           0 :   FD_LOG_ERR(( "config key %s is not classified for telemetry redaction; add it to jw_redacted_keys or jw_reported_keys in fd_config_json.c", path ));
     194           0 : }
     195             : 
     196             : /* an empty toml array parses to an empty subpod, indistinguishable
     197             :    from an empty table; the array-valued keys of the config vocabulary
     198             :    are listed so they render as [] */
     199             : 
     200             : static char const * const jw_array_keys[] = {
     201             :   "paths.authorized_voter_paths",
     202             :   "gossip.entrypoints",
     203             :   "snapshots.sources.gossip.allow_list",
     204             :   "snapshots.sources.gossip.block_list",
     205             :   "snapshots.sources.servers",
     206             :   "tiles.pack.account_blocklist",
     207             :   "tiles.replay.enable_features",
     208             :   "tiles.shred.additional_shred_destinations_retransmit",
     209             :   "tiles.shred.additional_shred_destinations_leader",
     210             : };
     211             : 
     212             : static int
     213          36 : jw_key_is_array( char const * path ) {
     214         222 :   for( ulong i=0UL; i<sizeof(jw_array_keys)/sizeof(jw_array_keys[0]); i++ ) if( !strcmp( path, jw_array_keys[ i ] ) ) return 1;
     215           9 :   return 0;
     216          36 : }
     217             : 
     218             : static int
     219        1458 : jw_key_is_index( char const * key ) {
     220        1488 :   for( ; *key; key++ ) if( *key<'0' || *key>'9' ) return 0;
     221          30 :   return 1;
     222        1458 : }
     223             : 
     224             : static void
     225         324 : jw_pod( jw_t * w, uchar const * pod, char const * prefix ) {
     226         324 :   fd_pod_iter_t head = fd_pod_iter_init( pod );
     227         324 :   int arr = fd_pod_iter_done( head ) ? jw_key_is_array( prefix )
     228         324 :                                      : !strcmp( fd_pod_iter_info( head ).key, "0" ); /* fd_toml keys arrays 0,1,... */
     229         324 :   jw_raw( w, arr ? "[" : "{" );
     230         324 :   w->first = 1;
     231        1467 :   for( fd_pod_iter_t iter=fd_pod_iter_init( pod ); !fd_pod_iter_done( iter ); iter=fd_pod_iter_next( iter ) ) {
     232        1143 :     fd_pod_info_t info = fd_pod_iter_info( iter );
     233        1143 :     char path[ 512 ];
     234        1143 :     if( jw_key_is_index( info.key ) )   FD_TEST( fd_cstr_printf_check( path, sizeof(path), NULL, "%s", prefix ) ); /* array elements classify as the array */
     235        1113 :     else if( prefix[ 0 ] )              FD_TEST( fd_cstr_printf_check( path, sizeof(path), NULL, "%s.%s", prefix, info.key ) );
     236         102 :     else                                FD_TEST( fd_cstr_printf_check( path, sizeof(path), NULL, "%s", info.key ) );
     237        1143 :     jw_comma( w );
     238        1143 :     if( !arr ) { jw_cstr( w, info.key ); jw_raw( w, ":" ); }
     239        1143 :     switch( info.val_type ) {
     240         315 :       case FD_POD_VAL_TYPE_SUBPOD:
     241         315 :         if( FD_UNLIKELY( jw_key_is_index( info.key ) ) ) FD_LOG_ERR(( "config array %s has a table or nested array element which cannot be classified for telemetry redaction", path ));
     242         315 :         jw_pod( w, (uchar const *)info.val, path );
     243         315 :         break;
     244         426 :       case FD_POD_VAL_TYPE_CSTR: {
     245         426 :         char const * val = info.val_sz ? (char const *)info.val : "";
     246         426 :         jw_cstr( w, ( jw_key_redacted( path ) && val[ 0 ] ) ? REDACTED : val );
     247         426 :         break;
     248         315 :       }
     249         315 :       case FD_POD_VAL_TYPE_LONG: { /* toml integer */
     250         315 :         ulong u; fd_ulong_svw_dec( (uchar const *)info.val, &u );
     251         315 :         jw_raw( w, "%ld", fd_long_zz_dec( u ) );
     252         315 :         break;
     253         315 :       }
     254          87 :       case FD_POD_VAL_TYPE_INT: { /* toml bool */
     255          87 :         ulong u; fd_ulong_svw_dec( (uchar const *)info.val, &u );
     256          87 :         jw_raw( w, "%s", fd_long_zz_dec( u ) ? "true" : "false" );
     257          87 :         break;
     258         315 :       }
     259           0 :       case FD_POD_VAL_TYPE_FLOAT: {
     260           0 :         float val; memcpy( &val, info.val, sizeof(float) );
     261           0 :         jw_raw( w, "%.9g", (double)val );
     262           0 :         break;
     263         315 :       }
     264           0 :       default:
     265           0 :         FD_LOG_ERR(( "unexpected pod value type %d for key %s", info.val_type, info.key ));
     266        1143 :     }
     267        1143 :   }
     268         324 :   jw_raw( w, arr ? "]" : "}" );
     269         324 :   w->first = 0;
     270         324 : }
     271             : 
     272             : ulong
     273             : fd_config_user_toml_to_json( fd_config_t const * config,
     274             :                              char *              buf,
     275           9 :                              ulong               buf_sz ) {
     276           9 :   if( FD_UNLIKELY( !buf_sz ) ) FD_LOG_ERR(( "zero sized buffer" ));
     277           9 :   buf[ 0 ] = '\0';
     278           9 :   if( FD_UNLIKELY( !config->user_config_len ) ) return 0UL;
     279             : 
     280           9 :   static uchar pod_mem[ 1UL<<20 ];
     281           9 :   uchar * pod = fd_pod_join( fd_pod_new( pod_mem, sizeof(pod_mem) ) );
     282           9 :   FD_TEST( pod );
     283             : 
     284           9 :   uchar scratch[ 4096 ];
     285           9 :   int err = fd_toml_parse( config->user_config, config->user_config_len, pod, scratch, sizeof(scratch), NULL );
     286           9 :   if( FD_UNLIKELY( err!=FD_TOML_SUCCESS ) ) FD_LOG_ERR(( "failed to re-parse the user config (%i-%s)", err, fd_toml_strerror( err ) ));
     287             : 
     288           9 :   jw_t w = { .buf = buf, .cur = buf, .rem = buf_sz, .fail = 0, .first = 1 };
     289           9 :   jw_pod( &w, pod, "" );
     290             : 
     291           9 :   fd_pod_delete( fd_pod_leave( pod ) );
     292             : 
     293           9 :   if( FD_UNLIKELY( w.fail ) ) FD_LOG_ERR(( "user config json does not fit in %lu bytes", buf_sz ));
     294           9 :   return (ulong)( w.cur-buf );
     295           9 : }
     296             : 
     297             : ulong
     298             : fd_config_to_json( fd_config_t const * config,
     299             :                    char *              buf,
     300          18 :                    ulong               buf_sz ) {
     301          18 :   fd_configf_t const * f = &config->firedancer;
     302             : 
     303          18 :   jw_t w = { .buf = buf, .cur = buf, .rem = buf_sz, .fail = !buf_sz, .first = 1 };
     304             : 
     305          18 :   jw_raw( &w, "{" );
     306          18 :   jw_str  ( &w, "name",              config->name );
     307          18 :   jw_path ( &w, "user",              config->user );
     308          18 :   jw_path ( &w, "hostname",          config->hostname );
     309          18 :   jw_bool ( &w, "telemetry",         config->telemetry );
     310          18 :   jw_f64  ( &w, "tick_per_ns_mu",    config->tick_per_ns_mu );
     311          18 :   jw_f64  ( &w, "tick_per_ns_sigma", config->tick_per_ns_sigma );
     312          18 :   jw_long ( &w, "boot_timestamp_nanos", config->boot_timestamp_nanos );
     313          18 :   jw_str  ( &w, "cluster",           config->cluster );
     314          18 :   jw_bool ( &w, "is_live_cluster",   config->is_live_cluster );
     315          18 :   jw_ulong( &w, "uid",               config->uid );
     316          18 :   jw_ulong( &w, "gid",               config->gid );
     317          18 :   jw_bool ( &w, "is_dev",            config->is_dev );
     318          18 :   jw_bool ( &w, "has_user_config",   config->has_user_config );
     319          18 :   jw_str  ( &w, "action",            config->action );
     320             : 
     321          18 :   jw_obj_open( &w, "paths" );
     322          18 :     jw_path( &w, "base",                    config->paths.base );
     323          18 :     jw_path( &w, "identity_key",            config->paths.identity_key );
     324          18 :     jw_path( &w, "vote_account",            config->paths.vote_account );
     325          18 :     jw_path( &w, "snapshots",               config->paths.snapshots );
     326          18 :     jw_path( &w, "genesis",                 config->paths.genesis );
     327          18 :     jw_path( &w, "accounts",                config->paths.accounts );
     328          18 :     jw_path( &w, "stake_delegations",       config->paths.stake_delegations );
     329          18 :     jw_path( &w, "epoch_credits",           config->paths.epoch_credits );
     330          18 :     jw_path( &w, "cost_tracker",            config->paths.cost_tracker );
     331          18 :     jw_path( &w, "vote_stakes",             config->paths.vote_stakes );
     332          18 :     jw_path( &w, "txncache",                config->paths.txncache );
     333          18 :     jw_path( &w, "shredb",                  config->paths.shredb );
     334          18 :     jw_path( &w, "guidb",                   config->paths.guidb );
     335          18 :     jw_path( &w, "vote_history",            config->paths.vote_history );
     336          18 :     jw_path_arr( &w, "authorized_voter_paths", f->paths.authorized_voter_paths_cnt );
     337          18 :   jw_obj_close( &w );
     338             : 
     339          18 :   jw_obj_open( &w, "log" );
     340          18 :     jw_path( &w, "path",          config->log.path );
     341          18 :     jw_str ( &w, "colorize",      config->log.colorize );
     342          18 :     jw_str ( &w, "level_logfile", config->log.level_logfile );
     343          18 :     jw_str ( &w, "level_stderr",  config->log.level_stderr );
     344          18 :     jw_str ( &w, "level_flush",   config->log.level_flush );
     345          18 :   jw_obj_close( &w );
     346             : 
     347          18 :   jw_obj_open( &w, "consensus" );
     348          18 :     jw_ulong ( &w, "expected_shred_version",                config->consensus.expected_shred_version );
     349          18 :     jw_str   ( &w, "expected_genesis_hash",                 config->consensus.expected_genesis_hash );
     350          18 :     jw_boolau( &w, "wait_for_vote_to_start_leader",         config->consensus.wait_for_vote_to_start_leader );
     351          18 :     jw_ulong ( &w, "wait_for_supermajority_at_slot",        f->consensus.wait_for_supermajority_at_slot );
     352          18 :     jw_str   ( &w, "wait_for_supermajority_with_bank_hash", f->consensus.wait_for_supermajority_with_bank_hash );
     353          18 :   jw_obj_close( &w );
     354             : 
     355          18 :   jw_obj_open( &w, "gossip" );
     356          18 :     jw_path_arr( &w, "entrypoints", config->gossip.entrypoints_cnt );
     357          18 :     jw_ulong( &w, "port", config->gossip.port );
     358          18 :     jw_path ( &w, "host", f->gossip.host );
     359          18 :   jw_obj_close( &w );
     360             : 
     361          18 :   jw_obj_open( &w, "layout" );
     362          18 :     jw_str  ( &w, "affinity",          config->layout.affinity );
     363          18 :     jw_str  ( &w, "blocklist_cores",   config->layout.blocklist_cores );
     364          18 :     jw_ulong( &w, "net_tile_count",    config->layout.net_tile_count );
     365          18 :     jw_ulong( &w, "quic_tile_count",   config->layout.quic_tile_count );
     366          18 :     jw_ulong( &w, "verify_tile_count", config->layout.verify_tile_count );
     367          18 :     jw_ulong( &w, "shred_tile_count",  config->layout.shred_tile_count );
     368          18 :     jw_str  ( &w, "mode",                       f->layout.mode );
     369          18 :     jw_bool ( &w, "enable_block_production",    f->layout.enable_block_production );
     370          18 :     jw_bool ( &w, "enable_snapshot_production", f->layout.enable_snapshot_production );
     371          18 :     jw_ulong( &w, "sign_tile_count",            f->layout.sign_tile_count );
     372          18 :     jw_ulong( &w, "gossvf_tile_count",          f->layout.gossvf_tile_count );
     373          18 :     jw_ulong( &w, "resolv_tile_count",          f->layout.resolv_tile_count );
     374          18 :     jw_ulong( &w, "execle_tile_count",          f->layout.execle_tile_count );
     375          18 :     jw_ulong( &w, "execrp_tile_count",          f->layout.execrp_tile_count );
     376          18 :     jw_ulong( &w, "snapzp_tile_count",          f->layout.snapzp_tile_count );
     377          18 :     jw_ulong( &w, "snapsv_tile_count",          f->layout.snapsv_tile_count );
     378          18 :     jw_ulong( &w, "snapsv_io_worker_count",     f->layout.snapsv_io_worker_count );
     379          18 :   jw_obj_close( &w );
     380             : 
     381          18 :   jw_obj_open( &w, "accounts" );
     382          18 :     jw_ulong( &w, "max_accounts",   f->accounts.max_accounts );
     383          18 :     jw_ulong( &w, "cache_size_gib", f->accounts.cache_size_gib );
     384          18 :   jw_obj_close( &w );
     385             : 
     386          18 :   jw_obj_open( &w, "runtime" );
     387          18 :     jw_ulong( &w, "max_live_slots", f->runtime.max_live_slots );
     388          18 :     jw_ulong( &w, "stake_delegation_cache_cnt", f->runtime.stake_delegation_cache_cnt );
     389          18 :     jw_ulong( &w, "program_cache_size_mib", f->runtime.program_cache_size_mib );
     390          18 :     jw_ulong( &w, "bank_cache_cnt", f->runtime.bank_cache_cnt );
     391          18 :     jw_ulong( &w, "transaction_cache_size_mib", f->runtime.transaction_cache_size_mib );
     392          18 :     jw_ulong( &w, "bpf_shared_frames", f->runtime.bpf_shared_frames );
     393          18 :     jw_ulong( &w, "bpf_local_frames", f->runtime.bpf_local_frames );
     394          18 :   jw_obj_close( &w );
     395             : 
     396          18 :   jw_obj_open( &w, "snapshots" );
     397          18 :     jw_obj_open( &w, "sources" );
     398          18 :       jw_ulong( &w, "max_local_full_effective_age", f->snapshots.sources.max_local_full_effective_age );
     399          18 :       jw_ulong( &w, "max_local_incremental_age",    f->snapshots.sources.max_local_incremental_age );
     400          18 :       jw_obj_open( &w, "gossip" );
     401          18 :         jw_bool( &w, "allow_any", f->snapshots.sources.gossip.allow_any );
     402          18 :         jw_str_arr( &w, "allow_list", f->snapshots.sources.gossip.allow_list[ 0 ], sizeof(f->snapshots.sources.gossip.allow_list[ 0 ]), f->snapshots.sources.gossip.allow_list_cnt );
     403          18 :         jw_str_arr( &w, "block_list", f->snapshots.sources.gossip.block_list[ 0 ], sizeof(f->snapshots.sources.gossip.block_list[ 0 ]), f->snapshots.sources.gossip.block_list_cnt );
     404          18 :       jw_obj_close( &w );
     405          18 :       jw_path_arr( &w, "servers", f->snapshots.sources.servers_cnt );
     406          18 :     jw_obj_close( &w );
     407          18 :     jw_bool ( &w, "incremental_snapshots",               f->snapshots.incremental_snapshots );
     408          18 :     jw_bool ( &w, "genesis_download",                    f->snapshots.genesis_download );
     409          18 :     jw_ulong( &w, "max_full_snapshots_to_keep",          f->snapshots.max_full_snapshots_to_keep );
     410          18 :     jw_ulong( &w, "max_incremental_snapshots_to_keep",   f->snapshots.max_incremental_snapshots_to_keep );
     411          18 :     jw_ulong( &w, "max_retry_abort",                     f->snapshots.max_retry_abort );
     412          18 :     jw_ulong( &w, "min_download_speed_mibs",             f->snapshots.min_download_speed_mibs );
     413          18 :     jw_ulong( &w, "wait_for_peers_timeout_seconds",      f->snapshots.wait_for_peers_timeout_seconds );
     414          18 :     jw_ulong( &w, "full_snapshot_interval_blocks",       f->snapshots.full_snapshot_interval_blocks );
     415          18 :     jw_ulong( &w, "incremental_snapshot_interval_blocks",f->snapshots.incremental_snapshot_interval_blocks );
     416          18 :     jw_ulong( &w, "max_incremental_snapshot_accounts",   f->snapshots.max_incremental_snapshot_accounts );
     417          18 :     jw_obj_open( &w, "server" );
     418          18 :       jw_bool ( &w, "enabled",              f->snapshots.server.enabled );
     419          18 :       jw_path ( &w, "http_listen_address",  f->snapshots.server.http_listen_address );
     420          18 :       jw_ulong( &w, "http_listen_port",     f->snapshots.server.http_listen_port );
     421          18 :       jw_ulong( &w, "max_http_connections", f->snapshots.server.max_http_connections );
     422          18 :       jw_ulong( &w, "idle_timeout_millis",  f->snapshots.server.idle_timeout_millis );
     423          18 :       jw_ulong( &w, "send_timeout_millis",  f->snapshots.server.send_timeout_millis );
     424          18 :       jw_ulong( &w, "send_buffer_size_kib", f->snapshots.server.send_buffer_size_kib );
     425          18 :     jw_obj_close( &w );
     426          18 :   jw_obj_close( &w );
     427             : 
     428          18 :   jw_obj_open( &w, "failover" );
     429          18 :     jw_bool ( &w, "enabled",         f->failover.enabled );
     430          18 :     jw_bool ( &w, "boot_to_standby", f->failover.boot_to_standby );
     431          18 :     jw_path ( &w, "listen_address",  f->failover.listen_address );
     432          18 :     jw_ulong( &w, "listen_port",     f->failover.listen_port );
     433          18 :   jw_obj_close( &w );
     434             : 
     435          18 :   jw_obj_open( &w, "hugetlbfs" );
     436          18 :     jw_path ( &w, "gigantic_page_mount_path",    config->hugetlbfs.gigantic_page_mount_path );
     437          18 :     jw_path ( &w, "huge_page_mount_path",        config->hugetlbfs.huge_page_mount_path );
     438          18 :     jw_path ( &w, "normal_page_mount_path",      config->hugetlbfs.normal_page_mount_path );
     439          18 :     jw_path ( &w, "mount_path",                  config->hugetlbfs.mount_path );
     440          18 :     jw_str  ( &w, "max_page_size",               config->hugetlbfs.max_page_size );
     441          18 :     jw_ulong( &w, "gigantic_page_threshold_mib", config->hugetlbfs.gigantic_page_threshold_mib );
     442          18 :   jw_obj_close( &w );
     443             : 
     444          18 :   jw_obj_open( &w, "net" );
     445          18 :     jw_str  ( &w, "provider",            config->net.provider );
     446          18 :     jw_str  ( &w, "interface",           config->net.interface );
     447          18 :     jw_path ( &w, "bind_address",        config->net.bind_address );
     448          18 :     jw_ulong( &w, "ingress_buffer_size", config->net.ingress_buffer_size );
     449          18 :     jw_obj_open( &w, "xdp" );
     450          18 :       jw_str  ( &w, "xdp_mode",             config->net.xdp.xdp_mode );
     451          18 :       jw_bool ( &w, "xdp_zero_copy",        config->net.xdp.xdp_zero_copy );
     452          18 :       jw_str  ( &w, "poll_mode",            config->net.xdp.poll_mode );
     453          18 :       jw_ulong( &w, "xdp_rx_queue_size",    config->net.xdp.xdp_rx_queue_size );
     454          18 :       jw_ulong( &w, "xdp_tx_queue_size",    config->net.xdp.xdp_tx_queue_size );
     455          18 :       jw_ulong( &w, "flush_timeout_micros", config->net.xdp.flush_timeout_micros );
     456          18 :       jw_str  ( &w, "rss_queue_mode",       config->net.xdp.rss_queue_mode );
     457          18 :       jw_bool ( &w, "listen_gre",           config->net.xdp.listen_gre );
     458          18 :       jw_bool ( &w, "native_bond",          config->net.xdp.native_bond );
     459          18 :     jw_obj_close( &w );
     460          18 :     jw_obj_open( &w, "socket" );
     461          18 :       jw_ulong( &w, "receive_buffer_size", config->net.socket.receive_buffer_size );
     462          18 :       jw_ulong( &w, "send_buffer_size",    config->net.socket.send_buffer_size );
     463          18 :     jw_obj_close( &w );
     464          18 :     jw_obj_open( &w, "mlx5" );
     465          18 :       jw_ulong( &w, "rx_queue_size", config->net.mlx5.rx_queue_size );
     466          18 :       jw_ulong( &w, "tx_queue_size", config->net.mlx5.tx_queue_size );
     467          18 :     jw_obj_close( &w );
     468             : 
     469          18 :     jw_obj_open( &w, "iavf" );
     470          18 :       jw_ulong( &w, "rx_queue_size", config->net.iavf.rx_queue_size );
     471          18 :       jw_ulong( &w, "tx_queue_size", config->net.iavf.tx_queue_size );
     472          18 :     jw_obj_close( &w );
     473          18 :   jw_obj_close( &w );
     474             : 
     475          18 :   jw_obj_open( &w, "development" );
     476          18 :     jw_bool( &w, "sandbox",   config->development.sandbox );
     477          18 :     jw_bool( &w, "no_clone",  config->development.no_clone );
     478          18 :     jw_bool( &w, "bootstrap", config->development.bootstrap );
     479          18 :     jw_str ( &w, "core_dump", config->development.core_dump );
     480          18 :     jw_bool( &w, "hard_fork_fatal", f->development.hard_fork_fatal );
     481          18 :     jw_bool( &w, "fixed_fec_sets",  f->development.fixed_fec_sets );
     482          18 :     jw_obj_open( &w, "votor" );
     483          18 :       jw_ulong( &w, "quic_client_listen_port", f->development.votor.quic_client_listen_port );
     484          18 :       jw_ulong( &w, "quic_server_listen_port", f->development.votor.quic_server_listen_port );
     485          18 :     jw_obj_close( &w );
     486          18 :     jw_obj_open( &w, "gossip" );
     487          18 :       jw_bool( &w, "allow_private_address", config->development.gossip.allow_private_address );
     488          18 :     jw_obj_close( &w );
     489          18 :     jw_obj_open( &w, "genesis" );
     490          18 :       jw_ulong( &w, "target_tick_duration_micros",  config->development.genesis.target_tick_duration_micros );
     491          18 :       jw_ulong( &w, "ticks_per_slot",               config->development.genesis.ticks_per_slot );
     492          18 :       jw_ulong( &w, "fund_initial_accounts",        config->development.genesis.fund_initial_accounts );
     493          18 :       jw_ulong( &w, "fund_initial_amount_lamports", config->development.genesis.fund_initial_amount_lamports );
     494          18 :       jw_ulong( &w, "vote_account_stake_lamports",  config->development.genesis.vote_account_stake_lamports );
     495          18 :       jw_bool ( &w, "warmup_epochs",                config->development.genesis.warmup_epochs );
     496          18 :       jw_bool ( &w, "validate_genesis_hash",        f->development.genesis.validate_genesis_hash );
     497          18 :       jw_ulong( &w, "max_file_size_mib",            f->development.genesis.max_file_size_mib );
     498          18 :     jw_obj_close( &w );
     499          18 :     jw_obj_open( &w, "ledger_input" );
     500          18 :       jw_str  ( &w, "format",   f->development.ledger_input.format );
     501          18 :       jw_path ( &w, "path",     f->development.ledger_input.path );
     502          18 :       jw_ulong( &w, "end_slot", f->development.ledger_input.end_slot );
     503          18 :     jw_obj_close( &w );
     504          18 :     jw_obj_open( &w, "backtest" );
     505          18 :       jw_str  ( &w, "affinity",      f->development.backtest.affinity );
     506          18 :       jw_ulong( &w, "root_distance", f->development.backtest.root_distance );
     507          18 :     jw_obj_close( &w );
     508          18 :     jw_obj_open( &w, "bench" );
     509          18 :       jw_ulong( &w, "benchg_tile_count",            config->development.bench.benchg_tile_count );
     510          18 :       jw_ulong( &w, "benchs_tile_count",            config->development.bench.benchs_tile_count );
     511          18 :       jw_str  ( &w, "affinity",                     config->development.bench.affinity );
     512          18 :       jw_str  ( &w, "transaction_mode",             config->development.bench.transaction_mode );
     513          18 :       jw_ulong( &w, "max_cost_per_block",           config->development.bench.max_cost_per_block );
     514          18 :       jw_ulong( &w, "max_shreds_per_block",         config->development.bench.max_shreds_per_block );
     515          18 :       jw_ulong( &w, "disable_blockstore_from_slot", config->development.bench.disable_blockstore_from_slot );
     516          18 :       jw_bool ( &w, "disable_status_cache",         config->development.bench.disable_status_cache );
     517          18 :     jw_obj_close( &w );
     518          18 :     jw_obj_open( &w, "bundle" );
     519          18 :       jw_path ( &w, "ssl_key_log_file",  config->development.bundle.ssl_key_log_file );
     520          18 :       jw_ulong( &w, "buffer_size_kib",   config->development.bundle.buffer_size_kib );
     521          18 :     jw_obj_close( &w );
     522          18 :     jw_obj_open( &w, "event" );
     523          18 :       jw_bool( &w, "report_shreds",            config->development.event.report_shreds );
     524          18 :       jw_bool( &w, "report_transactions",      config->development.event.report_transactions );
     525          18 :       jw_bool ( &w, "report_runtime_diffs",      config->development.event.report_runtime_diffs );
     526          18 :       jw_bool ( &w, "report_repair_requests",    config->development.event.report_repair_requests );
     527          18 :       jw_ulong( &w, "max_upload_rate_mbps",      config->development.event.max_upload_rate_mbps );
     528          18 :     jw_obj_close( &w );
     529          18 :     jw_obj_open( &w, "pktgen" );
     530          18 :       jw_str( &w, "affinity",    config->development.pktgen.affinity );
     531          18 :       jw_str( &w, "fake_dst_ip", config->development.pktgen.fake_dst_ip );
     532          18 :     jw_obj_close( &w );
     533          18 :     jw_obj_open( &w, "udpecho" );
     534          18 :       jw_str( &w, "affinity", config->development.udpecho.affinity );
     535          18 :     jw_obj_close( &w );
     536          18 :     jw_obj_open( &w, "snapshot_load" );
     537          18 :       jw_str( &w, "affinity", config->development.snapshot_load.affinity );
     538          18 :     jw_obj_close( &w );
     539          18 :     jw_obj_open( &w, "gui" );
     540          18 :       jw_bool( &w, "websocket_compression", config->development.gui.websocket_compression );
     541          18 :     jw_obj_close( &w );
     542          18 :     jw_obj_open( &w, "accdb" );
     543          18 :       jw_ulong( &w, "partition_size_gib", config->development.accdb.partition_size_gib );
     544          18 :     jw_obj_close( &w );
     545          18 :     jw_obj_open( &w, "hugetlbfs" );
     546          18 :       jw_bool( &w, "min_size", config->development.hugetlbfs.min_size );
     547          18 :     jw_obj_close( &w );
     548          18 :   jw_obj_close( &w );
     549             : 
     550          18 :   jw_obj_open( &w, "tiles" );
     551          18 :     jw_obj_open( &w, "netlink" );
     552          18 :       jw_ulong( &w, "max_routes",      config->tiles.netlink.max_routes );
     553          18 :       jw_ulong( &w, "max_peer_routes", config->tiles.netlink.max_peer_routes );
     554          18 :       jw_ulong( &w, "max_neighbors",   config->tiles.netlink.max_neighbors );
     555          18 :     jw_obj_close( &w );
     556          18 :     jw_obj_open( &w, "gossip" );
     557          18 :       jw_ulong( &w, "max_entries", config->tiles.gossip.max_entries );
     558          18 :     jw_obj_close( &w );
     559          18 :     jw_obj_open( &w, "quic" );
     560          18 :       jw_ulong( &w, "regular_transaction_listen_port", config->tiles.quic.regular_transaction_listen_port );
     561          18 :       jw_ulong( &w, "quic_transaction_listen_port",    config->tiles.quic.quic_transaction_listen_port );
     562          18 :       jw_ulong( &w, "txn_reassembly_count",            config->tiles.quic.txn_reassembly_count );
     563          18 :       jw_ulong( &w, "max_concurrent_connections",      config->tiles.quic.max_concurrent_connections );
     564          18 :       jw_ulong( &w, "max_concurrent_handshakes",       config->tiles.quic.max_concurrent_handshakes );
     565          18 :       jw_ulong( &w, "idle_timeout_millis",             config->tiles.quic.idle_timeout_millis );
     566          18 :       jw_ulong( &w, "ack_delay_millis",                config->tiles.quic.ack_delay_millis );
     567          18 :       jw_bool ( &w, "retry",                           config->tiles.quic.retry );
     568          18 :       jw_path ( &w, "ssl_key_log_file",                config->tiles.quic.ssl_key_log_file );
     569          18 :     jw_obj_close( &w );
     570          18 :     jw_obj_open( &w, "verify" );
     571          18 :       jw_ulong( &w, "signature_cache_size", config->tiles.verify.signature_cache_size );
     572          18 :       jw_ulong( &w, "receive_buffer_size",  config->tiles.verify.receive_buffer_size );
     573          18 :       jw_ulong( &w, "mtu",                  config->tiles.verify.mtu );
     574          18 :     jw_obj_close( &w );
     575          18 :     jw_obj_open( &w, "dedup" );
     576          18 :       jw_ulong( &w, "signature_cache_size", config->tiles.dedup.signature_cache_size );
     577          18 :     jw_obj_close( &w );
     578          18 :     jw_obj_open( &w, "bundle" );
     579          18 :       jw_bool ( &w, "enabled",                       config->tiles.bundle.enabled );
     580          18 :       jw_url  ( &w, "url",                           config->tiles.bundle.url );
     581          18 :       jw_str  ( &w, "tls_domain_name",               config->tiles.bundle.tls_domain_name );
     582          18 :       jw_str  ( &w, "tip_distribution_program_addr", config->tiles.bundle.tip_distribution_program_addr );
     583          18 :       jw_str  ( &w, "tip_payment_program_addr",      config->tiles.bundle.tip_payment_program_addr );
     584          18 :       jw_str  ( &w, "tip_distribution_authority",    config->tiles.bundle.tip_distribution_authority );
     585          18 :       jw_ulong( &w, "commission_bps",                config->tiles.bundle.commission_bps );
     586          18 :       jw_ulong( &w, "keepalive_interval_millis",     config->tiles.bundle.keepalive_interval_millis );
     587          18 :       jw_bool ( &w, "tls_cert_verify",               config->tiles.bundle.tls_cert_verify );
     588          18 :     jw_obj_close( &w );
     589          18 :     jw_obj_open( &w, "pack" );
     590          18 :       jw_ulong( &w, "max_pending_transactions", config->tiles.pack.max_pending_transactions );
     591          18 :       jw_bool ( &w, "use_consumed_cus",         config->tiles.pack.use_consumed_cus );
     592          18 :       jw_str  ( &w, "schedule_strategy",        config->tiles.pack.schedule_strategy );
     593          18 :       jw_str_arr( &w, "account_blocklist", config->tiles.pack.account_blocklist[ 0 ], sizeof(config->tiles.pack.account_blocklist[ 0 ]), config->tiles.pack.account_blocklist_cnt );
     594          18 :     jw_obj_close( &w );
     595          18 :     jw_obj_open( &w, "shred" );
     596          18 :       jw_ulong( &w, "max_pending_shred_sets", config->tiles.shred.max_pending_shred_sets );
     597          18 :       jw_ulong( &w, "shred_listen_port",      config->tiles.shred.shred_listen_port );
     598          18 :       jw_path_arr( &w, "additional_shred_destinations_retransmit", config->tiles.shred.additional_shred_destinations_retransmit_cnt );
     599          18 :       jw_path_arr( &w, "additional_shred_destinations_leader",     config->tiles.shred.additional_shred_destinations_leader_cnt );
     600          18 :       jw_ulong( &w, "shred_cache_size_mib",   config->tiles.shred.shred_cache_size_mib );
     601          18 :     jw_obj_close( &w );
     602          18 :     jw_obj_open( &w, "metric" );
     603          18 :       jw_path ( &w, "prometheus_listen_address", config->tiles.metric.prometheus_listen_address );
     604          18 :       jw_ulong( &w, "prometheus_listen_port",    config->tiles.metric.prometheus_listen_port );
     605          18 :     jw_obj_close( &w );
     606          18 :     jw_obj_open( &w, "event" );
     607          18 :       jw_url( &w, "url", config->tiles.event.url );
     608          18 :     jw_obj_close( &w );
     609          18 :     jw_obj_open( &w, "gui" );
     610          18 :       jw_bool ( &w, "enabled",                   config->tiles.gui.enabled );
     611          18 :       jw_path ( &w, "gui_listen_address",        config->tiles.gui.gui_listen_address );
     612          18 :       jw_ulong( &w, "gui_listen_port",           config->tiles.gui.gui_listen_port );
     613          18 :       jw_ulong( &w, "max_http_connections",      config->tiles.gui.max_http_connections );
     614          18 :       jw_ulong( &w, "max_websocket_connections", config->tiles.gui.max_websocket_connections );
     615          18 :       jw_ulong( &w, "send_buffer_size_mb",       config->tiles.gui.send_buffer_size_mb );
     616          18 :       jw_ulong( &w, "db_size_gib",               config->tiles.gui.db_size_gib );
     617          18 :     jw_obj_close( &w );
     618          18 :     jw_obj_open( &w, "rpc" );
     619          18 :       jw_bool ( &w, "enabled",                   config->tiles.rpc.enabled );
     620          18 :       jw_path ( &w, "rpc_listen_address",        config->tiles.rpc.rpc_listen_address );
     621          18 :       jw_ulong( &w, "rpc_listen_port",           config->tiles.rpc.rpc_listen_port );
     622          18 :       jw_ulong( &w, "max_http_connections",      config->tiles.rpc.max_http_connections );
     623          18 :       jw_ulong( &w, "max_websocket_connections", config->tiles.rpc.max_websocket_connections );
     624          18 :       jw_ulong( &w, "send_buffer_size_mb",       config->tiles.rpc.send_buffer_size_mb );
     625          18 :       jw_bool ( &w, "delay_startup",             config->tiles.rpc.delay_startup );
     626          18 :     jw_obj_close( &w );
     627          18 :     jw_obj_open( &w, "repair" );
     628          18 :       jw_ulong( &w, "repair_client_listen_port", config->tiles.repair.repair_client_listen_port );
     629          18 :     jw_obj_close( &w );
     630          18 :     jw_obj_open( &w, "rserve" );
     631          18 :       jw_bool ( &w, "enabled",                   config->tiles.rserve.enabled );
     632          18 :       jw_ulong( &w, "repair_serve_listen_port",  config->tiles.rserve.repair_serve_listen_port );
     633          18 :       jw_ulong( &w, "shred_storage_limit_gib",   config->tiles.rserve.shred_storage_limit_gib );
     634          18 :     jw_obj_close( &w );
     635          18 :     jw_obj_open( &w, "replay" );
     636          18 :       jw_ulong( &w, "max_transaction_lookahead_buffer_size", config->tiles.replay.max_transaction_lookahead_buffer_size );
     637          18 :       jw_str_arr( &w, "enable_features", config->tiles.replay.enable_features[ 0 ], sizeof(config->tiles.replay.enable_features[ 0 ]), config->tiles.replay.enable_features_cnt );
     638          18 :     jw_obj_close( &w );
     639          18 :   jw_obj_close( &w );
     640             : 
     641          18 :   jw_obj_open( &w, "capture" );
     642          18 :     jw_ulong( &w, "capture_start_slot",           config->capture.capture_start_slot );
     643          18 :     jw_path ( &w, "dump_proto_dir",               config->capture.dump_proto_dir );
     644          18 :     jw_path ( &w, "dump_syscall_name_filter",     config->capture.dump_syscall_name_filter );
     645          18 :     jw_str  ( &w, "dump_instr_program_id_filter", config->capture.dump_instr_program_id_filter );
     646          18 :     jw_path ( &w, "solcap_capture",               config->capture.solcap_capture );
     647          18 :     jw_bool ( &w, "recent_only",                  config->capture.recent_only );
     648          18 :     jw_ulong( &w, "recent_slots_per_file",        config->capture.recent_slots_per_file );
     649          18 :     jw_bool ( &w, "dump_syscall_to_pb",           config->capture.dump_syscall_to_pb );
     650          18 :     jw_bool ( &w, "dump_instr_to_pb",             config->capture.dump_instr_to_pb );
     651          18 :     jw_bool ( &w, "dump_txn_to_pb",               config->capture.dump_txn_to_pb );
     652          18 :     jw_bool ( &w, "dump_txn_as_fixture",          config->capture.dump_txn_as_fixture );
     653          18 :     jw_bool ( &w, "dump_block_to_pb",             config->capture.dump_block_to_pb );
     654          18 :   jw_obj_close( &w );
     655             : 
     656          18 :   jw_obj_open( &w, "capctx" );
     657          18 :     jw_path( &w, "path", f->capctx.path );
     658          18 :   jw_obj_close( &w );
     659             : 
     660             : 
     661          18 :   jw_raw( &w, "}" );
     662             : 
     663          18 :   if( FD_UNLIKELY( w.fail ) ) FD_LOG_ERR(( "config json does not fit in %lu bytes", buf_sz ));
     664          18 :   return (ulong)( w.cur-buf );
     665          18 : }

Generated by: LCOV version 1.14