LCOV - code coverage report
Current view: top level - discof/failover - fd_failover_proto.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 99 0.0 %
Date: 2026-11-11 12:40:43 Functions: 0 12 0.0 %

          Line data    Source code
       1             : #include "fd_failover_proto.h"
       2             : 
       3             : #include "../../ballet/ed25519/fd_ed25519.h"
       4             : #include "../../ballet/sha256/fd_sha256.h"
       5             : #include "../../disco/keyguard/fd_keyguard.h"
       6             : 
       7             : FD_STATIC_ASSERT( sizeof(FD_KEYGUARD_FAILOVER_CLIENT_DOMAIN)-1UL==FD_KEYGUARD_FAILOVER_DOMAIN_SZ, client_proof_domain );
       8             : FD_STATIC_ASSERT( sizeof(FD_KEYGUARD_FAILOVER_SERVER_DOMAIN)-1UL==FD_KEYGUARD_FAILOVER_DOMAIN_SZ, server_proof_domain );
       9             : 
      10             : int
      11             : fd_failover_hello_check( fd_failover_hello_t const * self,
      12           0 :                          fd_failover_hello_t const * peer ) {
      13           0 :   if( FD_UNLIKELY( self->version!=peer->version ) )                                return FD_FAILOVER_HELLO_ERR_VERSION;
      14           0 :   if( FD_UNLIKELY( self->holds>1 || peer->holds>1 ) )                              return FD_FAILOVER_HELLO_ERR_HOLDS;
      15           0 :   if( FD_UNLIKELY( self->mode!=FD_FAILOVER_MODE_ALPENGLOW ||
      16           0 :                    self->mode!=peer->mode ) )                                      return FD_FAILOVER_HELLO_ERR_MODE;
      17           0 :   if( FD_UNLIKELY( !self->boot_id || !peer->boot_id ) )                            return FD_FAILOVER_HELLO_ERR_BOOT_ID;
      18           0 :   if( FD_UNLIKELY( !fd_memeq( self->staked_pubkey, peer->staked_pubkey, 32UL ) ) ) return FD_FAILOVER_HELLO_ERR_STAKED;
      19           0 :   if( FD_UNLIKELY( self->boot_id==peer->boot_id ) )                                return FD_FAILOVER_HELLO_ERR_SELF;
      20           0 :   if( FD_UNLIKELY( self->holds && peer->holds ) )                                  return FD_FAILOVER_HELLO_ERR_BOTH_HOLD;
      21           0 :   return FD_FAILOVER_HELLO_OK;
      22           0 : }
      23             : 
      24             : void
      25             : fd_failover_admission_hash( fd_failover_admission_start_t const *     start,
      26             :                             uchar const *                            client_hello,
      27             :                             fd_failover_admission_challenge_t const * challenge,
      28           0 :                             uchar                                    out[ 32 ] ) {
      29           0 :   fd_sha256_t sha[1];
      30           0 :   fd_sha256_init( sha );
      31           0 :   fd_sha256_append( sha, start,        sizeof(*start)       );
      32           0 :   fd_sha256_append( sha, client_hello, start->client_hello_sz );
      33           0 :   fd_sha256_append( sha, challenge,    sizeof(*challenge)   );
      34           0 :   fd_sha256_fini( sha, out );
      35           0 : }
      36             : 
      37             : void
      38             : fd_failover_response_hash( uchar const   transcript[ 32 ],
      39             :                            uchar const   client_proof[ 64 ],
      40             :                            uchar const * server_flight,
      41             :                            ushort        server_flight_sz,
      42           0 :                            uchar         out[ 32 ] ) {
      43           0 :   fd_sha256_t sha[1];
      44           0 :   fd_sha256_init( sha );
      45           0 :   fd_sha256_append( sha, transcript,        32UL                     );
      46           0 :   fd_sha256_append( sha, client_proof,      64UL                     );
      47           0 :   fd_sha256_append( sha, &server_flight_sz, sizeof(server_flight_sz) );
      48           0 :   fd_sha256_append( sha, server_flight,     server_flight_sz         );
      49           0 :   fd_sha256_fini( sha, out );
      50           0 : }
      51             : 
      52             : void
      53             : fd_failover_proof_msg( uchar       out[ FD_KEYGUARD_FAILOVER_PROOF_SZ ],
      54             :                        int         server,
      55           0 :                        uchar const transcript[ 32 ] ) {
      56           0 :   fd_memcpy( out, server ? FD_KEYGUARD_FAILOVER_SERVER_DOMAIN : FD_KEYGUARD_FAILOVER_CLIENT_DOMAIN,
      57           0 :              FD_KEYGUARD_FAILOVER_DOMAIN_SZ );
      58           0 :   fd_memcpy( out+FD_KEYGUARD_FAILOVER_DOMAIN_SZ, transcript, 32UL );
      59           0 : }
      60             : 
      61             : int
      62             : fd_failover_handoff_request_decode( fd_failover_handoff_request_t * out,
      63             :                                     uchar const *                   payload,
      64           0 :                                     ulong                           payload_sz ) {
      65           0 :   if( FD_UNLIKELY( payload_sz!=sizeof(fd_failover_handoff_request_t) ) ) return 0;
      66           0 :   fd_failover_handoff_request_t request;
      67           0 :   fd_memcpy( &request, payload, sizeof(request) );
      68           0 :   if( FD_UNLIKELY( !request.handoff_id || !request.target_boot_id ) ) return 0;
      69           0 :   *out = request;
      70           0 :   return 1;
      71           0 : }
      72             : 
      73             : int
      74             : fd_failover_handoff_result_decode( fd_failover_handoff_result_t * out,
      75             :                                    uchar const *                  payload,
      76           0 :                                    ulong                          payload_sz ) {
      77           0 :   if( FD_UNLIKELY( payload_sz!=sizeof(fd_failover_handoff_result_t) ) ) return 0;
      78           0 :   fd_failover_handoff_result_t result;
      79           0 :   fd_memcpy( &result, payload, sizeof(result) );
      80           0 :   if( FD_UNLIKELY( !result.handoff_id ) ) return 0;
      81           0 :   *out = result;
      82           0 :   return 1;
      83           0 : }
      84             : 
      85             : ulong
      86             : fd_failover_demoted_encode( uchar *       out,
      87             :                             ulong         handoff_id,
      88             :                             ulong         target_boot_id,
      89             :                             ulong         last_vote_slot,
      90             :                             uchar const * state,
      91           0 :                             ulong         state_sz ) {
      92           0 :   if( FD_UNLIKELY( !state_sz || state_sz>FD_FAILOVER_ALPENGLOW_STATE_MAX ) ) return 0UL;
      93             : 
      94           0 :   fd_failover_demoted_t demoted = {
      95           0 :     .handoff_id     = handoff_id,
      96           0 :     .target_boot_id = target_boot_id,
      97           0 :     .last_vote_slot = last_vote_slot,
      98           0 :     .mode           = (uchar)FD_FAILOVER_MODE_ALPENGLOW,
      99           0 :     .state_len      = (ushort)state_sz,
     100           0 :   };
     101           0 :   fd_memcpy( out, &demoted, sizeof(demoted) );
     102           0 :   fd_memcpy( out+sizeof(demoted), state, state_sz );
     103           0 :   return sizeof(demoted)+state_sz;
     104           0 : }
     105             : 
     106             : int
     107             : fd_failover_demoted_decode( fd_failover_demoted_t * out,
     108             :                             uchar const *           payload,
     109           0 :                             ulong                   payload_sz ) {
     110           0 :   if( FD_UNLIKELY( payload_sz<sizeof(fd_failover_demoted_t) ||
     111           0 :                    payload_sz>FD_FAILOVER_DEMOTED_PAYLOAD_MAX ) ) return 0;
     112             : 
     113           0 :   fd_failover_demoted_t demoted;
     114           0 :   fd_memcpy( &demoted, payload, sizeof(demoted) );
     115             : 
     116           0 :   ulong state_sz = payload_sz-sizeof(fd_failover_demoted_t);
     117           0 :   if( FD_UNLIKELY( (ulong)demoted.state_len!=state_sz ||
     118           0 :                    !state_sz || state_sz>FD_FAILOVER_ALPENGLOW_STATE_MAX ||
     119           0 :                    demoted.mode!=(uchar)FD_FAILOVER_MODE_ALPENGLOW ||
     120           0 :                    demoted.last_vote_slot==FD_FAILOVER_SLOT_NULL ) ) return 0;
     121             : 
     122           0 :   *out = demoted;
     123           0 :   return 1;
     124           0 : }
     125             : 
     126             : ulong
     127             : fd_failover_promote_ack_encode( uchar * out,
     128           0 :                                 ulong   handoff_id ) {
     129           0 :   fd_failover_promote_ack_t ack = { .handoff_id=handoff_id };
     130           0 :   fd_memcpy( out, &ack, sizeof(ack) );
     131           0 :   return sizeof(ack);
     132           0 : }
     133             : 
     134             : ulong
     135             : fd_failover_promote_rejected_encode( uchar * out,
     136             :                                      ulong   handoff_id,
     137           0 :                                      uchar   reason ) {
     138           0 :   if( FD_UNLIKELY( reason==(uchar)FD_FAILOVER_REJECT_NONE || reason>=(uchar)FD_FAILOVER_REJECT_CNT ) ) return 0UL;
     139           0 :   fd_failover_promote_rejected_t rej = { .handoff_id=handoff_id, .reason=reason };
     140           0 :   fd_memcpy( out, &rej, sizeof(rej) );
     141           0 :   return sizeof(rej);
     142           0 : }
     143             : 
     144             : int
     145             : fd_failover_promote_ack_decode( fd_failover_promote_ack_t * out,
     146             :                                 uchar const *               payload,
     147           0 :                                 ulong                       payload_sz ) {
     148           0 :   if( FD_UNLIKELY( payload_sz!=sizeof(fd_failover_promote_ack_t) ) ) return 0;
     149           0 :   fd_memcpy( out, payload, sizeof(fd_failover_promote_ack_t) );
     150           0 :   return 1;
     151           0 : }
     152             : 
     153             : int
     154             : fd_failover_promote_rejected_decode( fd_failover_promote_rejected_t * out,
     155             :                                      uchar const *                    payload,
     156           0 :                                      ulong                            payload_sz ) {
     157           0 :   if( FD_UNLIKELY( payload_sz!=sizeof(fd_failover_promote_rejected_t) ) ) return 0;
     158           0 :   fd_failover_promote_rejected_t rej;
     159           0 :   fd_memcpy( &rej, payload, sizeof(rej) );
     160           0 :   if( FD_UNLIKELY( rej.reason==(uchar)FD_FAILOVER_REJECT_NONE || rej.reason>=(uchar)FD_FAILOVER_REJECT_CNT ) ) return 0;
     161           0 :   *out = rej;
     162           0 :   return 1;
     163           0 : }

Generated by: LCOV version 1.14