LCOV - code coverage report
Current view: top level - flamenco/genesis - fd_genesis_parse.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 84 125 67.2 %
Date: 2026-09-17 04:28:31 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           6 :                   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           6 :   memset( genesis, 0, offsetof(fd_genesis_t, builtin) );
      14             : 
      15           6 :   uchar const * _payload    = bin;
      16           6 :   ulong const   _payload_sz = bin_sz;
      17           6 :   ulong         _i          = 0UL;
      18             : 
      19        2004 : # define CHECK( cond )   { if( FD_UNLIKELY( !(cond) ) ) { return NULL; } }
      20        1761 : # define CHECK_LEFT( n ) CHECK( (n)<=(_payload_sz-_i) )
      21        1761 : # define INC( n )        (_i += (ulong)(n))
      22           6 : # define CUR_OFFSET      ((ushort)_i)
      23           6 : # define CURSOR          (_payload+_i)
      24             : 
      25           6 :   CHECK_LEFT( 8UL ); genesis->creation_time = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      26             : 
      27           6 :   CHECK_LEFT( 8UL ); genesis->account_cnt = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      28           6 :   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         231 :   for( ulong i=0UL; i<genesis->account_cnt; i++ ) {
      33         225 :     fd_genesis_account_off_t * account = &genesis->account[ i ];
      34             : 
      35         225 :     account->pubkey_off = _i;
      36         225 :     CHECK_LEFT( 32UL );                                            INC( 32UL ); /* pubkey */
      37         225 :     CHECK_LEFT(  8UL );                                            INC(  8UL ); /* lamports */
      38         225 :     CHECK_LEFT(  8UL ); ulong data_len = FD_LOAD( ulong, CURSOR ); INC(  8UL );
      39         225 :     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         225 :     CHECK_LEFT( data_len ); INC( data_len ); /* data */
      44             : 
      45         225 :     account->owner_off = _i;
      46         225 :     CHECK_LEFT( 32UL ); INC( 32UL ); /* owner */
      47         225 :     CHECK_LEFT(  1UL ); CHECK( FD_LOAD( uchar, CURSOR )<=1U ); INC(  1UL ); /* executable */
      48         225 :     CHECK_LEFT(  8UL ); INC(  8UL ); /* rent epoch */
      49         225 :   }
      50             : 
      51           6 :   CHECK_LEFT( 8UL ); genesis->builtin_cnt = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      52           6 :   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           6 :   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           6 :   CHECK_LEFT( 8UL ); ulong rewards_len = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      72           6 :   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 ); CHECK( FD_LOAD( uchar, CURSOR )<=1U ); INC(  1UL ); /* executable */
      79           0 :     CHECK_LEFT(  8UL );                                        INC(  8UL ); /* rent epoch */
      80           0 :   }
      81             : 
      82           6 :   CHECK_LEFT( 8UL ); genesis->poh.ticks_per_slot = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      83           6 :   if( FD_UNLIKELY( !genesis->poh.ticks_per_slot ) ) {
      84           0 :     FD_LOG_WARNING(( "genesis ticks_per_slot must be non-zero" ));
      85           0 :     return NULL;
      86           0 :   }
      87             : 
      88           6 :   CHECK_LEFT( sizeof(ulong) ); INC( sizeof(ulong) ); /* unused */
      89             : 
      90           6 :   CHECK_LEFT( 8UL ); genesis->poh.tick_duration_secs = FD_LOAD( ulong, CURSOR ); INC( 8UL );
      91           6 :   CHECK_LEFT( 4UL ); genesis->poh.tick_duration_ns   = FD_LOAD( uint,  CURSOR ); INC( 4UL );
      92           6 :   CHECK_LEFT( 1UL ); int has_target_tick_count       = FD_LOAD( uchar, CURSOR ); INC( 1UL );
      93           6 :   CHECK( has_target_tick_count<=1 );
      94           6 :   if( has_target_tick_count ) { CHECK_LEFT( 8UL ); genesis->poh.target_tick_count = FD_LOAD( ulong, CURSOR ); INC( 8UL ); }
      95           6 :   else                                            genesis->poh.target_tick_count = 0UL;
      96           6 :   CHECK_LEFT( 1UL ); int has_hashes_per_tick       = FD_LOAD( uchar, CURSOR ); INC( 1UL );
      97           6 :   CHECK( has_hashes_per_tick<=1 );
      98           6 :   if( has_hashes_per_tick ) { CHECK_LEFT( 8UL ); genesis->poh.hashes_per_tick = FD_LOAD( ulong, CURSOR ); INC( 8UL ); }
      99           6 :   else                                          genesis->poh.hashes_per_tick = 0UL;
     100             : 
     101           6 :   CHECK_LEFT( sizeof(ulong) ); INC( sizeof(ulong) ); /* backward compat v23 */
     102             : 
     103           6 :   CHECK_LEFT( 8UL ); genesis->fee_rate_governor.target_lamports_per_signature = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     104           6 :   CHECK_LEFT( 8UL ); genesis->fee_rate_governor.target_signatures_per_slot    = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     105           6 :   CHECK_LEFT( 8UL ); genesis->fee_rate_governor.min_lamports_per_signature    = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     106           6 :   CHECK_LEFT( 8UL ); genesis->fee_rate_governor.max_lamports_per_signature    = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     107           6 :   CHECK_LEFT( 1UL ); genesis->fee_rate_governor.burn_percent                  = FD_LOAD( uchar, CURSOR ); INC( 1UL );
     108             : 
     109           6 :   CHECK_LEFT( 8UL ); genesis->rent.lamports_per_uint8_year = FD_LOAD( ulong, CURSOR );  INC( 8UL );
     110           6 :   CHECK_LEFT( 8UL ); genesis->rent.exemption_threshold     = FD_LOAD( double, CURSOR ); INC( 8UL );
     111           6 :   CHECK_LEFT( 1UL ); genesis->rent.burn_percent            = FD_LOAD( uchar, CURSOR );  INC( 1UL );
     112             : 
     113           6 :   CHECK_LEFT( 8UL ); genesis->inflation.initial         = FD_LOAD( double, CURSOR ); INC( 8UL );
     114           6 :   CHECK_LEFT( 8UL ); genesis->inflation.terminal        = FD_LOAD( double, CURSOR ); INC( 8UL );
     115           6 :   CHECK_LEFT( 8UL ); genesis->inflation.taper           = FD_LOAD( double, CURSOR ); INC( 8UL );
     116           6 :   CHECK_LEFT( 8UL ); genesis->inflation.foundation      = FD_LOAD( double, CURSOR ); INC( 8UL );
     117           6 :   CHECK_LEFT( 8UL ); genesis->inflation.foundation_term = FD_LOAD( double, CURSOR ); INC( 8UL );
     118           6 :   CHECK_LEFT( 8UL );                                                                 INC( 8UL ); /* unused */
     119             : 
     120           6 :   CHECK_LEFT( 8UL ); genesis->epoch_schedule.slots_per_epoch             = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     121           6 :   CHECK_LEFT( 8UL ); genesis->epoch_schedule.leader_schedule_slot_offset = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     122           6 :   CHECK_LEFT( 1UL ); genesis->epoch_schedule.warmup                      = FD_LOAD( uchar, CURSOR ); INC( 1UL );
     123           6 :   CHECK( genesis->epoch_schedule.warmup<=1U );
     124           6 :   CHECK_LEFT( 8UL ); genesis->epoch_schedule.first_normal_epoch          = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     125           6 :   CHECK_LEFT( 8UL ); genesis->epoch_schedule.first_normal_slot           = FD_LOAD( ulong, CURSOR ); INC( 8UL );
     126             : 
     127           6 :   CHECK_LEFT( 4UL ); genesis->cluster_type = FD_LOAD( uint, CURSOR ); INC( 4UL );
     128             : 
     129           6 : # undef CHECK
     130           6 : # undef CHECK_LEFT
     131           6 : # undef INC
     132           6 : # undef CUR_OFFSET
     133           6 : # undef CURSOR
     134             : 
     135           6 :   if( _i!=_payload_sz ) {
     136           0 :     FD_LOG_WARNING(( "genesis blob has %lu trailing unrecognized bytes. Perhaps this Firedancer build is too old?", _payload_sz-_i ));
     137           0 :     return NULL;
     138           0 :   }
     139             : 
     140           6 :   return genesis;
     141           6 : }
     142             : 
     143             : fd_genesis_account_t *
     144             : fd_genesis_account( fd_genesis_t const *   genesis,
     145             :                     uchar const *          bin,
     146             :                     fd_genesis_account_t * out,
     147        3024 :                     ulong                  idx ) {
     148        3024 :   fd_genesis_account_off_t const * off = &genesis->account[ idx ];
     149        3024 :   out->pubkey   = FD_LOAD( fd_pubkey_t, bin+off->pubkey_off      );
     150        3024 :   out->lamports = FD_LOAD( ulong,       bin+off->pubkey_off+32UL );
     151        3024 :   out->data_len = (uint)FD_LOAD( ulong, bin+off->pubkey_off+40UL );
     152        3024 :   out->data     = bin+off->pubkey_off+48UL;
     153        3024 :   memcpy( out->owner.uc, bin+off->owner_off, sizeof(fd_pubkey_t) );
     154        3024 :   out->executable = !!bin[ off->owner_off+32UL ];
     155        3024 :   return out;
     156        3024 : }
     157             : 
     158             : fd_genesis_builtin_t *
     159             : fd_genesis_builtin( fd_genesis_t const *   genesis,
     160             :                     uchar const *          bin,
     161             :                     fd_genesis_builtin_t * out,
     162           0 :                     ulong                  idx ) {
     163           0 :   fd_genesis_builtin_off_t const * off = &genesis->builtin[ idx ];
     164           0 :   out->pubkey   = FD_LOAD( fd_pubkey_t, bin+off->pubkey_off   );
     165           0 :   out->data_len = FD_LOAD( ulong,       bin+off->data_len_off );
     166           0 :   out->data     = bin+off->data_len_off+8UL;
     167           0 :   return out;
     168           0 : }

Generated by: LCOV version 1.14