Line data Source code
1 : #include "fd_sysvar_stake_history.h" 2 : #include "fd_sysvar.h" 3 : #include "../fd_system_ids.h" 4 : #include "../context/fd_exec_slot_ctx.h" 5 : 6 : /* Ensure that the size declared by our header matches the minimum size 7 : of the corresponding fd_types entry. */ 8 : 9 : static void 10 : write_stake_history( fd_exec_slot_ctx_t * slot_ctx, 11 0 : fd_stake_history_t * stake_history ) { 12 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/sysvar/stake_history.rs#L12 */ 13 0 : uchar enc[16392] = {0}; 14 : 15 0 : fd_bincode_encode_ctx_t encode = 16 0 : { .data = enc, 17 0 : .dataend = enc + sizeof(enc) }; 18 0 : if( FD_UNLIKELY( fd_stake_history_encode( stake_history, &encode )!=FD_BINCODE_SUCCESS ) ) 19 0 : FD_LOG_ERR(("fd_stake_history_encode failed")); 20 : 21 0 : fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_stake_history_id, enc, sizeof(enc), slot_ctx->slot_bank.slot ); 22 0 : } 23 : 24 : static fd_stake_history_t * 25 : fd_sysvar_stake_history_read( fd_exec_slot_ctx_t * slot_ctx, 26 0 : fd_spad_t * runtime_spad ) { 27 0 : FD_TXN_ACCOUNT_DECL( stake_rec ); 28 0 : int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, &fd_sysvar_stake_history_id, stake_rec ); 29 0 : if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) 30 0 : return NULL; 31 : 32 0 : fd_bincode_decode_ctx_t ctx = { 33 0 : .data = stake_rec->const_data, 34 0 : .dataend = (char *)stake_rec->const_data + stake_rec->const_meta->dlen, 35 0 : }; 36 : 37 0 : ulong total_sz = 0UL; 38 0 : err = fd_stake_history_decode_footprint( &ctx, &total_sz ); 39 0 : if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { 40 0 : return NULL; 41 0 : } 42 : 43 0 : uchar * mem = fd_spad_alloc( runtime_spad, fd_stake_history_align(), total_sz ); 44 0 : if( FD_UNLIKELY( !mem ) ) { 45 0 : FD_LOG_ERR(( "Failed to allocate memory for stake history" )); 46 0 : } 47 : 48 0 : return fd_stake_history_decode( mem, &ctx ); 49 0 : } 50 : 51 : void 52 0 : fd_sysvar_stake_history_init( fd_exec_slot_ctx_t * slot_ctx ) { 53 0 : fd_stake_history_t stake_history; 54 0 : fd_stake_history_new( &stake_history ); 55 0 : write_stake_history( slot_ctx, &stake_history ); 56 0 : } 57 : 58 : void 59 : fd_sysvar_stake_history_update( fd_exec_slot_ctx_t * slot_ctx, 60 : fd_stake_history_entry_t * entry, 61 0 : fd_spad_t * runtime_spad ) { 62 : // Need to make this maybe zero copies of map... 63 0 : fd_stake_history_t * stake_history = fd_sysvar_stake_history_read( slot_ctx, runtime_spad ); 64 : 65 0 : if( stake_history->fd_stake_history_offset == 0 ) { 66 0 : stake_history->fd_stake_history_offset = stake_history->fd_stake_history_size - 1; 67 0 : } else { 68 0 : stake_history->fd_stake_history_offset--; 69 0 : } 70 : 71 0 : if( stake_history->fd_stake_history_len < stake_history->fd_stake_history_size ) { 72 0 : stake_history->fd_stake_history_len++; 73 0 : } 74 : 75 : // This should be done with a bit mask 76 0 : ulong idx = stake_history->fd_stake_history_offset; 77 : 78 0 : stake_history->fd_stake_history[ idx ].epoch = entry->epoch; 79 0 : stake_history->fd_stake_history[ idx ].activating = entry->activating; 80 0 : stake_history->fd_stake_history[ idx ].effective = entry->effective; 81 0 : stake_history->fd_stake_history[ idx ].deactivating = entry->deactivating; 82 : 83 0 : write_stake_history( slot_ctx, stake_history ); 84 0 : }