diff --git a/src/disco/pack/fd_compute_budget_program.h b/src/disco/pack/fd_compute_budget_program.h index 11db5dfd00..83e5832d7f 100644 --- a/src/disco/pack/fd_compute_budget_program.h +++ b/src/disco/pack/fd_compute_budget_program.h @@ -42,6 +42,7 @@ static const uchar FD_COMPUTE_BUDGET_PROGRAM_ID[FD_TXN_ACCT_ADDR_SZ] = { #define FD_COMPUTE_BUDGET_MICRO_LAMPORTS_PER_LAMPORT ( 1000000UL) #define FD_COMPUTE_BUDGET_DEFAULT_INSTR_CU_LIMIT ( 200000UL) +#define FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT ( 3000UL) #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) @@ -155,15 +156,22 @@ fd_compute_budget_program_parse( uchar const * instr_data, static inline void fd_compute_budget_program_finalize( fd_compute_budget_program_state_t const * state, ulong instr_cnt, + ulong non_builtin_instr_cnt, ulong * out_rewards, 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 */ - cu_limit = (instr_cnt - state->compute_budget_instr_cnt) * FD_COMPUTE_BUDGET_DEFAULT_INSTR_CU_LIMIT; - } else cu_limit = state->compute_units; + cu_limit += (instr_cnt - non_builtin_instr_cnt) * FD_COMPUTE_BUDGET_DEFAULT_INSTR_CU_LIMIT + + non_builtin_instr_cnt * FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT; + + /* All non-migratable builtin program instructions are counted as + 3000 CUs per instruction. Each non-builtin instruction and + migrated built-in program instruction is counted as 200000 CUs + per instruction. */ + } else cu_limit = state->compute_units; cu_limit = fd_ulong_min( cu_limit, FD_COMPUTE_BUDGET_MAX_CU_LIMIT ); *out_compute = (uint)cu_limit; diff --git a/src/disco/pack/fd_pack_cost.h b/src/disco/pack/fd_pack_cost.h index 69badfacfa..b31cb64101 100644 --- a/src/disco/pack/fd_pack_cost.h +++ b/src/disco/pack/fd_pack_cost.h @@ -63,16 +63,17 @@ typedef struct fd_pack_builtin_prog_cost fd_pack_builtin_prog_cost_t; #define MAP_PERFECT_HASH_R( ptr ) PERFECT_HASH( fd_uint_load_4( (uchar const *)ptr->b + 8UL ) ) -/* The cost model estimates 200,000 CUs for builtin programs that were migrated to BPF */ -#define MAP_PERFECT_0 ( VOTE_PROG_ID ), .cost_per_instr= 3000UL -#define MAP_PERFECT_1 ( SYS_PROG_ID ), .cost_per_instr= 3000UL -#define MAP_PERFECT_2 ( COMPUTE_BUDGET_PROG_ID ), .cost_per_instr= 3000UL -#define MAP_PERFECT_3 ( BPF_UPGRADEABLE_PROG_ID ), .cost_per_instr= 3000UL -#define MAP_PERFECT_4 ( BPF_LOADER_1_PROG_ID ), .cost_per_instr= 3000UL -#define MAP_PERFECT_5 ( BPF_LOADER_2_PROG_ID ), .cost_per_instr= 3000UL -#define MAP_PERFECT_6 ( LOADER_V4_PROG_ID ), .cost_per_instr= 3000UL -#define MAP_PERFECT_7 ( KECCAK_SECP_PROG_ID ), .cost_per_instr= 3000UL -#define MAP_PERFECT_8 ( ED25519_SV_PROG_ID ), .cost_per_instr= 3000UL +/* The cost model estimates 200,000 CUs for builtin programs that were + migrated to BPF. */ +#define MAP_PERFECT_0 ( VOTE_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT +#define MAP_PERFECT_1 ( SYS_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT +#define MAP_PERFECT_2 ( COMPUTE_BUDGET_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT +#define MAP_PERFECT_3 ( BPF_UPGRADEABLE_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT +#define MAP_PERFECT_4 ( BPF_LOADER_1_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT +#define MAP_PERFECT_5 ( BPF_LOADER_2_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT +#define MAP_PERFECT_6 ( LOADER_V4_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT +#define MAP_PERFECT_7 ( KECCAK_SECP_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT +#define MAP_PERFECT_8 ( ED25519_SV_PROG_ID ), .cost_per_instr = FD_COMPUTE_BUDGET_MAX_BUILTIN_CU_LIMIT #include "../../util/tmpl/fd_map_perfect.c" @@ -273,11 +274,17 @@ fd_pack_compute_cost( fd_txn_t const * txn, ulong fee[1]; uint compute[1]; ulong loaded_account_data_cost[1]; - fd_compute_budget_program_finalize( cbp, txn->instr_cnt, fee, compute, loaded_account_data_cost ); + fd_compute_budget_program_finalize( + cbp, + txn->instr_cnt, + non_builtin_cnt, + fee, + compute, + loaded_account_data_cost ); non_builtin_cnt = fd_ulong_min( non_builtin_cnt, FD_COMPUTE_BUDGET_MAX_CU_LIMIT/FD_COMPUTE_BUDGET_DEFAULT_INSTR_CU_LIMIT ); - ulong execution_cost = fd_ulong_if( (cbp->flags & FD_COMPUTE_BUDGET_PROGRAM_FLAG_SET_CU) && (non_builtin_cnt>0UL), + ulong execution_cost = fd_ulong_if( (cbp->flags & FD_COMPUTE_BUDGET_PROGRAM_FLAG_SET_CU), (ulong)*compute, builtin_cost + non_builtin_cnt*FD_COMPUTE_BUDGET_DEFAULT_INSTR_CU_LIMIT ); /* <= FD_COMPUTE_BUDGET_MAX_CU_LIMIT */ diff --git a/src/disco/pack/test_compute_budget_program.c b/src/disco/pack/test_compute_budget_program.c index f770139751..483dc7f096 100644 --- a/src/disco/pack/test_compute_budget_program.c +++ b/src/disco/pack/test_compute_budget_program.c @@ -29,7 +29,7 @@ test_txn( uchar const * payload, ulong rewards = 0UL; uint compute = 0U; ulong loaded_accounts_data_cost = 0UL; - fd_compute_budget_program_finalize( &state, txn->instr_cnt, &rewards, &compute, &loaded_accounts_data_cost); + fd_compute_budget_program_finalize( &state, txn->instr_cnt, txn->instr_cnt, &rewards, &compute, &loaded_accounts_data_cost); FD_TEST( rewards == expected_fee_lamports ); FD_TEST( (ulong)compute == expected_max_cu ); FD_TEST( loaded_accounts_data_cost == expected_loaded_accounts_data_cost ); diff --git a/src/disco/pack/test_pack.c b/src/disco/pack/test_pack.c index f807fbc360..b353f7aa2c 100644 --- a/src/disco/pack/test_pack.c +++ b/src/disco/pack/test_pack.c @@ -396,7 +396,7 @@ schedule_validate_microblock( fd_pack_t * pack, FD_TEST( fd_compute_budget_program_parse( txnp->payload + txn->instr[ i ].data_off, txn->instr[ i ].data_sz, &cbp ) ); } } - fd_compute_budget_program_finalize( &cbp, txn->instr_cnt, &rewards, &compute, &requested_loaded_accounts_data_cost ); + fd_compute_budget_program_finalize( &cbp, txn->instr_cnt, txn->instr_cnt, &rewards, &compute, &requested_loaded_accounts_data_cost ); total_rewards += rewards; diff --git a/src/flamenco/runtime/program/fd_builtin_programs.c b/src/flamenco/runtime/program/fd_builtin_programs.c index 54b101db58..f56fe52718 100644 --- a/src/flamenco/runtime/program/fd_builtin_programs.c +++ b/src/flamenco/runtime/program/fd_builtin_programs.c @@ -317,5 +317,5 @@ fd_is_migrating_builtin_program( fd_exec_txn_ctx_t const * txn_ctx, FD_FN_PURE uchar fd_is_non_migrating_builtin_program( fd_pubkey_t const * pubkey ) { - return !!( fd_non_migrating_builtins_tbl_contains( pubkey ) ); + return !!(fd_non_migrating_builtins_tbl_contains( pubkey )); } diff --git a/src/flamenco/runtime/tests/harness/fd_exec_sol_compat.c b/src/flamenco/runtime/tests/harness/fd_exec_sol_compat.c index f06b647e34..8bd06ef8b9 100644 --- a/src/flamenco/runtime/tests/harness/fd_exec_sol_compat.c +++ b/src/flamenco/runtime/tests/harness/fd_exec_sol_compat.c @@ -871,10 +871,11 @@ sol_compat_vm_interp_v1( uchar * out, return ok; } -int sol_compat_shred_parse_v1( uchar * out, - ulong * out_sz, - uchar const * in, - ulong in_sz ) { +int +sol_compat_shred_parse_v1( uchar * out, + ulong * out_sz, + uchar const * in, + ulong in_sz ) { fd_exec_test_shred_binary_t input[1] = {0}; void * res = sol_compat_decode( &input, in, in_sz, &fd_exec_test_shred_binary_t_msg ); if( FD_UNLIKELY( res==NULL ) ) { diff --git a/src/flamenco/runtime/tests/harness/fd_pack_harness.c b/src/flamenco/runtime/tests/harness/fd_pack_harness.c index e9dcf602a8..70e3ead2b7 100644 --- a/src/flamenco/runtime/tests/harness/fd_pack_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_pack_harness.c @@ -40,13 +40,15 @@ do { break; } ulong rewards; - uint compute_unit_limit; + uint compute_unit_limit; ulong loaded_accounts_data_cost = 0UL; - fd_compute_budget_program_finalize( cbp_state, - input->instr_datas_count, - &rewards, - &compute_unit_limit, - &loaded_accounts_data_cost ); + fd_compute_budget_program_finalize( + cbp_state, + input->instr_datas_count, + input->instr_datas_count, + &rewards, + &compute_unit_limit, + &loaded_accounts_data_cost ); effects->rewards = rewards; effects->compute_unit_limit = compute_unit_limit;