def test_dynamic_scratchvar_type(): myvar_default = pt.DynamicScratchVar() assert myvar_default.storage_type() == pt.TealType.anytype assert myvar_default.store(pt.Bytes("value")).type_of() == pt.TealType.none assert myvar_default.load().type_of() == pt.TealType.anytype with pytest.raises(pt.TealTypeError): myvar_default.store(pt.Pop(pt.Int(1))) myvar_int = pt.DynamicScratchVar(pt.TealType.uint64) assert myvar_int.storage_type() == pt.TealType.uint64 assert myvar_int.store(pt.Int(1)).type_of() == pt.TealType.none assert myvar_int.load().type_of() == pt.TealType.uint64 with pytest.raises(pt.TealTypeError): myvar_int.store(pt.Bytes("value")) with pytest.raises(pt.TealTypeError): myvar_int.store(pt.Pop(pt.Int(1))) myvar_bytes = pt.DynamicScratchVar(pt.TealType.bytes) assert myvar_bytes.storage_type() == pt.TealType.bytes assert myvar_bytes.store(pt.Bytes("value")).type_of() == pt.TealType.none assert myvar_bytes.load().type_of() == pt.TealType.bytes with pytest.raises(pt.TealTypeError): myvar_bytes.store(pt.Int(0)) with pytest.raises(pt.TealTypeError): myvar_bytes.store(pt.Pop(pt.Int(1)))
def test_dynamic_scratchvar_cannot_set_index_to_another_dynamic(): myvar = pt.DynamicScratchVar() myvar.load() regvar = pt.ScratchVar() myvar.set_index(regvar) dynvar = pt.DynamicScratchVar() with pytest.raises(pt.TealInputError): myvar.set_index(dynvar)
def test_dynamic_scratchvar_index(): myvar = pt.DynamicScratchVar() expr = myvar.index() expected = pt.TealSimpleBlock([pt.TealOp(expr, pt.Op.load, myvar.slot)]) actual, _ = expr.__teal__(options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert actual == expected
def test_dynamic_scratchvar_load(): myvar = pt.DynamicScratchVar() expr = myvar.load() expected = pt.TealSimpleBlock( [ pt.TealOp(pt.ScratchLoad(myvar.slot), pt.Op.load, myvar.slot), pt.TealOp(expr, pt.Op.loads), ] ) actual, _ = expr.__teal__(options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_dynamic_scratchvar_store(): myvar = pt.DynamicScratchVar(pt.TealType.bytes) arg = pt.Bytes("value") expr = myvar.store(arg) expected = pt.TealSimpleBlock( [ pt.TealOp(pt.ScratchLoad(myvar.slot), pt.Op.load, myvar.slot), pt.TealOp(arg, pt.Op.byte, '"value"'), pt.TealOp(expr, pt.Op.stores), ] ) actual, _ = expr.__teal__(options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def wilt_the_stilt(): player_score = pt.DynamicScratchVar(pt.TealType.uint64) wilt = pt.ScratchVar(pt.TealType.uint64, 129) kobe = pt.ScratchVar(pt.TealType.uint64) dt = pt.ScratchVar(pt.TealType.uint64, 131) return pt.Seq( player_score.set_index(wilt), player_score.store(pt.Int(100)), player_score.set_index(kobe), player_score.store(pt.Int(81)), player_score.set_index(dt), player_score.store(pt.Int(73)), pt.Assert(player_score.load() == pt.Int(73)), pt.Assert(player_score.index() == pt.Int(131)), player_score.set_index(wilt), pt.Assert(player_score.load() == pt.Int(100)), pt.Assert(player_score.index() == pt.Int(129)), pt.Int(100), )
def test_optimize_dynamic_var(): myvar = pt.DynamicScratchVar() regvar = pt.ScratchVar() program = pt.Seq( regvar.store(pt.Int(1)), myvar.set_index(regvar), regvar.store(pt.Int(2)), pt.Pop(regvar.load()), pt.Approve(), ) optimize_options = OptimizeOptions() # unoptimized expected = """#pragma version 4 int 1 store 1 int 1 store 0 int 2 store 1 load 1 pop int 1 return""".strip() actual = pt.compileTeal(program, version=4, mode=pt.Mode.Application, optimize=optimize_options) assert actual == expected # optimization should not change the code because the candidate slot # is used by the dynamic slot variable. optimize_options = OptimizeOptions(scratch_slots=True) actual = pt.compileTeal(program, version=4, mode=pt.Mode.Application, optimize=optimize_options) assert actual == expected
def empty_scratches(): cursor = pt.DynamicScratchVar() i1 = pt.ScratchVar(pt.TealType.uint64, 0) i2 = pt.ScratchVar(pt.TealType.uint64, 2) i3 = pt.ScratchVar(pt.TealType.uint64, 4) s1 = pt.ScratchVar(pt.TealType.bytes, 1) s2 = pt.ScratchVar(pt.TealType.bytes, 3) s3 = pt.ScratchVar(pt.TealType.bytes, 5) return pt.Seq( cursor.set_index(i1), cursor.store(pt.Int(0)), cursor.set_index(s1), cursor.store(pt.Bytes("")), cursor.set_index(i2), cursor.store(pt.Int(0)), cursor.set_index(s2), cursor.store(pt.Bytes("")), cursor.set_index(i3), cursor.store(pt.Int(0)), cursor.set_index(s3), cursor.store(pt.Bytes("")), pt.Int(42), )
def should_it_work() -> pt.Expr: xs = [ pt.ScratchVar(pt.TealType.uint64), pt.ScratchVar(pt.TealType.uint64), ] def store_initial_values(): return [s.store(pt.Int(i + 1)) for i, s in enumerate(xs)] d = pt.DynamicScratchVar(pt.TealType.uint64) @pt.Subroutine(pt.TealType.none) def retrieve_and_increment(s: pt.ScratchVar): return pt.Seq(d.set_index(s), d.store(d.load() + pt.Int(1))) def asserts(): return [pt.Assert(x.load() == pt.Int(i + 2)) for i, x in enumerate(xs)] return pt.Seq( pt.Seq(store_initial_values()), pt.Seq([retrieve_and_increment(x) for x in xs]), pt.Seq(asserts()), pt.Int(1), )
def lots_o_vars(): z = pt.Int(0) one = pt.ScratchVar() two = pt.ScratchVar() three = pt.ScratchVar() four = pt.ScratchVar() five = pt.Bytes("five") six = pt.Bytes("six") seven = pt.Bytes("seven") eight = pt.Bytes("eight") nine = pt.Bytes("nine") ten = pt.Bytes("ten") eleven = pt.Bytes("eleven") twelve = pt.Bytes("twelve") int_cursor = pt.DynamicScratchVar(pt.TealType.uint64) bytes_cursor = pt.DynamicScratchVar(pt.TealType.bytes) thirteen = pt.ScratchVar(pt.TealType.uint64, 13) fourteen = pt.ScratchVar(pt.TealType.bytes, 14) fifteen = pt.ScratchVar(pt.TealType.uint64) sixteen = pt.ScratchVar(pt.TealType.bytes) leet = pt.Int(1337) ngl = pt.Bytes("NGL: ") return (pt.If( pt.Or(pt.App.id() == pt.Int(0), pt.Txn.application_args.length() == pt.Int(0))).Then( pt.Int(1)).Else( pt.Seq( one.store(pt.Int(1)), two.store(pt.Bytes("two")), three.store(pt.Int(3)), four.store(pt.Bytes("four")), pt.App.localPut(z, five, pt.Int(5)), pt.App.localPut(z, six, six), pt.App.localPut(z, seven, pt.Int(7)), pt.App.localPut(z, eight, eight), pt.App.globalPut(nine, pt.Int(9)), pt.App.globalPut(ten, ten), pt.App.globalPut(eleven, pt.Int(11)), pt.App.globalPut(twelve, twelve), one.store(one.load() + leet), two.store(pt.Concat(ngl, two.load())), three.store(three.load() + leet), four.store(pt.Concat(ngl, four.load())), pt.App.localPut(z, five, leet + pt.App.localGet(z, five)), pt.App.localPut( z, six, pt.Concat(ngl, pt.App.localGet(z, six))), pt.App.localPut(z, seven, pt.App.localGet(z, seven)), pt.App.localPut( z, eight, pt.Concat(ngl, pt.App.localGet(z, eight))), pt.App.globalPut(nine, leet + pt.App.globalGet(nine)), pt.App.globalPut( ten, pt.Concat(ngl, pt.App.globalGet(ten))), pt.App.globalPut(eleven, leet + pt.App.globalGet(eleven)), pt.App.globalPut( twelve, pt.Concat(ngl, pt.App.globalGet(twelve))), thirteen.store(pt.Btoi(pt.Txn.application_args[0])), fourteen.store(pt.Txn.application_args[1]), fifteen.store(pt.Btoi(pt.Txn.application_args[2])), sixteen.store(pt.Txn.application_args[3]), pt.Pop(one.load()), pt.Pop(two.load()), pt.Pop(three.load()), pt.Pop(four.load()), pt.Pop(pt.App.localGet(z, five)), pt.Pop(pt.App.localGet(z, six)), pt.Pop(pt.App.localGet(z, seven)), pt.Pop(pt.App.localGet(z, eight)), pt.Pop(pt.App.globalGet(nine)), pt.Pop(pt.App.globalGet(ten)), pt.Pop(pt.App.globalGet(eleven)), pt.Pop(pt.App.globalGet(twelve)), int_cursor.set_index(thirteen), pt.Log(pt.Itob(int_cursor.load())), bytes_cursor.set_index(fourteen), pt.Log(bytes_cursor.load()), int_cursor.set_index(fifteen), pt.Log(pt.Itob(int_cursor.load())), bytes_cursor.set_index(sixteen), pt.Log(bytes_cursor.load()), leet, )))