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 : };
|