LCOV - code coverage report
Current view: top level - discof/repair - fd_rserve.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 119 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 11 0.0 %

          Line data    Source code
       1             : #include "fd_rserve.h"
       2             : #include "fd_repair.h"
       3             : #include "../../ballet/sha256/fd_sha256.h"
       4             : 
       5             : static void
       6             : fd_rserve_rotation_secret( uchar       out[ 32 ],
       7             :                            uchar const master[ 32 ],
       8           0 :                            ulong       idx ) {
       9           0 :   uchar buf[ 40 ];
      10           0 :   memcpy( buf, master, 32UL );
      11           0 :   FD_STORE( ulong, buf+32UL, idx );
      12           0 :   fd_sha256_hash( buf, sizeof(buf), out );
      13           0 : }
      14             : 
      15             : static void
      16             : fd_rserve_token_compute( uchar               token[ 32 ],
      17             :                          uchar const         secret[ 32 ],
      18             :                          fd_pubkey_t const * from,
      19             :                          uint                ip4,
      20           0 :                          ushort              port ) {
      21           0 :   memcpy( token, "SOLANA_PING_PONG", 16UL );
      22             : 
      23           0 :   uchar buf[ 32UL + 32UL + 4UL + 2UL ];
      24           0 :   memcpy( buf,       secret,   32UL );
      25           0 :   memcpy( buf+32UL,  from->uc, 32UL );
      26           0 :   FD_STORE( uint,   buf+64UL, ip4  );
      27           0 :   FD_STORE( ushort, buf+68UL, port );
      28             : 
      29           0 :   uchar mac[ 32 ];
      30           0 :   fd_sha256_hash( buf, sizeof(buf), mac );
      31           0 :   memcpy( token+16UL, mac, 16UL );
      32           0 : }
      33             : 
      34             : ulong
      35           0 : fd_rserve_footprint( ulong ping_cache_entries ) {
      36           0 :   if( FD_UNLIKELY( !ping_cache_entries ) ) return 0UL;
      37             : 
      38           0 :   ulong ping_max = fd_ulong_pow2_up( ping_cache_entries );
      39             : 
      40           0 :   ulong l = FD_LAYOUT_INIT;
      41           0 :   l = FD_LAYOUT_APPEND( l, alignof(fd_rserve_t), sizeof(fd_rserve_t) );
      42           0 :   l = FD_LAYOUT_APPEND( l, ping_pool_align(),    ping_pool_footprint( ping_max ) );
      43           0 :   l = FD_LAYOUT_APPEND( l, ping_map_align(),     ping_map_footprint( ping_map_chain_cnt_est( ping_max ) ) );
      44           0 :   l = FD_LAYOUT_APPEND( l, ping_dlist_align(),   ping_dlist_footprint() );
      45           0 :   return FD_LAYOUT_FINI( l, fd_rserve_align() );
      46           0 : }
      47             : 
      48             : void *
      49             : fd_rserve_new( void * shmem,
      50             :                ulong  ping_cache_entries,
      51             :                ulong  seed,
      52           0 :                uchar const secret[ 32 ] ) {
      53           0 :   if( FD_UNLIKELY( !shmem ) ) {
      54           0 :     FD_LOG_WARNING(( "NULL mem" ));
      55           0 :     return NULL;
      56           0 :   }
      57             : 
      58           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_rserve_align() ) ) ) {
      59           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      60           0 :     return NULL;
      61           0 :   }
      62             : 
      63           0 :   ulong footprint = fd_rserve_footprint( ping_cache_entries );
      64           0 :   if( FD_UNLIKELY( !footprint ) ) {
      65           0 :     FD_LOG_WARNING(( "bad ping cache size (%lu)", ping_cache_entries ));
      66           0 :     return NULL;
      67           0 :   }
      68             : 
      69           0 :   ulong ping_max = fd_ulong_pow2_up( ping_cache_entries );
      70             : 
      71           0 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      72           0 :   void * rserve_mem     = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_rserve_t), sizeof(fd_rserve_t) );
      73           0 :   void * ping_pool_mem  = FD_SCRATCH_ALLOC_APPEND( l, ping_pool_align(),    ping_pool_footprint( ping_max ) );
      74           0 :   void * ping_map_mem   = FD_SCRATCH_ALLOC_APPEND( l, ping_map_align(),     ping_map_footprint( ping_map_chain_cnt_est( ping_max ) ) );
      75           0 :   void * ping_dlist_mem = FD_SCRATCH_ALLOC_APPEND( l, ping_dlist_align(),   ping_dlist_footprint() );
      76             : 
      77           0 :   fd_rserve_t * rserve = (fd_rserve_t *)rserve_mem;
      78           0 :   ping_pool_new( ping_pool_mem, ping_max );
      79           0 :   rserve->ping_pool  = fd_type_pun( ping_pool_mem );
      80           0 :   rserve->ping_map   = ping_map_join  ( ping_map_new  ( ping_map_mem,   ping_map_chain_cnt_est( ping_max ), seed ) );
      81           0 :   rserve->ping_dlist = ping_dlist_join( ping_dlist_new( ping_dlist_mem ) );
      82             : 
      83             :   /* Initialize rotating token secrets. */
      84           0 :   rserve->seed           = seed;
      85           0 :   rserve->token_idx      = 0UL;
      86           0 :   rserve->last_rotate_ts = 0UL;
      87           0 :   memcpy( rserve->secret_master, secret, 32UL );
      88           0 :   fd_rserve_rotation_secret( rserve->secret_cur, rserve->secret_master, 0UL );
      89           0 :   memcpy( rserve->secret_prev, rserve->secret_cur, 32UL );
      90             : 
      91           0 :   FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_rserve_align() )==(ulong)shmem + footprint );
      92             : 
      93           0 :   return shmem;
      94           0 : }
      95             : 
      96             : fd_rserve_t *
      97           0 : fd_rserve_join( void * shrserve ) {
      98           0 :   if( FD_UNLIKELY( !shrserve ) ) {
      99           0 :     FD_LOG_WARNING(( "NULL rserve" ));
     100           0 :     return NULL;
     101           0 :   }
     102             : 
     103           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shrserve, fd_rserve_align() ) ) ) {
     104           0 :     FD_LOG_WARNING(( "misaligned rserve" ));
     105           0 :     return NULL;
     106           0 :   }
     107             : 
     108           0 :   fd_rserve_t * rserve = (fd_rserve_t *)shrserve;
     109           0 :   rserve->ping_pool  = ping_pool_join ( rserve->ping_pool  );
     110           0 :   rserve->ping_map   = ping_map_join  ( rserve->ping_map   );
     111           0 :   rserve->ping_dlist = ping_dlist_join( rserve->ping_dlist );
     112             : 
     113           0 :   return (fd_rserve_t *)rserve;
     114           0 : }
     115             : 
     116             : void *
     117           0 : fd_rserve_leave( fd_rserve_t const * rserve ) {
     118           0 :   if( FD_UNLIKELY( !rserve ) ) {
     119           0 :     FD_LOG_WARNING(( "NULL rserve" ));
     120           0 :     return NULL;
     121           0 :   }
     122             : 
     123           0 :   return (void *)rserve;
     124           0 : }
     125             : 
     126             : void *
     127           0 : fd_rserve_delete( void * rserve ) {
     128           0 :   if( FD_UNLIKELY( !rserve ) ) {
     129           0 :     FD_LOG_WARNING(( "NULL rserve" ));
     130           0 :     return NULL;
     131           0 :   }
     132             : 
     133           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)rserve, fd_rserve_align() ) ) ) {
     134           0 :     FD_LOG_WARNING(( "misaligned rserve" ));
     135           0 :     return NULL;
     136           0 :   }
     137             : 
     138           0 :   return rserve;
     139           0 : }
     140             : 
     141             : void
     142             : fd_rserve_ping_token( fd_rserve_t const * rserve,
     143             :                       uchar               token[ 32 ],
     144             :                       fd_pubkey_t const * from,
     145             :                       uint                ip4,
     146           0 :                       ushort              port ) {
     147           0 :   fd_rserve_token_compute( token, rserve->secret_cur, from, ip4, port );
     148           0 : }
     149             : 
     150             : static int
     151             : fd_rserve_secret_pong_verify( uchar const         secret[ 32 ],
     152             :                               uchar const       * pong_hash,
     153             :                               fd_pubkey_t const * from,
     154             :                               uint                ip4,
     155           0 :                               ushort              port ) {
     156           0 :   uchar token   [ 32 ];
     157           0 :   uchar preimage[ FD_REPAIR_PONG_PREIMAGE_SZ ];
     158           0 :   uchar expected[ 32 ];
     159             : 
     160           0 :   fd_rserve_token_compute( token, secret, from, ip4, port );
     161           0 :   preimage_pong( (fd_hash_t const *)token, preimage );
     162           0 :   fd_sha256_hash( preimage, FD_REPAIR_PONG_PREIMAGE_SZ, expected );
     163           0 :   return !memcmp( expected, pong_hash, 32UL );
     164           0 : }
     165             : 
     166             : int
     167             : fd_rserve_pong_token_verify( fd_rserve_t const * rserve,
     168             :                              uchar const       * pong_hash,
     169             :                              fd_pubkey_t const * from,
     170             :                              uint                ip4,
     171           0 :                              ushort              port ) {
     172           0 :   if( FD_LIKELY( fd_rserve_secret_pong_verify( rserve->secret_cur,  pong_hash, from, ip4, port ) ) ) return 1;
     173           0 :   if( FD_LIKELY( fd_rserve_secret_pong_verify( rserve->secret_prev, pong_hash, from, ip4, port ) ) ) return 1;
     174           0 :   return 0;
     175           0 : }
     176             : 
     177             : void
     178             : fd_rserve_maybe_rotate( fd_rserve_t * rserve,
     179           0 :                         ulong         now_ns ) {
     180           0 :   if( FD_UNLIKELY( now_ns-rserve->last_rotate_ts > FD_RSERVE_TOKEN_ROTATE_NS ) ) {
     181           0 :     rserve->last_rotate_ts = now_ns;
     182           0 :     rserve->token_idx++;
     183           0 :     memcpy( rserve->secret_prev, rserve->secret_cur, 32UL );
     184           0 :     fd_rserve_rotation_secret( rserve->secret_cur, rserve->secret_master, rserve->token_idx );
     185           0 :   }
     186           0 : }
     187             : 

Generated by: LCOV version 1.14