Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --with-compute-unit-price to cli program deploy commands #364

Merged
merged 8 commits into from
Mar 22, 2024

Conversation

jstarry
Copy link

@jstarry jstarry commented Mar 21, 2024

Problem

It's not possible to set a compute unit price or limit on deploy transactions. This causes deploys to be very slow when transaction priority fees increase on the cluster.

Summary of Changes

  • Add compute unit price and limit instructions to deploy instructions when the --with-compute-unit-price flag is passed for solana program deploy and solana program write-buffer
  • Compute unit limit is set by first simulating each type of deploy transaction and then using the number of compute units consumed

Fixes #21

Comment on lines 2777 to 2798
let mut compute_unit_limit: u32 = 300; // 2 * 150 for compute budget ixs
for ix in ixs.iter() {
if ix.program_id == bpf_loader_upgradeable::id() {
compute_unit_limit += 2370;
match ix.data.first() {
Some(2) // DeployWithMaxDataLen
| Some(6) // ExtendProgram
=> {
// add compute for native system program invocation
compute_unit_limit += 150;
}
_ => {}
}
} else if ix.program_id == system_program::id() {
compute_unit_limit += 150;
} else {
panic!(
"Couldn't estimate compute unit limit for unexpected program {}",
ix.program_id
);
}
}
Copy link
Author

Choose a reason for hiding this comment

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

I'm not really in favor of having compute unit limit logic here in the cli client. I'd prefer to get the units consumed from the simulate transaction call.

Choose a reason for hiding this comment

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

Yeah that would be great, I've been trying to figure out a nice API to do it. No need to change what you've done though

Copy link
Author

Choose a reason for hiding this comment

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

I would feel better knowing that deploys won't get broken in the future if we increase the compute unit limit for certain instructions. Let me know what you think of the simulation code!

@codecov-commenter
Copy link

codecov-commenter commented Mar 21, 2024

Codecov Report

Attention: Patch coverage is 36.44860% with 68 lines in your changes are missing coverage. Please review.

Project coverage is 81.9%. Comparing base (b2f4fb3) to head (01faab4).
Report is 10 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##           master     #364     +/-   ##
=========================================
- Coverage    81.9%    81.9%   -0.1%     
=========================================
  Files         838      838             
  Lines      227368   227412     +44     
=========================================
+ Hits       186238   186266     +28     
- Misses      41130    41146     +16     

joncinque
joncinque previously approved these changes Mar 21, 2024
Copy link

@joncinque joncinque left a comment

Choose a reason for hiding this comment

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

Looks great! Just a nit on the test, but nothing stopping this from going in

Comment on lines 2777 to 2798
let mut compute_unit_limit: u32 = 300; // 2 * 150 for compute budget ixs
for ix in ixs.iter() {
if ix.program_id == bpf_loader_upgradeable::id() {
compute_unit_limit += 2370;
match ix.data.first() {
Some(2) // DeployWithMaxDataLen
| Some(6) // ExtendProgram
=> {
// add compute for native system program invocation
compute_unit_limit += 150;
}
_ => {}
}
} else if ix.program_id == system_program::id() {
compute_unit_limit += 150;
} else {
panic!(
"Couldn't estimate compute unit limit for unexpected program {}",
ix.program_id
);
}
}

Choose a reason for hiding this comment

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

Yeah that would be great, I've been trying to figure out a nice API to do it. No need to change what you've done though

