LCOV - code coverage report
Current view: top level - choreo/tower - fd_tower_serde.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 73 94 77.7 %
Date: 2026-02-13 06:06:24 Functions: 6 6 100.0 %

          Line data    Source code
       1             : #include "fd_tower_serde.h"
       2             : #include "fd_tower.h"
       3             : 
       4             : #define SHORTVEC 0
       5             : 
       6         108 : #define DE( T, name ) do {                                                               \
       7         108 :     if( FD_UNLIKELY( off+sizeof(T)>buf_sz ) ) return -1;                                 \
       8         108 :     serde->name = *(T const *)fd_type_pun_const( buf+off );                              \
       9         108 :     off += sizeof(T);                                                                    \
      10         108 : } while(0)
      11             : 
      12         108 : #define SER( T, name ) do {                                                               \
      13         108 :     if( FD_UNLIKELY( off+sizeof(T)>buf_sz ) ) return -1;                                 \
      14         108 :     FD_STORE( T, buf+off, serde->name );                                                 \
      15         108 :     off += sizeof(T);                                                                    \
      16         108 : } while(0)
      17             : 
      18             : static ulong
      19           3 : de_short_u16( ushort * dst, uchar const * src ) {
      20           3 :   if     ( FD_LIKELY( !(0x80U & src[0]) ) ) { *dst = (ushort)src[0];                                                                           return 1; }
      21           0 :   else if( FD_LIKELY( !(0x80U & src[1]) ) ) { *dst = (ushort)((ulong)(src[0]&0x7FUL) + (((ulong)src[1])<<7));                                  return 2; }
      22           0 :   else                                      { *dst = (ushort)((ulong)(src[0]&0x7FUL) + (((ulong)(src[1]&0x7FUL))<<7) + (((ulong)src[2])<<14)); return 3; }
      23           3 : }
      24             : 
      25             : static ulong
      26          93 : de_var_int( ulong * dst, uchar const * src ) {
      27          93 :   *dst = 0;
      28          93 :   ulong off = 0;
      29          93 :   ulong bit = 0;
      30          93 :   while( FD_LIKELY( bit < 64 ) ) {
      31          93 :     uchar byte = *(uchar const *)(src+off);
      32          93 :     off       += 1;
      33          93 :     *dst      |= (byte & 0x7FUL) << bit;
      34          93 :     if( FD_LIKELY( (byte & 0x80U) == 0U ) ) {
      35          93 :       if( FD_UNLIKELY( (*dst>>bit) != byte                ) ) FD_LOG_CRIT(( "de_varint" ));
      36          93 :       if( FD_UNLIKELY( byte==0U && (bit!=0U || *dst!=0UL) ) ) FD_LOG_CRIT(( "de_varint" ));
      37          93 :       return off;
      38          93 :     }
      39           0 :     bit += 7;
      40           0 :   }
      41           0 :   FD_LOG_CRIT(( "de_varint" ));
      42           0 : }
      43             : 
      44             : static ulong
      45           3 : ser_short_u16( uchar * dst, ushort val ) {
      46           3 :   if     ( FD_LIKELY( val < 0x80U ) ) {
      47           3 :     dst[0] = (uchar)val;
      48           3 :     return 1;
      49           3 :   }
      50           0 :   else if( FD_LIKELY( val < 0x4000U ) ) {
      51           0 :     dst[0] = (uchar)((val & 0x7FUL) | 0x80U);
      52           0 :     dst[1] = (uchar)(val >> 7);
      53           0 :     return 2;
      54           0 :   }
      55           0 :   else {
      56           0 :     dst[0] = (uchar)((val & 0x7FUL) | 0x80U);
      57           0 :     dst[1] = (uchar)(((val >> 7) & 0x7FUL) | 0x80U);
      58           0 :     dst[2] = (uchar)(val >> 14);
      59           0 :     return 3;
      60           0 :   }
      61           3 : }
      62             : 
      63             : static ulong
      64          93 : ser_var_int( uchar * dst, ulong val ) {
      65          93 :   ulong off = 0;
      66          93 :   while( FD_LIKELY( val >= 0x80UL ) ) {
      67           0 :     dst[off] = (uchar)((val & 0x7FUL) | 0x80U);
      68           0 :     val >>= 7;
      69           0 :     off  += 1;
      70           0 :   }
      71          93 :   dst[off] = (uchar)val;
      72          93 :   return off + 1;
      73          93 : }
      74             : 
      75             : int
      76             : fd_compact_tower_sync_deserialize( fd_compact_tower_sync_serde_t * serde,
      77             :                                    uchar const *                   buf,
      78           3 :                                    ulong                           buf_sz ) {
      79           3 :   ulong off = 0;
      80           3 :   DE( ulong, root );
      81           3 :   off += de_short_u16( &serde->lockouts_cnt, buf+off );
      82           3 :   if( FD_UNLIKELY( serde->lockouts_cnt > FD_TOWER_VOTE_MAX ) ) return -1;
      83          96 :   for( ulong i = 0; i < serde->lockouts_cnt; i++ ) {
      84          93 :     off += de_var_int( &serde->lockouts[i].offset, buf+off );
      85          93 :     DE( uchar, lockouts[i].confirmation_count );
      86          93 :   }
      87           3 :   DE( fd_hash_t, hash             );
      88           3 :   DE( uchar,     timestamp_option );
      89           3 :   if( FD_LIKELY( serde->timestamp_option ) ) {
      90           3 :     DE( long, timestamp );
      91           3 :   }
      92           3 :   DE( fd_hash_t, block_id );
      93           3 :   return 0;
      94           3 : }
      95             : 
      96             : int
      97             : fd_compact_tower_sync_serialize( fd_compact_tower_sync_serde_t const * serde,
      98             :                                  uchar *                               buf,
      99             :                                  ulong                                 buf_sz,
     100           3 :                                  ulong *                               out_sz ) {
     101           3 :   ulong off = 0;
     102           3 :   SER( ulong, root );
     103           3 :   off += ser_short_u16( buf+off, serde->lockouts_cnt );
     104           3 :   if( FD_UNLIKELY( serde->lockouts_cnt > FD_TOWER_VOTE_MAX ) ) return -1;
     105          96 :   for( ulong i = 0; i < serde->lockouts_cnt; i++ ) {
     106          93 :     off += ser_var_int( buf+off, serde->lockouts[i].offset );
     107          93 :     SER( uchar, lockouts[i].confirmation_count );
     108          93 :   }
     109           3 :   SER( fd_hash_t, hash             );
     110           3 :   SER( uchar,     timestamp_option );
     111           3 :   if( FD_LIKELY( serde->timestamp_option ) ) {
     112           3 :     SER( long, timestamp );
     113           3 :   }
     114           3 :   SER( fd_hash_t, block_id );
     115           3 :   if( FD_LIKELY( out_sz ) ) *out_sz = off;
     116           3 :   return 0;
     117           3 : }

Generated by: LCOV version 1.14