Skip to content

Commit

Permalink
[WIP] fix pack cu calculation
Browse files Browse the repository at this point in the history
remove keccak, fix trailing whitespace

Addtl fixes
  • Loading branch information
jherrera-jump committed Feb 7, 2025
1 parent b6a460b commit c4f8a00
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 120 deletions.
2 changes: 1 addition & 1 deletion agave
2 changes: 1 addition & 1 deletion src/app/fdctl/external_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ extern void fd_ext_validator_main( const char ** args FD_PARAM_UNUSED ) {}
extern void fd_ext_genesis_main( const char ** args FD_PARAM_UNUSED ) {}

extern void * fd_ext_bank_pre_balance_info( void const * bank FD_PARAM_UNUSED, void * txns FD_PARAM_UNUSED, ulong txn_cnt FD_PARAM_UNUSED ) { return NULL; }
extern void * fd_ext_bank_load_and_execute_txns( void const * bank FD_PARAM_UNUSED, void * txns FD_PARAM_UNUSED, ulong txn_cnt FD_PARAM_UNUSED, int * out_load_results FD_PARAM_UNUSED, int * out_executing_results FD_PARAM_UNUSED, int * out_executed_results FD_PARAM_UNUSED, uint * out_consumed_cus FD_PARAM_UNUSED ) { return NULL; }
extern int fd_ext_bank_execute_and_commit_bundle( void const * bank FD_PARAM_UNUSED, void * txns FD_PARAM_UNUSED, ulong txn_cnt FD_PARAM_UNUSED, uint * out_consumed_cus FD_PARAM_UNUSED ) { return 0; }
extern void * fd_ext_bank_load_and_execute_txns( void const * bank FD_PARAM_UNUSED, void * txns FD_PARAM_UNUSED, ulong txn_cnt FD_PARAM_UNUSED, int * out_load_results FD_PARAM_UNUSED, int * out_executing_results FD_PARAM_UNUSED, int * out_executed_results FD_PARAM_UNUSED, uint * out_consumed_exec_cus FD_PARAM_UNUSED, uint * out_consumed_acct_data_cus FD_PARAM_UNUSED ) { return NULL; }
extern void fd_ext_bank_acquire( void const * bank FD_PARAM_UNUSED ) {}
extern void fd_ext_bank_release( void const * bank FD_PARAM_UNUSED ) {}
extern void fd_ext_bank_release_thunks( void * load_and_execute_output FD_PARAM_UNUSED ) {}
Expand Down
49 changes: 23 additions & 26 deletions src/app/fdctl/run/tiles/fd_bank.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ before_frag( fd_bank_ctx_t * ctx,
}

extern void * fd_ext_bank_pre_balance_info( void const * bank, void * txns, ulong txn_cnt );
extern void * fd_ext_bank_load_and_execute_txns( void const * bank, void * txns, ulong txn_cnt, int * out_processing_results, int * out_transaction_err, uint * out_consumed_cus );
extern int fd_ext_bank_execute_and_commit_bundle( void const * bank, void * txns, ulong txn_cnt, uint * out_consumed_cus );
extern void * fd_ext_bank_load_and_execute_txns( void const * bank, void * txns, ulong txn_cnt, int * out_processing_results, int * out_transaction_err, uint * out_consumed_exec_cus, uint * out_consumed_acct_data_cus );
extern void fd_ext_bank_commit_txns( void const * bank, void const * txns, ulong txn_cnt , void * load_and_execute_output, void * pre_balance_info );
extern void fd_ext_bank_release_thunks( void * load_and_execute_output );
extern void fd_ext_bank_release_pre_balance_info( void * pre_balance_info );
Expand Down Expand Up @@ -186,9 +186,10 @@ handle_microblock( fd_bank_ctx_t * ctx,

/* Just because a transaction was executed doesn't mean it succeeded,
but all executed transactions get committed. */
int processing_results[ MAX_TXN_PER_MICROBLOCK ] = { 0 };
int transaction_err [ MAX_TXN_PER_MICROBLOCK ] = { 0 };
uint consumed_cus [ MAX_TXN_PER_MICROBLOCK ] = { 0U };
int processing_results [ MAX_TXN_PER_MICROBLOCK ] = { 0 };
int transaction_err [ MAX_TXN_PER_MICROBLOCK ] = { 0 };
uint consumed_exec_cus [ MAX_TXN_PER_MICROBLOCK ] = { 0U };
uint consumed_acct_data_cus[ MAX_TXN_PER_MICROBLOCK ] = { 0U };

void * pre_balance_info = fd_ext_bank_pre_balance_info( ctx->_bank, ctx->txn_abi_mem, sanitized_txn_cnt );

Expand All @@ -197,17 +198,19 @@ handle_microblock( fd_bank_ctx_t * ctx,
sanitized_txn_cnt,
processing_results,
transaction_err,
consumed_cus );
consumed_exec_cus,
consumed_acct_data_cus );

