LCOV - code coverage report
Current view: top level - flamenco/genesis - fd_genesis_parse.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 80 118 67.8 %
Date: 2026-06-29 05:51:35 Functions: 2 3 66.7 %

          Line data    Source code
       1             : #include "fd_genesis_parse.h"
       2             : #include "../runtime/fd_runtime_const.h"
       3             : #include "../../util/bits/fd_bits.h"
       4             : 
       5             : #include <stddef.h>
       6             : 
       7             : fd_genesis_t *
       8             : fd_genesis_parse( fd_genesis_t * genesis,
       9             :                   uchar const *  bin,
      10           3 :                   ulong          bin_sz ) {
      11             :   /* Zero out top part of descriptor which is sufficient to fully
      12             :      initialize fd_genesis_t (assuming no struct reordering). */
      13           3 :   memset( genesis, 0, offsetof(fd_genesis_t, builtin) );
      14             : 
      15           3 :   uchar const * _payload    = bin;
      16           3 :   ulong const   _payload_sz = bin_sz;
      17           3 :   ulong         _i          = 0UL;
      18             : 
      19         513 : # define CHECK( cond )   { if( FD_UNLIKELY( !(cond) ) ) { return NULL; } }
      20         513 : # define CHECK_LEFT( n ) CHECK( (n)<=(_payload_sz-_i) )
      21         513 : # define INC( n )        (_i += (ulong)(n))
      22           3 : # define CUR_OFFSET      ((ushort)_i)
      23           3 : # define CURSOR          (_payload+_i)
      24             : 
      25           3 :   CHECK_LEFT( 8UL ); genesis->creation_time = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      26             : 
      27           3 :   CHECK_LEFT( 8UL ); genesis->account_cnt = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      28           3 :   if( FD_UNLIKELY( genesis->account_cnt>FD_GENESIS_ACCOUNT_MAX_COUNT ) ) {
      29           0 :     FD_LOG_WARNING(( "genesis account count %lu exceeds max %lu (increase FD_GENESIS_ACCOUNT_MAX_COUNT?)", genesis->account_cnt, FD_GENESIS_ACCOUNT_MAX_COUNT ));
      30           0 :     return NULL;
      31           0 :   }
      32          63 :   for( ulong i=0UL; i<genesis->account_cnt; i++ ) {
      33          60 :     fd_genesis_account_off_t * account = &genesis->account[ i ];
      34             : 
      35          60 :     account->pubkey_off = _i;
      36          60 :     CHECK_LEFT( 32UL );                                            INC( 32UL ); /* pubkey */
      37          60 :     CHECK_LEFT(  8UL );                                            INC(  8UL ); /* lamports */
      38          60 :     CHECK_LEFT(  8UL ); ulong data_len = FD_LOAD( ulong, CURSOR ); INC(  8UL );
      39          60 :     if( FD_UNLIKELY( data_len>FD_RUNTIME_ACC_SZ_MAX ) ) {
      40           0 :       FD_LOG_WARNING(( "genesis builtin account data length %lu exceeds max size %lu", data_len, FD_RUNTIME_ACC_SZ_MAX ));
      41           0 :       return NULL;
      42           0 :     }
      43          60 :     CHECK_LEFT( data_len ); INC( data_len ); /* data */
      44             : 
      45          60 :     account->owner_off = _i;
      46          60 :     CHECK_LEFT( 32UL ); INC( 32UL ); /* owner */
      47          60 :     CHECK_LEFT(  1UL ); INC(  1UL ); /* executable */
      48          60 :     CHECK_LEFT(  8UL ); INC(  8UL ); /* rent epoch */
      49          60 :   }
      50             : 
      51           3 :   CHECK_LEFT( 8UL ); genesis->builtin_cnt = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      52           3 :   if( FD_UNLIKELY( genesis->builtin_cnt>FD_GENESIS_BUILTIN_MAX_COUNT ) ) {
      53           0 :     FD_LOG_WARNING(( "genesis builtin count %lu exceeds max %lu", genesis->builtin_cnt, FD_GENESIS_BUILTIN_MAX_COUNT ));
      54           0 :     return NULL;
      55           0 :   }
      56           3 :   for( ulong i=0UL; i<genesis->builtin_cnt; i++ ) {
      57           0 :     fd_genesis_builtin_off_t * account = &genesis->builtin[ i ];
      58             : 
      59           0 :     account->data_len_off = _i;
      60           0 :     CHECK_LEFT( 8UL ); ulong data_len = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      61           0 :     if( FD_UNLIKELY( data_len>FD_RUNTIME_ACC_SZ_MAX ) ) {
      62           0 :       FD_LOG_WARNING(( "genesis builtin account data length %lu exceeds supported max size %lu", data_len, FD_RUNTIME_ACC_SZ_MAX ));
      63           0 :       return NULL;
      64           0 :     }
      65           0 :     CHECK_LEFT( data_len ); INC( data_len ); /* data */
      66             : 
      67           0 :     account->pubkey_off = _i;
      68           0 :     CHECK_LEFT( 32UL ); INC( 32UL ); /* pubkey */
      69           0 :   }
      70             : 
      71           3 :   CHECK_LEFT( 8UL ); ulong rewards_len = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      72           3 :   for( ulong i=0UL; i<rewards_len; i++ ) {
      73           0 :     CHECK_LEFT( 32UL );                                        INC( 32UL ); /* pubkey */
      74           0 :     CHECK_LEFT(  8UL );                                        INC(  8UL ); /* lamports */
      75           0 :     CHECK_LEFT(  8UL ); ulong dlen = FD_LOAD( ulong, CURSOR ); INC(  8UL ); /* dlen */
      76           0 :     CHECK_LEFT( dlen );                                        INC( dlen ); /* data */
      77           0 :     CHECK_LEFT( 32UL );                                        INC( 32UL ); /* owner */
      78           0 :     CHECK_LEFT(  1UL );                                        INC(  1UL ); /* executable */
      79           0 :     CHECK_LEFT(  8UL );                                        INC(  8UL ); /* rent epoch */
      80           0 :   }
      81             : 
      82           3 :   CHECK_LEFT( 8UL ); genesis->poh.ticks_per_slot = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      83             : 
      84           3 :   CHECK_LEFT( sizeof(ulong) ); INC( sizeof(ulong) ); /* unused */
      85             : 
      86           3 :   CHECK_LEFT( 8UL ); genesis->poh.tick_duration_secs = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      87           3 :   CHECK_LEFT( 4UL ); genesis->poh.tick_duration_ns   = FD_LOAD( uint,  CURSOR ); INC( 4UL );
      88           3 :   CHECK_LEFT( 1UL ); int has_target_tick_count       = FD_LOAD( uchar, CURSOR ); INC( 1UL );
      89           3 :   if( has_target_tick_count ) { CHECK_LEFT( 8UL ); genesis->poh.target_tick_count = FD_LOAD( ulong, CURSOR ); INC( 8UL ); }
      90           3 :   else                                            genesis->poh.target_tick_count = 0UL;
      91           3 :   CHECK_LEFT( 1UL ); int has_hashes_per_tick       = FD_LOAD( uchar, CURSOR ); INC( 1UL );
      92           3 :   if( has_hashes_per_tick ) { CHECK_LEFT( 8UL ); genesis->poh.hashes_per_tick = FD_LOAD( ulong, CURSOR ); INC( 8UL ); }
      93           3 :   else                                          genesis->poh.hashes_per_tick = 0UL;
      94             : 
      95           3 :   CHECK_LEFT( sizeof(ulong) ); INC( sizeof(ulong) ); /* backward compat v23 */
      96             : 
      97           3 :   CHECK_LEFT( 8UL ); genesis->fee_rate_governor.target_lamports_per_signature = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      98           3 :   CHECK_LEFT( 8UL ); genesis->fee_rate_governor.target_signatures_per_slot    = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      99           3 :   CHECK_LEFT( 8UL ); genesis->fee_rate_governor.min_lamports_per_signature    = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     100           3 :   CHECK_LEFT( 8UL ); genesis->fee_rate_governor.max_lamports_per_signature    = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     101           3 :   CHECK_LEFT( 1UL ); genesis->fee_rate_governor.burn_percent                  = FD_LOAD( uchar, CURSOR ); INC( 1UL );
     102             : 
     103           3 :   CHECK_LEFT( 8UL ); genesis->rent.lamports_per_uint8_year = FD_LOAD( ulong, CURSOR );  INC( 8UL );
     104           3 :   CHECK_LEFT( 8UL ); genesis->rent.exemption_threshold     = FD_LOAD( double, CURSOR ); INC( 8UL );
     105           3 :   CHECK_LEFT( 1UL ); genesis->rent.burn_percent            = FD_LOAD( uchar, CURSOR );  INC( 1UL );
     106             : 
     107           3 :   CHECK_LEFT( 8UL ); genesis->inflation.initial         = FD_LOAD( double, CURSOR ); INC( 8UL );
     108           3 :   CHECK_LEFT( 8UL ); genesis->inflation.terminal        = FD_LOAD( double, CURSOR ); INC( 8UL );
     109           3 :   CHECK_LEFT( 8UL ); genesis->inflation.taper           = FD_LOAD( double, CURSOR ); INC( 8UL );
     110           3 :   CHECK_LEFT( 8UL ); genesis->inflation.foundation      = FD_LOAD( double, CURSOR ); INC( 8UL );
     111           3 :   CHECK_LEFT( 8UL ); genesis->inflation.foundation_term = FD_LOAD( double, CURSOR ); INC( 8UL );
     112           3 :   CHECK_LEFT( 8UL );                                                                 INC( 8UL ); /* unused */
     113             : 
     114           3 :   CHECK_LEFT( 8UL ); genesis->epoch_schedule.slots_per_epoch             = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     115           3 :   CHECK_LEFT( 8UL ); genesis->epoch_schedule.leader_schedule_slot_offset = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     116           3 :   CHECK_LEFT( 1UL ); genesis->epoch_schedule.warmup                      = FD_LOAD( uchar, CURSOR ); INC( 1UL );
     117           3 :   CHECK_LEFT( 8UL ); genesis->epoch_schedule.first_normal_epoch          = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     118           3 :   CHECK_LEFT( 8UL ); genesis->epoch_schedule.first_normal_slot           = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     119             : 
     120           3 :   CHECK_LEFT( 4UL ); genesis->cluster_type = FD_LOAD( uint, CURSOR ); INC( 4UL );
     121             : 
     122           3 : # undef CHECK
     123           3 : # undef CHECK_LEFT
     124           3 : # undef INC
     125           3 : # undef CUR_OFFSET
     126           3 : # undef CURSOR
     127             : 
     128           3 :   if( _i!=_payload_sz ) {
     129           0 :     FD_LOG_WARNING(( "genesis blob has %lu trailing unrecognized bytes. Perhaps this Firedancer build is too old?", _payload_sz-_i ));
     130           0 :     return NULL;
     131           0 :   }
     132             : 
     133           3 :   return genesis;
     134           3 : }
     135             : 
     136             : fd_genesis_account_t *
     137             : fd_genesis_account( fd_genesis_t const *   genesis,
     138             :                     uchar const *          bin,
     139             :                     fd_genesis_account_t * out,
     140          21 :                     ulong                  idx ) {
     141          21 :   fd_genesis_account_off_t const * off = &genesis->account[ idx ];
     142          21 :   out->pubkey   = FD_LOAD( fd_pubkey_t, bin+off->pubkey_off      );
     143          21 :   out->lamports = FD_LOAD( ulong,       bin+off->pubkey_off+32UL );
     144          21 :   out->data_len = (uint)FD_LOAD( ulong, bin+off->pubkey_off+40UL );
     145          21 :   out->data     = bin+off->pubkey_off+48UL;
     146          21 :   memcpy( out->owner.uc, bin+off->owner_off, sizeof(fd_pubkey_t) );
     147          21 :   out->executable = !!bin[ off->owner_off+32UL ];
     148          21 :   return out;
     149          21 : }
     150             : 
     151             : fd_genesis_builtin_t *
     152             : fd_genesis_builtin( fd_genesis_t const *   genesis,
     153             :                     uchar const *          bin,
     154             :                     fd_genesis_builtin_t * out,
     155           0 :                     ulong                  idx ) {
     156           0 :   fd_genesis_builtin_off_t const * off = &genesis->builtin[ idx ];
     157           0 :   out->pubkey   = FD_LOAD( fd_pubkey_t, bin+off->pubkey_off   );
     158           0 :   out->data_len = FD_LOAD( ulong,       bin+off->data_len_off );
     159           0 :   out->data     = bin+off->data_len_off+8UL;
     160           0 :   return out;
     161           0 : }

Generated by: LCOV version 1.14