Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_fd_flamenco_base_h 2 : #define HEADER_fd_src_flamenco_fd_flamenco_base_h 3 : 4 : #include "../ballet/base58/fd_base58.h" 5 : 6 : /* fd_w_u128 is a wrapped "uint128" type providing basic 128-bit 7 : unsigned int functionality even if the compile target does not 8 : natively support uint128. */ 9 : 10 : union __attribute__((packed)) fd_w_u128 { 11 : uchar uc[16]; 12 : ulong ul[2]; 13 : # ifdef __SIZEOF_INT128__ 14 : uint128 ud; 15 : # endif 16 : }; 17 : 18 : typedef union fd_w_u128 fd_w_u128_t; 19 : 20 : /* 32-byte container */ 21 : 22 18064 : #define FD_HASH_FOOTPRINT (32UL) 23 1366 : #define FD_PUBKEY_FOOTPRINT FD_HASH_FOOTPRINT 24 : union __attribute__((packed)) fd_hash { 25 : uchar hash[ FD_HASH_FOOTPRINT ]; 26 : uchar key [ FD_HASH_FOOTPRINT ]; // Making fd_hash and fd_pubkey interchangeable 27 : 28 : // Generic type specific accessors 29 : ulong ul [ FD_HASH_FOOTPRINT / sizeof(ulong) ]; 30 : uint ui [ FD_HASH_FOOTPRINT / sizeof(uint) ]; 31 : ushort us [ FD_HASH_FOOTPRINT / sizeof(ushort) ]; 32 : uchar uc [ FD_HASH_FOOTPRINT ]; 33 : }; 34 : typedef union fd_hash fd_hash_t; 35 : typedef union fd_hash fd_pubkey_t; 36 : 37 : FD_FN_PURE static inline int 38 : fd_hash_eq( fd_hash_t const * a, 39 399633 : fd_hash_t const * b ) { 40 399633 : return 0==memcmp( a, b, sizeof(fd_hash_t) ); 41 399633 : } 42 : 43 : FD_FN_PURE static inline int 44 : fd_hash_eq1( fd_hash_t a, 45 0 : fd_hash_t b ) { 46 0 : return 47 0 : ( a.ul[0]==b.ul[0] ) & ( a.ul[1]==b.ul[1] ) & 48 0 : ( a.ul[2]==b.ul[2] ) & ( a.ul[3]==b.ul[3] ); 49 0 : } 50 : 51 : FD_FN_PURE static inline int 52 0 : fd_hash_check_zero( fd_hash_t const * _x ) { 53 0 : return !( (_x)->ul[0] | (_x)->ul[1] | (_x)->ul[2] | (_x)->ul[3] ); 54 0 : } 55 : 56 0 : #define fd_pubkey_check_zero fd_hash_check_zero 57 16575 : #define fd_pubkey_eq fd_hash_eq 58 : 59 : /* 64-byte container */ 60 : 61 : union fd_signature { 62 : uchar uc[ 64 ]; 63 : ulong ul[ 8 ]; 64 : }; 65 : typedef union fd_signature fd_signature_t; 66 : 67 : FD_FN_PURE static inline int 68 : fd_signature_eq( fd_signature_t const * a, 69 0 : fd_signature_t const * b ) { 70 0 : return 0==memcmp( a, b, sizeof(fd_signature_t) ); 71 0 : } 72 : 73 : /* Forward declarations */ 74 : 75 : struct fd_bank; 76 : typedef struct fd_bank fd_bank_t; 77 : 78 : struct fd_banks; 79 : typedef struct fd_banks fd_banks_t; 80 : 81 : struct fd_exec_instr_ctx; 82 : typedef struct fd_exec_instr_ctx fd_exec_instr_ctx_t; 83 : 84 : struct fd_acc_mgr; 85 : typedef struct fd_acc_mgr fd_acc_mgr_t; 86 : 87 : struct fd_capture_ctx; 88 : typedef struct fd_capture_ctx fd_capture_ctx_t; 89 : 90 : struct fd_txn_in; 91 : typedef struct fd_txn_in fd_txn_in_t; 92 : 93 : struct fd_dump_proto_ctx; 94 : typedef struct fd_dump_proto_ctx fd_dump_proto_ctx_t; 95 : 96 : struct fd_txn_dump_ctx; 97 : typedef struct fd_txn_dump_ctx fd_txn_dump_ctx_t; 98 : 99 : struct fd_borrowed_account; 100 : typedef struct fd_borrowed_account fd_borrowed_account_t; 101 : 102 : union fd_features; 103 : typedef union fd_features fd_features_t; 104 : 105 : struct fd_epoch_schedule; 106 : typedef struct fd_epoch_schedule fd_epoch_schedule_t; 107 : 108 : struct fd_slot_params; 109 : typedef struct fd_slot_params fd_slot_params_t; 110 : 111 : struct fd_progcache; 112 : typedef struct fd_progcache fd_progcache_t; 113 : 114 : struct fd_runtime_stack; 115 : typedef struct fd_runtime_stack fd_runtime_stack_t; 116 : 117 : struct fd_runtime; 118 : typedef struct fd_runtime fd_runtime_t; 119 : 120 : struct fd_txn_in; 121 : typedef struct fd_txn_in fd_txn_in_t; 122 : 123 : struct fd_txn_out; 124 : typedef struct fd_txn_out fd_txn_out_t; 125 : 126 : struct fd_log_collector; 127 : typedef struct fd_log_collector fd_log_collector_t; 128 : 129 : struct fd_genesis; 130 : typedef struct fd_genesis fd_genesis_t; 131 : 132 : struct fd_stake_rewards; 133 : typedef struct fd_stake_rewards fd_stake_rewards_t; 134 : 135 : /* Misc types */ 136 : 137 0 : #define FD_EPOCH_CREDITS_MAX (64UL) 138 : 139 : /* credits_delta/prev_credits_delta are stored as deltas from 140 : base_credits. These are u64 (no longer u32). */ 141 : 142 : struct fd_epoch_credits { 143 : uchar pubkey[32]; 144 : ulong base_credits; 145 : ushort epoch [ FD_EPOCH_CREDITS_MAX ]; 146 : ulong credits_delta [ FD_EPOCH_CREDITS_MAX ]; 147 : ulong prev_credits_delta[ FD_EPOCH_CREDITS_MAX ]; 148 : ushort commission; 149 : /* cnt does not include the Alpenglow marker entry */ 150 : uchar cnt; 151 : uchar fast_path_ok; /* True if the entries satisfy the boundary fast path prerequisites: 152 : (1) initial[n]<=final[n], (2) initial[n]==final[n-1], and (3) 153 : epoch[n]>=epoch[n-1]. Always true for production accounts written 154 : by vote programs. Points calculation takes the fast paths only 155 : when true and the slow reference implementation otherwise. So 156 : synthetic fuzzer inputs fall back gracefully. */ 157 : /* has_ag_migration_marker is 1 if the Alpenglow migration marker 158 : is present in the vote account's epoch credits, and 0 otherwise. 159 : This is only needed to correctly pay out rewards earnt during the 160 : Alpenglow migration epoch. 161 : 162 : The Alpenglow migration changes what epoch credit entries 163 : represent. Entries from before the migration are Tower credits, 164 : and entries from after are Alpenglow credits. 165 : 166 : During the migration epoch, vote accounts can earn both Tower 167 : credits before the migration slot and Alpenglow credits after. 168 : This means there can be two entries for the migration epoch, and 169 : if there is only one entry we don't know if it represents Tower 170 : credits or Alpenglow credits. The marker is used to disambiguate: 171 : entries from epochs before the marker are Tower credits, and 172 : entries at/after the marker are Alpenglow credits. 173 : 174 : It is also true that: 175 : - At most one entry per epoch is written in non-migration epochs. 176 : - At most one entry per epoch is written for Tower credits during 177 : the migration epoch. 178 : - At most one entry per epoch is written for Alpenglow credits 179 : during the migration epoch. 180 : - The marker is only written during the migration epoch, whilst 181 : crediting any Alpenglow credits earnt. If the vote account did 182 : not earn any Alpenglow credits during the migration epoch, 183 : there will never be a marker in its epoch credits. 184 : 185 : Therefore, we know that: 186 : - If the marker is not present and there is only 1 entry for the 187 : migration epoch, that entry must represent Tower credits 188 : - If the marker is present and there is only 1 entry for the 189 : migration epoch, that entry must represent Alpenglow credits 190 : - If the marker is present and there are 2 entries for the 191 : migration epoch, the first represents Tower credits and the 192 : second represents Alpenglow credits 193 : 194 : https://github.com/anza-xyz/agave/blob/v4.3.0/runtime/src/block_component_processor/vote_reward.rs#L532-L596 */ 195 : uchar has_ag_migration_marker; 196 : }; 197 : typedef struct fd_epoch_credits fd_epoch_credits_t; 198 : 199 : FD_STATIC_ASSERT( (ulong)UCHAR_MAX>=FD_EPOCH_CREDITS_MAX, cnt_width ); 200 : FD_STATIC_ASSERT( sizeof(fd_epoch_credits_t)==1200UL, fd_epoch_credits ); 201 : 202 : /* fd_epoch_credits_ag_marker_idx returns the index of the Alpenglow 203 : migration marker in the on-chain epoch credits state, given the 204 : epoch_credits and the migration epoch. This is so that our 205 : serialized epoch credits are Agave-compatible. */ 206 : 207 : static inline ulong 208 : fd_epoch_credits_ag_marker_idx( fd_epoch_credits_t const * epoch_credits, 209 0 : ulong ag_migration_epoch ) { 210 0 : if( FD_LIKELY( !epoch_credits->has_ag_migration_marker ) ) return ULONG_MAX; 211 : 212 : /* Find the last entry for the migration epoch - the marker goes 213 : immediately before this entry. */ 214 0 : for( ulong i=epoch_credits->cnt; i; i-- ) { 215 0 : if( FD_UNLIKELY ((ulong)epoch_credits->epoch[ i-1UL ]==ag_migration_epoch )) { 216 0 : return i-1UL; 217 0 : } 218 0 : } 219 : 220 : /* If there is no entry for the migration epoch, the marker is the 221 : last entry. */ 222 0 : return epoch_credits->cnt; 223 0 : } 224 : 225 : static inline uchar 226 1191 : fd_epoch_credits_fast_path_ok( fd_epoch_credits_t const * epoch_credits ) { 227 20836 : for( ulong i=0UL; i<epoch_credits->cnt; i++ ) { 228 19675 : if( FD_UNLIKELY( epoch_credits->base_credits>ULONG_MAX-(ulong)epoch_credits->credits_delta[ i ] ) ) return 0; /* no overflow/wrapping on any credits */ 229 19674 : if( FD_UNLIKELY( epoch_credits->prev_credits_delta[ i ]>epoch_credits->credits_delta[ i ] ) ) return 0; /* (1) */ 230 19674 : if( FD_UNLIKELY( i && epoch_credits->prev_credits_delta[ i ]!=epoch_credits->credits_delta[ i-1UL ] ) ) return 0; /* (2) */ 231 19658 : if( FD_UNLIKELY( i && epoch_credits->epoch[ i ]<epoch_credits->epoch[ i-1UL ] ) ) return 0; /* (3) */ 232 19658 : } 233 1161 : return 1; 234 1191 : } 235 : 236 : struct fd_hard_fork { 237 : ulong slot; 238 : ulong cnt; /* number of hard forks in that slot */ 239 : }; 240 : typedef struct fd_hard_fork fd_hard_fork_t; 241 : 242 : FD_PROTOTYPES_BEGIN 243 : 244 : struct fd_fee_rate_governor { 245 : ulong target_lamports_per_signature; 246 : ulong target_signatures_per_slot; 247 : ulong min_lamports_per_signature; 248 : ulong max_lamports_per_signature; 249 : uchar burn_percent; 250 : }; 251 : typedef struct fd_fee_rate_governor fd_fee_rate_governor_t; 252 : 253 : struct fd_inflation { 254 : double initial; 255 : double terminal; 256 : double taper; 257 : double foundation; 258 : double foundation_term; 259 : double unused; 260 : }; 261 : typedef struct fd_inflation fd_inflation_t; 262 : 263 : #endif /* HEADER_fd_src_flamenco_fd_flamenco_base_h */