LCOV - code coverage report
Current view: top level - choreo/votor - fd_vote_history_serde.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 94 0.0 %
Date: 2026-11-11 12:40:43 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #include "fd_vote_history_serde.h"
       2             : 
       3             : #include "../../ballet/ed25519/fd_ed25519.h"
       4             : 
       5             : void
       6             : fd_vote_history_ser( uchar const identity[ static 32 ],
       7             :                      ulong       root,
       8           0 :                      uchar       buf[ static FD_VOTE_HISTORY_SER_SZ ] ) {
       9           0 :   FD_STORE( uint,  buf,                                    FD_VOTE_HISTORY_SERDE_KIND                            );
      10           0 :   FD_STORE( ulong, buf+FD_VOTE_HISTORY_SERDE_SIG_OFF+64UL, FD_VOTE_HISTORY_SER_SZ-FD_VOTE_HISTORY_SERDE_DATA_OFF );
      11           0 :   memcpy( buf+FD_VOTE_HISTORY_SERDE_DATA_OFF,      identity, 32UL    );
      12           0 :   memset( buf+FD_VOTE_HISTORY_SERDE_DATA_OFF+32UL, 0,        9UL*8UL );
      13           0 :   FD_STORE( ulong, buf+FD_VOTE_HISTORY_SER_SZ-8UL, root );
      14           0 : }
      15             : 
      16           0 : #define LOAD( T, dst ) do {                                                         \
      17           0 :     if( FD_UNLIKELY( sizeof(T)>buf_sz-off ) ) return FD_VOTE_HISTORY_DE_ERR_SIZE; \
      18           0 :     (dst) = FD_LOAD( T, buf+off );                                                  \
      19           0 :     off += sizeof(T);                                                               \
      20           0 :   } while(0)
      21             : 
      22             : /* LOAD_LEN loads a u64 sequence length of elements at least min_sz
      23             :    bytes each, rejecting lengths the rest of the buffer cannot hold. */
      24           0 : #define LOAD_LEN( dst, min_sz ) do {                                                       \
      25           0 :     LOAD( ulong, dst );                                                                    \
      26           0 :     if( FD_UNLIKELY( (dst)>(buf_sz-off)/(min_sz) ) ) return FD_VOTE_HISTORY_DE_ERR_SIZE; \
      27           0 :   } while(0)
      28             : 
      29           0 : #define SKIP( sz ) do {                                                        \
      30           0 :     if( FD_UNLIKELY( (sz)>buf_sz-off ) ) return FD_VOTE_HISTORY_DE_ERR_SIZE; \
      31           0 :     off += (sz);                                                               \
      32           0 :   } while(0)
      33             : 
      34             : /* LOAD_VOTE loads a slot voted in and folds it into max_vote. */
      35           0 : #define LOAD_VOTE( dst ) do {                   \
      36           0 :     LOAD( ulong, dst );                         \
      37           0 :     max_vote = fd_ulong_max( max_vote, (dst) ); \
      38           0 :   } while(0)
      39             : 
      40           0 : #define LOAD_VOTES() do {                                           \
      41           0 :     ulong n_; LOAD_LEN( n_, 8UL );                                  \
      42           0 :     for( ulong i_=0UL; i_<n_; i_++ ) { ulong s_; LOAD_VOTE( s_ ); } \
      43           0 :   } while(0)
      44             : 
      45             : int
      46             : fd_vote_history_de( uchar const * buf,
      47             :                     ulong         buf_sz,
      48             :                     uchar const   identity[ static 32 ],
      49           0 :                     ulong *       wait_to_vote_slot ) {
      50           0 :   ulong off = 0UL;
      51             : 
      52           0 :   uint kind; LOAD( uint, kind );
      53           0 :   if( FD_UNLIKELY( kind!=FD_VOTE_HISTORY_SERDE_KIND ) ) return FD_VOTE_HISTORY_DE_ERR_VERSION;
      54             : 
      55           0 :   if( FD_UNLIKELY( buf_sz<FD_VOTE_HISTORY_SERDE_DATA_OFF ) ) return FD_VOTE_HISTORY_DE_ERR_SIZE;
      56           0 :   uchar const * sig = buf+FD_VOTE_HISTORY_SERDE_SIG_OFF;
      57           0 :   off = FD_VOTE_HISTORY_SERDE_SIG_OFF+64UL;
      58           0 :   ulong data_sz; LOAD( ulong, data_sz );
      59           0 :   if( FD_UNLIKELY( data_sz>buf_sz-FD_VOTE_HISTORY_SERDE_DATA_OFF                  ) ) return FD_VOTE_HISTORY_DE_ERR_SIZE;
      60           0 :   if( FD_UNLIKELY( data_sz>FD_VOTE_HISTORY_DE_MAX-FD_VOTE_HISTORY_SERDE_DATA_OFF ) ) return FD_VOTE_HISTORY_DE_ERR_SIZE;
      61           0 :   buf_sz = FD_VOTE_HISTORY_SERDE_DATA_OFF+data_sz; /* bytes after the history are ignored, as Agave does */
      62             : 
      63           0 :   fd_sha512_t sha[ 1 ];
      64           0 :   if( FD_UNLIKELY( FD_ED25519_SUCCESS!=fd_ed25519_verify( buf+FD_VOTE_HISTORY_SERDE_DATA_OFF, data_sz, sig, identity, sha ) ) ) return FD_VOTE_HISTORY_DE_ERR_SIG;
      65             : 
      66           0 :   if( FD_UNLIKELY( 32UL>buf_sz-off ) ) return FD_VOTE_HISTORY_DE_ERR_SIZE;
      67           0 :   if( FD_UNLIKELY( !fd_memeq( buf+off, identity, 32UL ) ) ) return FD_VOTE_HISTORY_DE_ERR_IDENTITY;
      68           0 :   off += 32UL;
      69             : 
      70           0 :   ulong max_vote = 0UL;
      71             : 
      72           0 :   LOAD_VOTES(); /* voted */
      73             : 
      74           0 :   ulong notar_cnt; LOAD_LEN( notar_cnt, 40UL );
      75           0 :   for( ulong i=0UL; i<notar_cnt; i++ ) {
      76           0 :     ulong slot; LOAD_VOTE( slot );
      77           0 :     SKIP( 32UL );
      78           0 :   }
      79             : 
      80           0 :   ulong notar_fallback_cnt; LOAD_LEN( notar_fallback_cnt, 16UL );
      81           0 :   for( ulong i=0UL; i<notar_fallback_cnt; i++ ) {
      82           0 :     ulong slot;     LOAD_VOTE( slot );
      83           0 :     ulong hash_cnt; LOAD_LEN( hash_cnt, 32UL );
      84           0 :     SKIP( hash_cnt*32UL );
      85           0 :   }
      86             : 
      87           0 :   LOAD_VOTES(); /* voted_skip_fallback */
      88           0 :   LOAD_VOTES(); /* skipped */
      89           0 :   LOAD_VOTES(); /* its_over */
      90             : 
      91           0 :   ulong votes_slot_cnt; LOAD_LEN( votes_slot_cnt, 16UL );
      92           0 :   for( ulong i=0UL; i<votes_slot_cnt; i++ ) {
      93           0 :     ulong slot;     LOAD_VOTE( slot );
      94           0 :     ulong vote_cnt; LOAD_LEN( vote_cnt, 11UL );
      95           0 :     for( ulong j=0UL; j<vote_cnt; j++ ) {
      96           0 :       uchar tag; LOAD( uchar, tag );
      97           0 :       ulong hash_sz;
      98           0 :       switch( tag ) {
      99           0 :       case FD_VOTE_HISTORY_SERDE_TAG_NOTAR:
     100           0 :       case FD_VOTE_HISTORY_SERDE_TAG_NOTAR_FALLBACK:
     101           0 :       case FD_VOTE_HISTORY_SERDE_TAG_GENESIS:       hash_sz = 32UL; break;
     102           0 :       case FD_VOTE_HISTORY_SERDE_TAG_FINAL:
     103           0 :       case FD_VOTE_HISTORY_SERDE_TAG_SKIP:
     104           0 :       case FD_VOTE_HISTORY_SERDE_TAG_SKIP_FALLBACK: hash_sz = 0UL;  break;
     105           0 :       default:                                 return FD_VOTE_HISTORY_DE_ERR_HISTORY;
     106           0 :       }
     107           0 :       ulong vote_slot; LOAD_VOTE( vote_slot );
     108           0 :       SKIP( hash_sz+2UL ); /* block hash, shred_version */
     109           0 :     }
     110           0 :   }
     111             : 
     112           0 :   ulong notarized_cnt; LOAD_LEN( notarized_cnt, 40UL );
     113           0 :   for( ulong i=0UL; i<notarized_cnt; i++ ) {
     114           0 :     SKIP( 40UL ); /* slot, block hash */
     115           0 :   }
     116             : 
     117           0 :   ulong parent_ready_slot_cnt; LOAD_LEN( parent_ready_slot_cnt, 16UL );
     118           0 :   for( ulong i=0UL; i<parent_ready_slot_cnt; i++ ) {
     119           0 :     SKIP( 8UL ); /* slot */
     120           0 :     ulong block_cnt; LOAD_LEN( block_cnt, 40UL );
     121           0 :     SKIP( block_cnt*40UL );
     122           0 :   }
     123             : 
     124           0 :   ulong root; LOAD( ulong, root );
     125             : 
     126           0 :   *wait_to_vote_slot = fd_ulong_sat_add( fd_first_slot_in_window( fd_ulong_max( max_vote, root ) ), FD_VOTOR_SLOTS_PER_WINDOW );
     127           0 :   return FD_VOTE_HISTORY_DE_SUCCESS;
     128           0 : }
     129             : 
     130             : #undef LOAD
     131             : #undef LOAD_LEN
     132             : #undef SKIP
     133             : #undef LOAD_VOTE
     134             : #undef LOAD_VOTES

Generated by: LCOV version 1.14