-
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
eval: increase opcode budget with fee credit #5943
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #5943 +/- ##
==========================================
- Coverage 55.75% 55.72% -0.04%
==========================================
Files 488 488
Lines 68101 68115 +14
==========================================
- Hits 37969 37956 -13
- Misses 27568 27586 +18
- Partials 2564 2573 +9 ☔ View full report in Codecov by Sentry. |
This will be a VERY welcome change to the AVM. Can't wait ! |
Hugely supportive of this. Opup is the one thing in Algorand that feels really inelegant and is a real pain for development. This approach can be easily combined with simulate to programmatically determine how to appropriately fund the amount of compute needed for a transaction without the contract developer or contract consumer needing to do (sometimes laborious) experimentation for the magic number of opups that are needed for a given call. |
I have updated the PR so that this only affects apps. Doing this for logic sigs wouldn't doesn't make since due to the fact they are executed in parallel. The main issue blocking this PR from going further is the fact that this fundamentally changes the semantics of what a transaction is (as pointed out to me by @jannotti). I see a couple of paths forward each with pros/cons Potential OptionsA) Send Inner TransactionsFor every additional 700 budget needed, we automatically send an inner txn. This is the most similar to current functionality and just adds a nice QoL to developers. The major downside of this is the complexities around existing B) Increment TxnCounterRather then actually sending a transaction, we could just increment the C) New Field in BlockRather than using My ThoughtsB seems like the quickest way forward but C would make the most since long term in my opinion. While B preserves the current semantics of transaction in terms of units of sequential work, I question how many consumers are actually interpreting transactions that way. The colloquial interpretation of transaction would get lost with B and A seems like unnecessarily doing work during evaluation. Of course, there are many decisions to made if we go the route of C but I feel like it makes the most logical sense |
Option A doesn't sound that bad. It would certainly be annoying if there was the possibility of creating a new weird transaction group. But the txn being created is always a singleton, and need not be configurable in any way. So in the worst case, I think the opcode would just move the existing This also desperately needs to be opted into by an app. You don't want this draining the app account on wasted cycles. (Perhaps you intend that the opup txn must never charge the app account?) |
True, there's no reason we couldn't do this. I suppose it really just seems kinda "ugly" to me. For example it would add a bunch of extra transaction to the simulate response with traces enabled or on explorers. We could make special exceptions to show these transactions differently, but at that point it would just seem simpler to increment the TxnCounter directly.
Yes it's using the |
The main reason I chose to hack on the AVM is because it feels very elegantly designed and that gives an intangible but very real and important joy factor to developing on it. So I believe it's important to make it right, not just to make it work, in a way that can also support future increases of the AVM limits without need to retouch it. To that effect it's worth taking a moment to think from first principles what we want and then figure out the most effective, and least disruptive, implementation strategy. Current context(I might make some mistakes here so please correct me as needed!) Today the main limitations to smart contracts (apps) / logic signatures (lsigs) on the AVM are:
I will focus on the first two here, since 3. is not directly linked to the opcode budget while 2. actually is, given that the program size is also a direct limit on the computation size for things that cannot be "compressed" through loops or subroutines (of course there are a few more low level details like stack depth, scratch space, etc. which I am also ignoring since I've never run into limits with them) Opcode budgetAt the moment we have the following limits:
So you can spend a max of:
To achieve the max possible opcode budget you need to build a transaction group of 16 lsigs signing an app call each and make 256 inner transactions from the app calls, so you can get: 16 * 20,000 + 16 * 700 + 256 * 700 = 510,400 The key here is that you can pool together the lsig budget and have one single lsig consume almost 320,000 by adding 15 dummy lsig transactions and also pool together the app budget and have one single app consume almost 190,400 by adding 15 + 256 dummy app calls but you cannot pool together the two budgets. The "you cannot pool together lsigs and apps budget" makes sense because lsigs are stateless and can run in parallel to app calls. Program size
Also, since apps are composable, and you can call up to 16 + 256 apps, you can have a "super app" split into 16 + 256 apps of 8192 bytes each, so plenty of space. The limit on lsigs really bites instead, lsigs are not composable neither with other lsigs nor with apps, as there is no communication mechanism between lsgis or between lsgis and apps except for success/failure. As a concrete example, a BLS12-381 zk verifier generated by AlgoPlonk consumes ~185,000 opcode budget which is too much to make it an app. This means you are forced to use AlgoPlonk's BN254 verifier which "only" consumes ~145,000 opcode budget. Since it has the same program length as the BLS12-381 one, you need to instantiate is as a smart contract and eat into the overall apps' budget. Now it might be that this specific example can be optimized for program size and eventually even fit in the 1K limit (I haven't worked on that yet) but the general point stays the same. Ideal designMy attempt at an ideal design would be:
This, and the P2P gossip network, are to me the most important changes to the AVM right now. |
Unless I am misunderstanding, that is essentially what this PR is doing. For every additional
Agreed, but seems orthogonal to the problem this PR is specifically addressing. I've created an issue to continue the discussion #5990 |
Yes, I am arguing for solution C) and break free of the inner transaction machinery, so that it works for lsigs too and it's a clean solution. Polluting the ledger with dummy transactions cannot be a long term solutions and will surely come back to bite us sooner or later and will always be more painful to break things later. I'd rather force changes to frontends now if we have to, I'm pretty sure everybody will be happy anyway to get this cleaned up even if creates some short term work.
Thank you for that, I commented there |
Summary
Right now using inner txns is a very common pattern to increase opcode budget within an app call. This works, but it can be quite a clunky experience as a developer trying to figure out where your opups (or opup checks) should be as you iterate. It also leads to some extra bytes in programs and extraneous inner transactions in blocks (and potentially created apps if not properly deleted).
This PR is a proposal to add a new feature that increases the opcode budget by deducting
MinTxnFee
from the fee credit when extra opcode budget is needed.pooledAllowedInners
is used and deducted accordingly to ensure that a single group doesn't consume more budget than what has historically been possible.Test Plan
TestInnerBudgetIncrementFromFee
ensures that this works in applications and verifies budget increase and fee credit deduction works as expected.pooledAllowedInners
is working as expected (or maybe just make it public so it can be verified in tests)TODO