algorand / pyteal

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

DynamicScratchVar: User-defined DynamicScratchVars in @Subroutines produce opaque errors #232

Closed michaeldiamant closed 2 years ago

michaeldiamant commented 2 years ago

Problem

Starting assumption:

With the assumption in mind, consider https://github.com/michaeldiamant/pyteal/pull/3/.

The problem might be two-fold:

Solution

Several options exist:

Dependencies

N/A

Urgency

TBD - Unclear how often users will run into the class of problem and find it challenging to debug the error message.

tzaffi commented 2 years ago

If this is a "pure research" ticket aimed mostly at seeing the viability of just removing the warning and proposing the next steps then this shouldn't be too onerous (probably 1-2 points).

tzaffi commented 2 years ago

Good news. When I loosened the restriction on using DynamicScratchVar's and made a slight tweak to the included program (there was an off-by-1 error in asserts() the program passed with flying colors. Here's the tweak that worked:

def should_it_work() -> Expr:
    xs = [
        ScratchVar(TealType.uint64),
        ScratchVar(TealType.uint64),
    ]

    def store_initial_values():
        return [s.store(Int(i + 1)) for i, s in enumerate(xs)]

    d = DynamicScratchVar(TealType.uint64)

    @Subroutine(TealType.none)
    def retrieve_and_increment(s: ScratchVar):
        return Seq(d.set_index(s), d.store(d.load() + Int(1)))

    def asserts():
        return [Assert(x.load() == Int(i + 2)) for i, x in enumerate(xs)]

    return Seq(
        Seq(store_initial_values()),
        Seq([retrieve_and_increment(x) for x in xs]),
        Seq(asserts()),
        Int(1),
    )
michaeldiamant commented 2 years ago

@tzaffi Thanks for taking a closer look. I reflected your findings into #242.

Closing - See #242 for rationale.