Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Quasi-bug: TEAL Output is Unstable #199

@tzaffi

Description

@tzaffi

TEAL Output Should be Stable When No Changes are Made to the Actual Compilation

Why is this useful

This would allow us to have less flaky end-to-end tests and assert that nothing about the PyTEAL compiler has affected between versions.

For example, consider this PyTEAL:

@Subroutine(TealType.none)
def swap(x: ScratchVar, y: ScratchVar):
    z = ScratchVar(TealType.anytype)
    return Seq(
        z.store(x.load()),
        x.store(y.load()),
        y.store(z.load()),
    )

@Subroutine(TealType.none)
def cat(x, y):
    return Pop(Concat(x, y))


def swapper():
    a = ScratchVar(TealType.bytes)
    b = ScratchVar(TealType.bytes)
    return Seq(
        a.store(Bytes("hello")),
        b.store(Bytes("goodbye")),
        cat(a.load(), b.load()),
        swap(a, b),
        Assert(a.load() == Bytes("goodbye")),
        Assert(b.load() == Bytes("hello")),
        Int(1000),
    )

I was able to generate the following 2 equivalent TEAL programs by changing some python code that didn't touch the actual compilation code:

Before Change

#pragma version 6
byte "hello"
store 0          
byte "goodbye"
store 1          
load 0
load 1
callsub cat_1
int 0
int 1
callsub swap_0   
load 0           
byte "goodbye"
==
assert           
load 1           
byte "hello"
==
assert           
int 1000         
return

// swap
swap_0:
store 3          
store 2          
load 2           
loads            
store 4          
load 2           
load 3           
loads            
stores           
load 3           
load 4           
stores           
retsub

// cat
cat_1:
store 6
store 5
load 5
load 6
concat
pop
retsub

After Change

#pragma version 6
byte "hello"
store 5
byte "goodbye"
store 6
load 5
load 6
callsub cat_1
int 5
int 6
callsub swap_0
load 5
byte "goodbye"
==
assert
load 6
byte "hello"
==
assert
int 1000
return

// swap
swap_0:
store 1
store 0
load 0
loads
store 2
load 0
load 1
loads
stores
load 1
load 2
stores
retsub

// cat
cat_1:
store 4
store 3
load 3
load 4
concat
pop
retsub

Steps to reproduce - this is non-trivial

  1. Compile a big program with several subroutines
  2. Make some significant change. I believe, for example, renaming ScratchVar to TemporaryRenamedScratchVar or changing the __hash__() method of ScratchSlots might do it.
  3. Compile again and notice that slot id's and possibly subroutine id's are not all the same

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions