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 : FD_STATIC_ASSERT( FD_SYSVAR_STAKE_HISTORY_CAP == FD_STAKE_HISTORY_MIN, types ); 9 : 10 : void 11 : write_stake_history( fd_exec_slot_ctx_t * slot_ctx, 12 21828 : fd_stake_history_t * stake_history ) { 13 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/sysvar/stake_history.rs#L12 */ 14 21828 : uchar enc[16392] = {0}; 15 : 16 21828 : fd_bincode_encode_ctx_t encode = 17 21828 : { .data = enc, 18 21828 : .dataend = enc + sizeof(enc) }; 19 21828 : if( FD_UNLIKELY( fd_stake_history_encode( stake_history, &encode )!=FD_BINCODE_SUCCESS ) ) 20 0 : FD_LOG_ERR(("fd_stake_history_encode failed")); 21 : 22 21828 : fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_stake_history_id, enc, sizeof(enc), slot_ctx->slot_bank.slot ); 23 21828 : } 24 : 25 : fd_stake_history_t * 26 : fd_sysvar_stake_history_read( fd_stake_history_t * result, 27 : fd_exec_slot_ctx_t * slot_ctx, 28 10914 : fd_valloc_t * valloc ) { 29 10914 : FD_BORROWED_ACCOUNT_DECL(stake_rec); 30 10914 : int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, &fd_sysvar_stake_history_id, stake_rec); 31 10914 : if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) 32 0 : return NULL; 33 : 34 10914 : fd_bincode_decode_ctx_t ctx = { 35 10914 : .data = stake_rec->const_data, 36 10914 : .dataend = (char *) stake_rec->const_data + stake_rec->const_meta->dlen, 37 10914 : .valloc = *valloc 38 10914 : }; 39 : 40 10914 : if( FD_UNLIKELY( fd_stake_history_decode( result, &ctx )!=FD_BINCODE_SUCCESS ) ) 41 0 : return NULL; 42 10914 : return result; 43 10914 : } 44 : 45 : void 46 10914 : fd_sysvar_stake_history_init( fd_exec_slot_ctx_t * slot_ctx ) { 47 10914 : fd_stake_history_t stake_history = { 48 10914 : .pool = fd_stake_history_pool_alloc ( slot_ctx->valloc, FD_SYSVAR_STAKE_HISTORY_CAP ), 49 10914 : .treap = fd_stake_history_treap_alloc( slot_ctx->valloc, FD_SYSVAR_STAKE_HISTORY_CAP ) 50 10914 : }; 51 10914 : write_stake_history( slot_ctx, &stake_history ); 52 10914 : } 53 : 54 : void 55 : fd_sysvar_stake_history_update( fd_exec_slot_ctx_t * slot_ctx, 56 10914 : fd_stake_history_entry_t * entry ) { 57 : // Need to make this maybe zero copies of map... 58 10914 : fd_stake_history_t stake_history; 59 10914 : fd_sysvar_stake_history_read( &stake_history, slot_ctx, &slot_ctx->valloc ); 60 : 61 10914 : if (fd_stake_history_treap_ele_cnt( stake_history.treap ) == fd_stake_history_treap_ele_max( stake_history.treap )) { 62 0 : fd_stake_history_treap_fwd_iter_t iter = fd_stake_history_treap_fwd_iter_init( stake_history.treap, stake_history.pool ); 63 0 : fd_stake_history_entry_t * ele = fd_stake_history_treap_fwd_iter_ele( iter, stake_history.pool ); 64 0 : stake_history.treap = fd_stake_history_treap_ele_remove( stake_history.treap, ele, stake_history.pool ); 65 0 : fd_stake_history_pool_ele_release( stake_history.pool, ele ); 66 0 : } 67 : 68 10914 : if( 0 == fd_stake_history_pool_free( stake_history.pool ) ) { 69 0 : FD_LOG_ERR(( "stake_history.pool is empty" )); 70 0 : } 71 : 72 10914 : ulong idx = fd_stake_history_pool_idx_acquire( stake_history.pool ); 73 : 74 10914 : stake_history.pool[ idx ].epoch = entry->epoch; 75 10914 : stake_history.pool[ idx ].activating = entry->activating; 76 10914 : stake_history.pool[ idx ].effective = entry->effective; 77 10914 : stake_history.pool[ idx ].deactivating = entry->deactivating; 78 10914 : stake_history.treap = fd_stake_history_treap_idx_insert( stake_history.treap, idx, stake_history.pool ); 79 : 80 : 81 10914 : write_stake_history( slot_ctx, &stake_history); 82 10914 : fd_bincode_destroy_ctx_t destroy = { .valloc = slot_ctx->valloc }; 83 10914 : fd_stake_history_destroy( &stake_history, &destroy ); 84 10914 : }