LCOV - code coverage report
Current view: top level - app/shared - fd_config_json.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 453 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 23 0.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)==24458368UL, update_fd_config_to_json_for_the_layout_change );
      16             : 
      17           0 : #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           0 : jw_raw( jw_t * w, char const * fmt, ... ) {
      34           0 :   if( FD_UNLIKELY( w->fail ) ) return;
      35           0 :   va_list ap;
      36           0 :   va_start( ap, fmt );
      37           0 :   int n = vsnprintf( w->cur, w->rem, fmt, ap );
      38           0 :   va_end( ap );
      39           0 :   if( FD_UNLIKELY( n<0 || (ulong)n>=w->rem ) ) { w->fail = 1; return; }
      40           0 :   w->cur += n; w->rem -= (ulong)n;
      41           0 : }
      42             : 
      43             : static void
      44           0 : jw_comma( jw_t * w ) {
      45           0 :   if( !w->first ) jw_raw( w, "," );
      46           0 :   w->first = 0;
      47           0 : }
      48             : 
      49             : static void
      50           0 : jw_cstr( jw_t * w, char const * s ) {
      51           0 :   if( FD_UNLIKELY( w->fail ) ) return;
      52           0 :   jw_raw( w, "\"" );
      53           0 :   for( ; *s && !w->fail; s++ ) {
      54           0 :     uchar c = (uchar)*s;
      55           0 :     if(      c=='"' || c=='\\' ) jw_raw( w, "\\%c", (char)c );
      56           0 :     else if( c<0x20 )            jw_raw( w, "\\u%04x", (uint)c );
      57           0 :     else                         jw_raw( w, "%c", (char)c );
      58           0 :   }
      59           0 :   jw_raw( w, "\"" );
      60           0 : }
      61             : 
      62           0 : 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           0 : static void jw_obj_close( jw_t * w )                   { jw_raw( w, "}" ); w->first = 0; }
      64           0 : 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           0 : static void jw_arr_close( jw_t * w )                   { jw_raw( w, "]" ); w->first = 0; }
      66             : 
      67           0 : 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           0 : 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           0 : 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           0 : 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           0 : 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           0 : 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           0 : 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           0 : static void jw_url( jw_t * w, char const * key, char const * val ) { jw_path( w, key, val ); }
      84             : 
      85             : static void
      86           0 : jw_str_arr( jw_t * w, char const * key, char const * vals, ulong stride, ulong cnt ) {
      87           0 :   jw_arr_open( w, key );
      88           0 :   for( ulong i=0UL; i<cnt; i++ ) { jw_comma( w ); jw_cstr( w, vals+i*stride ); }
      89           0 :   jw_arr_close( w );
      90           0 : }
      91             : 
      92             : static void
      93           0 : jw_path_arr( jw_t * w, char const * key, ulong cnt ) {
      94           0 :   jw_arr_open( w, key );
      95           0 :   for( ulong i=0UL; i<cnt; i++ ) { jw_comma( w ); jw_cstr( w, REDACTED ); }
      96           0 :   jw_arr_close( w );
      97           0 : }
      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.shredb",
     122             :   "paths.guidb",
     123             :   "paths.vote_history",
     124             :   "log.path",
     125             :   "gossip.host",
     126             :   "snapshots.sources.servers",
     127             :   "snapshots.server.http_listen_address",
     128             :   "hugetlbfs.mount_path",
     129             :   "net.bind_address",
     130             :   "tiles.quic.ssl_key_log_file",
     131             :   "tiles.bundle.url",
     132             :   "tiles.event.url",
     133             :   "tiles.shred.additional_shred_destinations_retransmit",
     134             :   "tiles.shred.additional_shred_destinations_leader",
     135             :   "tiles.metric.prometheus_listen_address",
     136             :   "gossip.entrypoints",
     137             :   "tiles.gui.gui_listen_address",
     138             :   "tiles.rpc.rpc_listen_address",
     139             :   "development.bundle.ssl_key_log_file",
     140             :   "development.ledger_input.path",
     141             :   "capture.dump_proto_dir",
     142             :   "capture.dump_syscall_name_filter",
     143             :   "capture.solcap_capture",
     144             : };
     145             : 
     146             : static char const * const jw_reported_keys[] = {
     147             :   "name",
     148             :   "layout.mode",
     149             :   "log.colorize",
     150             :   "log.level_logfile",
     151             :   "log.level_stderr",
     152             :   "log.level_flush",
     153             :   "snapshots.sources.gossip.allow_list",
     154             :   "snapshots.sources.gossip.block_list",
     155             :   "consensus.expected_genesis_hash",
     156             :   "consensus.wait_for_vote_to_start_leader",
     157             :   "consensus.wait_for_supermajority_with_bank_hash",
     158             :   "layout.affinity",
     159             :   "layout.blocklist_cores",
     160             :   "hugetlbfs.max_page_size",
     161             :   "net.provider",
     162             :   "net.interface",
     163             :   "net.xdp.xdp_mode",
     164             :   "net.xdp.xdp_zero_copy",
     165             :   "net.xdp.poll_mode",
     166             :   "net.xdp.rss_queue_mode",
     167             :   "net.xdp.listen_gre",
     168             :   "net.xdp.native_bond",
     169             :   "tiles.bundle.tls_domain_name",
     170             :   "tiles.bundle.tip_distribution_program_addr",
     171             :   "tiles.bundle.tip_payment_program_addr",
     172             :   "tiles.bundle.tip_distribution_authority",
     173             :   "tiles.pack.schedule_strategy",
     174             :   "tiles.pack.account_blocklist",
     175             :   "tiles.replay.enable_features",
     176             :   "development.core_dump",
     177             :   "development.bench.affinity",
     178             :   "development.bench.transaction_mode",
     179             :   "development.pktgen.affinity",
     180             :   "development.pktgen.fake_dst_ip",
     181             :   "development.udpecho.affinity",
     182             :   "development.ledger_input.format",
     183             :   "development.backtest.affinity",
     184             :   "capture.dump_instr_program_id_filter",
     185             : };
     186             : 
     187             : static int
     188           0 : jw_key_redacted( char const * path ) {
     189           0 :   for( ulong i=0UL; i<sizeof(jw_redacted_keys)/sizeof(jw_redacted_keys[0]); i++ ) if( !strcmp( path, jw_redacted_keys[ i ] ) ) return 1;
     190           0 :   for( ulong i=0UL; i<sizeof(jw_reported_keys)/sizeof(jw_reported_keys[0]); i++ ) if( !strcmp( path, jw_reported_keys[ i ] ) ) return 0;
     191           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 ));
     192           0 : }
     193             : 
     194             : /* an empty toml array parses to an empty subpod, indistinguishable
     195             :    from an empty table; the array-valued keys of the config vocabulary
     196             :    are listed so they render as [] */
     197             : 
     198             : static char const * const jw_array_keys[] = {
     199             :   "paths.authorized_voter_paths",
     200             :   "gossip.entrypoints",
     201             :   "snapshots.sources.gossip.allow_list",
     202             :   "snapshots.sources.gossip.block_list",
     203             :   "snapshots.sources.servers",
     204             :   "tiles.pack.account_blocklist",
     205             :   "tiles.replay.enable_features",
     206             :   "tiles.shred.additional_shred_destinations_retransmit",
     207             :   "tiles.shred.additional_shred_destinations_leader",
     208             : };
     209             : 
     210             : static int
     211           0 : jw_key_is_array( char const * path ) {
     212           0 :   for( ulong i=0UL; i<sizeof(jw_array_keys)/sizeof(jw_array_keys[0]); i++ ) if( !strcmp( path, jw_array_keys[ i ] ) ) return 1;
     213           0 :   return 0;
     214           0 : }
     215             : 
     216             : static int
     217           0 : jw_key_is_index( char const * key ) {
     218           0 :   for( ; *key; key++ ) if( *key<'0' || *key>'9' ) return 0;
     219           0 :   return 1;
     220           0 : }
     221             : 
     222             : static void
     223           0 : jw_pod( jw_t * w, uchar const * pod, char const * prefix ) {
     224           0 :   fd_pod_iter_t head = fd_pod_iter_init( pod );
     225           0 :   int arr = fd_pod_iter_done( head ) ? jw_key_is_array( prefix )
     226           0 :                                      : !strcmp( fd_pod_iter_info( head ).key, "0" ); /* fd_toml keys arrays 0,1,... */
     227           0 :   jw_raw( w, arr ? "[" : "{" );
     228           0 :   w->first = 1;
     229           0 :   for( fd_pod_iter_t iter=fd_pod_iter_init( pod ); !fd_pod_iter_done( iter ); iter=fd_pod_iter_next( iter ) ) {
     230           0 :     fd_pod_info_t info = fd_pod_iter_info( iter );
     231           0 :     char path[ 512 ];
     232           0 :     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 */
     233           0 :     else if( prefix[ 0 ] )              FD_TEST( fd_cstr_printf_check( path, sizeof(path), NULL, "%s.%s", prefix, info.key ) );
     234           0 :     else                                FD_TEST( fd_cstr_printf_check( path, sizeof(path), NULL, "%s", info.key ) );
     235           0 :     jw_comma( w );
     236           0 :     if( !arr ) { jw_cstr( w, info.key ); jw_raw( w, ":" ); }
     237           0 :     switch( info.val_type ) {
     238           0 :       case FD_POD_VAL_TYPE_SUBPOD:
     239           0 :         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 ));
     240           0 :         jw_pod( w, (uchar const *)info.val, path );
     241           0 :         break;
     242           0 :       case FD_POD_VAL_TYPE_CSTR: {
     243           0 :         char const * val = info.val_sz ? (char const *)info.val : "";
     244           0 :         jw_cstr( w, ( jw_key_redacted( path ) && val[ 0 ] ) ? REDACTED : val );
     245           0 :         break;
     246           0 :       }
     247           0 :       case FD_POD_VAL_TYPE_LONG: { /* toml integer */
     248           0 :         ulong u; fd_ulong_svw_dec( (uchar const *)info.val, &u );
     249           0 :         jw_raw( w, "%ld", fd_long_zz_dec( u ) );
     250           0 :         break;
     251           0 :       }
     252           0 :       case FD_POD_VAL_TYPE_INT: { /* toml bool */
     253           0 :         ulong u; fd_ulong_svw_dec( (uchar const *)info.val, &u );
     254           0 :         jw_raw( w, "%s", fd_long_zz_dec( u ) ? "true" : "false" );
     255           0 :         break;
     256           0 :       }
     257           0 :       case FD_POD_VAL_TYPE_FLOAT: {
     258           0 :         float val; memcpy( &val, info.val, sizeof(float) );
     259           0 :         jw_raw( w, "%.9g", (double)val );
     260           0 :         break;
     261           0 :       }
     262           0 :       default:
     263           0 :         FD_LOG_ERR(( "unexpected pod value type %d for key %s", info.val_type, info.key ));
     264           0 :     }
     265           0 :   }
     266           0 :   jw_raw( w, arr ? "]" : "}" );
     267           0 :   w->first = 0;
     268           0 : }
     269             : 
     270             : ulong
     271             : fd_config_user_toml_to_json( fd_config_t const * config,
     272             :                              char *              buf,
     273           0 :                              ulong               buf_sz ) {
     274           0 :   if( FD_UNLIKELY( !buf_sz ) ) FD_LOG_ERR(( "zero sized buffer" ));
     275           0 :   buf[ 0 ] = '\0';
     276           0 :   if( FD_UNLIKELY( !config->user_config_len ) ) return 0UL;
     277             : 
     278           0 :   static uchar pod_mem[ 1UL<<20 ];
     279           0 :   uchar * pod = fd_pod_join( fd_pod_new( pod_mem, sizeof(pod_mem) ) );
     280           0 :   FD_TEST( pod );
     281             : 
     282           0 :   uchar scratch[ 4096 ];
     283           0 :   int err = fd_toml_parse( config->user_config, config->user_config_len, pod, scratch, sizeof(scratch), NULL );
     284           0 :   if( FD_UNLIKELY( err!=FD_TOML_SUCCESS ) ) FD_LOG_ERR(( "failed to re-parse the user config (%i-%s)", err, fd_toml_strerror( err ) ));
     285             : 
     286           0 :   jw_t w = { .buf = buf, .cur = buf, .rem = buf_sz, .fail = 0, .first = 1 };
     287           0 :   jw_pod( &w, pod, "" );
     288             : 
     289           0 :   fd_pod_delete( fd_pod_leave( pod ) );
     290             : 
     291           0 :   if( FD_UNLIKELY( w.fail ) ) FD_LOG_ERR(( "user config json does not fit in %lu bytes", buf_sz ));
     292           0 :   return (ulong)( w.cur-buf );
     293           0 : }
     294             : 
     295             : ulong
     296             : fd_config_to_json( fd_config_t const * config,
     297             :                    char *              buf,
     298           0 :                    ulong               buf_sz ) {
     299           0 :   fd_configf_t const * f = &config->firedancer;
     300             : 
     301           0 :   jw_t w = { .buf = buf, .cur = buf, .rem = buf_sz, .fail = !buf_sz, .first = 1 };
     302             : 
     303           0 :   jw_raw( &w, "{" );
     304           0 :   jw_str  ( &w, "name",              config->name );
     305           0 :   jw_path ( &w, "user",              config->user );
     306           0 :   jw_path ( &w, "hostname",          config->hostname );
     307           0 :   jw_bool ( &w, "telemetry",         config->telemetry );
     308           0 :   jw_f64  ( &w, "tick_per_ns_mu",    config->tick_per_ns_mu );
     309           0 :   jw_f64  ( &w, "tick_per_ns_sigma", config->tick_per_ns_sigma );
     310           0 :   jw_long ( &w, "boot_timestamp_nanos", config->boot_timestamp_nanos );
     311           0 :   jw_str  ( &w, "cluster",           config->cluster );
     312           0 :   jw_bool ( &w, "is_live_cluster",   config->is_live_cluster );
     313           0 :   jw_ulong( &w, "uid",               config->uid );
     314           0 :   jw_ulong( &w, "gid",               config->gid );
     315           0 :   jw_bool ( &w, "is_dev",            config->is_dev );
     316           0 :   jw_bool ( &w, "has_user_config",   config->has_user_config );
     317           0 :   jw_str  ( &w, "action",            config->action );
     318             : 
     319           0 :   jw_obj_open( &w, "paths" );
     320           0 :     jw_path( &w, "base",                    config->paths.base );
     321           0 :     jw_path( &w, "identity_key",            config->paths.identity_key );
     322           0 :     jw_path( &w, "vote_account",            config->paths.vote_account );
     323           0 :     jw_path( &w, "snapshots",               config->paths.snapshots );
     324           0 :     jw_path( &w, "genesis",                 config->paths.genesis );
     325           0 :     jw_path( &w, "accounts",                config->paths.accounts );
     326           0 :     jw_path( &w, "stake_delegations",       config->paths.stake_delegations );
     327           0 :     jw_path( &w, "epoch_credits",           config->paths.epoch_credits );
     328           0 :     jw_path( &w, "cost_tracker",            config->paths.cost_tracker );
     329           0 :     jw_path( &w, "vote_stakes",             config->paths.vote_stakes );
     330           0 :     jw_path( &w, "shredb",                  config->paths.shredb );
     331           0 :     jw_path( &w, "guidb",                   config->paths.guidb );
     332           0 :     jw_path( &w, "vote_history",            config->paths.vote_history );
     333           0 :     jw_path_arr( &w, "authorized_voter_paths", f->paths.authorized_voter_paths_cnt );
     334           0 :   jw_obj_close( &w );
     335             : 
     336           0 :   jw_obj_open( &w, "log" );
     337           0 :     jw_path( &w, "path",          config->log.path );
     338           0 :     jw_str ( &w, "colorize",      config->log.colorize );
     339           0 :     jw_str ( &w, "level_logfile", config->log.level_logfile );
     340           0 :     jw_str ( &w, "level_stderr",  config->log.level_stderr );
     341           0 :     jw_str ( &w, "level_flush",   config->log.level_flush );
     342           0 :   jw_obj_close( &w );
     343             : 
     344           0 :   jw_obj_open( &w, "consensus" );
     345           0 :     jw_ulong ( &w, "expected_shred_version",                config->consensus.expected_shred_version );
     346           0 :     jw_str   ( &w, "expected_genesis_hash",                 config->consensus.expected_genesis_hash );
     347           0 :     jw_boolau( &w, "wait_for_vote_to_start_leader",         config->consensus.wait_for_vote_to_start_leader );
     348           0 :     jw_ulong ( &w, "wait_for_supermajority_at_slot",        f->consensus.wait_for_supermajority_at_slot );
     349           0 :     jw_str   ( &w, "wait_for_supermajority_with_bank_hash", f->consensus.wait_for_supermajority_with_bank_hash );
     350           0 :   jw_obj_close( &w );
     351             : 
     352           0 :   jw_obj_open( &w, "gossip" );
     353           0 :     jw_path_arr( &w, "entrypoints", config->gossip.entrypoints_cnt );
     354           0 :     jw_ulong( &w, "port", config->gossip.port );
     355           0 :     jw_path ( &w, "host", f->gossip.host );
     356           0 :   jw_obj_close( &w );
     357             : 
     358           0 :   jw_obj_open( &w, "layout" );
     359           0 :     jw_str  ( &w, "affinity",          config->layout.affinity );
     360           0 :     jw_str  ( &w, "blocklist_cores",   config->layout.blocklist_cores );
     361           0 :     jw_ulong( &w, "net_tile_count",    config->layout.net_tile_count );
     362           0 :     jw_ulong( &w, "quic_tile_count",   config->layout.quic_tile_count );
     363           0 :     jw_ulong( &w, "verify_tile_count", config->layout.verify_tile_count );
     364           0 :     jw_ulong( &w, "shred_tile_count",  config->layout.shred_tile_count );
     365           0 :     jw_str  ( &w, "mode",                       f->layout.mode );
     366           0 :     jw_bool ( &w, "enable_block_production",    f->layout.enable_block_production );
     367           0 :     jw_bool ( &w, "enable_snapshot_production", f->layout.enable_snapshot_production );
     368           0 :     jw_ulong( &w, "sign_tile_count",            f->layout.sign_tile_count );
     369           0 :     jw_ulong( &w, "gossvf_tile_count",          f->layout.gossvf_tile_count );
     370           0 :     jw_ulong( &w, "resolv_tile_count",          f->layout.resolv_tile_count );
     371           0 :     jw_ulong( &w, "execle_tile_count",          f->layout.execle_tile_count );
     372           0 :     jw_ulong( &w, "execrp_tile_count",          f->layout.execrp_tile_count );
     373           0 :     jw_ulong( &w, "snapzp_tile_count",          f->layout.snapzp_tile_count );
     374           0 :     jw_ulong( &w, "snapsv_tile_count",          f->layout.snapsv_tile_count );
     375           0 :     jw_ulong( &w, "snapsv_io_worker_count",     f->layout.snapsv_io_worker_count );
     376           0 :   jw_obj_close( &w );
     377             : 
     378           0 :   jw_obj_open( &w, "accounts" );
     379           0 :     jw_ulong( &w, "max_accounts",   f->accounts.max_accounts );
     380           0 :     jw_ulong( &w, "cache_size_gib", f->accounts.cache_size_gib );
     381           0 :   jw_obj_close( &w );
     382             : 
     383           0 :   jw_obj_open( &w, "runtime" );
     384           0 :     jw_ulong( &w, "max_live_slots", f->runtime.max_live_slots );
     385           0 :     jw_ulong( &w, "stake_delegation_cache_cnt", f->runtime.stake_delegation_cache_cnt );
     386           0 :     jw_ulong( &w, "program_cache_size_mib", f->runtime.program_cache_size_mib );
     387           0 :     jw_ulong( &w, "bank_cache_cnt", f->runtime.bank_cache_cnt );
     388           0 :   jw_obj_close( &w );
     389             : 
     390           0 :   jw_obj_open( &w, "snapshots" );
     391           0 :     jw_obj_open( &w, "sources" );
     392           0 :       jw_ulong( &w, "max_local_full_effective_age", f->snapshots.sources.max_local_full_effective_age );
     393           0 :       jw_ulong( &w, "max_local_incremental_age",    f->snapshots.sources.max_local_incremental_age );
     394           0 :       jw_obj_open( &w, "gossip" );
     395           0 :         jw_bool( &w, "allow_any", f->snapshots.sources.gossip.allow_any );
     396           0 :         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 );
     397           0 :         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 );
     398           0 :       jw_obj_close( &w );
     399           0 :       jw_path_arr( &w, "servers", f->snapshots.sources.servers_cnt );
     400           0 :     jw_obj_close( &w );
     401           0 :     jw_bool ( &w, "incremental_snapshots",               f->snapshots.incremental_snapshots );
     402           0 :     jw_bool ( &w, "genesis_download",                    f->snapshots.genesis_download );
     403           0 :     jw_ulong( &w, "max_full_snapshots_to_keep",          f->snapshots.max_full_snapshots_to_keep );
     404           0 :     jw_ulong( &w, "max_incremental_snapshots_to_keep",   f->snapshots.max_incremental_snapshots_to_keep );
     405           0 :     jw_ulong( &w, "max_retry_abort",                     f->snapshots.max_retry_abort );
     406           0 :     jw_ulong( &w, "min_download_speed_mibs",             f->snapshots.min_download_speed_mibs );
     407           0 :     jw_ulong( &w, "wait_for_peers_timeout_seconds",      f->snapshots.wait_for_peers_timeout_seconds );
     408           0 :     jw_ulong( &w, "full_snapshot_interval_blocks",       f->snapshots.full_snapshot_interval_blocks );
     409           0 :     jw_ulong( &w, "incremental_snapshot_interval_blocks",f->snapshots.incremental_snapshot_interval_blocks );
     410           0 :     jw_ulong( &w, "max_incremental_snapshot_accounts",   f->snapshots.max_incremental_snapshot_accounts );
     411           0 :     jw_obj_open( &w, "server" );
     412           0 :       jw_bool ( &w, "enabled",              f->snapshots.server.enabled );
     413           0 :       jw_path ( &w, "http_listen_address",  f->snapshots.server.http_listen_address );
     414           0 :       jw_ulong( &w, "http_listen_port",     f->snapshots.server.http_listen_port );
     415           0 :       jw_ulong( &w, "max_http_connections", f->snapshots.server.max_http_connections );
     416           0 :       jw_ulong( &w, "idle_timeout_millis",  f->snapshots.server.idle_timeout_millis );
     417           0 :       jw_ulong( &w, "send_timeout_millis",  f->snapshots.server.send_timeout_millis );
     418           0 :       jw_ulong( &w, "send_buffer_size_kib", f->snapshots.server.send_buffer_size_kib );
     419           0 :     jw_obj_close( &w );
     420           0 :   jw_obj_close( &w );
     421             : 
     422           0 :   jw_obj_open( &w, "hugetlbfs" );
     423           0 :     jw_path ( &w, "gigantic_page_mount_path",    config->hugetlbfs.gigantic_page_mount_path );
     424           0 :     jw_path ( &w, "huge_page_mount_path",        config->hugetlbfs.huge_page_mount_path );
     425           0 :     jw_path ( &w, "normal_page_mount_path",      config->hugetlbfs.normal_page_mount_path );
     426           0 :     jw_path ( &w, "mount_path",                  config->hugetlbfs.mount_path );
     427           0 :     jw_str  ( &w, "max_page_size",               config->hugetlbfs.max_page_size );
     428           0 :     jw_ulong( &w, "gigantic_page_threshold_mib", config->hugetlbfs.gigantic_page_threshold_mib );
     429           0 :   jw_obj_close( &w );
     430             : 
     431           0 :   jw_obj_open( &w, "net" );
     432           0 :     jw_str  ( &w, "provider",            config->net.provider );
     433           0 :     jw_str  ( &w, "interface",           config->net.interface );
     434           0 :     jw_path ( &w, "bind_address",        config->net.bind_address );
     435           0 :     jw_ulong( &w, "ingress_buffer_size", config->net.ingress_buffer_size );
     436           0 :     jw_obj_open( &w, "xdp" );
     437           0 :       jw_str  ( &w, "xdp_mode",             config->net.xdp.xdp_mode );
     438           0 :       jw_bool ( &w, "xdp_zero_copy",        config->net.xdp.xdp_zero_copy );
     439           0 :       jw_str  ( &w, "poll_mode",            config->net.xdp.poll_mode );
     440           0 :       jw_ulong( &w, "xdp_rx_queue_size",    config->net.xdp.xdp_rx_queue_size );
     441           0 :       jw_ulong( &w, "xdp_tx_queue_size",    config->net.xdp.xdp_tx_queue_size );
     442           0 :       jw_ulong( &w, "flush_timeout_micros", config->net.xdp.flush_timeout_micros );
     443           0 :       jw_str  ( &w, "rss_queue_mode",       config->net.xdp.rss_queue_mode );
     444           0 :       jw_bool ( &w, "listen_gre",           config->net.xdp.listen_gre );
     445           0 :       jw_bool ( &w, "native_bond",          config->net.xdp.native_bond );
     446           0 :     jw_obj_close( &w );
     447           0 :     jw_obj_open( &w, "socket" );
     448           0 :       jw_ulong( &w, "receive_buffer_size", config->net.socket.receive_buffer_size );
     449           0 :       jw_ulong( &w, "send_buffer_size",    config->net.socket.send_buffer_size );
     450           0 :     jw_obj_close( &w );
     451           0 :     jw_obj_open( &w, "mlx5" );
     452           0 :       jw_ulong( &w, "rx_queue_size", config->net.mlx5.rx_queue_size );
     453           0 :       jw_ulong( &w, "tx_queue_size", config->net.mlx5.tx_queue_size );
     454           0 :     jw_obj_close( &w );
     455           0 :   jw_obj_close( &w );
     456             : 
     457           0 :   jw_obj_open( &w, "development" );
     458           0 :     jw_bool( &w, "sandbox",   config->development.sandbox );
     459           0 :     jw_bool( &w, "no_clone",  config->development.no_clone );
     460           0 :     jw_bool( &w, "bootstrap", config->development.bootstrap );
     461           0 :     jw_str ( &w, "core_dump", config->development.core_dump );
     462           0 :     jw_bool( &w, "hard_fork_fatal", f->development.hard_fork_fatal );
     463           0 :     jw_bool( &w, "fixed_fec_sets",  f->development.fixed_fec_sets );
     464           0 :     jw_obj_open( &w, "votor" );
     465           0 :       jw_ulong( &w, "quic_client_listen_port", f->development.votor.quic_client_listen_port );
     466           0 :       jw_ulong( &w, "quic_server_listen_port", f->development.votor.quic_server_listen_port );
     467           0 :     jw_obj_close( &w );
     468           0 :     jw_obj_open( &w, "gossip" );
     469           0 :       jw_bool( &w, "allow_private_address", config->development.gossip.allow_private_address );
     470           0 :     jw_obj_close( &w );
     471           0 :     jw_obj_open( &w, "genesis" );
     472           0 :       jw_ulong( &w, "hashes_per_tick",              config->development.genesis.hashes_per_tick );
     473           0 :       jw_ulong( &w, "target_tick_duration_micros",  config->development.genesis.target_tick_duration_micros );
     474           0 :       jw_ulong( &w, "ticks_per_slot",               config->development.genesis.ticks_per_slot );
     475           0 :       jw_ulong( &w, "fund_initial_accounts",        config->development.genesis.fund_initial_accounts );
     476           0 :       jw_ulong( &w, "fund_initial_amount_lamports", config->development.genesis.fund_initial_amount_lamports );
     477           0 :       jw_ulong( &w, "vote_account_stake_lamports",  config->development.genesis.vote_account_stake_lamports );
     478           0 :       jw_bool ( &w, "warmup_epochs",                config->development.genesis.warmup_epochs );
     479           0 :       jw_bool ( &w, "validate_genesis_hash",        f->development.genesis.validate_genesis_hash );
     480           0 :       jw_ulong( &w, "max_file_size_mib",            f->development.genesis.max_file_size_mib );
     481           0 :     jw_obj_close( &w );
     482           0 :     jw_obj_open( &w, "ledger_input" );
     483           0 :       jw_str  ( &w, "format",   f->development.ledger_input.format );
     484           0 :       jw_path ( &w, "path",     f->development.ledger_input.path );
     485           0 :       jw_ulong( &w, "end_slot", f->development.ledger_input.end_slot );
     486           0 :     jw_obj_close( &w );
     487           0 :     jw_obj_open( &w, "backtest" );
     488           0 :       jw_str  ( &w, "affinity",      f->development.backtest.affinity );
     489           0 :       jw_ulong( &w, "root_distance", f->development.backtest.root_distance );
     490           0 :     jw_obj_close( &w );
     491           0 :     jw_obj_open( &w, "bench" );
     492           0 :       jw_ulong( &w, "benchg_tile_count",            config->development.bench.benchg_tile_count );
     493           0 :       jw_ulong( &w, "benchs_tile_count",            config->development.bench.benchs_tile_count );
     494           0 :       jw_str  ( &w, "affinity",                     config->development.bench.affinity );
     495           0 :       jw_str  ( &w, "transaction_mode",             config->development.bench.transaction_mode );
     496           0 :       jw_ulong( &w, "max_cost_per_block",           config->development.bench.max_cost_per_block );
     497           0 :       jw_ulong( &w, "max_shreds_per_block",         config->development.bench.max_shreds_per_block );
     498           0 :       jw_ulong( &w, "disable_blockstore_from_slot", config->development.bench.disable_blockstore_from_slot );
     499           0 :       jw_bool ( &w, "disable_status_cache",         config->development.bench.disable_status_cache );
     500           0 :     jw_obj_close( &w );
     501           0 :     jw_obj_open( &w, "bundle" );
     502           0 :       jw_path ( &w, "ssl_key_log_file",  config->development.bundle.ssl_key_log_file );
     503           0 :       jw_ulong( &w, "buffer_size_kib",   config->development.bundle.buffer_size_kib );
     504           0 :     jw_obj_close( &w );
     505           0 :     jw_obj_open( &w, "event" );
     506           0 :       jw_bool( &w, "report_shreds",            config->development.event.report_shreds );
     507           0 :       jw_bool( &w, "report_transactions",      config->development.event.report_transactions );
     508           0 :       jw_bool( &w, "report_runtime_diffs",      config->development.event.report_runtime_diffs );
     509           0 :     jw_obj_close( &w );
     510           0 :     jw_obj_open( &w, "pktgen" );
     511           0 :       jw_str( &w, "affinity",    config->development.pktgen.affinity );
     512           0 :       jw_str( &w, "fake_dst_ip", config->development.pktgen.fake_dst_ip );
     513           0 :     jw_obj_close( &w );
     514           0 :     jw_obj_open( &w, "udpecho" );
     515           0 :       jw_str( &w, "affinity", config->development.udpecho.affinity );
     516           0 :     jw_obj_close( &w );
     517           0 :     jw_obj_open( &w, "snapshot_load" );
     518           0 :       jw_str( &w, "affinity", config->development.snapshot_load.affinity );
     519           0 :     jw_obj_close( &w );
     520           0 :     jw_obj_open( &w, "gui" );
     521           0 :       jw_bool( &w, "websocket_compression", config->development.gui.websocket_compression );
     522           0 :     jw_obj_close( &w );
     523           0 :     jw_obj_open( &w, "accdb" );
     524           0 :       jw_ulong( &w, "partition_size_gib", config->development.accdb.partition_size_gib );
     525           0 :     jw_obj_close( &w );
     526           0 :     jw_obj_open( &w, "hugetlbfs" );
     527           0 :       jw_bool( &w, "min_size", config->development.hugetlbfs.min_size );
     528           0 :     jw_obj_close( &w );
     529           0 :   jw_obj_close( &w );
     530             : 
     531           0 :   jw_obj_open( &w, "tiles" );
     532           0 :     jw_obj_open( &w, "netlink" );
     533           0 :       jw_ulong( &w, "max_routes",      config->tiles.netlink.max_routes );
     534           0 :       jw_ulong( &w, "max_peer_routes", config->tiles.netlink.max_peer_routes );
     535           0 :       jw_ulong( &w, "max_neighbors",   config->tiles.netlink.max_neighbors );
     536           0 :     jw_obj_close( &w );
     537           0 :     jw_obj_open( &w, "gossip" );
     538           0 :       jw_ulong( &w, "max_entries", config->tiles.gossip.max_entries );
     539           0 :     jw_obj_close( &w );
     540           0 :     jw_obj_open( &w, "quic" );
     541           0 :       jw_ulong( &w, "regular_transaction_listen_port", config->tiles.quic.regular_transaction_listen_port );
     542           0 :       jw_ulong( &w, "quic_transaction_listen_port",    config->tiles.quic.quic_transaction_listen_port );
     543           0 :       jw_ulong( &w, "txn_reassembly_count",            config->tiles.quic.txn_reassembly_count );
     544           0 :       jw_ulong( &w, "max_concurrent_connections",      config->tiles.quic.max_concurrent_connections );
     545           0 :       jw_ulong( &w, "max_concurrent_handshakes",       config->tiles.quic.max_concurrent_handshakes );
     546           0 :       jw_ulong( &w, "idle_timeout_millis",             config->tiles.quic.idle_timeout_millis );
     547           0 :       jw_ulong( &w, "ack_delay_millis",                config->tiles.quic.ack_delay_millis );
     548           0 :       jw_bool ( &w, "retry",                           config->tiles.quic.retry );
     549           0 :       jw_path ( &w, "ssl_key_log_file",                config->tiles.quic.ssl_key_log_file );
     550           0 :     jw_obj_close( &w );
     551           0 :     jw_obj_open( &w, "verify" );
     552           0 :       jw_ulong( &w, "signature_cache_size", config->tiles.verify.signature_cache_size );
     553           0 :       jw_ulong( &w, "receive_buffer_size",  config->tiles.verify.receive_buffer_size );
     554           0 :       jw_ulong( &w, "mtu",                  config->tiles.verify.mtu );
     555           0 :     jw_obj_close( &w );
     556           0 :     jw_obj_open( &w, "dedup" );
     557           0 :       jw_ulong( &w, "signature_cache_size", config->tiles.dedup.signature_cache_size );
     558           0 :     jw_obj_close( &w );
     559           0 :     jw_obj_open( &w, "bundle" );
     560           0 :       jw_bool ( &w, "enabled",                       config->tiles.bundle.enabled );
     561           0 :       jw_url  ( &w, "url",                           config->tiles.bundle.url );
     562           0 :       jw_str  ( &w, "tls_domain_name",               config->tiles.bundle.tls_domain_name );
     563           0 :       jw_str  ( &w, "tip_distribution_program_addr", config->tiles.bundle.tip_distribution_program_addr );
     564           0 :       jw_str  ( &w, "tip_payment_program_addr",      config->tiles.bundle.tip_payment_program_addr );
     565           0 :       jw_str  ( &w, "tip_distribution_authority",    config->tiles.bundle.tip_distribution_authority );
     566           0 :       jw_ulong( &w, "commission_bps",                config->tiles.bundle.commission_bps );
     567           0 :       jw_ulong( &w, "keepalive_interval_millis",     config->tiles.bundle.keepalive_interval_millis );
     568           0 :       jw_bool ( &w, "tls_cert_verify",               config->tiles.bundle.tls_cert_verify );
     569           0 :     jw_obj_close( &w );
     570           0 :     jw_obj_open( &w, "pack" );
     571           0 :       jw_ulong( &w, "max_pending_transactions", config->tiles.pack.max_pending_transactions );
     572           0 :       jw_bool ( &w, "use_consumed_cus",         config->tiles.pack.use_consumed_cus );
     573           0 :       jw_str  ( &w, "schedule_strategy",        config->tiles.pack.schedule_strategy );
     574           0 :       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 );
     575           0 :     jw_obj_close( &w );
     576           0 :     jw_obj_open( &w, "shred" );
     577           0 :       jw_ulong( &w, "max_pending_shred_sets", config->tiles.shred.max_pending_shred_sets );
     578           0 :       jw_ulong( &w, "shred_listen_port",      config->tiles.shred.shred_listen_port );
     579           0 :       jw_path_arr( &w, "additional_shred_destinations_retransmit", config->tiles.shred.additional_shred_destinations_retransmit_cnt );
     580           0 :       jw_path_arr( &w, "additional_shred_destinations_leader",     config->tiles.shred.additional_shred_destinations_leader_cnt );
     581           0 :       jw_ulong( &w, "shred_cache_size_mib",   config->tiles.shred.shred_cache_size_mib );
     582           0 :     jw_obj_close( &w );
     583           0 :     jw_obj_open( &w, "metric" );
     584           0 :       jw_path ( &w, "prometheus_listen_address", config->tiles.metric.prometheus_listen_address );
     585           0 :       jw_ulong( &w, "prometheus_listen_port",    config->tiles.metric.prometheus_listen_port );
     586           0 :     jw_obj_close( &w );
     587           0 :     jw_obj_open( &w, "event" );
     588           0 :       jw_url( &w, "url", config->tiles.event.url );
     589           0 :     jw_obj_close( &w );
     590           0 :     jw_obj_open( &w, "gui" );
     591           0 :       jw_bool ( &w, "enabled",                   config->tiles.gui.enabled );
     592           0 :       jw_path ( &w, "gui_listen_address",        config->tiles.gui.gui_listen_address );
     593           0 :       jw_ulong( &w, "gui_listen_port",           config->tiles.gui.gui_listen_port );
     594           0 :       jw_ulong( &w, "max_http_connections",      config->tiles.gui.max_http_connections );
     595           0 :       jw_ulong( &w, "max_websocket_connections", config->tiles.gui.max_websocket_connections );
     596           0 :       jw_ulong( &w, "send_buffer_size_mb",       config->tiles.gui.send_buffer_size_mb );
     597           0 :       jw_ulong( &w, "db_size_gib",               config->tiles.gui.db_size_gib );
     598           0 :     jw_obj_close( &w );
     599           0 :     jw_obj_open( &w, "rpc" );
     600           0 :       jw_bool ( &w, "enabled",                   config->tiles.rpc.enabled );
     601           0 :       jw_path ( &w, "rpc_listen_address",        config->tiles.rpc.rpc_listen_address );
     602           0 :       jw_ulong( &w, "rpc_listen_port",           config->tiles.rpc.rpc_listen_port );
     603           0 :       jw_ulong( &w, "max_http_connections",      config->tiles.rpc.max_http_connections );
     604           0 :       jw_ulong( &w, "max_websocket_connections", config->tiles.rpc.max_websocket_connections );
     605           0 :       jw_ulong( &w, "send_buffer_size_mb",       config->tiles.rpc.send_buffer_size_mb );
     606           0 :       jw_bool ( &w, "delay_startup",             config->tiles.rpc.delay_startup );
     607           0 :     jw_obj_close( &w );
     608           0 :     jw_obj_open( &w, "repair" );
     609           0 :       jw_ulong( &w, "repair_client_listen_port", config->tiles.repair.repair_client_listen_port );
     610           0 :       jw_ulong( &w, "slot_max",                  config->tiles.repair.slot_max );
     611           0 :     jw_obj_close( &w );
     612           0 :     jw_obj_open( &w, "rserve" );
     613           0 :       jw_bool ( &w, "enabled",                   config->tiles.rserve.enabled );
     614           0 :       jw_ulong( &w, "repair_serve_listen_port",  config->tiles.rserve.repair_serve_listen_port );
     615           0 :       jw_ulong( &w, "shred_storage_limit_gib",   config->tiles.rserve.shred_storage_limit_gib );
     616           0 :     jw_obj_close( &w );
     617           0 :     jw_obj_open( &w, "replay" );
     618           0 :       jw_ulong( &w, "max_transaction_lookahead_buffer_size", config->tiles.replay.max_transaction_lookahead_buffer_size );
     619           0 :       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 );
     620           0 :     jw_obj_close( &w );
     621           0 :   jw_obj_close( &w );
     622             : 
     623           0 :   jw_obj_open( &w, "capture" );
     624           0 :     jw_ulong( &w, "capture_start_slot",           config->capture.capture_start_slot );
     625           0 :     jw_path ( &w, "dump_proto_dir",               config->capture.dump_proto_dir );
     626           0 :     jw_path ( &w, "dump_syscall_name_filter",     config->capture.dump_syscall_name_filter );
     627           0 :     jw_str  ( &w, "dump_instr_program_id_filter", config->capture.dump_instr_program_id_filter );
     628           0 :     jw_path ( &w, "solcap_capture",               config->capture.solcap_capture );
     629           0 :     jw_bool ( &w, "recent_only",                  config->capture.recent_only );
     630           0 :     jw_ulong( &w, "recent_slots_per_file",        config->capture.recent_slots_per_file );
     631           0 :     jw_bool ( &w, "dump_syscall_to_pb",           config->capture.dump_syscall_to_pb );
     632           0 :     jw_bool ( &w, "dump_instr_to_pb",             config->capture.dump_instr_to_pb );
     633           0 :     jw_bool ( &w, "dump_txn_to_pb",               config->capture.dump_txn_to_pb );
     634           0 :     jw_bool ( &w, "dump_txn_as_fixture",          config->capture.dump_txn_as_fixture );
     635           0 :     jw_bool ( &w, "dump_block_to_pb",             config->capture.dump_block_to_pb );
     636           0 :   jw_obj_close( &w );
     637             : 
     638           0 :   jw_obj_open( &w, "capctx" );
     639           0 :     jw_path( &w, "path", f->capctx.path );
     640           0 :   jw_obj_close( &w );
     641             : 
     642             : 
     643           0 :   jw_raw( &w, "}" );
     644             : 
     645           0 :   if( FD_UNLIKELY( w.fail ) ) FD_LOG_ERR(( "config json does not fit in %lu bytes", buf_sz ));
     646           0 :   return (ulong)( w.cur-buf );
     647           0 : }

Generated by: LCOV version 1.14