Skip to content

add tx_priority_fee argument for program deploy subcommand#144

Closed
Nagaprasadvr wants to merge 11 commits intoanza-xyz:masterfrom
Nagaprasadvr:feat-add-tx-priority-fee-and-max-retries-for-program-deploy
Closed

add tx_priority_fee argument for program deploy subcommand#144
Nagaprasadvr wants to merge 11 commits intoanza-xyz:masterfrom
Nagaprasadvr:feat-add-tx-priority-fee-and-max-retries-for-program-deploy

Conversation

@Nagaprasadvr
Copy link
Copy Markdown

@Nagaprasadvr Nagaprasadvr commented Mar 8, 2024

Issue - #21

Add Transaction priority fee argument in terms of LAMPORTS to solana program deploy subcommand

Problem

  1. solana program deploy command could take a lot of time to finish due to program code size .Transaction execution speeds can be increased or txs can be prioritised by setting compute_unit_price (priority fee) for every tx this price is set and txs are executes faster than normal therefore making program deployment faster.
    usage - solana program deploy --tx-priority-fee 1000000

Summary of Changes

solana/cli/program - added tx_priority_fee logic

@mergify mergify Bot requested a review from a team March 8, 2024 04:19
@Nagaprasadvr Nagaprasadvr marked this pull request as draft March 8, 2024 04:21
@Nagaprasadvr
Copy link
Copy Markdown
Author

Should we update program_v4 as well ?

Comment thread cli/src/program.rs Outdated
@Nagaprasadvr Nagaprasadvr marked this pull request as ready for review March 9, 2024 03:44
@Nagaprasadvr Nagaprasadvr requested a review from tao-stones March 9, 2024 03:45
Comment thread cli/src/program.rs
)
};

initial_instructions.extend(ixs);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It could error out when making ixs above, so maybe more economic to extend ComputeBudgetInstruction::set_compute_unit_price(...) into ixs, instead of allocate set_compute_unit_price then fails on rpc call.

Copy link
Copy Markdown
Author

@Nagaprasadvr Nagaprasadvr Mar 13, 2024

Choose a reason for hiding this comment

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

After reading this https://www.helius.dev/blog/priority-fees-understanding-solanas-transaction-fee-mechanics Section:Best practices , it says set_compute_limit and set_compute_units should always be added to the start of ix Vec.

So a solution for this can be i create set_compute_units and set_compute_limit instructions after ixs is prepared ?
at line no 2318

