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 : }