compute_unit_limit += 2370;
match ix.data.first() {
Some(2) // DeployWithMaxDataLen
| Some(6) // ExtendProgram

Choose a reason for hiding this comment

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

Thanks for thinking about the future by including this even though it isn't used in this PR ❤️

Comment on lines 2785 to 2786
// add compute for native system program invocation
compute_unit_limit += 150;

Choose a reason for hiding this comment

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

Confirming this is correct

Comment on lines +2397 to +2398
let (initial_message, write_messages, balance_needed) = if let Some(buffer_signer) =
buffer_signer

Choose a reason for hiding this comment

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

thanks rustfmt 🙃

Comment on lines 2194 to 2198
match try_from_slice_unchecked(&tx.message.instructions[0].data) {
Ok(ComputeBudgetInstruction::SetComputeUnitPrice(price))
if price == compute_unit_price => {}
ix => assert!(false, "unexpected ix {ix:?}"),
}

Choose a reason for hiding this comment

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

nit: I believe all of these checks could use matches! to be simpler, ie:

Suggested change
match try_from_slice_unchecked(&tx.message.instructions[0].data) {
Ok(ComputeBudgetInstruction::SetComputeUnitPrice(price))
if price == compute_unit_price => {}
ix => assert!(false, "unexpected ix {ix:?}"),
}
assert!(
matches!(
try_from_slice_unchecked(&tx.message.instructions[0].data),
Ok(ComputeBudgetInstruction::SetComputeUnitPrice(price)) if price == compute_unit_price
),
"unexpected ix {ix:?}"
);

joncinque
joncinque previously approved these changes Mar 22, 2024
Copy link

@joncinque joncinque left a comment

Choose a reason for hiding this comment

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

Still looks great! Just a couple of nits, but nothing to stop this from going in

cli/src/program.rs Outdated Show resolved Hide resolved
cli/src/program.rs Outdated Show resolved Hide resolved
@jstarry jstarry added automerge automerge Merge this Pull Request automatically once CI passes v1.18 labels Mar 22, 2024
Copy link

mergify bot commented Mar 22, 2024

Backports to the beta branch are to be avoided unless absolutely necessary for fixing bugs, security issues, and perf regressions. Changes intended for backport should be structured such that a minimum effective diff can be committed separately from any refactoring, plumbing, cleanup, etc that are not strictly necessary to achieve the goal. Any of the latter should go only into master and ride the normal stabilization schedule. Exceptions include CI/metrics changes, CLI improvements and documentation updates on a case by case basis.

@mergify mergify bot merged commit 2ee606d into anza-xyz:master Mar 22, 2024
50 checks passed
mergify bot pushed a commit that referenced this pull request Mar 22, 2024
* add set compute units arg for program deploy

* update master changes

* remove duplicates

* fixes and tests

* remove extra lines

* feedback

* Use simulation to determine compute units consumed

* feedback

---------

Co-authored-by: NagaprasadVr <nagaprasadvr246@gmail.com>
(cherry picked from commit 2ee606d)
joncinque pushed a commit that referenced this pull request Mar 22, 2024
… (backport of #364) (#392)

Add `--with-compute-unit-price` to cli program deploy commands (#364)

* add set compute units arg for program deploy

* update master changes

* remove duplicates

* fixes and tests

* remove extra lines

* feedback

* Use simulation to determine compute units consumed

* feedback

---------

Co-authored-by: NagaprasadVr <nagaprasadvr246@gmail.com>
(cherry picked from commit 2ee606d)

Co-authored-by: Justin Starry <justin@anza.xyz>
@tarunjais28
Copy link

tarunjais28 commented Jul 19, 2024

Hi @joncinque, after adding --with-compute-unit-price on solana program deploy command still it is taking a days and not getting deployed to mainnet, is there a way for fast mainnet deployment?
solana program deploy target/deploy/program.so --url https://api.mainnet-beta.solana.com --with-compute-unit-price 1000000 --max-sign-attempts 1000
image
It's more than a day and still the program is not deployed

@joncinque
Copy link

@tarunjais28 it still can be difficult to get transactions to the leader due to stake-weighted quality of service setups, but you're doing the right thing. You can also try adding the --use-rpc flag to send transactions through RPC instead of TPU. If you have additional questions, please ask them on the Solana Stack Exchange https://solana.stackexchange.com/

@anza-xyz anza-xyz locked as resolved and limited conversation to collaborators Jul 19, 2024
@jstarry jstarry deleted the cli/deploy-priority-fee branch July 19, 2024 10:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
automerge automerge Merge this Pull Request automatically once CI passes v1.18
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add priority fees and retry count to solana program deploy
5 participants