-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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 default_cost as mandatory field for Builtin #30639
add default_cost as mandatory field for Builtin #30639
Conversation
Following programs are not in builtins covered by this PR, are they not being executed via invoke_context, or perhaps I missed them out somehow?
|
52c2d0c
to
bc2571c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really great!
I also double-checked all the values to be safe. It's funny this also showed that the old map had solana_sdk::stake::config::id()
which isn't even a program, so I hope this will make things much better!
Regarding the other programs, here's some info:
|
It is not ideal to maintain a static list of builtins separately, this change will make it better. I am going to close #30617 in favor of this, and start updating all broken tests. And thank you for the advices. |
Anytime! Feel free to ping me when this is ready |
30c1782
to
1b664e5
Compare
@joncinque all tests have been updated, thank @samkim-crypto for quickly measure cost for zkp. PR is ready for review. |
@@ -43,6 +43,7 @@ pub type ProcessInstructionWithContext = fn(&mut InvokeContext) -> Result<(), In | |||
pub struct BuiltinProgram { | |||
pub program_id: Pubkey, | |||
pub process_instruction: ProcessInstructionWithContext, | |||
pub default_compute_unit_cost: u64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default_compute_unit_cost
will be used in follow-up PR to consume units from TX's compute budget when builtins are processed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good on my part! I'd be interested to review the follow up PR as well (since this relates to zk proof program).
For the case of the zk proof program, the costs should ideally be determined by the instruction, but this should suffice for now as an approximate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall! Just a question for the default compute unit usage on the zk proof program. Once that's resolved, this will be good to go
runtime/src/builtins.rs
Outdated
125906, // the average CUs for 6 zkp program instructions, | ||
// see comment at https://github.com/solana-labs/solana/pull/30639 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to come back to this, but I'd prefer setting an extremely high default so that the zk program is forced to always manually consume compute units, maybe even u64::MAX
. It would stink to open up a DOS opportunity just because we forget to consume compute units in a new expensive instruction. With u64::MAX
, it should fail tests immediately, right?
@samkim-crypto what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, if the idea is to use the default compute budget when the individual instructions fail to manually consume compute units, then making it always fail by setting it to a high number would be the way to go.
Currently (well, it is currently behind a feature gate), the proof program does consume units at the program level, so it is not completely clear when the default units will kick in. I was hoping to see how this is done in the follow-up PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good concern. Think about it, the risk of new instruction (of an existing program) would use much more units than pre-define program default cost applies not just zkp program, but to all.
It is always preferred builtin programs to manually deduct units during process. But for those don't have the luxury to do so at the moment, a default projects the worst scenario should be good enough.
For zkp program, my reason for using average instead of worse scenario (407_121 CU) is that compute budget defines default unit per instruction as 200_000, and max as 1_400_000 cu per tx. So I think anything close to 200_000 is reasonable, cause you can't have more than 7 of that in single tx. But if we really want to be careful, then worse scenario is ok too. u64::max might be overkill - that'd fail tx immediately. This is my 2 cents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@samkim-crypto sorry I didn't see your comment before post mine above.
The use case of default cost is described in this comment #30639 (comment). Basically if builtin.process_instruction() does not deduct units from compute budget, then the program's default cost will be used.
In the case of proof program, since it'd consume 100_000 during process, the default will not be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the idea is to use the default compute budget when the individual instructions fail to manually consume compute units
regarding this, currently no builtin manually consumes units (i mean nothing was deducted from compute budget after builtin.process_instruction()). So if sets default cost to max, then all tx has builtin will fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(BTW, I think this discussion is very helpful, thanks guys)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok that all makes sense. How about we split the difference, and use the CUs from VerifyTransfer
as the default? That should be the most used instruction. And since it's over 200k, we'll have to request more compute units in tests, which means we're much less likely to forget.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good to me, changed it in comment 959f686
Co-authored-by: Jon Cinque <[email protected]>
959f686
to
8085015
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
Codecov Report
@@ Coverage Diff @@
## master #30639 +/- ##
=======================================
Coverage 81.6% 81.7%
=======================================
Files 723 723
Lines 201674 201682 +8
=======================================
+ Hits 164762 164784 +22
+ Misses 36912 36898 -14 |
@samkim-crypto the follow up PR is #30680 |
* add default_cost as mandatory field for Builtin * updated tests * set zkp program default to VerifyTransfer CUs --------- Co-authored-by: Jon Cinque <[email protected]>
Sorry @taozhu-chicago that I only saw this PR now. Problem is, that @pgarg66 and I are in the process of removing |
No worries, I should have tagged you on this PR. I knew you and @pgarg66 are working in the area, didn't know what changes you guys are actually making. In any case, let me catch up on your changes, see if there are chance to apply/merge this PRs. If not, OK to revert. The end goal is to find a quick way to make builtin programs to consume units (as in #30680) |
Problem
Builtin should consume compute units when executed; if no exact units being deducted from compute budget, a default cost should be used. In order to do so, a mandatory
default_cost
field is added toBuiltin
, which is passed down toinvoke_context::BuiltinProgram
where it can be used for compute budget.Summary of Changes
default_cost
toBuiltin
, assigned pre-defined value fromblock_cost_limits.rs
invoke_context::BuiltinProgram
(A follow up PR would use that value to deduct builtin's cost from compute budget)Fixes #