Line data Source code
1 : #include "fd_sysvar_fees.h" 2 : #include "fd_sysvar.h" 3 : #include "../fd_system_ids.h" 4 : #include "../fd_runtime.h" 5 : #include "../context/fd_exec_epoch_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 : .data = enc, 14 0 : .dataend = enc + sz 15 0 : }; 16 0 : if( fd_sysvar_fees_encode( fees, &ctx ) ) { 17 0 : FD_LOG_ERR(( "fd_sysvar_fees_encode failed" )); 18 0 : } 19 : 20 0 : fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_fees_id, enc, sz, slot_ctx->slot_bank.slot ); 21 0 : } 22 : 23 : fd_sysvar_fees_t * 24 : fd_sysvar_fees_read( fd_funk_t * funk, 25 : fd_funk_txn_t * funk_txn, 26 0 : fd_spad_t * spad ) { 27 : 28 0 : FD_TXN_ACCOUNT_DECL( acc ); 29 0 : int err = fd_txn_account_init_from_funk_readonly( acc, &fd_sysvar_fees_id, funk, funk_txn ); 30 0 : if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) 31 0 : return NULL; 32 : 33 0 : return fd_bincode_decode_spad( 34 0 : sysvar_fees, spad, 35 0 : acc->vt->get_data( acc ), 36 0 : acc->vt->get_data_len( acc ), 37 0 : &err ); 38 0 : } 39 : 40 : /* 41 : https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/sdk/program/src/fee_calculator.rs#L105-L165 42 : */ 43 : void 44 : fd_sysvar_fees_new_derived( fd_exec_slot_ctx_t * slot_ctx, 45 : fd_fee_rate_governor_t base_fee_rate_governor, 46 0 : ulong latest_singatures_per_slot ) { 47 0 : fd_fee_rate_governor_t me = { 48 0 : .target_signatures_per_slot = base_fee_rate_governor.target_signatures_per_slot, 49 0 : .target_lamports_per_signature = base_fee_rate_governor.target_lamports_per_signature, 50 0 : .max_lamports_per_signature = base_fee_rate_governor.max_lamports_per_signature, 51 0 : .min_lamports_per_signature = base_fee_rate_governor.min_lamports_per_signature, 52 0 : .burn_percent = base_fee_rate_governor.burn_percent 53 0 : }; 54 : 55 0 : ulong lamports_per_signature = 0; 56 0 : if ( me.target_signatures_per_slot > 0 ) { 57 0 : me.min_lamports_per_signature = fd_ulong_max( 1UL, (ulong)(me.target_lamports_per_signature / 2) ); 58 0 : me.max_lamports_per_signature = me.target_lamports_per_signature * 10; 59 0 : ulong desired_lamports_per_signature = fd_ulong_min( 60 0 : me.max_lamports_per_signature, 61 0 : fd_ulong_max( 62 0 : me.min_lamports_per_signature, 63 0 : me.target_lamports_per_signature 64 0 : * fd_ulong_min(latest_singatures_per_slot, (ulong)UINT_MAX) 65 0 : / me.target_signatures_per_slot 66 0 : ) 67 0 : ); 68 0 : long gap = (long)desired_lamports_per_signature - (long)slot_ctx->slot_bank.lamports_per_signature; 69 0 : if ( gap == 0 ) { 70 0 : lamports_per_signature = desired_lamports_per_signature; 71 0 : } else { 72 0 : long gap_adjust = (long)(fd_ulong_max( 1UL, (ulong)(me.target_lamports_per_signature / 20) )) 73 0 : * (gap != 0) 74 0 : * (gap > 0 ? 1 : -1); 75 0 : lamports_per_signature = fd_ulong_min( 76 0 : me.max_lamports_per_signature, 77 0 : fd_ulong_max( 78 0 : me.min_lamports_per_signature, 79 0 : (ulong)((long) slot_ctx->slot_bank.lamports_per_signature + gap_adjust) 80 0 : ) 81 0 : ); 82 0 : } 83 0 : } else { 84 0 : lamports_per_signature = base_fee_rate_governor.target_lamports_per_signature; 85 0 : me.min_lamports_per_signature = me.target_lamports_per_signature; 86 0 : me.max_lamports_per_signature = me.target_lamports_per_signature; 87 0 : } 88 : 89 0 : if( FD_UNLIKELY( slot_ctx->slot_bank.lamports_per_signature==0UL ) ) { 90 0 : slot_ctx->prev_lamports_per_signature = lamports_per_signature; 91 0 : } else { 92 0 : slot_ctx->prev_lamports_per_signature = slot_ctx->slot_bank.lamports_per_signature; 93 0 : } 94 : 95 0 : slot_ctx->slot_bank.lamports_per_signature = lamports_per_signature; 96 0 : slot_ctx->slot_bank.fee_rate_governor = me; 97 0 : } 98 : 99 : void 100 0 : fd_sysvar_fees_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { 101 0 : if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar )) 102 0 : return; 103 : 104 0 : fd_sysvar_fees_t * fees = fd_sysvar_fees_read( slot_ctx->funk, 105 0 : slot_ctx->funk_txn, 106 0 : runtime_spad ); 107 0 : if( FD_UNLIKELY( fees == NULL ) ) { 108 0 : FD_LOG_ERR(( "failed to read sysvar fees" )); 109 0 : } 110 : /* todo: I need to the lamports_per_signature field */ 111 0 : fees->fee_calculator.lamports_per_signature = slot_ctx->slot_bank.lamports_per_signature; 112 0 : write_fees( slot_ctx, fees ); 113 0 : } 114 : 115 0 : void fd_sysvar_fees_init( fd_exec_slot_ctx_t * slot_ctx ) { 116 : /* Default taken from https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/fee_calculator.rs#L110 */ 117 : /* TODO: handle non-default case */ 118 0 : fd_sysvar_fees_t fees = { 119 0 : { 120 0 : .lamports_per_signature = 0, 121 0 : } 122 0 : }; 123 0 : write_fees( slot_ctx, &fees ); 124 0 : }