LCOV - code coverage report
Current view: top level - choreo/notar - fd_notar.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 114 0.0 %
Date: 2026-03-19 18:19:27 Functions: 0 6 0.0 %

          Line data    Source code
       1             : #include "fd_notar.h"
       2             : #include "../../util/bits/fd_bits.h"
       3             : 
       4             : void *
       5             : fd_notar_new( void * shmem,
       6           0 :               ulong  slot_max ) {
       7             : 
       8           0 :   if( FD_UNLIKELY( !shmem ) ) {
       9           0 :     FD_LOG_WARNING(( "NULL mem" ));
      10           0 :     return NULL;
      11           0 :   }
      12             : 
      13           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_notar_align() ) ) ) {
      14           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      15           0 :     return NULL;
      16           0 :   }
      17             : 
      18           0 :   ulong footprint = fd_notar_footprint( slot_max );
      19           0 :   if( FD_UNLIKELY( !footprint ) ) {
      20           0 :     FD_LOG_WARNING(( "bad slot_max (%lu)", slot_max ));
      21           0 :     return NULL;
      22           0 :   }
      23             : 
      24           0 :   fd_memset( shmem, 0, footprint );
      25             : 
      26           0 :   int lg_slot_max = fd_ulong_find_msb( fd_ulong_pow2_up( slot_max ) ) + 1;
      27           0 :   int lg_blk_max  = fd_ulong_find_msb( fd_ulong_pow2_up( slot_max * FD_VOTER_MAX ) ) + 1;
      28           0 :   int lg_vtr_max  = fd_ulong_find_msb( fd_ulong_pow2_up( FD_VOTER_MAX ) ) + 1;
      29             : 
      30           0 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      31           0 :   fd_notar_t * notar     = FD_SCRATCH_ALLOC_APPEND( l, fd_notar_align(),      sizeof(fd_notar_t)                     );
      32           0 :   void *       slot_map  = FD_SCRATCH_ALLOC_APPEND( l, fd_notar_slot_align(), fd_notar_slot_footprint( lg_slot_max ) );
      33           0 :   void *       blk_map   = FD_SCRATCH_ALLOC_APPEND( l, fd_notar_blk_align(),  fd_notar_blk_footprint( lg_blk_max )   );
      34           0 :   void *       vtr_map   = FD_SCRATCH_ALLOC_APPEND( l, fd_notar_vtr_align(),  fd_notar_vtr_footprint( lg_vtr_max )   );
      35           0 :   FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_notar_align() ) == (ulong)shmem + footprint );
      36             : 
      37           0 :   notar->root     = ULONG_MAX;
      38           0 :   notar->slot_max = slot_max;
      39           0 :   notar->slot_map = fd_notar_slot_new( slot_map, lg_slot_max, 0UL );
      40           0 :   notar->blk_map  = fd_notar_blk_new( blk_map, lg_blk_max, 0UL );
      41           0 :   notar->vtr_map  = fd_notar_vtr_new( vtr_map, lg_vtr_max, 0UL );
      42             : 
      43           0 :   return shmem;
      44           0 : }
      45             : 
      46             : fd_notar_t *
      47           0 : fd_notar_join( void * shnotar ) {
      48           0 :   fd_notar_t * notar = (fd_notar_t *)shnotar;
      49             : 
      50           0 :   if( FD_UNLIKELY( !notar ) ) {
      51           0 :     FD_LOG_WARNING(( "NULL notar" ));
      52           0 :     return NULL;
      53           0 :   }
      54             : 
      55           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned((ulong)notar, fd_notar_align() ) ) ) {
      56           0 :     FD_LOG_WARNING(( "misaligned notar" ));
      57           0 :     return NULL;
      58           0 :   }
      59             : 
      60           0 :   notar->slot_map = fd_notar_slot_join( notar->slot_map );
      61           0 :   notar->blk_map  = fd_notar_blk_join( notar->blk_map );
      62           0 :   notar->vtr_map  = fd_notar_vtr_join( notar->vtr_map );
      63             : 
      64           0 :   return notar;
      65           0 : }
      66             : 
      67             : void *
      68           0 : fd_notar_leave( fd_notar_t const * notar ) {
      69             : 
      70           0 :   if( FD_UNLIKELY( !notar ) ) {
      71           0 :     FD_LOG_WARNING(( "NULL notar" ));
      72           0 :     return NULL;
      73           0 :   }
      74             : 
      75           0 :   return (void *)notar;
      76           0 : }
      77             : 
      78             : void *
      79           0 : fd_notar_delete( void * notar ) {
      80             : 
      81           0 :   if( FD_UNLIKELY( !notar ) ) {
      82           0 :     FD_LOG_WARNING(( "NULL notar" ));
      83           0 :     return NULL;
      84           0 :   }
      85             : 
      86           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned((ulong)notar, fd_notar_align() ) ) ) {
      87           0 :     FD_LOG_WARNING(( "misaligned notar" ));
      88           0 :     return NULL;
      89           0 :   }
      90             : 
      91           0 :   return notar;
      92           0 : }
      93             : 
      94             : fd_notar_blk_t *
      95             : fd_notar_count_vote( fd_notar_t *        notar,
      96             :                      fd_pubkey_t const * addr,
      97             :                      ulong               vote_slot,
      98           0 :                      fd_hash_t const *   vote_block_id ) {
      99             : 
     100           0 :   if( FD_UNLIKELY( notar->root==ULONG_MAX                    ) ) return NULL; /* uninitialized root */
     101           0 :   if( FD_UNLIKELY( vote_slot < notar->root                   ) ) return NULL; /* vote too far behind */
     102           0 :   if( FD_UNLIKELY( vote_slot > notar->root + notar->slot_max ) ) return NULL; /* vote too far ahead */
     103             : 
     104           0 :   fd_notar_vtr_t const * vtr = fd_notar_vtr_query( notar->vtr_map, *addr, NULL );
     105           0 :   if( FD_UNLIKELY( !vtr ) ) return NULL; /* voter not found */
     106             : 
     107             :   /* Check we haven't already counted the voter's stake for this slot.
     108             :      If a voter votes for multiple block ids for the same slot, we only
     109             :      count their first one.  Honest voters never vote more than once for
     110             :      the same slot so the percentage of stake doing this should be small
     111             :      as only malicious voters would equivocate votes this way. */
     112             : 
     113           0 :   fd_notar_slot_t * notar_slot = fd_notar_slot_query( notar->slot_map, vote_slot, NULL );
     114           0 :   if( FD_UNLIKELY( !notar_slot ) ) {
     115           0 :     FD_TEST( fd_notar_slot_key_cnt( notar->slot_map ) < fd_notar_slot_slot_cnt( notar->slot_map ) );
     116           0 :     notar_slot                   = fd_notar_slot_insert( notar->slot_map, vote_slot );
     117           0 :     notar_slot->parent_slot      = ULONG_MAX;
     118           0 :     notar_slot->prev_leader_slot = ULONG_MAX;
     119           0 :     notar_slot->stake            = 0;
     120           0 :     notar_slot->is_leader        = 0;
     121           0 :     notar_slot->is_propagated    = 0;
     122           0 :     notar_slot->block_ids_cnt    = 0;
     123           0 :     fd_notar_slot_vtrs_null( notar_slot->vtrs );
     124           0 :   }
     125           0 :   if( FD_UNLIKELY( vtr->bit==ULONG_MAX                                   ) ) return NULL;
     126           0 :   if( FD_UNLIKELY( fd_notar_slot_vtrs_test( notar_slot->vtrs, vtr->bit ) ) ) return NULL;
     127           0 :   fd_notar_slot_vtrs_insert( notar_slot->vtrs, vtr->bit );
     128           0 :   notar_slot->stake += vtr->stake;
     129             : 
     130             :   /* Get the actual block with the block_id. */
     131             : 
     132           0 :   fd_notar_blk_t * notar_blk = fd_notar_blk_query( notar->blk_map, *vote_block_id, NULL );
     133           0 :   if( FD_UNLIKELY( !notar_blk ) ) {
     134           0 :     FD_TEST( notar_slot->block_ids_cnt < FD_VOTER_MAX ); /* at most one unique block id per voter in a slot */
     135           0 :     notar_blk            = fd_notar_blk_insert( notar->blk_map, *vote_block_id );
     136           0 :     notar_blk->slot      = vote_slot;
     137           0 :     notar_blk->stake     = 0;
     138           0 :     notar_blk->level     = -1;
     139           0 :     notar_blk->fwd_level = -1;
     140           0 :     notar_slot->block_ids[notar_slot->block_ids_cnt++] = *vote_block_id;
     141           0 :   }
     142           0 :   notar_blk->stake += vtr->stake;
     143           0 :   return notar_blk;
     144           0 : }
     145             : 
     146             : void
     147             : fd_notar_publish( fd_notar_t * notar,
     148           0 :                   ulong        root ) {
     149           0 :   for(ulong slot = notar->root; slot < root; slot++ ) {
     150           0 :     fd_notar_slot_t * notar_slot = fd_notar_slot_query( notar->slot_map, slot, NULL );
     151           0 :     if( FD_LIKELY( notar_slot ) ) {
     152           0 :       for( ulong i=0; i<notar_slot->block_ids_cnt; i++ ) {
     153           0 :         fd_hash_t const * block_id = &notar_slot->block_ids[i];
     154           0 :         fd_notar_blk_t * notar_blk = fd_notar_blk_query( notar->blk_map, *block_id, NULL );
     155           0 :         if( FD_UNLIKELY( !notar_blk ) ) { FD_BASE58_ENCODE_32_BYTES( block_id->uc, crit ); FD_LOG_CRIT(( "missing %lu %s %lu %lu", slot, crit, i, notar_slot->block_ids_cnt )); };
     156           0 :         fd_notar_blk_remove( notar->blk_map, notar_blk );
     157           0 :       }
     158           0 :       fd_notar_slot_remove( notar->slot_map, notar_slot );
     159           0 :     }
     160           0 :   }
     161           0 :   notar->root = root;
     162           0 : }

Generated by: LCOV version 1.14