LCOV - code coverage report
Current view: top level - flamenco/runtime/program/vote - fd_vote_state_v5.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 56 0.0 %
Date: 2026-11-11 12:40:43 Functions: 0 5 0.0 %

          Line data    Source code
       1             : #include "fd_vote_state_v5.h"
       2             : #include "fd_vote_utils.h"
       3             : #include "../fd_vote_program.h"
       4             : #include "../../fd_runtime.h"
       5             : 
       6             : static ulong
       7             : authorized_voter_idx( fd_vote_state_v5_t const * self,
       8           0 :                       ulong                      epoch ) {
       9           0 :   for( ulong i=0UL; i<self->authorized_voters_len; i++ ) {
      10           0 :     if( self->authorized_voters[ i ].epoch==epoch ) return i;
      11           0 :   }
      12           0 :   return ULONG_MAX;
      13           0 : }
      14             : 
      15             : static int
      16             : insert_authorized_voter( fd_vote_state_v5_t * self,
      17             :                          ulong                epoch,
      18           0 :                          fd_pubkey_t const *  pubkey ) {
      19           0 :   ulong cnt = self->authorized_voters_len;
      20           0 :   if( FD_UNLIKELY( cnt>=MAX_AUTHORIZED_VOTERS ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
      21             : 
      22           0 :   ulong i = cnt;
      23           0 :   for( ; i && self->authorized_voters[ i-1UL ].epoch>epoch; i-- ) {
      24           0 :     self->authorized_voters[ i ] = self->authorized_voters[ i-1UL ];
      25           0 :   }
      26           0 :   self->authorized_voters[ i ] = (fd_vote_state_v5_authorized_voter_t){ .epoch=epoch, .pubkey=*pubkey };
      27           0 :   self->authorized_voters_len  = (uint)( cnt+1UL );
      28           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
      29           0 : }
      30             : 
      31             : static void
      32             : purge_authorized_voters( fd_vote_state_v5_t * self,
      33           0 :                          ulong                epoch ) {
      34           0 :   ulong cnt  = self->authorized_voters_len;
      35           0 :   ulong skip = 0UL;
      36           0 :   while( skip<cnt && self->authorized_voters[ skip ].epoch<epoch ) skip++;
      37           0 :   memmove( self->authorized_voters, self->authorized_voters+skip, (cnt-skip)*sizeof(fd_vote_state_v5_authorized_voter_t) );
      38           0 :   fd_memset( self->authorized_voters+cnt-skip, 0, skip*sizeof(fd_vote_state_v5_authorized_voter_t) );
      39           0 :   self->authorized_voters_len = (uint)( cnt-skip );
      40           0 : }
      41             : 
      42             : int
      43             : fd_vote_state_v5_get_and_update_authorized_voter( fd_vote_state_v5_t * self,
      44             :                                                   ulong                current_epoch,
      45           0 :                                                   fd_pubkey_t **       pubkey ) {
      46           0 :   ulong idx = ULONG_MAX;
      47           0 :   for( ulong i=0UL; i<self->authorized_voters_len; i++ ) {
      48           0 :     if( self->authorized_voters[ i ].epoch<=current_epoch ) idx = i;
      49           0 :   }
      50           0 :   if( FD_UNLIKELY( idx==ULONG_MAX ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
      51             : 
      52           0 :   fd_pubkey_t voter   = self->authorized_voters[ idx ].pubkey;
      53           0 :   int         existed = self->authorized_voters[ idx ].epoch==current_epoch;
      54           0 :   purge_authorized_voters( self, fd_ulong_sat_sub( current_epoch, 1UL ) );
      55           0 :   if( !existed ) {
      56           0 :     int rc = insert_authorized_voter( self, current_epoch, &voter );
      57           0 :     if( FD_UNLIKELY( rc ) ) return rc;
      58           0 :   }
      59             : 
      60           0 :   *pubkey = &self->authorized_voters[ authorized_voter_idx( self, current_epoch ) ].pubkey;
      61           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
      62           0 : }
      63             : 
      64             : int
      65             : fd_vote_state_v5_set_new_authorized_voter( fd_exec_instr_ctx_t * ctx,
      66             :                                            fd_vote_state_v5_t *  self,
      67             :                                            fd_pubkey_t const *   authorized_pubkey,
      68             :                                            ulong                 current_epoch,
      69             :                                            ulong                 target_epoch,
      70             :                                            uchar const *         bls_pubkey,
      71             :                                            int                   authorized_withdrawer_signer,
      72             :                                            fd_pubkey_t const *   signers[ FD_INSTR_SIGNERS_MAX ],
      73           0 :                                            ulong                 signers_cnt ) {
      74           0 :   fd_pubkey_t * epoch_authorized_voter = NULL;
      75           0 :   int rc = fd_vote_state_v5_get_and_update_authorized_voter( self, current_epoch, &epoch_authorized_voter );
      76           0 :   if( FD_UNLIKELY( rc ) ) return rc;
      77             : 
      78           0 :   rc = fd_vote_signature_verify( epoch_authorized_voter, authorized_withdrawer_signer, signers, signers_cnt );
      79           0 :   if( FD_UNLIKELY( rc ) ) return rc;
      80             : 
      81           0 :   if( FD_UNLIKELY( authorized_voter_idx( self, target_epoch )!=ULONG_MAX ) ) {
      82           0 :     ctx->txn_out->err.custom_err = FD_VOTE_ERR_TOO_SOON_TO_REAUTHORIZE;
      83           0 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
      84           0 :   }
      85             : 
      86           0 :   rc = insert_authorized_voter( self, target_epoch, authorized_pubkey );
      87           0 :   if( FD_UNLIKELY( rc ) ) return rc;
      88             : 
      89           0 :   if( FD_LIKELY( bls_pubkey ) ) memcpy( self->bls_pubkey_compressed, bls_pubkey, FD_BLS_PUBKEY_COMPRESSED_SZ );
      90           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
      91           0 : }

Generated by: LCOV version 1.14