LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_cost_tracker.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 5 25 20.0 %
Date: 2026-08-31 04:29:48 Functions: 0 154 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_fd_cost_tracker_h
       2             : #define HEADER_fd_src_flamenco_runtime_fd_cost_tracker_h
       3             : 
       4             : /* fd_cost_tracker_t is a block-level tracker for various limits
       5             :    including CU consumption, writable account usage, and account data
       6             :    size.  A cost is calculated per-transaction and is accumulated to the
       7             :    block.  If a block's limits are exceeded, then the block is marked as
       8             :    dead. */
       9             : 
      10             : #include "fd_runtime_err.h"
      11             : #include "fd_runtime_const.h"
      12             : #include "../../disco/pack/fd_pack_cost.h"
      13             : 
      14             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L62-L79 */
      15             : 
      16         414 : #define FD_WRITE_LOCK_UNITS (300U) /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/block_cost_limits.rs#L20 */
      17             : 
      18             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L18-L33 */
      19         504 : #define FD_COST_TRACKER_SUCCESS                                     (0)
      20           0 : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_BLOCK_MAX_LIMIT          (1)
      21           0 : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_MAX_LIMIT        (3)
      22           0 : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT (4)
      23           0 : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT (5)
      24             : 
      25             : FD_STATIC_ASSERT( FD_WRITE_LOCK_UNITS*FD_RUNTIME_MAX_TXN_ACC_WRITES_PER_SLOT +
      26             :                   FD_PACK_COST_PER_SIGNATURE*((FD_RUNTIME_MAX_TXN_ACC_WRITES_PER_SLOT+63UL)/64UL)<=87500000UL,
      27             :                   max_writable_accounts_per_slot_fits );
      28             : FD_STATIC_ASSERT( FD_WRITE_LOCK_UNITS*(FD_RUNTIME_MAX_TXN_ACC_WRITES_PER_SLOT+1UL) +
      29             :                   FD_PACK_COST_PER_SIGNATURE*((FD_RUNTIME_MAX_TXN_ACC_WRITES_PER_SLOT+64UL)/64UL)>87500000UL,
      30             :                   max_writable_accounts_per_slot_is_tight );
      31             : 
      32             : /* TODO: Extremely gross.  Used because these are in a pool which needs
      33             :    to be compile time sized T. */
      34             : 
      35             : /* The average mainnet block uses around 4200 distinct writable
      36             :    accounts. We size the cost tracker's account map at 8192 chains
      37             :    to give ~2x headroom over the observed average load. */
      38         816 : #define FD_COST_TRACKER_CHAIN_CNT_EST (8192UL)
      39             : #define FD_COST_TRACKER_FOOTPRINT                                                                   \
      40             :   ( FD_LAYOUT_FINI( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND(         \
      41             :     FD_LAYOUT_INIT,                                                                                 \
      42             :       128UL /* alignof(fd_cost_tracker_t) */,  128UL /* sizeof(fd_cost_tracker_t) */          ),    \
      43             :       128UL /* alignof(cost_tracker_out_t )*/, 128UL /* sizeof(cost_tracker_out_t ) */        ),    \
      44             :       8UL   /* alignof(account_cost_map_t) */, FD_COST_TRACKER_CHAIN_CNT_EST*4UL /*sizeof(uint)*/ +24UL /* sizeof(account_cost_map_t) */ ), \
      45             :       4UL   /* alignof(account_cost_t) */,     FD_RUNTIME_MAX_TXN_ACC_WRITES_PER_SLOT*40UL /*sizeof(account_cost_t)*/ ), \
      46             :       128UL ) )                                               \
      47             : 
      48         807 : #define FD_COST_TRACKER_MAGIC (0xF17EDA2CE7C05170UL) /* FIREDANCER COST V0 */
      49             : 
      50        2469 : #define FD_COST_TRACKER_ALIGN (128UL)
      51             : 
      52             : struct __attribute__((aligned(FD_COST_TRACKER_ALIGN))) fd_cost_tracker {
      53             :   ulong block_cost;
      54             :   ulong allocated_accounts_data_size;
      55             : 
      56             :   ulong block_cost_limit;
      57             :   ulong account_cost_limit;
      58             :   ulong data_size_limit;
      59             : 
      60             :   int larger_max_cost_per_block;
      61             : };
      62             : 
      63             : typedef struct fd_cost_tracker fd_cost_tracker_t;
      64             : 
      65             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/transaction_cost.rs#L153-L161 */
      66             : 
      67             : struct fd_usage_cost_details {
      68             :   uint  signature_cost;
      69             :   uint  write_lock_cost;
      70             :   uint  data_bytes_cost;
      71             :   uint  programs_execution_cost;
      72             :   uint  loaded_accounts_data_size_cost;
      73             :   ulong allocated_accounts_data_size;
      74             : };
      75             : typedef struct fd_usage_cost_details fd_usage_cost_details_t;
      76             : 
      77             : struct fd_transaction_cost {
      78             :   fd_usage_cost_details_t transaction;
      79             : };
      80             : 
      81             : typedef struct fd_transaction_cost fd_transaction_cost_t;
      82             : 
      83             : FD_PROTOTYPES_BEGIN
      84             : 
      85             : static inline int
      86           0 : fd_cost_tracker_err_to_runtime_err( int err ) {
      87           0 :   switch( err ) {
      88           0 :     case FD_COST_TRACKER_SUCCESS:
      89           0 :       return FD_RUNTIME_EXECUTE_SUCCESS;
      90           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_BLOCK_MAX_LIMIT:
      91           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_MAX_BLOCK_COST_LIMIT;
      92           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_MAX_LIMIT:
      93           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_MAX_ACCOUNT_COST_LIMIT;
      94           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT:
      95           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT;
      96           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT:
      97           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT;
      98           0 :     default:
      99           0 :       FD_LOG_CRIT(( "unexpected cost tracker error %d", err ));
     100           0 :   }
     101           0 : }
     102             : 
     103             : FD_FN_CONST ulong
     104             : fd_cost_tracker_align( void );
     105             : 
     106             : FD_FN_CONST ulong
     107             : fd_cost_tracker_footprint( void );
     108             : 
     109             : void *
     110             : fd_cost_tracker_new( void * shmem,
     111             :                      int    larger_max_cost_per_block,
     112             :                      ulong  seed );
     113             : 
     114             : fd_cost_tracker_t *
     115             : fd_cost_tracker_join( void * shct );
     116             : 
     117             : void
     118             : fd_cost_tracker_init( fd_cost_tracker_t *      cost_tracker,
     119             :                       fd_features_t const *    features,
     120             :                       fd_slot_params_t const * slot_params,
     121             :                       ulong                    slot );
     122             : 
     123             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L323-L328 */
     124             : FD_FN_PURE uint
     125             : fd_cost_tracker_calculate_loaded_accounts_data_size_cost( fd_txn_out_t const * txn_out );
     126             : 
     127             : /* fd_cost_tracker_calculate_cost_and_add takes a transaction,
     128             :    calculates the cost of the transaction in terms of various block
     129             :    level limits and adds it to the cost tracker.  If the incremental
     130             :    transaction fits in the block, then the cost tracking is updated and
     131             :    FD_COST_TRACKER_SUCCESS is returned.  If the transaction does not
     132             :    fit then FD_COST_TRACKER_ERROR_{*} is returned depending on what
     133             :    limit is violated.
     134             : 
     135             :    This function assumes that the caller is responsible for managing
     136             :    concurrent callers.
     137             : 
     138             :    This function represents the Agave client function:
     139             :    `CostModel::calculate_cost_for_executed_transaction()`
     140             : 
     141             :     https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L69-L95
     142             : */
     143             : 
     144             : void
     145             : fd_cost_tracker_calculate_cost( fd_bank_t *         bank,
     146             :                                 fd_txn_in_t const * txn_in,
     147             :                                 fd_txn_out_t *      txn_out );
     148             : 
     149             : /* fd_cost_tracker_try_add_cost takes the cost as calculated by
     150             :    fd_cost_tracker_calculate_cost and tries to accumulate it into the
     151             :    cost tracker.  If the cost fits, the cost is added and
     152             :    FD_COST_TRACKER_SUCCESS is returned.  If the cost does not fit, the
     153             :    cost will not be updated and FD_COST_TRACKER_ERROR_* is returned
     154             :    depending on what limit is violated.
     155             : 
     156             :    This function is the Agave client function: 'CostTracker::try_add()'
     157             :    https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L163-L173 */
     158             : 
     159             : int
     160             : fd_cost_tracker_try_add_cost( fd_cost_tracker_t * cost_tracker,
     161             :                               fd_txn_out_t *      txn_out );
     162             : 
     163             : FD_PROTOTYPES_END
     164             : 
     165             : #endif /* HEADER_fd_src_flamenco_runtime_fd_cost_tracker_h */

Generated by: LCOV version 1.14