Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies = [
"coincurve>=19.0.1",
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
# "algorand-python>=3",
"algorand-python@git+https://github.com/algorandfoundation/puya.git@v5.0.0-rc.11#subdirectory=stubs",
"algorand-python@git+https://github.com/algorandfoundation/puya.git@v5.0.0-rc.12#subdirectory=stubs",
]

[project.urls]
Expand All @@ -54,7 +54,7 @@ python = "3.12"
dependencies = [
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
# "puyapy>=5",
"puyapy@git+https://github.com/algorandfoundation/puya.git@v5.0.0-rc.11",
"puyapy@git+https://github.com/algorandfoundation/puya.git@v5.0.0-rc.12",
"pytest>=7.4",
"pytest-mock>=3.10.0",
"pytest-xdist[psutil]>=3.3",
Expand Down Expand Up @@ -138,7 +138,7 @@ dependencies = [
"algokit-utils>=3.0.0",
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
# "puyapy>=5",
"puyapy@git+https://github.com/algorandfoundation/puya.git@v5.0.0-rc.11",
"puyapy@git+https://github.com/algorandfoundation/puya.git@v5.0.0-rc.12",
]

[tool.hatch.envs.test.scripts]
Expand Down Expand Up @@ -191,7 +191,7 @@ post-install-commands = [
dependencies = [
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
# "algorand-python>=3",
"algorand-python@git+https://github.com/algorandfoundation/puya.git@v5.0.0-rc.11#subdirectory=stubs",
"algorand-python@git+https://github.com/algorandfoundation/puya.git@v5.0.0-rc.12#subdirectory=stubs",
"pytest>=7.4",
"pytest-mock>=3.10.0",
"pytest-xdist[psutil]>=3.3",
Expand Down
1 change: 1 addition & 0 deletions src/_algopy_testing/models/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ApplicationFields(typing.TypedDict, total=False):
local_num_bytes: algopy.UInt64
extra_program_pages: algopy.UInt64
creator: algopy.Account
version: algopy.UInt64


AccountKey = str
Expand Down
2 changes: 1 addition & 1 deletion src/_algopy_testing/models/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def __init_subclass__(
algopy.urange | tuple[int | algopy.urange, ...] | list[int | algopy.urange] | None
) = None,
state_totals: StateTotals | None = None,
avm_version: int = 10,
avm_version: int = 11,
):
cls._name = name or cls.__name__
cls._scratch_slots = scratch_slots
Expand Down
6 changes: 6 additions & 0 deletions src/_algopy_testing/models/txn_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class ApplicationCallFields(ActiveTransactionFields, total=False):
approval_program: Sequence[algopy.Bytes]
clear_state_program: Sequence[algopy.Bytes]
created_app: algopy.Application
reject_version: algopy.UInt64


class KeyRegistrationFields(TransactionBaseFields, total=False):
Expand Down Expand Up @@ -153,6 +154,7 @@ class TransactionFields( # type: ignore[misc]
"local_num_bytes": UInt64,
"extra_program_pages": UInt64,
"vote_first": UInt64,
"reject_version": UInt64,
"vote_last": UInt64,
"vote_key_dilution": UInt64,
"created_app": Application,
Expand Down Expand Up @@ -505,6 +507,10 @@ def num_logs(self) -> algopy.UInt64:
def logs(self) -> Callable[[algopy.UInt64 | int], algopy.Bytes]:
return _create_array_accessor(self._logs)

@property
def reject_version(self) -> algopy.UInt64:
return self.fields["reject_version"] # type: ignore[return-value]

def __getattr__(self, name: str) -> object:
try:
return self.fields[name]
Expand Down
2 changes: 1 addition & 1 deletion src/_algopy_testing/op/pure.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def bsqrt(a: BigUInt | int, /) -> BigUInt:
def btoi(a: Bytes | bytes, /) -> UInt64:
a_bytes = as_bytes(a)
if len(a_bytes) > 8:
raise ValueError(f"btoi arg too long, got [{len(a_bytes)}]bytes")
raise ValueError(f"btoi arg too long, got {len(a_bytes)} bytes")
return UInt64(int.from_bytes(a_bytes))


Expand Down
1 change: 1 addition & 0 deletions src/_algopy_testing/value_generators/avm.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ def application(
"local_num_bytes": _algopy_testing.UInt64(0),
"extra_program_pages": _algopy_testing.UInt64(0),
"creator": lazy_context.value.default_sender,
"version": _algopy_testing.UInt64(0),
}

# Merge provided fields with defaults, prioritizing provided fields
Expand Down
2 changes: 1 addition & 1 deletion tests/arc4/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from tests.common import AVMInvoker, create_avm_invoker

ARTIFACTS_DIR = Path(__file__).parent / ".." / "artifacts"
APP_SPEC = ARTIFACTS_DIR / "Arc4PrimitiveOps" / "data" / "Arc4PrimitiveOpsContract.arc32.json"
APP_SPEC = ARTIFACTS_DIR / "Arc4PrimitiveOps" / "data" / "Arc4PrimitiveOpsContract.arc56.json"


@pytest.fixture(scope="module")
Expand Down
2 changes: 1 addition & 1 deletion tests/arc4/test_arc4_method_signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from tests.common import AVMInvoker, create_avm_invoker

ARTIFACTS_DIR = Path(__file__).parent / ".." / "artifacts"
APP_SPEC = ARTIFACTS_DIR / "Arc4ABIMethod" / "data" / "SignaturesContract.arc32.json"
APP_SPEC = ARTIFACTS_DIR / "Arc4ABIMethod" / "data" / "SignaturesContract.arc56.json"
_FUNDED_ACCOUNT_SPENDING = 1234


Expand Down
5 changes: 4 additions & 1 deletion tests/arc4/test_bool.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ def test_string_from_log_invalid_prefix(
) -> None:
with pytest.raises(
algokit_utils.LogicError,
match=re.compile("(assert failed)|(extraction start \\d+ is beyond length)"),
match=re.compile(
"(application log value is not the result of an ABI return)|"
"(extraction start \\d+ is beyond length)"
),
):
get_avm_result("verify_bool_from_log", a=prefix + value)
with pytest.raises(ValueError, match="ABI return prefix not found"):
Expand Down
5 changes: 4 additions & 1 deletion tests/arc4/test_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ def test_string_from_log_invalid_prefix(
value = int_to_bytes(len(value), 2) + value
with pytest.raises(
algokit_utils.LogicError,
match=re.compile("(assert failed)|(extraction start \\d+ is beyond length)"),
match=re.compile(
"(application log value is not the result of an ABI return)|"
"(extraction start \\d+ is beyond length)"
),
):
get_avm_result("verify_string_from_log", a=prefix + value)
with pytest.raises(ValueError, match="ABI return prefix not found"):
Expand Down
8 changes: 6 additions & 2 deletions tests/arc4/test_ufixednxm.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ def test_ufixednxm_from_log(get_avm_result: AVMInvoker, value: bytes, expected:
def test_ufixednxm_from_log_invalid_prefix(
get_avm_result: AVMInvoker, value: bytes, prefix: bytes
) -> None:
with pytest.raises(algokit_utils.LogicError, match="assert failed"):
with pytest.raises(
algokit_utils.LogicError, match="application log value is not the result of an ABI return"
):
get_avm_result("verify_ufixednxm_from_log", a=prefix + value)
with pytest.raises(ValueError, match="ABI return prefix not found"):
arc4.UFixedNxM[typing.Literal[32], typing.Literal[8]].from_log(Bytes(prefix + value))
Expand Down Expand Up @@ -204,7 +206,9 @@ def test_bigufixednxm_from_log(get_avm_result: AVMInvoker, value: bytes, expecte
def test_bigufixednxm_from_log_invalid_prefix(
get_avm_result: AVMInvoker, value: bytes, prefix: bytes
) -> None:
with pytest.raises(algokit_utils.LogicError, match="assert failed"):
with pytest.raises(
algokit_utils.LogicError, match="application log value is not the result of an ABI return"
):
get_avm_result("verify_bigufixednxm_from_log", a=prefix + value)
with pytest.raises(ValueError, match="ABI return prefix not found"):
arc4.BigUFixedNxM[typing.Literal[256], typing.Literal[16]].from_log(Bytes(prefix + value))
Expand Down
14 changes: 9 additions & 5 deletions tests/arc4/test_uintn.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def test_uintn_comparison(get_avm_result: AVMInvoker, op_name: str, a: int, b: i
)
def test_uintn_overflow(get_avm_result: AVMInvoker, value: int, expected: int | None) -> None:
if expected is None:
with pytest.raises(algokit_utils.LogicError, match="assert failed"):
with pytest.raises(algokit_utils.LogicError, match="overflow"):
get_avm_result("verify_uintn_init", a=int_to_bytes(value))
with pytest.raises(ValueError, match=f"expected value <= {2**32 - 1}"):
arc4.UInt32(value)
Expand All @@ -128,7 +128,7 @@ def test_uintn_overflow(get_avm_result: AVMInvoker, value: int, expected: int |
)
def test_biguintn_overflow(get_avm_result: AVMInvoker, value: int, expected: int | None) -> None:
if expected is None:
with pytest.raises(algokit_utils.LogicError, match="assert failed"):
with pytest.raises(algokit_utils.LogicError, match="overflow"):
get_avm_result("verify_biguintn_init", a=int_to_bytes(value))
with pytest.raises(ValueError, match=f"expected value <= {2**256 - 1}"):
arc4.UInt256(value)
Expand Down Expand Up @@ -230,7 +230,9 @@ def test_uintn_from_log(get_avm_result: AVMInvoker, value: bytes, expected: int)
def test_uintn_from_log_invalid_prefix(
get_avm_result: AVMInvoker, value: bytes, prefix: bytes
) -> None:
with pytest.raises(algokit_utils.LogicError, match="assert failed"):
with pytest.raises(
algokit_utils.LogicError, match="application log value is not the result of an ABI return"
):
get_avm_result("verify_uintn_from_log", a=prefix + value)
with pytest.raises(ValueError, match="ABI return prefix not found"):
arc4.UInt32.from_log(Bytes(prefix + value))
Expand Down Expand Up @@ -279,7 +281,9 @@ def test_biguintn_from_log(get_avm_result: AVMInvoker, value: bytes, expected: i
def test_biguintn_from_log_invalid_prefix(
get_avm_result: AVMInvoker, value: bytes, prefix: bytes
) -> None:
with pytest.raises(algokit_utils.LogicError, match="assert failed"):
with pytest.raises(
algokit_utils.LogicError, match="application log value is not the result of an ABI return"
):
get_avm_result("verify_biguintn_from_log", a=prefix + value)
with pytest.raises(ValueError, match="ABI return prefix not found"):
arc4.UInt256.from_log(Bytes(prefix + value))
Expand Down Expand Up @@ -323,7 +327,7 @@ def test_biguintn_as_uint64(get_avm_result: AVMInvoker, value: bytes) -> None:
],
)
def test_biguintn_as_uint64_overflow(get_avm_result: AVMInvoker, value: bytes) -> None:
with pytest.raises(algokit_utils.LogicError, match="assert failed"):
with pytest.raises(algokit_utils.LogicError, match="overflow"):
get_avm_result("verify_biguintn_as_uint64", a=value)
with pytest.raises(OverflowError, match="value too large to fit in UInt64"):
arc4.UInt256.from_bytes(Bytes(value)).as_uint64()
Expand Down
Empty file.
45 changes: 45 additions & 0 deletions tests/artifacts/AVM12/contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from algopy import ARC4Contract, OnCompleteAction, Txn, arc4, compile_contract, itxn, op


class Contract(ARC4Contract, avm_version=12):
@arc4.abimethod
def test_falcon_verify(self) -> None:
assert not op.falcon_verify(b"", b"", op.bzero(1793))

@arc4.abimethod
def test_reject_version(self) -> None:
app_v0_txn = arc4.arc4_create(ContractV0)
app = app_v0_txn.created_app
assert app.version == 0, "should be version 0"

arc4.arc4_update(
ContractV0.update, app_id=app, reject_version=1, compiled=compile_contract(ContractV1)
)
assert app.version == 1, "should be version 1"

itxn.ApplicationCall(
app_args=(
arc4.arc4_signature(
ContractV1.delete,
),
),
on_completion=OnCompleteAction.DeleteApplication,
app_id=app,
reject_version=2,
).submit()


class ContractV0(ARC4Contract, avm_version=12):
@arc4.abimethod(allow_actions=("UpdateApplication",))
def update(self) -> None:
assert (
Txn.reject_version == 1
), "can only update if caller expects this to be currently be v0"


class ContractV1(ARC4Contract, avm_version=12):
@arc4.abimethod(allow_actions=("DeleteApplication",))
def delete(self) -> None:
assert (
Txn.reject_version == 2
), "can only update if caller expects this to be currently be v1"
Loading