LCOV - code coverage report
Current view: top level - disco/keyguard - fd_keyguard_client.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 83 0.0 %
Date: 2026-09-17 04:28:31 Functions: 0 5 0.0 %

          Line data    Source code
       1             : #include "fd_keyguard_client.h"
       2             : #include "fd_keyguard.h"
       3             : 
       4             : #include "../../tango/mcache/fd_mcache.h"
       5             : #include "../../tango/dcache/fd_dcache.h"
       6             : 
       7             : static inline void
       8             : fd_keyguard_client_publish( fd_keyguard_client_t * client,
       9             :                             ulong                  sig,
      10           0 :                             ulong                  sign_data_len ) {
      11           0 : #if FD_HAS_AVX
      12           0 :   fd_mcache_publish_avx( client->request, client->request_depth, client->request_seq, sig, client->request_chunk, sign_data_len, 0UL, 0UL, 0UL );
      13             : #elif FD_HAS_ARM
      14             :   fd_mcache_publish_arm( client->request, client->request_depth, client->request_seq, sig, client->request_chunk, sign_data_len, 0UL, 0UL, 0UL );
      15             : #else
      16             :   fd_mcache_publish( client->request, client->request_depth, client->request_seq, sig, client->request_chunk, sign_data_len, 0UL, 0UL, 0UL );
      17             : #endif
      18           0 : }
      19             : 
      20             : void *
      21             : fd_keyguard_client_new( void *           shmem,
      22             :                         fd_frag_meta_t * request_mcache,
      23             :                         uchar *          request_dcache,
      24             :                         fd_frag_meta_t * response_mcache,
      25             :                         uchar *          response_dcache,
      26             :                         ulong            request_mtu,
      27           0 :                         ulong            response_mtu ) {
      28           0 :   fd_keyguard_client_t * client = (fd_keyguard_client_t*)shmem;
      29             : 
      30           0 :   client->request        = request_mcache;
      31           0 :   client->request_depth  = fd_mcache_depth( request_mcache );
      32           0 :   client->request_seq    = 0UL;
      33           0 :   client->request_mem    = fd_wksp_containing( request_dcache );
      34           0 :   client->request_chunk0 = fd_dcache_compact_chunk0( client->request_mem, request_dcache );
      35           0 :   client->request_wmark  = fd_dcache_compact_wmark( client->request_mem, request_dcache, request_mtu );
      36           0 :   client->request_chunk  = client->request_chunk0;
      37           0 :   client->request_mtu    = request_mtu;
      38             : 
      39           0 :   client->response        = response_mcache;
      40           0 :   client->response_depth  = fd_mcache_depth( response_mcache );
      41           0 :   client->response_seq    = 0UL;
      42           0 :   client->response_mem    = fd_wksp_containing( response_dcache );
      43           0 :   client->response_chunk0 = fd_dcache_compact_chunk0( client->response_mem, response_dcache );
      44           0 :   client->response_wmark  = fd_dcache_compact_wmark( client->response_mem, response_dcache, response_mtu );
      45           0 :   client->response_mtu    = response_mtu;
      46             : 
      47           0 :   return shmem;
      48           0 : }
      49             : 
      50             : /* fd_keyguard_client_sign_sz is the common request/response path.
      51             :    signature_sz is the size of the signature the sign tile responds
      52             :    with for sign_type. */
      53             : 
      54             : static void
      55             : fd_keyguard_client_sign_sz( fd_keyguard_client_t * client,
      56             :                             uchar *                signature,
      57             :                             ulong                  signature_sz,
      58             :                             uchar const *          sign_data,
      59             :                             ulong                  sign_data_len,
      60           0 :                             int                    sign_type ) {
      61           0 :   FD_TEST( sign_data_len<=client->request_mtu );
      62             : 
      63           0 :   uchar * dst = fd_chunk_to_laddr( client->request_mem, client->request_chunk );
      64           0 :   fd_memcpy( dst, sign_data, sign_data_len );
      65             : 
      66           0 :   ulong sig = (ulong)(uint)sign_type;
      67           0 :   fd_keyguard_client_publish( client, sig, sign_data_len );
      68           0 :   client->request_seq   = fd_seq_inc( client->request_seq, 1UL );
      69           0 :   client->request_chunk = fd_dcache_compact_next( client->request_chunk, sign_data_len, client->request_chunk0, client->request_wmark );
      70             : 
      71           0 :   fd_frag_meta_t meta;
      72           0 :   fd_frag_meta_t const * mline;
      73           0 :   ulong seq_found;
      74           0 :   long seq_diff;
      75           0 :   ulong poll_max = ULONG_MAX;
      76           0 :   FD_MCACHE_WAIT( &meta, mline, seq_found, seq_diff, poll_max, client->response, client->response_depth, client->response_seq );
      77           0 :   if( FD_UNLIKELY( !poll_max ) ) FD_LOG_ERR(( "sign request timed out while polling" ));
      78           0 :   if( FD_UNLIKELY( seq_diff ) ) FD_LOG_ERR(( "sign request was overrun while polling" ));
      79           0 :   FD_HW_MFENCE_LD();
      80             : 
      81             :   /* Chunk is in shared memory and might be be written to by an
      82             :      attacking tile after we validate it, so load once. */
      83           0 :   ulong chunk = FD_VOLATILE_CONST( mline->chunk );
      84           0 :   FD_TEST( chunk>=client->response_chunk0 && chunk<=client->response_wmark );
      85             : 
      86           0 :   FD_TEST( signature_sz<=client->response_mtu );
      87           0 :   uchar * src = fd_chunk_to_laddr( client->response_mem, chunk );
      88           0 :   fd_memcpy( signature, src, signature_sz );
      89             : 
      90           0 :   FD_HW_MFENCE_LD();
      91           0 :   seq_found = fd_frag_meta_seq_query( mline );
      92           0 :   if( FD_UNLIKELY( fd_seq_ne( seq_found, client->response_seq ) ) ) FD_LOG_ERR(( "sign request was overrun while reading" ));
      93           0 :   client->response_seq = fd_seq_inc( client->response_seq, 1UL );
      94           0 : }
      95             : 
      96             : void
      97             : fd_keyguard_client_sign( fd_keyguard_client_t * client,
      98             :                          uchar *                signature,
      99             :                          uchar const *          sign_data,
     100             :                          ulong                  sign_data_len,
     101           0 :                          int                    sign_type ) {
     102           0 :   ulong signature_sz = fd_ulong_if( sign_type==FD_KEYGUARD_SIGN_TYPE_BLS, FD_KEYGUARD_BLS_SIG_SZ, 64UL );
     103           0 :   fd_keyguard_client_sign_sz( client, signature, signature_sz, sign_data, sign_data_len, sign_type );
     104           0 : }
     105             : 
     106             : void
     107             : fd_keyguard_client_vote_txn_sign( fd_keyguard_client_t * client,
     108             :                                   uchar *                signatures,
     109             :                                   ulong                  authority_idx,
     110             :                                   uchar const *          sign_data,
     111           0 :                                   ulong                  sign_data_len ) {
     112           0 :   FD_CHECK_CRIT( sign_data_len<=client->request_mtu, "the request is too large and will not fit in the mtu" );
     113           0 :   FD_CHECK_CRIT( authority_idx==ULONG_MAX || authority_idx<16UL, "unexpected authorized voter index" );
     114             : 
     115           0 :   uchar * dst = fd_chunk_to_laddr( client->request_mem, client->request_chunk );
     116             : 
     117             :   /* In the signature of the message we use the lower 32 bits to
     118             :      indicate the sign type.  We can use the upper 32 bits to encode if
     119             :      a second signature is needed and what index the authorized voter
     120             :      that a signature is needed from.
     121             :      The least significant bit of the upper 32 is 1 if a second
     122             :      signature is needed.  The next 4 least significant bits of the
     123             :      upper 32 are used to encode the index of the authorized voter
     124             :      where the index is [0,16). */
     125             : 
     126           0 :   ulong sig = 0UL;
     127           0 :   if( authority_idx!=ULONG_MAX ) sig |= (1UL << 32) | (authority_idx << 33);
     128           0 :   memcpy( dst, sign_data, sign_data_len );
     129             : 
     130           0 :   fd_keyguard_client_publish( client, sig, sign_data_len );
     131           0 :   client->request_seq   = fd_seq_inc( client->request_seq, 1UL );
     132           0 :   client->request_chunk = fd_dcache_compact_next( client->request_chunk, sign_data_len, client->request_chunk0, client->request_wmark );
     133             : 
     134           0 :   fd_frag_meta_t meta;
     135           0 :   fd_frag_meta_t const * mline;
     136           0 :   ulong seq_found;
     137           0 :   long seq_diff;
     138           0 :   ulong poll_max = ULONG_MAX;
     139           0 :   FD_MCACHE_WAIT( &meta, mline, seq_found, seq_diff, poll_max, client->response, client->response_depth, client->response_seq );
     140           0 :   if( FD_UNLIKELY( !poll_max ) ) FD_LOG_ERR(( "sign request timed out while polling" ));
     141           0 :   if( FD_UNLIKELY( seq_diff ) ) FD_LOG_ERR(( "sign request was overrun while polling" ));
     142           0 :   FD_HW_MFENCE_LD();
     143             : 
     144             :   /* Chunk is in shared memory and might be be written to by an
     145             :       attacking tile after we validate it, so load once. */
     146           0 :   ulong chunk = FD_VOLATILE_CONST( mline->chunk );
     147           0 :   FD_TEST( chunk>=client->response_chunk0 && chunk<=client->response_wmark );
     148             : 
     149           0 :   uchar * src = fd_chunk_to_laddr( client->response_mem, chunk );
     150           0 :   memcpy( signatures, src, 64UL );
     151           0 :   if( authority_idx!=ULONG_MAX ) memcpy( signatures+64UL, src+64UL, 64UL );
     152             : 
     153           0 :   FD_HW_MFENCE_LD();
     154           0 :   seq_found = fd_frag_meta_seq_query( mline );
     155           0 :   if( FD_UNLIKELY( fd_seq_ne( seq_found, client->response_seq ) ) ) FD_LOG_ERR(( "sign request was overrun while reading" ));
     156           0 :   client->response_seq = fd_seq_inc( client->response_seq, 1UL );
     157           0 : }

Generated by: LCOV version 1.14