LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_cost_tracker.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 9 35 25.7 %
Date: 2025-12-28 05:17:03 Functions: 0 76 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_executor.h"
      11             : #include "fd_runtime_err.h"
      12             : #include "../../disco/pack/fd_pack.h" /* TODO: Layering violation */
      13             : #include "../../disco/pack/fd_pack_cost.h"
      14             : 
      15             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L62-L79 */
      16             : 
      17          45 : #define FD_WRITE_LOCK_UNITS                   (      300UL) /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/block_cost_limits.rs#L20 */
      18             : #define FD_MAX_BLOCK_ACCOUNTS_DATA_SIZE_DELTA (100000000UL) /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/block_cost_limits.rs#L42 */
      19          27 : #define FD_MAX_WRITABLE_ACCOUNT_UNITS         ( 12000000UL) /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/block_cost_limits.rs#L34 */
      20          27 : #define FD_MAX_BLOCK_UNITS_SIMD_0207          ( 50000000UL) /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/block_cost_limits.rs#L50-L56 */
      21           0 : #define FD_MAX_BLOCK_UNITS_SIMD_0256          ( 60000000UL) /* https://github.com/anza-xyz/agave/blob/v2.3.0/cost-model/src/block_cost_limits.rs#L50-L56 */
      22          45 : #define FD_MAX_BLOCK_UNITS_SIMD_0286          (100000000UL) /* https://github.com/anza-xyz/agave/blob/v3.0.0/cost-model/src/block_cost_limits.rs#L30 */
      23          27 : #define FD_MAX_VOTE_UNITS                     ( 36000000UL) /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/block_cost_limits.rs#L38 */
      24             : 
      25             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L18-L33 */
      26           0 : #define FD_COST_TRACKER_SUCCESS                                     (0)
      27           0 : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_BLOCK_MAX_LIMIT          (1)
      28           0 : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_VOTE_MAX_LIMIT           (2)
      29           0 : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_MAX_LIMIT        (3)
      30           0 : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT (4)
      31             : #define FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT (5)
      32             : 
      33             : /* A reasonably tight bound can be derived based on CUs.  The most
      34             :    optimal use of CUs is to pack as many writable accounts as possible
      35             :    for as cheaply as possible.  This means we should try to pack as many
      36             :    writable accounts as possible into each transaction.  Each
      37             :    transaction requires at least one signature.  We will assume that all
      38             :    of these accounts have no account data.
      39             : 
      40             :    64 - Max number of accounts per transaction.  In this case we will
      41             :    assume that all of these accounts are writable and have no data.
      42             :    100000000 - CUs per slot
      43             :    720 - Cost of a signature
      44             :    300 - Cost of a writable account write lock
      45             : 
      46             :    We can have (100000000 / (720 + 64 * 300)) = 5020 transactions per
      47             :    slot with maximum writable account utilization.
      48             : 
      49             :    So, 5020 transactions per slot * 64 accounts per transaction =
      50             :    321280 writable accounts per slot.
      51             : 
      52             :    NOTE: A slightly tighter bound can probably be derived. */
      53             : 
      54          30 : #define FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_SLOT ( \
      55          30 :   FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_TRANSACTION * (FD_MAX_BLOCK_UNITS_SIMD_0286 / ( FD_WRITE_LOCK_UNITS * FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_TRANSACTION + FD_PACK_COST_PER_SIGNATURE)) )
      56             : FD_STATIC_ASSERT( FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_SLOT==321280UL, "Incorrect FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_SLOT" );
      57             : 
      58             : /* TODO: Extremely gross.  Used because these are in a pool which needs
      59             :    to be compile time sized T. */
      60             : #define FD_COST_TRACKER_CHAIN_CNT_EST (262144UL)
      61             : #define FD_COST_TRACKER_FOOTPRINT                                                                   \
      62             :   ( FD_LAYOUT_FINI( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND(         \
      63             :     FD_LAYOUT_INIT,                                                                                 \
      64             :       128UL /* alignof(fd_cost_tracker_t) */,  128UL /* sizeof(fd_cost_tracker_t) */          ),    \
      65             :       128UL /* alignof(cost_tracker_out_t )*/, 128UL /* sizeof(cost_tracker_out_t ) */        ),    \
      66             :       8UL   /* alignof(account_cost_map_t) */, FD_COST_TRACKER_CHAIN_CNT_EST*8UL /*sizeof(ulong)*/ +24UL /* sizeof(account_cost_map_t) */ ), \
      67             :       8UL   /* alignof(account_cost_t) */,     FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_SLOT*48UL /*sizeof(account_cost_t)*/ ), \
      68             :       128UL ) )                                               \
      69             : 
      70          21 : #define FD_COST_TRACKER_MAGIC (0xF17EDA2CE7C05170UL) /* FIREDANCER COST V0 */
      71             : 
      72         111 : #define FD_COST_TRACKER_ALIGN (128UL)
      73             : 
      74             : struct __attribute__((aligned(FD_COST_TRACKER_ALIGN))) fd_cost_tracker {
      75             :   ulong block_cost;
      76             :   ulong vote_cost;
      77             :   ulong allocated_accounts_data_size;
      78             : 
      79             :   ulong block_cost_limit;
      80             :   ulong vote_cost_limit;
      81             :   ulong account_cost_limit;
      82             : 
      83             :   int larger_max_cost_per_block;
      84             : };
      85             : 
      86             : typedef struct fd_cost_tracker fd_cost_tracker_t;
      87             : 
      88             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/transaction_cost.rs#L153-L161 */
      89             : 
      90             : struct fd_usage_cost_details {
      91             :   ulong signature_cost;
      92             :   ulong write_lock_cost;
      93             :   ulong data_bytes_cost;
      94             :   ulong programs_execution_cost;
      95             :   ulong loaded_accounts_data_size_cost;
      96             :   ulong allocated_accounts_data_size;
      97             : };
      98             : typedef struct fd_usage_cost_details fd_usage_cost_details_t;
      99             : 
     100             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/transaction_cost.rs#L20-L23 */
     101             : 
     102             : struct fd_transaction_cost {
     103             :   uint type; /* FD_TXN_COST_TYPE_* */
     104             :   union {
     105             :     fd_usage_cost_details_t transaction;
     106             :   };
     107             : };
     108             : 
     109             : typedef struct fd_transaction_cost fd_transaction_cost_t;
     110             : 
     111           0 : #define FD_TXN_COST_TYPE_SIMPLE_VOTE 0U
     112           0 : #define FD_TXN_COST_TYPE_TRANSACTION 1U
     113             : 
     114             : FD_PROTOTYPES_BEGIN
     115             : 
     116             : static inline int
     117           0 : fd_cost_tracker_err_to_runtime_err( int err ) {
     118           0 :   switch( err ) {
     119           0 :     case FD_COST_TRACKER_SUCCESS:
     120           0 :       return FD_RUNTIME_EXECUTE_SUCCESS;
     121           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_BLOCK_MAX_LIMIT:
     122           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_MAX_BLOCK_COST_LIMIT;
     123           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_VOTE_MAX_LIMIT:
     124           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_MAX_VOTE_COST_LIMIT;
     125           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_MAX_LIMIT:
     126           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_MAX_ACCOUNT_COST_LIMIT;
     127           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT:
     128           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT;
     129           0 :     case FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT:
     130           0 :       return FD_RUNTIME_TXN_ERR_WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT;
     131           0 :     default:
     132           0 :       __builtin_unreachable();
     133           0 :   }
     134           0 : }
     135             : 
     136             : FD_FN_CONST ulong
     137             : fd_cost_tracker_align( void );
     138             : 
     139             : FD_FN_CONST ulong
     140             : fd_cost_tracker_footprint( void );
     141             : 
     142             : void *
     143             : fd_cost_tracker_new( void * shmem,
     144             :                      int    larger_max_cost_per_block,
     145             :                      ulong  seed );
     146             : 
     147             : fd_cost_tracker_t *
     148             : fd_cost_tracker_join( void * shct );
     149             : 
     150             : void
     151             : fd_cost_tracker_init( fd_cost_tracker_t *   cost_tracker,
     152             :                       fd_features_t const * features,
     153             :                       ulong                 slot );
     154             : 
     155             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L323-L328 */
     156             : FD_FN_PURE ulong
     157             : fd_cost_tracker_calculate_loaded_accounts_data_size_cost( fd_txn_out_t const * txn_out );
     158             : 
     159             : /* fd_cost_tracker_calculate_cost_and_add takes a transaction,
     160             :    calculates the cost of the transaction in terms of various block
     161             :    level limits and adds it to the cost tracker.  If the incremental
     162             :    transaction fits in the block, then the cost tracking is updated and
     163             :    FD_COST_TRACKER_SUCCESS is returned.  If the transaction does not
     164             :    fit then FD_COST_TRACKER_ERROR_{*} is returned depending on what
     165             :    limit is violated.
     166             : 
     167             :    This function assumes that the caller is responsible for managing
     168             :    concurrent callers.
     169             : 
     170             :    This function represents the combination of Agave client functions:
     171             :    `CostModel::calculate_cost_for_executed_transaction()` and
     172             :    `CostTracker::try_add()`.
     173             : 
     174             :     https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L69-L95
     175             :     https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L163-L173 */
     176             : 
     177             : int
     178             : fd_cost_tracker_calculate_cost_and_add( fd_cost_tracker_t * cost_tracker,
     179             :                                         fd_bank_t *         bank,
     180             :                                         fd_txn_in_t const * txn_in,
     181             :                                         fd_txn_out_t *      txn_out );
     182             : 
     183             : FD_PROTOTYPES_END
     184             : 
     185             : #endif /* HEADER_fd_src_flamenco_runtime_fd_cost_tracker_h */

Generated by: LCOV version 1.14