LCOV - code coverage report
Current view: top level - choreo/votor - test_ag_cert_builder.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 135 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 50 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_choreo_votor_test_ag_cert_builder_h
       2             : #define HEADER_fd_src_choreo_votor_test_ag_cert_builder_h
       3             : 
       4             : /* Certificates are built incrementally in ag_slot_state.c as votes
       5             :    arrive.  These rebuild one from a complete vote list, which tests
       6             :    need to get a cert in isolation; they are not part of the ag_cert
       7             :    API. */
       8             : 
       9             : #include "ag_cert.h"
      10             : #include "ag_epoch_info.h"
      11             : #include "ag_vote.h"
      12             : 
      13             : static inline void
      14             : bls_key_from_sec( ag_bls_key_t         out,
      15           0 :                   fd_bls_sec_t const * sec ) {
      16           0 :   fd_bls_pub_t pub[1];
      17           0 :   fd_bls_sec_to_pub( sec, pub );
      18           0 :   blst_p1_affine_compress( out, pub );
      19           0 : }
      20             : 
      21             : /* epoch_info_build fills epoch_info from an already ranked validator
      22             :    list.  Production ranks in the votor tile (rank_voters). */
      23             : 
      24             : static inline void
      25             : epoch_info_build( ag_epoch_info_t *           epoch_info,
      26             :                   ag_validator_info_t const * validators,
      27           0 :                   ulong                       validator_cnt ) {
      28           0 :   epoch_info->total_stake = 0UL;
      29           0 :   for( ulong i=0UL; i<validator_cnt; i++ ) {
      30           0 :     FD_TEST( validators[i].id==i );
      31           0 :     epoch_info->validators[i] = validators[i];
      32           0 :     FD_TEST( !fd_bls_pub_de( &epoch_info->pubkeys[i], validators[i].bls_key, sizeof(ag_bls_key_t) ) );
      33           0 :     epoch_info->total_stake  += validators[i].stake;
      34           0 :   }
      35           0 :   epoch_info->validator_cnt = validator_cnt;
      36           0 : }
      37             : 
      38             : static uchar const test_bls_public_key[ FD_BLS_PUB_COMPRESSED_SZ ] = {0};
      39             : 
      40             : /* sec_sign_fn is the fd_bls_sign_fn of a test that holds the secret
      41             :    key in memory; ctx points to the fd_bls_sec_t. */
      42             : 
      43             : static inline void
      44             : sec_sign_fn( void *         ctx,
      45             :              fd_bls_sig_t * sig,
      46             :              uchar const *  public_key,
      47             :              uchar const *  msg,
      48           0 :              ulong          msg_sz ) {
      49           0 :   (void)public_key;
      50           0 :   fd_bls_sec_sign( (fd_bls_sec_t const *)ctx, msg, msg_sz, sig );
      51           0 : }
      52             : 
      53             : static inline void
      54             : agg_add( fd_bls_agg_t *       agg,
      55             :          ulong                rank,
      56           0 :          fd_bls_sig_t const * sig ) {
      57           0 :   fd_bls_set_insert( agg->set, rank );
      58           0 :   blst_p2_add_or_double_affine( &agg->sig, &agg->sig, sig );
      59           0 : }
      60             : 
      61             : static inline int
      62           0 : agg_is_identity( fd_bls_agg_t const * agg ) {
      63           0 :   return !!blst_p2_is_inf( &agg->sig );
      64           0 : }
      65             : 
      66             : static inline ag_cert_t
      67             : cert_build_final( ag_vote_final_t const * votes, ulong vote_cnt, ag_epoch_info_t const * epoch_info );
      68             : static inline ag_cert_t
      69             : cert_build_fast_final( ag_vote_notar_t const * votes, ulong vote_cnt, ag_epoch_info_t const * epoch_info );
      70             : static inline ag_cert_t
      71             : cert_build_notar( ag_vote_notar_t const * votes, ulong vote_cnt, ag_epoch_info_t const * epoch_info );
      72             : static inline ag_cert_t
      73             : cert_build_notar_fallback( ag_vote_notar_t const * votes, ulong vote_cnt, ag_vote_notar_fallback_t const * fallback_votes, ulong fallback_vote_cnt, ag_epoch_info_t const * epoch_info );
      74             : static inline ag_cert_t
      75             : cert_build_skip( ag_vote_skip_t const * votes, ulong vote_cnt, ag_vote_skip_fallback_t const * fallback_votes, ulong fallback_vote_cnt, ag_epoch_info_t const * epoch_info );
      76             : 
      77             : static inline ag_cert_t
      78             : cert_build_final( ag_vote_final_t const * votes,
      79             :                   ulong                   vote_cnt,
      80           0 :                   ag_epoch_info_t const * epoch_info ) {
      81           0 :   ag_validator_info_t const * validators = ag_epoch_info_validators( epoch_info );
      82           0 :   FD_TEST( vote_cnt>0UL );
      83           0 :   ulong slot  = votes[0].slot;
      84           0 :   ulong stake = 0UL;
      85           0 :   for( ulong i=0UL; i<vote_cnt; i++ ) {
      86           0 :     FD_TEST( votes[i].slot==slot );
      87           0 :     stake += validators[ votes[i].rank ].stake;
      88           0 :   }
      89           0 :   ag_cert_final_t cert;
      90           0 :   cert.slot = slot; cert.stake = stake; cert.shred_version = votes[0].shred_version;
      91           0 :   memset( &cert.agg, 0, sizeof(fd_bls_agg_t) );
      92           0 :   for( ulong i=0UL; i<vote_cnt; i++ ) agg_add( &cert.agg, votes[i].rank, &votes[i].sig );
      93           0 :   return (ag_cert_t){ .kind = AG_CERT_KIND_FINAL, .final = cert };
      94           0 : }
      95             : 
      96             : static inline ag_cert_t
      97             : cert_build_fast_final( ag_vote_notar_t const * votes,
      98             :                        ulong                   vote_cnt,
      99           0 :                        ag_epoch_info_t const * epoch_info ) {
     100           0 :   ag_cert_notar_t      notar = cert_build_notar( votes, vote_cnt, epoch_info ).notar;
     101           0 :   ag_cert_fast_final_t cert;
     102           0 :   cert.slot = notar.slot; cert.stake = notar.stake; cert.agg = notar.agg; cert.shred_version = notar.shred_version;
     103           0 :   memcpy( cert.block_hash, notar.block_hash, sizeof(ag_block_hash_t) );
     104           0 :   return (ag_cert_t){ .kind = AG_CERT_KIND_FAST_FINAL, .fast_final = cert };
     105           0 : }
     106             : 
     107             : static inline ag_cert_t
     108             : cert_build_notar( ag_vote_notar_t const * votes,
     109             :                   ulong                   vote_cnt,
     110           0 :                   ag_epoch_info_t const * epoch_info ) {
     111           0 :   ag_validator_info_t const * validators = ag_epoch_info_validators( epoch_info );
     112           0 :   FD_TEST( vote_cnt>0UL );
     113           0 :   ulong           slot  = votes[0].slot;
     114           0 :   ulong           stake = 0UL;
     115           0 :   ag_block_hash_t block_hash;
     116           0 :   memcpy( block_hash, votes[0].block_hash, sizeof(ag_block_hash_t) );
     117           0 :   for( ulong i=0UL; i<vote_cnt; i++ ) {
     118           0 :     FD_TEST( votes[i].slot==slot );
     119           0 :     FD_TEST( !memcmp( votes[i].block_hash, block_hash, sizeof(ag_block_hash_t) ) );
     120           0 :     stake += validators[ votes[i].rank ].stake;
     121           0 :   }
     122           0 :   ag_cert_notar_t cert;
     123           0 :   cert.slot = slot; cert.stake = stake; cert.shred_version = votes[0].shred_version;
     124           0 :   memcpy( cert.block_hash, block_hash, sizeof(ag_block_hash_t) );
     125           0 :   memset( &cert.agg, 0, sizeof(fd_bls_agg_t) );
     126           0 :   for( ulong i=0UL; i<vote_cnt; i++ ) agg_add( &cert.agg, votes[i].rank, &votes[i].sig );
     127           0 :   return (ag_cert_t){ .kind = AG_CERT_KIND_NOTAR, .notar = cert };
     128           0 : }
     129             : 
     130             : static inline ag_cert_t
     131             : cert_build_notar_fallback( ag_vote_notar_t const *          votes,
     132             :                            ulong                            vote_cnt,
     133             :                            ag_vote_notar_fallback_t const * fallback_votes,
     134             :                            ulong                            fallback_vote_cnt,
     135           0 :                            ag_epoch_info_t const *          epoch_info ) {
     136           0 :   ag_validator_info_t const * validators = ag_epoch_info_validators( epoch_info );
     137           0 :   FD_TEST( vote_cnt>0UL || fallback_vote_cnt>0UL );
     138           0 :   ulong           slot;
     139           0 :   ag_block_hash_t block_hash;
     140           0 :   if( vote_cnt>0UL ) { slot = votes[0].slot;                   memcpy( block_hash, votes[0].block_hash,                   sizeof(ag_block_hash_t) ); }
     141           0 :   else               { slot = fallback_votes[0].slot; memcpy( block_hash, fallback_votes[0].block_hash, sizeof(ag_block_hash_t) ); }
     142             : 
     143           0 :   ulong stake = 0UL;
     144           0 :   for( ulong i=0UL; i<vote_cnt; i++ ) {
     145           0 :     FD_TEST( votes[i].slot==slot );
     146           0 :     FD_TEST( !memcmp( votes[i].block_hash, block_hash, sizeof(ag_block_hash_t) ) );
     147           0 :     stake += validators[ votes[i].rank ].stake;
     148           0 :   }
     149           0 :   ulong stake_fallback = 0UL;
     150           0 :   for( ulong i=0UL; i<fallback_vote_cnt; i++ ) {
     151           0 :     FD_TEST( fallback_votes[i].slot==slot );
     152           0 :     FD_TEST( !memcmp( fallback_votes[i].block_hash, block_hash, sizeof(ag_block_hash_t) ) );
     153           0 :     stake_fallback += validators[ fallback_votes[i].rank ].stake;
     154           0 :   }
     155             : 
     156           0 :   ag_cert_notar_fallback_t cert;
     157           0 :   cert.slot = slot; cert.shred_version = vote_cnt>0UL ? votes[0].shred_version : fallback_votes[0].shred_version;
     158           0 :   memcpy( cert.block_hash, block_hash, sizeof(ag_block_hash_t) );
     159           0 :   memset( &cert.agg_notar, 0, sizeof(fd_bls_agg_t) );
     160           0 :   for( ulong i=0UL; i<vote_cnt; i++ ) agg_add( &cert.agg_notar, votes[i].rank, &votes[i].sig );
     161           0 :   if( FD_UNLIKELY( agg_is_identity( &cert.agg_notar ) ) ) {
     162           0 :     memset( &cert.agg_notar, 0, sizeof(fd_bls_agg_t) );
     163           0 :     stake = 0UL;
     164           0 :   }
     165           0 :   memset( &cert.agg_notar_fallback, 0, sizeof(fd_bls_agg_t) );
     166           0 :   for( ulong i=0UL; i<fallback_vote_cnt; i++ ) agg_add( &cert.agg_notar_fallback, fallback_votes[i].rank, &fallback_votes[i].sig );
     167           0 :   if( FD_UNLIKELY( agg_is_identity( &cert.agg_notar_fallback ) ) ) {
     168           0 :     memset( &cert.agg_notar_fallback, 0, sizeof(fd_bls_agg_t) );
     169           0 :     stake_fallback = 0UL;
     170           0 :   }
     171           0 :   cert.stake = stake + stake_fallback;
     172           0 :   return (ag_cert_t){ .kind = AG_CERT_KIND_NOTAR_FALLBACK, .notar_fallback = cert };
     173           0 : }
     174             : 
     175             : static inline ag_cert_t
     176             : cert_build_skip( ag_vote_skip_t const *          votes,
     177             :                  ulong                           vote_cnt,
     178             :                  ag_vote_skip_fallback_t const * fallback_votes,
     179             :                  ulong                           fallback_vote_cnt,
     180           0 :                  ag_epoch_info_t const *         epoch_info ) {
     181           0 :   ag_validator_info_t const * validators = ag_epoch_info_validators( epoch_info );
     182           0 :   FD_TEST( vote_cnt>0UL || fallback_vote_cnt>0UL );
     183           0 :   ulong slot = vote_cnt>0UL ? votes[0].slot : fallback_votes[0].slot;
     184             : 
     185           0 :   ulong stake = 0UL;
     186           0 :   for( ulong i=0UL; i<vote_cnt; i++ ) {
     187           0 :     FD_TEST( votes[i].slot==slot );
     188           0 :     stake += validators[ votes[i].rank ].stake;
     189           0 :   }
     190           0 :   ulong stake_fallback = 0UL;
     191           0 :   for( ulong i=0UL; i<fallback_vote_cnt; i++ ) {
     192           0 :     FD_TEST( fallback_votes[i].slot==slot );
     193           0 :     stake_fallback += validators[ fallback_votes[i].rank ].stake;
     194           0 :   }
     195             : 
     196           0 :   ag_cert_skip_t cert;
     197           0 :   cert.slot = slot; cert.shred_version = vote_cnt>0UL ? votes[0].shred_version : fallback_votes[0].shred_version;
     198           0 :   memset( &cert.agg_skip, 0, sizeof(fd_bls_agg_t) );
     199           0 :   for( ulong i=0UL; i<vote_cnt; i++ ) agg_add( &cert.agg_skip, votes[i].rank, &votes[i].sig );
     200           0 :   if( FD_UNLIKELY( agg_is_identity( &cert.agg_skip ) ) ) {
     201           0 :     memset( &cert.agg_skip, 0, sizeof(fd_bls_agg_t) );
     202           0 :     stake = 0UL;
     203           0 :   }
     204           0 :   memset( &cert.agg_skip_fallback, 0, sizeof(fd_bls_agg_t) );
     205           0 :   for( ulong i=0UL; i<fallback_vote_cnt; i++ ) agg_add( &cert.agg_skip_fallback, fallback_votes[i].rank, &fallback_votes[i].sig );
     206           0 :   if( FD_UNLIKELY( agg_is_identity( &cert.agg_skip_fallback ) ) ) {
     207           0 :     memset( &cert.agg_skip_fallback, 0, sizeof(fd_bls_agg_t) );
     208           0 :     stake_fallback = 0UL;
     209           0 :   }
     210           0 :   cert.stake = stake + stake_fallback;
     211           0 :   return (ag_cert_t){ .kind = AG_CERT_KIND_SKIP, .skip = cert };
     212           0 : }
     213             : 
     214             : #endif

Generated by: LCOV version 1.14