LCOV - code coverage report
Current view: top level - app/firedancer-dev/commands - tower.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 99 0.0 %
Date: 2026-06-29 05:51:35 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             : 
       9             : #include <stdio.h>
      10             : #include <unistd.h>
      11             : 
      12             : fd_topo_run_tile_t
      13             : fdctl_tile_run( fd_topo_tile_t const * tile );
      14             : 
      15             : extern action_t fd_action_tower;
      16             : 
      17             : /* fd_tower_tile_t is defined in fd_tower_tile.c, we just need to access it */
      18             : 
      19             : static void
      20             : tower_ctx_wksp( args_t *           args,
      21             :                 config_t *         config,
      22             :                 fd_tower_tile_t ** tower_ctx,
      23           0 :                 fd_topo_wksp_t **  tower_wksp ) {
      24           0 :   (void)args;
      25             : 
      26           0 :   fd_topo_t * topo = &config->topo;
      27             : 
      28           0 :   ulong tile_id = fd_topo_find_tile( topo, "tower", 0UL );
      29           0 :   if( FD_UNLIKELY( tile_id==ULONG_MAX ) ) FD_LOG_ERR(( "tower tile not found" ));
      30             : 
      31           0 :   fd_topo_tile_t * tile = &topo->tiles[ tile_id ];
      32             : 
      33             :   /* Get the workspace that contains the tile's scratch memory */
      34           0 :   ulong scratch_wksp_id = topo->objs[ tile->tile_obj_id ].wksp_id;
      35           0 :   if( FD_UNLIKELY( scratch_wksp_id>=topo->wksp_cnt ) ) FD_LOG_ERR(( "invalid workspace id %lu for tile scratch", scratch_wksp_id ));
      36             : 
      37           0 :   fd_topo_wksp_t * _tower_wksp = &topo->workspaces[ scratch_wksp_id ];
      38           0 :   fd_topo_join_workspace( topo, _tower_wksp, FD_SHMEM_JOIN_MODE_READ_ONLY, FD_TOPO_CORE_DUMP_LEVEL_DISABLED );
      39             : 
      40             :   /* Access the tower tile scratch memory where tower_tile_ctx is stored */
      41           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
      42           0 :   if( FD_UNLIKELY( !scratch ) ) FD_LOG_ERR(( "Failed to access tower tile scratch memory" ));
      43             : 
      44           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
      45           0 :   fd_tower_tile_t * _tower_ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_tower_tile_t), sizeof(fd_tower_tile_t) );
      46             : 
      47           0 :   *tower_ctx  = _tower_ctx;
      48           0 :   *tower_wksp = _tower_wksp;
      49           0 : }
      50             : 
      51             : static void
      52           0 : print_all_forks( fd_tower_t * tower ) {
      53           0 :   printf( "\n[Tower Forks]\n" );
      54           0 :   printf( "=============\n" );
      55           0 :   printf( "%-15s | %-15s | %-10s | %-10s\n", "Slot", "Parent Slot", "Voted", "Confirmed" );
      56           0 :   printf( "%-15s-+-%-15s-+-%-10s-+-%-10s\n", "---------------", "---------------", "----------", "----------" );
      57             : 
      58           0 :   ulong slot_count = 0;
      59           0 :   for( ulong i = 0; i < tower->blk_max; i++ ) {
      60           0 :     fd_tower_blk_t * blk = tower->blk_pool + i;
      61           0 :     if( !blk->slot ) continue; /* unused pool element */
      62           0 :     fd_tower_blk_t * found = fd_tower_blocks_query( tower, blk->slot );
      63           0 :     if( !found ) continue;
      64           0 :     printf( "%-15lu | ", found->slot );
      65           0 :     if( found->parent_slot == ULONG_MAX ) {
      66           0 :       printf( "%-15s | ", "NULL" );
      67           0 :     } else {
      68           0 :       printf( "%-15lu | ", found->parent_slot );
      69           0 :     }
      70           0 :     printf( "%-10s | ", found->voted ? "Yes" : "No" );
      71           0 :     printf( "%-10s\n", found->confirmed ? "Yes" : "No" );
      72           0 :     slot_count++;
      73           0 :   }
      74             : 
      75           0 :   printf( "Total slots: %lu\n", slot_count );
      76           0 :   printf( "\n" );
      77           0 : }
      78             : 
      79             : static void
      80             : tower_cmd_fn_forks( args_t *   args,
      81           0 :                     config_t * config ) {
      82           0 :   fd_tower_tile_t *          tower_ctx;
      83           0 :   fd_topo_wksp_t * tower_wksp;
      84           0 :   tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
      85             : 
      86           0 :   for( ;; ) {
      87           0 :     print_all_forks( tower_ctx->tower );
      88           0 :     sleep( 1 );
      89           0 :   }
      90           0 : }
      91             : 
      92             : static void
      93             : tower_cmd_fn_ghost( args_t *   args,
      94           0 :                     config_t * config ) {
      95           0 :   fd_tower_tile_t *          tower_ctx;
      96           0 :   fd_topo_wksp_t * tower_wksp;
      97           0 :   tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
      98             : 
      99           0 :   ulong ghost_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->ghost );
     100           0 :   fd_ghost_t * ghost = (fd_ghost_t *)fd_wksp_laddr( tower_wksp->wksp, ghost_gaddr );
     101           0 :   fd_ghost_root( ghost );
     102           0 :   FD_LOG_NOTICE(( "root slot %lu", fd_ghost_root( ghost )->slot ));
     103             : 
     104           0 :   for( ;; ) {
     105           0 :     char cstr[4096]; cstr[4095] = '\0'; ulong sz;
     106           0 :     FD_LOG_NOTICE(( "\n\n%s", fd_ghost_to_cstr( ghost, fd_ghost_root( ghost ), cstr, sizeof(cstr), &sz ) ));
     107           0 :     sleep( 1 );
     108           0 :   }
     109           0 : }
     110             : 
     111             : static void
     112             : tower_cmd_fn_tower( args_t    * args,
     113           0 :                      config_t * config ) {
     114           0 :   fd_tower_tile_t *          tower_ctx;
     115           0 :   fd_topo_wksp_t * tower_wksp;
     116           0 :   tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
     117             : 
     118           0 :   ulong tower_laddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->tower );
     119           0 :   fd_tower_t * tower = (fd_tower_t *)fd_wksp_laddr( tower_wksp->wksp, tower_laddr );
     120             : 
     121           0 :   for( ;; ) {
     122           0 :     char cstr[4096]; cstr[4095] = '\0';
     123           0 :     FD_LOG_DEBUG(( "\n\n%s", fd_tower_to_cstr( tower, cstr ) ));
     124           0 :     sleep( 1 );
     125           0 :   }
     126           0 : }
     127             : 
     128             : void
     129             : tower_cmd_args( int *    pargc,
     130             :                 char *** pargv,
     131           0 :                 args_t * args ) {
     132             : 
     133             :   /* positional arg */
     134           0 :   args->tower.pos_arg = (*pargv)[0];
     135           0 :   if( FD_UNLIKELY( !args->tower.pos_arg ) ) {
     136           0 :     args->tower.help = 1;
     137           0 :     return;
     138           0 :   }
     139             : 
     140           0 :   (*pargc)--;
     141           0 :   (*pargv)++;
     142           0 : }
     143             : 
     144             : static void
     145             : tower_cmd_fn( args_t *   args,
     146           0 :               config_t * config ) {
     147             : 
     148           0 :   if( args->tower.help ) {
     149           0 :     fd_action_help_print( &fd_action_tower );
     150           0 :     return;
     151           0 :   }
     152             : 
     153           0 :   if     ( !strcmp( args->tower.pos_arg, "forks" ) ) tower_cmd_fn_forks( args, config );
     154           0 :   else if( !strcmp( args->tower.pos_arg, "ghost" ) ) tower_cmd_fn_ghost( args, config );
     155           0 :   else if( !strcmp( args->tower.pos_arg, "tower" ) ) tower_cmd_fn_tower( args, config );
     156           0 :   else                                               fd_action_help_print( &fd_action_tower );
     157           0 : }
     158             : 
     159             : static void
     160           0 : tower_args_help( fd_action_help_t * help ) {
     161           0 :   fd_action_help_arg( help, "forks", NULL, "Print the tower forks tree structure and leaves" );
     162           0 :   fd_action_help_arg( help, "ghost", NULL, "Print the ghost fork choice structure" );
     163             :   fd_action_help_arg( help, "tower", NULL, "Print the local tower" );
     164           0 : }
     165             : 
     166             : action_t fd_action_tower = {
     167             :   .name        = "tower",
     168             :   .args        = tower_cmd_args,
     169             :   .fn          = tower_cmd_fn,
     170             :   .perm        = dev_cmd_perm,
     171             :   .description = "Inspect a running validator's tower, ghost, and forks state",
     172             :   .detail      = "Attaches to a running validator's tower tile and continuously prints the\n"
     173             :                  "requested data structure.  Pick one of the subcommands below.",
     174             :   .usage       = "tower <forks|ghost|tower>",
     175             :   .args_help   = tower_args_help,
     176             : };

Generated by: LCOV version 1.14