LCOV - code coverage report
Current view: top level - flamenco/runtime/program/vote - fd_vote_utils.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 5 75 6.7 %
Date: 2026-06-29 05:51:35 Functions: 1 10 10.0 %

          Line data    Source code
       1             : #include "fd_vote_utils.h"
       2             : #include "fd_vote_codec.h"
       3             : #include "../fd_vote_program.h"
       4             : #include "../fd_program_util.h"
       5             : 
       6             : /**********************************************************************/
       7             : /* Lockout utilities                                                  */
       8             : /**********************************************************************/
       9             : 
      10             : // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L104
      11             : ulong
      12           0 : fd_vote_lockout_get_lockout( fd_vote_lockout_t * self ) {
      13             :   /* Confirmation count can never be greater than MAX_LOCKOUT_HISTORY, preventing overflow.
      14             :      Although Agave does not consider overflow, we do for fuzzing conformance. */
      15           0 :   ulong confirmation_count = fd_ulong_min( self->confirmation_count, MAX_LOCKOUT_HISTORY );
      16           0 :   return 1UL<<confirmation_count;
      17           0 : }
      18             : 
      19             : // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L110
      20             : ulong
      21           0 : fd_vote_lockout_last_locked_out_slot( fd_vote_lockout_t * self ) {
      22           0 :   return fd_ulong_sat_add( self->slot, fd_vote_lockout_get_lockout( self ) );
      23           0 : }
      24             : 
      25             : // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L114
      26             : ulong
      27           0 : fd_vote_lockout_is_locked_out_at_slot( fd_vote_lockout_t * self, ulong slot ) {
      28           0 :   return fd_vote_lockout_last_locked_out_slot( self ) >= slot;
      29           0 : }
      30             : 
      31             : // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L122
      32             : void
      33           0 : fd_vote_lockout_increase_confirmation_count( fd_vote_lockout_t * self, uint by ) {
      34           0 :   self->confirmation_count = fd_uint_sat_add( self->confirmation_count, by );
      35           0 : }
      36             : 
      37             : fd_landed_vote_t *
      38             : fd_vote_lockout_landed_votes_from_lockouts( fd_vote_lockout_t * lockouts,
      39           0 :                                             uchar *             mem ) {
      40           0 :   if( !lockouts ) return NULL;
      41             : 
      42           0 :   ulong cnt = deq_fd_vote_lockout_t_cnt( lockouts );
      43           0 :         cnt = fd_ulong_max( cnt, MAX_LOCKOUT_HISTORY );
      44             : 
      45           0 :   fd_landed_vote_t * landed_votes = deq_fd_landed_vote_t_join( deq_fd_landed_vote_t_new( mem, cnt ) );
      46           0 :   if( FD_UNLIKELY( !landed_votes ) ) {
      47           0 :     FD_LOG_CRIT(( "failed to join landed votes" ));
      48           0 :   }
      49             : 
      50           0 :   for( deq_fd_vote_lockout_t_iter_t iter = deq_fd_vote_lockout_t_iter_init( lockouts );
      51           0 :        !deq_fd_vote_lockout_t_iter_done( lockouts, iter );
      52           0 :        iter = deq_fd_vote_lockout_t_iter_next( lockouts, iter ) ) {
      53           0 :     fd_vote_lockout_t const * ele = deq_fd_vote_lockout_t_iter_ele_const( lockouts, iter );
      54             : 
      55           0 :     fd_landed_vote_t * elem = deq_fd_landed_vote_t_push_tail_nocopy( landed_votes );
      56             : 
      57           0 :     elem->latency                    = 0;
      58           0 :     elem->lockout.slot               = ele->slot;
      59           0 :     elem->lockout.confirmation_count = ele->confirmation_count;
      60           0 :   }
      61             : 
      62           0 :   return landed_votes;
      63           0 : }
      64             : 
      65             : /**********************************************************************/
      66             : /* Vote state utilities                                               */
      67             : /**********************************************************************/
      68             : 
      69             : int
      70             : fd_vote_verify_authorized_signer( fd_pubkey_t const * authorized,
      71             :                                   fd_pubkey_t const * signers[static FD_TXN_SIG_MAX],
      72           6 :                                   ulong               signers_cnt ) {
      73             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L989
      74           6 :   return fd_signers_contains( signers, signers_cnt, authorized ) ?
      75           6 :     FD_EXECUTOR_INSTR_SUCCESS :
      76           6 :     FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
      77           6 : }
      78             : 
      79             : int
      80             : fd_vote_signature_verify( fd_pubkey_t *       epoch_authorized_voter,
      81             :                           int                 authorized_withdrawer_signer,
      82             :                           fd_pubkey_t const * signers[static FD_TXN_SIG_MAX],
      83           0 :                           ulong               signers_cnt ) {
      84           0 :   return authorized_withdrawer_signer ? 0 : fd_vote_verify_authorized_signer( epoch_authorized_voter, signers, signers_cnt );
      85           0 : }
      86             : 
      87             : uchar
      88             : fd_vote_compute_vote_latency( ulong voted_for_slot,
      89           0 :                               ulong current_slot ) {
      90           0 :   return (uchar)fd_ulong_min( fd_ulong_sat_sub( current_slot, voted_for_slot ), UCHAR_MAX );
      91           0 : }
      92             : 
      93             : ulong
      94             : fd_vote_credits_for_vote_at_index( fd_landed_vote_t const * votes,
      95           0 :                                    ulong                    index ) {
      96             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L679
      97           0 :   fd_landed_vote_t const * landed_vote = deq_fd_landed_vote_t_peek_index_const( votes, index );
      98           0 :   ulong                    latency     = landed_vote == NULL ? 0 : landed_vote->latency;
      99             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L683
     100           0 :   ulong                    max_credits =  VOTE_CREDITS_MAXIMUM_PER_SLOT;
     101             : 
     102             :   /* If latency is 0, this means that the Lockout was created and stored
     103             :      from a software version that did not store vote latencies; in this
     104             :      case, 1 credit is awarded.
     105             :      https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L691 */
     106           0 :   if( FD_UNLIKELY( latency==0UL ) ) {
     107           0 :     return 1;
     108           0 :   }
     109             : 
     110           0 :   ulong diff = 0;
     111           0 :   int   cf   = fd_ulong_checked_sub( latency, VOTE_CREDITS_GRACE_SLOTS, &diff );
     112           0 :   if( cf || diff==0UL ) {
     113             :     // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L697
     114           0 :     return max_credits;
     115           0 :   }
     116             : 
     117           0 :   ulong credits = 0;
     118           0 :   cf = fd_ulong_checked_sub( max_credits, diff, &credits );
     119           0 :   if( cf != 0 || credits == 0 ) {
     120             :     // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L705
     121           0 :     return 1;
     122           0 :   }
     123             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L707
     124           0 :   return credits;
     125           0 : }
     126             : 
     127             : int
     128             : fd_vote_contains_slot( fd_landed_vote_t const * votes,
     129           0 :                        ulong                    slot ) {
     130             :   /* Logic is copied from slice::binary_search_by() in Rust. While not fully optimized,
     131             :      it aims to achieve fuzzing conformance for both sorted and unsorted inputs. */
     132           0 :   ulong size = deq_fd_landed_vote_t_cnt( votes );
     133           0 :   if( FD_UNLIKELY( size==0UL ) ) return 0;
     134             : 
     135           0 :   ulong base = 0UL;
     136           0 :   while( size>1UL ) {
     137           0 :     ulong half = size / 2UL;
     138           0 :     ulong mid = base + half;
     139           0 :     ulong mid_slot = deq_fd_landed_vote_t_peek_index_const( votes, mid )->lockout.slot;
     140           0 :     base = (slot<mid_slot) ? base : mid;
     141           0 :     size -= half;
     142           0 :   }
     143             : 
     144           0 :   return deq_fd_landed_vote_t_peek_index_const( votes, base )->lockout.slot==slot;
     145           0 : }

Generated by: LCOV version 1.14