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

          Line data    Source code
       1             : #include "ag_cert_serde.h"
       2             : 
       3           0 : #define FAIL( cond, err ) do { if( FD_UNLIKELY( cond ) ) return AG_CERT_DE_ERR_##err; } while( 0 )
       4             : 
       5             : ulong
       6             : ag_cert_ser( ag_cert_t const * self,
       7           0 :              uchar             buf[ static AG_CERT_SER_MAX ] ) {
       8           0 :   fd_bls_agg_t const * agg;
       9           0 :   fd_bls_agg_t const * agg2 = NULL;
      10           0 :   uchar const *        hash = NULL;
      11           0 :   ulong                slot;
      12           0 :   switch( self->kind ) {
      13           0 :   case AG_CERT_KIND_FINAL:
      14           0 :     slot = self->final.slot;
      15           0 :     agg  = &self->final.agg;
      16           0 :     break;
      17           0 :   case AG_CERT_KIND_FAST_FINAL:
      18           0 :     slot = self->fast_final.slot;
      19           0 :     agg  = &self->fast_final.agg;
      20           0 :     hash = self->fast_final.block_hash;
      21           0 :     break;
      22           0 :   case AG_CERT_KIND_NOTAR:
      23           0 :     slot = self->notar.slot;
      24           0 :     agg  = &self->notar.agg;
      25           0 :     hash = self->notar.block_hash;
      26           0 :     break;
      27           0 :   case AG_CERT_KIND_NOTAR_FALLBACK:
      28           0 :     slot = self->notar_fallback.slot;
      29           0 :     agg  = &self->notar_fallback.agg_notar;
      30           0 :     agg2 = &self->notar_fallback.agg_notar_fallback;
      31           0 :     hash = self->notar_fallback.block_hash;
      32           0 :     break;
      33           0 :   case AG_CERT_KIND_SKIP:
      34           0 :     slot = self->skip.slot;
      35           0 :     agg  = &self->skip.agg_skip;
      36           0 :     agg2 = &self->skip.agg_skip_fallback;
      37           0 :     break;
      38           0 :   default:
      39           0 :     FD_LOG_ERR(( "unimplemented" ));
      40           0 :   }
      41             : 
      42           0 :   if( FD_UNLIKELY( agg2 && !fd_bls_set_cnt( agg2->set ) ) ) agg2 = NULL; /* check empty */
      43             : 
      44           0 :   blst_p2 sig = agg->sig;
      45           0 :   if( FD_UNLIKELY( agg2 ) ) blst_p2_add_or_double( &sig, &sig, &agg2->sig );
      46             : 
      47           0 :   ag_cert_serde_t cert = {
      48           0 :     .version       = (uchar)1,
      49           0 :     .tag           = (uchar)( self->kind+AG_CERT_SERDE_TAG_FINAL ),
      50           0 :     .slot          = slot,
      51           0 :     .block_id      = hash,
      52           0 :     .bitmap_sz     = agg2 ? ag_bls_agg_pair_ser_sz( agg, agg2 ) : ag_bls_agg_ser_sz( agg ),
      53           0 :     .shred_version = ag_cert_shred_version( self ),
      54           0 :   };
      55             : 
      56           0 :   ulong off = 0UL;
      57           0 :   buf[ off ] = cert.version;                                                                    off += sizeof(uchar);
      58           0 :   buf[ off ] = cert.tag;                                                                        off += sizeof(uchar);
      59           0 :   FD_STORE( ulong, buf+off, cert.slot );                                                        off += sizeof(ulong);
      60           0 :   if( FD_LIKELY( cert.block_id ) ) { memcpy( buf+off, cert.block_id, sizeof(ag_block_hash_t) ); off += sizeof(ag_block_hash_t); }
      61           0 :   fd_bls_sig_t sig_aff[1];
      62           0 :   blst_p2_to_affine( sig_aff, &sig );
      63           0 :   blst_p2_affine_serialize( buf+off, sig_aff );                                                 off += FD_BLS_SIG_SZ;
      64           0 :   FD_STORE( ulong, buf+off, cert.bitmap_sz );                                                   off += sizeof(ulong);
      65           0 :                                                                                                 off += agg2 ? ag_bls_agg_pair_ser( agg, agg2, buf+off ) : ag_bls_agg_ser( agg, buf+off );
      66           0 :   FD_STORE( ushort, buf+off, cert.shred_version );                                              off += sizeof(ushort);
      67             : 
      68           0 :   return off;
      69           0 : }
      70             : 
      71             : int
      72             : ag_cert_de( ag_cert_t *   self,
      73             :             ulong *       bit_cnt,
      74             :             uchar const * buf,
      75           0 :             ulong         buf_sz ) {
      76           0 :   FAIL( buf_sz<2 /* version + tag */, SZ );
      77             : 
      78           0 :   ag_cert_serde_t cert; ulong off = 0UL;
      79           0 :   cert.version       = buf[ off ];                off += sizeof(uchar);
      80           0 :   cert.tag           = buf[ off ];                off += sizeof(uchar);
      81           0 :   FAIL( cert.version!=1, INVAL );
      82             : 
      83           0 :   fd_memset( self, 0, sizeof(ag_cert_t) );
      84           0 :   self->kind = (uint)cert.tag - AG_CERT_SERDE_TAG_FINAL;
      85             : 
      86           0 :   int   has_block_id = self->kind==AG_CERT_KIND_FAST_FINAL || self->kind==AG_CERT_KIND_NOTAR || self->kind==AG_CERT_KIND_NOTAR_FALLBACK;
      87           0 :   ulong hdr_sz       = AG_CERT_SER_HDR_SZ( has_block_id );
      88           0 :   FAIL( buf_sz<hdr_sz, SZ );
      89             : 
      90           0 :   cert.slot          = FD_LOAD( ulong, buf+off ); off += sizeof(ulong);
      91           0 :   cert.block_id      = NULL;
      92           0 :   if( FD_LIKELY( has_block_id ) ) {
      93           0 :     cert.block_id    = buf+off;                   off += sizeof(ag_block_hash_t);
      94           0 :   }
      95           0 :   cert.signature     = buf+off;                   off += FD_BLS_SIG_SZ;
      96             : 
      97           0 :   blst_p2      sig[1];
      98           0 :   fd_bls_sig_t sig_aff[1];
      99           0 :   FAIL( blst_p2_deserialize( sig_aff, cert.signature )!=BLST_SUCCESS, INVAL );
     100           0 :   blst_p2_from_affine( sig, sig_aff );
     101           0 :   cert.bitmap_sz     = FD_LOAD( ulong, buf+off ); off += sizeof(ulong);
     102           0 :   cert.bitmap        = buf+off;
     103           0 :   FD_TEST( off==hdr_sz );
     104             : 
     105           0 :   ulong rem = buf_sz - hdr_sz;
     106           0 :   FAIL( cert.bitmap_sz>rem || rem-cert.bitmap_sz<sizeof(ushort), SZ ); /* too few, trailing bytes are ignored */
     107             : 
     108           0 :   cert.shred_version = FD_LOAD( ushort, cert.bitmap+cert.bitmap_sz );
     109             : 
     110           0 :   int err;
     111           0 :   switch( self->kind ) {
     112           0 :   case AG_CERT_KIND_FINAL:
     113           0 :     self->final.slot = cert.slot;
     114           0 :     self->final.shred_version = cert.shred_version;
     115           0 :     if( FD_UNLIKELY( err = ag_bls_agg_de( &self->final.agg, bit_cnt, cert.bitmap, cert.bitmap_sz ) ) ) return err;
     116           0 :     self->final.agg.sig = *sig;
     117           0 :     break;
     118           0 :   case AG_CERT_KIND_FAST_FINAL:
     119           0 :     self->fast_final.slot = cert.slot;
     120           0 :     self->fast_final.shred_version = cert.shred_version;
     121           0 :     memcpy( self->fast_final.block_hash, cert.block_id, sizeof(ag_block_hash_t) );
     122           0 :     if( FD_UNLIKELY( err = ag_bls_agg_de( &self->fast_final.agg, bit_cnt, cert.bitmap, cert.bitmap_sz ) ) ) return err;
     123           0 :     self->fast_final.agg.sig = *sig;
     124           0 :     break;
     125           0 :   case AG_CERT_KIND_NOTAR:
     126           0 :     self->notar.slot = cert.slot;
     127           0 :     self->notar.shred_version = cert.shred_version;
     128           0 :     memcpy( self->notar.block_hash, cert.block_id, sizeof(ag_block_hash_t) );
     129           0 :     if( FD_UNLIKELY( err = ag_bls_agg_de( &self->notar.agg, bit_cnt, cert.bitmap, cert.bitmap_sz ) ) ) return err;
     130           0 :     self->notar.agg.sig = *sig;
     131           0 :     break;
     132           0 :   case AG_CERT_KIND_NOTAR_FALLBACK: {
     133           0 :     fd_bls_agg_t * agg  = &self->notar_fallback.agg_notar;
     134           0 :     fd_bls_agg_t * agg2 = &self->notar_fallback.agg_notar_fallback;
     135           0 :     self->notar_fallback.slot = cert.slot;
     136           0 :     self->notar_fallback.shred_version = cert.shred_version;
     137           0 :     memcpy( self->notar_fallback.block_hash, cert.block_id, sizeof(ag_block_hash_t) );
     138           0 :     if( FD_UNLIKELY( err = ag_bls_agg_pair_de( agg, agg2, bit_cnt, cert.bitmap, cert.bitmap_sz ) ) ) return err;
     139           0 :     agg->sig = *sig;
     140           0 :     break;
     141           0 :   }
     142           0 :   case AG_CERT_KIND_SKIP: {
     143           0 :     fd_bls_agg_t * agg  = &self->skip.agg_skip;
     144           0 :     fd_bls_agg_t * agg2 = &self->skip.agg_skip_fallback;
     145           0 :     self->skip.slot = cert.slot;
     146           0 :     self->skip.shred_version = cert.shred_version;
     147           0 :     if( FD_UNLIKELY( err = ag_bls_agg_pair_de( agg, agg2, bit_cnt, cert.bitmap, cert.bitmap_sz ) ) ) return err;
     148           0 :     agg->sig = *sig;
     149           0 :     break;
     150           0 :   }
     151           0 :   default:
     152           0 :     return AG_CERT_DE_ERR_INVAL;
     153           0 :   }
     154             : 
     155           0 :   return AG_CERT_DE_SUCCESS;
     156           0 : }

Generated by: LCOV version 1.14