def test_wrap_handler_method_txn_types(): wrapped: pt.Expr = ASTBuilder.wrap_handler(True, multiple_txn) actual: pt.TealBlock = assemble_helper(wrapped) args: list[pt.abi.Transaction] = [ pt.abi.ApplicationCallTransaction(), pt.abi.AssetTransferTransaction(), pt.abi.PaymentTransaction(), pt.abi.Transaction(), ] output_temp = pt.abi.Uint64() expected_ast = pt.Seq( args[0]._set_index(pt.Txn.group_index() - pt.Int(4)), pt.Assert(args[0].get().type_enum() == pt.TxnType.ApplicationCall), args[1]._set_index(pt.Txn.group_index() - pt.Int(3)), pt.Assert(args[1].get().type_enum() == pt.TxnType.AssetTransfer), args[2]._set_index(pt.Txn.group_index() - pt.Int(2)), pt.Assert(args[2].get().type_enum() == pt.TxnType.Payment), args[3]._set_index(pt.Txn.group_index() - pt.Int(1)), multiple_txn(*args).store_into(output_temp), pt.abi.MethodReturn(output_temp), pt.Approve(), ) expected = assemble_helper(expected_ast) with pt.TealComponent.Context.ignoreScratchSlotEquality(), pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected assert pt.TealBlock.MatchScratchSlotReferences( pt.TealBlock.GetReferencedScratchSlots(actual), pt.TealBlock.GetReferencedScratchSlots(expected), )
def swapper(): a = pt.ScratchVar(pt.TealType.bytes) b = pt.ScratchVar(pt.TealType.bytes) return pt.Seq( a.store(pt.Bytes("hello")), b.store(pt.Bytes("goodbye")), cat(a.load(), b.load()), swap(a, b), pt.Assert(a.load() == pt.Bytes("goodbye")), pt.Assert(b.load() == pt.Bytes("hello")), pt.Int(1000), )
def test_teal_2_assert_multi(): args = [pt.Int(1), pt.Int(2)] expr = pt.Assert(*args) assert expr.type_of() == pt.TealType.none firstAssert = pt.Assert(args[0]) secondAssert = pt.Assert(args[1]) expected, _ = pt.Seq(firstAssert, secondAssert).__teal__(avm2Options) actual, _ = expr.__teal__(avm2Options) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_gitxna_expr_invalid(): for f, e in [ ( lambda: pt.GitxnaExpr("Invalid_type", pt.TxnField.application_args, 1), pt.TealInputError, ), ( lambda: pt.GitxnaExpr(1, pt.TxnField.application_args, "Invalid_type"), pt.TealInputError, ), ( lambda: pt.GitxnaExpr( 0, pt.TxnField.application_args, pt.Assert(pt.Int(1)) ), pt.TealTypeError, ), ( lambda: pt.GitxnaExpr(0, pt.TxnField.application_args, 0).__teal__( avm5Options ), pt.TealInputError, ), ]: with pytest.raises(e): f()
def sub_logcat_dynamic(): first = pt.ScratchVar(pt.TealType.bytes) return pt.Seq( first.store(pt.Bytes("hello")), logcat_dynamic(first, pt.Int(42)), pt.Assert(pt.Bytes("hello42") == first.load()), pt.Int(1), )
def test_gtxn_expr_invalid(): for f, e in [ ( lambda: pt.GtxnExpr(pt.Assert(pt.Int(1)), pt.TxnField.sender), pt.TealTypeError, ), ]: with pytest.raises(e): f()
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_gtxna_expr_invalid(): for f, e in [ ( lambda: pt.GtxnaExpr("Invalid_type", pt.TxnField.assets, 1), pt.TealInputError, ), ( lambda: pt.GtxnaExpr(1, pt.TxnField.assets, "Invalid_type"), pt.TealInputError, ), ( lambda: pt.GtxnaExpr(pt.Assert(pt.Int(1)), pt.TxnField.assets, 1), pt.TealTypeError, ), ( lambda: pt.GtxnaExpr(1, pt.TxnField.assets, pt.Assert(pt.Int(1))), pt.TealTypeError, ), ]: with pytest.raises(e): f()
def test_teal_3_assert(): arg = pt.Int(1) expr = pt.Assert(arg) assert expr.type_of() == pt.TealType.none expected = pt.TealSimpleBlock( [pt.TealOp(arg, pt.Op.int, 1), pt.TealOp(expr, pt.Op.assert_)]) actual, _ = expr.__teal__(avm3Options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert actual == expected
def test_ArrayElement_init(): dynamicArrayType = abi.DynamicArrayTypeSpec(abi.Uint64TypeSpec()) array = dynamicArrayType.new_instance() index = pt.Int(6) element = abi.ArrayElement(array, index) assert element.array is array assert element.index is index with pytest.raises(pt.TealTypeError): abi.ArrayElement(array, pt.Bytes("abc")) with pytest.raises(pt.TealTypeError): abi.ArrayElement(array, pt.Assert(index))
def test_teal_2_assert(): arg = pt.Int(1) expr = pt.Assert(arg) assert expr.type_of() == pt.TealType.none expected, _ = arg.__teal__(avm2Options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(pt.TealSimpleBlock([])) expectedBranch.setFalseBlock(pt.Err().__teal__(avm2Options)[0]) expected.setNextBlock(expectedBranch) actual, _ = expr.__teal__(avm2Options) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_assert_comment(): comment = "Make sure 1 is true" expr = pt.Assert(pt.Int(1), comment=comment) assert expr.type_of() == pt.TealType.none expected = pt.TealSimpleBlock([ pt.TealOp(None, pt.Op.int, 1), pt.TealOp(None, pt.Op.comment, comment), pt.TealOp(None, pt.Op.assert_), ]) actual, _ = expr.__teal__(avm3Options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_teal_3_assert_multi(): args = [pt.Int(1), pt.Int(2)] expr = pt.Assert(*args) assert expr.type_of() == pt.TealType.none expected = pt.TealSimpleBlock( [pt.TealOp(args[0], pt.Op.int, 1), pt.TealOp(expr, pt.Op.assert_)] + [pt.TealOp(args[1], pt.Op.int, 2), pt.TealOp(expr, pt.Op.assert_)]) actual, _ = expr.__teal__(avm3Options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def __test_single_assert(expr: pt.MultiValue, op, args: List[pt.Expr], iargs, reducer): __test_single(expr) expected_call = pt.TealSimpleBlock([ pt.TealOp(expr, op, *iargs), pt.TealOp(expr.output_slots[1].store(), pt.Op.store, expr.output_slots[1]), pt.TealOp(expr.output_slots[0].store(), pt.Op.store, expr.output_slots[0]), ]) assertExpr = pt.Seq(pt.Assert(expr.output_slots[1].load()), expr.output_slots[0].load()) assertBlockStart, _ = assertExpr.__teal__(options) expected_call.setNextBlock(assertBlockStart) if len(args) == 0: expected: pt.TealBlock = expected_call elif len(args) == 1: expected, after_arg = args[0].__teal__(options) after_arg.setNextBlock(expected_call) elif len(args) == 2: expected, after_arg_1 = args[0].__teal__(options) arg_2, after_arg_2 = args[1].__teal__(options) after_arg_1.setNextBlock(arg_2) after_arg_2.setNextBlock(expected_call) expected.addIncoming() expected = pt.TealBlock.NormalizeBlocks(expected) actual, _ = expr.outputReducer(reducer).__teal__(options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected
def test_multi_value(op, type, iargs, args): reducer = (lambda value, hasValue: pt.If(hasValue).Then(value).Else( pt.App.globalGet(pt.Bytes("None")))) expr = pt.MultiValue(op, [type, pt.TealType.uint64], immediate_args=iargs, args=args) __test_single_conditional(expr, op, args, iargs, reducer) reducer = lambda value, hasValue: pt.Seq(pt.Assert(hasValue), value ) # noqa: E731 expr = pt.MultiValue(op, [type, pt.TealType.uint64], immediate_args=iargs, args=args) __test_single_assert(expr, op, args, iargs, reducer) hasValueVar = pt.ScratchVar(pt.TealType.uint64) valueVar = pt.ScratchVar(type) reducer = lambda value, hasValue: pt.Seq( # noqa: E731 hasValueVar.store(hasValue), valueVar.store(value)) expr = pt.MultiValue(op, [type, pt.TealType.uint64], immediate_args=iargs, args=args) __test_single_with_vars(expr, op, args, iargs, hasValueVar, valueVar, reducer)
def asserts(): return [pt.Assert(x.load() == pt.Int(i + 2)) for i, x in enumerate(xs)]
def test_assert_invalid(): with pytest.raises(pt.TealTypeError): pt.Assert(pt.Txn.receiver()) with pytest.raises(pt.TealTypeError): pt.Assert(pt.Int(1), pt.Txn.receiver())
def sub_logcat(): return pt.Seq( pt.Assert( logcat(pt.Bytes("hello"), pt.Int(42)) == pt.Bytes("hello42")), pt.Int(1), )
def test_wrap_handler_method_call(): with pytest.raises(pt.TealInputError) as bug: ASTBuilder.wrap_handler(True, not_registrable) assert "method call ABIReturnSubroutine is not routable" in str(bug) with pytest.raises(pt.TealInputError) as bug: ASTBuilder.wrap_handler(True, safe_clear_state_delete) assert "method call should be only registering ABIReturnSubroutine" in str(bug) ONLY_ABI_SUBROUTINE_CASES = list( filter(lambda x: isinstance(x, pt.ABIReturnSubroutine), GOOD_SUBROUTINE_CASES) ) for abi_subroutine in ONLY_ABI_SUBROUTINE_CASES: wrapped: pt.Expr = ASTBuilder.wrap_handler(True, abi_subroutine) actual: pt.TealBlock = assemble_helper(wrapped) args: list[pt.abi.BaseType] = [ spec.new_instance() for spec in typing.cast( list[pt.abi.TypeSpec], abi_subroutine.subroutine.expected_arg_types ) ] app_args = [ arg for arg in args if arg.type_spec() not in pt.abi.TransactionTypeSpecs ] app_arg_cnt = len(app_args) txn_args: list[pt.abi.Transaction] = [ arg for arg in args if arg.type_spec() in pt.abi.TransactionTypeSpecs ] loading: list[pt.Expr] = [] if app_arg_cnt > pt.METHOD_ARG_NUM_CUTOFF: sdk_last_arg = pt.abi.TupleTypeSpec( *[arg.type_spec() for arg in app_args[pt.METHOD_ARG_NUM_CUTOFF - 1 :]] ).new_instance() loading = [ arg.decode(pt.Txn.application_args[index + 1]) for index, arg in enumerate(app_args[: pt.METHOD_ARG_NUM_CUTOFF - 1]) ] loading.append( sdk_last_arg.decode(pt.Txn.application_args[pt.METHOD_ARG_NUM_CUTOFF]) ) else: loading = [ arg.decode(pt.Txn.application_args[index + 1]) for index, arg in enumerate(app_args) ] if len(txn_args) > 0: for idx, txn_arg in enumerate(txn_args): loading.append( txn_arg._set_index( pt.Txn.group_index() - pt.Int(len(txn_args) - idx) ) ) if str(txn_arg.type_spec()) != "txn": loading.append( pt.Assert( txn_arg.get().type_enum() == txn_arg.type_spec().txn_type_enum() ) ) if app_arg_cnt > pt.METHOD_ARG_NUM_CUTOFF: loading.extend( [ sdk_last_arg[idx].store_into(val) for idx, val in enumerate(app_args[pt.METHOD_ARG_NUM_CUTOFF - 1 :]) ] ) evaluate: pt.Expr if abi_subroutine.type_of() != "void": output_temp = abi_subroutine.output_kwarg_info.abi_type.new_instance() evaluate = pt.Seq( abi_subroutine(*args).store_into(output_temp), pt.abi.MethodReturn(output_temp), ) else: evaluate = abi_subroutine(*args) expected = assemble_helper(pt.Seq(*loading, evaluate, pt.Approve())) with pt.TealComponent.Context.ignoreScratchSlotEquality(), pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected assert pt.TealBlock.MatchScratchSlotReferences( pt.TealBlock.GetReferencedScratchSlots(actual), pt.TealBlock.GetReferencedScratchSlots(expected), )