LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_cost_harness.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 60 0.0 %
Date: 2026-05-31 08:07:40 Functions: 0 1 0.0 %

          Line data    Source code
       1             : #include "fd_cost_harness.h"
       2             : #include "fd_solfuzz_private.h"
       3             : #include "fd_txn_harness.h"
       4             : 
       5             : #include "../fd_cost_tracker.h"
       6             : #include "../program/fd_compute_budget_program.h"
       7             : 
       8             : int
       9             : fd_solfuzz_pb_cost_run( fd_solfuzz_runner_t *               runner,
      10             :                         fd_exec_test_cost_context_t const * input,
      11           0 :                         fd_exec_test_cost_result_t *        output ) {
      12           0 :   if( FD_UNLIKELY( !input->has_tx || !input->has_features ) ) return 0;
      13             : 
      14           0 :   int ok = 0;
      15             : 
      16           0 :   fd_banks_clear_bank( runner->banks, runner->bank, 64UL );
      17           0 :   runner->bank->f.slot = 1UL;
      18           0 :   FD_TEST( fd_solfuzz_pb_restore_features( &runner->bank->f.features, &input->features ) );
      19             : 
      20           0 :   fd_txn_p_t * txn_p = fd_spad_alloc( runner->spad, alignof(fd_txn_p_t), sizeof(fd_txn_p_t) );
      21           0 :   ulong txn_sz = fd_solfuzz_pb_txn_serialize( txn_p->payload, &input->tx );
      22           0 :   if( FD_UNLIKELY( txn_sz==ULONG_MAX ) ) return 0;
      23             : 
      24           0 :   txn_p->payload_sz = txn_sz;
      25           0 :   if( FD_UNLIKELY( !fd_txn_parse( txn_p->payload, txn_p->payload_sz, TXN( txn_p ), NULL ) ) ) {
      26           0 :     return 0;
      27           0 :   }
      28             : 
      29           0 :   fd_txn_in_t txn_in = {0};
      30           0 :   txn_in.txn = txn_p;
      31             : 
      32           0 :   fd_txn_out_t txn_out = {0};
      33           0 :   fd_compute_budget_details_new( &txn_out.details.compute_budget );
      34           0 :   txn_out.details.loaded_accounts_data_size = txn_out.details.compute_budget.loaded_accounts_data_size_limit;
      35           0 :   txn_out.details.is_simple_vote = fd_txn_is_simple_vote_transaction( TXN( txn_p ), txn_p->payload );
      36             : 
      37           0 :   int err = fd_executor_compute_budget_program_execute_instructions( runner->bank, &txn_in, &txn_out );
      38           0 :   if( FD_LIKELY( !err ) ) err = fd_sanitize_compute_unit_limits( &txn_out );
      39           0 :   if( FD_UNLIKELY( err ) ) return 0;
      40             : 
      41           0 :   if( input->mode==FD_EXEC_TEST_TXN_COST_MODE_ACTUAL ) {
      42           0 :     ulong actual_cost = (ulong)input->actual_programs_execution_cost;
      43           0 :     ulong limit = txn_out.details.compute_budget.compute_unit_limit;
      44           0 :     txn_out.details.compute_budget.compute_meter = fd_ulong_sat_sub( limit, fd_ulong_min( actual_cost, limit ) );
      45           0 :     txn_out.details.loaded_accounts_data_size = (ulong)input->actual_loaded_accounts_data_size_bytes;
      46           0 :   } else {
      47             :     /* In ESTIMATE mode, programs_execution_cost = compute_unit_limit (see
      48             :        agave cost_model.rs:get_estimated_execution_cost). fd_cost_tracker
      49             :        computes programs_execution_cost as (limit - compute_meter), so zero
      50             :        the meter here to yield the full limit. */
      51           0 :     txn_out.details.compute_budget.compute_meter = 0UL;
      52           0 :     txn_out.details.loaded_accounts_data_size = txn_out.details.compute_budget.loaded_accounts_data_size_limit;
      53           0 :   }
      54             : 
      55           0 :   fd_cost_tracker_calculate_cost( runner->bank, &txn_in, &txn_out );
      56             : 
      57             :   /* In ACTUAL mode agave passes actual_programs_execution_cost through
      58             :      without clamping to compute_unit_limit (see agave cost_model.rs:
      59             :      calculate_cost_for_executed_transaction). The (limit - meter)
      60             :      formula in fd_cost_tracker inherently clamps, so overwrite with the
      61             :      raw actual value here for parity. */
      62           0 :   if( input->mode==FD_EXEC_TEST_TXN_COST_MODE_ACTUAL &&
      63           0 :       txn_out.details.txn_cost.type==FD_TXN_COST_TYPE_TRANSACTION ) {
      64           0 :     txn_out.details.txn_cost.transaction.programs_execution_cost = input->actual_programs_execution_cost;
      65           0 :   }
      66             : 
      67           0 :   *output = (fd_exec_test_cost_result_t)FD_EXEC_TEST_COST_RESULT_INIT_ZERO;
      68           0 :   output->has_cost = 1;
      69           0 :   if( txn_out.details.txn_cost.type==FD_TXN_COST_TYPE_TRANSACTION ) {
      70           0 :     output->signature_cost = txn_out.details.txn_cost.transaction.signature_cost;
      71           0 :     output->write_lock_cost = txn_out.details.txn_cost.transaction.write_lock_cost;
      72           0 :     output->data_bytes_cost = txn_out.details.txn_cost.transaction.data_bytes_cost;
      73           0 :     output->programs_execution_cost = txn_out.details.txn_cost.transaction.programs_execution_cost;
      74           0 :     output->loaded_accounts_data_size_cost = txn_out.details.txn_cost.transaction.loaded_accounts_data_size_cost;
      75           0 :     output->allocated_accounts_data_size = txn_out.details.txn_cost.transaction.allocated_accounts_data_size;
      76           0 :   } else {
      77             :     /* Simple-vote branch: proto CostResult fields have to match agave's
      78             :        TransactionCost::SimpleVote component-wise (cost-model/src/
      79             :        transaction_cost.rs:48-51 and :86-93). The 2100 here is
      80             :        solana_vote_program::vote_processor::DEFAULT_COMPUTE_UNITS --
      81             :        the vote program's per-invocation cost. Components sum to
      82             :        FD_SIMPLE_VOTE_USAGE_COST (3428). */
      83           0 :     output->signature_cost = FD_PACK_COST_PER_SIGNATURE;
      84           0 :     output->write_lock_cost = FD_WRITE_LOCK_UNITS * 2UL;
      85           0 :     output->data_bytes_cost = 0UL;
      86           0 :     output->programs_execution_cost = 2100UL;
      87           0 :     output->loaded_accounts_data_size_cost = 8UL;
      88           0 :     output->allocated_accounts_data_size = 0UL;
      89           0 :   }
      90             :   /* Saturating add to match agave's UsageCostDetails::sum (transaction_cost.rs:
      91             :      saturating_add chain). Plain + wraps on u64::MAX inputs (e.g. adversarial
      92             :      actual_programs_execution_cost = u64::MAX). */
      93           0 :   output->total_cost = fd_ulong_sat_add( output->signature_cost, output->write_lock_cost );
      94           0 :   output->total_cost = fd_ulong_sat_add( output->total_cost, output->data_bytes_cost );
      95           0 :   output->total_cost = fd_ulong_sat_add( output->total_cost, output->programs_execution_cost );
      96           0 :   output->total_cost = fd_ulong_sat_add( output->total_cost, output->loaded_accounts_data_size_cost );
      97           0 :   ok = 1;
      98             : 
      99           0 :   return ok;
     100           0 : }

Generated by: LCOV version 1.14