LCOV - code coverage report
Current view: top level - discof/rpcserver - fd_rpcserv_tile.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 132 0.0 %
Date: 2025-10-13 04:42:14 Functions: 0 10 0.0 %

          Line data    Source code
       1             : #include "../../disco/topo/fd_topo.h"
       2             : #include <sys/socket.h>
       3             : #include "generated/fd_rpcserv_tile_seccomp.h"
       4             : #include "../rpcserver/fd_rpc_service.h"
       5             : #include "../../disco/keyguard/fd_keyload.h"
       6             : #include "../../disco/keyguard/fd_keyswitch.h"
       7             : 
       8             : #include <fcntl.h>
       9             : #include <unistd.h>
      10             : 
      11           0 : #define IN_KIND_REPLAY_OUT (0)
      12           0 : #define IN_KIND_STAKE_OUT  (1)
      13           0 : #define IN_KIND_SHRED_OUT  (2)
      14             : 
      15             : struct fd_rpcserv_in {
      16             :   fd_wksp_t * mem;
      17             :   ulong       chunk0;
      18             :   ulong       wmark;
      19             :   ulong       mtu;
      20             : };
      21             : 
      22             : typedef struct fd_rpcserv_in fd_rpcserv_in_t;
      23             : 
      24             : struct fd_rpcserv_tile {
      25             :   fd_rpcserver_args_t args;
      26             : 
      27             :   fd_rpc_ctx_t * ctx;
      28             : 
      29             :   fd_pubkey_t      identity_key;
      30             :   fd_keyswitch_t * keyswitch;
      31             : 
      32             :   int in_kind[ 16UL ];
      33             :   fd_rpcserv_in_t in[ 16UL ];
      34             : };
      35             : 
      36             : typedef struct fd_rpcserv_tile fd_rpcserv_tile_t;
      37             : 
      38           0 : #define FD_RPC_SCRATCH_MAX (1LU<<30)
      39             : 
      40             : const fd_http_server_params_t RPCSERV_HTTP_PARAMS = {
      41             :   .max_connection_cnt    = 10,
      42             :   .max_ws_connection_cnt = 10,
      43             :   .max_request_len       = 1<<16,
      44             :   .max_ws_recv_frame_len = 1<<16,
      45             :   .max_ws_send_frame_cnt = 10,
      46             :   .outgoing_buffer_sz    = 100<<20,
      47             : };
      48             : 
      49             : FD_FN_CONST static inline ulong
      50           0 : scratch_align( void ) {
      51           0 :   return 128UL;
      52           0 : }
      53             : 
      54             : FD_FN_PURE static inline ulong
      55           0 : scratch_footprint( fd_topo_tile_t const * tile FD_PARAM_UNUSED) {
      56           0 :   ulong l = FD_LAYOUT_INIT;
      57           0 :   l = FD_LAYOUT_APPEND( l, alignof(fd_rpcserv_tile_t), sizeof(fd_rpcserv_tile_t) );
      58           0 :   l = FD_LAYOUT_APPEND( l, fd_spad_align(),            fd_spad_footprint( FD_RPC_SCRATCH_MAX ) );
      59           0 :   return FD_LAYOUT_FINI( l, scratch_align() );
      60           0 : }
      61             : 
      62             : FD_FN_PURE static inline ulong
      63           0 : loose_footprint( fd_topo_tile_t const * tile FD_PARAM_UNUSED ) {
      64           0 :   return 1UL * FD_SHMEM_GIGANTIC_PAGE_SZ;
      65           0 : }
      66             : 
      67             : static inline void
      68           0 : during_housekeeping( fd_rpcserv_tile_t * ctx ) {
      69           0 :   if( FD_UNLIKELY( fd_keyswitch_state_query( ctx->keyswitch )==FD_KEYSWITCH_STATE_SWITCH_PENDING ) ) {
      70           0 :     memcpy( &ctx->identity_key, ctx->keyswitch->bytes, sizeof(fd_pubkey_t) );
      71           0 :     fd_keyswitch_state( ctx->keyswitch, FD_KEYSWITCH_STATE_COMPLETED );
      72           0 :   }
      73           0 : }
      74             : 
      75             : static inline void
      76             : before_credit( fd_rpcserv_tile_t * ctx,
      77             :                fd_stem_context_t * stem,
      78           0 :                int *               charge_busy ) {
      79           0 :   (void)stem;
      80           0 :   *charge_busy = fd_rpc_ws_poll( ctx->ctx );
      81           0 : }
      82             : 
      83             : static inline int
      84             : returnable_frag( fd_rpcserv_tile_t * ctx,
      85             :                  ulong               in_idx,
      86             :                  ulong               seq,
      87             :                  ulong               sig,
      88             :                  ulong               chunk,
      89             :                  ulong               sz,
      90             :                  ulong               ctl,
      91             :                  ulong               tsorig,
      92             :                  ulong               tspub,
      93           0 :                  fd_stem_context_t * stem ) {
      94           0 :   (void)seq;
      95           0 :   (void)tsorig;
      96           0 :   (void)tspub;
      97           0 :   (void)stem;
      98             : 
      99           0 :   if( FD_UNLIKELY( chunk<ctx->in[ in_idx ].chunk0 || chunk>ctx->in[ in_idx ].wmark || sz>ctx->in[ in_idx ].mtu ) ) {
     100           0 :     FD_LOG_ERR(( "chunk %lu %lu corrupt, not in range [%lu,%lu]", chunk, sz, ctx->in[ in_idx ].chunk0, ctx->in[ in_idx ].wmark ));
     101           0 :   }
     102             : 
     103           0 :   switch( ctx->in_kind[ in_idx ] ) {
     104           0 :     case IN_KIND_REPLAY_OUT: {
     105           0 :       fd_rpc_replay_during_frag( ctx->ctx, fd_chunk_to_laddr_const( ctx->in[ in_idx ].mem, chunk ), sig, sz, ctl );
     106           0 :       fd_rpc_replay_after_frag( ctx->ctx, sig );
     107           0 :       break;
     108           0 :     }
     109           0 :     case IN_KIND_STAKE_OUT: {
     110           0 :       fd_rpc_stake_during_frag( ctx->ctx, fd_chunk_to_laddr_const( ctx->in[ in_idx ].mem, chunk ), sz );
     111           0 :       fd_rpc_stake_after_frag( ctx->ctx );
     112           0 :       break;
     113           0 :     }
     114           0 :     case IN_KIND_SHRED_OUT: {
     115           0 :       fd_rpc_repair_during_frag( ctx->ctx, fd_chunk_to_laddr_const( ctx->in[ in_idx ].mem, chunk ), sz );
     116           0 :       fd_rpc_repair_after_frag( ctx->ctx );
     117           0 :       break;
     118           0 :     }
     119           0 :     default: FD_LOG_ERR(( "unhandled kind %d", ctx->in_kind[ in_idx ] ));
     120           0 :   }
     121             : 
     122           0 :   return 0;
     123           0 : }
     124             : 
     125             : static void
     126             : privileged_init( fd_topo_t *      topo,
     127           0 :                  fd_topo_tile_t * tile ) {
     128           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
     129             : 
     130           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
     131           0 :   fd_rpcserv_tile_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_rpcserv_tile_t), sizeof(fd_rpcserv_tile_t) );
     132           0 :   void * spad_mem         = FD_SCRATCH_ALLOC_APPEND( l, fd_spad_align(),            fd_spad_footprint( FD_RPC_SCRATCH_MAX ) );
     133           0 :   FD_SCRATCH_ALLOC_FINI( l, scratch_align() );
     134             : 
     135           0 :   if( FD_UNLIKELY( !strcmp( tile->rpcserv.identity_key_path, "" ) ) ) FD_LOG_ERR( ( "identity_key_path not set" ) );
     136           0 :   memcpy( &ctx->identity_key, fd_keyload_load( tile->rpcserv.identity_key_path, /* pubkey only: */ 1 ), sizeof(fd_pubkey_t) );
     137             : 
     138           0 :   fd_rpcserver_args_t * args = &ctx->args;
     139           0 :   fd_memset( args, 0, sizeof(fd_rpcserver_args_t) );
     140             : 
     141           0 :   args->offline = 0;
     142           0 :   args->params = RPCSERV_HTTP_PARAMS;
     143             : 
     144           0 :   args->port = tile->rpcserv.rpc_port;
     145             : 
     146           0 :   args->tpu_addr.sin_family = AF_INET;
     147           0 :   args->tpu_addr.sin_addr.s_addr = tile->rpcserv.tpu_ip_addr;
     148           0 :   args->tpu_addr.sin_port = htons( (ushort)tile->rpcserv.tpu_port );
     149             : 
     150           0 :   uchar * spad_mem_cur = spad_mem;
     151           0 :   args->spad = fd_spad_join( fd_spad_new( spad_mem_cur, FD_RPC_SCRATCH_MAX ) );
     152             : 
     153           0 :   args->block_index_max = tile->rpcserv.block_index_max;
     154           0 :   args->txn_index_max = tile->rpcserv.txn_index_max;
     155           0 :   args->acct_index_max = tile->rpcserv.acct_index_max;
     156           0 :   strncpy( args->history_file, tile->rpcserv.history_file, sizeof(args->history_file) );
     157           0 :   args->identity_key = ctx->identity_key;
     158             : 
     159           0 :   fd_spad_push( args->spad ); /* We close this out when we stop the server */
     160           0 :   fd_rpc_create_ctx( args, &ctx->ctx );
     161             : 
     162             :   /* Wait until after replay tile boots before starting service */
     163           0 : }
     164             : 
     165             : static void
     166             : unprivileged_init( fd_topo_t *      topo,
     167           0 :                    fd_topo_tile_t * tile ) {
     168           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
     169             : 
     170           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
     171           0 :   fd_rpcserv_tile_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_rpcserv_tile_t), sizeof(fd_rpcserv_tile_t) );
     172           0 :                             FD_SCRATCH_ALLOC_APPEND( l, fd_spad_align(),            fd_ulong_align_up( FD_RPC_SCRATCH_MAX, fd_spad_align() ) );
     173             : 
     174           0 :   ctx->keyswitch = fd_keyswitch_join( fd_topo_obj_laddr( topo, tile->keyswitch_obj_id ) );
     175           0 :   FD_TEST( ctx->keyswitch );
     176             : 
     177           0 :   fd_rpcserver_args_t * args = &ctx->args;
     178           0 :   FD_TEST( fd_funk_join( args->funk, fd_topo_obj_laddr( topo, tile->rpcserv.funk_obj_id ) ) );
     179             : 
     180           0 :   args->store = fd_store_join( fd_topo_obj_laddr( topo, tile->rpcserv.store_obj_id ) );
     181           0 :   FD_TEST( args->store );
     182             : 
     183           0 :   fd_rpc_start_service( args, ctx->ctx );
     184             : 
     185           0 :   for( uint in_idx=0U; in_idx<(tile->in_cnt); in_idx++ ) {
     186           0 :     fd_topo_link_t * link = &topo->links[ tile->in_link_id[ in_idx ] ];
     187             : 
     188           0 :     if( FD_LIKELY( !strcmp( link->name, "replay_out"        ) ) ) ctx->in_kind[ in_idx ] = IN_KIND_REPLAY_OUT;
     189           0 :     else if( FD_LIKELY( !strcmp( link->name, "replay_stake" ) ) ) ctx->in_kind[ in_idx ] = IN_KIND_STAKE_OUT;
     190           0 :     else if( FD_LIKELY( !strcmp( link->name, "shred_out"    ) ) ) ctx->in_kind[ in_idx ] = IN_KIND_SHRED_OUT;
     191           0 :     else FD_LOG_ERR(( "rpcserv tile has unexpected input link %s", link->name ));
     192             : 
     193           0 :     ctx->in[ in_idx ].mem    = topo->workspaces[ topo->objs[ link->dcache_obj_id ].wksp_id ].wksp;
     194           0 :     ctx->in[ in_idx ].chunk0 = fd_dcache_compact_chunk0( ctx->in[ in_idx ].mem, link->dcache );
     195           0 :     ctx->in[ in_idx ].wmark  = fd_dcache_compact_wmark ( ctx->in[ in_idx ].mem, link->dcache, link->mtu );
     196           0 :     ctx->in[ in_idx ].mtu    = link->mtu;
     197           0 :   }
     198             : 
     199           0 :   ulong scratch_top = FD_SCRATCH_ALLOC_FINI( l, scratch_align() );
     200           0 :   if( FD_UNLIKELY( scratch_top > (ulong)scratch + scratch_footprint( tile ) ) )
     201           0 :     FD_LOG_ERR(( "scratch overflow %lu %lu %lu", scratch_top - (ulong)scratch - scratch_footprint( tile ), scratch_top, (ulong)scratch + scratch_footprint( tile ) ));
     202           0 : }
     203             : 
     204             : static ulong
     205             : populate_allowed_seccomp( fd_topo_t const *      topo,
     206             :                           fd_topo_tile_t const * tile,
     207             :                           ulong                  out_cnt,
     208           0 :                           struct sock_filter *   out ) {
     209           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
     210             : 
     211           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
     212           0 :   fd_rpcserv_tile_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_rpcserv_tile_t), sizeof(fd_rpcserv_tile_t) );
     213             : 
     214           0 :   populate_sock_filter_policy_fd_rpcserv_tile( out_cnt, out, (uint)fd_log_private_logfile_fd(), (uint)fd_rpc_ws_fd( ctx->ctx ) );
     215           0 :   return sock_filter_policy_fd_rpcserv_tile_instr_cnt;
     216           0 : }
     217             : 
     218             : static ulong
     219             : populate_allowed_fds( fd_topo_t const *      topo,
     220             :                       fd_topo_tile_t const * tile,
     221             :                       ulong                  out_fds_cnt,
     222           0 :                       int *                  out_fds ) {
     223           0 :   void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
     224             : 
     225           0 :   FD_SCRATCH_ALLOC_INIT( l, scratch );
     226           0 :   fd_rpcserv_tile_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_rpcserv_tile_t), sizeof(fd_rpcserv_tile_t) );
     227             : 
     228           0 :   if( FD_UNLIKELY( out_fds_cnt<3UL ) ) FD_LOG_ERR(( "out_fds_cnt %lu", out_fds_cnt ));
     229             : 
     230           0 :   ulong out_cnt = 0;
     231           0 :   out_fds[ out_cnt++ ] = 2; /* stderr */
     232           0 :   if( FD_LIKELY( -1!=fd_log_private_logfile_fd() ) )
     233           0 :     out_fds[ out_cnt++ ] = fd_log_private_logfile_fd(); /* logfile */
     234           0 :   out_fds[ out_cnt++ ] = fd_rpc_ws_fd( ctx->ctx ); /* listen socket */
     235           0 :   return out_cnt;
     236           0 : }
     237             : 
     238           0 : #define STEM_BURST (1UL)
     239             : 
     240           0 : #define STEM_CALLBACK_CONTEXT_TYPE  fd_rpcserv_tile_t
     241           0 : #define STEM_CALLBACK_CONTEXT_ALIGN alignof(fd_rpcserv_tile_t)
     242             : 
     243           0 : #define STEM_CALLBACK_BEFORE_CREDIT       before_credit
     244           0 : #define STEM_CALLBACK_DURING_HOUSEKEEPING during_housekeeping
     245           0 : #define STEM_CALLBACK_RETURNABLE_FRAG     returnable_frag
     246             : 
     247             : #include "../../disco/stem/fd_stem.c"
     248             : 
     249             : fd_topo_run_tile_t fd_tile_rpcserv = {
     250             :   .name                     = "rpcsrv",
     251             :   .loose_footprint          = loose_footprint,
     252             :   .populate_allowed_seccomp = populate_allowed_seccomp,
     253             :   .populate_allowed_fds     = populate_allowed_fds,
     254             :   .scratch_align            = scratch_align,
     255             :   .scratch_footprint        = scratch_footprint,
     256             :   .unprivileged_init        = unprivileged_init,
     257             :   .privileged_init          = privileged_init,
     258             :   .run                      = stem_run,
     259             : };

Generated by: LCOV version 1.14