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

          Line data    Source code
       1             : #include "fd_tower_blocks.h"
       2             : 
       3             : void *
       4             : fd_tower_blocks_new( void * shmem,
       5             :                      ulong  slot_max,
       6           0 :                      ulong  seed ) {
       7           0 :   if( FD_UNLIKELY( !shmem ) ) {
       8           0 :     FD_LOG_WARNING(( "NULL mem" ));
       9           0 :     return NULL;
      10           0 :   }
      11             : 
      12           0 :   ulong footprint = fd_tower_blocks_footprint( slot_max );
      13           0 :   if( FD_UNLIKELY( !footprint ) ) {
      14           0 :     FD_LOG_WARNING(( "bad slot_max (%lu)", slot_max ));
      15           0 :     return NULL;
      16           0 :   }
      17             : 
      18           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_tower_blocks_align() ) ) ) {
      19           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      20           0 :     return NULL;
      21           0 :   }
      22             : 
      23           0 :   int   lg_slot_max  = fd_ulong_find_msb( fd_ulong_pow2_up( slot_max ) ) + 1;
      24             : 
      25           0 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      26           0 :   fd_tower_blocks_t * blocks = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_blocks_align(), sizeof(fd_tower_blocks_t)             );
      27           0 :   void *              map    = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_blk_align(),    fd_tower_blk_footprint( lg_slot_max ) );
      28           0 :   FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_tower_blocks_align() ) == (ulong)shmem + footprint );
      29             : 
      30           0 :   blocks->blk_map = fd_tower_blk_new( map, lg_slot_max, seed );
      31           0 :   FD_TEST( blocks->blk_map );
      32             : 
      33           0 :   return shmem;
      34           0 : }
      35             : 
      36             : fd_tower_blocks_t *
      37           0 : fd_tower_blocks_join( void * shblocks ) {
      38           0 :   fd_tower_blocks_t * blocks = (fd_tower_blocks_t *)shblocks;
      39             : 
      40           0 :   if( FD_UNLIKELY( !blocks ) ) {
      41           0 :     FD_LOG_WARNING(( "NULL tower_blocks" ));
      42           0 :     return NULL;
      43           0 :   }
      44             : 
      45           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned((ulong)blocks, fd_tower_blocks_align() ) ) ) {
      46           0 :     FD_LOG_WARNING(( "misaligned tower_blocks" ));
      47           0 :     return NULL;
      48           0 :   }
      49             : 
      50           0 :   blocks->blk_map = fd_tower_blk_join( blocks->blk_map );
      51           0 :   FD_TEST( blocks->blk_map );
      52             : 
      53           0 :   return blocks;
      54           0 : }
      55             : 
      56             : void *
      57           0 : fd_tower_blocks_leave( fd_tower_blocks_t const * blocks ) {
      58             : 
      59           0 :   if( FD_UNLIKELY( !blocks ) ) {
      60           0 :     FD_LOG_WARNING(( "NULL blocks" ));
      61           0 :     return NULL;
      62           0 :   }
      63             : 
      64           0 :   return (void *)blocks;
      65           0 : }
      66             : 
      67             : void *
      68           0 : fd_tower_blocks_delete( void * blocks ) {
      69             : 
      70           0 :   if( FD_UNLIKELY( !blocks ) ) {
      71           0 :     FD_LOG_WARNING(( "NULL blocks" ));
      72           0 :     return NULL;
      73           0 :   }
      74             : 
      75           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned((ulong)blocks, fd_tower_blocks_align() ) ) ) {
      76           0 :     FD_LOG_WARNING(( "misaligned blocks" ));
      77           0 :     return NULL;
      78           0 :   }
      79             : 
      80           0 :   return blocks;
      81           0 : }
      82             : 
      83             : int
      84             : is_ancestor( fd_tower_blk_t * forks,
      85             :              ulong              slot,
      86           0 :              ulong              ancestor_slot ) {
      87           0 :   fd_tower_blk_t * anc = fd_tower_blk_query( forks, slot, NULL );
      88           0 :   while( FD_LIKELY( anc ) ) {
      89           0 :     if( FD_LIKELY( anc->parent_slot == ancestor_slot ) ) return 1;
      90           0 :     anc = anc->parent_slot == ULONG_MAX ? NULL : fd_tower_blk_query( forks, anc->parent_slot, NULL );
      91           0 :   }
      92           0 :   return 0;
      93           0 : }
      94             : 
      95             : int
      96             : fd_tower_blocks_is_slot_ancestor( fd_tower_blocks_t * forks,
      97             :                            ulong        descendant_slot,
      98           0 :                            ulong        ancestor_slot ) {
      99           0 :   return is_ancestor( forks->blk_map, descendant_slot, ancestor_slot );
     100           0 : }
     101             : 
     102             : int
     103             : fd_tower_blocks_is_slot_descendant( fd_tower_blocks_t * forks,
     104             :                              ulong        ancestor_slot,
     105           0 :                              ulong        descendant_slot ) {
     106           0 :   return is_ancestor( forks->blk_map, descendant_slot, ancestor_slot );
     107           0 : }
     108             : 
     109             : ulong
     110             : fd_tower_blocks_lowest_common_ancestor( fd_tower_blocks_t * forks,
     111             :                                         ulong               slot1,
     112           0 :                                         ulong               slot2 ) {
     113             : 
     114           0 :   fd_tower_blk_t * fork1 = fd_tower_blk_query( forks->blk_map, slot1, NULL );
     115           0 :   fd_tower_blk_t * fork2 = fd_tower_blk_query( forks->blk_map, slot2, NULL );
     116             : 
     117           0 :   if( FD_UNLIKELY( !fork1 )) FD_LOG_CRIT(( "slot1 %lu not found", slot1 ));
     118           0 :   if( FD_UNLIKELY( !fork2 )) FD_LOG_CRIT(( "slot2 %lu not found", slot2 ));
     119             : 
     120           0 :   while( FD_LIKELY( fork1 && fork2 ) ) {
     121           0 :     if( FD_UNLIKELY( fork1->slot == fork2->slot ) ) return fork1->slot;
     122           0 :     if( fork1->slot > fork2->slot                 ) fork1 = fd_tower_blk_query( forks->blk_map, fork1->parent_slot, NULL );
     123           0 :     else                                            fork2 = fd_tower_blk_query( forks->blk_map, fork2->parent_slot, NULL );
     124           0 :   }
     125             : 
     126             :   /* If we reach here, then one of the slots is on a minority fork who's
     127             :      ancestor that connected it to the main fork has been pruned (i.e.)
     128             :      we have a dangling leaf right now! There is no LCA in this case. */
     129             : 
     130           0 :   return ULONG_MAX;
     131           0 : }
     132             : 
     133             : fd_hash_t const *
     134             : fd_tower_blocks_canonical_block_id( fd_tower_blocks_t * forks,
     135           0 :                                     ulong               slot ) {
     136           0 :   fd_tower_blk_t * fork = fd_tower_blk_query( forks->blk_map, slot, NULL );
     137           0 :   if( FD_UNLIKELY( !fork ) ) return NULL;
     138           0 :   if     ( FD_LIKELY( fork->confirmed ) ) return &fork->confirmed_block_id;
     139           0 :   else if( FD_LIKELY( fork->voted     ) ) return &fork->voted_block_id;
     140           0 :   else                                    return &fork->replayed_block_id;
     141           0 : }
     142             : 
     143             : fd_tower_blk_t *
     144           0 : fd_tower_blocks_query( fd_tower_blocks_t * forks, ulong slot ) {
     145           0 :   return fd_tower_blk_query( forks->blk_map, slot, NULL );
     146           0 : }
     147             : 
     148             : fd_tower_blk_t *
     149             : fd_tower_blocks_insert( fd_tower_blocks_t * forks,
     150             :                         ulong               slot,
     151           0 :                         ulong               parent_slot ) {
     152           0 :   fd_tower_blk_t * fork = fd_tower_blk_insert( forks->blk_map, slot );
     153           0 :   if( FD_UNLIKELY( !fork ) ) return NULL;
     154             : 
     155           0 :   memset( fork, 0, sizeof(fd_tower_blk_t) );
     156           0 :   fork->parent_slot = parent_slot;
     157           0 :   fork->slot        = slot;
     158           0 :   fork->confirmed   = 0;
     159           0 :   fork->voted       = 0;
     160           0 :   return fork;
     161           0 : }
     162             : 
     163             : void
     164             : fd_tower_blocks_remove( fd_tower_blocks_t * forks,
     165           0 :                         ulong               slot ) {
     166           0 :   fd_tower_blk_t * blk = fd_tower_blk_query( forks->blk_map, slot, NULL ); /* validate slot exists before removing */
     167           0 :   if( FD_LIKELY( blk ) ) fd_tower_blk_remove( forks->blk_map, blk );
     168           0 : }

Generated by: LCOV version 1.14