LCOV - code coverage report
Current view: top level - app/firedancer-dev/commands - tower.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 125 0.0 %
Date: 2026-01-23 05:02:40 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /* The tower command prints the tower forks tree structure and leaves.
       2             :    This is a standalone application that can be run to inspect the tower
       3             :    tile's fork structure. */
       4             : 
       5             : #include "../../shared/fd_config.h" /* config_t */
       6             : #include "../../shared_dev/commands/dev.h"
       7             : #include "../../../discof/tower/fd_tower_tile.c"
       8             : #include "../../../choreo/tower/fd_tower_forks.h"
       9             : 
      10             : #include <stdio.h>
      11             : #include <unistd.h>
      12             : 
      13             : fd_topo_run_tile_t
      14             : fdctl_tile_run( fd_topo_tile_t const * tile );
      15             : 
      16             : /* ctx_t is defined in fd_tower_tile.c, we just need to access it */
      17             : 
      18             : static void
      19             : tower_ctx_wksp( args_t *          args,
      20             :                 config_t *        config,
      21             :                 ctx_t **          tower_ctx,
      22           0 :                 fd_topo_wksp_t ** tower_wksp ) {
      23           0 :   (void)args;
      24             : 
      25           0 :   fd_topo_t * topo = &config->topo;
      26             : 
      27           0 :   ulong tile_id = fd_topo_find_tile( topo, "tower", 0UL );
      28           0 :   if( FD_UNLIKELY( tile_id==ULONG_MAX ) ) FD_LOG_ERR(( "tower tile not found" ));
      29             : 
      30           0 :   fd_topo_tile_t * tile = &topo->tiles[ tile_id ];
      31             : 
      32             :   /* Get the workspace that contains the tile's scratch memory */
      33           0 :   ulong scratch_wksp_id = topo->objs[ tile->tile_obj_id ].wksp_id;
      34           0 :   if( FD_UNLIKELY( scratch_wksp_id>=topo->wksp_cnt ) ) FD_LOG_ERR(( "invalid workspace id %lu for tile scratch", scratch_wksp_id ));
      35             : 
      36           0 :   fd_topo_wksp_t * _tower_wksp = &topo->workspaces[ scratch_wksp_id ];
      37           0 :   fd_topo_join_workspace( topo, _tower_wksp, FD_SHMEM_JOIN_MODE_READ_ONLY, FD_TOPO_CORE_DUMP_LEVEL_DISABLED );
      38             : 
      39             :   /* Access the tower tile scratch memory where tower_tile_ctx is stored */
      40           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
      41           0 :   if( FD_UNLIKELY( !scratch ) ) FD_LOG_ERR(( "Failed to access tower tile scratch memory" ));
      42             : 
      43           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
      44           0 :   ctx_t * _tower_ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(ctx_t), sizeof(ctx_t) );
      45             : 
      46           0 :   *tower_ctx  = _tower_ctx;
      47           0 :   *tower_wksp = _tower_wksp;
      48           0 : }
      49             : 
      50             : static void
      51           0 : print_all_forks( fd_wksp_t * wksp, ctx_t * tower_ctx, fd_forks_t * forks ) {
      52           0 :   printf( "\n[Tower Forks]\n" );
      53           0 :   printf( "=============\n" );
      54           0 :   printf( "%-15s | %-15s | %-10s | %-10s\n", "Slot", "Parent Slot", "Voted", "Confirmed" );
      55           0 :   printf( "%-15s-+-%-15s-+-%-10s-+-%-10s\n", "---------------", "---------------", "----------", "----------" );
      56             : 
      57             :   /* Iterate through all map slots */
      58           0 :   ulong tower_forks_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, forks->tower_forks );
      59           0 :   fd_tower_forks_t * map = (fd_tower_forks_t *)fd_wksp_laddr_fast( wksp, tower_forks_gaddr );
      60           0 :   ulong slot_count = 0;
      61             : 
      62           0 :   for( ulong slot_idx = 0UL; slot_idx < fd_tower_forks_slot_cnt( map ); slot_idx++ ) {
      63           0 :     fd_tower_forks_t * fork = &map[ slot_idx ];
      64             :     /* Check if key is valid (not MAP_KEY_NULL which is ULONG_MAX) */
      65           0 :     if( !fd_tower_forks_key_inval( fork->slot ) ) {
      66           0 :       printf( "%-15lu | ", fork->slot );
      67           0 :       if( fork->parent_slot == ULONG_MAX ) {
      68           0 :         printf( "%-15s | ", "NULL" );
      69           0 :       } else {
      70           0 :         printf( "%-15lu | ", fork->parent_slot );
      71           0 :       }
      72           0 :       printf( "%-10s | ", fork->voted ? "Yes" : "No" );
      73           0 :       printf( "%-10s\n", fork->confirmed ? "Yes" : "No" );
      74           0 :       slot_count++;
      75           0 :     }
      76           0 :   }
      77             : 
      78           0 :   printf( "\n[Tower Leaves]\n" );
      79           0 :   printf( "==============\n" );
      80             : 
      81           0 :   ulong         tower_leaves_dlist_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, forks->tower_leaves_dlist );
      82           0 :   fd_tower_leaves_dlist_t * leaves_dlist = (fd_tower_leaves_dlist_t *)fd_wksp_laddr_fast( wksp, tower_leaves_dlist_gaddr );
      83           0 :   ulong tower_leaves_pool_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, forks->tower_leaves_pool );
      84           0 :   fd_tower_leaf_t * leaves_pool = (fd_tower_leaf_t *)fd_wksp_laddr_fast( wksp, tower_leaves_pool_gaddr );
      85             : 
      86           0 :   ulong leaf_count = 0;
      87           0 :   for( fd_tower_leaves_dlist_iter_t iter = fd_tower_leaves_dlist_iter_fwd_init( leaves_dlist, leaves_pool );
      88           0 :                                           !fd_tower_leaves_dlist_iter_done( iter, leaves_dlist, leaves_pool );
      89           0 :                                     iter = fd_tower_leaves_dlist_iter_fwd_next( iter, leaves_dlist, leaves_pool ) ) {
      90           0 :     fd_tower_leaf_t * leaf = fd_tower_leaves_dlist_iter_ele( iter, leaves_dlist, leaves_pool );
      91           0 :     if( FD_LIKELY( leaf ) ) {
      92           0 :       fd_tower_forks_t * fork = fd_tower_forks_query( map, leaf->slot, NULL );
      93           0 :       printf( "Leaf slot: %lu", leaf->slot );
      94           0 :       if( fork->voted )     printf( " [voted]"     );
      95           0 :       if( fork->confirmed ) printf( " [confirmed]" );
      96           0 :       printf( "\n" );
      97           0 :       leaf_count++;
      98           0 :     }
      99           0 :   }
     100           0 :   printf( "\nTotal leaves: %lu\n", leaf_count );
     101           0 :   printf( "Total slots: %lu\n", slot_count );
     102           0 :   printf( "\n" );
     103           0 : }
     104             : 
     105             : static const char * HELP =
     106             :   "\n\n"
     107             :   "usage: tower [-h] {forks}\n"
     108             :   "\n"
     109             :   "positional arguments:\n"
     110             :   "  {forks}\n"
     111             :   "    forks              prints the tower forks tree structure and leaves\n"
     112             :   "    ghost              prints the ghost fork choice structure\n"
     113             :   "    tower              prints the local tower\n"
     114             :   "\n"
     115             :   "optional arguments:\n"
     116             :   "  -h, --help            show this help message and exit\n";
     117             : 
     118             : static const char * FORKS_HELP =
     119             :   "\n\n"
     120             :   "usage: tower forks [-h]\n"
     121             :   "\n"
     122             :   "optional arguments:\n"
     123             :   "  -h, --help            show this help message and exit\n";
     124             : 
     125             : static const char * GHOST_HELP =
     126             :   "\n\n"
     127             :   "usage: tower ghost [-h]\n"
     128             :   "\n"
     129             :   "optional arguments:\n"
     130             :   "  -h, --help            show this help message and exit\n";
     131             : 
     132             : static const char * TOWER_HELP =
     133             :   "\n\n"
     134             :   "usage: tower tower [-h]\n"
     135             :   "\n"
     136             :   "optional arguments:\n"
     137             :   "  -h, --help            show this help message and exit\n";
     138             : 
     139             : void
     140           0 : tower_cmd_help( char const * arg ) {
     141           0 :   if      ( FD_LIKELY( !arg                    ) ) FD_LOG_NOTICE(( "%s", HELP           ));
     142           0 :   else if ( FD_LIKELY( !strcmp( arg, "forks" ) ) ) FD_LOG_NOTICE(( "%s", FORKS_HELP    ));
     143           0 :   else if ( FD_LIKELY( !strcmp( arg, "ghost" ) ) ) FD_LOG_NOTICE(( "%s", GHOST_HELP    ));
     144           0 :   else if ( FD_LIKELY( !strcmp( arg, "tower" ) ) ) FD_LOG_NOTICE(( "%s", TOWER_HELP    ));
     145           0 :   else                                             FD_LOG_NOTICE(( "%s", HELP           ));
     146           0 : }
     147             : 
     148             : static void
     149             : tower_cmd_fn_forks( args_t *   args,
     150           0 :                     config_t * config ) {
     151           0 :   ctx_t *          tower_ctx;
     152           0 :   fd_topo_wksp_t * tower_wksp;
     153           0 :   tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
     154             : 
     155           0 :   ulong forks_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->forks );
     156           0 :   fd_forks_t * forks = (fd_forks_t *)fd_wksp_laddr( tower_wksp->wksp, forks_gaddr );
     157             : 
     158           0 :   for( ;; ) {
     159           0 :     print_all_forks( tower_wksp->wksp, tower_ctx, forks );
     160           0 :     sleep( 1 );
     161           0 :   }
     162           0 : }
     163             : 
     164             : static void
     165             : tower_cmd_fn_ghost( args_t *   args,
     166           0 :                     config_t * config ) {
     167           0 :   ctx_t *          tower_ctx;
     168           0 :   fd_topo_wksp_t * tower_wksp;
     169           0 :   tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
     170             : 
     171           0 :   ulong ghost_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->ghost );
     172           0 :   fd_ghost_t * ghost = (fd_ghost_t *)fd_wksp_laddr( tower_wksp->wksp, ghost_gaddr );
     173           0 :   fd_ghost_root( ghost );
     174           0 :   FD_LOG_NOTICE(( "root slot %lu", fd_ghost_root( ghost )->slot ));
     175             : 
     176           0 :   for( ;; ) {
     177           0 :     fd_ghost_print( ghost, fd_ghost_root( ghost ), NULL );
     178           0 :     sleep( 1 );
     179           0 :   }
     180           0 : }
     181             : 
     182             : static void
     183             : tower_cmd_fn_tower( args_t    * args,
     184           0 :                      config_t * config ) {
     185           0 :   ctx_t *          tower_ctx;
     186           0 :   fd_topo_wksp_t * tower_wksp;
     187           0 :   tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
     188             : 
     189           0 :   ulong tower_laddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->tower );
     190           0 :   fd_tower_t * tower = (fd_tower_t *)fd_wksp_laddr( tower_wksp->wksp, tower_laddr );
     191             : 
     192           0 :   for( ;; ) {
     193           0 :     fd_tower_print( tower, ULONG_MAX, NULL );
     194           0 :     sleep( 1 );
     195           0 :   }
     196           0 : }
     197             : 
     198             : void
     199             : tower_cmd_args( int *    pargc,
     200             :                 char *** pargv,
     201           0 :                 args_t * args ) {
     202             : 
     203             :   /* help */
     204           0 :   args->tower.help = fd_env_strip_cmdline_contains( pargc, pargv, "--help" );
     205           0 :   args->tower.help = args->tower.help || fd_env_strip_cmdline_contains( pargc, pargv, "-h" );
     206             : 
     207             :   /* positional arg */
     208           0 :   args->tower.pos_arg = (*pargv)[0];
     209           0 :   if( FD_UNLIKELY( !args->tower.pos_arg ) ) {
     210           0 :     args->tower.help = 1;
     211           0 :     return;
     212           0 :   }
     213             : 
     214           0 :   (*pargc)--;
     215           0 : }
     216             : 
     217             : static void
     218             : tower_cmd_fn( args_t *   args,
     219           0 :               config_t * config ) {
     220             : 
     221           0 :   if( args->tower.help ) {
     222           0 :     tower_cmd_help( args->tower.pos_arg );
     223           0 :     return;
     224           0 :   }
     225             : 
     226           0 :   if     ( !strcmp( args->tower.pos_arg, "forks" ) ) tower_cmd_fn_forks( args, config );
     227           0 :   else if( !strcmp( args->tower.pos_arg, "ghost" ) ) tower_cmd_fn_ghost( args, config );
     228           0 :   else if( !strcmp( args->tower.pos_arg, "tower" ) ) tower_cmd_fn_tower( args, config );
     229           0 :   else                                               tower_cmd_help( NULL );
     230           0 : }
     231             : 
     232             : action_t fd_action_tower = {
     233             :   .name = "tower",
     234             :   .args = tower_cmd_args,
     235             :   .fn   = tower_cmd_fn,
     236             :   .perm = dev_cmd_perm,
     237             : };

Generated by: LCOV version 1.14