Line data Source code
1 : #include "fd_exec_epoch_ctx.h" 2 : #include <assert.h> 3 : #include "../sysvar/fd_sysvar_stake_history.h" 4 : #include "../fd_runtime.h" 5 : 6 : /* TODO remove this */ 7 : #define MAX_LG_SLOT_CNT 10UL 8 : 9 : ulong 10 7665 : fd_exec_epoch_ctx_align( void ) { 11 7665 : return FD_EXEC_EPOCH_CTX_ALIGN; 12 7665 : } 13 : 14 : static ulong 15 : fd_exec_epoch_ctx_footprint_ext( fd_exec_epoch_ctx_layout_t * layout, 16 0 : ulong vote_acc_max ) { 17 : 18 0 : if( FD_UNLIKELY( !vote_acc_max ) ) return 0UL; 19 : 20 0 : fd_memset( layout, 0, sizeof(fd_exec_epoch_ctx_layout_t) ); 21 0 : layout->vote_acc_max = vote_acc_max; 22 : 23 0 : ulong stake_votes_sz = fd_vote_accounts_pair_t_map_footprint( vote_acc_max ); if( !stake_votes_sz ) return 0UL; 24 0 : ulong stake_delegations_sz = fd_delegation_pair_t_map_footprint ( vote_acc_max ); if( !stake_delegations_sz ) return 0UL; 25 0 : ulong next_epoch_stakes_sz = fd_vote_accounts_pair_t_map_footprint( vote_acc_max ); if( !next_epoch_stakes_sz ) return 0UL; 26 0 : ulong leaders_sz = fd_epoch_leaders_footprint( MAX_PUB_CNT, MAX_SLOTS_CNT ); if( !leaders_sz ) FD_LOG_CRIT(( "invalid fd_epoch_leaders footprint" )); 27 : 28 0 : FD_SCRATCH_ALLOC_INIT( l, 0 ); 29 0 : FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_epoch_ctx_t), sizeof(fd_exec_epoch_ctx_t) ); 30 0 : layout->stake_votes_off = (ulong)FD_SCRATCH_ALLOC_APPEND( l, fd_vote_accounts_pair_t_map_align(), stake_votes_sz ); 31 0 : layout->stake_delegations_off = (ulong)FD_SCRATCH_ALLOC_APPEND( l, fd_delegation_pair_t_map_align(), stake_delegations_sz ); 32 0 : layout->next_epoch_stakes_off = (ulong)FD_SCRATCH_ALLOC_APPEND( l, fd_vote_accounts_pair_t_map_align(), next_epoch_stakes_sz ); 33 0 : layout->leaders_off = (ulong)FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_leaders_align(), leaders_sz ); 34 : 35 0 : return layout->footprint = (ulong)FD_SCRATCH_ALLOC_FINI( l, fd_exec_epoch_ctx_align() ); 36 0 : } 37 : 38 : ulong 39 0 : fd_exec_epoch_ctx_footprint( ulong vote_acc_max ) { 40 0 : fd_exec_epoch_ctx_layout_t layout[1]; 41 0 : return fd_exec_epoch_ctx_footprint_ext( layout, vote_acc_max ); 42 0 : } 43 : 44 : void * 45 : fd_exec_epoch_ctx_new( void * mem, 46 0 : ulong vote_acc_max ) { 47 0 : if( FD_UNLIKELY( !mem ) ) { 48 0 : FD_LOG_WARNING(( "NULL mem" )); 49 0 : return NULL; 50 0 : } 51 : 52 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, FD_EXEC_EPOCH_CTX_ALIGN ) ) ) { 53 0 : FD_LOG_WARNING(( "misaligned mem %lu", (ulong)mem )); 54 0 : return NULL; 55 0 : } 56 : 57 0 : fd_exec_epoch_ctx_t * self = mem; 58 0 : fd_memset( self, 0, sizeof(fd_exec_epoch_ctx_t) ); 59 : 60 0 : if( FD_UNLIKELY( !fd_exec_epoch_ctx_footprint_ext( &self->layout, vote_acc_max ) ) ) { 61 0 : FD_LOG_WARNING(( "invalid vote_acc_max" )); 62 0 : return NULL; 63 0 : } 64 : 65 0 : fd_exec_epoch_ctx_bank_mem_setup( self ); 66 : 67 0 : fd_features_disable_all( &self->features ); 68 0 : self->epoch_bank.cluster_version[0] = FD_DEFAULT_AGAVE_CLUSTER_VERSION_MAJOR; 69 0 : self->epoch_bank.cluster_version[1] = FD_DEFAULT_AGAVE_CLUSTER_VERSION_MINOR; 70 0 : self->epoch_bank.cluster_version[2] = FD_DEFAULT_AGAVE_CLUSTER_VERSION_PATCH; 71 0 : fd_features_enable_cleaned_up( &self->features, self->epoch_bank.cluster_version ); 72 : 73 0 : FD_COMPILER_MFENCE(); 74 0 : self->magic = FD_EXEC_EPOCH_CTX_MAGIC; 75 0 : FD_COMPILER_MFENCE(); 76 : 77 0 : return mem; 78 0 : } 79 : 80 : fd_exec_epoch_ctx_t * 81 0 : fd_exec_epoch_ctx_join( void * mem ) { 82 0 : if( FD_UNLIKELY( !mem ) ) { 83 0 : FD_LOG_WARNING(( "NULL block" )); 84 0 : return NULL; 85 0 : } 86 : 87 0 : fd_exec_epoch_ctx_t * ctx = (fd_exec_epoch_ctx_t *) mem; 88 : 89 0 : if( FD_UNLIKELY( ctx->magic!=FD_EXEC_EPOCH_CTX_MAGIC ) ) { 90 0 : FD_LOG_WARNING(( "bad magic" )); 91 0 : return NULL; 92 0 : } 93 : 94 0 : return ctx; 95 0 : } 96 : 97 : static void 98 0 : epoch_ctx_bank_mem_leave( fd_exec_epoch_ctx_t * epoch_ctx ) { 99 0 : void * mem = epoch_ctx; 100 0 : fd_exec_epoch_ctx_layout_t const * layout = &epoch_ctx->layout; 101 : 102 0 : void * stake_votes_mem = (void *)( (ulong)mem + layout->stake_votes_off ); 103 0 : void * stake_delegations_mem = (void *)( (ulong)mem + layout->stake_delegations_off ); 104 : 105 0 : fd_vote_accounts_pair_t_map_leave ( stake_votes_mem ); 106 0 : fd_delegation_pair_t_map_leave ( stake_delegations_mem ); 107 0 : } 108 : 109 : void * 110 0 : fd_exec_epoch_ctx_leave( fd_exec_epoch_ctx_t * ctx ) { 111 0 : if( FD_UNLIKELY( !ctx ) ) { 112 0 : FD_LOG_WARNING(( "NULL block" )); 113 0 : return NULL; 114 0 : } 115 : 116 0 : if( FD_UNLIKELY( ctx->magic!=FD_EXEC_EPOCH_CTX_MAGIC ) ) { 117 0 : FD_LOG_WARNING(( "bad magic" )); 118 0 : return NULL; 119 0 : } 120 : 121 0 : epoch_ctx_bank_mem_leave( ctx ); 122 : 123 0 : return (void *) ctx; 124 0 : } 125 : 126 : void * 127 0 : fd_exec_epoch_ctx_delete( void * mem ) { 128 0 : if( FD_UNLIKELY( !mem ) ) { 129 0 : FD_LOG_WARNING(( "NULL mem" )); 130 0 : return NULL; 131 0 : } 132 : 133 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, FD_EXEC_EPOCH_CTX_ALIGN) ) ) { 134 0 : FD_LOG_WARNING(( "misaligned mem" )); 135 0 : return NULL; 136 0 : } 137 : 138 0 : fd_exec_epoch_ctx_t * hdr = (fd_exec_epoch_ctx_t *)mem; 139 0 : if( FD_UNLIKELY( hdr->magic!=FD_EXEC_EPOCH_CTX_MAGIC ) ) { 140 0 : FD_LOG_WARNING(( "bad magic" )); 141 0 : return NULL; 142 0 : } 143 0 : fd_exec_epoch_ctx_layout_t const * layout = &hdr->layout; 144 : 145 0 : void * next_epoch_stakes_mem = (void *)( (ulong)mem + layout->next_epoch_stakes_off ); 146 0 : void * leaders_mem = (void *)( (ulong)mem + layout->leaders_off ); 147 : 148 0 : fd_vote_accounts_pair_t_map_delete( next_epoch_stakes_mem ); 149 0 : fd_epoch_leaders_delete ( leaders_mem ); 150 : 151 0 : fd_exec_epoch_ctx_epoch_bank_delete( hdr ); 152 : 153 0 : FD_COMPILER_MFENCE(); 154 0 : FD_VOLATILE( hdr->magic ) = 0UL; 155 0 : FD_COMPILER_MFENCE(); 156 : 157 0 : return mem; 158 0 : } 159 : 160 : static void 161 0 : epoch_ctx_bank_mem_delete( fd_exec_epoch_ctx_t * epoch_ctx ) { 162 0 : void * mem = epoch_ctx; 163 0 : fd_exec_epoch_ctx_layout_t const * layout = &epoch_ctx->layout; 164 : 165 0 : void * stake_votes_mem = (void *)( (ulong)mem + layout->stake_votes_off ); 166 0 : void * stake_delegations_mem = (void *)( (ulong)mem + layout->stake_delegations_off ); 167 : 168 0 : fd_vote_accounts_pair_t_map_delete( stake_votes_mem ); 169 0 : fd_delegation_pair_t_map_delete ( stake_delegations_mem ); 170 0 : } 171 : 172 : void 173 0 : fd_exec_epoch_ctx_epoch_bank_delete( fd_exec_epoch_ctx_t * epoch_ctx ) { 174 0 : epoch_ctx_bank_mem_delete( epoch_ctx ); 175 0 : memset( &epoch_ctx->epoch_bank, 0UL, FD_EPOCH_BANK_FOOTPRINT); 176 0 : } 177 : 178 : void 179 0 : fd_exec_epoch_ctx_bank_mem_clear( fd_exec_epoch_ctx_t * epoch_ctx ) { 180 0 : fd_epoch_bank_t * const epoch_bank = &epoch_ctx->epoch_bank; 181 0 : { 182 0 : fd_vote_accounts_pair_t_mapnode_t * old_pool = epoch_bank->stakes.vote_accounts.vote_accounts_pool; 183 0 : fd_vote_accounts_pair_t_mapnode_t * old_root = epoch_bank->stakes.vote_accounts.vote_accounts_root; 184 0 : fd_vote_accounts_pair_t_map_release_tree( old_pool, old_root ); 185 0 : epoch_bank->stakes.vote_accounts.vote_accounts_root = NULL; 186 0 : } 187 0 : { 188 0 : fd_delegation_pair_t_mapnode_t * old_pool = epoch_bank->stakes.stake_delegations_pool; 189 0 : fd_delegation_pair_t_mapnode_t * old_root = epoch_bank->stakes.stake_delegations_root; 190 0 : fd_delegation_pair_t_map_release_tree( old_pool, old_root ); 191 0 : epoch_bank->stakes.stake_delegations_root = NULL; 192 0 : } 193 0 : { 194 0 : fd_vote_accounts_pair_t_mapnode_t * old_pool = epoch_bank->next_epoch_stakes.vote_accounts_pool; 195 0 : fd_vote_accounts_pair_t_mapnode_t * old_root = epoch_bank->next_epoch_stakes.vote_accounts_root; 196 0 : fd_vote_accounts_pair_t_map_release_tree( old_pool, old_root ); 197 0 : epoch_bank->next_epoch_stakes.vote_accounts_root = NULL; 198 0 : } 199 0 : } 200 : 201 : fd_epoch_bank_t * 202 0 : fd_exec_epoch_ctx_bank_mem_setup( fd_exec_epoch_ctx_t * self ) { 203 0 : fd_exec_epoch_ctx_layout_t * layout = &self->layout; 204 : 205 0 : void * stake_votes_mem = (void *)( (ulong)self + layout->stake_votes_off ); 206 0 : void * stake_delegations_mem = (void *)( (ulong)self + layout->stake_delegations_off ); 207 0 : void * next_epoch_stakes_mem = (void *)( (ulong)self + layout->next_epoch_stakes_off ); 208 : //void * leaders_mem = (void *)( (ulong)self + layout->leaders_off ); 209 : 210 0 : fd_epoch_bank_t * epoch_bank = &self->epoch_bank; 211 0 : fd_epoch_bank_new( &self->epoch_bank ); 212 : 213 0 : epoch_bank->stakes.vote_accounts.vote_accounts_pool = 214 0 : fd_vote_accounts_pair_t_map_join( fd_vote_accounts_pair_t_map_new( stake_votes_mem, layout->vote_acc_max ) ); 215 : 216 0 : epoch_bank->stakes.stake_delegations_pool = 217 0 : fd_delegation_pair_t_map_join ( fd_delegation_pair_t_map_new ( stake_delegations_mem, layout->vote_acc_max ) ); 218 : 219 0 : epoch_bank->next_epoch_stakes.vote_accounts_pool = 220 0 : fd_vote_accounts_pair_t_map_join( fd_vote_accounts_pair_t_map_new( next_epoch_stakes_mem, layout->vote_acc_max ) ); 221 : 222 : //TODO support separate epoch leaders new and init 223 : //fd_epoch_leaders_new ( leaders_mem, MAX_PUB_CNT, MAX_SLOTS_CNT ); 224 : 225 0 : return epoch_bank; 226 0 : } 227 : 228 : void 229 : fd_exec_epoch_ctx_from_prev( fd_exec_epoch_ctx_t * self, 230 : fd_exec_epoch_ctx_t * prev, 231 0 : fd_spad_t * runtime_spad ) { 232 0 : fd_memcpy( &self->features, &prev->features, sizeof(fd_features_t) ); 233 : 234 0 : self->bank_hash_cmp = prev->bank_hash_cmp; 235 0 : self->replay_public = prev->replay_public; 236 0 : self->total_epoch_stake = 0UL; 237 : 238 0 : fd_memcpy( &self->replay_public->features, &prev->features, sizeof(fd_features_t) ); 239 : 240 0 : fd_epoch_bank_t * old_epoch_bank = fd_exec_epoch_ctx_epoch_bank( prev ); 241 : 242 0 : FD_SPAD_FRAME_BEGIN( runtime_spad ) { 243 : 244 0 : ulong sz = fd_epoch_bank_size( old_epoch_bank ); 245 0 : uchar * buf = fd_spad_alloc( runtime_spad, fd_epoch_bank_align(), sz ); 246 : 247 0 : fd_bincode_encode_ctx_t encode = {.data = buf, .dataend = buf + sz }; 248 0 : fd_epoch_bank_encode( old_epoch_bank, &encode ); 249 : 250 0 : sz = fd_ulong_align_up( fd_epoch_leaders_footprint( MAX_PUB_CNT, MAX_SLOTS_CNT ), fd_epoch_leaders_align() ); 251 0 : fd_memcpy( fd_exec_epoch_ctx_leaders( self ), fd_exec_epoch_ctx_leaders( prev ), sz ); 252 : 253 0 : } FD_SPAD_FRAME_END; 254 0 : }