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