LCOV - code coverage report
Current view: top level - app/firedancer-dev/commands - backtest.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 274 0.0 %
Date: 2025-08-05 05:04:49 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /* The backtest command spawns a smaller topology for replaying shreds from
       2             :    rocksdb (or other sources TBD) and reproduce the behavior of replay tile.
       3             : 
       4             :    The smaller topology is:
       5             :            repair_repla         replay_exec       exec_writer
       6             :    backtest-------------->replay------------->exec------------->writer
       7             :      ^                    |^ | |                                   ^
       8             :      |____________________|| | |___________________________________|
       9             :           replay_notif     | |
      10             :                            | |------------------------------>no consumer
      11             :     no producer-------------  stake_out, send_out, poh_out
      12             :                 store_replay
      13             : 
      14             : */
      15             : 
      16             : #include "../../firedancer/topology.h"
      17             : #include "../../shared/commands/configure/configure.h"
      18             : #include "../../shared/commands/run/run.h" /* initialize_workspaces */
      19             : #include "../../shared/fd_config.h" /* config_t */
      20             : #include "../../platform/fd_sys_util.h"
      21             : #include "../../../disco/tiles.h"
      22             : #include "../../../disco/topo/fd_topob.h"
      23             : #include "../../../disco/metrics/fd_metrics.h"
      24             : #include "../../../util/pod/fd_pod_format.h"
      25             : #include "../../../discof/replay/fd_replay_notif.h"
      26             : #include "../../../discof/repair/fd_fec_chainer.h"
      27             : #include "../main.h"
      28             : 
      29             : #include <unistd.h> /* pause */
      30             : 
      31             : extern fd_topo_obj_callbacks_t * CALLBACKS[];
      32             : fd_topo_run_tile_t fdctl_tile_run( fd_topo_tile_t const * tile );
      33             : 
      34             : static void
      35           0 : backtest_topo( config_t * config ) {
      36           0 :   ulong exec_tile_cnt   = config->firedancer.layout.exec_tile_count;
      37           0 :   ulong writer_tile_cnt = config->firedancer.layout.writer_tile_count;
      38             : 
      39           0 :   fd_topo_t * topo = { 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           0 :   topo->gigantic_page_threshold = config->hugetlbfs.gigantic_page_threshold_mib << 20;
      42             : 
      43           0 :   ulong cpu_idx = 0;
      44             : 
      45             :   /**********************************************************************/
      46             :   /* Add the metric tile to topo                                        */
      47             :   /**********************************************************************/
      48           0 :   fd_topob_wksp( topo, "metric" );
      49           0 :   fd_topob_wksp( topo, "metric_in" );
      50           0 :   fd_topob_tile( topo, "metric", "metric", "metric_in", cpu_idx++, 0, 0 );
      51             : 
      52             :   /**********************************************************************/
      53             :   /* Add the backtest tile to topo                                      */
      54             :   /**********************************************************************/
      55           0 :   fd_topob_wksp( topo, "back" );
      56           0 :   fd_topo_tile_t * backtest_tile = fd_topob_tile( topo, "back", "back", "metric_in", cpu_idx++, 0, 0 );
      57             : 
      58             :   /**********************************************************************/
      59             :   /* Add the replay tile to topo                                        */
      60             :   /**********************************************************************/
      61           0 :   fd_topob_wksp( topo, "replay" );
      62           0 :   fd_topo_tile_t * replay_tile = fd_topob_tile( topo, "replay", "replay", "metric_in", cpu_idx++, 0, 0 );
      63             : 
      64             :   /* specified by [tiles.replay] */
      65             : 
      66           0 :   fd_topob_wksp( topo, "funk" );
      67           0 :   fd_topo_obj_t * funk_obj = setup_topo_funk( topo, "funk",
      68           0 :       config->firedancer.funk.max_account_records,
      69           0 :       config->firedancer.funk.max_database_transactions,
      70           0 :       config->firedancer.funk.heap_size_gib,
      71           0 :       config->firedancer.funk.lock_pages );
      72             : 
      73           0 :   fd_topob_tile_uses( topo, replay_tile, funk_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
      74             : 
      75             :   /**********************************************************************/
      76             :   /* Add the executor tiles to topo                                     */
      77             :   /**********************************************************************/
      78           0 :   fd_topob_wksp( topo, "exec" );
      79           0 :   #define FOR(cnt) for( ulong i=0UL; i<cnt; i++ )
      80           0 :   FOR(exec_tile_cnt) fd_topob_tile( topo, "exec",   "exec",   "metric_in", cpu_idx++, 0, 0 );
      81             : 
      82             :   /**********************************************************************/
      83             :   /* Add the writer tiles to topo                                       */
      84             :   /**********************************************************************/
      85           0 :   fd_topob_wksp( topo, "writer" );
      86           0 :   FOR(writer_tile_cnt) fd_topob_tile( topo, "writer",  "writer",  "metric_in",  cpu_idx++, 0, 0 );
      87             : 
      88             :   /**********************************************************************/
      89             :   /* Add the snapshot tiles to topo                                       */
      90             :   /**********************************************************************/
      91           0 :   fd_topob_wksp( topo, "snaprd" );
      92           0 :   fd_topob_wksp( topo, "snapdc" );
      93           0 :   fd_topob_wksp( topo, "snapin" );
      94           0 :   fd_topo_tile_t * snaprd_tile = fd_topob_tile( topo, "snaprd",  "snaprd",  "metric_in",  cpu_idx++, 0, 0 );
      95           0 :   fd_topo_tile_t * snapdc_tile = fd_topob_tile( topo, "snapdc",  "snapdc",  "metric_in",  cpu_idx++, 0, 0 );
      96           0 :   fd_topo_tile_t * snapin_tile = fd_topob_tile( topo, "snapin",  "snapin",  "metric_in",  cpu_idx++, 0, 0 );
      97           0 :   snaprd_tile->allow_shutdown = 1;
      98           0 :   snapdc_tile->allow_shutdown = 1;
      99           0 :   snapin_tile->allow_shutdown = 1;
     100             : 
     101             :   /**********************************************************************/
     102             :   /* Setup backtest->replay link (repair_repla) in topo                 */
     103             :   /**********************************************************************/
     104             : 
     105             :   /* The repair tile is replaced by the backtest tile for the repair to
     106             :      replay link.  The frag interface is a "slice", ie. entry batch,
     107             :      which is provided by the backtest tile, which reads in the entry
     108             :      batches from the CLI-specified source (eg. RocksDB). */
     109             : 
     110           0 :   fd_topob_wksp( topo, "repair_repla" );
     111           0 :   fd_topob_link( topo, "repair_repla", "repair_repla", 65536UL, sizeof(fd_fec_out_t), 1UL );
     112           0 :   fd_topob_tile_in( topo, "replay", 0UL, "metric_in", "repair_repla", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     113           0 :   fd_topob_tile_out( topo, "back", 0UL, "repair_repla", 0UL );
     114             : 
     115             :   /**********************************************************************/
     116             :   /* Setup snapshot links in topo                                       */
     117             :   /**********************************************************************/
     118           0 :   fd_topob_wksp( topo, "snap_zstd" );
     119           0 :   fd_topob_wksp( topo, "snap_stream");
     120           0 :   fd_topob_wksp( topo, "snapdc_rd" );
     121           0 :   fd_topob_wksp( topo, "snapin_rd" );
     122           0 :   fd_topob_wksp( topo, "snap_out" );
     123           0 :   fd_topob_wksp( topo, "replay_manif" );
     124             :   /* TODO: Should be depth of 1 or 2, not 4, but it causes backpressure
     125             :      from the replay tile parsing the manifest, remove when this is
     126             :      fixed. */
     127           0 :   fd_topob_link( topo, "snap_out", "snap_out", 4UL, 5UL*(1UL<<30UL), 1UL );
     128             : 
     129           0 :   fd_topob_link( topo, "snap_zstd",   "snap_zstd",   8192UL, 16384UL,    1UL );
     130           0 :   fd_topob_link( topo, "snap_stream", "snap_stream", 2048UL, USHORT_MAX, 1UL );
     131           0 :   fd_topob_link( topo, "snapdc_rd", "snapdc_rd", 128UL, 0UL, 1UL );
     132           0 :   fd_topob_link( topo, "snapin_rd", "snapin_rd", 128UL, 0UL, 1UL );
     133             : 
     134           0 :   fd_topob_tile_out( topo, "snaprd", 0UL, "snap_zstd",   0UL );
     135           0 :   fd_topob_tile_in ( topo, "snapdc", 0UL, "metric_in",   "snap_zstd", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     136           0 :   fd_topob_tile_out( topo, "snapdc", 0UL, "snap_stream", 0UL );
     137           0 :   fd_topob_tile_in ( topo, "snapin", 0UL, "metric_in",   "snap_stream", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED   );
     138           0 :   fd_topob_tile_out( topo, "snapin", 0UL, "snap_out",    0UL );
     139           0 :   fd_topob_tile_in ( topo, "replay", 0UL, "metric_in",   "snap_out", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     140             : 
     141           0 :   fd_topob_tile_in( topo, "snaprd", 0UL, "metric_in", "snapdc_rd", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     142           0 :   fd_topob_tile_out( topo, "snapdc", 0UL, "snapdc_rd", 0UL );
     143           0 :   fd_topob_tile_in( topo, "snaprd", 0UL, "metric_in", "snapin_rd", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     144           0 :   fd_topob_tile_out( topo, "snapin", 0UL, "snapin_rd", 0UL );
     145             : 
     146             :   /**********************************************************************/
     147             :   /* More backtest->replay links in topo                                */
     148             :   /**********************************************************************/
     149             : 
     150             :   /* The tower tile is replaced by the backtest tile for the tower to
     151             :      replay link.  The backtest tile simply sends monotonically
     152             :      increasing rooted slot numbers to the replay tile, once after each
     153             :      "replayed a full slot" notification received from the replay tile.
     154             :      This allows the replay tile to advance its watermark, and publish
     155             :      various data structures.  This is an oversimplified barebones mock
     156             :      of the tower tile. */
     157           0 :   fd_topob_wksp( topo, "tower_replay" );
     158           0 :   fd_topob_link( topo, "tower_replay", "tower_replay", 128UL, 0UL, 1UL );
     159           0 :   fd_topob_tile_in( topo, "replay", 0UL, "metric_in", "tower_replay", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     160           0 :   fd_topob_tile_out( topo, "back", 0UL, "tower_replay", 0UL );
     161             : 
     162             :   /**********************************************************************/
     163             :   /* Setup replay->stake/send/poh links in topo w/o consumers         */
     164             :   /**********************************************************************/
     165           0 :   fd_topob_wksp( topo, "stake_out"    );
     166           0 :   fd_topob_wksp( topo, "replay_poh"   );
     167             : 
     168           0 :   fd_topob_link( topo, "stake_out",   "stake_out",   128UL, 40UL + 40200UL * 40UL, 1UL );
     169           0 :   ulong bank_tile_cnt   = config->layout.bank_tile_count;
     170           0 :   FOR(bank_tile_cnt) fd_topob_link( topo, "replay_poh", "replay_poh", 128UL, (4096UL*sizeof(fd_txn_p_t))+sizeof(fd_microblock_trailer_t), 1UL );
     171             : 
     172           0 :   fd_topob_tile_out( topo, "replay", 0UL, "stake_out",   0UL );
     173           0 :   FOR(bank_tile_cnt) fd_topob_tile_out( topo, "replay", 0UL, "replay_poh", i );
     174             : 
     175           0 :   topo->links[ replay_tile->out_link_id[ fd_topo_find_tile_out_link( topo, replay_tile, "stake_out",   0 ) ] ].permit_no_consumers = 1;
     176           0 :   FOR(bank_tile_cnt) topo->links[ replay_tile->out_link_id[ fd_topo_find_tile_out_link( topo, replay_tile, "replay_poh", i ) ] ].permit_no_consumers = 1;
     177             : 
     178             :   /**********************************************************************/
     179             :   /* Setup replay->backtest link (replay_notif) in topo                 */
     180             :   /**********************************************************************/
     181           0 :   fd_topob_wksp( topo, "replay_notif" );
     182           0 :   fd_topob_link( topo, "replay_notif", "replay_notif", FD_REPLAY_NOTIF_DEPTH, FD_REPLAY_NOTIF_MTU, 1UL );
     183           0 :   fd_topob_tile_in(  topo, "back", 0UL, "metric_in", "replay_notif", 0UL, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     184           0 :   fd_topob_tile_out( topo, "replay", 0UL, "replay_notif", 0UL );
     185             : 
     186             :   /**********************************************************************/
     187             :   /* Setup replay->exec links in topo                                   */
     188             :   /**********************************************************************/
     189           0 :   fd_topob_wksp( topo, "replay_exec" );
     190           0 :   for( ulong i=0; i<exec_tile_cnt; i++ ) {
     191           0 :     fd_topob_link( topo, "replay_exec", "replay_exec", 128UL, 10240UL, exec_tile_cnt );
     192           0 :     fd_topob_tile_out( topo, "replay", 0UL, "replay_exec", i );
     193           0 :     fd_topob_tile_in( topo, "exec", i, "metric_in", "replay_exec", i, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     194           0 :   }
     195             : 
     196             :   /**********************************************************************/
     197             :   /* Setup exec->writer links in topo                                   */
     198             :   /**********************************************************************/
     199           0 :   fd_topob_wksp( topo, "exec_writer" );
     200           0 :   FOR(exec_tile_cnt) fd_topob_link( topo, "exec_writer", "exec_writer", 128UL, FD_EXEC_WRITER_MTU, 1UL );
     201           0 :   FOR(exec_tile_cnt) fd_topob_tile_out( topo, "exec", i, "exec_writer", i );
     202           0 :   FOR(writer_tile_cnt) for( ulong j=0UL; j<exec_tile_cnt; j++ )
     203           0 :     fd_topob_tile_in( topo, "writer", i, "metric_in", "exec_writer", j, FD_TOPOB_RELIABLE, FD_TOPOB_POLLED );
     204             : 
     205             :   /**********************************************************************/
     206             :   /* Setup the shared objs used by replay and exec tiles                */
     207             :   /**********************************************************************/
     208             : 
     209           0 :   fd_topob_wksp( topo, "slot_fseqs"  ); /* fseqs for marked slots eg. turbine slot */
     210             : 
     211           0 :   fd_topob_wksp( topo, "store" );
     212           0 :   fd_topo_obj_t * store_obj = setup_topo_store( topo, "store", config->firedancer.store.max_completed_shred_sets, 1 );
     213           0 :   fd_topob_tile_uses( topo, backtest_tile, store_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     214           0 :   fd_topob_tile_uses( topo, replay_tile, store_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     215           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, store_obj->id, "store" ) );
     216             : 
     217           0 :   fd_topo_obj_t * root_slot_obj = fd_topob_obj( topo, "fseq", "slot_fseqs" );
     218           0 :   fd_topob_tile_uses( topo, backtest_tile,  root_slot_obj, FD_SHMEM_JOIN_MODE_READ_ONLY  );
     219           0 :   fd_topob_tile_uses( topo, replay_tile, root_slot_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     220           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, root_slot_obj->id, "root_slot" ) );
     221             : 
     222           0 :   fd_topo_obj_t * turbine_slot0_obj = fd_topob_obj( topo, "fseq", "slot_fseqs" );
     223           0 :   fd_topob_tile_uses( topo, backtest_tile, turbine_slot0_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     224           0 :   fd_topob_tile_uses( topo, replay_tile, turbine_slot0_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     225           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, turbine_slot0_obj->id, "turbine_slot0" ) );
     226             : 
     227           0 :   fd_topo_obj_t * turbine_slot_obj = fd_topob_obj( topo, "fseq", "slot_fseqs" );
     228           0 :   fd_topob_tile_uses( topo, backtest_tile, turbine_slot_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     229           0 :   fd_topob_tile_uses( topo, replay_tile, turbine_slot_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     230           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, turbine_slot_obj->id, "turbine_slot" ) );
     231             : 
     232             :   /* runtime_pub_obj shared by replay, exec and writer tiles */
     233           0 :   fd_topob_wksp( topo, "runtime_pub" );
     234           0 :   fd_topo_obj_t * runtime_pub_obj = setup_topo_runtime_pub( topo, "runtime_pub", config->firedancer.runtime.heap_size_gib<<30 );
     235           0 :   fd_topob_tile_uses( topo, replay_tile, runtime_pub_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     236           0 :   FOR(exec_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], runtime_pub_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     237           0 :   FOR(writer_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "writer", i ) ], runtime_pub_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     238           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, runtime_pub_obj->id, "runtime_pub" ) );
     239             : 
     240             :   /* banks_obj shared by replay, exec and writer tiles */
     241           0 :   fd_topob_wksp( topo, "banks" );
     242           0 :   fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.limits.max_total_banks, config->firedancer.runtime.limits.max_fork_width );
     243           0 :   fd_topob_tile_uses( topo, replay_tile, banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     244           0 :   FOR(exec_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     245           0 :   FOR(writer_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "writer", i ) ], banks_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     246           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, banks_obj->id, "banks" ) );
     247             : 
     248             :   /* bank_hash_cmp_obj shared by replay, exec and writer tiles */
     249           0 :   fd_topob_wksp( topo, "bh_cmp" );
     250           0 :   fd_topo_obj_t * bank_hash_cmp_obj = setup_topo_bank_hash_cmp( topo, "bh_cmp" );
     251           0 :   fd_topob_tile_uses( topo, replay_tile, bank_hash_cmp_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     252           0 :   FOR(exec_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], bank_hash_cmp_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     253           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, bank_hash_cmp_obj->id, "bh_cmp" ) );
     254             : 
     255             :   /* exec_spad_obj shared by replay, exec and writer tiles */
     256           0 :   fd_topob_wksp( topo, "exec_spad" );
     257           0 :   for( ulong i=0UL; i<exec_tile_cnt; i++ ) {
     258           0 :     fd_topo_obj_t * exec_spad_obj = fd_topob_obj( topo, "exec_spad", "exec_spad" );
     259           0 :     fd_topob_tile_uses( topo, replay_tile, exec_spad_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     260           0 :     fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], exec_spad_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     261           0 :     for( ulong j=0UL; j<writer_tile_cnt; j++ ) {
     262             :       /* For txn_ctx. */
     263           0 :       fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "writer", j ) ], exec_spad_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     264           0 :     }
     265           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, exec_spad_obj->id, "exec_spad.%lu", i ) );
     266           0 :   }
     267             : 
     268             :   /* exec_fseq_obj shared by replay and exec tiles */
     269           0 :   fd_topob_wksp( topo, "exec_fseq" );
     270           0 :   for( ulong i=0UL; i<exec_tile_cnt; i++ ) {
     271           0 :     fd_topo_obj_t * exec_fseq_obj = fd_topob_obj( topo, "fseq", "exec_fseq" );
     272           0 :     fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], exec_fseq_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     273           0 :     fd_topob_tile_uses( topo, replay_tile, exec_fseq_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
     274           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, exec_fseq_obj->id, "exec_fseq.%lu", i ) );
     275           0 :   }
     276             : 
     277             :   /* writer_fseq_obj shared by replay and writer tiles */
     278           0 :   fd_topob_wksp( topo, "writer_fseq" );
     279           0 :   for( ulong i=0UL; i<writer_tile_cnt; i++ ) {
     280           0 :     fd_topo_obj_t * writer_fseq_obj = fd_topob_obj( topo, "fseq", "writer_fseq" );
     281           0 :     fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "writer", i ) ], writer_fseq_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     282           0 :     fd_topob_tile_uses( topo, replay_tile, writer_fseq_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     283           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, writer_fseq_obj->id, "writer_fseq.%lu", i ) );
     284           0 :   }
     285             : 
     286             :   /* txncache_obj, busy_obj and poh_slot_obj only by replay tile */
     287           0 :   fd_topob_wksp( topo, "tcache"      );
     288           0 :   fd_topob_wksp( topo, "bank_busy"   );
     289           0 :   fd_topo_obj_t * txncache_obj = setup_topo_txncache( topo, "tcache",
     290           0 :       config->firedancer.runtime.limits.max_rooted_slots,
     291           0 :       config->firedancer.runtime.limits.max_live_slots,
     292           0 :       config->firedancer.runtime.limits.max_transactions_per_slot );
     293           0 :   fd_topob_tile_uses( topo, replay_tile, txncache_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     294           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, txncache_obj->id, "txncache" ) );
     295           0 :   for( ulong i=0UL; i<bank_tile_cnt; i++ ) {
     296           0 :     fd_topo_obj_t * busy_obj = fd_topob_obj( topo, "fseq", "bank_busy" );
     297           0 :     fd_topob_tile_uses( topo, replay_tile, busy_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     298           0 :     FD_TEST( fd_pod_insertf_ulong( topo->props, busy_obj->id, "bank_busy.%lu", i ) );
     299           0 :   }
     300             : 
     301             :   /* Replay decoded manifest dcache topo obj */
     302           0 :   fd_topo_obj_t * replay_manifest_dcache = fd_topob_obj( topo, "dcache", "replay_manif" );
     303           0 :   fd_pod_insertf_ulong( topo->props, 2UL << 30UL, "obj.%lu.data_sz", replay_manifest_dcache->id );
     304           0 :   fd_pod_insert_ulong(  topo->props, "manifest_dcache", replay_manifest_dcache->id );
     305             : 
     306           0 :   fd_topob_tile_uses( topo, snapin_tile, funk_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
     307           0 :   fd_topob_tile_uses( topo, snapin_tile, replay_manifest_dcache, FD_SHMEM_JOIN_MODE_READ_WRITE );
     308           0 :   fd_topob_tile_uses( topo, replay_tile, replay_manifest_dcache, FD_SHMEM_JOIN_MODE_READ_ONLY );
     309             : 
     310           0 :   for( ulong i=0UL; i<topo->tile_cnt; i++ ) {
     311           0 :     fd_topo_tile_t * tile = &topo->tiles[ i ];
     312           0 :     if( !fd_topo_configure_tile( tile, config ) ) {
     313           0 :       FD_LOG_ERR(( "unknown tile name %lu `%s`", i, tile->name ));
     314           0 :     }
     315             : 
     316             :     /* Override */
     317           0 :     if( !strcmp( tile->name, "replay" ) ) {
     318           0 :       tile->replay.enable_bank_hash_cmp = 0;
     319           0 :       tile->replay.enable_features_cnt = config->tiles.replay.enable_features_cnt;
     320           0 :       for( ulong i = 0; i < tile->replay.enable_features_cnt; i++ ) {
     321           0 :         strncpy( tile->replay.enable_features[i], config->tiles.replay.enable_features[i], sizeof(tile->replay.enable_features[i]) );
     322           0 :       }
     323           0 :     }
     324           0 :   }
     325             : 
     326             :   /**********************************************************************/
     327             :   /* Finish and print out the topo information                          */
     328             :   /**********************************************************************/
     329           0 :   fd_topob_finish( topo, CALLBACKS );
     330           0 : }
     331             : 
     332             : extern int * fd_log_private_shared_lock;
     333             : 
     334             : static void
     335           0 : backtest_cmd_topo( config_t * config ) {
     336           0 :   backtest_topo( config );
     337           0 : }
     338             : 
     339             : args_t
     340           0 : configure_args( void ) {
     341           0 :   args_t args = {
     342           0 :     .configure.command = CONFIGURE_CMD_INIT,
     343           0 :   };
     344             : 
     345           0 :   ulong stage_idx = 0UL;
     346           0 :   args.configure.stages[ stage_idx++ ] = &fd_cfg_stage_hugetlbfs;
     347           0 :   args.configure.stages[ stage_idx++ ] = &fd_cfg_stage_normalpage;
     348           0 :   args.configure.stages[ stage_idx++ ] = &fd_cfg_stage_snapshots;
     349           0 :   args.configure.stages[ stage_idx++ ] = NULL;
     350             : 
     351           0 :   return args;
     352           0 : }
     353             : 
     354             : void
     355             : backtest_cmd_perm( args_t *         args FD_PARAM_UNUSED,
     356             :                    fd_cap_chk_t *   chk,
     357           0 :                    config_t const * config ) {
     358           0 :   args_t c_args = configure_args();
     359           0 :   configure_cmd_perm( &c_args, chk, config );
     360           0 :   run_cmd_perm( NULL, chk, config );
     361           0 : }
     362             : 
     363             : static void
     364             : backtest_cmd_fn( args_t *   args FD_PARAM_UNUSED,
     365           0 :                  config_t * config ) {
     366           0 :   args_t c_args = configure_args();
     367           0 :   configure_cmd_fn( &c_args, config );
     368             : 
     369           0 :   run_firedancer_init( config, 1 );
     370             : 
     371           0 :   fd_log_private_shared_lock[ 1 ] = 0;
     372           0 :   fd_topo_join_workspaces( &config->topo, FD_SHMEM_JOIN_MODE_READ_WRITE );
     373           0 :   fd_topo_fill( &config->topo );
     374             : 
     375           0 :   double tick_per_ns = fd_tempo_tick_per_ns( NULL );
     376           0 :   double ns_per_tick = 1.0/tick_per_ns;
     377             : 
     378           0 :   long start = fd_log_wallclock();
     379           0 :   fd_topo_run_single_process( &config->topo, 2, config->uid, config->gid, fdctl_tile_run );
     380             : 
     381           0 :   fd_topo_t * topo = &config->topo;
     382             : 
     383           0 :   fd_topo_tile_t * snaprd_tile = &topo->tiles[ fd_topo_find_tile( topo, "snaprd", 0UL ) ];
     384           0 :   fd_topo_tile_t * snapdc_tile = &topo->tiles[ fd_topo_find_tile( topo, "snapdc", 0UL ) ];
     385           0 :   fd_topo_tile_t * snapin_tile = &topo->tiles[ fd_topo_find_tile( topo, "snapin", 0UL ) ];
     386             : 
     387           0 :   ulong volatile * const snaprd_metrics = fd_metrics_tile( snaprd_tile->metrics );
     388           0 :   ulong volatile * const snapdc_metrics = fd_metrics_tile( snapdc_tile->metrics );
     389           0 :   ulong volatile * const snapin_metrics = fd_metrics_tile( snapin_tile->metrics );
     390             : 
     391           0 :   ulong total_off_old    = 0UL;
     392           0 :   ulong snaprd_backp_old = 0UL;
     393           0 :   ulong snaprd_wait_old  = 0UL;
     394           0 :   ulong snapdc_backp_old = 0UL;
     395           0 :   ulong snapdc_wait_old  = 0UL;
     396           0 :   ulong snapin_backp_old = 0UL;
     397           0 :   ulong snapin_wait_old  = 0UL;
     398           0 :   ulong acc_cnt_old      = 0UL;
     399           0 :   sleep( 1 );
     400           0 :   puts( "-------------backp=(snaprd,snapdc,snapin) busy=(snaprd,snapdc,snapin)---------------" );
     401           0 :   long next = start+1000L*1000L*1000L;
     402           0 :   for(;;) {
     403           0 :     ulong snaprd_status = FD_VOLATILE_CONST( snaprd_metrics[ MIDX( GAUGE, TILE, STATUS ) ] );
     404           0 :     ulong snapdc_status = FD_VOLATILE_CONST( snapdc_metrics[ MIDX( GAUGE, TILE, STATUS ) ] );
     405           0 :     ulong snapin_status = FD_VOLATILE_CONST( snapin_metrics[ MIDX( GAUGE, TILE, STATUS ) ] );
     406             : 
     407           0 :     if( FD_UNLIKELY( snaprd_status==2UL && snapdc_status==2UL && snapin_status == 2UL ) ) break;
     408             : 
     409           0 :     long cur = fd_log_wallclock();
     410           0 :     if( FD_UNLIKELY( cur<next ) ) {
     411           0 :       long sleep_nanos = fd_long_min( 1000L*1000L, next-cur );
     412           0 :       FD_TEST( !fd_sys_util_nanosleep(  (uint)(sleep_nanos/(1000L*1000L*1000L)), (uint)(sleep_nanos%(1000L*1000L*1000L)) ) );
     413           0 :       continue;
     414           0 :     }
     415             : 
     416           0 :     ulong total_off    = snaprd_metrics[ MIDX( GAUGE, SNAPRD, FULL_BYTES_READ ) ] +
     417           0 :                          snaprd_metrics[ MIDX( GAUGE, SNAPRD, INCREMENTAL_BYTES_READ ) ];
     418           0 :     ulong snaprd_backp = snaprd_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_BACKPRESSURE_PREFRAG ) ];
     419           0 :     ulong snaprd_wait  = snaprd_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_CAUGHT_UP_PREFRAG    ) ] +
     420           0 :                          snaprd_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_CAUGHT_UP_POSTFRAG   ) ] + snaprd_backp;
     421           0 :     ulong snapdc_backp = snapdc_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_BACKPRESSURE_PREFRAG ) ];
     422           0 :     ulong snapdc_wait  = snapdc_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_CAUGHT_UP_PREFRAG    ) ] +
     423           0 :                          snapdc_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_CAUGHT_UP_POSTFRAG   ) ] + snapdc_backp;
     424           0 :     ulong snapin_backp = snapin_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_BACKPRESSURE_PREFRAG ) ];
     425           0 :     ulong snapin_wait  = snapin_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_CAUGHT_UP_PREFRAG    ) ] +
     426           0 :                          snapin_metrics[ MIDX( COUNTER, TILE, REGIME_DURATION_NANOS_CAUGHT_UP_POSTFRAG   ) ] + snapin_backp;
     427             : 
     428           0 :     ulong acc_cnt      = snapin_metrics[ MIDX( GAUGE, SNAPIN, ACCOUNTS_INSERTED    ) ];
     429           0 :     printf( "bw=%4.0f MB/s backp=(%3.0f%%,%3.0f%%,%3.0f%%) busy=(%3.0f%%,%3.0f%%,%3.0f%%) acc=%3.1f M/s\n",
     430           0 :             (double)( total_off-total_off_old )/1e6,
     431           0 :             ( (double)( snaprd_backp-snaprd_backp_old )*ns_per_tick )/1e7,
     432           0 :             ( (double)( snapdc_backp-snapdc_backp_old )*ns_per_tick )/1e7,
     433           0 :             ( (double)( snapin_backp-snapin_backp_old )*ns_per_tick )/1e7,
     434           0 :             100-( ( (double)( snaprd_wait-snaprd_wait_old  )*ns_per_tick )/1e7 ),
     435           0 :             100-( ( (double)( snapdc_wait-snapdc_wait_old  )*ns_per_tick )/1e7 ),
     436           0 :             100-( ( (double)( snapin_wait-snapin_wait_old  )*ns_per_tick )/1e7 ),
     437           0 :             (double)( acc_cnt-acc_cnt_old  )/1e6 );
     438           0 :     fflush( stdout );
     439           0 :     total_off_old    = total_off;
     440           0 :     snaprd_backp_old = snaprd_backp;
     441           0 :     snaprd_wait_old  = snaprd_wait;
     442           0 :     snapdc_backp_old = snapdc_backp;
     443           0 :     snapdc_wait_old  = snapdc_wait;
     444           0 :     snapin_backp_old = snapin_backp;
     445           0 :     snapin_wait_old  = snapin_wait;
     446           0 :     acc_cnt_old      = acc_cnt;
     447             : 
     448           0 :     next+=1000L*1000L*1000L;
     449           0 :   }
     450             : 
     451           0 :   for(;;) pause();
     452           0 : }
     453             : 
     454             : action_t fd_action_backtest = {
     455             :   .name = "backtest",
     456             :   .fn   = backtest_cmd_fn,
     457             :   .perm = backtest_cmd_perm,
     458             :   .topo = backtest_cmd_topo,
     459             : };

Generated by: LCOV version 1.14