LCOV - code coverage report
Current view: top level - app/firedancer-dev/commands - sim.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 150 0.0 %
Date: 2025-07-01 05:00:49 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/topo/fd_topob.h"
      24             : #include "../../../util/pod/fd_pod_format.h"
      25             : #include "../../../flamenco/runtime/fd_runtime.h"
      26             : #include "../../../flamenco/runtime/fd_txncache.h"
      27             : 
      28             : #include <unistd.h> /* pause */
      29             : extern fd_topo_obj_callbacks_t * CALLBACKS[];
      30             : fd_topo_run_tile_t fdctl_tile_run( fd_topo_tile_t const * tile );
      31             : 
      32             : static void
      33           0 : sim_topo( config_t * config ) {
      34           0 :   fd_topo_cpus_t cpus[1];
      35           0 :   fd_topo_cpus_init( cpus );
      36             : 
      37           0 :   fd_topo_t * topo = &config->topo;
      38           0 :   fd_topob_new( &config->topo, config->name );
      39           0 :   topo->max_page_size = fd_cstr_to_shmem_page_sz( config->hugetlbfs.max_page_size );
      40             : 
      41           0 :   enum{
      42           0 :   metric_cpu_idx=0,
      43           0 :   playback_cpu_idx,
      44           0 :   storei_cpu_idx,
      45           0 :   replay_cpu_idx,
      46           0 :   static_end_idx,
      47           0 :   };
      48             : 
      49           0 :   fd_topob_wksp( topo, "metric" );
      50           0 :   fd_topob_wksp( topo, "metric_in" );
      51           0 :   fd_topob_tile( topo, "metric", "metric", "metric_in", metric_cpu_idx, 0, 0 );
      52             : 
      53           0 :   fd_topob_wksp( topo, "playback" );
      54           0 :   fd_topob_tile( topo, "arch_p", "playback", "metric_in", playback_cpu_idx, 0, 0 );
      55             : 
      56           0 :   fd_topob_wksp( topo, "storei" );
      57           0 :   fd_topo_tile_t * storei_tile = fd_topob_tile( topo, "storei", "storei", "metric_in", storei_cpu_idx, 0, 0 );
      58             : 
      59           0 :   fd_topob_wksp( topo, "replay" );
      60           0 :   fd_topo_tile_t * replay_tile = fd_topob_tile( topo, "replay", "replay", "metric_in", replay_cpu_idx, 0, 0 );
      61             : 
      62           0 :   #define FOR(cnt) for( ulong i=0UL; i<cnt; i++ )
      63             : 
      64           0 :   fd_topob_wksp( topo, "exec" );
      65           0 :   ulong exec_tile_cnt = config->firedancer.layout.exec_tile_count;
      66           0 :   FOR(exec_tile_cnt) fd_topob_tile( topo, "exec", "exec", "metric_in", static_end_idx+i, 0, 0 );
      67             : 
      68             :   /**********************************************************************/
      69             :   /* Setup playback<->storei and storei<->replay links in topo          */
      70             :   /**********************************************************************/
      71           0 :   fd_topob_wksp( topo, "shred_storei" );
      72           0 :   fd_topob_wksp( topo, "repair_store" );
      73           0 :   fd_topob_wksp( topo, "storei_notif" );
      74           0 :   fd_topob_wksp( topo, "stake_out"    );
      75           0 :   fd_topob_wksp( topo, "store_replay" );
      76             :   /*             topo,  link_name,      wksp_name,     depth,         mtu,                    burst */
      77           0 :   fd_topob_link( topo, "shred_storei", "shred_storei", 65536UL,       4UL*FD_SHRED_STORE_MTU, 4UL+config->tiles.shred.max_pending_shred_sets );
      78           0 :   fd_topob_link( topo, "repair_store", "repair_store", 1024UL*1024UL, FD_SHRED_MAX_SZ,        128UL                                          );
      79           0 :   fd_topob_link( topo, "storei_notif", "storei_notif", 65536UL,       4UL*FD_SHRED_STORE_MTU, 4UL+config->tiles.shred.max_pending_shred_sets );
      80           0 :   fd_topob_link( topo, "stake_out",    "stake_out",    128UL,         40UL + 40200UL * 40UL,  1UL                                            );
      81           0 :   fd_topob_link( topo, "store_replay", "store_replay", 32768UL,       sizeof(ulong),          64UL                                           );
      82             : 
      83             :   /*                 topo, tile_name, tile_kind_id, link_name,      link_kind_id */
      84           0 :   fd_topob_tile_out( topo, "arch_p",  0UL,          "shred_storei", 0UL );
      85           0 :   fd_topob_tile_out( topo, "arch_p",  0UL,          "repair_store", 0UL );
      86           0 :   fd_topob_tile_in(  topo, "arch_p",  0UL,          "metric_in", "storei_notif",       0UL,          FD_TOPOB_RELIABLE,   FD_TOPOB_POLLED );
      87             : 
      88             :   /*                 topo, tile_name, tile_kind_id, fseq_wksp,   link_name,            link_kind_id, reliable,            polled */
      89           0 :   fd_topob_tile_in(  topo, "storei",  0UL,          "metric_in", "stake_out",          0UL,          FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
      90           0 :   fd_topob_tile_in(  topo, "storei",  0UL,          "metric_in", "repair_store",       0UL,          FD_TOPOB_RELIABLE,   FD_TOPOB_POLLED );
      91           0 :   fd_topob_tile_in(  topo, "storei",  0UL,          "metric_in", "shred_storei",       0UL,          FD_TOPOB_RELIABLE,   FD_TOPOB_POLLED );
      92             : 
      93             :   /*                 topo, tile_name, tile_kind_id, link_name,          link_kind_id */
      94           0 :   fd_topob_tile_out( topo, "storei",  0UL,          "store_replay",     0UL );
      95           0 :   fd_topob_tile_out( topo, "storei",  0UL,          "storei_notif",     0UL );
      96             : 
      97             :   /*                 topo, tile_name, tile_kind_id, fseq_wksp,   link_name,            link_kind_id, reliable,            polled */
      98           0 :   fd_topob_tile_in(  topo, "replay",  0UL,          "metric_in", "store_replay",       0UL,          FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED   );
      99             : 
     100             :   /*                 topo, tile_name, tile_kind_id, link_name,          link_kind_id */
     101           0 :   fd_topob_tile_out( topo, "replay",  0UL,          "stake_out",        0UL );
     102             : 
     103             :   /**********************************************************************/
     104             :   /* Setup replay<->exec links in topo                                  */
     105             :   /**********************************************************************/
     106           0 :   fd_topob_wksp( topo, "replay_exec" );
     107           0 :   for( ulong i=0; i<config->firedancer.layout.exec_tile_count; i++ ) {
     108           0 :     fd_topob_link( topo, "replay_exec", "replay_exec", 128UL, 10240UL, 1UL );
     109           0 :     fd_topob_tile_out( topo, "replay", 0UL, "replay_exec", i );
     110           0 :     fd_topob_tile_in( topo, "exec", i, "metric_in", "replay_exec", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     111           0 :   }
     112           0 :   fd_topo_tile_t * exec_tile   = &topo->tiles[ fd_topo_find_tile( topo, "exec", 0UL ) ];
     113             : 
     114             :   /**********************************************************************/
     115             :   /* Setup the shared objs used by storei, replay and exec tiles        */
     116             :   /**********************************************************************/
     117           0 :   fd_topob_wksp( topo, "bstore"      );
     118           0 :   fd_topob_wksp( topo, "poh_shred"   );
     119           0 :   fd_topob_wksp( topo, "root_slot"   );
     120           0 :   fd_topob_wksp( topo, "runtime_pub" );
     121           0 :   fd_topob_wksp( topo, "tcache"      );
     122           0 :   fd_topob_wksp( topo, "poh_slot"    );
     123           0 :   fd_topob_wksp( topo, "constipate"  );
     124           0 :   fd_topob_wksp( topo, "bank_busy"   );
     125           0 :   fd_topob_wksp( topo, "exec_spad"   );
     126           0 :   fd_topob_wksp( topo, "exec_fseq"   );
     127           0 :   fd_topo_obj_t * blockstore_obj = setup_topo_blockstore( topo,
     128           0 :                                                           "bstore",
     129           0 :                                                           config->firedancer.blockstore.shred_max,
     130           0 :                                                           config->firedancer.blockstore.block_max,
     131           0 :                                                           config->firedancer.blockstore.idx_max,
     132           0 :                                                           config->firedancer.blockstore.txn_max,
     133           0 :                                                           config->firedancer.blockstore.alloc_max );
     134           0 :   fd_topo_obj_t * poh_shred_obj = fd_topob_obj( topo, "fseq", "poh_shred" );
     135           0 :   fd_topo_obj_t * root_slot_obj = fd_topob_obj( topo, "fseq", "root_slot" );
     136           0 :   fd_topo_obj_t * runtime_pub_obj = setup_topo_runtime_pub( topo, "runtime_pub", config->firedancer.runtime.heap_size_gib<<30 );
     137           0 :   fd_topo_obj_t * txncache_obj = setup_topo_txncache( topo, "tcache",
     138           0 :       config->firedancer.runtime.limits.max_rooted_slots,
     139           0 :       config->firedancer.runtime.limits.max_live_slots,
     140           0 :       config->firedancer.runtime.limits.max_transactions_per_slot,
     141           0 :       fd_txncache_max_constipated_slots_est( config->firedancer.runtime.limits.snapshot_grace_period_seconds ) );
     142           0 :   fd_topo_obj_t * poh_slot_obj = fd_topob_obj( topo, "fseq", "poh_slot" );
     143           0 :   fd_topo_obj_t * constipated_obj = fd_topob_obj( topo, "fseq", "constipate" );
     144           0 :   fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.limits.max_banks );
     145             : 
     146           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, blockstore_obj->id, "blockstore" ) );
     147           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, poh_shred_obj->id, "poh_shred" ) );
     148           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, root_slot_obj->id, "root_slot" ) );
     149           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, runtime_pub_obj->id, "runtime_pub" ) );
     150           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, txncache_obj->id, "txncache" ) );
     151           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, poh_slot_obj->id, "poh_slot" ) );
     152           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, constipated_obj->id, "constipate" ) );
     153           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, banks_obj->id, "banks" ) );
     154             : 
     155           0 :   fd_topob_tile_uses( topo, storei_tile, blockstore_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     156           0 :   fd_topob_tile_uses( topo, storei_tile, poh_shred_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     157           0 :   fd_topob_tile_uses( topo, storei_tile, root_slot_obj, FD_SHMEM_JOIN_MODE_READ_ONLY  );
     158             : 
     159           0 :   fd_topob_tile_uses( topo, replay_tile, blockstore_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     160           0 :   fd_topob_tile_uses( topo, replay_tile, runtime_pub_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     161           0 :   fd_topob_tile_uses( topo, replay_tile, root_slot_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     162           0 :   fd_topob_tile_uses( topo, replay_tile, poh_slot_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     163           0 :   fd_topob_tile_uses( topo, replay_tile, constipated_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     164           0 :   fd_topob_tile_uses( topo, replay_tile, banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     165           0 :   for( ulong i=0UL; i<config->layout.bank_tile_count; i++ ) {
     166           0 :     fd_topo_obj_t * busy_obj = fd_topob_obj( topo, "fseq", "bank_busy" );
     167             : 
     168           0 :     fd_topob_tile_uses( topo, replay_tile, busy_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     169           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, busy_obj->id, "bank_busy.%lu", i ) );
     170           0 :   }
     171             : 
     172           0 :   for( ulong i=0UL; i<config->firedancer.layout.exec_tile_count; i++ ) {
     173           0 :     fd_topo_obj_t * exec_spad_obj = fd_topob_obj( topo, "exec_spad", "exec_spad" );
     174           0 :     fd_topo_obj_t * exec_fseq_obj = fd_topob_obj( topo, "fseq", "exec_fseq" );
     175           0 :     fd_topob_tile_uses( topo, replay_tile, exec_spad_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     176           0 :     fd_topob_tile_uses( topo, replay_tile, exec_fseq_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     177           0 :     fd_topob_tile_uses( topo, exec_tile, exec_spad_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     178           0 :     fd_topob_tile_uses( topo, exec_tile, exec_fseq_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     179           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, exec_spad_obj->id, "exec_spad.%lu", i ) );
     180           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, exec_fseq_obj->id, "exec_fseq.%lu", i ) );
     181           0 :   }
     182             : 
     183           0 :   for( ulong i=0UL; i<topo->tile_cnt; i++ ) {
     184           0 :     fd_topo_tile_t * tile = &topo->tiles[ i ];
     185           0 :     if( !strcmp( tile->name, "arch_p" ) ) {
     186           0 :       strncpy( tile->archiver.archiver_path, config->tiles.archiver.archiver_path, PATH_MAX );
     187           0 :       if( FD_UNLIKELY( 0==strlen( tile->archiver.archiver_path ) ) ) {
     188           0 :         FD_LOG_ERR(( "Archive file not found for playback" ));
     189           0 :       } else {
     190           0 :         FD_LOG_NOTICE(( "Found archive file from config: %s", tile->archiver.archiver_path ));
     191           0 :       }
     192           0 :     } else if( !fd_topo_configure_tile( tile, config ) ) {
     193           0 :       FD_LOG_ERR(( "unknown tile name %lu `%s`", i, tile->name ));
     194           0 :     }
     195             : 
     196             :     /* Override */
     197           0 :     if( !strcmp( tile->name, "replay" ) ) {
     198           0 :       strncpy( tile->replay.incremental, config->tiles.replay.incremental, sizeof(tile->replay.incremental) );
     199           0 :       strncpy( tile->replay.slots_replayed, config->tiles.replay.slots_replayed, sizeof(tile->replay.slots_replayed) );
     200           0 :       strncpy( tile->replay.snapshot, config->tiles.replay.snapshot, sizeof(tile->replay.snapshot) );
     201           0 :       strncpy( tile->replay.status_cache, config->tiles.replay.status_cache, sizeof(tile->replay.status_cache) );
     202           0 :     }
     203           0 :   }
     204             : 
     205             :   /**********************************************************************/
     206             :   /* Finish and print out the topo information                          */
     207             :   /**********************************************************************/
     208           0 :   fd_topob_finish( topo, CALLBACKS );
     209           0 :   fd_topo_print_log( /* stdout */ 1, topo );
     210           0 : }
     211             : 
     212             : static void
     213             : sim_cmd_fn( args_t *   args FD_PARAM_UNUSED,
     214           0 :             config_t * config ) {
     215           0 :   sim_topo( config );
     216             : 
     217           0 :   initialize_workspaces( config );
     218           0 :   initialize_stacks( config );
     219           0 :   fd_topo_t * topo = &config->topo;
     220           0 :   fd_topo_join_workspaces( topo, FD_SHMEM_JOIN_MODE_READ_WRITE );
     221             : 
     222             :   /* FIXME: there's no PoH tile in this mini-topology,
     223             :    *        but replay tile waits for `poh_slot!=ULONG_MAX` before starting to vote
     224             :    *        -- vote updates the root for funk/blockstore publish */
     225           0 :   ulong poh_slot_obj_id = fd_pod_query_ulong( topo->props, "poh_slot", ULONG_MAX );
     226           0 :   FD_TEST( poh_slot_obj_id!=ULONG_MAX );
     227           0 :   ulong * poh = fd_fseq_join( fd_topo_obj_laddr( topo, poh_slot_obj_id ) );
     228           0 :   fd_fseq_update( poh, 0UL );
     229             : 
     230           0 :   fd_topo_run_single_process( topo, 2, config->uid, config->gid, fdctl_tile_run, NULL );
     231           0 :   for(;;) pause();
     232           0 : }
     233             : 
     234             : static void
     235             : sim_cmd_perm( args_t *         args   FD_PARAM_UNUSED,
     236             :               fd_cap_chk_t *   chk    FD_PARAM_UNUSED,
     237           0 :               config_t const * config FD_PARAM_UNUSED ) {}
     238             : 
     239             : static void
     240             : sim_cmd_args( int *    pargc FD_PARAM_UNUSED,
     241             :               char *** pargv FD_PARAM_UNUSED,
     242           0 :               args_t * args  FD_PARAM_UNUSED ) {}
     243             : 
     244             : action_t fd_action_sim = {
     245             :   .name = "sim",
     246             :   .args = sim_cmd_args,
     247             :   .fn   = sim_cmd_fn,
     248             :   .perm = sim_cmd_perm,
     249             : };

Generated by: LCOV version 1.14