LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_cost_tracker.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 256 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 14 0.0 %

          Line data    Source code
       1             : #include "fd_cost_tracker.h"
       2             : 
       3             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L323-L328 */
       4             : FD_FN_PURE static inline ulong
       5           0 : calculate_loaded_accounts_data_size_cost( fd_exec_txn_ctx_t const * txn_ctx ) {
       6           0 :   ulong cost = fd_ulong_sat_sub( fd_ulong_sat_add( txn_ctx->loaded_accounts_data_size,
       7           0 :                                                    FD_ACCOUNT_DATA_COST_PAGE_SIZE ),
       8           0 :                                  1UL );
       9           0 :   cost /= FD_ACCOUNT_DATA_COST_PAGE_SIZE;
      10           0 :   return fd_ulong_sat_mul( cost, FD_VM_HEAP_COST );
      11           0 : }
      12             : 
      13             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L313-L321 */
      14             : FD_FN_PURE static inline ulong
      15           0 : get_instructions_data_cost( fd_exec_txn_ctx_t const * txn_ctx ) {
      16           0 :   ulong total_instr_data_sz = 0UL;
      17           0 :   for( ushort i=0; i<txn_ctx->txn_descriptor->instr_cnt; i++ ) {
      18           0 :     total_instr_data_sz += txn_ctx->txn_descriptor->instr[ i ].data_sz;
      19           0 :   }
      20           0 :   return total_instr_data_sz / FD_PACK_INV_COST_PER_INSTR_DATA_BYTE;
      21           0 : }
      22             : 
      23             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L152-L187 */
      24             : FD_FN_PURE static inline ulong
      25           0 : get_signature_cost( fd_exec_txn_ctx_t const * txn_ctx ) {
      26           0 :   fd_txn_t const *       txn      = txn_ctx->txn_descriptor;
      27           0 :   void const *           payload  = txn_ctx->_txn_raw->raw;
      28           0 :   fd_acct_addr_t const * accounts = fd_txn_get_acct_addrs( txn, payload );
      29             : 
      30             :   /* Compute signature counts (both normal + precompile)
      31             :      TODO: Factor this logic out into a shared function that can be used both here and in fd_pack_cost.h */
      32           0 :   ulong signature_cost                       = fd_ulong_sat_mul( txn->signature_cnt, FD_PACK_COST_PER_SIGNATURE );
      33           0 :   ulong num_secp256k1_instruction_signatures = 0UL;
      34           0 :   ulong num_ed25519_instruction_signatures   = 0UL;
      35           0 :   ulong num_secp256r1_instruction_signatures = 0UL;
      36             : 
      37           0 :   for( ushort i=0; i<txn->instr_cnt; i++ ) {
      38           0 :     fd_txn_instr_t const * instr = &txn->instr[ i ];
      39           0 :     if( instr->data_sz==0UL ) continue;
      40             : 
      41           0 :     fd_acct_addr_t const * prog_id    = accounts + instr->program_id;
      42           0 :     uchar const *          instr_data = fd_txn_get_instr_data( instr, payload );
      43             : 
      44           0 :     if( fd_memeq( prog_id, fd_solana_ed25519_sig_verify_program_id.key, sizeof(fd_pubkey_t) ) ) {
      45           0 :       num_ed25519_instruction_signatures += (ulong)instr_data[ 0 ];
      46           0 :     } else if( fd_memeq( prog_id, fd_solana_keccak_secp_256k_program_id.key, sizeof(fd_pubkey_t) ) ) {
      47           0 :       num_secp256k1_instruction_signatures += (ulong)instr_data[ 0 ];
      48           0 :     } else if( fd_memeq( prog_id, fd_solana_secp256r1_program_id.key, sizeof(fd_pubkey_t) ) ) {
      49           0 :       num_secp256r1_instruction_signatures += (ulong)instr_data[ 0 ];
      50           0 :     }
      51           0 :   }
      52             : 
      53             :   /* No direct permalink, just factored out for readability */
      54           0 :   ulong secp256k1_verify_cost = fd_ulong_sat_mul( FD_PACK_COST_PER_SECP256K1_SIGNATURE, num_secp256k1_instruction_signatures );
      55             : 
      56             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L155-L160 */
      57           0 :   ulong ed25519_verify_cost;
      58           0 :   if( FD_FEATURE_ACTIVE( txn_ctx->slot, txn_ctx->features, ed25519_precompile_verify_strict ) ) {
      59           0 :     ed25519_verify_cost = fd_ulong_sat_mul( FD_PACK_COST_PER_ED25519_SIGNATURE, num_ed25519_instruction_signatures );
      60           0 :   } else {
      61           0 :     ed25519_verify_cost = fd_ulong_sat_mul( FD_PACK_COST_PER_NON_STRICT_ED25519_SIGNATURE, num_ed25519_instruction_signatures );
      62           0 :   }
      63             : 
      64             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L162-L167 */
      65           0 :   ulong secp256r1_verify_cost = 0UL;
      66           0 :   if( FD_FEATURE_ACTIVE( txn_ctx->slot, txn_ctx->features, enable_secp256r1_precompile ) ) {
      67           0 :     secp256r1_verify_cost = fd_ulong_sat_mul( FD_PACK_COST_PER_SECP256R1_SIGNATURE, num_secp256r1_instruction_signatures );
      68           0 :   }
      69             : 
      70             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L169-L186 */
      71           0 :   return fd_ulong_sat_add( signature_cost,
      72           0 :                            fd_ulong_sat_add( secp256k1_verify_cost,
      73           0 :                                              fd_ulong_sat_add( ed25519_verify_cost,
      74           0 :                                                                secp256r1_verify_cost ) ) );
      75           0 : }
      76             : 
      77             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L190-L192 */
      78             : FD_FN_PURE static inline ulong
      79           0 : get_write_lock_cost( ulong num_write_locks ) {
      80           0 :   return fd_ulong_sat_mul( num_write_locks, FD_WRITE_LOCK_UNITS );
      81           0 : }
      82             : 
      83             : /* Loop through all instructions here and deserialize the instruction data to try to determine any
      84             :    system program allocations done.
      85             : 
      86             :    https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L367-L386 */
      87             : static inline ulong
      88             : calculate_allocated_accounts_data_size( fd_exec_txn_ctx_t const * txn_ctx,
      89           0 :                                         fd_spad_t *               spad ) {
      90           0 :   FD_SPAD_FRAME_BEGIN( spad ) {
      91           0 :     fd_txn_t const * txn     = txn_ctx->txn_descriptor;
      92           0 :     void const *     payload = txn_ctx->_txn_raw->raw;
      93             : 
      94           0 :     ulong allocated_accounts_data_size = 0UL;
      95           0 :     for( ushort i=0UL; i<txn->instr_cnt; i++ ) {
      96           0 :       fd_txn_instr_t const * instr      = &txn->instr[ i ];
      97           0 :       fd_acct_addr_t const * accounts   = fd_txn_get_acct_addrs( txn, payload );
      98           0 :       fd_acct_addr_t const * prog_id    = accounts + instr->program_id;
      99           0 :       uchar const *          instr_data = fd_txn_get_instr_data( instr, payload );
     100             : 
     101           0 :       if( instr->data_sz==0UL || !fd_memeq( prog_id, &fd_solana_system_program_id, sizeof(fd_pubkey_t) ) ) continue;
     102             : 
     103           0 :       fd_bincode_decode_ctx_t decode = {
     104           0 :         .data    = instr_data,
     105           0 :         .dataend = instr_data + instr->data_sz
     106           0 :       };
     107             : 
     108           0 :       ulong total_sz   = 0UL;
     109           0 :       int   decode_err = fd_system_program_instruction_decode_footprint( &decode, &total_sz );
     110           0 :       if( FD_UNLIKELY( decode_err ) ) continue;
     111             : 
     112           0 :       uchar * mem = fd_spad_alloc( spad, fd_system_program_instruction_align(), total_sz );
     113           0 :       if( FD_UNLIKELY( !mem ) ) {
     114           0 :         FD_LOG_ERR(( "Unable to allocate memory for system program instruction" ));
     115           0 :       }
     116             : 
     117             :       /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L330-L346 */
     118           0 :       fd_system_program_instruction_t * instruction = fd_system_program_instruction_decode( mem, &decode );
     119           0 :       ulong                             space       = 0UL;
     120             : 
     121           0 :       switch( instruction->discriminant ) {
     122           0 :         case fd_system_program_instruction_enum_create_account: {
     123           0 :           space = instruction->inner.create_account.space;
     124           0 :           break;
     125           0 :         }
     126           0 :         case fd_system_program_instruction_enum_create_account_with_seed: {
     127           0 :           space = instruction->inner.create_account_with_seed.space;
     128           0 :           break;
     129           0 :         }
     130           0 :         case fd_system_program_instruction_enum_allocate: {
     131           0 :           space = instruction->inner.allocate;
     132           0 :           break;
     133           0 :         }
     134           0 :         case fd_system_program_instruction_enum_allocate_with_seed: {
     135           0 :           space = instruction->inner.allocate_with_seed.space;
     136           0 :           break;
     137           0 :         }
     138           0 :       }
     139             : 
     140             :       /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L373-L380 */
     141           0 :       if( FD_UNLIKELY( space>FD_ACC_SZ_MAX ) ) return 0UL;
     142             : 
     143           0 :       allocated_accounts_data_size = fd_ulong_sat_add( allocated_accounts_data_size, space );
     144           0 :     }
     145             : 
     146             :     /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L396-L397 */
     147           0 :     return fd_ulong_min( 2UL*FD_ACC_SZ_MAX, allocated_accounts_data_size );
     148           0 :   } FD_SPAD_FRAME_END;
     149           0 : }
     150             : 
     151             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L123-L149 */
     152             : static inline fd_transaction_cost_t
     153             : calculate_non_vote_transaction_cost( fd_exec_txn_ctx_t const * txn_ctx,
     154             :                                      ulong                     loaded_accounts_data_size_cost,
     155             :                                      ulong                     data_bytes_cost,
     156           0 :                                      fd_spad_t *               spad ) {
     157             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L132 */
     158           0 :   ulong signature_cost = get_signature_cost( txn_ctx );
     159             : 
     160             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L133 */
     161           0 :   ulong write_lock_cost = get_write_lock_cost( fd_txn_account_cnt( txn_ctx->txn_descriptor, FD_TXN_ACCT_CAT_WRITABLE ) );
     162             : 
     163             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L135-L136 */
     164           0 :   ulong allocated_accounts_data_size = calculate_allocated_accounts_data_size( txn_ctx, spad );
     165             : 
     166           0 :   return (fd_transaction_cost_t){ .discriminant = fd_transaction_cost_enum_transaction,
     167           0 :                                   .inner = {
     168           0 :                                     .transaction = {
     169           0 :                                       .signature_cost                 = signature_cost,
     170           0 :                                       .write_lock_cost                = write_lock_cost,
     171           0 :                                       .data_bytes_cost                = data_bytes_cost,
     172           0 :                                       .programs_execution_cost        = fd_ulong_sat_sub( txn_ctx->compute_unit_limit,
     173           0 :                                                                                           txn_ctx->compute_meter ),
     174           0 :                                       .loaded_accounts_data_size_cost = loaded_accounts_data_size_cost,
     175           0 :                                       .allocated_accounts_data_size   = allocated_accounts_data_size,
     176           0 :                                     }
     177           0 :                                   }
     178           0 :                                 };
     179           0 : }
     180             : 
     181             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/transaction_cost.rs#L26-L42 */
     182             : FD_FN_PURE static inline ulong
     183           0 : transaction_cost_sum( fd_transaction_cost_t const * self ) {
     184           0 :   switch( self->discriminant ) {
     185           0 :     case fd_transaction_cost_enum_simple_vote: {
     186             :       /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/transaction_cost.rs#L38 */
     187           0 :       return FD_PACK_SIMPLE_VOTE_COST;
     188           0 :     }
     189           0 :     case fd_transaction_cost_enum_transaction: {
     190             :       /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/transaction_cost.rs#L164-L171 */
     191           0 :       fd_usage_cost_details_t const * usage_cost = &self->inner.transaction;
     192           0 :       ulong                           cost       = 0UL;
     193             : 
     194           0 :       cost = fd_ulong_sat_add( cost, usage_cost->signature_cost );
     195           0 :       cost = fd_ulong_sat_add( cost, usage_cost->write_lock_cost );
     196           0 :       cost = fd_ulong_sat_add( cost, usage_cost->data_bytes_cost );
     197           0 :       cost = fd_ulong_sat_add( cost, usage_cost->programs_execution_cost );
     198           0 :       cost = fd_ulong_sat_add( cost, usage_cost->loaded_accounts_data_size_cost );
     199             : 
     200           0 :       return cost;
     201           0 :     }
     202           0 :     default: {
     203           0 :       __builtin_unreachable();
     204           0 :     }
     205           0 :   }
     206           0 : }
     207             : 
     208             : FD_FN_PURE static inline ulong
     209           0 : get_allocated_accounts_data_size( fd_transaction_cost_t const * self ) {
     210           0 :   switch( self->discriminant ) {
     211           0 :     case fd_transaction_cost_enum_simple_vote: {
     212           0 :       return 0UL;
     213           0 :     }
     214           0 :     case fd_transaction_cost_enum_transaction: {
     215           0 :       return self->inner.transaction.allocated_accounts_data_size;
     216           0 :     }
     217           0 :     default: {
     218           0 :       __builtin_unreachable();
     219           0 :     }
     220           0 :   }
     221           0 : }
     222             : 
     223             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L277-L322 */
     224             : static inline int
     225             : would_fit( fd_cost_tracker_t const *     self,
     226             :            fd_exec_txn_ctx_t const *     txn_ctx,
     227           0 :            fd_transaction_cost_t const * tx_cost ) {
     228           0 :   fd_txn_t const * txn_descriptor = txn_ctx->txn_descriptor;
     229           0 :   void const *     payload        = txn_ctx->_txn_raw->raw;
     230             : 
     231             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L281 */
     232           0 :   ulong cost = transaction_cost_sum( tx_cost );
     233             : 
     234             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L283-L288 */
     235           0 :   if( fd_transaction_cost_is_simple_vote( tx_cost ) ) {
     236           0 :     if( FD_UNLIKELY( fd_ulong_sat_add( self->vote_cost, cost )>self->vote_cost_limit ) ) {
     237           0 :       return FD_COST_TRACKER_ERROR_WOULD_EXCEED_VOTE_MAX_LIMIT;
     238           0 :     }
     239           0 :   }
     240             : 
     241             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L290-L293 */
     242           0 :   if( FD_UNLIKELY( fd_ulong_sat_add( self->block_cost, cost )>self->block_cost_limit ) ) {
     243           0 :     return FD_COST_TRACKER_ERROR_WOULD_EXCEED_BLOCK_MAX_LIMIT;
     244           0 :   }
     245             : 
     246             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L295-L298 */
     247           0 :   if( FD_UNLIKELY( cost>self->account_cost_limit ) ) {
     248           0 :     return FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_MAX_LIMIT;
     249           0 :   }
     250             : 
     251             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L300-L301 */
     252           0 :   ulong allocated_accounts_data_size = fd_ulong_sat_add( self->allocated_accounts_data_size,
     253           0 :                                                          get_allocated_accounts_data_size( tx_cost ) );
     254             : 
     255             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L303-L304 */
     256           0 :   if( FD_UNLIKELY( allocated_accounts_data_size>FD_MAX_BLOCK_ACCOUNTS_DATA_SIZE_DELTA ) ) {
     257           0 :     return FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT;
     258           0 :   }
     259             : 
     260             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L308-L319 */
     261           0 :   fd_account_costs_pair_t_mapnode_t * pool         = self->cost_by_writable_accounts.account_costs_pool;
     262           0 :   fd_account_costs_pair_t_mapnode_t * root         = self->cost_by_writable_accounts.account_costs_root;
     263           0 :   fd_acct_addr_t const *              account_keys = fd_txn_get_acct_addrs( txn_descriptor, payload );
     264             : 
     265           0 :   for( fd_txn_acct_iter_t i=fd_txn_acct_iter_init( txn_descriptor, FD_TXN_ACCT_CAT_WRITABLE );
     266           0 :                           i!=fd_txn_acct_iter_end();
     267           0 :                           i=fd_txn_acct_iter_next( i ) ) {
     268           0 :     fd_acct_addr_t const * writable_acc = &account_keys[ fd_txn_acct_iter_idx( i ) ];
     269           0 :     fd_account_costs_pair_t_mapnode_t elem;
     270           0 :     fd_memcpy( &elem.elem.key, writable_acc, sizeof(fd_pubkey_t) );
     271             : 
     272           0 :     fd_account_costs_pair_t_mapnode_t * chained_cost = fd_account_costs_pair_t_map_find( pool, root, &elem );
     273           0 :     if( chained_cost ) {
     274           0 :       if( FD_UNLIKELY( fd_ulong_sat_add( chained_cost->elem.cost, cost )>self->account_cost_limit ) ) {
     275           0 :         return FD_COST_TRACKER_ERROR_WOULD_EXCEED_ACCOUNT_MAX_LIMIT;
     276           0 :       }
     277           0 :     }
     278           0 :   }
     279             : 
     280           0 :   return FD_COST_TRACKER_SUCCESS;
     281           0 : }
     282             : 
     283             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L352-L372 */
     284             : static inline void
     285             : add_transaction_execution_cost( fd_cost_tracker_t *           self,
     286             :                                 fd_exec_txn_ctx_t const *     txn_ctx,
     287             :                                 fd_transaction_cost_t const * tx_cost,
     288           0 :                                 ulong                         adjustment ) {
     289             : 
     290           0 :   fd_txn_t const *                     txn_descriptor = txn_ctx->txn_descriptor;
     291           0 :   void const *                         payload        = txn_ctx->_txn_raw->raw;
     292           0 :   fd_account_costs_pair_t_mapnode_t *  pool           = self->cost_by_writable_accounts.account_costs_pool;
     293           0 :   fd_account_costs_pair_t_mapnode_t ** root           = &self->cost_by_writable_accounts.account_costs_root;
     294           0 :   fd_acct_addr_t const *               account_keys   = fd_txn_get_acct_addrs( txn_descriptor, payload );
     295             : 
     296           0 :   for( fd_txn_acct_iter_t i=fd_txn_acct_iter_init( txn_descriptor, FD_TXN_ACCT_CAT_WRITABLE );
     297           0 :                           i!=fd_txn_acct_iter_end();
     298           0 :                           i=fd_txn_acct_iter_next( i ) ) {
     299           0 :     fd_acct_addr_t const * writable_acc = &account_keys[ fd_txn_acct_iter_idx( i ) ];
     300           0 :     fd_account_costs_pair_t_mapnode_t elem;
     301           0 :     fd_memcpy( &elem.elem.key, writable_acc, sizeof(fd_pubkey_t) );
     302             : 
     303           0 :     fd_account_costs_pair_t_mapnode_t * account_cost = fd_account_costs_pair_t_map_find( pool, *root, &elem );
     304           0 :     if( account_cost==NULL ) {
     305           0 :       account_cost = fd_account_costs_pair_t_map_acquire( pool );
     306           0 :       fd_memcpy( &account_cost->elem.key, writable_acc, sizeof(fd_pubkey_t) );
     307           0 :       account_cost->elem.cost = adjustment;
     308           0 :       fd_account_costs_pair_t_map_insert( pool, root, account_cost );
     309           0 :     } else {
     310           0 :       account_cost->elem.cost = fd_ulong_sat_add( account_cost->elem.cost, adjustment );
     311           0 :     }
     312           0 :   }
     313             : 
     314           0 :   self->block_cost = fd_ulong_sat_add( self->block_cost, adjustment );
     315           0 :   if( fd_transaction_cost_is_simple_vote( tx_cost ) ) {
     316           0 :     self->vote_cost = fd_ulong_sat_add( self->vote_cost, adjustment );
     317           0 :   }
     318           0 : }
     319             : 
     320             : /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L325-L335 */
     321             : static inline void
     322             : add_transaction_cost( fd_cost_tracker_t *           self,
     323             :                       fd_exec_txn_ctx_t const *     txn_ctx,
     324           0 :                       fd_transaction_cost_t const * tx_cost ) {
     325             :   /* Note: We purposely omit signature counts updates since they're not relevant to cost calculations right now. */
     326           0 :   self->allocated_accounts_data_size += get_allocated_accounts_data_size( tx_cost );
     327           0 :   self->transaction_count++;
     328           0 :   add_transaction_execution_cost( self, txn_ctx, tx_cost, transaction_cost_sum( tx_cost ) );
     329           0 : }
     330             : 
     331             : /** PUBLIC FUNCTIONS ***/
     332             : 
     333             : void
     334             : fd_cost_tracker_init( fd_cost_tracker_t *        self,
     335             :                       fd_exec_slot_ctx_t const * slot_ctx,
     336           0 :                       fd_spad_t *                spad ) {
     337             :   // Set limits appropriately
     338           0 :   self->account_cost_limit = FD_MAX_WRITABLE_ACCOUNT_UNITS;
     339           0 :   self->block_cost_limit   = FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, raise_block_limits_to_50m ) ? FD_MAX_BLOCK_UNITS_SIMD_0207 : FD_MAX_BLOCK_UNITS;
     340           0 :   self->vote_cost_limit    = FD_MAX_VOTE_UNITS;
     341             : 
     342             :   /* Init cost tracker map
     343             :      TODO: The maximum number of accounts within a block needs to be bounded out properly. It's currently
     344             :      hardcoded here at 4096*1024 accounts. */
     345           0 :   self->cost_by_writable_accounts.account_costs_root = NULL;
     346           0 :   uchar * pool_mem                                   = fd_spad_alloc( spad, fd_account_costs_pair_t_map_align(), fd_account_costs_pair_t_map_footprint( FD_WRITABLE_ACCOUNTS_PER_BLOCK * 1024UL ) );
     347           0 :   self->cost_by_writable_accounts.account_costs_pool = fd_account_costs_pair_t_map_join( fd_account_costs_pair_t_map_new( pool_mem, FD_WRITABLE_ACCOUNTS_PER_BLOCK * 1024UL ) );
     348           0 :   if( FD_UNLIKELY( !self->cost_by_writable_accounts.account_costs_pool ) ) {
     349           0 :     FD_LOG_ERR(( "failed to allocate memory for cost tracker accounts pool" ));
     350           0 :   }
     351             : 
     352             :   // Reset aggregated stats for new block
     353           0 :   self->block_cost                            = 0UL;
     354           0 :   self->vote_cost                             = 0UL;
     355           0 :   self->transaction_count                     = 0UL;
     356           0 :   self->allocated_accounts_data_size          = 0UL;
     357           0 :   self->transaction_signature_count           = 0UL;
     358           0 :   self->secp256k1_instruction_signature_count = 0UL;
     359           0 :   self->ed25519_instruction_signature_count   = 0UL;
     360           0 :   self->secp256r1_instruction_signature_count = 0UL;
     361           0 : }
     362             : 
     363             : fd_transaction_cost_t
     364             : fd_calculate_cost_for_executed_transaction( fd_exec_txn_ctx_t const * txn_ctx,
     365           0 :                                             fd_spad_t *               spad ) {
     366             :   /* https://github.com/anza-xyz/agave/blob/v2.1.0/cost-model/src/cost_model.rs#L83-L85 */
     367           0 :   if( fd_txn_is_simple_vote_transaction( txn_ctx->txn_descriptor, txn_ctx->_txn_raw->raw ) ) {
     368           0 :     return (fd_transaction_cost_t){ .discriminant = fd_transaction_cost_enum_simple_vote };
     369           0 :   }
     370             : 
     371             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L78-L81 */
     372           0 :   ulong loaded_accounts_data_size_cost = calculate_loaded_accounts_data_size_cost( txn_ctx );
     373             : 
     374             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L82-L83 */
     375           0 :   ulong instructions_data_cost = get_instructions_data_cost( txn_ctx );
     376             : 
     377             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_model.rs#L85-L93 */
     378           0 :   return calculate_non_vote_transaction_cost( txn_ctx, loaded_accounts_data_size_cost, instructions_data_cost, spad );
     379           0 : }
     380             : 
     381             : int
     382             : fd_cost_tracker_try_add( fd_cost_tracker_t *           self,
     383             :                          fd_exec_txn_ctx_t const *     txn_ctx,
     384           0 :                          fd_transaction_cost_t const * tx_cost ) {
     385             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L167 */
     386           0 :   int err = would_fit( self, txn_ctx, tx_cost );
     387           0 :   if( FD_UNLIKELY( err ) ) return err;
     388             : 
     389             :   /* We don't need `updated_costliest_account_cost` since it seems to be for a different use case
     390             :      other than validating block cost limits.
     391             :      https://github.com/anza-xyz/agave/blob/v2.2.0/cost-model/src/cost_tracker.rs#L168 */
     392           0 :   add_transaction_cost( self, txn_ctx, tx_cost );
     393           0 :   return FD_COST_TRACKER_SUCCESS;
     394           0 : }

Generated by: LCOV version 1.14