Line data Source code
1 : #include "fd_sysvar_fees.h" 2 : #include "fd_sysvar.h" 3 : #include "../fd_system_ids.h" 4 : #include "../context/fd_exec_epoch_ctx.h" 5 : #include "../context/fd_exec_slot_ctx.h" 6 : 7 : static void 8 0 : write_fees( fd_exec_slot_ctx_t* slot_ctx, fd_sysvar_fees_t* fees ) { 9 0 : ulong sz = fd_sysvar_fees_size( fees ); 10 0 : uchar enc[sz]; 11 0 : fd_memset( enc, 0, sz ); 12 0 : fd_bincode_encode_ctx_t ctx; 13 0 : ctx.data = enc; 14 0 : ctx.dataend = enc + sz; 15 0 : if ( fd_sysvar_fees_encode( fees, &ctx ) ) 16 0 : FD_LOG_ERR(("fd_sysvar_fees_encode failed")); 17 : 18 0 : fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_fees_id, enc, sz, slot_ctx->slot_bank.slot ); 19 0 : } 20 : 21 : fd_sysvar_fees_t * 22 : fd_sysvar_fees_read( fd_sysvar_fees_t * result, 23 0 : fd_exec_slot_ctx_t const * slot_ctx ) { 24 0 : fd_sysvar_fees_t const * ret = fd_sysvar_cache_fees( slot_ctx->sysvar_cache ); 25 0 : if( FD_UNLIKELY( NULL != ret ) ) { 26 0 : fd_memcpy(result, ret, sizeof(fd_sysvar_fees_t)); 27 0 : return result; 28 0 : } 29 : 30 0 : FD_BORROWED_ACCOUNT_DECL(acc); 31 0 : int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, &fd_sysvar_fees_id, acc ); 32 0 : if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) 33 0 : return NULL; 34 : 35 0 : fd_bincode_decode_ctx_t decode = 36 0 : { .data = acc->const_data, 37 0 : .dataend = acc->const_data + acc->const_meta->dlen, 38 0 : .valloc = {0} /* valloc not required */ }; 39 : 40 0 : if( FD_UNLIKELY( fd_sysvar_fees_decode( result, &decode )!=FD_BINCODE_SUCCESS ) ) 41 0 : return NULL; 42 0 : return result; 43 0 : } 44 : 45 : /* 46 : https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/sdk/program/src/fee_calculator.rs#L105-L165 47 : */ 48 : void 49 : fd_sysvar_fees_new_derived( 50 : fd_exec_slot_ctx_t * slot_ctx, 51 : fd_fee_rate_governor_t base_fee_rate_governor, 52 : ulong latest_singatures_per_slot 53 0 : ) { 54 0 : fd_fee_rate_governor_t me = { 55 0 : .target_signatures_per_slot = base_fee_rate_governor.target_signatures_per_slot, 56 0 : .target_lamports_per_signature = base_fee_rate_governor.target_lamports_per_signature, 57 0 : .max_lamports_per_signature = base_fee_rate_governor.max_lamports_per_signature, 58 0 : .min_lamports_per_signature = base_fee_rate_governor.min_lamports_per_signature, 59 0 : .burn_percent = base_fee_rate_governor.burn_percent 60 0 : }; 61 : 62 0 : ulong lamports_per_signature = 0; 63 0 : if ( me.target_signatures_per_slot > 0 ) { 64 0 : me.min_lamports_per_signature = fd_ulong_max( 1UL, (ulong)(me.target_lamports_per_signature / 2) ); 65 0 : me.max_lamports_per_signature = me.target_lamports_per_signature * 10; 66 0 : ulong desired_lamports_per_signature = fd_ulong_min( 67 0 : me.max_lamports_per_signature, 68 0 : fd_ulong_max( 69 0 : me.min_lamports_per_signature, 70 0 : me.target_lamports_per_signature 71 0 : * fd_ulong_min(latest_singatures_per_slot, (ulong)UINT_MAX) 72 0 : / me.target_signatures_per_slot 73 0 : ) 74 0 : ); 75 0 : long gap = (long)desired_lamports_per_signature - (long)slot_ctx->slot_bank.lamports_per_signature; 76 0 : if ( gap == 0 ) { 77 0 : lamports_per_signature = desired_lamports_per_signature; 78 0 : } else { 79 0 : long gap_adjust = (long)(fd_ulong_max( 1UL, (ulong)(me.target_lamports_per_signature / 20) )) 80 0 : * (gap != 0) 81 0 : * (gap > 0 ? 1 : -1); 82 0 : lamports_per_signature = fd_ulong_min( 83 0 : me.max_lamports_per_signature, 84 0 : fd_ulong_max( 85 0 : me.min_lamports_per_signature, 86 0 : (ulong)((long) slot_ctx->slot_bank.lamports_per_signature + gap_adjust) 87 0 : ) 88 0 : ); 89 0 : } 90 0 : } else { 91 0 : lamports_per_signature = base_fee_rate_governor.target_lamports_per_signature; 92 0 : me.min_lamports_per_signature = me.target_lamports_per_signature; 93 0 : me.max_lamports_per_signature = me.target_lamports_per_signature; 94 0 : } 95 : 96 0 : if( FD_UNLIKELY( slot_ctx->slot_bank.lamports_per_signature==0UL ) ) { 97 0 : slot_ctx->prev_lamports_per_signature = lamports_per_signature; 98 0 : } else { 99 0 : slot_ctx->prev_lamports_per_signature = slot_ctx->slot_bank.lamports_per_signature; 100 0 : } 101 : 102 0 : slot_ctx->slot_bank.lamports_per_signature = lamports_per_signature; 103 0 : fd_memcpy(&slot_ctx->slot_bank.fee_rate_governor, &me, sizeof(fd_fee_rate_governor_t)); 104 0 : } 105 : 106 : void 107 0 : fd_sysvar_fees_update( fd_exec_slot_ctx_t * slot_ctx ) { 108 0 : if ( FD_FEATURE_ACTIVE( slot_ctx, disable_fees_sysvar )) 109 0 : return; 110 0 : fd_sysvar_fees_t fees; 111 0 : fd_sysvar_fees_read( &fees, slot_ctx ); 112 : /* todo: I need to the lamports_per_signature field */ 113 0 : fees.fee_calculator.lamports_per_signature = slot_ctx->slot_bank.lamports_per_signature; 114 0 : write_fees( slot_ctx, &fees ); 115 0 : } 116 : 117 0 : void fd_sysvar_fees_init( fd_exec_slot_ctx_t * slot_ctx ) { 118 : /* Default taken from https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/fee_calculator.rs#L110 */ 119 : /* TODO: handle non-default case */ 120 0 : fd_sysvar_fees_t fees = { 121 0 : { 122 0 : .lamports_per_signature = 0, 123 0 : } 124 0 : }; 125 0 : write_fees( slot_ctx, &fees ); 126 0 : }