Skip to content

Commit

Permalink
Add Execute Method (#444)
Browse files Browse the repository at this point in the history
* adding execute method to allow omission of begin/submit for common use case

* exec docstring

* update testcase

Co-authored-by: Hang Su <hang.su@algorand.com>
  • Loading branch information
barnjamin and ahangsu committed Jul 20, 2022
1 parent 25c6898 commit c936cbc
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 19 deletions.
21 changes: 21 additions & 0 deletions pyteal/ast/itxn.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,27 @@ def SetField(cls, field: TxnField, value: Union[Expr, List[Expr]]) -> Expr:
]
)

@classmethod
def Execute(cls, fields: Dict[TxnField, Union[Expr, List[Expr]]]) -> Expr:
"""Performs a single transaction given fields passed in.
A convenience method that accepts fields to submit a single inner transaction, which is equivalent to:
.. code-block:: python
InnerTxnBuilder.Begin()
InnerTxnBuilder.SetFields(fields)
InnerTxnBuilder.End()
Requires TEAL version 5 or higher. This operation is only permitted in application mode.
Args:
fields: A dictionary whose keys are fields to set and whose values are the value each
field should take. Each value must evaluate to a type that is compatible with the
field being set.
"""
return Seq(cls.Begin(), cls.SetFields(fields), cls.Submit())

@classmethod
def SetFields(cls, fields: Dict[TxnField, Union[Expr, List[Expr]]]) -> Expr:
"""Set multiple fields of the current inner transaction.
Expand Down
62 changes: 43 additions & 19 deletions pyteal/ast/itxn_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,28 +92,29 @@ def test_InnerTxnBuilder_SetField():
expr.__teal__(teal4Options)


def test_InnerTxnBuilder_SetFields():
cases = (
({}, pt.Seq()),
(
{pt.TxnField.amount: pt.Int(5)},
pt.InnerTxnBuilder.SetField(pt.TxnField.amount, pt.Int(5)),
),
(
{
pt.TxnField.type_enum: pt.TxnType.Payment,
pt.TxnField.close_remainder_to: pt.Txn.sender(),
},
pt.Seq(
pt.InnerTxnBuilder.SetField(pt.TxnField.type_enum, pt.TxnType.Payment),
pt.InnerTxnBuilder.SetField(
pt.TxnField.close_remainder_to, pt.Txn.sender()
),
ITXN_FIELDS_CASES = [
({}, pt.Seq()),
(
{pt.TxnField.amount: pt.Int(5)},
pt.InnerTxnBuilder.SetField(pt.TxnField.amount, pt.Int(5)),
),
(
{
pt.TxnField.type_enum: pt.TxnType.Payment,
pt.TxnField.close_remainder_to: pt.Txn.sender(),
},
pt.Seq(
pt.InnerTxnBuilder.SetField(pt.TxnField.type_enum, pt.TxnType.Payment),
pt.InnerTxnBuilder.SetField(
pt.TxnField.close_remainder_to, pt.Txn.sender()
),
),
)
),
]


for fields, expectedExpr in cases:
def test_InnerTxnBuilder_SetFields():
for fields, expectedExpr in ITXN_FIELDS_CASES:
expr = pt.InnerTxnBuilder.SetFields(fields)
assert expr.type_of() == pt.TealType.none
assert not expr.has_return()
Expand All @@ -134,4 +135,27 @@ def test_InnerTxnBuilder_SetFields():
expr.__teal__(teal4Options)


def test_InnerTxnBuilder_Execute():
for fields, expectedExpr in ITXN_FIELDS_CASES:
expr = pt.InnerTxnBuilder.Execute(fields)

expected, _ = pt.Seq(
pt.InnerTxnBuilder.Begin(),
expectedExpr,
pt.InnerTxnBuilder.Submit(),
).__teal__(teal5Options)
expected.addIncoming()
expected = pt.TealBlock.NormalizeBlocks(expected)

actual, _ = expr.__teal__(teal5Options)
actual.addIncoming()
actual = pt.TealBlock.NormalizeBlocks(actual)

with pt.TealComponent.Context.ignoreExprEquality():
assert actual == expected

with pytest.raises(pt.TealInputError):
expr.__teal__(teal4Options)


# txn_test.py performs additional testing

0 comments on commit c936cbc

Please sign in to comment.