LCOV - code coverage report
Current view: top level - app/firedancer-dev/commands - sim.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 118 0.0 %
Date: 2025-10-13 04:42:14 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* The sim command spawns a smaller topology for 2 purposes:
       2             :    1. read an archive file and reproduce the frags into the storei tile
       3             :    2. reproduce the behavior of the replay tile (e.g., the set of forks)
       4             : 
       5             :    The smaller topology is:
       6             :              shred_storei          store_replay       replay_exec
       7             :    playback--------------->storei-------------->replay------------>exec
       8             :      ^      \         ---->   |  <-----       /
       9             :      |       \_______/        |        \_____/
      10             :      |      repair_store      |       stake_out
      11             :      |______storei_notif______|
      12             : 
      13             :    Some tiles are not shown such as the metric tile.
      14             : 
      15             :    The playback tile will only send the next frag to the storei tile (
      16             :    either through shred_storei or through repair_store ) after receiving
      17             :    a notification for the previous frag from storei_notif.
      18             :  */
      19             : 
      20             : #include "../../firedancer/topology.h"
      21             : #include "../../shared/commands/run/run.h" /* initialize_workspaces */
      22             : #include "../../../disco/topo/fd_cpu_topo.h" /* fd_topo_cpus */
      23             : #include "../../../disco/pack/fd_pack.h"
      24             : #include "../../../disco/pack/fd_pack_cost.h"
      25             : #include "../../../disco/topo/fd_topob.h"
      26             : #include "../../../util/pod/fd_pod_format.h"
      27             : 
      28             : #include <unistd.h> /* pause */
      29             : 
      30             : extern fd_topo_obj_callbacks_t * CALLBACKS[];
      31             : fd_topo_run_tile_t fdctl_tile_run( fd_topo_tile_t const * tile );
      32             : 
      33             : static void
      34           0 : sim_topo( config_t * config ) {
      35           0 :   fd_topo_cpus_t cpus[1];
      36           0 :   fd_topo_cpus_init( cpus );
      37             : 
      38           0 :   fd_topo_t * topo = &config->topo;
      39           0 :   fd_topob_new( &config->topo, config->name );
      40           0 :   topo->max_page_size = fd_cstr_to_shmem_page_sz( config->hugetlbfs.max_page_size );
      41             : 
      42           0 :   enum{
      43           0 :   metric_cpu_idx=0,
      44           0 :   playback_cpu_idx,
      45           0 :   storei_cpu_idx,
      46           0 :   replay_cpu_idx,
      47           0 :   static_end_idx,
      48           0 :   };
      49             : 
      50           0 :   fd_topob_wksp( topo, "metric" );
      51           0 :   fd_topob_wksp( topo, "metric_in" );
      52           0 :   fd_topob_tile( topo, "metric", "metric", "metric_in", metric_cpu_idx, 0, 0 );
      53             : 
      54           0 :   fd_topob_wksp( topo, "playback" );
      55           0 :   fd_topob_tile( topo, "arch_p", "playback", "metric_in", playback_cpu_idx, 0, 0 );
      56             : 
      57           0 :   fd_topob_wksp( topo, "storei" );
      58           0 :   fd_topo_tile_t * storei_tile = fd_topob_tile( topo, "storei", "storei", "metric_in", storei_cpu_idx, 0, 0 );
      59             : 
      60           0 :   fd_topob_wksp( topo, "replay" );
      61           0 :   fd_topo_tile_t * replay_tile = fd_topob_tile( topo, "replay", "replay", "metric_in", replay_cpu_idx, 0, 0 );
      62             : 
      63           0 :   #define FOR(cnt) for( ulong i=0UL; i<cnt; i++ )
      64             : 
      65           0 :   fd_topob_wksp( topo, "exec" );
      66           0 :   ulong exec_tile_cnt = config->firedancer.layout.exec_tile_count;
      67           0 :   FOR(exec_tile_cnt) fd_topob_tile( topo, "exec", "exec", "metric_in", static_end_idx+i, 0, 0 );
      68             : 
      69             :   /**********************************************************************/
      70             :   /* Setup playback<->storei and storei<->replay links in topo          */
      71             :   /**********************************************************************/
      72           0 :   fd_topob_wksp( topo, "shred_storei" );
      73           0 :   fd_topob_wksp( topo, "repair_store" );
      74           0 :   fd_topob_wksp( topo, "storei_notif" );
      75           0 :   fd_topob_wksp( topo, "replay_stake" );
      76           0 :   fd_topob_wksp( topo, "store_replay" );
      77             :   /*             topo,  link_name,      wksp_name,     depth,         mtu,                    burst */
      78           0 :   fd_topob_link( topo, "shred_storei", "shred_storei", 65536UL,       4UL*FD_SHRED_STORE_MTU, 4UL+config->tiles.shred.max_pending_shred_sets );
      79           0 :   fd_topob_link( topo, "repair_store", "repair_store", 1024UL*1024UL, FD_SHRED_MAX_SZ,        128UL                                          );
      80           0 :   fd_topob_link( topo, "storei_notif", "storei_notif", 65536UL,       4UL*FD_SHRED_STORE_MTU, 4UL+config->tiles.shred.max_pending_shred_sets );
      81           0 :   fd_topob_link( topo, "replay_stake", "replay_stake", 128UL,         40UL + 40200UL * 40UL,  1UL                                            );
      82           0 :   fd_topob_link( topo, "store_replay", "store_replay", 32768UL,       sizeof(ulong),          64UL                                           );
      83             : 
      84             :   /*                 topo, tile_name, tile_kind_id, link_name,      link_kind_id */
      85           0 :   fd_topob_tile_out( topo, "arch_p",  0UL,          "shred_storei", 0UL );
      86           0 :   fd_topob_tile_out( topo, "arch_p",  0UL,          "repair_store", 0UL );
      87           0 :   fd_topob_tile_in(  topo, "arch_p",  0UL,          "metric_in", "storei_notif",       0UL,          FD_TOPOB_RELIABLE,   FD_TOPOB_POLLED );
      88             : 
      89             :   /*                 topo, tile_name, tile_kind_id, fseq_wksp,   link_name,            link_kind_id, reliable,            polled */
      90           0 :   fd_topob_tile_in(  topo, "storei",  0UL,          "metric_in", "replay_stake",       0UL,          FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
      91           0 :   fd_topob_tile_in(  topo, "storei",  0UL,          "metric_in", "repair_store",       0UL,          FD_TOPOB_RELIABLE,   FD_TOPOB_POLLED );
      92           0 :   fd_topob_tile_in(  topo, "storei",  0UL,          "metric_in", "shred_storei",       0UL,          FD_TOPOB_RELIABLE,   FD_TOPOB_POLLED );
      93             : 
      94             :   /*                 topo, tile_name, tile_kind_id, link_name,          link_kind_id */
      95           0 :   fd_topob_tile_out( topo, "storei",  0UL,          "store_replay",     0UL );
      96           0 :   fd_topob_tile_out( topo, "storei",  0UL,          "storei_notif",     0UL );
      97             : 
      98             :   /*                 topo, tile_name, tile_kind_id, fseq_wksp,   link_name,            link_kind_id, reliable,            polled */
      99           0 :   fd_topob_tile_in(  topo, "replay",  0UL,          "metric_in", "store_replay",       0UL,          FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED   );
     100             : 
     101             :   /*                 topo, tile_name, tile_kind_id, link_name,          link_kind_id */
     102           0 :   fd_topob_tile_out( topo, "replay",  0UL,          "replay_stake",     0UL );
     103             : 
     104             :   /**********************************************************************/
     105             :   /* Setup replay-->exec links in topo                                  */
     106             :   /**********************************************************************/
     107           0 :   fd_topob_wksp( topo, "replay_exec" );
     108           0 :   fd_topob_link( topo, "replay_exec", "replay_exec", 16384UL, 2240UL, 1UL );
     109           0 :   fd_topob_tile_out( topo, "replay", 0UL, "replay_exec", 0UL );
     110           0 :   for( ulong i=0; i<config->firedancer.layout.exec_tile_count; i++ ) {
     111           0 :     fd_topob_tile_in( topo, "exec", i, "metric_in", "replay_exec", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     112           0 :   }
     113           0 :   fd_topo_tile_t * exec_tile   = &topo->tiles[ fd_topo_find_tile( topo, "exec", 0UL ) ];
     114             : 
     115             :   /**********************************************************************/
     116             :   /* Setup the shared objs used by storei, replay and exec tiles        */
     117             :   /**********************************************************************/
     118           0 :   fd_topob_wksp( topo, "bstore"      );
     119           0 :   fd_topob_wksp( topo, "poh_shred"   );
     120           0 :   fd_topob_wksp( topo, "root_slot"   );
     121           0 :   fd_topob_wksp( topo, "txncache"    );
     122           0 :   fd_topob_wksp( topo, "poh_slot"    );
     123           0 :   fd_topob_wksp( topo, "bank_busy"   );
     124           0 :   fd_topob_wksp( topo, "exec_spad"   );
     125           0 :   fd_topo_obj_t * poh_shred_obj = fd_topob_obj( topo, "fseq", "poh_shred" );
     126           0 :   fd_topo_obj_t * root_slot_obj = fd_topob_obj( topo, "fseq", "root_slot" );
     127           0 :   fd_topo_obj_t * txncache_obj = setup_topo_txncache( topo, "txncache",
     128           0 :       config->firedancer.runtime.max_live_slots,
     129           0 :       fd_ulong_pow2_up( FD_PACK_MAX_TXNCACHE_TXN_PER_SLOT ) );
     130           0 :   fd_topo_obj_t * poh_slot_obj = fd_topob_obj( topo, "fseq", "poh_slot" );
     131           0 :   fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.max_live_slots, config->firedancer.runtime.max_fork_width );
     132             : 
     133           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, poh_shred_obj->id, "poh_shred" ) );
     134           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, root_slot_obj->id, "root_slot" ) );
     135           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, txncache_obj->id, "txncache" ) );
     136           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, poh_slot_obj->id, "poh_slot" ) );
     137           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, banks_obj->id, "banks" ) );
     138             : 
     139           0 :   fd_topob_tile_uses( topo, storei_tile, poh_shred_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     140           0 :   fd_topob_tile_uses( topo, storei_tile, root_slot_obj, FD_SHMEM_JOIN_MODE_READ_ONLY  );
     141             : 
     142           0 :   fd_topob_tile_uses( topo, replay_tile, root_slot_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     143           0 :   fd_topob_tile_uses( topo, replay_tile, poh_slot_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     144           0 :   fd_topob_tile_uses( topo, replay_tile, banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     145           0 :   for( ulong i=0UL; i<config->layout.bank_tile_count; i++ ) {
     146           0 :     fd_topo_obj_t * busy_obj = fd_topob_obj( topo, "fseq", "bank_busy" );
     147             : 
     148           0 :     fd_topob_tile_uses( topo, replay_tile, busy_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     149           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, busy_obj->id, "bank_busy.%lu", i ) );
     150           0 :   }
     151             : 
     152           0 :   for( ulong i=0UL; i<config->firedancer.layout.exec_tile_count; i++ ) {
     153           0 :     fd_topo_obj_t * exec_spad_obj = fd_topob_obj( topo, "exec_spad", "exec_spad" );
     154           0 :     fd_topob_tile_uses( topo, exec_tile, exec_spad_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     155           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, exec_spad_obj->id, "exec_spad.%lu", i ) );
     156           0 :   }
     157             : 
     158           0 :   for( ulong i=0UL; i<topo->tile_cnt; i++ ) {
     159           0 :     fd_topo_tile_t * tile = &topo->tiles[ i ];
     160           0 :     if( !strcmp( tile->name, "arch_p" ) ) {
     161           0 :       strncpy( tile->archiver.rocksdb_path, config->tiles.archiver.rocksdb_path, PATH_MAX );
     162           0 :       if( FD_UNLIKELY( 0==strlen( tile->archiver.rocksdb_path ) ) ) {
     163           0 :         FD_LOG_ERR(( "Archive file not found for playback" ));
     164           0 :       } else {
     165           0 :         FD_LOG_NOTICE(( "Found archive file from config: %s", tile->archiver.rocksdb_path ));
     166           0 :       }
     167           0 :     } else {
     168           0 :       fd_topo_configure_tile( tile, config );
     169           0 :     }
     170           0 :   }
     171             : 
     172             :   /**********************************************************************/
     173             :   /* Finish and print out the topo information                          */
     174             :   /**********************************************************************/
     175           0 :   fd_topob_finish( topo, CALLBACKS );
     176           0 :   fd_topo_print_log( /* stdout */ 1, topo );
     177           0 : }
     178             : 
     179             : static void
     180             : sim_cmd_fn( args_t *   args FD_PARAM_UNUSED,
     181           0 :             config_t * config ) {
     182           0 :   sim_topo( config );
     183             : 
     184           0 :   initialize_workspaces( config );
     185           0 :   initialize_stacks( config );
     186           0 :   fd_topo_t * topo = &config->topo;
     187           0 :   fd_topo_join_workspaces( topo, FD_SHMEM_JOIN_MODE_READ_WRITE );
     188             : 
     189             :   /* FIXME: there's no PoH tile in this mini-topology,
     190             :    *        but replay tile waits for `poh_slot!=ULONG_MAX` before starting to vote
     191             :    *        -- vote updates the root for funk/blockstore publish */
     192           0 :   ulong poh_slot_obj_id = fd_pod_query_ulong( topo->props, "poh_slot", ULONG_MAX );
     193           0 :   FD_TEST( poh_slot_obj_id!=ULONG_MAX );
     194           0 :   ulong * poh = fd_fseq_join( fd_topo_obj_laddr( topo, poh_slot_obj_id ) );
     195           0 :   fd_fseq_update( poh, 0UL );
     196             : 
     197           0 :   fd_topo_run_single_process( topo, 2, config->uid, config->gid, fdctl_tile_run );
     198           0 :   for(;;) pause();
     199           0 : }
     200             : 
     201             : static void
     202             : sim_cmd_perm( args_t *         args   FD_PARAM_UNUSED,
     203             :               fd_cap_chk_t *   chk    FD_PARAM_UNUSED,
     204           0 :               config_t const * config FD_PARAM_UNUSED ) {}
     205             : 
     206             : static void
     207             : sim_cmd_args( int *    pargc FD_PARAM_UNUSED,
     208             :               char *** pargv FD_PARAM_UNUSED,
     209           0 :               args_t * args  FD_PARAM_UNUSED ) {}
     210             : 
     211             : action_t fd_action_sim = {
     212             :   .name = "sim",
     213             :   .args = sim_cmd_args,
     214             :   .fn   = sim_cmd_fn,
     215             :   .perm = sim_cmd_perm,
     216             : };

Generated by: LCOV version 1.14