Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method call itxn #387

Merged
merged 54 commits into from
Jun 28, 2022
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
8ac26ea
define reference type spec
barnjamin Jun 6, 2022
531fe7d
fmt, lint
barnjamin Jun 6, 2022
af97dda
merge
barnjamin Jun 6, 2022
ad85a13
adding itxn method call method
barnjamin Jun 7, 2022
cdc21f1
moved method_return to ast
barnjamin Jun 7, 2022
d8ac02b
fmt
barnjamin Jun 7, 2022
cb2f236
Create params and holding objects for references (#385)
jasonpaulos Jun 8, 2022
7628696
Merge branch 'feature/abi' into reference-typespec
barnjamin Jun 8, 2022
a13d025
Merge branch 'reference-typespec' into method-call-itxn
barnjamin Jun 8, 2022
c8b779b
tmp
barnjamin Jun 8, 2022
10b3cae
Merge branch 'reference-typespec' into method-call-itxn
barnjamin Jun 8, 2022
9b4ae65
merged and type checking
barnjamin Jun 8, 2022
8d6b406
fix method return imports
barnjamin Jun 8, 2022
07e8419
gen init
barnjamin Jun 8, 2022
23cb458
fmt
barnjamin Jun 8, 2022
403c79a
Merge branch 'reference-typespec' into method-call-itxn
barnjamin Jun 8, 2022
f2a6f9f
another method return path fix
barnjamin Jun 8, 2022
d7604da
adding transactions
barnjamin Jun 8, 2022
58d4784
Fmt
barnjamin Jun 8, 2022
b9bc181
allow passing fields for app call transaction
barnjamin Jun 8, 2022
765ecb0
rename
barnjamin Jun 8, 2022
14f11b0
more explicit uint8ify, add comments
barnjamin Jun 8, 2022
3401a3d
making MethodCall use kwargs
barnjamin Jun 8, 2022
1382fc1
merge
barnjamin Jun 8, 2022
3d1777a
Update pyteal/ast/abi/util.py
barnjamin Jun 9, 2022
85b07be
Update pyteal/ast/abi/util_test.py
barnjamin Jun 9, 2022
d938c0f
Update pyteal/ast/abi/util.py
barnjamin Jun 9, 2022
eb57c34
Update pyteal/ast/router.py
barnjamin Jun 9, 2022
95c1d40
Update pyteal/ast/itxn.py
barnjamin Jun 9, 2022
1151146
Update pyteal/ast/itxn.py
barnjamin Jun 9, 2022
fca4ac8
Update pyteal/ast/itxn.py
barnjamin Jun 9, 2022
9d1bf7d
fix union notation
barnjamin Jun 9, 2022
243d7a4
fix test
barnjamin Jun 9, 2022
8a320a1
fmt
barnjamin Jun 9, 2022
3305f13
update to use 3.10 notation everywhere in itxn
barnjamin Jun 9, 2022
c8c9d76
Adding test cases for method sig => types method
barnjamin Jun 9, 2022
5c4c202
return None if
barnjamin Jun 9, 2022
d74b846
fix typing
barnjamin Jun 9, 2022
211fa11
Adding test cases for MethodCall
barnjamin Jun 9, 2022
cbefd19
modify and use uint_encode
barnjamin Jun 9, 2022
67054a8
Update pyteal/ast/abi/util.py
barnjamin Jun 13, 2022
405fe92
parameterizing cases
barnjamin Jun 13, 2022
54aac18
fix types
barnjamin Jun 13, 2022
bc689f1
Fix recursive import in a different way (#420)
jasonpaulos Jun 27, 2022
83b77ba
partial cr
barnjamin Jun 27, 2022
49c6fc7
adding check for transaction type
barnjamin Jun 27, 2022
06bcb40
starting doc string
barnjamin Jun 27, 2022
f059da1
starting doc string
barnjamin Jun 27, 2022
6f21749
improve tests, rename fields to extra_fields
barnjamin Jun 28, 2022
79f1ed6
add check for match scratch slot refs
barnjamin Jun 28, 2022
b3c2468
improve tests and docstring further, mypy doesnt like walrus
barnjamin Jun 28, 2022
66c4239
fix mypy issues
barnjamin Jun 28, 2022
02e77ed
fix ref test
barnjamin Jun 28, 2022
04b9168
adding additional check, fixup docs
barnjamin Jun 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyteal/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ __all__ = [
"MIN_TEAL_VERSION",
"MaybeValue",
"MethodConfig",
"MethodReturn",
"MethodSignature",
"MinBalance",
"Minus",
Expand Down
4 changes: 4 additions & 0 deletions pyteal/ast/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@
from pyteal.ast.continue_ import Continue

# misc

from pyteal.ast.method_return import MethodReturn

from pyteal.ast.scratch import (
ScratchIndex,
ScratchLoad,
Expand Down Expand Up @@ -305,4 +308,5 @@
"EcdsaVerify",
"EcdsaDecompress",
"EcdsaRecover",
"MethodReturn",
]
6 changes: 4 additions & 2 deletions pyteal/ast/abi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
AssetTypeSpec,
Application,
ApplicationTypeSpec,
ReferenceType,
ReferenceTypeSpec,
ReferenceTypeSpecs,
)
from pyteal.ast.abi.transaction import (
Expand All @@ -60,7 +62,6 @@
KeyRegisterTransactionTypeSpec,
TransactionTypeSpecs,
)
from pyteal.ast.abi.method_return import MethodReturn
from pyteal.ast.abi.util import (
algosdk_from_annotation,
algosdk_from_type_spec,
Expand All @@ -79,6 +80,8 @@
"AssetTypeSpec",
"Application",
"ApplicationTypeSpec",
"ReferenceType",
"ReferenceTypeSpec",
"ReferenceTypeSpecs",
"Address",
"AddressTypeSpec",
Expand Down Expand Up @@ -117,7 +120,6 @@
"StaticArray",
"DynamicArrayTypeSpec",
"DynamicArray",
"MethodReturn",
"Transaction",
"TransactionTypeSpec",
"PaymentTransaction",
Expand Down
14 changes: 9 additions & 5 deletions pyteal/ast/abi/uint.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,24 @@ def uint_decode(
raise ValueError("Unsupported uint size: {}".format(size))


def uint_encode(size: int, uintVar: ScratchVar) -> Expr:
def uint_encode(size: int, uintVar: Expr | ScratchVar) -> Expr:

if isinstance(uintVar, ScratchVar):
uintVar = uintVar.load()

if size > 64:
raise NotImplementedError(
"Uint operations have not yet been implemented for bit sizes larger than 64"
)

if size == 8:
return SetByte(Bytes(b"\x00"), Int(0), uintVar.load())
return SetByte(Bytes(b"\x00"), Int(0), uintVar)
if size == 16:
return Suffix(Itob(uintVar.load()), Int(6))
return Suffix(Itob(uintVar), Int(6))
if size == 32:
return Suffix(Itob(uintVar.load()), Int(4))
return Suffix(Itob(uintVar), Int(4))
if size == 64:
return Itob(uintVar.load())
return Itob(uintVar)

raise ValueError("Unsupported uint size: {}".format(size))

Expand Down
100 changes: 99 additions & 1 deletion pyteal/ast/abi/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
from typing import Sequence, TypeVar, Any, Literal, get_origin, get_args, cast
from typing import (
Any,
Literal,
Optional,
Sequence,
TypeVar,
Union,
cast,
get_args,
get_origin,
)

import algosdk.abi

Expand Down Expand Up @@ -379,3 +389,91 @@ def algosdk_from_type_spec(t: TypeSpec) -> algosdk.abi.ABIType:

def algosdk_from_annotation(t: type[T]) -> algosdk.abi.ABIType:
return algosdk_from_type_spec(type_spec_from_annotation(t))


def type_spec_from_algosdk(t: Union[algosdk.abi.ABIType, str]) -> TypeSpec:

from pyteal.ast.abi.reference_type import ReferenceTypeSpecs
from pyteal.ast.abi.transaction import TransactionTypeSpecs

from pyteal.ast.abi.array_dynamic import DynamicArrayTypeSpec
from pyteal.ast.abi.array_static import StaticArrayTypeSpec
from pyteal.ast.abi.tuple import TupleTypeSpec
from pyteal.ast.abi.bool import BoolTypeSpec
from pyteal.ast.abi.string import StringTypeSpec
from pyteal.ast.abi.address import AddressTypeSpec
from pyteal.ast.abi.uint import (
ByteTypeSpec,
Uint8TypeSpec,
Uint16TypeSpec,
Uint32TypeSpec,
Uint64TypeSpec,
)

match t:
# Currently reference and transaction types are only strings
case str():
barnjamin marked this conversation as resolved.
Show resolved Hide resolved
if algosdk.abi.is_abi_reference_type(t):
ref_dict: dict[str, TypeSpec] = {
str(rts): rts for rts in ReferenceTypeSpecs
}
if t in ref_dict:
return ref_dict[t]
else:
raise TealInputError(f"Invalid reference type: {t}")

elif algosdk.abi.is_abi_transaction_type(t):
txn_dict: dict[str, TypeSpec] = {
str(tts): tts for tts in TransactionTypeSpecs
}
if t in txn_dict:
return txn_dict[t]
else:
raise TealInputError(f"Invalid transaction type: {t}")
else:
raise TealInputError(f"Invalid ABI type: {t}")

case algosdk.abi.ABIType():
match t:
case algosdk.abi.ArrayDynamicType():
return DynamicArrayTypeSpec(type_spec_from_algosdk(t.child_type))
case algosdk.abi.ArrayStaticType():
return StaticArrayTypeSpec(
type_spec_from_algosdk(t.child_type), t.static_length
)
case algosdk.abi.TupleType():
return TupleTypeSpec(
*[type_spec_from_algosdk(ct) for ct in t.child_types]
)
case algosdk.abi.UintType():
match t.bit_size:
case 8:
return Uint8TypeSpec()
case 16:
return Uint16TypeSpec()
case 32:
return Uint32TypeSpec()
case 64:
return Uint64TypeSpec()
case algosdk.abi.ByteType():
return ByteTypeSpec()
case algosdk.abi.BoolType():
return BoolTypeSpec()
case algosdk.abi.StringType():
return StringTypeSpec()
case algosdk.abi.AddressType():
return AddressTypeSpec()
case algosdk.abi.UfixedType():
raise TealInputError("Ufixed not supported")

raise TealInputError(f"Invalid Type: {t}")


def type_specs_from_signature(sig: str) -> tuple[list[TypeSpec], Optional[TypeSpec]]:
sdk_method = algosdk.abi.Method.from_signature(sig)

return_type = None
if sdk_method.returns.type != algosdk.abi.Returns.VOID:
return_type = type_spec_from_algosdk(sdk_method.returns.type)

return [type_spec_from_algosdk(arg.type) for arg in sdk_method.args], return_type
73 changes: 73 additions & 0 deletions pyteal/ast/abi/util_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from pyteal.ast.abi.util import (
substringForDecoding,
int_literal_from_annotation,
type_spec_from_algosdk,
type_spec_from_annotation,
type_specs_from_signature,
)
from pyteal.errors import TealInputError

Expand Down Expand Up @@ -552,6 +554,62 @@ def test_size_of():
),
]

ABI_SIGNATURE_TYPESPEC_CASES = [
ahangsu marked this conversation as resolved.
Show resolved Hide resolved
(
"check(uint64,uint64)uint64",
[abi.Uint64TypeSpec(), abi.Uint64TypeSpec()],
abi.Uint64TypeSpec(),
),
(
"check(uint64[],uint64)uint64",
[abi.DynamicArrayTypeSpec(abi.Uint64TypeSpec()), abi.Uint64TypeSpec()],
abi.Uint64TypeSpec(),
),
(
"check(uint64[5],uint64)uint64",
[abi.StaticArrayTypeSpec(abi.Uint64TypeSpec(), 5), abi.Uint64TypeSpec()],
abi.Uint64TypeSpec(),
),
(
"check(uint64,uint64)uint64[]",
[abi.Uint64TypeSpec(), abi.Uint64TypeSpec()],
abi.DynamicArrayTypeSpec(abi.Uint64TypeSpec()),
),
(
"check(uint64,uint64)uint64[5]",
[abi.Uint64TypeSpec(), abi.Uint64TypeSpec()],
abi.StaticArrayTypeSpec(abi.Uint64TypeSpec(), 5),
),
(
"check((uint64,uint64),asset)string",
[
abi.TupleTypeSpec(abi.Uint64TypeSpec(), abi.Uint64TypeSpec()),
abi.AssetTypeSpec(),
],
abi.StringTypeSpec(),
),
(
"check(string,asset)(uint64,uint64)",
[abi.StringTypeSpec(), abi.AssetTypeSpec()],
abi.TupleTypeSpec(abi.Uint64TypeSpec(), abi.Uint64TypeSpec()),
),
(
"check(account,asset,application)string",
[abi.AccountTypeSpec(), abi.AssetTypeSpec(), abi.ApplicationTypeSpec()],
abi.StringTypeSpec(),
),
(
"check(pay,txn,appl)string",
[
abi.PaymentTransactionTypeSpec(),
abi.TransactionTypeSpec(),
abi.ApplicationCallTransactionTypeSpec(),
],
abi.StringTypeSpec(),
),
("check(uint64,uint64)void", [abi.Uint64TypeSpec(), abi.Uint64TypeSpec()], None),
]


@pytest.mark.parametrize(
"algosdk_abi, abi_string, pyteal_abi_ts, pyteal_abi", ABI_TRANSLATION_TEST_CASES
Expand Down Expand Up @@ -593,3 +651,18 @@ def test_abi_type_translation(algosdk_abi, abi_string, pyteal_abi_ts, pyteal_abi
)
assert algosdk_abi == abi.algosdk_from_type_spec(pyteal_abi_ts)
assert algosdk_abi == abi.algosdk_from_annotation(pyteal_abi)


@pytest.mark.parametrize("case", ABI_TRANSLATION_TEST_CASES)
def test_sdk_abi_translation(case):
# Errors are strings in the 0th element
if type(case[0]) is str:
return
assert type_spec_from_algosdk(case[0]) == case[2]


@pytest.mark.parametrize("sig_str, sig_args, sig_rets", ABI_SIGNATURE_TYPESPEC_CASES)
def test_sdk_type_specs_from_signature(sig_str, sig_args, sig_rets):
barnjamin marked this conversation as resolved.
Show resolved Hide resolved
args, ret = type_specs_from_signature(sig_str)
assert args == sig_args
assert ret == sig_rets
Loading