Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

cost model could double count builtin instruction cost #32422

Conversation

tao-stones
Copy link
Contributor

Problem

Philip @ FD pointed out "when there are no ComputeBudgetProgram instructions but at least 1 non-builtin instruction, bpf_execution_cost is initially set to 200k*(number of non-built-in instructions) but then overwritten to 200k*(number of non-ComputeBudgetProgram instructions) by the result of compute_budget.process_instructions . This means that if you have a mix of built-in and non-built-in instructions, the built-in ones get double counted (included in builtins_execution_cost and bpf_execution_cost )."

Summary of Changes

  1. add test test_transaction_cost_with_mix_instruction_without_compute_budget to cost_model.rs, confirms builtin ix add cost to bpf_execution_cost
  2. add test test_process_mixed_instructions_without_compute_budget to compute_budget.rs, to explicitly demo default compute unit limit behavior
  3. add explicite checking for set_compute_unit_limit instruction in CostModel::get_transaction_cost() to fix the issue.

Fixes #

@tao-stones tao-stones added v1.14 v1.16 PRs that should be backported to v1.16 labels Jul 7, 2023
@tao-stones tao-stones requested review from apfitzge and mschneider July 7, 2023 23:46
if let Ok(ComputeBudgetInstruction::SetComputeUnitLimit(_)) =
try_from_slice_unchecked(&instruction.data)
{
compute_unit_limit_is_set = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have to explicitly check if SetComputeUnitLimit is included in the TX, only then can safely override default with compute_budget.compute_unit_limit.

@tao-stones
Copy link
Contributor Author

cost_model::get_transaction_cost() isn't very satisfying - it iterates through instructions twice, calling compute_budget::process_instruction() just for user specified cu-limit (if any), too many logics. Going to refactor it separately, thinking to call compute_budget::process_instruction once per transaction to start with. thoughts?

@codecov
Copy link

codecov bot commented Jul 8, 2023

Codecov Report

Merging #32422 (b06e663) into master (37a3638) will increase coverage by 0.0%.
The diff coverage is 95.7%.

@@           Coverage Diff           @@
##           master   #32422   +/-   ##
=======================================
  Coverage    82.1%    82.1%           
=======================================
  Files         778      778           
  Lines      210107   210152   +45     
=======================================
+ Hits       172556   172642   +86     
+ Misses      37551    37510   -41     

Copy link
Contributor

@apfitzge apfitzge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine as quick fix. As implied by the comments, I think the right approach is refactoring this so we don't have a confusing setup of looping over the ixs twice. That will also help with performance.

bpf_costs = bpf_costs.saturating_add(DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT.into());
bpf_costs = bpf_costs
.saturating_add(u64::from(DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT))
.min(u64::from(MAX_COMPUTE_UNIT_LIMIT));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably don't need to do this every time, right? just do it after the loop

Comment on lines +112 to +113
if let Ok(ComputeBudgetInstruction::SetComputeUnitLimit(_)) =
try_from_slice_unchecked(&instruction.data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels dirty, but is a quick fix.

@tao-stones tao-stones merged commit c69bc00 into solana-labs:master Jul 17, 2023
@tao-stones tao-stones deleted the cost-model-could-double-count-builtin-cost branch July 17, 2023 20:50
mergify bot pushed a commit that referenced this pull request Jul 17, 2023
1. add tests to demo builtin cost could be double counted;
2. quick fix for now

(cherry picked from commit c69bc00)

# Conflicts:
#	cost-model/src/cost_model.rs
#	program-runtime/src/compute_budget.rs
mergify bot pushed a commit that referenced this pull request Jul 17, 2023
1. add tests to demo builtin cost could be double counted;
2. quick fix for now

(cherry picked from commit c69bc00)

# Conflicts:
#	runtime/src/cost_model.rs
willhickey pushed a commit that referenced this pull request Jul 18, 2023
1. add tests to demo builtin cost could be double counted;
2. quick fix for now

(cherry picked from commit c69bc00)

# Conflicts:
#	runtime/src/cost_model.rs
@tao-stones tao-stones removed the v1.14 label Jul 18, 2023
tao-stones added a commit that referenced this pull request Jul 19, 2023
…rt of #32422) (#32516)

* cost model could double count builtin instruction cost (#32422)

1. add tests to demo builtin cost could be double counted;
2. quick fix for now

(cherry picked from commit c69bc00)

# Conflicts:
#	runtime/src/cost_model.rs

* fix backport merge conflict

* fix a logic error

---------

Co-authored-by: Tao Zhu <82401714+taozhu-chicago@users.noreply.github.com>
Co-authored-by: Tao Zhu <tao@solana.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
v1.16 PRs that should be backported to v1.16
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants