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_blocks.h"
9 : #include "../../../choreo/tower/fd_tower_leaves.h"
10 :
11 : #include <stdio.h>
12 : #include <unistd.h>
13 :
14 : fd_topo_run_tile_t
15 : fdctl_tile_run( fd_topo_tile_t const * tile );
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_wksp_t * wksp, fd_tower_tile_t * tower_ctx, fd_tower_blocks_t * forks ) {
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 : /* Iterate through all map slots */
59 0 : ulong tower_forks_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, forks->blk_map );
60 0 : fd_tower_blk_t * map = (fd_tower_blk_t *)fd_wksp_laddr_fast( wksp, tower_forks_gaddr );
61 0 : ulong slot_count = 0;
62 :
63 0 : for( ulong slot_idx = 0UL; slot_idx < fd_tower_blk_slot_cnt( map ); slot_idx++ ) {
64 0 : fd_tower_blk_t * fork = &map[ slot_idx ];
65 : /* Check if key is valid (not MAP_KEY_NULL which is ULONG_MAX) */
66 0 : if( !fd_tower_blk_key_inval( fork->slot ) ) {
67 0 : printf( "%-15lu | ", fork->slot );
68 0 : if( fork->parent_slot == ULONG_MAX ) {
69 0 : printf( "%-15s | ", "NULL" );
70 0 : } else {
71 0 : printf( "%-15lu | ", fork->parent_slot );
72 0 : }
73 0 : printf( "%-10s | ", fork->voted ? "Yes" : "No" );
74 0 : printf( "%-10s\n", fork->confirmed ? "Yes" : "No" );
75 0 : slot_count++;
76 0 : }
77 0 : }
78 :
79 0 : printf( "Total slots: %lu\n", slot_count );
80 :
81 0 : printf( "\n[Tower Leaves]\n" );
82 0 : printf( "==============\n" );
83 :
84 0 : ulong tower_leaves_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->tower_leaves );
85 0 : fd_tower_leaves_t * leaves = (fd_tower_leaves_t *)fd_wksp_laddr_fast( wksp, tower_leaves_gaddr );
86 :
87 0 : ulong tower_leaves_dlist_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, leaves->dlist );
88 0 : fd_tower_leaves_dlist_t * leaves_dlist = (fd_tower_leaves_dlist_t *)fd_wksp_laddr_fast( wksp, tower_leaves_dlist_gaddr );
89 0 : ulong tower_leaves_pool_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, leaves->pool );
90 0 : fd_tower_leaf_t * leaves_pool = (fd_tower_leaf_t *)fd_wksp_laddr_fast( wksp, tower_leaves_pool_gaddr );
91 :
92 0 : ulong leaf_count = 0;
93 0 : for( fd_tower_leaves_dlist_iter_t iter = fd_tower_leaves_dlist_iter_fwd_init( leaves_dlist, leaves_pool );
94 0 : !fd_tower_leaves_dlist_iter_done( iter, leaves_dlist, leaves_pool );
95 0 : iter = fd_tower_leaves_dlist_iter_fwd_next( iter, leaves_dlist, leaves_pool ) ) {
96 0 : fd_tower_leaf_t * leaf = fd_tower_leaves_dlist_iter_ele( iter, leaves_dlist, leaves_pool );
97 0 : if( FD_LIKELY( leaf ) ) {
98 0 : fd_tower_blk_t * fork = fd_tower_blk_query( map, leaf->slot, NULL );
99 0 : printf( "Leaf slot: %lu", leaf->slot );
100 0 : if( fork && fork->voted ) printf( " [voted]" );
101 0 : if( fork && fork->confirmed ) printf( " [confirmed]" );
102 0 : printf( "\n" );
103 0 : leaf_count++;
104 0 : }
105 0 : }
106 0 : printf( "\nTotal leaves: %lu\n", leaf_count );
107 0 : printf( "\n" );
108 0 : }
109 :
110 : static const char * HELP =
111 : "\n\n"
112 : "usage: tower [-h] {forks}\n"
113 : "\n"
114 : "positional arguments:\n"
115 : " {forks}\n"
116 : " forks prints the tower forks tree structure and leaves\n"
117 : " ghost prints the ghost fork choice structure\n"
118 : " tower prints the local tower\n"
119 : "\n"
120 : "optional arguments:\n"
121 : " -h, --help show this help message and exit\n";
122 :
123 : static const char * FORKS_HELP =
124 : "\n\n"
125 : "usage: tower forks [-h]\n"
126 : "\n"
127 : "optional arguments:\n"
128 : " -h, --help show this help message and exit\n";
129 :
130 : static const char * GHOST_HELP =
131 : "\n\n"
132 : "usage: tower ghost [-h]\n"
133 : "\n"
134 : "optional arguments:\n"
135 : " -h, --help show this help message and exit\n";
136 :
137 : static const char * TOWER_HELP =
138 : "\n\n"
139 : "usage: tower tower [-h]\n"
140 : "\n"
141 : "optional arguments:\n"
142 : " -h, --help show this help message and exit\n";
143 :
144 : void
145 0 : tower_cmd_help( char const * arg ) {
146 0 : if ( FD_LIKELY( !arg ) ) FD_LOG_NOTICE(( "%s", HELP ));
147 0 : else if ( FD_LIKELY( !strcmp( arg, "forks" ) ) ) FD_LOG_NOTICE(( "%s", FORKS_HELP ));
148 0 : else if ( FD_LIKELY( !strcmp( arg, "ghost" ) ) ) FD_LOG_NOTICE(( "%s", GHOST_HELP ));
149 0 : else if ( FD_LIKELY( !strcmp( arg, "tower" ) ) ) FD_LOG_NOTICE(( "%s", TOWER_HELP ));
150 0 : else FD_LOG_NOTICE(( "%s", HELP ));
151 0 : }
152 :
153 : static void
154 : tower_cmd_fn_forks( args_t * args,
155 0 : config_t * config ) {
156 0 : fd_tower_tile_t * tower_ctx;
157 0 : fd_topo_wksp_t * tower_wksp;
158 0 : tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
159 :
160 0 : ulong forks_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->tower_blocks );
161 0 : fd_tower_blocks_t * forks = (fd_tower_blocks_t *)fd_wksp_laddr( tower_wksp->wksp, forks_gaddr );
162 :
163 0 : for( ;; ) {
164 0 : print_all_forks( tower_wksp->wksp, tower_ctx, forks );
165 0 : sleep( 1 );
166 0 : }
167 0 : }
168 :
169 : static void
170 : tower_cmd_fn_ghost( args_t * args,
171 0 : config_t * config ) {
172 0 : fd_tower_tile_t * tower_ctx;
173 0 : fd_topo_wksp_t * tower_wksp;
174 0 : tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
175 :
176 0 : ulong ghost_gaddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->ghost );
177 0 : fd_ghost_t * ghost = (fd_ghost_t *)fd_wksp_laddr( tower_wksp->wksp, ghost_gaddr );
178 0 : fd_ghost_root( ghost );
179 0 : FD_LOG_NOTICE(( "root slot %lu", fd_ghost_root( ghost )->slot ));
180 :
181 0 : for( ;; ) {
182 0 : char cstr[4096]; cstr[4095] = '\0'; ulong sz;
183 0 : FD_LOG_NOTICE(( "\n\n%s", fd_ghost_to_cstr( ghost, fd_ghost_root( ghost ), cstr, sizeof(cstr), &sz ) ));
184 0 : sleep( 1 );
185 0 : }
186 0 : }
187 :
188 : static void
189 : tower_cmd_fn_tower( args_t * args,
190 0 : config_t * config ) {
191 0 : fd_tower_tile_t * tower_ctx;
192 0 : fd_topo_wksp_t * tower_wksp;
193 0 : tower_ctx_wksp( args, config, &tower_ctx, &tower_wksp );
194 :
195 0 : ulong tower_laddr = fd_wksp_gaddr_fast( tower_ctx->wksp, tower_ctx->tower );
196 0 : fd_tower_t * tower = (fd_tower_t *)fd_wksp_laddr( tower_wksp->wksp, tower_laddr );
197 :
198 0 : for( ;; ) {
199 0 : char cstr[4096]; cstr[4095] = '\0';
200 0 : FD_LOG_DEBUG(( "\n\n%s", fd_tower_to_cstr( tower, tower_ctx->root_slot, cstr ) ));
201 0 : sleep( 1 );
202 0 : }
203 0 : }
204 :
205 : void
206 : tower_cmd_args( int * pargc,
207 : char *** pargv,
208 0 : args_t * args ) {
209 :
210 : /* help */
211 0 : args->tower.help = fd_env_strip_cmdline_contains( pargc, pargv, "--help" );
212 0 : args->tower.help = args->tower.help || fd_env_strip_cmdline_contains( pargc, pargv, "-h" );
213 :
214 : /* positional arg */
215 0 : args->tower.pos_arg = (*pargv)[0];
216 0 : if( FD_UNLIKELY( !args->tower.pos_arg ) ) {
217 0 : args->tower.help = 1;
218 0 : return;
219 0 : }
220 :
221 0 : (*pargc)--;
222 0 : }
223 :
224 : static void
225 : tower_cmd_fn( args_t * args,
226 0 : config_t * config ) {
227 :
228 0 : if( args->tower.help ) {
229 0 : tower_cmd_help( args->tower.pos_arg );
230 0 : return;
231 0 : }
232 :
233 0 : if ( !strcmp( args->tower.pos_arg, "forks" ) ) tower_cmd_fn_forks( args, config );
234 0 : else if( !strcmp( args->tower.pos_arg, "ghost" ) ) tower_cmd_fn_ghost( args, config );
235 0 : else if( !strcmp( args->tower.pos_arg, "tower" ) ) tower_cmd_fn_tower( args, config );
236 0 : else tower_cmd_help( NULL );
237 0 : }
238 :
239 : action_t fd_action_tower = {
240 : .name = "tower",
241 : .args = tower_cmd_args,
242 : .fn = tower_cmd_fn,
243 : .perm = dev_cmd_perm,
244 : };
|