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

          Line data    Source code
       1             : #define _GNU_SOURCE
       2             : #include "../fd_config.h"
       3             : #include "../fd_action.h"
       4             : #include "../../../util/fd_util.h"
       5             : #include "../../../ballet/base58/fd_base58.h"
       6             : #include "../../../flamenco/types/fd_types_custom.h"
       7             : #include "../../../disco/shred/fd_shred_tile.h"
       8             : #include "../../../disco/keyguard/fd_keyswitch.h"
       9             : #include <unistd.h>
      10             : 
      11             : void
      12             : get_identity_cmd_fn( args_t *   args   FD_PARAM_UNUSED,
      13           0 :                      config_t * config ) {
      14             :   /* Find the shred tile which is always present and has the current runtime identity */
      15           0 :   ulong shred_tile_idx = fd_topo_find_tile( &config->topo, "shred", 0UL );
      16           0 :   if( FD_UNLIKELY( shred_tile_idx==ULONG_MAX ) ) {
      17           0 :     FD_LOG_ERR(( "Shred tile not found in topology" ));
      18           0 :   }
      19             : 
      20           0 :   fd_topo_tile_t const * shred_tile = &config->topo.tiles[ shred_tile_idx ];
      21             :   /* Access shred tile object to find its workspace */
      22           0 :   if( FD_UNLIKELY( shred_tile->tile_obj_id==ULONG_MAX ) ) {
      23           0 :     FD_LOG_ERR(( "Shred tile object not found" ));
      24           0 :   }
      25             :   /* Find the workspace containing the shred tile object */
      26           0 :   fd_topo_obj_t const * shred_obj = &config->topo.objs[ shred_tile->tile_obj_id ];
      27           0 :   ulong shred_wksp_id = shred_obj->wksp_id;
      28             : 
      29             :   /* Join the workspace in read-only mode */
      30           0 :   fd_topo_join_workspace( &config->topo, &config->topo.workspaces[ shred_wksp_id ], FD_SHMEM_JOIN_MODE_READ_ONLY );
      31             : 
      32             :   /* Cast to shred context structure */
      33           0 :   fd_shred_ctx_t const * shred_ctx = fd_topo_obj_laddr( &config->topo, shred_tile->tile_obj_id );
      34           0 :   if( FD_UNLIKELY( !shred_ctx ) ) {
      35           0 :     fd_topo_leave_workspaces( &config->topo );
      36           0 :     FD_LOG_ERR(( "Failed to access shred tile object" ));
      37           0 :   }
      38             :   /* Join the keyswitch to check for concurrent identity updates */
      39           0 :   fd_keyswitch_t * keyswitch = fd_keyswitch_join( fd_topo_obj_laddr( &config->topo, shred_tile->keyswitch_obj_id ) );
      40           0 :   if( FD_UNLIKELY( !keyswitch ) ) {
      41           0 :     fd_topo_leave_workspaces( &config->topo );
      42           0 :     FD_LOG_ERR(( "Failed to join keyswitch" ));
      43           0 :   }
      44             : 
      45             :   /* Read identity key with retry if needed */
      46           0 :   fd_pubkey_t identity_key;
      47             :   /* TODO: Consider adding a counter to detect multiple rapid identity switches
      48             :      that could cause us to read a stale identity between state checks. */
      49           0 :   for( int retry = 0; retry < 2; retry++ ) {
      50             :     /* Peek the pre-read keyswitch state */
      51           0 :     ulong switch_state0 = fd_keyswitch_state_query( keyswitch );
      52             : 
      53             :     /* Speculatively read current key */
      54           0 :     identity_key = FD_VOLATILE_CONST( *shred_ctx->identity_key );
      55             : 
      56             :     /* Peek the post-read keyswitch state */
      57           0 :     ulong switch_state1 = fd_keyswitch_state_query( keyswitch );
      58             : 
      59             :     /* Check if we got a consistent read */
      60           0 :     if( FD_LIKELY( switch_state0 == switch_state1 &&
      61           0 :                    switch_state0 != FD_KEYSWITCH_STATE_SWITCH_PENDING ) ) {
      62             :       /* Success - we have a consistent identity key */
      63           0 :       break;
      64           0 :     }
      65             : 
      66             :     /* Key switch in progress or states don't match, retry after delay */
      67           0 :     if( retry == 0 ) {
      68           0 :       usleep( 10000 ); /* 10ms delay */
      69           0 :     } else {
      70           0 :       fd_keyswitch_leave( keyswitch );
      71           0 :       fd_topo_leave_workspaces( &config->topo );
      72           0 :       FD_LOG_ERR(( "Failed to read identity key - keyswitch in progress" ));
      73           0 :     }
      74           0 :   }
      75             : 
      76             :   /* Leave keyswitch */
      77           0 :   fd_keyswitch_leave( keyswitch );
      78             : 
      79             :   /* Convert to base58 and print */
      80           0 :   char identity_key_str[ FD_BASE58_ENCODED_32_SZ ];
      81           0 :   fd_base58_encode_32( identity_key.uc, NULL, identity_key_str );
      82             : 
      83             :   FD_LOG_STDOUT(( "%s\n", identity_key_str ));
      84           0 : }
      85             : 
      86             : action_t fd_action_get_identity = {
      87             :   .name           = "get-identity",
      88             :   .args           = NULL,
      89             :   .fn             = get_identity_cmd_fn,
      90             :   .require_config = 1,
      91             :   .perm           = NULL, /* TODO: This command may require RLIMIT_MLOCK permissions
      92             :                              to mlock(2) the workspace in memory. This should be
      93             :                              addressed in future updates. */
      94             :   .description    = "Get the current active identity of the running validator",
      95             : };

Generated by: LCOV version 1.14