ulong sanitized_idx = 0UL;
for( ulong i=0UL; i<txn_cnt; i++ ) {
fd_txn_p_t * txn = (fd_txn_p_t *)( dst + (i*sizeof(fd_txn_p_t)) );

uint requested_cus = txn->pack_cu.requested_execution_cus;
uint non_execution_cus = txn->pack_cu.non_execution_cus;
/* Assume failure, set below if success. If it doesn't land in the
uint requested_execution_cus = txn->pack_cu.requested_execution_cus;
uint requested_acct_data_cus = txn->pack_cu.requested_acct_data_cus;
uint non_execution_cus = txn->pack_cu.non_execution_cus;
/* Assume failure, set below if success. If it doesn't land cin the
block, rebate the non-execution CUs too. */
txn->bank_cu.rebated_cus = requested_cus + non_execution_cus;
txn->bank_cu.rebated_cus = requested_acct_data_cus + requested_execution_cus + non_execution_cus;
txn->flags &= ~FD_TXN_P_FLAGS_EXECUTE_SUCCESS;
if( FD_UNLIKELY( !(txn->flags & FD_TXN_P_FLAGS_SANITIZE_SUCCESS) ) ) continue;

Expand All @@ -234,23 +237,17 @@ handle_microblock( fd_bank_ctx_t * ctx,
if( transaction_err[ sanitized_idx-1UL ] ) ctx->metrics.exec_failed++;
else ctx->metrics.success++;

uint executed_cus = consumed_cus[ sanitized_idx-1UL ];
txn->bank_cu.actual_consumed_cus = non_execution_cus + executed_cus;
if( FD_UNLIKELY( executed_cus>requested_cus ) ) {
/* There's basically a bug in the Agave codebase right now
regarding the cost model for some transactions. Some built-in
instructions like creating an address lookup table consume more
CUs than the cost model allocates for them, which is only
allowed because the runtime computes requested CUs differently
from the cost model. Rather than implement a broken system,
we'll just permit the risk of slightly overpacking blocks by
ignoring these transactions when it comes to rebating. */
FD_LOG_INFO(( "Transaction executed %u CUs but only requested %u CUs", executed_cus, requested_cus ));
FD_MCNT_INC( BANK, COST_MODEL_UNDERCOUNT, 1UL );
txn->bank_cu.rebated_cus = 0U;
continue;
}
txn->bank_cu.rebated_cus = requested_cus - executed_cus;
uint actual_execution_cus = consumed_exec_cus[ sanitized_idx-1UL ];
uint actual_acct_data_cus = consumed_acct_data_cus[ sanitized_idx-1UL ];
txn->bank_cu.actual_consumed_cus = non_execution_cus + actual_execution_cus + actual_acct_data_cus;

/* The VM will stop executing and fail an instruction immediately if
it exceeds its requested CUs. A transaction which requests less
account data than it actually consumes will fail in the account
loading stage. */
FD_TEST( actual_execution_cus <= requested_execution_cus );
FD_TEST( actual_acct_data_cus <= requested_acct_data_cus );
txn->bank_cu.rebated_cus = ( requested_acct_data_cus - actual_acct_data_cus ) + ( requested_execution_cus - actual_execution_cus );
}

/* Commit must succeed so no failure path. This function takes
Expand Down
30 changes: 25 additions & 5 deletions src/ballet/pack/fd_compute_budget_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ static const uchar FD_COMPUTE_BUDGET_PROGRAM_ID[FD_TXN_ACCT_ADDR_SZ] = {

/* Any requests for larger heap frames must be a multiple of 1k or the
transaction is malformed. */
#define FD_COMPUTE_BUDGET_HEAP_FRAME_GRANULARITY (1024UL)
#define FD_COMPUTE_BUDGET_HEAP_FRAME_GRANULARITY ( 1024UL)
/* SetComputeUnitPrice specifies the price in "micro-lamports," which is
10^(-6) lamports, so 10^(-15) SOL. */
#define FD_COMPUTE_BUDGET_MICRO_LAMPORTS_PER_LAMPORT (1000000UL)
#define FD_COMPUTE_BUDGET_MICRO_LAMPORTS_PER_LAMPORT ( 1000000UL)

#define FD_COMPUTE_BUDGET_DEFAULT_INSTR_CU_LIMIT ( 200000UL)
#define FD_COMPUTE_BUDGET_MAX_CU_LIMIT (1400000UL)
#define FD_COMPUTE_BUDGET_DEFAULT_INSTR_CU_LIMIT ( 200000UL)
#define FD_COMPUTE_BUDGET_MAX_CU_LIMIT ( 1400000UL)
#define FD_COMPUTE_BUDGET_HEAP_COST ( 8UL)
#define FD_COMPUTE_BUDGET_ACCOUNT_DATA_COST_PAGE_SIZE (32UL * 1024UL)

/* Max loaded data size is 64 MiB */
#define FD_COMPUTE_BUDGET_MAX_LOADED_DATA_SZ (64UL*1024UL*1024UL)
Expand Down Expand Up @@ -154,7 +156,8 @@ static inline void
fd_compute_budget_program_finalize( fd_compute_budget_program_state_t const * state,
ulong instr_cnt,
ulong * out_rewards,
uint * out_compute ) {
uint * out_compute,
ulong * out_loaded_account_data_cost ) {
ulong cu_limit = 0UL;
if( FD_LIKELY( (state->flags & FD_COMPUTE_BUDGET_PROGRAM_FLAG_SET_CU)==0U ) ) {
/* Use default compute limit */
Expand All @@ -165,6 +168,23 @@ fd_compute_budget_program_finalize( fd_compute_budget_program_state_t const * st

*out_compute = (uint)cu_limit;

ulong loaded_accounts_data_size = 0UL;
if( FD_LIKELY( (state->flags & FD_COMPUTE_BUDGET_PROGRAM_FLAG_SET_LOADED_DATA_SZ)==0U ) ) {
/* Use default loaded account data size */
loaded_accounts_data_size = FD_COMPUTE_BUDGET_MAX_LOADED_DATA_SZ;
} else loaded_accounts_data_size = state->loaded_acct_data_sz;

/* https://github.com/firedancer-io/agave/blob/927c6d30ed5e1baea30c06ebf2aa0c9bae0e1dd1/sdk/fee-structure/src/lib.rs#L122-L129
loaded_accounts_data_size <= FD_COMPUTE_BUDGET_MAX_LOADED_DATA_SZ
means no overflow */

ulong loaded_accounts_data_cost = FD_COMPUTE_BUDGET_ACCOUNT_DATA_COST_PAGE_SIZE - 1UL;
loaded_accounts_data_cost = loaded_accounts_data_cost + loaded_accounts_data_size;
loaded_accounts_data_cost = loaded_accounts_data_cost / FD_COMPUTE_BUDGET_ACCOUNT_DATA_COST_PAGE_SIZE;
loaded_accounts_data_cost = loaded_accounts_data_cost * FD_COMPUTE_BUDGET_HEAP_COST;
*out_loaded_account_data_cost = loaded_accounts_data_cost;

ulong total_fee = 0UL;

/* We need to compute max(ceil((cu_limit * micro_lamports_per_cu)/10^6),
Expand Down
3 changes: 2 additions & 1 deletion src/ballet/pack/fd_microblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ struct __attribute__((aligned(64))) fd_txn_p {
struct {
uint non_execution_cus;
uint requested_execution_cus;
uint requested_acct_data_cus;
} pack_cu; /* Populated by pack. Bank reads these to populate the other struct of the union. */
struct {
uint rebated_cus; /* requested_execution_cus-real execution CUs. Pack reads this for CU rebating. */
uint actual_consumed_cus; /* non_execution_cus+real execution CUs. PoH reads this for block CU counting. */
uint actual_consumed_cus; /* non_execution_cus+real execution CUs+real account data cus. PoH reads this for block CU counting. */
} bank_cu; /* Populated by bank. */
ulong blockhash_slot; /* Slot provided by resolv tile when txn arrives at the pack tile. Used when txn is in extra storage in pack. */
};
Expand Down
21 changes: 12 additions & 9 deletions src/ballet/pack/fd_pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -871,12 +871,13 @@ fd_pack_estimate_rewards_and_compute( fd_txn_e_t * txne,
fd_txn_t * txn = TXN(txne->txnp);
ulong sig_rewards = FD_PACK_FEE_PER_SIGNATURE * txn->signature_cnt; /* Easily in [5000, 635000] */

ulong execution_cus;
ulong adtl_rewards;
ulong requested_execution_cus;
ulong priority_rewards;
ulong precompile_sigs;
ulong cost = fd_pack_compute_cost( txn, txne->txnp->payload, &txne->txnp->flags, &execution_cus, &adtl_rewards, &precompile_sigs );
ulong requested_loaded_accounts_data_cost;
ulong cost_estimate = fd_pack_compute_cost( txn, txne->txnp->payload, &txne->txnp->flags, &requested_execution_cus, &priority_rewards, &precompile_sigs, &requested_loaded_accounts_data_cost );

if( FD_UNLIKELY( !cost ) ) return 0;
if( FD_UNLIKELY( !cost_estimate ) ) return 0;

/* precompile_sigs <= 16320, so after the addition,
sig_rewards < 83,000,000 */
Expand All @@ -888,10 +889,11 @@ fd_pack_estimate_rewards_and_compute( fd_txn_e_t * txne,
fd_acct_addr_t const * acct_addr = fd_txn_get_acct_addrs( txn, txnp->payload ) + (ulong)prog_id_idx;
}
*/
out->rewards = (adtl_rewards < (UINT_MAX - sig_rewards)) ? (uint)(sig_rewards + adtl_rewards) : UINT_MAX;
out->compute_est = (uint)cost;
out->txn->pack_cu.requested_execution_cus = (uint)execution_cus;
out->txn->pack_cu.non_execution_cus = (uint)(cost - execution_cus);
out->rewards = (priority_rewards < (UINT_MAX - sig_rewards)) ? (uint)(sig_rewards + priority_rewards) : UINT_MAX;
out->compute_est = (uint)cost_estimate;
out->txn->pack_cu.requested_execution_cus = (uint)(requested_execution_cus);
out->txn->pack_cu.requested_acct_data_cus = (uint)(requested_loaded_accounts_data_cost);
out->txn->pack_cu.non_execution_cus = (uint)(cost_estimate - requested_execution_cus - requested_loaded_accounts_data_cost);

return fd_int_if( txne->txnp->flags & FD_TXN_P_FLAGS_IS_SIMPLE_VOTE, 1, 2 );
}
Expand Down Expand Up @@ -1830,6 +1832,7 @@ fd_pack_schedule_impl( fd_pack_t * pack,
fd_memcpy( TXN(out), txn, fd_txn_footprint( txn->instr_cnt, txn->addr_table_lookup_cnt ) );
out->payload_sz = cur->txn->payload_sz;
out->pack_cu.requested_execution_cus = cur->txn->pack_cu.requested_execution_cus;
out->pack_cu.requested_acct_data_cus = cur->txn->pack_cu.requested_acct_data_cus;
out->pack_cu.non_execution_cus = cur->txn->pack_cu.non_execution_cus;
out->flags = cur->txn->flags;
}
Expand Down Expand Up @@ -2347,7 +2350,7 @@ fd_pack_schedule_next_microblock( fd_pack_t * pack,
total_cus = fd_ulong_min( total_cus, pack->lim->max_cost_per_block - pack->cumulative_block_cost );
ulong vote_cus = fd_ulong_min( (ulong)((float)total_cus * vote_fraction),
pack->lim->max_vote_cost_per_block - pack->cumulative_vote_cost );
ulong vote_reserved_txns = fd_ulong_min( vote_cus/FD_PACK_TYPICAL_VOTE_COST,
ulong vote_reserved_txns = fd_ulong_min( vote_cus/FD_PACK_SIMPLE_VOTE_COST,
(ulong)((float)pack->lim->max_txn_per_microblock * vote_fraction) );


Expand Down
Loading

0 comments on commit c4f8a00

Please sign in to comment.