Comment thread cli/src/program.rs Outdated
Comment thread cli/src/program.rs Outdated
Comment on lines +245 to +261
)
.arg(
Arg::with_name("compute_unit_price")
.long("compute-unit-price")
.takes_value(true)
.help(
"Set computeUnitPrice (tx priotity fee) to boost transactions resulting in faster execution speed \
[Note: priority fee is added in LAMPORTS, so enter priority fee in terms of LAMPORTS]",
),
).
arg(
Arg::with_name("max_retires")
.long("max-retries")
.takes_value(true)
.help(
"Specifies the max retry count for failed transactions",
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

these should be added in separate PRs

Copy link
Copy Markdown
Author

@Nagaprasadvr Nagaprasadvr Mar 13, 2024

Choose a reason for hiding this comment

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

so compute_unit_price is one pr and max_retries is another pr ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

resolved

Comment thread cli/src/program.rs Outdated
Comment on lines +246 to +254
.arg(
Arg::with_name("compute_unit_price")
.long("compute-unit-price")
.takes_value(true)
.help(
"Set computeUnitPrice (tx priotity fee) to boost transactions resulting in faster execution speed \
[Note: priority fee is added in LAMPORTS, so enter priority fee in terms of LAMPORTS]",
),
).
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

we'll want to define this arg somewhere and such that it can be reused on all transaction-bearing subcommands, for consistencies sake. most likely that will be in the clap-utils dir, similarly to the offline_signing module

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

can we do this in a diff pr ?

@ChewingGlass
Copy link
Copy Markdown

FYI this seems to only put priority fees on the initial buffer creation transaction and not on all the subsequent txns (the ones that take the lion's share of the time)

@Nagaprasadvr
Copy link
Copy Markdown
Author

FYI this seems to only put priority fees on the initial buffer creation transaction and not on all the subsequent txns (the ones that take the lion's share of the time)

I have added set compute limit and set compute price ixs to write messages and final messages as well

@Nagaprasadvr Nagaprasadvr changed the title add tx_priority_fee and max_retries arguments for program deploy subcommand add tx_priority_fee arguments for program deploy subcommand Mar 14, 2024
@Nagaprasadvr Nagaprasadvr changed the title add tx_priority_fee arguments for program deploy subcommand add tx_priority_fee argument for program deploy subcommand Mar 14, 2024
Comment thread cli/src/program.rs Outdated
3 as u32 * 200_000u32,
));
ixs.push(ComputeBudgetInstruction::set_compute_unit_price(
0u64.mul((10 as u64).pow(6)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Will always be 0?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
0u64.mul((10 as u64).pow(6)),
compute_unit_price.mul((10 as u64).pow(6)),

Copy link
Copy Markdown
Author

@Nagaprasadvr Nagaprasadvr Mar 15, 2024

Choose a reason for hiding this comment

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

Will always be 0?

Oh my bad , that is wrong it should be compute_unit_price

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

resolved

@ChewingGlass
Copy link
Copy Markdown

The arg should be in terms of microlamports, otherwise the min you can pay is 0.000605 SOL per write tx. Which gets pricy.

@Nagaprasadvr
Copy link
Copy Markdown
Author

The arg should be in terms of microlamports, otherwise the min you can pay is 0.000605 SOL per write tx. Which gets pricy.

Will change to micro lamports

@Nagaprasadvr
Copy link
Copy Markdown
Author

The arg should be in terms of microlamports, otherwise the min you can pay is 0.000605 SOL per write tx. Which gets pricy.

resolved

Comment thread cli/src/program.rs Outdated
),
)
.arg(
Arg::with_name("compute_unit_price")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

prefer the pre-defined Arg from clap-utils

pub fn compute_unit_price_arg<'a, 'b>() -> Arg<'a, 'b> {
Arg::with_name(COMPUTE_UNIT_PRICE_ARG.name)
.long(COMPUTE_UNIT_PRICE_ARG.long)
.takes_value(true)
.value_name("COMPUTE-UNIT-PRICE")
.help(COMPUTE_UNIT_PRICE_ARG.help)
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

resolved

Comment thread cli/src/program.rs Outdated
ixs_len: usize,
) {
if let Some(compute_unit_price) = compute_unit_price {
println!("ixs_len: {}", ixs_len);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

remove this debug print

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

resolved

Comment thread cli/src/program.rs Outdated
if let Some(compute_unit_price) = compute_unit_price {
println!("ixs_len: {}", ixs_len);
ixs.push(ComputeBudgetInstruction::set_compute_unit_limit(
((ixs_len + 2) as u32) * 200_000u32,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

most likely this is a drastic over-reservation which may reduce the likelihood of the transaction being included toward the end of a block

Copy link
Copy Markdown
Author

@Nagaprasadvr Nagaprasadvr Mar 15, 2024

Choose a reason for hiding this comment

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

Can u elaborate what is wrong here exactly is it setting more cu than required?

i have also read that setting compute_unit_limit is optional when setting compute_unit_price wyt?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It is optional, but it's recommended to set a limit because the default limit is 200k * the number of instructions in the transaction. The transaction priority fee is calculated by multiplying the micro-lamport fee (per compute unit) by the transaction's compute unit limit. So if you set the compute unit too high or if you don't specify one and use the default limit, you will end up overpaying priority fees.. in other words, wasting tokens.

This set_compute_budget_ixs_if_needed should probably accept compute_unit_limit argument explicitly and then each caller can calculate the exact compute unit limit needed for the passed ixs. Then this function can add 300 compute units to the limit for the two additional compute budget program instructions. The default compute units charged per core program instruction are as follows:

  • System program: 150
  • Compute budget program: 150
  • Upgradeable BPF loader program: 2370

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

will add this logic ty

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

so we need to check each ix in ix vec and calculate compute_units required in this case right?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yes each ix has to be counted. I already explained this above and gave my suggestion for how to implement the fix.

@Nagaprasadvr
Copy link
Copy Markdown
Author

Nagaprasadvr commented Mar 16, 2024

found a workaround for this
@jstarry

i have added 2000 cu when program is neither system_program or bpf_upgradable_loader
image

@Nagaprasadvr Nagaprasadvr closed this by deleting the head repository Mar 19, 2024
@Nagaprasadvr
Copy link
Copy Markdown
Author

please look at #312 ! apologies for closing this pr , please add your comments there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants