diff --git a/pyproject.toml b/pyproject.toml index 813cea4..22f9dd1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -228,7 +228,7 @@ ignore = [ "RET503", # false negatives when involving typing.Never, covered by mypy anyway "RET504", "RET505", # stylistic choices for readability - "S101", # allow asserts + "S101", # allow asserts ] unfixable = [ "F841", # don't delete unused local variables automatically @@ -238,6 +238,7 @@ unfixable = [ "PT", # no pytest rules ] "scripts/**/*.py" = ["T201"] +"scripts/refresh_test_artifacts.py" = ["S603"] [tool.ruff.lint.flake8-annotations] allow-star-arg-any = true diff --git a/scripts/refresh_test_artifacts.py b/scripts/refresh_test_artifacts.py index ffdef11..f288e03 100644 --- a/scripts/refresh_test_artifacts.py +++ b/scripts/refresh_test_artifacts.py @@ -27,14 +27,12 @@ def compile_contract(folder: Path) -> None: "hatch", "run", "puyapy", - "--log-level", - "debug", str(contract_path), "--out-dir", "data", ] subprocess.run( - compile_cmd, # noqa: S603 + compile_cmd, check=True, env=ENV_WITH_NO_COLOR, encoding="utf-8", @@ -56,7 +54,7 @@ def generate_client(folder: Path) -> None: str(client_path), ] subprocess.run( - generate_cmd, # noqa: S603 + generate_cmd, check=True, env=ENV_WITH_NO_COLOR, encoding="utf-8", diff --git a/src/algopy_testing/context.py b/src/algopy_testing/context.py index b3b1a68..2c9a7a3 100644 --- a/src/algopy_testing/context.py +++ b/src/algopy_testing/context.py @@ -2,6 +2,7 @@ import secrets import string +from collections import ChainMap from contextlib import contextmanager from contextvars import ContextVar from dataclasses import dataclass @@ -659,7 +660,22 @@ def any_asset( raise ValueError("Asset with such ID already exists in testing context!") new_asset = algopy.Asset(asset_id or next(self._asset_id)) - self._asset_data[int(new_asset.id)] = AssetFields(**asset_fields) + default_asset_fields = { + "total": self.any_uint64(), + "decimals": self.any_uint64(1, 6), + "default_frozen": False, + "unit_name": self.any_bytes(4), + "name": self.any_bytes(50), + "url": self.any_bytes(10), + "metadata_hash": self.any_bytes(32), + "manager": self.any_account(), + "freeze": self.any_account(), + "clawback": self.any_account(), + "creator": self.any_account(), + "reserve": self.any_account(), + } + merged_fields = dict(ChainMap(asset_fields, default_asset_fields)) # type: ignore[arg-type] + self._asset_data[int(new_asset.id)] = AssetFields(**merged_fields) # type: ignore[typeddict-item] return new_asset def any_application( # type: ignore[misc] @@ -929,7 +945,8 @@ def any_application_call_transaction( # type: ignore[misc] # noqa: PLR0913 } new_txn = algopy.gtxn.ApplicationCallTransaction(NULL_GTXN_GROUP_INDEX) - for key, value in {**kwargs, **dynamic_params}.items(): + merged_params = dict(ChainMap(kwargs, dynamic_params)) + for key, value in merged_params.items(): setattr(new_txn, key, value) self.set_scratch_space(new_txn.txn_id, scratch_space or {}) @@ -1170,7 +1187,6 @@ def reset(self) -> None: self._app_id = iter(range(1, 2**64)) -# _var: ContextVar[AlgopyTestContext] = ContextVar("_var") diff --git a/src/algopy_testing/op.py b/src/algopy_testing/op.py index 2ffde05..bf598e9 100644 --- a/src/algopy_testing/op.py +++ b/src/algopy_testing/op.py @@ -866,13 +866,13 @@ def get_asset_param(a: algopy.Asset | algopy.UInt64 | int) -> tuple[typing.Any, if not active_txn: raise ValueError("No active transaction found to reference asset") - asset_id = a.value if isinstance(a, (algopy.Asset)) else int(a) - asset_data = active_txn.assets[asset_id] + asset_id = int(a.id) if isinstance(a, (algopy.Asset)) else int(a) + asset_data = context.get_asset(asset_id) if asset_data is None: return None, False - param = "config_" + name + param = name.replace("asset_", "") value = getattr(asset_data, param, None) return value, True @@ -955,12 +955,81 @@ def asset_frozen( class _AppParamsGet: - def __getattr__(self, name: str) -> Any: - raise NotImplementedError( - f"AppParamsGet.{name} is currently not available as a native " - "`algorand-python-testing` type. Use your own preferred testing " - "framework of choice to mock the behaviour." - ) + @staticmethod + def _get_app_param_from_ctx( + index: algopy.Application | algopy.UInt64 | int, param: str + ) -> tuple[Any, bool]: + from algopy_testing import get_test_context + + context = get_test_context() + + if not context: + raise ValueError( + "Test context is not initialized! Use `with algopy_testing_context()` " + "to access the context manager." + ) + + try: + application = context.get_application_data()[int(index)] + except IndexError: + return None, False + + try: + response = getattr(application, param) + except AttributeError: + return None, False + else: + return response, True + + @staticmethod + def app_approval_program( + a: algopy.Application | algopy.UInt64 | int, / + ) -> tuple[algopy.Bytes, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "approval_program") + + @staticmethod + def app_clear_state_program( + a: algopy.Application | algopy.UInt64 | int, / + ) -> tuple[algopy.Bytes, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "clear_state_program") + + @staticmethod + def app_global_num_uint( + a: algopy.Application | algopy.UInt64 | int, / + ) -> tuple[algopy.UInt64, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "global_num_uint") + + @staticmethod + def app_global_num_byte_slice( + a: algopy.Application | algopy.UInt64 | int, / + ) -> tuple[algopy.UInt64, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "global_num_byte_slice") + + @staticmethod + def app_local_num_uint( + a: algopy.Application | algopy.UInt64 | int, / + ) -> tuple[algopy.UInt64, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "local_num_uint") + + @staticmethod + def app_local_num_byte_slice( + a: algopy.Application | algopy.UInt64 | int, / + ) -> tuple[algopy.UInt64, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "local_num_byte_slice") + + @staticmethod + def app_extra_program_pages( + a: algopy.Application | algopy.UInt64 | int, / + ) -> tuple[algopy.UInt64, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "extra_program_pages") + + @staticmethod + def app_creator(a: algopy.Application | algopy.UInt64 | int, /) -> tuple[algopy.Account, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "creator") + + @staticmethod + def app_address(a: algopy.Application | algopy.UInt64 | int, /) -> tuple[algopy.Account, bool]: + return _AppParamsGet._get_app_param_from_ctx(a, "address") AppParamsGet = _AppParamsGet() diff --git a/tests/artifacts/StateOps/__init__.py b/tests/artifacts/StateOps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/artifacts/StateOps/contract.py b/tests/artifacts/StateOps/contract.py new file mode 100644 index 0000000..4655088 --- /dev/null +++ b/tests/artifacts/StateOps/contract.py @@ -0,0 +1,73 @@ +from algopy import Account, ARC4Contract, Asset, Bytes, UInt64, arc4, op + + +class StateOpsContract(ARC4Contract): + @arc4.abimethod() + def verify_asset_holding_get(self, a: Account, b: Asset) -> UInt64: + balance, _val = op.AssetHoldingGet.asset_balance(a, b) + return balance + + @arc4.abimethod() + def verify_asset_frozen_get(self, a: Account, b: Asset) -> bool: + frozen, _val = op.AssetHoldingGet.asset_frozen(a, b) + return frozen + + @arc4.abimethod() + def verify_asset_params_get_total(self, a: Asset) -> UInt64: + total, _val = op.AssetParamsGet.asset_total(a) + return total + + @arc4.abimethod() + def verify_asset_params_get_decimals(self, a: Asset) -> UInt64: + decimals, _val = op.AssetParamsGet.asset_decimals(a) + return decimals + + @arc4.abimethod() + def verify_asset_params_get_default_frozen(self, a: Asset) -> bool: + default_frozen, _val = op.AssetParamsGet.asset_default_frozen(a) + return default_frozen + + @arc4.abimethod() + def verify_asset_params_get_unit_name(self, a: Asset) -> Bytes: + unit_name, _val = op.AssetParamsGet.asset_unit_name(a) + return unit_name + + @arc4.abimethod() + def verify_asset_params_get_name(self, a: Asset) -> Bytes: + name, _val = op.AssetParamsGet.asset_name(a) + return name + + @arc4.abimethod() + def verify_asset_params_get_url(self, a: Asset) -> Bytes: + url, _val = op.AssetParamsGet.asset_url(a) + return url + + @arc4.abimethod() + def verify_asset_params_get_metadata_hash(self, a: Asset) -> Bytes: + metadata_hash, _val = op.AssetParamsGet.asset_metadata_hash(a) + return metadata_hash + + @arc4.abimethod() + def verify_asset_params_get_manager(self, a: Asset) -> Bytes: + manager, _val = op.AssetParamsGet.asset_manager(a) + return manager.bytes + + @arc4.abimethod() + def verify_asset_params_get_reserve(self, a: Asset) -> Bytes: + reserve, _val = op.AssetParamsGet.asset_reserve(a) + return reserve.bytes + + @arc4.abimethod() + def verify_asset_params_get_freeze(self, a: Asset) -> Bytes: + freeze, _val = op.AssetParamsGet.asset_freeze(a) + return freeze.bytes + + @arc4.abimethod() + def verify_asset_params_get_clawback(self, a: Asset) -> Bytes: + clawback, _val = op.AssetParamsGet.asset_clawback(a) + return clawback.bytes + + @arc4.abimethod() + def verify_asset_params_get_creator(self, a: Asset) -> Bytes: + creator, _val = op.AssetParamsGet.asset_creator(a) + return creator.bytes diff --git a/tests/artifacts/StateOps/data/CryptoOpsContract.approval.teal b/tests/artifacts/StateOps/data/CryptoOpsContract.approval.teal new file mode 100644 index 0000000..2b6f28e --- /dev/null +++ b/tests/artifacts/StateOps/data/CryptoOpsContract.approval.teal @@ -0,0 +1,875 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.CryptoOpsContract.approval_program: + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@17 + method "verify_sha256(byte[],uint64)byte[]" + method "verify_sha3_256(byte[],uint64)byte[]" + method "verify_keccak_256(byte[],uint64)byte[]" + method "verify_sha512_256(byte[],uint64)byte[]" + method "verify_ed25519verify(byte[],byte[],byte[])bool" + method "verify_ed25519verify_bare(byte[],byte[],byte[])bool" + method "verify_ecdsa_verify_k1(byte[],byte[],byte[],byte[],byte[])bool" + method "verify_ecdsa_verify_r1(byte[],byte[],byte[],byte[],byte[])bool" + method "verify_ecdsa_recover_k1(byte[],uint64,byte[],byte[])(byte[],byte[])" + method "verify_ecdsa_recover_r1(byte[],uint64,byte[],byte[])(byte[],byte[])" + method "verify_ecdsa_decompress_k1(byte[])(byte[],byte[])" + method "verify_ecdsa_decompress_r1(byte[])(byte[],byte[])" + method "verify_vrf_verify(byte[],byte[],byte[])(byte[],bool)" + txna ApplicationArgs 0 + match main_verify_sha256_route@2 main_verify_sha3_256_route@3 main_verify_keccak_256_route@4 main_verify_sha512_256_route@5 main_verify_ed25519verify_route@6 main_verify_ed25519verify_bare_route@7 main_verify_ecdsa_verify_k1_route@8 main_verify_ecdsa_verify_r1_route@9 main_verify_ecdsa_recover_k1_route@10 main_verify_ecdsa_recover_r1_route@11 main_verify_ecdsa_decompress_k1_route@12 main_verify_ecdsa_decompress_r1_route@13 main_verify_vrf_verify_route@14 + err // reject transaction + +main_verify_sha256_route@2: + // tests/artifacts/StateOps/contract.py:5 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/StateOps/contract.py:5 + // @arc4.abimethod() + callsub verify_sha256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_sha3_256_route@3: + // tests/artifacts/StateOps/contract.py:11 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/StateOps/contract.py:11 + // @arc4.abimethod() + callsub verify_sha3_256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_keccak_256_route@4: + // tests/artifacts/StateOps/contract.py:17 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/StateOps/contract.py:17 + // @arc4.abimethod() + callsub verify_keccak_256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_sha512_256_route@5: + // tests/artifacts/StateOps/contract.py:23 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/StateOps/contract.py:23 + // @arc4.abimethod() + callsub verify_sha512_256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ed25519verify_route@6: + // tests/artifacts/StateOps/contract.py:29 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/StateOps/contract.py:29 + // @arc4.abimethod() + callsub verify_ed25519verify + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ed25519verify_bare_route@7: + // tests/artifacts/StateOps/contract.py:35 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/StateOps/contract.py:35 + // @arc4.abimethod() + callsub verify_ed25519verify_bare + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_verify_k1_route@8: + // tests/artifacts/StateOps/contract.py:41 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + txna ApplicationArgs 4 + extract 2 0 + txna ApplicationArgs 5 + extract 2 0 + // tests/artifacts/StateOps/contract.py:41 + // @arc4.abimethod() + callsub verify_ecdsa_verify_k1 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_verify_r1_route@9: + // tests/artifacts/StateOps/contract.py:49 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + txna ApplicationArgs 4 + extract 2 0 + txna ApplicationArgs 5 + extract 2 0 + // tests/artifacts/StateOps/contract.py:49 + // @arc4.abimethod() + callsub verify_ecdsa_verify_r1 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_recover_k1_route@10: + // tests/artifacts/StateOps/contract.py:57 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + extract 2 0 + txna ApplicationArgs 4 + extract 2 0 + // tests/artifacts/StateOps/contract.py:57 + // @arc4.abimethod() + callsub verify_ecdsa_recover_k1 + swap + dup + len + itob + extract 6 2 + swap + concat + dig 1 + len + itob + extract 6 2 + uncover 2 + concat + swap + dup + len + int 4 + + + itob + extract 6 2 + byte 0x0004 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_recover_r1_route@11: + // tests/artifacts/StateOps/contract.py:64 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + extract 2 0 + txna ApplicationArgs 4 + extract 2 0 + // tests/artifacts/StateOps/contract.py:64 + // @arc4.abimethod() + callsub verify_ecdsa_recover_r1 + swap + dup + len + itob + extract 6 2 + swap + concat + dig 1 + len + itob + extract 6 2 + uncover 2 + concat + swap + dup + len + int 4 + + + itob + extract 6 2 + byte 0x0004 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_decompress_k1_route@12: + // tests/artifacts/StateOps/contract.py:74 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/StateOps/contract.py:74 + // @arc4.abimethod() + callsub verify_ecdsa_decompress_k1 + swap + dup + len + itob + extract 6 2 + swap + concat + dig 1 + len + itob + extract 6 2 + uncover 2 + concat + swap + dup + len + int 4 + + + itob + extract 6 2 + byte 0x0004 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_decompress_r1_route@13: + // tests/artifacts/StateOps/contract.py:79 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/StateOps/contract.py:79 + // @arc4.abimethod() + callsub verify_ecdsa_decompress_r1 + swap + dup + len + itob + extract 6 2 + swap + concat + dig 1 + len + itob + extract 6 2 + uncover 2 + concat + swap + dup + len + int 4 + + + itob + extract 6 2 + byte 0x0004 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_vrf_verify_route@14: + // tests/artifacts/StateOps/contract.py:84 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/StateOps/contract.py:84 + // @arc4.abimethod() + callsub verify_vrf_verify + swap + dup + len + itob + extract 6 2 + swap + concat + byte 0x00 + int 0 + uncover 3 + setbit + byte 0x0003 + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@17: + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_sha256(a: bytes, pad_size: uint64) -> bytes: +verify_sha256: + // tests/artifacts/StateOps/contract.py:5-6 + // @arc4.abimethod() + // def verify_sha256(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/StateOps/contract.py:7 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/StateOps/contract.py:8 + // result = op.sha256(a) + sha256 + // tests/artifacts/StateOps/contract.py:9 + // return result + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_sha3_256(a: bytes, pad_size: uint64) -> bytes: +verify_sha3_256: + // tests/artifacts/StateOps/contract.py:11-12 + // @arc4.abimethod() + // def verify_sha3_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/StateOps/contract.py:13 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/StateOps/contract.py:14 + // result = op.sha3_256(a) + sha3_256 + // tests/artifacts/StateOps/contract.py:15 + // return result + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_keccak_256(a: bytes, pad_size: uint64) -> bytes: +verify_keccak_256: + // tests/artifacts/StateOps/contract.py:17-18 + // @arc4.abimethod() + // def verify_keccak_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/StateOps/contract.py:19 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/StateOps/contract.py:20 + // result = op.keccak256(a) + keccak256 + // tests/artifacts/StateOps/contract.py:21 + // return result + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_sha512_256(a: bytes, pad_size: uint64) -> bytes: +verify_sha512_256: + // tests/artifacts/StateOps/contract.py:23-24 + // @arc4.abimethod() + // def verify_sha512_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/StateOps/contract.py:25 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/StateOps/contract.py:26 + // result = op.sha512_256(a) + sha512_256 + // tests/artifacts/StateOps/contract.py:27 + // return result + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_ed25519verify(a: bytes, b: bytes, c: bytes) -> bytes: +verify_ed25519verify: + // tests/artifacts/StateOps/contract.py:29-30 + // @arc4.abimethod() + // def verify_ed25519verify(self, a: Bytes, b: Bytes, c: Bytes) -> arc4.Bool: + proto 3 1 + // tests/artifacts/StateOps/contract.py:31 + // ensure_budget(1900, OpUpFeeSource.GroupCredit) + int 1900 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:32 + // result = op.ed25519verify(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + ed25519verify + // tests/artifacts/StateOps/contract.py:33 + // return arc4.Bool(result) + byte 0x00 + int 0 + uncover 2 + setbit + retsub + + +// algopy.ensure_budget(required_budget: uint64, fee_source: uint64) -> void: +ensure_budget: + // /algopy.py:11-17 + proto 2 0 + // /algopy.py:18 + frame_dig -2 + int 10 + + + +ensure_budget_while_top@1: + // /algopy.py:19 + frame_dig 0 + global OpcodeBudget + > + bz ensure_budget_after_while@7 + // /algopy.py:20 + itxn_begin + // /algopy.py:21 + int appl + itxn_field TypeEnum + // /algopy.py:22 + int DeleteApplication + itxn_field OnCompletion + // /algopy.py:23 + byte 0x068101 + itxn_field ApprovalProgram + // /algopy.py:24 + byte 0x068101 + itxn_field ClearStateProgram + // /algopy.py:25-29 + frame_dig -1 + switch ensure_budget_switch_case_0@3 ensure_budget_switch_case_1@4 + b ensure_budget_switch_case_next@6 + +ensure_budget_switch_case_0@3: + // /algopy.py:27 + int 0 + itxn_field Fee + b ensure_budget_switch_case_next@6 + +ensure_budget_switch_case_1@4: + // /algopy.py:29 + global MinTxnFee + itxn_field Fee + +ensure_budget_switch_case_next@6: + // /algopy.py:30 + itxn_submit + b ensure_budget_while_top@1 + +ensure_budget_after_while@7: + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes) -> bytes: +verify_ed25519verify_bare: + // tests/artifacts/StateOps/contract.py:35-36 + // @arc4.abimethod() + // def verify_ed25519verify_bare(self, a: Bytes, b: Bytes, c: Bytes) -> arc4.Bool: + proto 3 1 + // tests/artifacts/StateOps/contract.py:37 + // ensure_budget(1900, OpUpFeeSource.GroupCredit) + int 1900 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:38 + // result = op.ed25519verify_bare(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + ed25519verify_bare + // tests/artifacts/StateOps/contract.py:39 + // return arc4.Bool(result) + byte 0x00 + int 0 + uncover 2 + setbit + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_ecdsa_verify_k1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes) -> uint64: +verify_ecdsa_verify_k1: + // tests/artifacts/StateOps/contract.py:41-44 + // @arc4.abimethod() + // def verify_ecdsa_verify_k1( # noqa: PLR0913 + // self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes + // ) -> bool: + proto 5 1 + // tests/artifacts/StateOps/contract.py:45 + // ensure_budget(3000, OpUpFeeSource.GroupCredit) + int 3000 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:46 + // result_k1 = op.ecdsa_verify(op.ECDSA.Secp256k1, a, b, c, d, e) + frame_dig -5 + frame_dig -4 + frame_dig -3 + frame_dig -2 + frame_dig -1 + ecdsa_verify Secp256k1 + // tests/artifacts/StateOps/contract.py:47 + // return result_k1 + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_ecdsa_verify_r1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes) -> uint64: +verify_ecdsa_verify_r1: + // tests/artifacts/StateOps/contract.py:49-52 + // @arc4.abimethod() + // def verify_ecdsa_verify_r1( # noqa: PLR0913 + // self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes + // ) -> bool: + proto 5 1 + // tests/artifacts/StateOps/contract.py:53 + // ensure_budget(3000, OpUpFeeSource.GroupCredit) + int 3000 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:54 + // result_r1 = op.ecdsa_verify(op.ECDSA.Secp256r1, a, b, c, d, e) + frame_dig -5 + frame_dig -4 + frame_dig -3 + frame_dig -2 + frame_dig -1 + ecdsa_verify Secp256r1 + // tests/artifacts/StateOps/contract.py:55 + // return result_r1 + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_ecdsa_recover_k1(a: bytes, b: uint64, c: bytes, d: bytes) -> bytes, bytes: +verify_ecdsa_recover_k1: + // tests/artifacts/StateOps/contract.py:57-60 + // @arc4.abimethod() + // def verify_ecdsa_recover_k1( + // self, a: Bytes, b: UInt64, c: Bytes, d: Bytes + // ) -> tuple[Bytes, Bytes]: + proto 4 2 + // tests/artifacts/StateOps/contract.py:61 + // ensure_budget(3000, OpUpFeeSource.GroupCredit) + int 3000 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:62 + // return op.ecdsa_pk_recover(op.ECDSA.Secp256k1, a, b, c, d) + frame_dig -4 + frame_dig -3 + frame_dig -2 + frame_dig -1 + ecdsa_pk_recover Secp256k1 + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_ecdsa_recover_r1(a: bytes, b: uint64, c: bytes, d: bytes) -> bytes, bytes: +verify_ecdsa_recover_r1: + // tests/artifacts/StateOps/contract.py:64-67 + // @arc4.abimethod() + // def verify_ecdsa_recover_r1( + // self, a: Bytes, b: UInt64, c: Bytes, d: Bytes + // ) -> tuple[Bytes, Bytes]: + proto 4 2 + // tests/artifacts/StateOps/contract.py:71 + // ensure_budget(3000, OpUpFeeSource.GroupCredit) + int 3000 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:72 + // return op.ecdsa_pk_recover(op.ECDSA.Secp256r1, a, b, c, d) + frame_dig -4 + frame_dig -3 + frame_dig -2 + frame_dig -1 + ecdsa_pk_recover Secp256r1 + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_ecdsa_decompress_k1(a: bytes) -> bytes, bytes: +verify_ecdsa_decompress_k1: + // tests/artifacts/StateOps/contract.py:74-75 + // @arc4.abimethod() + // def verify_ecdsa_decompress_k1(self, a: Bytes) -> tuple[Bytes, Bytes]: + proto 1 2 + // tests/artifacts/StateOps/contract.py:76 + // ensure_budget(700, OpUpFeeSource.GroupCredit) + int 700 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:77 + // return op.ecdsa_pk_decompress(op.ECDSA.Secp256k1, a) + frame_dig -1 + ecdsa_pk_decompress Secp256k1 + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_ecdsa_decompress_r1(a: bytes) -> bytes, bytes: +verify_ecdsa_decompress_r1: + // tests/artifacts/StateOps/contract.py:79-80 + // @arc4.abimethod() + // def verify_ecdsa_decompress_r1(self, a: Bytes) -> tuple[Bytes, Bytes]: + proto 1 2 + // tests/artifacts/StateOps/contract.py:81 + // ensure_budget(700, OpUpFeeSource.GroupCredit) + int 700 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:82 + // return op.ecdsa_pk_decompress(op.ECDSA.Secp256r1, a) + frame_dig -1 + ecdsa_pk_decompress Secp256r1 + retsub + + +// tests.artifacts.StateOps.contract.CryptoOpsContract.verify_vrf_verify(a: bytes, b: bytes, c: bytes) -> bytes, uint64: +verify_vrf_verify: + // tests/artifacts/StateOps/contract.py:84-85 + // @arc4.abimethod() + // def verify_vrf_verify(self, a: Bytes, b: Bytes, c: Bytes) -> tuple[Bytes, bool]: + proto 3 2 + // tests/artifacts/StateOps/contract.py:86 + // ensure_budget(5700, OpUpFeeSource.GroupCredit) + int 5700 + int 0 + callsub ensure_budget + // tests/artifacts/StateOps/contract.py:87 + // result = op.vrf_verify(op.VrfVerify.VrfAlgorand, a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + vrf_verify VrfAlgorand + // tests/artifacts/StateOps/contract.py:88 + // return result + retsub diff --git a/tests/artifacts/StateOps/data/CryptoOpsContract.arc32.json b/tests/artifacts/StateOps/data/CryptoOpsContract.arc32.json new file mode 100644 index 0000000..30fbaa7 --- /dev/null +++ b/tests/artifacts/StateOps/data/CryptoOpsContract.arc32.json @@ -0,0 +1,355 @@ +{ + "hints": { + "verify_sha256(byte[],uint64)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_sha3_256(byte[],uint64)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_keccak_256(byte[],uint64)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_sha512_256(byte[],uint64)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_ed25519verify(byte[],byte[],byte[])bool": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_ed25519verify_bare(byte[],byte[],byte[])bool": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_ecdsa_verify_k1(byte[],byte[],byte[],byte[],byte[])bool": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_ecdsa_verify_r1(byte[],byte[],byte[],byte[],byte[])bool": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_ecdsa_recover_k1(byte[],uint64,byte[],byte[])(byte[],byte[])": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_ecdsa_recover_r1(byte[],uint64,byte[],byte[])(byte[],byte[])": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_ecdsa_decompress_k1(byte[])(byte[],byte[])": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_ecdsa_decompress_r1(byte[])(byte[],byte[])": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_vrf_verify(byte[],byte[],byte[])(byte[],bool)": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDE3CiAgICBtZXRob2QgInZlcmlmeV9zaGEyNTYoYnl0ZVtdLHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9zaGEzXzI1NihieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2tlY2Nha18yNTYoYnl0ZVtdLHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9zaGE1MTJfMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZWQyNTUxOXZlcmlmeShieXRlW10sYnl0ZVtdLGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlKGJ5dGVbXSxieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9lY2RzYV92ZXJpZnlfazEoYnl0ZVtdLGJ5dGVbXSxieXRlW10sYnl0ZVtdLGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxKGJ5dGVbXSxieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2VjZHNhX3JlY292ZXJfazEoYnl0ZVtdLHVpbnQ2NCxieXRlW10sYnl0ZVtdKShieXRlW10sYnl0ZVtdKSIKICAgIG1ldGhvZCAidmVyaWZ5X2VjZHNhX3JlY292ZXJfcjEoYnl0ZVtdLHVpbnQ2NCxieXRlW10sYnl0ZVtdKShieXRlW10sYnl0ZVtdKSIKICAgIG1ldGhvZCAidmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazEoYnl0ZVtdKShieXRlW10sYnl0ZVtdKSIKICAgIG1ldGhvZCAidmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEoYnl0ZVtdKShieXRlW10sYnl0ZVtdKSIKICAgIG1ldGhvZCAidmVyaWZ5X3ZyZl92ZXJpZnkoYnl0ZVtdLGJ5dGVbXSxieXRlW10pKGJ5dGVbXSxib29sKSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X3NoYTI1Nl9yb3V0ZUAyIG1haW5fdmVyaWZ5X3NoYTNfMjU2X3JvdXRlQDMgbWFpbl92ZXJpZnlfa2VjY2FrXzI1Nl9yb3V0ZUA0IG1haW5fdmVyaWZ5X3NoYTUxMl8yNTZfcm91dGVANSBtYWluX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X3JvdXRlQDYgbWFpbl92ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlX3JvdXRlQDcgbWFpbl92ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxX3JvdXRlQDggbWFpbl92ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxX3JvdXRlQDkgbWFpbl92ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMV9yb3V0ZUAxMCBtYWluX3ZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxX3JvdXRlQDExIG1haW5fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTIgbWFpbl92ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMV9yb3V0ZUAxMyBtYWluX3ZlcmlmeV92cmZfdmVyaWZ5X3JvdXRlQDE0CiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX3ZlcmlmeV9zaGEyNTZfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGEyNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zaGEzXzI1Nl9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2hhM18yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9rZWNjYWtfMjU2X3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9rZWNjYWtfMjU2CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2hhNTEyXzI1NgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWQyNTUxOXZlcmlmeQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMQogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGludCA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZSAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjFfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjEKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpbnQgNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGUgMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX2sxX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMQogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGludCA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZSAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjFfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX3IxCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaW50IDQKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBieXRlIDB4MDAwNAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdnJmX3ZlcmlmeV9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdnJmX3ZlcmlmeQogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMwogICAgc2V0Yml0CiAgICBieXRlIDB4MDAwMwogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9zaGEyNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2hhMjU2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2hhMjU2KHNlbGYsIGE6IEJ5dGVzLCBwYWRfc2l6ZTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcKICAgIC8vIGEgPSBvcC5iemVybyhwYWRfc2l6ZSkgKyBhCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgZHVwCiAgICBmcmFtZV9idXJ5IC0yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OAogICAgLy8gcmVzdWx0ID0gb3Auc2hhMjU2KGEpCiAgICBzaGEyNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X3NoYTNfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTNfMjU2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExLTEyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zaGEzXzI1NihzZWxmLCBhOiBCeXRlcywgcGFkX3NpemU6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMwogICAgLy8gYSA9IG9wLmJ6ZXJvKHBhZF9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgLTIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNAogICAgLy8gcmVzdWx0ID0gb3Auc2hhM18yNTYoYSkKICAgIHNoYTNfMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfa2VjY2FrXzI1NihhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9rZWNjYWtfMjU2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3LTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9rZWNjYWtfMjU2KHNlbGYsIGE6IEJ5dGVzLCBwYWRfc2l6ZTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5CiAgICAvLyBhID0gb3AuYnplcm8ocGFkX3NpemUpICsgYQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIGR1cAogICAgZnJhbWVfYnVyeSAtMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIwCiAgICAvLyByZXN1bHQgPSBvcC5rZWNjYWsyNTYoYSkKICAgIGtlY2NhazI1NgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X3NoYTUxMl8yNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2hhNTEyXzI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMy0yNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2hhNTEyXzI1NihzZWxmLCBhOiBCeXRlcywgcGFkX3NpemU6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNQogICAgLy8gYSA9IG9wLmJ6ZXJvKHBhZF9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgLTIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNgogICAgLy8gcmVzdWx0ID0gb3Auc2hhNTEyXzI1NihhKQogICAgc2hhNTEyXzI1NgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VkMjU1MTl2ZXJpZnkoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9lZDI1NTE5dmVyaWZ5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9lZDI1NTE5dmVyaWZ5KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogQnl0ZXMpIC0+IGFyYzQuQm9vbDoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDE5MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgMTkwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyCiAgICAvLyByZXN1bHQgPSBvcC5lZDI1NTE5dmVyaWZ5KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlZDI1NTE5dmVyaWZ5CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzMKICAgIC8vIHJldHVybiBhcmM0LkJvb2wocmVzdWx0KQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIHJldHN1YgoKCi8vIGFsZ29weS5lbnN1cmVfYnVkZ2V0KHJlcXVpcmVkX2J1ZGdldDogdWludDY0LCBmZWVfc291cmNlOiB1aW50NjQpIC0+IHZvaWQ6CmVuc3VyZV9idWRnZXQ6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MTEtMTcKICAgIHByb3RvIDIgMAogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjE4CiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAxMAogICAgKwoKZW5zdXJlX2J1ZGdldF93aGlsZV90b3BAMToKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToxOQogICAgZnJhbWVfZGlnIDAKICAgIGdsb2JhbCBPcGNvZGVCdWRnZXQKICAgID4KICAgIGJ6IGVuc3VyZV9idWRnZXRfYWZ0ZXJfd2hpbGVANwogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjIwCiAgICBpdHhuX2JlZ2luCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjEKICAgIGludCBhcHBsCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjIKICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgaXR4bl9maWVsZCBPbkNvbXBsZXRpb24KICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyMwogICAgYnl0ZSAweDA2ODEwMQogICAgaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyNAogICAgYnl0ZSAweDA2ODEwMQogICAgaXR4bl9maWVsZCBDbGVhclN0YXRlUHJvZ3JhbQogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjI1LTI5CiAgICBmcmFtZV9kaWcgLTEKICAgIHN3aXRjaCBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzBAMyBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzFANAogICAgYiBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANgoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8wQDM6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjcKICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgYiBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANgoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8xQDQ6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjkKICAgIGdsb2JhbCBNaW5UeG5GZWUKICAgIGl0eG5fZmllbGQgRmVlCgplbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANjoKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weTozMAogICAgaXR4bl9zdWJtaXQKICAgIGIgZW5zdXJlX2J1ZGdldF93aGlsZV90b3BAMQoKZW5zdXJlX2J1ZGdldF9hZnRlcl93aGlsZUA3OgogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmUoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUtMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMsIGM6IEJ5dGVzKSAtPiBhcmM0LkJvb2w6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNwogICAgLy8gZW5zdXJlX2J1ZGdldCgxOTAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDE5MDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOAogICAgLy8gcmVzdWx0ID0gb3AuZWQyNTUxOXZlcmlmeV9iYXJlKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlZDI1NTE5dmVyaWZ5X2JhcmUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOQogICAgLy8gcmV0dXJuIGFyYzQuQm9vbChyZXN1bHQpCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9lY2RzYV92ZXJpZnlfazEoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcywgZDogYnl0ZXMsIGU6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9lY2RzYV92ZXJpZnlfazE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEtNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VjZHNhX3ZlcmlmeV9rMSggICMgbm9xYTogUExSMDkxMwogICAgLy8gICAgIHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogQnl0ZXMsIGQ6IEJ5dGVzLCBlOiBCeXRlcwogICAgLy8gKSAtPiBib29sOgogICAgcHJvdG8gNSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUKICAgIC8vIGVuc3VyZV9idWRnZXQoMzAwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCAzMDAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYKICAgIC8vIHJlc3VsdF9rMSA9IG9wLmVjZHNhX3ZlcmlmeShvcC5FQ0RTQS5TZWNwMjU2azEsIGEsIGIsIGMsIGQsIGUpCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfdmVyaWZ5IFNlY3AyNTZrMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyByZXR1cm4gcmVzdWx0X2sxCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcywgZTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0OS01MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxKCAgIyBub3FhOiBQTFIwOTEzCiAgICAvLyAgICAgc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzLCBjOiBCeXRlcywgZDogQnl0ZXMsIGU6IEJ5dGVzCiAgICAvLyApIC0+IGJvb2w6CiAgICBwcm90byA1IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MwogICAgLy8gZW5zdXJlX2J1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDMwMDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NAogICAgLy8gcmVzdWx0X3IxID0gb3AuZWNkc2FfdmVyaWZ5KG9wLkVDRFNBLlNlY3AyNTZyMSwgYSwgYiwgYywgZCwgZSkKICAgIGZyYW1lX2RpZyAtNQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV92ZXJpZnkgU2VjcDI1NnIxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUKICAgIC8vIHJldHVybiByZXN1bHRfcjEKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzLCBieXRlczoKdmVyaWZ5X2VjZHNhX3JlY292ZXJfazE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTctNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VjZHNhX3JlY292ZXJfazEoCiAgICAvLyAgICAgc2VsZiwgYTogQnl0ZXMsIGI6IFVJbnQ2NCwgYzogQnl0ZXMsIGQ6IEJ5dGVzCiAgICAvLyApIC0+IHR1cGxlW0J5dGVzLCBCeXRlc106CiAgICBwcm90byA0IDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MQogICAgLy8gZW5zdXJlX2J1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDMwMDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MgogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX3JlY292ZXIob3AuRUNEU0EuU2VjcDI1NmsxLCBhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19yZWNvdmVyIFNlY3AyNTZrMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IGJ5dGVzLCBkOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NC02NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMSgKICAgIC8vICAgICBzZWxmLCBhOiBCeXRlcywgYjogVUludDY0LCBjOiBCeXRlcywgZDogQnl0ZXMKICAgIC8vICkgLT4gdHVwbGVbQnl0ZXMsIEJ5dGVzXToKICAgIHByb3RvIDQgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcxCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDMwMDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgMzAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcyCiAgICAvLyByZXR1cm4gb3AuZWNkc2FfcGtfcmVjb3ZlcihvcC5FQ0RTQS5TZWNwMjU2cjEsIGEsIGIsIGMsIGQpCiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX3JlY292ZXIgU2VjcDI1NnIxCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazEoYTogYnl0ZXMpIC0+IGJ5dGVzLCBieXRlczoKdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzQtNzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazEoc2VsZiwgYTogQnl0ZXMpIC0+IHR1cGxlW0J5dGVzLCBCeXRlc106CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3NgogICAgLy8gZW5zdXJlX2J1ZGdldCg3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgNzAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzcKICAgIC8vIHJldHVybiBvcC5lY2RzYV9wa19kZWNvbXByZXNzKG9wLkVDRFNBLlNlY3AyNTZrMSwgYSkKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfcGtfZGVjb21wcmVzcyBTZWNwMjU2azEKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3OS04MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShzZWxmLCBhOiBCeXRlcykgLT4gdHVwbGVbQnl0ZXMsIEJ5dGVzXToKICAgIHByb3RvIDEgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDcwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCA3MDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4MgogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX2RlY29tcHJlc3Mob3AuRUNEU0EuU2VjcDI1NnIxLCBhKQogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19kZWNvbXByZXNzIFNlY3AyNTZyMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV92cmZfdmVyaWZ5KGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IGJ5dGVzLCB1aW50NjQ6CnZlcmlmeV92cmZfdmVyaWZ5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg0LTg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV92cmZfdmVyaWZ5KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogQnl0ZXMpIC0+IHR1cGxlW0J5dGVzLCBib29sXToKICAgIHByb3RvIDMgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg2CiAgICAvLyBlbnN1cmVfYnVkZ2V0KDU3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgNTcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg3CiAgICAvLyByZXN1bHQgPSBvcC52cmZfdmVyaWZ5KG9wLlZyZlZlcmlmeS5WcmZBbGdvcmFuZCwgYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHZyZl92ZXJpZnkgVnJmQWxnb3JhbmQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "CryptoOpsContract", + "methods": [ + { + "name": "verify_sha256", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "uint64", + "name": "pad_size" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_sha3_256", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "uint64", + "name": "pad_size" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_keccak_256", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "uint64", + "name": "pad_size" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_sha512_256", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "uint64", + "name": "pad_size" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_ed25519verify", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + }, + { + "type": "byte[]", + "name": "c" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "verify_ed25519verify_bare", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + }, + { + "type": "byte[]", + "name": "c" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "verify_ecdsa_verify_k1", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + }, + { + "type": "byte[]", + "name": "c" + }, + { + "type": "byte[]", + "name": "d" + }, + { + "type": "byte[]", + "name": "e" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "verify_ecdsa_verify_r1", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + }, + { + "type": "byte[]", + "name": "c" + }, + { + "type": "byte[]", + "name": "d" + }, + { + "type": "byte[]", + "name": "e" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "verify_ecdsa_recover_k1", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "uint64", + "name": "b" + }, + { + "type": "byte[]", + "name": "c" + }, + { + "type": "byte[]", + "name": "d" + } + ], + "returns": { + "type": "(byte[],byte[])" + } + }, + { + "name": "verify_ecdsa_recover_r1", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "uint64", + "name": "b" + }, + { + "type": "byte[]", + "name": "c" + }, + { + "type": "byte[]", + "name": "d" + } + ], + "returns": { + "type": "(byte[],byte[])" + }, + "desc": "Must fail, AVM does not support Secp256r1 for recover" + }, + { + "name": "verify_ecdsa_decompress_k1", + "args": [ + { + "type": "byte[]", + "name": "a" + } + ], + "returns": { + "type": "(byte[],byte[])" + } + }, + { + "name": "verify_ecdsa_decompress_r1", + "args": [ + { + "type": "byte[]", + "name": "a" + } + ], + "returns": { + "type": "(byte[],byte[])" + } + }, + { + "name": "verify_vrf_verify", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + }, + { + "type": "byte[]", + "name": "c" + } + ], + "returns": { + "type": "(byte[],bool)" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/tests/artifacts/StateOps/data/CryptoOpsContract.clear.teal b/tests/artifacts/StateOps/data/CryptoOpsContract.clear.teal new file mode 100644 index 0000000..b6f9242 --- /dev/null +++ b/tests/artifacts/StateOps/data/CryptoOpsContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.CryptoOpsContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/StateOps/data/StateOpsContract.approval.teal b/tests/artifacts/StateOps/data/StateOpsContract.approval.teal new file mode 100644 index 0000000..705a413 --- /dev/null +++ b/tests/artifacts/StateOps/data/StateOpsContract.approval.teal @@ -0,0 +1,655 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateOpsContract.approval_program: + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@18 + method "verify_asset_holding_get(account,asset)uint64" + method "verify_asset_frozen_get(account,asset)bool" + method "verify_asset_params_get_total(asset)uint64" + method "verify_asset_params_get_decimals(asset)uint64" + method "verify_asset_params_get_default_frozen(asset)bool" + method "verify_asset_params_get_unit_name(asset)byte[]" + method "verify_asset_params_get_name(asset)byte[]" + method "verify_asset_params_get_url(asset)byte[]" + method "verify_asset_params_get_metadata_hash(asset)byte[]" + method "verify_asset_params_get_manager(asset)byte[]" + method "verify_asset_params_get_reserve(asset)byte[]" + method "verify_asset_params_get_freeze(asset)byte[]" + method "verify_asset_params_get_clawback(asset)byte[]" + method "verify_asset_params_get_creator(asset)byte[]" + txna ApplicationArgs 0 + match main_verify_asset_holding_get_route@2 main_verify_asset_frozen_get_route@3 main_verify_asset_params_get_total_route@4 main_verify_asset_params_get_decimals_route@5 main_verify_asset_params_get_default_frozen_route@6 main_verify_asset_params_get_unit_name_route@7 main_verify_asset_params_get_name_route@8 main_verify_asset_params_get_url_route@9 main_verify_asset_params_get_metadata_hash_route@10 main_verify_asset_params_get_manager_route@11 main_verify_asset_params_get_reserve_route@12 main_verify_asset_params_get_freeze_route@13 main_verify_asset_params_get_clawback_route@14 main_verify_asset_params_get_creator_route@15 + err // reject transaction + +main_verify_asset_holding_get_route@2: + // tests/artifacts/StateOps/contract.py:5 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:5 + // @arc4.abimethod() + callsub verify_asset_holding_get + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_frozen_get_route@3: + // tests/artifacts/StateOps/contract.py:10 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:10 + // @arc4.abimethod() + callsub verify_asset_frozen_get + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_total_route@4: + // tests/artifacts/StateOps/contract.py:15 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:15 + // @arc4.abimethod() + callsub verify_asset_params_get_total + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_decimals_route@5: + // tests/artifacts/StateOps/contract.py:20 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:20 + // @arc4.abimethod() + callsub verify_asset_params_get_decimals + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_default_frozen_route@6: + // tests/artifacts/StateOps/contract.py:25 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:25 + // @arc4.abimethod() + callsub verify_asset_params_get_default_frozen + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_unit_name_route@7: + // tests/artifacts/StateOps/contract.py:30 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:30 + // @arc4.abimethod() + callsub verify_asset_params_get_unit_name + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_name_route@8: + // tests/artifacts/StateOps/contract.py:35 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:35 + // @arc4.abimethod() + callsub verify_asset_params_get_name + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_url_route@9: + // tests/artifacts/StateOps/contract.py:40 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:40 + // @arc4.abimethod() + callsub verify_asset_params_get_url + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_metadata_hash_route@10: + // tests/artifacts/StateOps/contract.py:45 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:45 + // @arc4.abimethod() + callsub verify_asset_params_get_metadata_hash + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_manager_route@11: + // tests/artifacts/StateOps/contract.py:50 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:50 + // @arc4.abimethod() + callsub verify_asset_params_get_manager + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_reserve_route@12: + // tests/artifacts/StateOps/contract.py:55 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:55 + // @arc4.abimethod() + callsub verify_asset_params_get_reserve + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_freeze_route@13: + // tests/artifacts/StateOps/contract.py:60 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:60 + // @arc4.abimethod() + callsub verify_asset_params_get_freeze + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_clawback_route@14: + // tests/artifacts/StateOps/contract.py:65 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:65 + // @arc4.abimethod() + callsub verify_asset_params_get_clawback + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_creator_route@15: + // tests/artifacts/StateOps/contract.py:70 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:70 + // @arc4.abimethod() + callsub verify_asset_params_get_creator + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@18: + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_holding_get(a: bytes, b: uint64) -> uint64: +verify_asset_holding_get: + // tests/artifacts/StateOps/contract.py:5-6 + // @arc4.abimethod() + // def verify_asset_holding_get(self, a: Account, b: Asset) -> UInt64: + proto 2 1 + // tests/artifacts/StateOps/contract.py:7 + // balance, _val = op.AssetHoldingGet.asset_balance(a, b) + frame_dig -2 + frame_dig -1 + asset_holding_get AssetBalance + pop + // tests/artifacts/StateOps/contract.py:8 + // return balance + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_frozen_get(a: bytes, b: uint64) -> uint64: +verify_asset_frozen_get: + // tests/artifacts/StateOps/contract.py:10-11 + // @arc4.abimethod() + // def verify_asset_frozen_get(self, a: Account, b: Asset) -> bool: + proto 2 1 + // tests/artifacts/StateOps/contract.py:12 + // frozen, _val = op.AssetHoldingGet.asset_frozen(a, b) + frame_dig -2 + frame_dig -1 + asset_holding_get AssetFrozen + pop + // tests/artifacts/StateOps/contract.py:13 + // return frozen + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_total(a: uint64) -> uint64: +verify_asset_params_get_total: + // tests/artifacts/StateOps/contract.py:15-16 + // @arc4.abimethod() + // def verify_asset_params_get_total(self, a: Asset) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:17 + // total, _val = op.AssetParamsGet.asset_total(a) + frame_dig -1 + asset_params_get AssetTotal + pop + // tests/artifacts/StateOps/contract.py:18 + // return total + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_decimals(a: uint64) -> uint64: +verify_asset_params_get_decimals: + // tests/artifacts/StateOps/contract.py:20-21 + // @arc4.abimethod() + // def verify_asset_params_get_decimals(self, a: Asset) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:22 + // decimals, _val = op.AssetParamsGet.asset_decimals(a) + frame_dig -1 + asset_params_get AssetDecimals + pop + // tests/artifacts/StateOps/contract.py:23 + // return decimals + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_default_frozen(a: uint64) -> uint64: +verify_asset_params_get_default_frozen: + // tests/artifacts/StateOps/contract.py:25-26 + // @arc4.abimethod() + // def verify_asset_params_get_default_frozen(self, a: Asset) -> bool: + proto 1 1 + // tests/artifacts/StateOps/contract.py:27 + // default_frozen, _val = op.AssetParamsGet.asset_default_frozen(a) + frame_dig -1 + asset_params_get AssetDefaultFrozen + pop + // tests/artifacts/StateOps/contract.py:28 + // return default_frozen + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_unit_name(a: uint64) -> bytes: +verify_asset_params_get_unit_name: + // tests/artifacts/StateOps/contract.py:30-31 + // @arc4.abimethod() + // def verify_asset_params_get_unit_name(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:32 + // unit_name, _val = op.AssetParamsGet.asset_unit_name(a) + frame_dig -1 + asset_params_get AssetUnitName + pop + // tests/artifacts/StateOps/contract.py:33 + // return unit_name + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_name(a: uint64) -> bytes: +verify_asset_params_get_name: + // tests/artifacts/StateOps/contract.py:35-36 + // @arc4.abimethod() + // def verify_asset_params_get_name(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:37 + // name, _val = op.AssetParamsGet.asset_name(a) + frame_dig -1 + asset_params_get AssetName + pop + // tests/artifacts/StateOps/contract.py:38 + // return name + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_url(a: uint64) -> bytes: +verify_asset_params_get_url: + // tests/artifacts/StateOps/contract.py:40-41 + // @arc4.abimethod() + // def verify_asset_params_get_url(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:42 + // url, _val = op.AssetParamsGet.asset_url(a) + frame_dig -1 + asset_params_get AssetURL + pop + // tests/artifacts/StateOps/contract.py:43 + // return url + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_metadata_hash(a: uint64) -> bytes: +verify_asset_params_get_metadata_hash: + // tests/artifacts/StateOps/contract.py:45-46 + // @arc4.abimethod() + // def verify_asset_params_get_metadata_hash(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:47 + // metadata_hash, _val = op.AssetParamsGet.asset_metadata_hash(a) + frame_dig -1 + asset_params_get AssetMetadataHash + pop + // tests/artifacts/StateOps/contract.py:48 + // return metadata_hash + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_manager(a: uint64) -> bytes: +verify_asset_params_get_manager: + // tests/artifacts/StateOps/contract.py:50-51 + // @arc4.abimethod() + // def verify_asset_params_get_manager(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:52 + // manager, _val = op.AssetParamsGet.asset_manager(a) + frame_dig -1 + asset_params_get AssetManager + pop + // tests/artifacts/StateOps/contract.py:53 + // return manager.bytes + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_reserve(a: uint64) -> bytes: +verify_asset_params_get_reserve: + // tests/artifacts/StateOps/contract.py:55-56 + // @arc4.abimethod() + // def verify_asset_params_get_reserve(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:57 + // reserve, _val = op.AssetParamsGet.asset_reserve(a) + frame_dig -1 + asset_params_get AssetReserve + pop + // tests/artifacts/StateOps/contract.py:58 + // return reserve.bytes + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_freeze(a: uint64) -> bytes: +verify_asset_params_get_freeze: + // tests/artifacts/StateOps/contract.py:60-61 + // @arc4.abimethod() + // def verify_asset_params_get_freeze(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:62 + // freeze, _val = op.AssetParamsGet.asset_freeze(a) + frame_dig -1 + asset_params_get AssetFreeze + pop + // tests/artifacts/StateOps/contract.py:63 + // return freeze.bytes + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_clawback(a: uint64) -> bytes: +verify_asset_params_get_clawback: + // tests/artifacts/StateOps/contract.py:65-66 + // @arc4.abimethod() + // def verify_asset_params_get_clawback(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:67 + // clawback, _val = op.AssetParamsGet.asset_clawback(a) + frame_dig -1 + asset_params_get AssetClawback + pop + // tests/artifacts/StateOps/contract.py:68 + // return clawback.bytes + retsub + + +// tests.artifacts.StateOps.contract.StateOpsContract.verify_asset_params_get_creator(a: uint64) -> bytes: +verify_asset_params_get_creator: + // tests/artifacts/StateOps/contract.py:70-71 + // @arc4.abimethod() + // def verify_asset_params_get_creator(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:72 + // creator, _val = op.AssetParamsGet.asset_creator(a) + frame_dig -1 + asset_params_get AssetCreator + pop + // tests/artifacts/StateOps/contract.py:73 + // return creator.bytes + retsub diff --git a/tests/artifacts/StateOps/data/StateOpsContract.arc32.json b/tests/artifacts/StateOps/data/StateOpsContract.arc32.json new file mode 100644 index 0000000..44db7bf --- /dev/null +++ b/tests/artifacts/StateOps/data/StateOpsContract.arc32.json @@ -0,0 +1,283 @@ +{ + "hints": { + "verify_asset_holding_get(account,asset)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_frozen_get(account,asset)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_total(asset)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_decimals(asset)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_default_frozen(asset)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_unit_name(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_name(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_url(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_metadata_hash(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_manager(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_reserve(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_freeze(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_clawback(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_asset_params_get_creator(asset)byte[]": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVPcHNDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIFN0YXRlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxOAogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoYWNjb3VudCxhc3NldCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KGFjY291bnQsYXNzZXQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwoYXNzZXQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFscyhhc3NldCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuKGFzc2V0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZShhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWUoYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmwoYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoKGFzc2V0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjayhhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXNzZXQpYnl0ZVtdIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXRfcm91dGVAMiBtYWluX3ZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0X3JvdXRlQDMgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbF9yb3V0ZUA0IG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHNfcm91dGVANSBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuX3JvdXRlQDYgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWVfcm91dGVANyBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWVfcm91dGVAOCBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybF9yb3V0ZUA5IG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaF9yb3V0ZUAxMCBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXJfcm91dGVAMTEgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9yZXNlcnZlX3JvdXRlQDEyIG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplX3JvdXRlQDEzIG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2tfcm91dGVAMTQgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jcmVhdG9yX3JvdXRlQDE1CiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX3ZlcmlmeV9hc3NldF9ob2xkaW5nX2dldF9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9ob2xkaW5nX2dldAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfZnJvemVuX2dldF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIFN0YXRlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuX3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWVfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBTdGF0ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybF9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIFN0YXRlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmwKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2hfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2gKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXJfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZV9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBTdGF0ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBTdGF0ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2sKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0AxODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBTdGF0ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlT3BzQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoc2VsZiwgYTogQWNjb3VudCwgYjogQXNzZXQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcKICAgIC8vIGJhbGFuY2UsIF92YWwgPSBvcC5Bc3NldEhvbGRpbmdHZXQuYXNzZXRfYmFsYW5jZShhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OAogICAgLy8gcmV0dXJuIGJhbGFuY2UKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZU9wc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAtMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoc2VsZiwgYTogQWNjb3VudCwgYjogQXNzZXQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMgogICAgLy8gZnJvemVuLCBfdmFsID0gb3AuQXNzZXRIb2xkaW5nR2V0LmFzc2V0X2Zyb3plbihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0RnJvemVuCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMwogICAgLy8gcmV0dXJuIGZyb3plbgogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlT3BzQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1LTE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKHNlbGYsIGE6IEFzc2V0KSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gdG90YWwsIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF90b3RhbChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4CiAgICAvLyByZXR1cm4gdG90YWwKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZU9wc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFsczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMC0yMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFscyhzZWxmLCBhOiBBc3NldCkgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjIKICAgIC8vIGRlY2ltYWxzLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZGVjaW1hbHMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlY2ltYWxzCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMwogICAgLy8gcmV0dXJuIGRlY2ltYWxzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVPcHNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUtMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW4oc2VsZiwgYTogQXNzZXQpIC0+IGJvb2w6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNwogICAgLy8gZGVmYXVsdF9mcm96ZW4sIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9kZWZhdWx0X2Zyb3plbihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RGVmYXVsdEZyb3plbgogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjgKICAgIC8vIHJldHVybiBkZWZhdWx0X2Zyb3plbgogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlT3BzQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMC0zMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUoc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzIKICAgIC8vIHVuaXRfbmFtZSwgX3ZhbCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VuaXRfbmFtZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzCiAgICAvLyByZXR1cm4gdW5pdF9uYW1lCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVPcHNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUtMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZShzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNwogICAgLy8gbmFtZSwgX3ZhbCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X25hbWUoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4CiAgICAvLyByZXR1cm4gbmFtZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlT3BzQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MC00MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmwoc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDIKICAgIC8vIHVybCwgX3ZhbCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VybChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VVJMCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MwogICAgLy8gcmV0dXJuIHVybAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlT3BzQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1LTQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2goc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDcKICAgIC8vIG1ldGFkYXRhX2hhc2gsIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tZXRhZGF0YV9oYXNoKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ4CiAgICAvLyByZXR1cm4gbWV0YWRhdGFfaGFzaAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlT3BzQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjUwLTUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIoc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTIKICAgIC8vIG1hbmFnZXIsIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tYW5hZ2VyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNYW5hZ2VyCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MwogICAgLy8gcmV0dXJuIG1hbmFnZXIuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZU9wc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NS01NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9yZXNlcnZlKHNlbGYsIGE6IEFzc2V0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3CiAgICAvLyByZXNlcnZlLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfcmVzZXJ2ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0UmVzZXJ2ZQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTgKICAgIC8vIHJldHVybiByZXNlcnZlLmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVPcHNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYwLTYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZShzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MgogICAgLy8gZnJlZXplLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZnJlZXplKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRGcmVlemUKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzCiAgICAvLyByZXR1cm4gZnJlZXplLmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVPcHNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjayhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjazoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NS02NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjayhzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NwogICAgLy8gY2xhd2JhY2ssIF92YWwgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9jbGF3YmFjayhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q2xhd2JhY2sKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjY4CiAgICAvLyByZXR1cm4gY2xhd2JhY2suYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZU9wc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3MC03MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jcmVhdG9yKHNlbGYsIGE6IEFzc2V0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcyCiAgICAvLyBjcmVhdG9yLCBfdmFsID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfY3JlYXRvcihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q3JlYXRvcgogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzMKICAgIC8vIHJldHVybiBjcmVhdG9yLmJ5dGVzCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVPcHNDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIFN0YXRlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": {}, + "reserved": {} + } + }, + "contract": { + "name": "StateOpsContract", + "methods": [ + { + "name": "verify_asset_holding_get", + "args": [ + { + "type": "account", + "name": "a" + }, + { + "type": "asset", + "name": "b" + } + ], + "returns": { + "type": "uint64" + } + }, + { + "name": "verify_asset_frozen_get", + "args": [ + { + "type": "account", + "name": "a" + }, + { + "type": "asset", + "name": "b" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "verify_asset_params_get_total", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "uint64" + } + }, + { + "name": "verify_asset_params_get_decimals", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "uint64" + } + }, + { + "name": "verify_asset_params_get_default_frozen", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "bool" + } + }, + { + "name": "verify_asset_params_get_unit_name", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_asset_params_get_name", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_asset_params_get_url", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_asset_params_get_metadata_hash", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_asset_params_get_manager", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_asset_params_get_reserve", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_asset_params_get_freeze", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_asset_params_get_clawback", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_asset_params_get_creator", + "args": [ + { + "type": "asset", + "name": "a" + } + ], + "returns": { + "type": "byte[]" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ No newline at end of file diff --git a/tests/artifacts/StateOps/data/StateOpsContract.clear.teal b/tests/artifacts/StateOps/data/StateOpsContract.clear.teal new file mode 100644 index 0000000..b8b45a9 --- /dev/null +++ b/tests/artifacts/StateOps/data/StateOpsContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateOpsContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:4 + // class StateOpsContract(ARC4Contract): + int 1 + return diff --git a/tests/common.py b/tests/common.py index 3c70e6e..099ffc3 100644 --- a/tests/common.py +++ b/tests/common.py @@ -1,8 +1,11 @@ +import math +import random import secrets import typing from pathlib import Path -from algokit_utils import ApplicationClient, get_localnet_default_account +import algosdk +from algokit_utils import Account, ApplicationClient, get_localnet_default_account from algosdk.v2client.algod import AlgodClient @@ -54,3 +57,44 @@ def create_avm_invoker(app_spec: Path, algod_client: AlgodClient) -> AVMInvoker: ) return AVMInvoker(client) + + +def generate_test_asset(algod_client: AlgodClient, sender: Account, total: int | None) -> int: + if total is None: + total = math.floor(random.random() * 100) + 20 # noqa: S311 + + decimals = 0 + asset_name = ( + f"ASA ${math.floor(random.random() * 100) + 1}_" # noqa: S311 + f"${math.floor(random.random() * 100) + 1}_${total}" # noqa: S311 + ) + + params = algod_client.suggested_params() + + txn = algosdk.transaction.AssetConfigTxn( + sender=sender.address, + sp=params, + total=total * 10**decimals, + decimals=decimals, + default_frozen=False, + unit_name="", + asset_name=asset_name, + manager=sender.address, + reserve=sender.address, + freeze=sender.address, + clawback=sender.address, + url="https://algorand.co", + metadata_hash=None, + note=None, + lease=None, + rekey_to=None, + ) # type: ignore[no-untyped-call, unused-ignore] + + signed_transaction = txn.sign(sender.private_key) # type: ignore[no-untyped-call, unused-ignore] + algod_client.send_transaction(signed_transaction) + ptx = algod_client.pending_transaction_info(txn.get_txid()) # type: ignore[no-untyped-call, unused-ignore] + + if isinstance(ptx, dict) and "asset-index" in ptx and isinstance(ptx["asset-index"], int): + return ptx["asset-index"] + else: + raise ValueError("Unexpected response from pending_transaction_info") diff --git a/tests/test_op.py b/tests/test_op.py index 6d661c1..19cd317 100644 --- a/tests/test_op.py +++ b/tests/test_op.py @@ -8,8 +8,9 @@ import ecdsa.util # type: ignore # noqa: PGH003 import nacl.signing import pytest +from algokit_utils import get_localnet_default_account from algopy_testing import op -from algopy_testing.context import algopy_testing_context +from algopy_testing.context import AlgopyTestContext, algopy_testing_context from algopy_testing.primitives.bytes import Bytes from algopy_testing.primitives.uint64 import UInt64 from algosdk.v2client.algod import AlgodClient @@ -17,10 +18,12 @@ from ecdsa import SECP256k1, SigningKey, curves from pytest_mock import MockerFixture -from tests.common import AVMInvoker, create_avm_invoker +from tests.artifacts.StateOps.contract import StateOpsContract +from tests.common import AVMInvoker, create_avm_invoker, generate_test_asset ARTIFACTS_DIR = Path(__file__).parent / "artifacts" -APP_SPEC = ARTIFACTS_DIR / "CryptoOps" / "data" / "CryptoOpsContract.arc32.json" +CRYPTO_OPS_APP_SPEC = ARTIFACTS_DIR / "CryptoOps" / "data" / "CryptoOpsContract.arc32.json" +STATE_OPS_APP_SPEC = ARTIFACTS_DIR / "StateOps" / "data" / "StateOpsContract.arc32.json" MAX_ARG_LEN = 2048 MAX_BYTES_SIZE = 4096 @@ -46,9 +49,21 @@ def _generate_ecdsa_test_data(curve: curves.Curve) -> dict[str, typing.Any]: } +@pytest.fixture() +def context() -> typing.Generator[AlgopyTestContext, None, None]: + with algopy_testing_context() as ctx: + yield ctx + ctx.reset() + + @pytest.fixture(scope="module") def get_crypto_ops_avm_result(algod_client: AlgodClient) -> AVMInvoker: - return create_avm_invoker(APP_SPEC, algod_client) + return create_avm_invoker(CRYPTO_OPS_APP_SPEC, algod_client) + + +@pytest.fixture(scope="module") +def get_state_ops_avm_result(algod_client: AlgodClient) -> AVMInvoker: + return create_avm_invoker(STATE_OPS_APP_SPEC, algod_client) @pytest.mark.parametrize( @@ -318,3 +333,159 @@ def run_mocked_vrf_verify() -> tuple[Bytes, bool]: mocked_result = run_mocked_vrf_verify() assert avm_result == mocked_result + + +def test_asset_holding_get( + algod_client: AlgodClient, get_state_ops_avm_result: AVMInvoker, context: AlgopyTestContext +) -> None: + dummy_account_a = get_localnet_default_account(algod_client) + expected_balance = 100 + dummy_asset = generate_test_asset(algod_client, dummy_account_a, expected_balance) + sp = algod_client.suggested_params() + sp.fee = 1000 + + avm_asset_balance = get_state_ops_avm_result( + "verify_asset_holding_get", + a=dummy_account_a.address, + b=dummy_asset, + suggested_params=sp, + ) + avm_frozen_balance = get_state_ops_avm_result( + "verify_asset_frozen_get", + a=dummy_account_a.address, + b=dummy_asset, + suggested_params=sp, + ) + + mock_asset = context.any_asset() + mock_account = context.any_account( + opted_asset_balances={mock_asset.id: algopy.UInt64(expected_balance)} + ) + mock_contract = StateOpsContract() + mock_asset_balance = mock_contract.verify_asset_holding_get(mock_account, mock_asset) + assert mock_asset_balance == avm_asset_balance == expected_balance + mock_frozen_balance = mock_contract.verify_asset_frozen_get(mock_account, mock_asset) + assert mock_frozen_balance == avm_frozen_balance is False + + +def test_asset_params_get( + algod_client: AlgodClient, get_state_ops_avm_result: AVMInvoker, context: AlgopyTestContext +) -> None: + dummy_account_a = get_localnet_default_account(algod_client) + expected_balance = 100 + dummy_asset = generate_test_asset(algod_client, dummy_account_a, expected_balance) + sp = algod_client.suggested_params() + sp.fee = 1000 + + mock_asset = context.any_asset( + total=algopy.UInt64(expected_balance), decimals=algopy.UInt64(0) + ) + mock_contract = StateOpsContract() + + # Test total + avm_total = get_state_ops_avm_result( + "verify_asset_params_get_total", + a=dummy_asset, + suggested_params=sp, + ) + mock_total = mock_contract.verify_asset_params_get_total(mock_asset) + assert mock_total == avm_total == expected_balance + + # Test decimals + avm_decimals = get_state_ops_avm_result( + "verify_asset_params_get_decimals", + a=dummy_asset, + suggested_params=sp, + ) + mock_decimals = mock_contract.verify_asset_params_get_decimals(mock_asset) + assert mock_decimals == avm_decimals + + # Test default frozen + avm_default_frozen = get_state_ops_avm_result( + "verify_asset_params_get_default_frozen", + a=dummy_asset, + suggested_params=sp, + ) + mock_default_frozen = mock_contract.verify_asset_params_get_default_frozen(mock_asset) + assert mock_default_frozen == avm_default_frozen + + # # Test unit name + # avm_unit_name = get_state_ops_avm_result( + # "verify_asset_params_get_unit_name", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_unit_name = mock_contract.verify_asset_params_get_unit_name(mock_asset) + # assert mock_unit_name == avm_unit_name + + # # Test name + # avm_name = get_state_ops_avm_result( + # "verify_asset_params_get_name", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_name = mock_contract.verify_asset_params_get_name(mock_asset) + # assert mock_name == avm_name + + # # Test URL + # avm_url = get_state_ops_avm_result( + # "verify_asset_params_get_url", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_url = mock_contract.verify_asset_params_get_url(mock_asset) + # assert mock_url == avm_url + + # # Test metadata hash + # avm_metadata_hash = get_state_ops_avm_result( + # "verify_asset_params_get_metadata_hash", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_metadata_hash = mock_contract.verify_asset_params_get_metadata_hash(mock_asset) + # assert mock_metadata_hash == avm_metadata_hash + + # # Test manager + # avm_manager = get_state_ops_avm_result( + # "verify_asset_params_get_manager", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_manager = mock_contract.verify_asset_params_get_manager(mock_asset) + # assert mock_manager == avm_manager + + # # Test reserve + # avm_reserve = get_state_ops_avm_result( + # "verify_asset_params_get_reserve", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_reserve = mock_contract.verify_asset_params_get_reserve(mock_asset) + # assert mock_reserve == avm_reserve + + # # Test freeze + # avm_freeze = get_state_ops_avm_result( + # "verify_asset_params_get_freeze", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_freeze = mock_contract.verify_asset_params_get_freeze(mock_asset) + # assert mock_freeze == avm_freeze + + # # Test clawback + # avm_clawback = get_state_ops_avm_result( + # "verify_asset_params_get_clawback", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_clawback = mock_contract.verify_asset_params_get_clawback(mock_asset) + # assert mock_clawback == avm_clawback + + # # Test creator + # avm_creator = get_state_ops_avm_result( + # "verify_asset_params_get_creator", + # a=dummy_asset, + # suggested_params=sp, + # ) + # mock_creator = mock_contract.verify_asset_params_get_creator(mock_asset) + # assert mock_creator == avm_creator