LCOV - code coverage report
Current view: top level - flamenco/runtime/program - fd_compute_budget_program.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 111 113 98.2 %
Date: 2024-11-13 11:58:15 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #include "fd_compute_budget_program.h"
       2             : 
       3             : #include "../fd_runtime_err.h"
       4             : #include "../fd_system_ids.h"
       5             : #include "../fd_executor.h"
       6             : #include "../context/fd_exec_instr_ctx.h"
       7             : #include "../context/fd_exec_txn_ctx.h"
       8             : #include "../context/fd_exec_slot_ctx.h"
       9             : #include "../context/fd_exec_epoch_ctx.h"
      10             : #include "../../vm/fd_vm.h"
      11             : 
      12        6048 : #define DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT  (200000)
      13             : #define DEFAULT_COMPUTE_UNITS                   (150UL)
      14             : 
      15             : FD_FN_PURE static inline int
      16             : is_compute_budget_instruction( fd_exec_txn_ctx_t const * ctx,
      17       10995 :                                fd_txn_instr_t    const * instr ) {
      18       10995 :   fd_pubkey_t const * txn_accs       = ctx->accounts;
      19       10995 :   fd_pubkey_t const * program_pubkey = &txn_accs[ instr->program_id ];
      20       10995 :   return !memcmp(program_pubkey, fd_solana_compute_budget_program_id.key, sizeof(fd_pubkey_t));
      21       10995 : }
      22             : 
      23             : /* https://github.com/anza-xyz/agave/blob/16de8b75ebcd57022409b422de557dd37b1de8db/compute-budget/src/compute_budget_processor.rs#L150-L153 */
      24             : FD_FN_PURE static inline int
      25          57 : sanitize_requested_heap_size( ulong bytes ) {
      26          57 :   return !(bytes>FD_MAX_HEAP_FRAME_BYTES || bytes<FD_MIN_HEAP_FRAME_BYTES || bytes%FD_HEAP_FRAME_BYTES_GRANULARITY);
      27          57 : }
      28             : 
      29             : /* https://github.com/anza-xyz/agave/blob/16de8b75ebcd57022409b422de557dd37b1de8db/compute-budget/src/compute_budget_processor.rs#L69-L148 */
      30             : int 
      31        6210 : fd_executor_compute_budget_program_execute_instructions( fd_exec_txn_ctx_t * ctx, fd_rawtxn_b_t const * txn_raw ) {
      32        6210 :   uint   has_compute_units_limit_update              = 0UL;
      33        6210 :   uint   has_compute_units_price_update              = 0UL;
      34        6210 :   uint   has_requested_heap_size                     = 0UL;
      35        6210 :   uint   has_loaded_accounts_data_size_limit_update  = 0UL;
      36             : 
      37        6210 :   ushort requested_heap_size_instr_index             = 0;
      38        6210 :   uint   num_non_compute_budget_instrs               = 0U;
      39             : 
      40        6210 :   uint   updated_compute_unit_limit                  = 0U;
      41        6210 :   uint   updated_requested_heap_size                 = 0U;
      42        6210 :   uint   updated_loaded_accounts_data_size_limit     = 0U;
      43        6210 :   ulong  updated_compute_unit_price                  = 0UL;
      44             : 
      45        6210 :   uint prioritization_fee_type = FD_COMPUTE_BUDGET_PRIORITIZATION_FEE_TYPE_COMPUTE_UNIT_PRICE;
      46             : 
      47       17121 :   for( ushort i=0; i<ctx->txn_descriptor->instr_cnt; i++ ) {
      48       10995 :     fd_txn_instr_t const * instr = &ctx->txn_descriptor->instr[i];
      49             : 
      50       10995 :     if( !is_compute_budget_instruction( ctx, instr ) ) {
      51       10668 :       num_non_compute_budget_instrs++;
      52       10668 :       continue;
      53       10668 :     }
      54             :     /* Deserialize the ComputeBudgetInstruction enum */
      55         327 :     uchar * data = (uchar *)txn_raw->raw + instr->data_off;
      56             : 
      57         327 :     fd_compute_budget_program_instruction_t instruction;
      58         327 :     fd_bincode_decode_ctx_t decode_ctx = {
      59         327 :       .data    = data,
      60         327 :       .dataend = &data[ instr->data_sz ],
      61         327 :       .valloc  = ctx->valloc,
      62         327 :     };
      63             : 
      64         327 :     int ret = fd_compute_budget_program_instruction_decode( &instruction, &decode_ctx );
      65         327 :     if ( ret ) {
      66          66 :       FD_LOG_WARNING(("fd_compute_budget_program_instruction_decode failed"));
      67          66 :       FD_LOG_HEXDUMP_WARNING(("cbi data", data, instr->data_sz));
      68          66 :       FD_TXN_ERR_FOR_LOG_INSTR( ctx, FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA, i );
      69          66 :       return FD_RUNTIME_TXN_ERR_INSTRUCTION_ERROR;
      70          66 :     }
      71             : 
      72         261 :     switch( instruction.discriminant ) {
      73          69 :       case fd_compute_budget_program_instruction_enum_request_heap_frame: {
      74          69 :         if( FD_UNLIKELY( has_requested_heap_size ) ) {
      75           6 :           return FD_RUNTIME_TXN_ERR_DUPLICATE_INSTRUCTION;
      76           6 :         }
      77             : 
      78          63 :         has_requested_heap_size     = 1U;
      79          63 :         updated_requested_heap_size = instruction.inner.request_heap_frame;
      80          63 :         requested_heap_size_instr_index = i;
      81             : 
      82          63 :         break;
      83          69 :       }
      84          75 :       case fd_compute_budget_program_instruction_enum_set_compute_unit_limit: {
      85          75 :         if( FD_UNLIKELY( has_compute_units_limit_update ) ) {
      86           3 :           return FD_RUNTIME_TXN_ERR_DUPLICATE_INSTRUCTION;
      87           3 :         }
      88             : 
      89          72 :         has_compute_units_limit_update  = 1U;
      90          72 :         updated_compute_unit_limit      = instruction.inner.set_compute_unit_limit;
      91             : 
      92          72 :         break;
      93          75 :       }
      94          63 :       case fd_compute_budget_program_instruction_enum_set_compute_unit_price: {
      95          63 :         if( FD_UNLIKELY( has_compute_units_price_update ) ) {
      96           3 :           return FD_RUNTIME_TXN_ERR_DUPLICATE_INSTRUCTION;
      97           3 :         }
      98             : 
      99          60 :         has_compute_units_price_update = 1U;
     100          60 :         prioritization_fee_type        = FD_COMPUTE_BUDGET_PRIORITIZATION_FEE_TYPE_COMPUTE_UNIT_PRICE;
     101          60 :         updated_compute_unit_price     = instruction.inner.set_compute_unit_price;
     102             : 
     103          60 :         break;
     104          63 :       }
     105          48 :       case fd_compute_budget_program_instruction_enum_set_loaded_accounts_data_size_limit: {
     106          48 :           if( FD_UNLIKELY( has_loaded_accounts_data_size_limit_update ) ) {
     107           0 :             return FD_RUNTIME_TXN_ERR_DUPLICATE_INSTRUCTION;
     108           0 :           }
     109             : 
     110          48 :           has_loaded_accounts_data_size_limit_update = 1U;
     111          48 :           updated_loaded_accounts_data_size_limit    = instruction.inner.set_loaded_accounts_data_size_limit;
     112             : 
     113          48 :           break;
     114          48 :       }
     115           6 :       default: {
     116           6 :         FD_TXN_ERR_FOR_LOG_INSTR( ctx, FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA, i );
     117           6 :         return FD_RUNTIME_TXN_ERR_INSTRUCTION_ERROR;
     118          48 :       }
     119         261 :     }
     120         261 :   }
     121             : 
     122             :   /* https://github.com/anza-xyz/agave/blob/v2.1/runtime-transaction/src/compute_budget_instruction_details.rs#L51-L64 */
     123        6126 :   if( has_requested_heap_size ) {
     124          57 :     if( FD_UNLIKELY( !sanitize_requested_heap_size( updated_requested_heap_size ) ) ) {
     125           9 :       FD_TXN_ERR_FOR_LOG_INSTR( ctx, FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA, requested_heap_size_instr_index );
     126           9 :       return FD_RUNTIME_TXN_ERR_INSTRUCTION_ERROR;
     127           9 :     } 
     128          48 :     ctx->heap_size = updated_requested_heap_size;
     129          48 :   }
     130             : 
     131             :   /* https://github.com/anza-xyz/agave/blob/v2.1/runtime-transaction/src/compute_budget_instruction_details.rs#L66-L76 */
     132        6117 :   if( has_compute_units_limit_update ) {
     133          69 :     ctx->compute_unit_limit = fd_ulong_min( FD_MAX_COMPUTE_UNIT_LIMIT, updated_compute_unit_limit );
     134        6048 :   } else {
     135        6048 :     ctx->compute_unit_limit = fd_ulong_min( FD_MAX_COMPUTE_UNIT_LIMIT, 
     136        6048 :                                             (ulong)fd_uint_sat_mul( num_non_compute_budget_instrs, DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT ) );
     137        6048 :   }
     138        6117 :   ctx->compute_meter = ctx->compute_unit_limit;
     139             : 
     140        6117 :   if( has_compute_units_price_update ) {
     141          57 :     ctx->prioritization_fee_type = prioritization_fee_type;
     142          57 :     ctx->compute_unit_price      = updated_compute_unit_price;
     143          57 :   }
     144             : 
     145             :   /* https://github.com/anza-xyz/agave/blob/v2.1/runtime-transaction/src/compute_budget_instruction_details.rs#L84-L93 */
     146        6117 :   if( has_loaded_accounts_data_size_limit_update ) {
     147          48 :     if( FD_UNLIKELY( updated_loaded_accounts_data_size_limit==0UL ) ) {
     148           6 :       return FD_RUNTIME_TXN_ERR_INVALID_LOADED_ACCOUNTS_DATA_SIZE_LIMIT;
     149           6 :     }
     150          42 :     ctx->loaded_accounts_data_size_limit = 
     151          42 :       fd_ulong_min( FD_VM_LOADED_ACCOUNTS_DATA_SIZE_LIMIT, updated_loaded_accounts_data_size_limit );
     152          42 :   }
     153             : 
     154        6111 :   return FD_RUNTIME_EXECUTE_SUCCESS;
     155        6117 : }
     156             : 
     157             : 
     158         543 : int fd_compute_budget_program_execute( fd_exec_instr_ctx_t * ctx ) {
     159         543 :   FD_EXEC_CU_UPDATE( ctx, DEFAULT_COMPUTE_UNITS );
     160         519 :   return FD_EXECUTOR_INSTR_SUCCESS;
     161         543 : }

Generated by: LCOV version 1.14