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