-
Notifications
You must be signed in to change notification settings - Fork 471
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
Simulate: Add opcode costs and budgets into response #5221
Simulate: Add opcode costs and budgets into response #5221
Conversation
Codecov Report
@@ Coverage Diff @@
## master #5221 +/- ##
==========================================
- Coverage 53.55% 46.53% -7.02%
==========================================
Files 441 441
Lines 55123 55137 +14
==========================================
- Hits 29520 25659 -3861
- Misses 23317 27080 +3763
- Partials 2286 2398 +112
... and 188 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
ledger/simulation/tracer.go
Outdated
} | ||
tracer.cursorEvalTracer.BeforeTxnGroup(ep) | ||
|
||
// Currently only supports one (first) txn group | ||
if ep.PooledApplicationBudget != nil && tracer.result.TxnGroups[0].BudgetAdded == 0 { |
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.
We initialize the group budget by only accounting for top-level transactions. If we are in an inner level txn, then we dynamically add ep.Proto.MaxAppProgramCost
to the budget each time. We might also want to think about how this can be handled when an app has depleted all its funds before it tries to "op-up" in an inner transaction and whether simulation should report an error in this case (like real execution), or simulate anyway.
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.
when an app has depleted all its funds before it tries to "op-up" in an inner transaction and whether simulation should report an error in this case
That is what we discussed yesterday about keeping track of budget as execution goes, right?
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.
I can understand that, the second if seems mutual exclusive with the first if, for first if condition makes BudgetAdded != 0
, thus second if cannot be entered.
Could you explain more on what scenario the first if and second if will be triggered, such that it won't seem too abstract.
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.
I forgot to clarify this in the previous comment:
- I considered a case where
ep.PooledApplicationBudget
might be nil because of an old consensus version (before pooling was enabled, this pointer would just be nil).Maybe for completion's sake, we should specify that the budget =ep.Proto.MaxAppProgramCost
if this value is nil (since you cannot pool), and if it's not nil, we start adding the budget.- edit: I forgot there are also non-app calls that do not have a budget at all, so it's best to leave as is.
- The
BudgetAdded == 0
checks that we are always at the top-level transaction. If we are at an inner transaction, ourPooledApplicationBudget
could be something like567
after being called midway through the app call. So we are saying that at the root-level transaction, set theBudgetAdded
to a value that only accounts for the top level txns (e.g. 2100 for 3 txns) and then in the inner txn, we only add 700 once.
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.
I think it's ok to do nothing here if EnableAppCostPooling
is false (i.e. the current code looks good to me).
If I understand the code correctly, BudgetAdded
for the group would then be 0 and get omitted from the response. This makes sense, since if app budgets aren't pooled, there's not much use in aggregating the budgets for the whole group anyway. And of course individual transactions' BudgetUsed
would still be accurate in that case.
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.
thanks for explaining! that helps me a lot in understanding and catching up!
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.
taking a quick first pass, generally seems straightforward, have some minor questions as I am catching up.
ledger/simulation/tracer.go
Outdated
} | ||
tracer.cursorEvalTracer.BeforeTxnGroup(ep) | ||
|
||
// Currently only supports one (first) txn group | ||
if ep.PooledApplicationBudget != nil && tracer.result.TxnGroups[0].BudgetAdded == 0 { |
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.
when an app has depleted all its funds before it tries to "op-up" in an inner transaction and whether simulation should report an error in this case
That is what we discussed yesterday about keeping track of budget as execution goes, right?
ledger/simulation/tracer.go
Outdated
} | ||
tracer.cursorEvalTracer.BeforeTxnGroup(ep) | ||
|
||
// Currently only supports one (first) txn group | ||
if ep.PooledApplicationBudget != nil && tracer.result.TxnGroups[0].BudgetAdded == 0 { |
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.
I can understand that, the second if seems mutual exclusive with the first if, for first if condition makes BudgetAdded != 0
, thus second if cannot be entered.
Could you explain more on what scenario the first if and second if will be triggered, such that it won't seem too abstract.
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, I just have some minor comments and a test suggestion
ledger/simulation/tracer.go
Outdated
} | ||
tracer.cursorEvalTracer.BeforeTxnGroup(ep) | ||
|
||
// Currently only supports one (first) txn group | ||
if ep.PooledApplicationBudget != nil && tracer.result.TxnGroups[0].BudgetAdded == 0 { |
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.
I think it's ok to do nothing here if EnableAppCostPooling
is false (i.e. the current code looks good to me).
If I understand the code correctly, BudgetAdded
for the group would then be 0 and get omitted from the response. This makes sense, since if app budgets aren't pooled, there's not much use in aggregating the budgets for the whole group anyway. And of course individual transactions' BudgetUsed
would still be accurate in that case.
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, thanks for including logicsig budget as well!
Summary
This PR adds the following support for the simulator:
budget-added
,budget-consumed
fields in the algod API specCloses #4971
Test Plan
Revised existing tests to report opcode budget and costs in the simulator and the handler. Added two new tests that tests over-budget app/logic sig calls to show behavior and how budget/costs are reported. Appreciate any other suggestions for tests as well 😄