algorand / pyteal

Algorand Smart Contracts in Python
https://pyteal.readthedocs.io
MIT License
285 stars 131 forks source link

Pyteal utility to get more opcode budget #169

Closed algoanne closed 2 years ago

algoanne commented 2 years ago

Context TEAL Contracts have a 700 opcode budget limitation on compute. This limit has been an issue for some use cases.

The upcoming contract-to-contract functionality includes pooled opcode budget across contracts that were called by another contract. Therefore, once this is released, devs who need more opcode budget for their program (and are willing to pay for it) will be able to make an artificial contract call that simply returns. This will give them an additional 700 opcode budget. They can theoretically do this many times (256) to keep adding budget as they need it.

What are you looking for? We want to make the above "hack" simple to do in pyteal, by offering a pyteal function that can be called to get more opcode budget - with the budget asked for as an input.

Why is it useful? makes it easy to get more opcode budget for a contract.

Notes Devs will still need to know/figure out (or have a good guess) how much opcode budget their contract will need when called.

barnjamin commented 2 years ago

who you gonna call?

Because we're not allowed to call ourselves to prevent re-entrant behavior there must be some external application that can be called to increase the budget. A couple options

  1. Create "dummy" app ahead of time, always pass it in to app calls that may need more budget. Downside is that it takes up some slot for foreign apps and workflow is a little awkward.
  2. Create "dummy" app at runtime and use it to dispatch additional application calls as needed. Downside is it creates a lot of applications that might give the indexer a hard time and you'd want to delete the application in the same transaction.

are you gonna call me? is this even your real phone number?

Knowing when to ask for more budget is not always straightforward. The evaluation of a contract may take a number of different code paths with different budget needs depending on the transactions or state.

A good pattern might be to profile the logic ahead of time and for certain expensive methods, call some ensure_opcode_budget(N) method that checks the current remaining budget and if necessary makes some number of transactions to ensure the budget is at least N. The value N should be determined ahead of time based on profiling or automated opcode cost summation for that section.

algoanne commented 2 years ago

design consideration: to add this budget, could create a contract that immediately deletes itself on complete. would be nice to optimize this that it never is written to the database. however, indexer will remember it forever.

will have follow-up work to design a better long-term solution that doesn't create lots of app ids and clog up indexer.

tzaffi commented 2 years ago

Here is a design doc put together by @shiqizng

tzaffi commented 2 years ago

This Op Up Demo by @barnjamin shows a way one might approach this problem

tzaffi commented 2 years ago

Recent addition to the dev portal: https://developer.algorand.org/tutorials/understanding-teal-opcode-budget/#5-expanding-the-budget

fabrice102 commented 2 years ago

Here are two random thoughts:

For "who you gonna call?": What about having a special application ID that would be used as dummy application (like application ID 2^64-1, also maybe this can be an issue with JS that does not support integers above 2^53 or so)? That requires a change in the blockchain though.

For "are you gonna call me? is this even your real phone number?" The ABI metadata may indicate a max fee needed per application call so at least there is a way to get a fee that will always work. We could imagine having some simulation but that may not always return the correct value in all cases.