From 0bc1041e02398adcaa84020f33c86570636dd74b Mon Sep 17 00:00:00 2001 From: Adam Chidlow Date: Tue, 21 May 2024 14:20:19 +0800 Subject: [PATCH] - remove stub_name from WType (WIP) - make assignment type mismatch error a bit more generic - front ends should be validating this anyway, no need to confuse now with wtype names vs language native names - simplify / improve error message for arc4 copy requirements - remove var_expression usage (WIP) - boxes & state changes (WIP) - fix box bytes indexing - field_name -> member_name for contract class member vars --- examples/amm/out/client_ConstantProductAMM.py | 2 +- examples/amm/out/contract.awst | 106 ++--- examples/arc-28/out/client_EventEmitter.py | 4 +- examples/arc-28/out/contract.awst | 12 +- examples/auction/out/client_Auction.py | 4 +- examples/auction/out/contract.awst | 58 +-- examples/box_storage/contract.py | 8 +- .../box_storage/out/BoxContract.approval.mir | 326 ++++++++-------- .../box_storage/out/BoxContract.approval.teal | 100 ++--- .../box_storage/out/BoxContract.arc32.json | 2 +- .../out/BoxContract.destructured.ir | 120 +++--- examples/box_storage/out/BoxContract.ssa.ir | 170 ++++---- .../out/BoxContract.ssa.opt_pass_1.ir | 138 ++++--- .../out/BoxContract.ssa.opt_pass_2.ir | 120 +++--- .../out/BoxContract.ssa.opt_pass_3.ir | 120 +++--- .../out/BoxContract.ssa.opt_pass_4.ir | 120 +++--- .../out/BoxContract.ssa.opt_pass_5.ir | 120 +++--- .../box_storage/out/client_BoxContract.py | 10 +- examples/box_storage/out/contract.awst | 102 ++--- .../out_O2/BoxContract.approval.teal | 54 +-- .../out_O2/BoxContract.destructured.ir | 120 +++--- .../out_unoptimized/BoxContract.approval.teal | 126 +++--- .../BoxContract.destructured.ir | 176 +++++---- examples/box_storage/puya.log | 302 +++++++------- examples/calculator/out/contract.awst | 44 +-- .../out/AppStateContract.approval.mir | 58 +-- examples/global_state/out/contract.awst | 36 +- examples/hello_world/out/contract.awst | 2 +- examples/hello_world_arc4/out/contract.awst | 2 +- .../local_state/out/local_state_contract.awst | 20 +- .../out/local_state_with_offsets.awst | 22 +- examples/merkle/out/contract.awst | 20 +- .../out/TicTacToeContract.approval.mir | 2 +- .../tictactoe/out/client_TicTacToeContract.py | 8 +- examples/tictactoe/out/tictactoe.awst | 60 +-- .../voting/out/VotingRoundApp.approval.mir | 14 +- .../voting/out/VotingRoundApp.approval.teal | 8 +- examples/voting/out/VotingRoundApp.arc32.json | 2 +- examples/voting/out/VotingRoundApp.ssa.ir | 10 +- .../out/VotingRoundApp.ssa.opt_pass_1.ir | 4 +- examples/voting/out/client_VotingRoundApp.py | 18 +- examples/voting/out/voting.awst | 132 +++---- .../VotingRoundApp.approval.teal | 12 +- .../VotingRoundApp.destructured.ir | 10 +- examples/voting/puya.log | 10 +- examples/voting/voting.py | 4 +- pyproject.toml | 1 + src/puya/arc32.py | 4 +- src/puya/awst/function_traverser.py | 17 +- src/puya/awst/nodes.py | 171 ++------ src/puya/awst/to_code_visitor.py | 35 +- src/puya/awst/visitors.py | 12 - src/puya/awst/wtypes.py | 212 +++------- src/puya/awst_build/contract.py | 18 +- src/puya/awst_build/eb/_storage.py | 144 +++++++ src/puya/awst_build/eb/app_account_state.py | 367 ++++++++++-------- src/puya/awst_build/eb/app_state.py | 281 ++++++++------ src/puya/awst_build/eb/arc4/_utils.py | 70 ++-- src/puya/awst_build/eb/arc4/abi_call.py | 56 +-- src/puya/awst_build/eb/arc4/arrays.py | 236 ++++++----- src/puya/awst_build/eb/arc4/base.py | 77 ++-- src/puya/awst_build/eb/arc4/bool.py | 19 +- src/puya/awst_build/eb/arc4/dynamic_bytes.py | 45 +-- src/puya/awst_build/eb/arc4/emit.py | 26 +- src/puya/awst_build/eb/arc4/numeric.py | 66 ++-- src/puya/awst_build/eb/arc4/string.py | 7 +- src/puya/awst_build/eb/arc4/struct.py | 39 +- src/puya/awst_build/eb/arc4/tuple.py | 55 +-- src/puya/awst_build/eb/array.py | 49 ++- src/puya/awst_build/eb/base.py | 207 +++++----- src/puya/awst_build/eb/biguint.py | 7 +- src/puya/awst_build/eb/bool.py | 9 +- src/puya/awst_build/eb/box/_common.py | 48 ++- src/puya/awst_build/eb/box/_util.py | 65 +++- src/puya/awst_build/eb/box/box.py | 239 ++++++------ src/puya/awst_build/eb/box/box_map.py | 300 +++++++------- src/puya/awst_build/eb/box/box_ref.py | 152 +++++--- src/puya/awst_build/eb/bytes.py | 10 +- src/puya/awst_build/eb/bytes_backed.py | 56 ++- src/puya/awst_build/eb/contracts.py | 88 +++-- src/puya/awst_build/eb/ensure_budget.py | 12 +- src/puya/awst_build/eb/intrinsics.py | 60 +-- src/puya/awst_build/eb/log.py | 8 +- .../awst_build/eb/reference_types/account.py | 135 +++---- .../eb/reference_types/application.py | 44 ++- .../awst_build/eb/reference_types/asset.py | 69 ++-- .../awst_build/eb/reference_types/base.py | 63 ++- src/puya/awst_build/eb/string.py | 17 +- src/puya/awst_build/eb/struct.py | 25 +- src/puya/awst_build/eb/subroutine.py | 11 +- src/puya/awst_build/eb/template_variables.py | 21 +- src/puya/awst_build/eb/transaction/base.py | 32 +- src/puya/awst_build/eb/transaction/group.py | 103 +++-- src/puya/awst_build/eb/transaction/inner.py | 115 +++--- .../awst_build/eb/transaction/inner_params.py | 84 ++-- src/puya/awst_build/eb/tuple.py | 85 ++-- src/puya/awst_build/eb/type_registry.py | 64 +-- src/puya/awst_build/eb/uint64.py | 7 +- src/puya/awst_build/eb/unsigned_builtins.py | 42 +- src/puya/awst_build/eb/value_proxy.py | 9 +- src/puya/awst_build/eb/var_factory.py | 12 +- src/puya/awst_build/eb/void.py | 8 +- src/puya/awst_build/pytypes.py | 245 ++++++------ src/puya/awst_build/subroutine.py | 180 +++------ src/puya/awst_build/utils.py | 15 +- src/puya/awst_build/validation/arc4_copy.py | 17 +- src/puya/ir/builder/box.py | 131 +------ src/puya/ir/builder/main.py | 12 - src/puya/ir/builder/state.py | 46 ++- src/puya/ir/types_.py | 11 +- stubs/algopy-stubs/_box.pyi | 43 +- .../abi_routing/out/client_Reference.py | 68 ++-- test_cases/abi_routing/out/contract.awst | 90 ++--- test_cases/abi_routing/out/minimal.awst | 4 +- test_cases/application/out/contract.awst | 28 +- .../arc4_numeric_comparisons/out/uint_n.awst | 354 ++++++++--------- test_cases/arc4_types/out/address.awst | 18 +- test_cases/arc4_types/out/array.awst | 42 +- test_cases/arc4_types/out/bool.awst | 21 +- test_cases/arc4_types/out/bool_eval.awst | 66 ++-- test_cases/arc4_types/out/dynamic_bytes.awst | 32 +- .../arc4_types/out/dynamic_string_array.awst | 10 +- test_cases/arc4_types/out/mutable_params.awst | 68 ++-- test_cases/arc4_types/out/mutation.awst | 184 ++++----- test_cases/arc4_types/out/numeric.awst | 84 ++-- .../arc4_types/out/reference_types.awst | 12 +- test_cases/arc4_types/out/string.awst | 32 +- test_cases/arc4_types/out/structs.awst | 46 +-- test_cases/arc4_types/out/structs2.awst | 4 +- test_cases/arc4_types/out/tuples.awst | 42 +- test_cases/asset/out/contract.awst | 14 +- .../augmented_assignment/out/contract.awst | 22 +- .../out/client_TestContract.py | 12 +- test_cases/avm_types_in_abi/out/contract.awst | 10 +- .../biguint_binary_ops/out/contract.awst | 4 +- .../boolean_binary_ops/out/contract.awst | 12 +- test_cases/bytes_ops/out/contract.awst | 16 +- test_cases/callsub/out/contract.awst | 6 +- .../chained_assignment/out/contract.awst | 12 +- .../conditional_execution/out/contract.awst | 2 +- .../conditional_expressions/out/contract.awst | 28 +- .../constants/out/address_constant.awst | 12 +- test_cases/constants/out/byte_constants.awst | 12 +- test_cases/contains/out/contract.awst | 12 +- .../dup2_optimization_bug/out/crash.awst | 4 +- test_cases/enumeration/out/contract.awst | 30 +- .../everything/out/client_MyContract.py | 6 +- test_cases/everything/out/contract.awst | 46 +-- test_cases/everything/out/my_base.awst | 12 +- .../inner_transactions/out/array_access.awst | 10 +- .../out/asset_transfer.awst | 4 +- test_cases/inner_transactions/out/c2c.awst | 18 +- .../inner_transactions/out/client_Greeter.py | 2 +- .../inner_transactions/out/contract.awst | 82 ++-- .../out/field_tuple_assignment.awst | 16 +- .../inner_transactions/out/itxn_loop.awst | 8 +- .../intrinsics/out/Overloaded.approval.mir | 4 +- .../intrinsics/out/immediate_variants.awst | 6 +- test_cases/intrinsics/out/overloaded.awst | 4 +- test_cases/koopman/out/contract.awst | 14 +- test_cases/less_simple/out/contract.awst | 16 +- test_cases/logic_signature/out/signature.awst | 12 +- test_cases/match/out/contract.awst | 56 +-- test_cases/mylib/out/simple_functions.awst | 50 +-- test_cases/nested_loops/out/contract.awst | 10 +- .../regression_118/out/client_Contract.py | 2 +- test_cases/regression_118/out/contract.awst | 8 +- test_cases/reinterpret_cast/out/contract.awst | 6 +- .../reversed_iteration/out/contract.awst | 30 +- test_cases/scratch_slots/out/contract2.awst | 2 +- test_cases/simple/out/contract.awst | 12 +- test_cases/simple/out/pkg_a/pkg_1/subs.awst | 2 +- test_cases/simple/out/subs.awst | 2 +- test_cases/simplish/out/base_class.awst | 12 +- test_cases/simplish/out/contract.awst | 78 ++-- test_cases/ssa/out/contract.awst | 56 +-- test_cases/ssa2/out/contract.awst | 22 +- test_cases/state_proxies/contract.py | 4 +- .../out/StateProxyContract.approval.mir | 64 +-- .../out/StateProxyContract.approval.teal | 4 +- .../out/StateProxyContract.arc32.json | 2 +- test_cases/state_proxies/out/contract.awst | 18 +- .../StateProxyContract.approval.teal | 4 +- test_cases/state_totals/out/contract.awst | 6 +- .../out/brute_force_rotation_search.awst | 6 +- test_cases/string_ops/out/contract.awst | 2 +- test_cases/stubs/out/biguint.awst | 8 +- test_cases/stubs/out/bytes.awst | 36 +- test_cases/stubs/out/string.awst | 50 +-- test_cases/stubs/out/uint64.awst | 22 +- .../out/client_TemplateVariablesContract.py | 2 +- .../template_variables/out/contract.awst | 16 +- .../too_many_permutations/out/contract.awst | 12 +- test_cases/transaction/out/contract.awst | 26 +- .../tuple_support/out/tuple_support.awst | 78 ++-- .../typed_abi_call/out/client_Logger.py | 58 +-- test_cases/typed_abi_call/out/logger.awst | 40 +- test_cases/typed_abi_call/out/typed_c2c.awst | 136 +++---- test_cases/unary/out/contract.awst | 6 +- .../unassigned_expression/out/contract.awst | 8 +- test_cases/undefined_phi_args/out/baddie.awst | 38 +- test_cases/unssa/out/contract.awst | 68 ++-- test_cases/with_reentrancy/out/contract.awst | 32 +- tests/test_arc32.py | 2 +- tests/test_expected_output/arc4.test | 100 +++-- tests/test_expected_output/awst.test | 6 +- .../test_expected_output/expected_errors.test | 8 +- tests/test_expected_output/subroutine.test | 6 +- tests/test_transaction_fields.py | 2 +- 209 files changed, 5304 insertions(+), 5419 deletions(-) create mode 100644 src/puya/awst_build/eb/_storage.py diff --git a/examples/amm/out/client_ConstantProductAMM.py b/examples/amm/out/client_ConstantProductAMM.py index cbeb3d9ee..27dddb37a 100644 --- a/examples/amm/out/client_ConstantProductAMM.py +++ b/examples/amm/out/client_ConstantProductAMM.py @@ -19,7 +19,7 @@ def bootstrap( seed: algopy.gtxn.PaymentTransaction, a_asset: algopy.Asset, b_asset: algopy.Asset, - ) -> algopy.arc4.UInt64: ... + ) -> algopy.arc4.UIntN[typing.Literal[64]]: ... @algopy.arc4.abimethod(default_args={'pool_asset': 'pool_token', 'a_asset': 'asset_a', 'b_asset': 'asset_b'}) def mint( diff --git a/examples/amm/out/contract.awst b/examples/amm/out/contract.awst index dc91e82c2..d928dcbc1 100644 --- a/examples/amm/out/contract.awst +++ b/examples/amm/out/contract.awst @@ -6,45 +6,45 @@ FACTOR = 995 contract ConstantProductAMM { globals { - ['asset_a']: algopy.Asset - ['asset_b']: algopy.Asset - ['governor']: algopy.Account - ['pool_token']: algopy.Asset - ['ratio']: algopy.UInt64 + ['asset_a']: asset + ['asset_b']: asset + ['governor']: account + ['pool_token']: asset + ['ratio']: uint64 } constructor() { - this.asset_a: algopy.Asset = reinterpret_cast(0u) - this.asset_b: algopy.Asset = reinterpret_cast(0u) - this.governor: algopy.Account = txn() - this.pool_token: algopy.Asset = reinterpret_cast(0u) - this.ratio: algopy.UInt64 = 0u + this.asset_a: asset = reinterpret_cast(0u) + this.asset_b: asset = reinterpret_cast(0u) + this.governor: account = txn() + this.pool_token: asset = reinterpret_cast(0u) + this.ratio: uint64 = 0u } - abimethod set_governor(new_governor: algopy.Account): None + abimethod set_governor(new_governor: account): void { this::_check_is_governor() - this.governor: algopy.Account = new_governor + this.governor: account = new_governor } - abimethod bootstrap(seed: algopy.gtxn.PaymentTransaction, a_asset: algopy.Asset, b_asset: algopy.Asset): algopy.UInt64 + abimethod bootstrap(seed: group_transaction_pay, a_asset: asset, b_asset: asset): uint64 { assert(!(reinterpret_cast(this.pool_token)), comment="application has already been bootstrapped") this::_check_is_governor() assert(global() == 2u, comment="group size not 2") assert(gtxns(seed) == global(), comment="receiver not app address") assert(gtxns(seed) >= 300000u, comment="amount minimum not met") - assert(reinterpret_cast(a_asset) < reinterpret_cast(b_asset), comment="asset a must be less than asset b") - this.asset_a: algopy.Asset = a_asset - this.asset_b: algopy.Asset = b_asset - this.pool_token: algopy.Asset = this::_create_pool_token() + assert(reinterpret_cast(a_asset) < reinterpret_cast(b_asset), comment="asset a must be less than asset b") + this.asset_a: asset = a_asset + this.asset_b: asset = b_asset + this.pool_token: asset = this::_create_pool_token() this::_do_opt_in(this.asset_a) this::_do_opt_in(this.asset_b) - return reinterpret_cast(this.pool_token) + return reinterpret_cast(this.pool_token) } - abimethod mint(a_xfer: algopy.gtxn.AssetTransferTransaction, b_xfer: algopy.gtxn.AssetTransferTransaction, pool_asset: algopy.Asset, a_asset: algopy.Asset, b_asset: algopy.Asset): None + abimethod mint(a_xfer: group_transaction_axfer, b_xfer: group_transaction_axfer, pool_asset: asset, a_asset: asset, b_asset: asset): void { this::_check_bootstrapped() assert(pool_asset == this.pool_token, comment="asset pool incorrect") @@ -58,13 +58,13 @@ contract ConstantProductAMM assert(gtxns(b_xfer) == global(), comment="receiver not app address") assert(gtxns(b_xfer) == this.asset_b, comment="asset b incorrect") assert(gtxns(b_xfer) > 0u, comment="amount minimum not met") - to_mint: algopy.UInt64 = examples.amm.contract::tokens_to_mint(pool_balance=this::_current_pool_balance(), a_balance=this::_current_a_balance(), b_balance=this::_current_b_balance(), a_amount=gtxns(a_xfer), b_amount=gtxns(b_xfer)) + to_mint: uint64 = examples.amm.contract::tokens_to_mint(pool_balance=this::_current_pool_balance(), a_balance=this::_current_a_balance(), b_balance=this::_current_b_balance(), a_amount=gtxns(a_xfer), b_amount=gtxns(b_xfer)) assert(to_mint > 0u, comment="send amount too low") examples.amm.contract::do_asset_transfer(receiver=txn(), asset=this.pool_token, amount=to_mint) this::_update_ratio() } - abimethod burn(pool_xfer: algopy.gtxn.AssetTransferTransaction, pool_asset: algopy.Asset, a_asset: algopy.Asset, b_asset: algopy.Asset): None + abimethod burn(pool_xfer: group_transaction_axfer, pool_asset: asset, a_asset: asset, b_asset: asset): void { this::_check_bootstrapped() assert(pool_asset == this.pool_token, comment="asset pool incorrect") @@ -74,15 +74,15 @@ contract ConstantProductAMM assert(gtxns(pool_xfer) > 0u, comment="amount minimum not met") assert(gtxns(pool_xfer) == this.pool_token, comment="asset pool incorrect") assert(gtxns(pool_xfer) == txn(), comment="sender invalid") - pool_balance: algopy.UInt64 = this::_current_pool_balance() - a_amt: algopy.UInt64 = examples.amm.contract::tokens_to_burn(pool_balance=pool_balance, supply=this::_current_a_balance(), amount=gtxns(pool_xfer)) - b_amt: algopy.UInt64 = examples.amm.contract::tokens_to_burn(pool_balance=pool_balance, supply=this::_current_b_balance(), amount=gtxns(pool_xfer)) + pool_balance: uint64 = this::_current_pool_balance() + a_amt: uint64 = examples.amm.contract::tokens_to_burn(pool_balance=pool_balance, supply=this::_current_a_balance(), amount=gtxns(pool_xfer)) + b_amt: uint64 = examples.amm.contract::tokens_to_burn(pool_balance=pool_balance, supply=this::_current_b_balance(), amount=gtxns(pool_xfer)) examples.amm.contract::do_asset_transfer(receiver=txn(), asset=this.asset_a, amount=a_amt) examples.amm.contract::do_asset_transfer(receiver=txn(), asset=this.asset_b, amount=b_amt) this::_update_ratio() } - abimethod swap(swap_xfer: algopy.gtxn.AssetTransferTransaction, a_asset: algopy.Asset, b_asset: algopy.Asset): None + abimethod swap(swap_xfer: group_transaction_axfer, a_asset: asset, b_asset: asset): void { this::_check_bootstrapped() assert(a_asset == this.asset_a, comment="asset a incorrect") @@ -91,77 +91,77 @@ contract ConstantProductAMM assert(gtxns(swap_xfer) == txn(), comment="sender invalid") switch (SINGLE_EVAL(id=0, source=gtxns(swap_xfer))) { case this.asset_a: { - in_supply: algopy.UInt64 = this::_current_b_balance() - out_supply: algopy.UInt64 = this::_current_a_balance() - out_asset: algopy.Asset = this.asset_a + in_supply: uint64 = this::_current_b_balance() + out_supply: uint64 = this::_current_a_balance() + out_asset: asset = this.asset_a } case this.asset_b: { - in_supply: algopy.UInt64 = this::_current_a_balance() - out_supply: algopy.UInt64 = this::_current_b_balance() - out_asset: algopy.Asset = this.asset_b + in_supply: uint64 = this::_current_a_balance() + out_supply: uint64 = this::_current_b_balance() + out_asset: asset = this.asset_b } case _: { assert(false, comment="asset id incorrect") } } - to_swap: algopy.UInt64 = examples.amm.contract::tokens_to_swap(in_amount=gtxns(swap_xfer), in_supply=in_supply, out_supply=out_supply) + to_swap: uint64 = examples.amm.contract::tokens_to_swap(in_amount=gtxns(swap_xfer), in_supply=in_supply, out_supply=out_supply) assert(to_swap > 0u, comment="send amount too low") examples.amm.contract::do_asset_transfer(receiver=txn(), asset=out_asset, amount=to_swap) this::_update_ratio() } - subroutine _check_bootstrapped(): None + subroutine _check_bootstrapped(): void { assert(reinterpret_cast(this.pool_token), comment="bootstrap method needs to be called first") } - subroutine _update_ratio(): None + subroutine _update_ratio(): void { - a_balance: algopy.UInt64 = this::_current_a_balance() - b_balance: algopy.UInt64 = this::_current_b_balance() - this.ratio: algopy.UInt64 = a_balance * 1000u // b_balance + a_balance: uint64 = this::_current_a_balance() + b_balance: uint64 = this::_current_b_balance() + this.ratio: uint64 = a_balance * 1000u // b_balance } - subroutine _check_is_governor(): None + subroutine _check_is_governor(): void { assert(txn() == this.governor, comment="Only the account set in global_state.governor may call this method") } - subroutine _create_pool_token(): algopy.Asset + subroutine _create_pool_token(): asset { return submit_txn(create_inner_transaction(Fee=0u, TypeEnum=acfg, ConfigAssetName='DPT-' + checked_maybe(asset_params_get(this.asset_a)) + '-' + checked_maybe(asset_params_get(this.asset_b)), ConfigAssetUnitName='dbt', ConfigAssetTotal=10000000000u, ConfigAssetDecimals=3u, ConfigAssetManager=global(), ConfigAssetReserve=global())).CreatedAssetID } - subroutine _do_opt_in(asset: algopy.Asset): None + subroutine _do_opt_in(asset: asset): void { examples.amm.contract::do_asset_transfer(receiver=global(), asset=asset, amount=0u) } - subroutine _current_pool_balance(): algopy.UInt64 + subroutine _current_pool_balance(): uint64 { return checked_maybe(asset_holding_get(global(), this.pool_token)) } - subroutine _current_a_balance(): algopy.UInt64 + subroutine _current_a_balance(): uint64 { return checked_maybe(asset_holding_get(global(), this.asset_a)) } - subroutine _current_b_balance(): algopy.UInt64 + subroutine _current_b_balance(): uint64 { return checked_maybe(asset_holding_get(global(), this.asset_b)) } } -subroutine tokens_to_mint(pool_balance: algopy.UInt64, a_balance: algopy.UInt64, b_balance: algopy.UInt64, a_amount: algopy.UInt64, b_amount: algopy.UInt64): algopy.UInt64 +subroutine tokens_to_mint(pool_balance: uint64, a_balance: uint64, b_balance: uint64, a_amount: uint64, b_amount: uint64): uint64 { is_initial_mint: bool = a_balance == a_amount and b_balance == b_amount if (is_initial_mint) { return sqrt(a_amount * b_amount) - 1000u } - issued: algopy.UInt64 = 10000000000u - pool_balance - a_ratio: algopy.UInt64 = 1000u * a_amount // a_balance - a_amount - b_ratio: algopy.UInt64 = 1000u * b_amount // b_balance - b_amount + issued: uint64 = 10000000000u - pool_balance + a_ratio: uint64 = 1000u * a_amount // a_balance - a_amount + b_ratio: uint64 = 1000u * b_amount // b_balance - b_amount if (a_ratio < b_ratio) { return a_ratio * issued // 1000u } else { @@ -169,20 +169,20 @@ subroutine tokens_to_mint(pool_balance: algopy.UInt64, a_balance: algopy.UInt64, } } -subroutine tokens_to_burn(pool_balance: algopy.UInt64, supply: algopy.UInt64, amount: algopy.UInt64): algopy.UInt64 +subroutine tokens_to_burn(pool_balance: uint64, supply: uint64, amount: uint64): uint64 { - issued: algopy.UInt64 = 10000000000u - pool_balance - amount + issued: uint64 = 10000000000u - pool_balance - amount return supply * amount // issued } -subroutine tokens_to_swap(in_amount: algopy.UInt64, in_supply: algopy.UInt64, out_supply: algopy.UInt64): algopy.UInt64 +subroutine tokens_to_swap(in_amount: uint64, in_supply: uint64, out_supply: uint64): uint64 { - in_total: algopy.UInt64 = 1000u * in_supply - in_amount + in_amount * 995u - out_total: algopy.UInt64 = in_amount * 995u * out_supply + in_total: uint64 = 1000u * in_supply - in_amount + in_amount * 995u + out_total: uint64 = in_amount * 995u * out_supply return out_total // in_total } -subroutine do_asset_transfer(receiver: algopy.Account, asset: algopy.Asset, amount: algopy.UInt64): None +subroutine do_asset_transfer(receiver: account, asset: asset, amount: uint64): void { submit_txn(create_inner_transaction(Fee=0u, TypeEnum=axfer, XferAsset=asset, AssetAmount=amount, AssetReceiver=receiver)) } \ No newline at end of file diff --git a/examples/arc-28/out/client_EventEmitter.py b/examples/arc-28/out/client_EventEmitter.py index 88c22672f..7e537b38a 100644 --- a/examples/arc-28/out/client_EventEmitter.py +++ b/examples/arc-28/out/client_EventEmitter.py @@ -10,6 +10,6 @@ class EventEmitter(algopy.arc4.ARC4Client, typing.Protocol): @algopy.arc4.abimethod def emit_swapped( self, - a: algopy.arc4.UInt64, - b: algopy.arc4.UInt64, + a: algopy.arc4.UIntN[typing.Literal[64]], + b: algopy.arc4.UIntN[typing.Literal[64]], ) -> None: ... diff --git a/examples/arc-28/out/contract.awst b/examples/arc-28/out/contract.awst index 4bdfd59ea..f481affed 100644 --- a/examples/arc-28/out/contract.awst +++ b/examples/arc-28/out/contract.awst @@ -1,14 +1,14 @@ struct Swapped { - a: algopy.arc4.UInt64 - b: algopy.arc4.UInt64 + a: arc4.uint64 + b: arc4.uint64 } contract EventEmitter { - abimethod emit_swapped(a: algopy.arc4.UInt64, b: algopy.arc4.UInt64): None + abimethod emit_swapped(a: arc4.uint64, b: arc4.uint64): void { - log(concat(Method("Swapped(uint64,uint64)"), new contract.Swapped(a=b, b=a))) - log(concat(Method("Swapped(uint64,uint64)"), arc4_encode((b, a), algopy.arc4.Tuple[algopy.arc4.UInt64, algopy.arc4.UInt64]))) - log(concat(Method("Swapped(uint64,uint64)"), arc4_encode((b, a), algopy.arc4.Tuple[algopy.arc4.UInt64, algopy.arc4.UInt64]))) + log(concat(Method("Swapped(uint64,uint64)"), new arc4.struct(a=b, b=a))) + log(concat(Method("Swapped(uint64,uint64)"), arc4_encode((b, a), arc4.tuple))) + log(concat(Method("Swapped(uint64,uint64)"), arc4_encode((b, a), arc4.tuple))) } } \ No newline at end of file diff --git a/examples/auction/out/client_Auction.py b/examples/auction/out/client_Auction.py index 54b441203..b732937d2 100644 --- a/examples/auction/out/client_Auction.py +++ b/examples/auction/out/client_Auction.py @@ -16,8 +16,8 @@ def opt_into_asset( @algopy.arc4.abimethod def start_auction( self, - starting_price: algopy.arc4.UInt64, - length: algopy.arc4.UInt64, + starting_price: algopy.arc4.UIntN[typing.Literal[64]], + length: algopy.arc4.UIntN[typing.Literal[64]], axfer: algopy.gtxn.AssetTransferTransaction, ) -> None: ... diff --git a/examples/auction/out/contract.awst b/examples/auction/out/contract.awst index df5183a3e..efce964f0 100644 --- a/examples/auction/out/contract.awst +++ b/examples/auction/out/contract.awst @@ -1,23 +1,23 @@ contract Auction { globals { - ['auction_end']: algopy.UInt64 - ['previous_bid']: algopy.UInt64 - ['asa_amount']: algopy.UInt64 - ['asa']: algopy.Asset - ['previous_bidder']: algopy.Account + ['auction_end']: uint64 + ['previous_bid']: uint64 + ['asa_amount']: uint64 + ['asa']: asset + ['previous_bidder']: account } locals { - ['claim']: algopy.UInt64 + ['claim']: uint64 } constructor() { - this.auction_end: algopy.UInt64 = 0u - this.previous_bid: algopy.UInt64 = 0u - this.asa_amount: algopy.UInt64 = 0u - this.asa: algopy.Asset = reinterpret_cast(0u) - this.previous_bidder: algopy.Account = global() + this.auction_end: uint64 = 0u + this.previous_bid: uint64 = 0u + this.asa_amount: uint64 = 0u + this.asa: asset = reinterpret_cast(0u) + this.previous_bidder: account = global() } clear_state_program(): bool @@ -25,56 +25,56 @@ contract Auction return true } - abimethod opt_into_asset(asset: algopy.Asset): None + abimethod opt_into_asset(asset: asset): void { assert(txn() == global(), comment="Only creator can opt in to ASA") - assert(reinterpret_cast(this.asa) == 0u, comment="ASA already opted in") - this.asa: algopy.Asset = asset + assert(reinterpret_cast(this.asa) == 0u, comment="ASA already opted in") + this.asa: asset = asset submit_txn(create_inner_transaction(Fee=0u, TypeEnum=axfer, AssetReceiver=global(), XferAsset=asset)) } - abimethod start_auction(starting_price: algopy.UInt64, length: algopy.UInt64, axfer: algopy.gtxn.AssetTransferTransaction): None + abimethod start_auction(starting_price: uint64, length: uint64, axfer: group_transaction_axfer): void { assert(txn() == global(), comment="auction must be started by creator") assert(this.auction_end == 0u, comment="auction already started") assert(gtxns(axfer) == global(), comment="axfer must transfer to this app") - this.asa_amount: algopy.UInt64 = gtxns(axfer) - this.auction_end: algopy.UInt64 = global() + length - this.previous_bid: algopy.UInt64 = starting_price + this.asa_amount: uint64 = gtxns(axfer) + this.auction_end: uint64 = global() + length + this.previous_bid: uint64 = starting_price } - abimethod opt_in(): None + abimethod opt_in(): void { } - abimethod bid(pay: algopy.gtxn.PaymentTransaction): None + abimethod bid(pay: group_transaction_pay): void { assert(global() < this.auction_end, comment="auction has ended") assert(gtxns(pay) == txn(), comment="payment sender must match transaction sender") assert(gtxns(pay) > this.previous_bid, comment="Bid must be higher than previous bid") - this.previous_bid: algopy.UInt64 = gtxns(pay) - this.previous_bidder: algopy.Account = gtxns(pay) - this.claimable_amount[txn()]: algopy.UInt64 = gtxns(pay) + this.previous_bid: uint64 = gtxns(pay) + this.previous_bidder: account = gtxns(pay) + this.claimable_amount[txn()]: uint64 = gtxns(pay) } - abimethod claim_bids(): None + abimethod claim_bids(): void { - original_amount: algopy.UInt64 = SINGLE_EVAL(id=0, source=this.claimable_amount[txn()]) - amount: algopy.UInt64 = SINGLE_EVAL(id=0, source=this.claimable_amount[txn()]) + original_amount: uint64 = SINGLE_EVAL(id=0, source=this.claimable_amount[txn()]) + amount: uint64 = SINGLE_EVAL(id=0, source=this.claimable_amount[txn()]) if (txn() == this.previous_bidder) { amount -= this.previous_bid } submit_txn(create_inner_transaction(Fee=0u, TypeEnum=pay, Amount=amount, Receiver=txn())) - this.claimable_amount[txn()]: algopy.UInt64 = original_amount - amount + this.claimable_amount[txn()]: uint64 = original_amount - amount } - abimethod claim_asset(asset: algopy.Asset): None + abimethod claim_asset(asset: asset): void { assert(global() > this.auction_end, comment="auction has not ended") submit_txn(create_inner_transaction(Fee=0u, TypeEnum=axfer, XferAsset=asset, AssetCloseTo=this.previous_bidder, AssetReceiver=this.previous_bidder, AssetAmount=this.asa_amount)) } - subroutine delete_application(): None + subroutine delete_application(): void { submit_txn(create_inner_transaction(Fee=0u, TypeEnum=pay, Receiver=global(), CloseRemainderTo=global())) } diff --git a/examples/box_storage/contract.py b/examples/box_storage/contract.py index e0994e5d5..a0c76729d 100644 --- a/examples/box_storage/contract.py +++ b/examples/box_storage/contract.py @@ -7,10 +7,10 @@ class BoxContract(arc4.ARC4Contract): def __init__(self) -> None: - self.box_a = Box(UInt64, key=b"BOX_A") - self.box_b = Box(Bytes, key=b"b") + self.box_a = Box(UInt64) + self.box_b = Box(Bytes, key="b") self.box_c = Box(arc4.String, key=b"BOX_C") - self.box_map = BoxMap(UInt64, String) + self.box_map = BoxMap(UInt64, String, key_prefix="") @arc4.abimethod def set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None: @@ -49,7 +49,7 @@ def arc4_box(self) -> None: @arc4.abimethod def box_blob(self) -> None: - box_blob = BoxRef(key=b"blob") + box_blob = BoxRef(key="blob") sender_bytes = Txn.sender.bytes app_address = Global.current_application_address.bytes assert box_blob.create(size=8000) diff --git a/examples/box_storage/out/BoxContract.approval.mir b/examples/box_storage/out/BoxContract.approval.mir index 47bd1a185..98daa0c3c 100644 --- a/examples/box_storage/out/BoxContract.approval.mir +++ b/examples/box_storage/out/BoxContract.approval.mir @@ -381,22 +381,22 @@ set_boxes_block@0: frame_dig -3 // load a#0 from parameters (𝕡) a#0,b#0,c#0 | a#0 self.box_a.value = a box_storage/contract.py:17 itob // (𝕡) a#0,b#0,c#0 | {itob} self.box_a.value = a box_storage/contract.py:17 // virtual: store new_box_value%0#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%0#0 self.box_a.value = a box_storage/contract.py:17 - byte "BOX_A" // (𝕡) a#0,b#0,c#0 | new_box_value%0#0,"BOX_A" b"BOX_A" box_storage/contract.py:10 - swap // load new_box_value%0#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | "BOX_A",new_box_value%0#0 self.box_a.value = a box_storage/contract.py:17 + byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%0#0,"box_a" self.box_a box_storage/contract.py:10 + swap // load new_box_value%0#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | "box_a",new_box_value%0#0 self.box_a.value = a box_storage/contract.py:17 box_put // (𝕡) a#0,b#0,c#0 | self.box_a.value = a box_storage/contract.py:17 - byte "b" // (𝕡) a#0,b#0,c#0 | "b" b"b" box_storage/contract.py:11 + byte "b" // (𝕡) a#0,b#0,c#0 | "b" "b" box_storage/contract.py:11 box_del // (𝕡) a#0,b#0,c#0 | {box_del} self.box_b.value = b box_storage/contract.py:18 pop // (𝕡) a#0,b#0,c#0 | self.box_b.value = b box_storage/contract.py:18 - byte "b" // (𝕡) a#0,b#0,c#0 | "b" b"b" box_storage/contract.py:11 + byte "b" // (𝕡) a#0,b#0,c#0 | "b" "b" box_storage/contract.py:11 frame_dig -2 // load b#0 from parameters (𝕡) a#0,b#0,c#0 | "b",b#0 self.box_b.value = b box_storage/contract.py:18 box_put // (𝕡) a#0,b#0,c#0 | self.box_b.value = b box_storage/contract.py:18 - byte "BOX_C" // (𝕡) a#0,b#0,c#0 | "BOX_C" b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | 0x424f585f43 b"BOX_C" box_storage/contract.py:12 box_del // (𝕡) a#0,b#0,c#0 | {box_del} self.box_c.value = c box_storage/contract.py:19 pop // (𝕡) a#0,b#0,c#0 | self.box_c.value = c box_storage/contract.py:19 - byte "BOX_C" // (𝕡) a#0,b#0,c#0 | "BOX_C" b"BOX_C" box_storage/contract.py:12 - frame_dig -1 // load c#0 from parameters (𝕡) a#0,b#0,c#0 | "BOX_C",c#0 self.box_c.value = c box_storage/contract.py:19 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + frame_dig -1 // load c#0 from parameters (𝕡) a#0,b#0,c#0 | 0x424f585f43,c#0 self.box_c.value = c box_storage/contract.py:19 box_put // (𝕡) a#0,b#0,c#0 | self.box_c.value = c box_storage/contract.py:19 - byte "BOX_A" // (𝕡) a#0,b#0,c#0 | "BOX_A" b"BOX_A" box_storage/contract.py:10 + byte "box_a" // (𝕡) a#0,b#0,c#0 | "box_a" self.box_a box_storage/contract.py:10 box_get // (𝕡) a#0,b#0,c#0 | {box_get}.0,{box_get}.1 self.box_a.value box_storage/contract.py:21 swap // store box_exists%0#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | box_exists%0#0,{box_get}.0 self.box_a.value box_storage/contract.py:21 // virtual: store box_value%0#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | box_exists%0#0,box_value%0#0 self.box_a.value box_storage/contract.py:21 @@ -412,8 +412,8 @@ set_boxes_block@0: // virtual: load new_box_value%1#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0 self.box_a.value += 3 box_storage/contract.py:21 itob // (𝕡) a#0,b#0,c#0 | {itob} self.box_a.value += 3 box_storage/contract.py:21 // virtual: store new_box_value%2#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%2#0 self.box_a.value += 3 box_storage/contract.py:21 - byte "BOX_A" // (𝕡) a#0,b#0,c#0 | new_box_value%2#0,"BOX_A" b"BOX_A" box_storage/contract.py:10 - swap // load new_box_value%2#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | "BOX_A",new_box_value%2#0 self.box_a.value += 3 box_storage/contract.py:21 + byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%2#0,"box_a" self.box_a box_storage/contract.py:10 + swap // load new_box_value%2#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | "box_a",new_box_value%2#0 self.box_a.value += 3 box_storage/contract.py:21 box_put // (𝕡) a#0,b#0,c#0 | self.box_a.value += 3 box_storage/contract.py:21 retsub // @@ -423,7 +423,7 @@ read_boxes: proto 0 3 // @arc4.abimethod\ndef read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: box_storage/contract.py:23-24 read_boxes_block@0: - byte "BOX_A" // "BOX_A" b"BOX_A" box_storage/contract.py:10 + byte "box_a" // "box_a" self.box_a box_storage/contract.py:10 box_get // {box_get}.0,{box_get}.1 self.box_a.value box_storage/contract.py:25 swap // store box_exists%0#0 to l-stack (no copy) box_exists%0#0,{box_get}.0 self.box_a.value box_storage/contract.py:25 // virtual: store box_value%0#0 to l-stack (no copy) box_exists%0#0,box_value%0#0 self.box_a.value box_storage/contract.py:25 @@ -432,13 +432,13 @@ read_boxes_block@0: swap // store box_value_uint64%0#0 to l-stack (no copy) box_value_uint64%0#0,box_exists%0#0 self.box_a.value box_storage/contract.py:25 // virtual: load box_exists%0#0 from l-stack (no copy) box_value_uint64%0#0,box_exists%0#0 self.box_a.value box_storage/contract.py:25 assert // Box must exist // box_value_uint64%0#0 self.box_a.value box_storage/contract.py:25 - byte "b" // box_value_uint64%0#0,"b" b"b" box_storage/contract.py:11 + byte "b" // box_value_uint64%0#0,"b" "b" box_storage/contract.py:11 box_get // box_value_uint64%0#0,{box_get}.0,{box_get}.1 self.box_b.value box_storage/contract.py:25 // virtual: store box_exists%1#0 to l-stack (no copy) box_value_uint64%0#0,box_exists%1#0,{box_get}.0 self.box_b.value box_storage/contract.py:25 // virtual: store box_value%1#0 to l-stack (no copy) box_value_uint64%0#0,box_value%1#0,box_exists%1#0 self.box_b.value box_storage/contract.py:25 // virtual: load box_exists%1#0 from l-stack (no copy) box_value_uint64%0#0,box_value%1#0,box_exists%1#0 self.box_b.value box_storage/contract.py:25 assert // Box must exist // box_value_uint64%0#0,box_value%1#0 self.box_b.value box_storage/contract.py:25 - byte "BOX_C" // box_value_uint64%0#0,box_value%1#0,"BOX_C" b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // box_value_uint64%0#0,box_value%1#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 box_get // box_value_uint64%0#0,box_value%1#0,{box_get}.0,{box_get}.1 self.box_c.value box_storage/contract.py:25 // virtual: store box_exists%2#0 to l-stack (no copy) box_value_uint64%0#0,box_value%1#0,box_exists%2#0,{box_get}.0 self.box_c.value box_storage/contract.py:25 // virtual: store box_value%2#0 to l-stack (no copy) box_value_uint64%0#0,box_value%1#0,box_value%2#0,box_exists%2#0 self.box_c.value box_storage/contract.py:25 @@ -455,15 +455,15 @@ boxes_exist: proto 0 3 // @arc4.abimethod\ndef boxes_exist(self) -> tuple[bool, bool, bool]: box_storage/contract.py:27-28 boxes_exist_block@0: - byte "BOX_A" // "BOX_A" b"BOX_A" box_storage/contract.py:10 + byte "box_a" // "box_a" self.box_a box_storage/contract.py:10 box_len // {box_len}.0,{box_len}.1 bool(self.box_a) box_storage/contract.py:29 swap // store box_exists%0#0 to l-stack (no copy) box_exists%0#0,{box_len}.0 bool(self.box_a) box_storage/contract.py:29 pop // box_exists%0#0 bool(self.box_a) box_storage/contract.py:29 - byte "b" // box_exists%0#0,"b" b"b" box_storage/contract.py:11 + byte "b" // box_exists%0#0,"b" "b" box_storage/contract.py:11 box_len // box_exists%0#0,{box_len}.0,{box_len}.1 bool(self.box_b) box_storage/contract.py:29 swap // store box_exists%1#0 to l-stack (no copy) box_exists%0#0,box_exists%1#0,{box_len}.0 bool(self.box_b) box_storage/contract.py:29 pop // box_exists%0#0,box_exists%1#0 bool(self.box_b) box_storage/contract.py:29 - byte "BOX_C" // box_exists%0#0,box_exists%1#0,"BOX_C" b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // box_exists%0#0,box_exists%1#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 box_len // box_exists%0#0,box_exists%1#0,{box_len}.0,{box_len}.1 bool(self.box_c) box_storage/contract.py:29 swap // store box_exists%2#0 to l-stack (no copy) box_exists%0#0,box_exists%1#0,box_exists%2#0,{box_len}.0 bool(self.box_c) box_storage/contract.py:29 pop // box_exists%0#0,box_exists%1#0,box_exists%2#0 bool(self.box_c) box_storage/contract.py:29 @@ -478,91 +478,87 @@ slice_box: proto 0 0 // @arc4.abimethod\ndef slice_box(self) -> None: box_storage/contract.py:31-32 slice_box_block@0: - byte "0" // "0" b"0" box_storage/contract.py:33 + byte 0x30 // 0x30 b"0" box_storage/contract.py:33 box_del // {box_del} box_0.value = Bytes(b"Testing testing 123") box_storage/contract.py:34 pop // box_0.value = Bytes(b"Testing testing 123") box_storage/contract.py:34 - byte "0" // "0" b"0" box_storage/contract.py:33 - byte "Testing testing 123" // "0","Testing testing 123" b"Testing testing 123" box_storage/contract.py:34 + byte 0x30 // 0x30 b"0" box_storage/contract.py:33 + byte "Testing testing 123" // 0x30,"Testing testing 123" b"Testing testing 123" box_storage/contract.py:34 box_put // box_0.value = Bytes(b"Testing testing 123") box_storage/contract.py:34 - byte "0" // "0" b"0" box_storage/contract.py:33 + byte 0x30 // 0x30 b"0" box_storage/contract.py:33 box_len // {box_len}.0,{box_len}.1 box_0.value[0:7] box_storage/contract.py:35 - // virtual: store box_exists%0#0 to l-stack (no copy) box_exists%0#0,{box_len}.0 box_0.value[0:7] box_storage/contract.py:35 - // virtual: store box_len%0#0 to l-stack (no copy) box_len%0#0,box_exists%0#0 box_0.value[0:7] box_storage/contract.py:35 - // virtual: load box_exists%0#0 from l-stack (no copy) box_len%0#0,box_exists%0#0 box_0.value[0:7] box_storage/contract.py:35 - assert // Box must exist // box_len%0#0 box_0.value[0:7] box_storage/contract.py:35 - dup // load box_len%0#0 from l-stack (copy) box_len%0#0,box_len%0#0 box_0.value[0:7] box_storage/contract.py:35 - int 0 // box_len%0#0,box_len%0#0,0 0 box_storage/contract.py:35 - dig 2 // load box_len%0#0 from l-stack (copy) box_len%0#0,box_len%0#0,0,box_len%0#0 box_0.value[0:7] box_storage/contract.py:35 - select // box_len%0#0,{select} box_0.value[0:7] box_storage/contract.py:35 - swap // store tmp%1#0 to l-stack (no copy) tmp%1#0,box_len%0#0 box_0.value[0:7] box_storage/contract.py:35 - int 7 // tmp%1#0,box_len%0#0,7 7 box_storage/contract.py:35 - dig 1 // load box_len%0#0 from l-stack (copy) tmp%1#0,box_len%0#0,7,box_len%0#0 box_0.value[0:7] box_storage/contract.py:35 - < // tmp%1#0,box_len%0#0,{<} box_0.value[0:7] box_storage/contract.py:35 - swap // store tmp%2#0 to l-stack (no copy) tmp%1#0,tmp%2#0,box_len%0#0 box_0.value[0:7] box_storage/contract.py:35 - // virtual: load box_len%0#0 from l-stack (no copy) tmp%1#0,tmp%2#0,box_len%0#0 box_0.value[0:7] box_storage/contract.py:35 - int 7 // tmp%1#0,tmp%2#0,box_len%0#0,7 7 box_storage/contract.py:35 - uncover 2 // load tmp%2#0 from l-stack (no copy) tmp%1#0,box_len%0#0,7,tmp%2#0 box_0.value[0:7] box_storage/contract.py:35 - select // tmp%1#0,{select} box_0.value[0:7] box_storage/contract.py:35 - // virtual: store tmp%3#0 to l-stack (no copy) tmp%1#0,tmp%3#0 box_0.value[0:7] box_storage/contract.py:35 - // virtual: load tmp%3#0 from l-stack (no copy) tmp%1#0,tmp%3#0 box_0.value[0:7] box_storage/contract.py:35 - dig 1 // load tmp%1#0 from l-stack (copy) tmp%1#0,tmp%3#0,tmp%1#0 box_0.value[0:7] box_storage/contract.py:35 - - // tmp%1#0,{-} box_0.value[0:7] box_storage/contract.py:35 - // virtual: store tmp%6#0 to l-stack (no copy) tmp%1#0,tmp%6#0 box_0.value[0:7] box_storage/contract.py:35 - byte "0" // tmp%1#0,tmp%6#0,"0" b"0" box_storage/contract.py:33 - uncover 2 // load tmp%1#0 from l-stack (no copy) tmp%6#0,"0",tmp%1#0 box_0.value[0:7] box_storage/contract.py:35 - uncover 2 // load tmp%6#0 from l-stack (no copy) "0",tmp%1#0,tmp%6#0 box_0.value[0:7] box_storage/contract.py:35 + pop // {box_len}.0 box_0.value[0:7] box_storage/contract.py:35 + // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 box_0.value[0:7] box_storage/contract.py:35 + dup // load tmp%0#0 from l-stack (copy) tmp%0#0,tmp%0#0 box_0.value[0:7] box_storage/contract.py:35 + int 0 // tmp%0#0,tmp%0#0,0 0 box_storage/contract.py:35 + dig 2 // load tmp%0#0 from l-stack (copy) tmp%0#0,tmp%0#0,0,tmp%0#0 box_0.value[0:7] box_storage/contract.py:35 + select // tmp%0#0,{select} box_0.value[0:7] box_storage/contract.py:35 + swap // store tmp%3#0 to l-stack (no copy) tmp%3#0,tmp%0#0 box_0.value[0:7] box_storage/contract.py:35 + int 7 // tmp%3#0,tmp%0#0,7 7 box_storage/contract.py:35 + dig 1 // load tmp%0#0 from l-stack (copy) tmp%3#0,tmp%0#0,7,tmp%0#0 box_0.value[0:7] box_storage/contract.py:35 + < // tmp%3#0,tmp%0#0,{<} box_0.value[0:7] box_storage/contract.py:35 + swap // store tmp%4#0 to l-stack (no copy) tmp%3#0,tmp%4#0,tmp%0#0 box_0.value[0:7] box_storage/contract.py:35 + // virtual: load tmp%0#0 from l-stack (no copy) tmp%3#0,tmp%4#0,tmp%0#0 box_0.value[0:7] box_storage/contract.py:35 + int 7 // tmp%3#0,tmp%4#0,tmp%0#0,7 7 box_storage/contract.py:35 + uncover 2 // load tmp%4#0 from l-stack (no copy) tmp%3#0,tmp%0#0,7,tmp%4#0 box_0.value[0:7] box_storage/contract.py:35 + select // tmp%3#0,{select} box_0.value[0:7] box_storage/contract.py:35 + // virtual: store tmp%5#0 to l-stack (no copy) tmp%3#0,tmp%5#0 box_0.value[0:7] box_storage/contract.py:35 + // virtual: load tmp%5#0 from l-stack (no copy) tmp%3#0,tmp%5#0 box_0.value[0:7] box_storage/contract.py:35 + dig 1 // load tmp%3#0 from l-stack (copy) tmp%3#0,tmp%5#0,tmp%3#0 box_0.value[0:7] box_storage/contract.py:35 + - // tmp%3#0,{-} box_0.value[0:7] box_storage/contract.py:35 + // virtual: store tmp%8#0 to l-stack (no copy) tmp%3#0,tmp%8#0 box_0.value[0:7] box_storage/contract.py:35 + byte 0x30 // tmp%3#0,tmp%8#0,0x30 b"0" box_storage/contract.py:33 + uncover 2 // load tmp%3#0 from l-stack (no copy) tmp%8#0,0x30,tmp%3#0 box_0.value[0:7] box_storage/contract.py:35 + uncover 2 // load tmp%8#0 from l-stack (no copy) 0x30,tmp%3#0,tmp%8#0 box_0.value[0:7] box_storage/contract.py:35 box_extract // {box_extract} box_0.value[0:7] box_storage/contract.py:35 - // virtual: store tmp%7#0 to l-stack (no copy) tmp%7#0 box_0.value[0:7] box_storage/contract.py:35 - // virtual: load tmp%7#0 from l-stack (no copy) tmp%7#0 box_0.value[0:7] == b"Testing" box_storage/contract.py:35 - byte "Testing" // tmp%7#0,"Testing" b"Testing" box_storage/contract.py:35 + // virtual: store tmp%9#0 to l-stack (no copy) tmp%9#0 box_0.value[0:7] box_storage/contract.py:35 + // virtual: load tmp%9#0 from l-stack (no copy) tmp%9#0 box_0.value[0:7] == b"Testing" box_storage/contract.py:35 + byte "Testing" // tmp%9#0,"Testing" b"Testing" box_storage/contract.py:35 == // {==} box_0.value[0:7] == b"Testing" box_storage/contract.py:35 - // virtual: store tmp%8#0 to l-stack (no copy) tmp%8#0 box_0.value[0:7] == b"Testing" box_storage/contract.py:35 - // virtual: load tmp%8#0 from l-stack (no copy) tmp%8#0 assert box_0.value[0:7] == b"Testing" box_storage/contract.py:35 + // virtual: store tmp%10#0 to l-stack (no copy) tmp%10#0 box_0.value[0:7] == b"Testing" box_storage/contract.py:35 + // virtual: load tmp%10#0 from l-stack (no copy) tmp%10#0 assert box_0.value[0:7] == b"Testing" box_storage/contract.py:35 assert // assert box_0.value[0:7] == b"Testing" box_storage/contract.py:35 - byte "BOX_C" // "BOX_C" b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // 0x424f585f43 b"BOX_C" box_storage/contract.py:12 box_del // {box_del} self.box_c.value = arc4.String("Hello") box_storage/contract.py:37 pop // self.box_c.value = arc4.String("Hello") box_storage/contract.py:37 - byte "BOX_C" // "BOX_C" b"BOX_C" box_storage/contract.py:12 - byte "\x00\x05Hello" // "BOX_C","\x00\x05Hello" arc4.String("Hello") box_storage/contract.py:37 + byte 0x424f585f43 // 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte "\x00\x05Hello" // 0x424f585f43,"\x00\x05Hello" arc4.String("Hello") box_storage/contract.py:37 box_put // self.box_c.value = arc4.String("Hello") box_storage/contract.py:37 - byte "BOX_C" // "BOX_C" b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // 0x424f585f43 b"BOX_C" box_storage/contract.py:12 box_len // {box_len}.0,{box_len}.1 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: store box_exists%1#0 to l-stack (no copy) box_exists%1#0,{box_len}.0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: store box_len%1#0 to l-stack (no copy) box_len%1#0,box_exists%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: load box_exists%1#0 from l-stack (no copy) box_len%1#0,box_exists%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - assert // Box must exist // box_len%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - int 2 // box_len%1#0,2 2 box_storage/contract.py:38 - dig 1 // load box_len%1#0 from l-stack (copy) box_len%1#0,2,box_len%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - < // box_len%1#0,{<} self.box_c.value.bytes[2:10] box_storage/contract.py:38 - swap // store tmp%9#0 to l-stack (no copy) tmp%9#0,box_len%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - dup // load box_len%1#0 from l-stack (copy) tmp%9#0,box_len%1#0,box_len%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - int 2 // tmp%9#0,box_len%1#0,box_len%1#0,2 2 box_storage/contract.py:38 - uncover 3 // load tmp%9#0 from l-stack (no copy) box_len%1#0,box_len%1#0,2,tmp%9#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - select // box_len%1#0,{select} self.box_c.value.bytes[2:10] box_storage/contract.py:38 - swap // store tmp%10#0 to l-stack (no copy) tmp%10#0,box_len%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - int 10 // tmp%10#0,box_len%1#0,10 10 box_storage/contract.py:38 - dig 1 // load box_len%1#0 from l-stack (copy) tmp%10#0,box_len%1#0,10,box_len%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - < // tmp%10#0,box_len%1#0,{<} self.box_c.value.bytes[2:10] box_storage/contract.py:38 - swap // store tmp%11#0 to l-stack (no copy) tmp%10#0,tmp%11#0,box_len%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: load box_len%1#0 from l-stack (no copy) tmp%10#0,tmp%11#0,box_len%1#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - int 10 // tmp%10#0,tmp%11#0,box_len%1#0,10 10 box_storage/contract.py:38 - uncover 2 // load tmp%11#0 from l-stack (no copy) tmp%10#0,box_len%1#0,10,tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - select // tmp%10#0,{select} self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: store tmp%12#0 to l-stack (no copy) tmp%10#0,tmp%12#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: load tmp%12#0 from l-stack (no copy) tmp%10#0,tmp%12#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - dig 1 // load tmp%10#0 from l-stack (copy) tmp%10#0,tmp%12#0,tmp%10#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - - // tmp%10#0,{-} self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: store tmp%15#0 to l-stack (no copy) tmp%10#0,tmp%15#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - byte "BOX_C" // tmp%10#0,tmp%15#0,"BOX_C" b"BOX_C" box_storage/contract.py:12 - uncover 2 // load tmp%10#0 from l-stack (no copy) tmp%15#0,"BOX_C",tmp%10#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - uncover 2 // load tmp%15#0 from l-stack (no copy) "BOX_C",tmp%10#0,tmp%15#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + pop // {box_len}.0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + // virtual: store tmp%11#0 to l-stack (no copy) tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + int 2 // tmp%11#0,2 2 box_storage/contract.py:38 + dig 1 // load tmp%11#0 from l-stack (copy) tmp%11#0,2,tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + < // tmp%11#0,{<} self.box_c.value.bytes[2:10] box_storage/contract.py:38 + swap // store tmp%13#0 to l-stack (no copy) tmp%13#0,tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + dup // load tmp%11#0 from l-stack (copy) tmp%13#0,tmp%11#0,tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + int 2 // tmp%13#0,tmp%11#0,tmp%11#0,2 2 box_storage/contract.py:38 + uncover 3 // load tmp%13#0 from l-stack (no copy) tmp%11#0,tmp%11#0,2,tmp%13#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + select // tmp%11#0,{select} self.box_c.value.bytes[2:10] box_storage/contract.py:38 + swap // store tmp%14#0 to l-stack (no copy) tmp%14#0,tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + int 10 // tmp%14#0,tmp%11#0,10 10 box_storage/contract.py:38 + dig 1 // load tmp%11#0 from l-stack (copy) tmp%14#0,tmp%11#0,10,tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + < // tmp%14#0,tmp%11#0,{<} self.box_c.value.bytes[2:10] box_storage/contract.py:38 + swap // store tmp%15#0 to l-stack (no copy) tmp%14#0,tmp%15#0,tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + // virtual: load tmp%11#0 from l-stack (no copy) tmp%14#0,tmp%15#0,tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + int 10 // tmp%14#0,tmp%15#0,tmp%11#0,10 10 box_storage/contract.py:38 + uncover 2 // load tmp%15#0 from l-stack (no copy) tmp%14#0,tmp%11#0,10,tmp%15#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + select // tmp%14#0,{select} self.box_c.value.bytes[2:10] box_storage/contract.py:38 + // virtual: store tmp%16#0 to l-stack (no copy) tmp%14#0,tmp%16#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + // virtual: load tmp%16#0 from l-stack (no copy) tmp%14#0,tmp%16#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + dig 1 // load tmp%14#0 from l-stack (copy) tmp%14#0,tmp%16#0,tmp%14#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + - // tmp%14#0,{-} self.box_c.value.bytes[2:10] box_storage/contract.py:38 + // virtual: store tmp%19#0 to l-stack (no copy) tmp%14#0,tmp%19#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + byte 0x424f585f43 // tmp%14#0,tmp%19#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + uncover 2 // load tmp%14#0 from l-stack (no copy) tmp%19#0,0x424f585f43,tmp%14#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + uncover 2 // load tmp%19#0 from l-stack (no copy) 0x424f585f43,tmp%14#0,tmp%19#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 box_extract // {box_extract} self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: store tmp%16#0 to l-stack (no copy) tmp%16#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 - // virtual: load tmp%16#0 from l-stack (no copy) tmp%16#0 self.box_c.value.bytes[2:10] == b"Hello" box_storage/contract.py:38 - byte "Hello" // tmp%16#0,"Hello" b"Hello" box_storage/contract.py:38 + // virtual: store tmp%20#0 to l-stack (no copy) tmp%20#0 self.box_c.value.bytes[2:10] box_storage/contract.py:38 + // virtual: load tmp%20#0 from l-stack (no copy) tmp%20#0 self.box_c.value.bytes[2:10] == b"Hello" box_storage/contract.py:38 + byte "Hello" // tmp%20#0,"Hello" b"Hello" box_storage/contract.py:38 == // {==} self.box_c.value.bytes[2:10] == b"Hello" box_storage/contract.py:38 - // virtual: store tmp%17#0 to l-stack (no copy) tmp%17#0 self.box_c.value.bytes[2:10] == b"Hello" box_storage/contract.py:38 - // virtual: load tmp%17#0 from l-stack (no copy) tmp%17#0 assert self.box_c.value.bytes[2:10] == b"Hello" box_storage/contract.py:38 + // virtual: store tmp%21#0 to l-stack (no copy) tmp%21#0 self.box_c.value.bytes[2:10] == b"Hello" box_storage/contract.py:38 + // virtual: load tmp%21#0 from l-stack (no copy) tmp%21#0 assert self.box_c.value.bytes[2:10] == b"Hello" box_storage/contract.py:38 assert // assert self.box_c.value.bytes[2:10] == b"Hello" box_storage/contract.py:38 retsub // @@ -572,10 +568,10 @@ arc4_box: proto 0 0 // @arc4.abimethod\ndef arc4_box(self) -> None: box_storage/contract.py:40-41 arc4_box_block@0: - byte "d" // "d" b"d" box_storage/contract.py:42 - byte 0x00010203 // "d",0x00010203 StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) box_storage/contract.py:43 + byte 0x64 // 0x64 b"d" box_storage/contract.py:42 + byte 0x00010203 // 0x64,0x00010203 StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) box_storage/contract.py:43 box_put // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) box_storage/contract.py:43 - byte "d" // "d" b"d" box_storage/contract.py:42 + byte 0x64 // 0x64 b"d" box_storage/contract.py:42 box_get // {box_get}.0,{box_get}.1 box_d.value box_storage/contract.py:45 // virtual: store box_exists%0#0 to l-stack (no copy) box_exists%0#0,{box_get}.0 box_d.value box_storage/contract.py:45 // virtual: store box_value%0#0 to l-stack (no copy) box_value%0#0,box_exists%0#0 box_d.value box_storage/contract.py:45 @@ -590,7 +586,7 @@ arc4_box_block@0: // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 box_d.value[0] == 0 box_storage/contract.py:45 // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 assert box_d.value[0] == 0 box_storage/contract.py:45 assert // assert box_d.value[0] == 0 box_storage/contract.py:45 - byte "d" // "d" b"d" box_storage/contract.py:42 + byte 0x64 // 0x64 b"d" box_storage/contract.py:42 box_get // {box_get}.0,{box_get}.1 box_d.value box_storage/contract.py:46 // virtual: store box_exists%1#0 to l-stack (no copy) box_exists%1#0,{box_get}.0 box_d.value box_storage/contract.py:46 // virtual: store box_value%1#0 to l-stack (no copy) box_value%1#0,box_exists%1#0 box_d.value box_storage/contract.py:46 @@ -605,7 +601,7 @@ arc4_box_block@0: // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 box_d.value[1] == 1 box_storage/contract.py:46 // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 assert box_d.value[1] == 1 box_storage/contract.py:46 assert // assert box_d.value[1] == 1 box_storage/contract.py:46 - byte "d" // "d" b"d" box_storage/contract.py:42 + byte 0x64 // 0x64 b"d" box_storage/contract.py:42 box_get // {box_get}.0,{box_get}.1 box_d.value box_storage/contract.py:47 // virtual: store box_exists%2#0 to l-stack (no copy) box_exists%2#0,{box_get}.0 box_d.value box_storage/contract.py:47 // virtual: store box_value%2#0 to l-stack (no copy) box_value%2#0,box_exists%2#0 box_d.value box_storage/contract.py:47 @@ -620,7 +616,7 @@ arc4_box_block@0: // virtual: store tmp%2#0 to l-stack (no copy) tmp%2#0 box_d.value[2] == 2 box_storage/contract.py:47 // virtual: load tmp%2#0 from l-stack (no copy) tmp%2#0 assert box_d.value[2] == 2 box_storage/contract.py:47 assert // assert box_d.value[2] == 2 box_storage/contract.py:47 - byte "d" // "d" b"d" box_storage/contract.py:42 + byte 0x64 // 0x64 b"d" box_storage/contract.py:42 box_get // {box_get}.0,{box_get}.1 box_d.value box_storage/contract.py:48 // virtual: store box_exists%3#0 to l-stack (no copy) box_exists%3#0,{box_get}.0 box_d.value box_storage/contract.py:48 // virtual: store box_value%3#0 to l-stack (no copy) box_value%3#0,box_exists%3#0 box_d.value box_storage/contract.py:48 @@ -647,22 +643,22 @@ box_blob_block@0: // virtual: store sender_bytes#0 to l-stack (no copy) sender_bytes#0 sender_bytes = Txn.sender.bytes box_storage/contract.py:53 global CurrentApplicationAddress // sender_bytes#0,{global} Global.current_application_address box_storage/contract.py:54 swap // store app_address#0 to l-stack (no copy) app_address#0,sender_bytes#0 app_address = Global.current_application_address.bytes box_storage/contract.py:54 - byte "blob" // app_address#0,sender_bytes#0,"blob" b"blob" box_storage/contract.py:52 + byte "blob" // app_address#0,sender_bytes#0,"blob" "blob" box_storage/contract.py:52 int 8000 // app_address#0,sender_bytes#0,"blob",8000 8000 box_storage/contract.py:55 box_create // app_address#0,sender_bytes#0,{box_create} box_blob.create(size=8000) box_storage/contract.py:55 // virtual: store tmp%0#0 to l-stack (no copy) app_address#0,sender_bytes#0,tmp%0#0 box_blob.create(size=8000) box_storage/contract.py:55 // virtual: load tmp%0#0 from l-stack (no copy) app_address#0,sender_bytes#0,tmp%0#0 assert box_blob.create(size=8000) box_storage/contract.py:55 assert // app_address#0,sender_bytes#0 assert box_blob.create(size=8000) box_storage/contract.py:55 - byte "blob" // app_address#0,sender_bytes#0,"blob" b"blob" box_storage/contract.py:52 + byte "blob" // app_address#0,sender_bytes#0,"blob" "blob" box_storage/contract.py:52 int 0 // app_address#0,sender_bytes#0,"blob",0 0 box_storage/contract.py:56 dig 2 // load sender_bytes#0 from l-stack (copy) app_address#0,sender_bytes#0,"blob",0,sender_bytes#0 box_blob.replace(0, sender_bytes) box_storage/contract.py:56 box_replace // app_address#0,sender_bytes#0 box_blob.replace(0, sender_bytes) box_storage/contract.py:56 - byte "blob" // app_address#0,sender_bytes#0,"blob" b"blob" box_storage/contract.py:52 + byte "blob" // app_address#0,sender_bytes#0,"blob" "blob" box_storage/contract.py:52 int 0 // app_address#0,sender_bytes#0,"blob",0 0 box_storage/contract.py:57 int 0 // app_address#0,sender_bytes#0,"blob",0,0 0 box_storage/contract.py:57 dig 4 // load app_address#0 from l-stack (copy) app_address#0,sender_bytes#0,"blob",0,0,app_address#0 box_blob.splice(0, 0, app_address) box_storage/contract.py:57 box_splice // app_address#0,sender_bytes#0 box_blob.splice(0, 0, app_address) box_storage/contract.py:57 - byte "blob" // app_address#0,sender_bytes#0,"blob" b"blob" box_storage/contract.py:52 + byte "blob" // app_address#0,sender_bytes#0,"blob" "blob" box_storage/contract.py:52 int 0 // app_address#0,sender_bytes#0,"blob",0 0 box_storage/contract.py:58 int 64 // app_address#0,sender_bytes#0,"blob",0,64 32 * 2 box_storage/contract.py:58 box_extract // app_address#0,sender_bytes#0,{box_extract} box_blob.extract(0, 32 * 2) box_storage/contract.py:58 @@ -677,12 +673,12 @@ box_blob_block@0: // virtual: store tmp%2#0 to l-stack (no copy) app_address#0,sender_bytes#0,tmp%2#0 first_64 == app_address + sender_bytes box_storage/contract.py:59 // virtual: load tmp%2#0 from l-stack (no copy) app_address#0,sender_bytes#0,tmp%2#0 assert first_64 == app_address + sender_bytes box_storage/contract.py:59 assert // app_address#0,sender_bytes#0 assert first_64 == app_address + sender_bytes box_storage/contract.py:59 - byte "blob" // app_address#0,sender_bytes#0,"blob" b"blob" box_storage/contract.py:52 + byte "blob" // app_address#0,sender_bytes#0,"blob" "blob" box_storage/contract.py:52 box_del // app_address#0,sender_bytes#0,{box_del} box_blob.delete() box_storage/contract.py:60 // virtual: store tmp%3#0 to l-stack (no copy) app_address#0,sender_bytes#0,tmp%3#0 box_blob.delete() box_storage/contract.py:60 // virtual: load tmp%3#0 from l-stack (no copy) app_address#0,sender_bytes#0,tmp%3#0 assert box_blob.delete() box_storage/contract.py:60 assert // app_address#0,sender_bytes#0 assert box_blob.delete() box_storage/contract.py:60 - byte "blob" // app_address#0,sender_bytes#0,"blob" b"blob" box_storage/contract.py:52 + byte "blob" // app_address#0,sender_bytes#0,"blob" "blob" box_storage/contract.py:52 box_get // app_address#0,sender_bytes#0,{box_get}.0,{box_get}.1 box_blob.maybe() box_storage/contract.py:62 swap // store exists#0 to l-stack (no copy) app_address#0,sender_bytes#0,exists#0,{box_get}.0 box_blob.maybe() box_storage/contract.py:62 pop // app_address#0,sender_bytes#0,exists#0 box_blob.maybe() box_storage/contract.py:62 @@ -691,13 +687,13 @@ box_blob_block@0: // virtual: store tmp%4#0 to l-stack (no copy) app_address#0,sender_bytes#0,tmp%4#0 not exists box_storage/contract.py:63 // virtual: load tmp%4#0 from l-stack (no copy) app_address#0,sender_bytes#0,tmp%4#0 assert not exists box_storage/contract.py:63 assert // app_address#0,sender_bytes#0 assert not exists box_storage/contract.py:63 - byte "blob" // app_address#0,sender_bytes#0,"blob" b"blob" box_storage/contract.py:52 + byte "blob" // app_address#0,sender_bytes#0,"blob" "blob" box_storage/contract.py:52 box_get // app_address#0,sender_bytes#0,{box_get}.0,{box_get}.1 box_blob.get(default=sender_bytes) box_storage/contract.py:64 - swap // store box_exists%1#0 to l-stack (no copy) app_address#0,sender_bytes#0,box_exists%1#0,{box_get}.0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 - // virtual: store box_value%1#0 to l-stack (no copy) app_address#0,sender_bytes#0,box_exists%1#0,box_value%1#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 - dig 2 // load sender_bytes#0 from l-stack (copy) app_address#0,sender_bytes#0,box_exists%1#0,box_value%1#0,sender_bytes#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 - swap // load box_value%1#0 from l-stack (no copy) app_address#0,sender_bytes#0,box_exists%1#0,sender_bytes#0,box_value%1#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 - uncover 2 // load box_exists%1#0 from l-stack (no copy) app_address#0,sender_bytes#0,sender_bytes#0,box_value%1#0,box_exists%1#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 + swap // store None_get_ex%1#0 to l-stack (no copy) app_address#0,sender_bytes#0,None_get_ex%1#0,{box_get}.0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 + // virtual: store None_get_ex%0#0 to l-stack (no copy) app_address#0,sender_bytes#0,None_get_ex%1#0,None_get_ex%0#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 + dig 2 // load sender_bytes#0 from l-stack (copy) app_address#0,sender_bytes#0,None_get_ex%1#0,None_get_ex%0#0,sender_bytes#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 + swap // load None_get_ex%0#0 from l-stack (no copy) app_address#0,sender_bytes#0,None_get_ex%1#0,sender_bytes#0,None_get_ex%0#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 + uncover 2 // load None_get_ex%1#0 from l-stack (no copy) app_address#0,sender_bytes#0,sender_bytes#0,None_get_ex%0#0,None_get_ex%1#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 select // app_address#0,sender_bytes#0,{select} box_blob.get(default=sender_bytes) box_storage/contract.py:64 // virtual: store tmp%5#0 to l-stack (no copy) app_address#0,sender_bytes#0,tmp%5#0 box_blob.get(default=sender_bytes) box_storage/contract.py:64 // virtual: load tmp%5#0 from l-stack (no copy) app_address#0,sender_bytes#0,tmp%5#0 box_blob.get(default=sender_bytes) == sender_bytes box_storage/contract.py:64 @@ -710,23 +706,23 @@ box_blob_block@0: swap // load app_address#0 from l-stack (no copy) sender_bytes#0,app_address#0 sender_bytes + app_address box_storage/contract.py:65 concat // {concat} sender_bytes + app_address box_storage/contract.py:65 // virtual: store tmp%7#0 to l-stack (no copy) tmp%7#0 sender_bytes + app_address box_storage/contract.py:65 - byte "blob" // tmp%7#0,"blob" b"blob" box_storage/contract.py:52 + byte "blob" // tmp%7#0,"blob" "blob" box_storage/contract.py:52 swap // load tmp%7#0 from l-stack (no copy) "blob",tmp%7#0 box_blob.put(sender_bytes + app_address) box_storage/contract.py:65 box_put // box_blob.put(sender_bytes + app_address) box_storage/contract.py:65 - byte "blob" // "blob" b"blob" box_storage/contract.py:52 + byte "blob" // "blob" "blob" box_storage/contract.py:52 box_len // {box_len}.0,{box_len}.1 box_blob box_storage/contract.py:66 - swap // store box_exists%2#0 to l-stack (no copy) box_exists%2#0,{box_len}.0 box_blob box_storage/contract.py:66 - pop // box_exists%2#0 box_blob box_storage/contract.py:66 - // virtual: load box_exists%2#0 from l-stack (no copy) box_exists%2#0 assert box_blob, "Blob exists" box_storage/contract.py:66 + swap // store box_exists%0#0 to l-stack (no copy) box_exists%0#0,{box_len}.0 box_blob box_storage/contract.py:66 + pop // box_exists%0#0 box_blob box_storage/contract.py:66 + // virtual: load box_exists%0#0 from l-stack (no copy) box_exists%0#0 assert box_blob, "Blob exists" box_storage/contract.py:66 assert // Blob exists // assert box_blob, "Blob exists" box_storage/contract.py:66 - byte "blob" // "blob" b"blob" box_storage/contract.py:52 + byte "blob" // "blob" "blob" box_storage/contract.py:52 box_len // {box_len}.0,{box_len}.1 box_blob.length box_storage/contract.py:67 - // virtual: store box_exists%3#0 to l-stack (no copy) box_exists%3#0,{box_len}.0 box_blob.length box_storage/contract.py:67 - // virtual: store box_len%1#0 to l-stack (no copy) box_len%1#0,box_exists%3#0 box_blob.length box_storage/contract.py:67 - // virtual: load box_exists%3#0 from l-stack (no copy) box_len%1#0,box_exists%3#0 box_blob.length box_storage/contract.py:67 - assert // Box must exist // box_len%1#0 box_blob.length box_storage/contract.py:67 - // virtual: load box_len%1#0 from l-stack (no copy) box_len%1#0 box_blob.length == 64 box_storage/contract.py:67 - int 64 // box_len%1#0,64 64 box_storage/contract.py:67 + // virtual: store check%0#0 to l-stack (no copy) check%0#0,{box_len}.0 box_blob.length box_storage/contract.py:67 + // virtual: store value%0#0 to l-stack (no copy) value%0#0,check%0#0 box_blob.length box_storage/contract.py:67 + // virtual: load check%0#0 from l-stack (no copy) value%0#0,check%0#0 box_blob.length box_storage/contract.py:67 + assert // box exists // value%0#0 box_blob.length box_storage/contract.py:67 + // virtual: load value%0#0 from l-stack (no copy) value%0#0 box_blob.length == 64 box_storage/contract.py:67 + int 64 // value%0#0,64 64 box_storage/contract.py:67 == // {==} box_blob.length == 64 box_storage/contract.py:67 // virtual: store tmp%8#0 to l-stack (no copy) tmp%8#0 box_blob.length == 64 box_storage/contract.py:67 // virtual: load tmp%8#0 from l-stack (no copy) tmp%8#0 assert box_blob.length == 64 box_storage/contract.py:67 @@ -750,60 +746,60 @@ box_map_test_block@0: box_put // tmp%0#0 self.box_map[key_0] = value box_storage/contract.py:74 dup // load tmp%0#0 from l-stack (copy) tmp%0#0,tmp%0#0 self.box_map[key_0].bytes.length box_storage/contract.py:75 box_len // tmp%0#0,{box_len}.0,{box_len}.1 self.box_map[key_0].bytes.length box_storage/contract.py:75 - // virtual: store box_exists%0#0 to l-stack (no copy) tmp%0#0,box_exists%0#0,{box_len}.0 self.box_map[key_0].bytes.length box_storage/contract.py:75 - // virtual: store box_len%0#0 to l-stack (no copy) tmp%0#0,box_len%0#0,box_exists%0#0 self.box_map[key_0].bytes.length box_storage/contract.py:75 - // virtual: load box_exists%0#0 from l-stack (no copy) tmp%0#0,box_len%0#0,box_exists%0#0 self.box_map[key_0].bytes.length box_storage/contract.py:75 - assert // Box must exist // tmp%0#0,box_len%0#0 self.box_map[key_0].bytes.length box_storage/contract.py:75 - // virtual: load box_len%0#0 from l-stack (no copy) tmp%0#0,box_len%0#0 self.box_map[key_0].bytes.length == value.bytes.length box_storage/contract.py:75 - int 6 // tmp%0#0,box_len%0#0,6 value.bytes.length box_storage/contract.py:75 + // virtual: store check%0#0 to l-stack (no copy) tmp%0#0,check%0#0,{box_len}.0 self.box_map[key_0].bytes.length box_storage/contract.py:75 + // virtual: store value%0#0 to l-stack (no copy) tmp%0#0,value%0#0,check%0#0 self.box_map[key_0].bytes.length box_storage/contract.py:75 + // virtual: load check%0#0 from l-stack (no copy) tmp%0#0,value%0#0,check%0#0 self.box_map[key_0].bytes.length box_storage/contract.py:75 + assert // box exists // tmp%0#0,value%0#0 self.box_map[key_0].bytes.length box_storage/contract.py:75 + // virtual: load value%0#0 from l-stack (no copy) tmp%0#0,value%0#0 self.box_map[key_0].bytes.length == value.bytes.length box_storage/contract.py:75 + int 6 // tmp%0#0,value%0#0,6 value.bytes.length box_storage/contract.py:75 == // tmp%0#0,{==} self.box_map[key_0].bytes.length == value.bytes.length box_storage/contract.py:75 - // virtual: store tmp%3#0 to l-stack (no copy) tmp%0#0,tmp%3#0 self.box_map[key_0].bytes.length == value.bytes.length box_storage/contract.py:75 - // virtual: load tmp%3#0 from l-stack (no copy) tmp%0#0,tmp%3#0 assert self.box_map[key_0].bytes.length == value.bytes.length box_storage/contract.py:75 + // virtual: store tmp%5#0 to l-stack (no copy) tmp%0#0,tmp%5#0 self.box_map[key_0].bytes.length == value.bytes.length box_storage/contract.py:75 + // virtual: load tmp%5#0 from l-stack (no copy) tmp%0#0,tmp%5#0 assert self.box_map[key_0].bytes.length == value.bytes.length box_storage/contract.py:75 assert // tmp%0#0 assert self.box_map[key_0].bytes.length == value.bytes.length box_storage/contract.py:75 dup // load tmp%0#0 from l-stack (copy) tmp%0#0,tmp%0#0 self.box_map.length(key_0) box_storage/contract.py:76 box_len // tmp%0#0,{box_len}.0,{box_len}.1 self.box_map.length(key_0) box_storage/contract.py:76 - // virtual: store box_exists%1#0 to l-stack (no copy) tmp%0#0,box_exists%1#0,{box_len}.0 self.box_map.length(key_0) box_storage/contract.py:76 - // virtual: store box_len%1#0 to l-stack (no copy) tmp%0#0,box_len%1#0,box_exists%1#0 self.box_map.length(key_0) box_storage/contract.py:76 - // virtual: load box_exists%1#0 from l-stack (no copy) tmp%0#0,box_len%1#0,box_exists%1#0 self.box_map.length(key_0) box_storage/contract.py:76 - assert // Box must exist // tmp%0#0,box_len%1#0 self.box_map.length(key_0) box_storage/contract.py:76 - // virtual: load box_len%1#0 from l-stack (no copy) tmp%0#0,box_len%1#0 self.box_map.length(key_0) == value.bytes.length box_storage/contract.py:76 - int 6 // tmp%0#0,box_len%1#0,6 value.bytes.length box_storage/contract.py:76 + // virtual: store check%1#0 to l-stack (no copy) tmp%0#0,check%1#0,{box_len}.0 self.box_map.length(key_0) box_storage/contract.py:76 + // virtual: store value%1#0 to l-stack (no copy) tmp%0#0,value%1#0,check%1#0 self.box_map.length(key_0) box_storage/contract.py:76 + // virtual: load check%1#0 from l-stack (no copy) tmp%0#0,value%1#0,check%1#0 self.box_map.length(key_0) box_storage/contract.py:76 + assert // box exists // tmp%0#0,value%1#0 self.box_map.length(key_0) box_storage/contract.py:76 + // virtual: load value%1#0 from l-stack (no copy) tmp%0#0,value%1#0 self.box_map.length(key_0) == value.bytes.length box_storage/contract.py:76 + int 6 // tmp%0#0,value%1#0,6 value.bytes.length box_storage/contract.py:76 == // tmp%0#0,{==} self.box_map.length(key_0) == value.bytes.length box_storage/contract.py:76 - // virtual: store tmp%6#0 to l-stack (no copy) tmp%0#0,tmp%6#0 self.box_map.length(key_0) == value.bytes.length box_storage/contract.py:76 - // virtual: load tmp%6#0 from l-stack (no copy) tmp%0#0,tmp%6#0 assert self.box_map.length(key_0) == value.bytes.length box_storage/contract.py:76 + // virtual: store tmp%9#0 to l-stack (no copy) tmp%0#0,tmp%9#0 self.box_map.length(key_0) == value.bytes.length box_storage/contract.py:76 + // virtual: load tmp%9#0 from l-stack (no copy) tmp%0#0,tmp%9#0 assert self.box_map.length(key_0) == value.bytes.length box_storage/contract.py:76 assert // tmp%0#0 assert self.box_map.length(key_0) == value.bytes.length box_storage/contract.py:76 int 1 // tmp%0#0,1 UInt64(1) box_storage/contract.py:72 itob // tmp%0#0,{itob} self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - // virtual: store tmp%7#0 to l-stack (no copy) tmp%0#0,tmp%7#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - dup // load tmp%7#0 from l-stack (copy) tmp%0#0,tmp%7#0,tmp%7#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - box_get // tmp%0#0,tmp%7#0,{box_get}.0,{box_get}.1 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - swap // store box_exists%2#0 to l-stack (no copy) tmp%0#0,tmp%7#0,box_exists%2#0,{box_get}.0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - // virtual: store box_value%0#0 to l-stack (no copy) tmp%0#0,tmp%7#0,box_exists%2#0,box_value%0#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - byte "default" // tmp%0#0,tmp%7#0,box_exists%2#0,box_value%0#0,"default" String("default") box_storage/contract.py:78 - swap // load box_value%0#0 from l-stack (no copy) tmp%0#0,tmp%7#0,box_exists%2#0,"default",box_value%0#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - uncover 2 // load box_exists%2#0 from l-stack (no copy) tmp%0#0,tmp%7#0,"default",box_value%0#0,box_exists%2#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - select // tmp%0#0,tmp%7#0,{select} self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - // virtual: store tmp%8#0 to l-stack (no copy) tmp%0#0,tmp%7#0,tmp%8#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 - // virtual: load tmp%8#0 from l-stack (no copy) tmp%0#0,tmp%7#0,tmp%8#0 self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 - byte "default" // tmp%0#0,tmp%7#0,tmp%8#0,"default" String("default") box_storage/contract.py:78 - == // tmp%0#0,tmp%7#0,{==} self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 - // virtual: store tmp%9#0 to l-stack (no copy) tmp%0#0,tmp%7#0,tmp%9#0 self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 - // virtual: load tmp%9#0 from l-stack (no copy) tmp%0#0,tmp%7#0,tmp%9#0 assert self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 - assert // tmp%0#0,tmp%7#0 assert self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 - // virtual: load tmp%7#0 from l-stack (no copy) tmp%0#0,tmp%7#0 self.box_map.maybe(key_1) box_storage/contract.py:79 + // virtual: store tmp%10#0 to l-stack (no copy) tmp%0#0,tmp%10#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + dup // load tmp%10#0 from l-stack (copy) tmp%0#0,tmp%10#0,tmp%10#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + box_get // tmp%0#0,tmp%10#0,{box_get}.0,{box_get}.1 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + swap // store None_get_ex%1#0 to l-stack (no copy) tmp%0#0,tmp%10#0,None_get_ex%1#0,{box_get}.0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + // virtual: store None_get_ex%0#0 to l-stack (no copy) tmp%0#0,tmp%10#0,None_get_ex%1#0,None_get_ex%0#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + byte "default" // tmp%0#0,tmp%10#0,None_get_ex%1#0,None_get_ex%0#0,"default" String("default") box_storage/contract.py:78 + swap // load None_get_ex%0#0 from l-stack (no copy) tmp%0#0,tmp%10#0,None_get_ex%1#0,"default",None_get_ex%0#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + uncover 2 // load None_get_ex%1#0 from l-stack (no copy) tmp%0#0,tmp%10#0,"default",None_get_ex%0#0,None_get_ex%1#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + select // tmp%0#0,tmp%10#0,{select} self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + // virtual: store tmp%12#0 to l-stack (no copy) tmp%0#0,tmp%10#0,tmp%12#0 self.box_map.get(key_1, default=String("default")) box_storage/contract.py:78 + // virtual: load tmp%12#0 from l-stack (no copy) tmp%0#0,tmp%10#0,tmp%12#0 self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 + byte "default" // tmp%0#0,tmp%10#0,tmp%12#0,"default" String("default") box_storage/contract.py:78 + == // tmp%0#0,tmp%10#0,{==} self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 + // virtual: store tmp%13#0 to l-stack (no copy) tmp%0#0,tmp%10#0,tmp%13#0 self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 + // virtual: load tmp%13#0 from l-stack (no copy) tmp%0#0,tmp%10#0,tmp%13#0 assert self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 + assert // tmp%0#0,tmp%10#0 assert self.box_map.get(key_1, default=String("default")) == String("default") box_storage/contract.py:78 + // virtual: load tmp%10#0 from l-stack (no copy) tmp%0#0,tmp%10#0 self.box_map.maybe(key_1) box_storage/contract.py:79 box_get // tmp%0#0,{box_get}.0,{box_get}.1 self.box_map.maybe(key_1) box_storage/contract.py:79 swap // store exists#0 to l-stack (no copy) tmp%0#0,exists#0,{box_get}.0 self.box_map.maybe(key_1) box_storage/contract.py:79 pop // tmp%0#0,exists#0 self.box_map.maybe(key_1) box_storage/contract.py:79 // virtual: load exists#0 from l-stack (no copy) tmp%0#0,exists#0 not exists box_storage/contract.py:80 ! // tmp%0#0,{!} not exists box_storage/contract.py:80 - // virtual: store tmp%11#0 to l-stack (no copy) tmp%0#0,tmp%11#0 not exists box_storage/contract.py:80 - // virtual: load tmp%11#0 from l-stack (no copy) tmp%0#0,tmp%11#0 assert not exists box_storage/contract.py:80 + // virtual: store tmp%16#0 to l-stack (no copy) tmp%0#0,tmp%16#0 not exists box_storage/contract.py:80 + // virtual: load tmp%16#0 from l-stack (no copy) tmp%0#0,tmp%16#0 assert not exists box_storage/contract.py:80 assert // tmp%0#0 assert not exists box_storage/contract.py:80 - // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-81 - box_len // {box_len}.0,{box_len}.1 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-81 - swap // store box_exists%4#0 to l-stack (no copy) box_exists%4#0,{box_len}.0 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-81 - pop // box_exists%4#0 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-81 - // virtual: load box_exists%4#0 from l-stack (no copy) box_exists%4#0 assert key_0 in self.box_map box_storage/contract.py:81 + // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-81 + box_len // {box_len}.0,{box_len}.1 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-81 + swap // store box_exists%0#0 to l-stack (no copy) box_exists%0#0,{box_len}.0 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-81 + pop // box_exists%0#0 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-81 + // virtual: load box_exists%0#0 from l-stack (no copy) box_exists%0#0 assert key_0 in self.box_map box_storage/contract.py:81 assert // assert key_0 in self.box_map box_storage/contract.py:81 retsub // @@ -848,13 +844,13 @@ box_map_exists: proto 1 1 // (𝕡) key#0 | @arc4.abimethod\ndef box_map_exists(self, key: UInt64) -> bool: box_storage/contract.py:91-92 box_map_exists_block@0: - frame_dig -1 // load key#0 from parameters (𝕡) key#0 | key#0 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-93 - itob // (𝕡) key#0 | {itob} BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-93 - // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) key#0 | tmp%0#0 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-93 - // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) key#0 | tmp%0#0 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-93 - box_len // (𝕡) key#0 | {box_len}.0,{box_len}.1 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-93 - swap // store box_exists%0#0 to l-stack (no copy) (𝕡) key#0 | box_exists%0#0,{box_len}.0 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-93 - pop // (𝕡) key#0 | box_exists%0#0 BoxMap(UInt64, String)\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.Strin... box_storage/contract.py:13-93 + frame_dig -1 // load key#0 from parameters (𝕡) key#0 | key#0 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-93 + itob // (𝕡) key#0 | {itob} "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-93 + // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) key#0 | tmp%0#0 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-93 + // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) key#0 | tmp%0#0 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-93 + box_len // (𝕡) key#0 | {box_len}.0,{box_len}.1 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-93 + swap // store box_exists%0#0 to l-stack (no copy) (𝕡) key#0 | box_exists%0#0,{box_len}.0 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-93 + pop // (𝕡) key#0 | box_exists%0#0 "")\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None:\nself.b... box_storage/contract.py:13-93 // virtual: load box_exists%0#0 from l-stack (no copy) (𝕡) key#0 | box_exists%0#0 return key in self.box_map box_storage/contract.py:93 retsub // box_exists%0#0 return key in self.box_map box_storage/contract.py:93 diff --git a/examples/box_storage/out/BoxContract.approval.teal b/examples/box_storage/out/BoxContract.approval.teal index a1c1ba617..28d5e2ab7 100644 --- a/examples/box_storage/out/BoxContract.approval.teal +++ b/examples/box_storage/out/BoxContract.approval.teal @@ -273,21 +273,21 @@ set_boxes: frame_dig -3 itob // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:17 // self.box_a.value = a swap box_put // box_storage/contract.py:11 - // self.box_b = Box(Bytes, key=b"b") + // self.box_b = Box(Bytes, key="b") byte "b" // box_storage/contract.py:18 // self.box_b.value = b box_del pop // box_storage/contract.py:11 - // self.box_b = Box(Bytes, key=b"b") + // self.box_b = Box(Bytes, key="b") byte "b" // box_storage/contract.py:18 // self.box_b.value = b @@ -295,21 +295,21 @@ set_boxes: box_put // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:19 // self.box_c.value = c box_del pop // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:19 // self.box_c.value = c frame_dig -1 box_put // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:21 // self.box_a.value += 3 box_get @@ -321,8 +321,8 @@ set_boxes: + itob // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:21 // self.box_a.value += 3 swap @@ -337,8 +337,8 @@ read_boxes: // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: proto 0 3 // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:25 // return self.box_a.value, self.box_b.value, self.box_c.value box_get @@ -347,7 +347,7 @@ read_boxes: swap assert // Box must exist // box_storage/contract.py:11 - // self.box_b = Box(Bytes, key=b"b") + // self.box_b = Box(Bytes, key="b") byte "b" // box_storage/contract.py:25 // return self.box_a.value, self.box_b.value, self.box_c.value @@ -355,7 +355,7 @@ read_boxes: assert // Box must exist // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:25 // return self.box_a.value, self.box_b.value, self.box_c.value box_get @@ -370,14 +370,14 @@ boxes_exist: // def boxes_exist(self) -> tuple[bool, bool, bool]: proto 0 3 // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:29 // return bool(self.box_a), bool(self.box_b), bool(self.box_c) box_len bury 1 // box_storage/contract.py:11 - // self.box_b = Box(Bytes, key=b"b") + // self.box_b = Box(Bytes, key="b") byte "b" // box_storage/contract.py:29 // return bool(self.box_a), bool(self.box_b), bool(self.box_c) @@ -385,7 +385,7 @@ boxes_exist: bury 1 // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:29 // return bool(self.box_a), bool(self.box_b), bool(self.box_c) box_len @@ -401,25 +401,25 @@ slice_box: proto 0 0 // box_storage/contract.py:33 // box_0 = Box(Bytes, key=b"0") - byte "0" + byte 0x30 // box_storage/contract.py:34 // box_0.value = Bytes(b"Testing testing 123") box_del pop // box_storage/contract.py:33 // box_0 = Box(Bytes, key=b"0") - byte "0" + byte 0x30 // box_storage/contract.py:34 // box_0.value = Bytes(b"Testing testing 123") byte "Testing testing 123" box_put // box_storage/contract.py:33 // box_0 = Box(Bytes, key=b"0") - byte "0" + byte 0x30 // box_storage/contract.py:35 // assert box_0.value[0:7] == b"Testing" box_len - assert // Box must exist + pop dup int 0 dig 2 @@ -435,7 +435,7 @@ slice_box: - // box_storage/contract.py:33 // box_0 = Box(Bytes, key=b"0") - byte "0" + byte 0x30 // box_storage/contract.py:35 // assert box_0.value[0:7] == b"Testing" cover 2 @@ -445,25 +445,25 @@ slice_box: assert // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:37 // self.box_c.value = arc4.String("Hello") box_del pop // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:37 // self.box_c.value = arc4.String("Hello") byte "\x00\x05Hello" box_put // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:38 // assert self.box_c.value.bytes[2:10] == b"Hello" box_len - assert // Box must exist + pop int 2 dig 1 < @@ -483,7 +483,7 @@ slice_box: - // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:38 // assert self.box_c.value.bytes[2:10] == b"Hello" cover 2 @@ -502,14 +502,14 @@ arc4_box: proto 0 0 // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:43 // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) byte 0x00010203 box_put // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:45 // assert box_d.value[0] == 0 box_get @@ -520,7 +520,7 @@ arc4_box: assert // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:46 // assert box_d.value[1] == 1 box_get @@ -531,7 +531,7 @@ arc4_box: assert // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:47 // assert box_d.value[2] == 2 box_get @@ -542,7 +542,7 @@ arc4_box: assert // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:48 // assert box_d.value[3] == 3 box_get @@ -567,7 +567,7 @@ box_blob: // sender_bytes = Txn.sender.bytes txn Sender // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:55 // assert box_blob.create(size=8000) @@ -575,7 +575,7 @@ box_blob: box_create assert // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:56 // box_blob.replace(0, sender_bytes) @@ -583,7 +583,7 @@ box_blob: dig 2 box_replace // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:57 // box_blob.splice(0, 0, app_address) @@ -592,7 +592,7 @@ box_blob: dig 4 box_splice // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:58 // first_64 = box_blob.extract(0, 32 * 2) @@ -607,14 +607,14 @@ box_blob: == assert // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:60 // assert box_blob.delete() box_del assert // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:62 // value, exists = box_blob.maybe() @@ -625,7 +625,7 @@ box_blob: ! assert // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:64 // assert box_blob.get(default=sender_bytes) == sender_bytes @@ -641,14 +641,14 @@ box_blob: swap concat // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:65 // box_blob.put(sender_bytes + app_address) swap box_put // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:66 // assert box_blob, "Blob exists" @@ -656,12 +656,12 @@ box_blob: bury 1 assert // Blob exists // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:67 // assert box_blob.length == 64 box_len - assert // Box must exist + assert // box exists int 64 == assert @@ -694,7 +694,7 @@ box_map_test: // assert self.box_map[key_0].bytes.length == value.bytes.length dup box_len - assert // Box must exist + assert // box exists int 6 == assert @@ -702,7 +702,7 @@ box_map_test: // assert self.box_map.length(key_0) == value.bytes.length dup box_len - assert // Box must exist + assert // box exists int 6 == assert @@ -729,7 +729,7 @@ box_map_test: ! assert // box_storage/contract.py:13-81 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") // // @arc4.abimethod // def set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None: @@ -768,7 +768,7 @@ box_map_test: // // @arc4.abimethod // def box_blob(self) -> None: - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") // sender_bytes = Txn.sender.bytes // app_address = Global.current_application_address.bytes // assert box_blob.create(size=8000) @@ -846,7 +846,7 @@ box_map_exists: // def box_map_exists(self, key: UInt64) -> bool: proto 1 1 // box_storage/contract.py:13-93 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") // // @arc4.abimethod // def set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None: @@ -885,7 +885,7 @@ box_map_exists: // // @arc4.abimethod // def box_blob(self) -> None: - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") // sender_bytes = Txn.sender.bytes // app_address = Global.current_application_address.bytes // assert box_blob.create(size=8000) diff --git a/examples/box_storage/out/BoxContract.arc32.json b/examples/box_storage/out/BoxContract.arc32.json index 58b351379..307273f16 100644 --- a/examples/box_storage/out/BoxContract.arc32.json +++ b/examples/box_storage/out/BoxContract.arc32.json @@ -52,7 +52,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDE0CiAgICBtZXRob2QgInNldF9ib3hlcyh1aW50NjQsYnl0ZVtdLHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJyZWFkX2JveGVzKCkodWludDY0LGJ5dGVbXSxzdHJpbmcpIgogICAgbWV0aG9kICJib3hlc19leGlzdCgpKGJvb2wsYm9vbCxib29sKSIKICAgIG1ldGhvZCAic2xpY2VfYm94KCl2b2lkIgogICAgbWV0aG9kICJhcmM0X2JveCgpdm9pZCIKICAgIG1ldGhvZCAiYm94X2Jsb2IoKXZvaWQiCiAgICBtZXRob2QgImJveF9tYXBfdGVzdCgpdm9pZCIKICAgIG1ldGhvZCAiYm94X21hcF9zZXQodWludDY0LHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJib3hfbWFwX2dldCh1aW50NjQpc3RyaW5nIgogICAgbWV0aG9kICJib3hfbWFwX2V4aXN0cyh1aW50NjQpYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fc2V0X2JveGVzX3JvdXRlQDIgbWFpbl9yZWFkX2JveGVzX3JvdXRlQDMgbWFpbl9ib3hlc19leGlzdF9yb3V0ZUA0IG1haW5fc2xpY2VfYm94X3JvdXRlQDUgbWFpbl9hcmM0X2JveF9yb3V0ZUA2IG1haW5fYm94X2Jsb2Jfcm91dGVANyBtYWluX2JveF9tYXBfdGVzdF9yb3V0ZUA4IG1haW5fYm94X21hcF9zZXRfcm91dGVAOSBtYWluX2JveF9tYXBfZ2V0X3JvdXRlQDEwIG1haW5fYm94X21hcF9leGlzdHNfcm91dGVAMTEKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fc2V0X2JveGVzX3JvdXRlQDI6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBzZXRfYm94ZXMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fcmVhZF9ib3hlc19yb3V0ZUAzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiByZWFkX2JveGVzCiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgc3Vic3RyaW5nIDYgOAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBieXRlIDB4MDAwYwogICAgY29uY2F0CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaW50IDEyCiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JveGVzX2V4aXN0X3JvdXRlQDQ6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJveGVzX2V4aXN0CiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgY292ZXIgMgogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMwogICAgc2V0Yml0CiAgICBzd2FwCiAgICBpbnQgMAogICAgZ2V0Yml0CiAgICB1bmNvdmVyIDIKICAgIGludCAxCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgc3dhcAogICAgaW50IDAKICAgIGdldGJpdAogICAgaW50IDIKICAgIHN3YXAKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zbGljZV9ib3hfcm91dGVANToKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgc2xpY2VfYm94CiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2FyYzRfYm94X3JvdXRlQDY6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGFyYzRfYm94CiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JveF9ibG9iX3JvdXRlQDc6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJveF9ibG9iCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JveF9tYXBfdGVzdF9yb3V0ZUA4OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBib3hfbWFwX3Rlc3QKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYm94X21hcF9zZXRfcm91dGVAOToKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgKICAgIC8vIGNsYXNzIEJveENvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIGJveF9tYXBfc2V0CiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JveF9tYXBfZ2V0X3JvdXRlQDEwOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib3hfbWFwX2dldAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYm94X21hcF9leGlzdHNfcm91dGVAMTE6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIGJveF9tYXBfZXhpc3RzCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTQ6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3Quc2V0X2JveGVzKGE6IHVpbnQ2NCwgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYm94ZXM6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNS0xNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgc2V0X2JveGVzKHNlbGYsIGE6IFVJbnQ2NCwgYjogQnl0ZXMsIGM6IGFyYzQuU3RyaW5nKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNwogICAgLy8gc2VsZi5ib3hfYS52YWx1ZSA9IGEKICAgIGZyYW1lX2RpZyAtMwogICAgaXRvYgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0LCBrZXk9YiJCT1hfQSIpCiAgICBieXRlICJCT1hfQSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBzZWxmLmJveF9hLnZhbHVlID0gYQogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTEKICAgIC8vIHNlbGYuYm94X2IgPSBCb3goQnl0ZXMsIGtleT1iImIiKQogICAgYnl0ZSAiYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE4CiAgICAvLyBzZWxmLmJveF9iLnZhbHVlID0gYgogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMQogICAgLy8gc2VsZi5ib3hfYiA9IEJveChCeXRlcywga2V5PWIiYiIpCiAgICBieXRlICJiIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTgKICAgIC8vIHNlbGYuYm94X2IudmFsdWUgPSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlICJCT1hfQyIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE5CiAgICAvLyBzZWxmLmJveF9jLnZhbHVlID0gYwogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAiQk9YX0MiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxOQogICAgLy8gc2VsZi5ib3hfYy52YWx1ZSA9IGMKICAgIGZyYW1lX2RpZyAtMQogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0LCBrZXk9YiJCT1hfQSIpCiAgICBieXRlICJCT1hfQSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjIxCiAgICAvLyBzZWxmLmJveF9hLnZhbHVlICs9IDMKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgaW50IDMKICAgICsKICAgIGl0b2IKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBzZWxmLmJveF9hID0gQm94KFVJbnQ2NCwga2V5PWIiQk9YX0EiKQogICAgYnl0ZSAiQk9YX0EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyMQogICAgLy8gc2VsZi5ib3hfYS52YWx1ZSArPSAzCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5yZWFkX2JveGVzKCkgLT4gdWludDY0LCBieXRlcywgYnl0ZXM6CnJlYWRfYm94ZXM6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyMy0yNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgcmVhZF9ib3hlcyhzZWxmKSAtPiB0dXBsZVtVSW50NjQsIEJ5dGVzLCBhcmM0LlN0cmluZ106CiAgICBwcm90byAwIDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBzZWxmLmJveF9hID0gQm94KFVJbnQ2NCwga2V5PWIiQk9YX0EiKQogICAgYnl0ZSAiQk9YX0EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNQogICAgLy8gcmV0dXJuIHNlbGYuYm94X2EudmFsdWUsIHNlbGYuYm94X2IudmFsdWUsIHNlbGYuYm94X2MudmFsdWUKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTEKICAgIC8vIHNlbGYuYm94X2IgPSBCb3goQnl0ZXMsIGtleT1iImIiKQogICAgYnl0ZSAiYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjI1CiAgICAvLyByZXR1cm4gc2VsZi5ib3hfYS52YWx1ZSwgc2VsZi5ib3hfYi52YWx1ZSwgc2VsZi5ib3hfYy52YWx1ZQogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIEJveCBtdXN0IGV4aXN0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAiQk9YX0MiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNQogICAgLy8gcmV0dXJuIHNlbGYuYm94X2EudmFsdWUsIHNlbGYuYm94X2IudmFsdWUsIHNlbGYuYm94X2MudmFsdWUKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3QuYm94ZXNfZXhpc3QoKSAtPiB1aW50NjQsIHVpbnQ2NCwgdWludDY0Ogpib3hlc19leGlzdDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjI3LTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hlc19leGlzdChzZWxmKSAtPiB0dXBsZVtib29sLCBib29sLCBib29sXToKICAgIHByb3RvIDAgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0LCBrZXk9YiJCT1hfQSIpCiAgICBieXRlICJCT1hfQSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMQogICAgLy8gc2VsZi5ib3hfYiA9IEJveChCeXRlcywga2V5PWIiYiIpCiAgICBieXRlICJiIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjkKICAgIC8vIHJldHVybiBib29sKHNlbGYuYm94X2EpLCBib29sKHNlbGYuYm94X2IpLCBib29sKHNlbGYuYm94X2MpCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlICJCT1hfQyIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5zbGljZV9ib3goKSAtPiB2b2lkOgpzbGljZV9ib3g6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozMS0zMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgc2xpY2VfYm94KHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjMzCiAgICAvLyBib3hfMCA9IEJveChCeXRlcywga2V5PWIiMCIpCiAgICBieXRlICIwIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzQKICAgIC8vIGJveF8wLnZhbHVlID0gQnl0ZXMoYiJUZXN0aW5nIHRlc3RpbmcgMTIzIikKICAgIGJveF9kZWwKICAgIHBvcAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzMKICAgIC8vIGJveF8wID0gQm94KEJ5dGVzLCBrZXk9YiIwIikKICAgIGJ5dGUgIjAiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozNAogICAgLy8gYm94XzAudmFsdWUgPSBCeXRlcyhiIlRlc3RpbmcgdGVzdGluZyAxMjMiKQogICAgYnl0ZSAiVGVzdGluZyB0ZXN0aW5nIDEyMyIKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjMzCiAgICAvLyBib3hfMCA9IEJveChCeXRlcywga2V5PWIiMCIpCiAgICBieXRlICIwIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzUKICAgIC8vIGFzc2VydCBib3hfMC52YWx1ZVswOjddID09IGIiVGVzdGluZyIKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgZHVwCiAgICBpbnQgMAogICAgZGlnIDIKICAgIHNlbGVjdAogICAgc3dhcAogICAgaW50IDcKICAgIGRpZyAxCiAgICA8CiAgICBpbnQgNwogICAgc3dhcAogICAgc2VsZWN0CiAgICBkaWcgMQogICAgLQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzMKICAgIC8vIGJveF8wID0gQm94KEJ5dGVzLCBrZXk9YiIwIikKICAgIGJ5dGUgIjAiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozNQogICAgLy8gYXNzZXJ0IGJveF8wLnZhbHVlWzA6N10gPT0gYiJUZXN0aW5nIgogICAgY292ZXIgMgogICAgYm94X2V4dHJhY3QKICAgIGJ5dGUgIlRlc3RpbmciCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAiQk9YX0MiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozNwogICAgLy8gc2VsZi5ib3hfYy52YWx1ZSA9IGFyYzQuU3RyaW5nKCJIZWxsbyIpCiAgICBib3hfZGVsCiAgICBwb3AKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlICJCT1hfQyIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBzZWxmLmJveF9jLnZhbHVlID0gYXJjNC5TdHJpbmcoIkhlbGxvIikKICAgIGJ5dGUgIlx4MDBceDA1SGVsbG8iCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAiQk9YX0MiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozOAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbMjoxMF0gPT0gYiJIZWxsbyIKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgaW50IDIKICAgIGRpZyAxCiAgICA8CiAgICBzd2FwCiAgICBkdXAKICAgIGludCAyCiAgICB1bmNvdmVyIDMKICAgIHNlbGVjdAogICAgc3dhcAogICAgaW50IDEwCiAgICBkaWcgMQogICAgPAogICAgaW50IDEwCiAgICBzd2FwCiAgICBzZWxlY3QKICAgIGRpZyAxCiAgICAtCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAiQk9YX0MiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozOAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbMjoxMF0gPT0gYiJIZWxsbyIKICAgIGNvdmVyIDIKICAgIGJveF9leHRyYWN0CiAgICBieXRlICJIZWxsbyIKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmFyYzRfYm94KCkgLT4gdm9pZDoKYXJjNF9ib3g6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0MC00MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYXJjNF9ib3goc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDIKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1iImQiKQogICAgYnl0ZSAiZCIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBib3hfZC52YWx1ZSA9IFN0YXRpY0ludHMoYXJjNC5VSW50OCgwKSwgYXJjNC5VSW50OCgxKSwgYXJjNC5VSW50OCgyKSwgYXJjNC5VSW50OCgzKSkKICAgIGJ5dGUgMHgwMDAxMDIwMwogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDIKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1iImQiKQogICAgYnl0ZSAiZCIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ1CiAgICAvLyBhc3NlcnQgYm94X2QudmFsdWVbMF0gPT0gMAogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIEJveCBtdXN0IGV4aXN0CiAgICBleHRyYWN0IDAgMQogICAgYnl0ZSAweDAwCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDIKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1iImQiKQogICAgYnl0ZSAiZCIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ2CiAgICAvLyBhc3NlcnQgYm94X2QudmFsdWVbMV0gPT0gMQogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIEJveCBtdXN0IGV4aXN0CiAgICBleHRyYWN0IDEgMQogICAgYnl0ZSAweDAxCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDIKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1iImQiKQogICAgYnl0ZSAiZCIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBhc3NlcnQgYm94X2QudmFsdWVbMl0gPT0gMgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIEJveCBtdXN0IGV4aXN0CiAgICBleHRyYWN0IDIgMQogICAgYnl0ZSAweDAyCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDIKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1iImQiKQogICAgYnl0ZSAiZCIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ4CiAgICAvLyBhc3NlcnQgYm94X2QudmFsdWVbM10gPT0gMwogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIEJveCBtdXN0IGV4aXN0CiAgICBleHRyYWN0IDMgMQogICAgYnl0ZSAweDAzCiAgICBiPT0KICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3QuYm94X2Jsb2IoKSAtPiB2b2lkOgpib3hfYmxvYjoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjUwLTUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfYmxvYihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1NAogICAgLy8gYXBwX2FkZHJlc3MgPSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLmJ5dGVzCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTMKICAgIC8vIHNlbmRlcl9ieXRlcyA9IFR4bi5zZW5kZXIuYnl0ZXMKICAgIHR4biBTZW5kZXIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBib3hfYmxvYiA9IEJveFJlZihrZXk9YiJibG9iIikKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1NQogICAgLy8gYXNzZXJ0IGJveF9ibG9iLmNyZWF0ZShzaXplPTgwMDApCiAgICBpbnQgODAwMAogICAgYm94X2NyZWF0ZQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MgogICAgLy8gYm94X2Jsb2IgPSBCb3hSZWYoa2V5PWIiYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTYKICAgIC8vIGJveF9ibG9iLnJlcGxhY2UoMCwgc2VuZGVyX2J5dGVzKQogICAgaW50IDAKICAgIGRpZyAyCiAgICBib3hfcmVwbGFjZQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTIKICAgIC8vIGJveF9ibG9iID0gQm94UmVmKGtleT1iImJsb2IiKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU3CiAgICAvLyBib3hfYmxvYi5zcGxpY2UoMCwgMCwgYXBwX2FkZHJlc3MpCiAgICBpbnQgMAogICAgZHVwCiAgICBkaWcgNAogICAgYm94X3NwbGljZQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTIKICAgIC8vIGJveF9ibG9iID0gQm94UmVmKGtleT1iImJsb2IiKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU4CiAgICAvLyBmaXJzdF82NCA9IGJveF9ibG9iLmV4dHJhY3QoMCwgMzIgKiAyKQogICAgaW50IDAKICAgIGludCA2NAogICAgYm94X2V4dHJhY3QKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBhc3NlcnQgZmlyc3RfNjQgPT0gYXBwX2FkZHJlc3MgKyBzZW5kZXJfYnl0ZXMKICAgIGRpZyAyCiAgICBkaWcgMgogICAgY29uY2F0CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MgogICAgLy8gYm94X2Jsb2IgPSBCb3hSZWYoa2V5PWIiYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjAKICAgIC8vIGFzc2VydCBib3hfYmxvYi5kZWxldGUoKQogICAgYm94X2RlbAogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MgogICAgLy8gYm94X2Jsb2IgPSBCb3hSZWYoa2V5PWIiYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjIKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBib3hfYmxvYi5tYXliZSgpCiAgICBib3hfZ2V0CiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjYzCiAgICAvLyBhc3NlcnQgbm90IGV4aXN0cwogICAgIQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MgogICAgLy8gYm94X2Jsb2IgPSBCb3hSZWYoa2V5PWIiYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjQKICAgIC8vIGFzc2VydCBib3hfYmxvYi5nZXQoZGVmYXVsdD1zZW5kZXJfYnl0ZXMpID09IHNlbmRlcl9ieXRlcwogICAgYm94X2dldAogICAgZGlnIDIKICAgIGNvdmVyIDIKICAgIHNlbGVjdAogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY1CiAgICAvLyBib3hfYmxvYi5wdXQoc2VuZGVyX2J5dGVzICsgYXBwX2FkZHJlc3MpCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBib3hfYmxvYiA9IEJveFJlZihrZXk9YiJibG9iIikKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo2NQogICAgLy8gYm94X2Jsb2IucHV0KHNlbmRlcl9ieXRlcyArIGFwcF9hZGRyZXNzKQogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTIKICAgIC8vIGJveF9ibG9iID0gQm94UmVmKGtleT1iImJsb2IiKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY2CiAgICAvLyBhc3NlcnQgYm94X2Jsb2IsICJCbG9iIGV4aXN0cyIKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgYXNzZXJ0IC8vIEJsb2IgZXhpc3RzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MgogICAgLy8gYm94X2Jsb2IgPSBCb3hSZWYoa2V5PWIiYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjcKICAgIC8vIGFzc2VydCBib3hfYmxvYi5sZW5ndGggPT0gNjQKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgaW50IDY0CiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX3Rlc3QoKSAtPiB2b2lkOgpib3hfbWFwX3Rlc3Q6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF90ZXN0KHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjcxCiAgICAvLyBrZXlfMCA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyBzZWxmLmJveF9tYXBba2V5XzBdID0gdmFsdWUKICAgIGl0b2IKICAgIGR1cAogICAgYm94X2RlbAogICAgcG9wCiAgICBkdXAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjczCiAgICAvLyB2YWx1ZSA9IFN0cmluZygiSG1tbW1tIikKICAgIGJ5dGUgIkhtbW1tbSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyBzZWxmLmJveF9tYXBba2V5XzBdID0gdmFsdWUKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfbWFwW2tleV8wXS5ieXRlcy5sZW5ndGggPT0gdmFsdWUuYnl0ZXMubGVuZ3RoCiAgICBkdXAKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgaW50IDYKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc2CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfbWFwLmxlbmd0aChrZXlfMCkgPT0gdmFsdWUuYnl0ZXMubGVuZ3RoCiAgICBkdXAKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgaW50IDYKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjcyCiAgICAvLyBrZXlfMSA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc4CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfbWFwLmdldChrZXlfMSwgZGVmYXVsdD1TdHJpbmcoImRlZmF1bHQiKSkgPT0gU3RyaW5nKCJkZWZhdWx0IikKICAgIGl0b2IKICAgIGR1cAogICAgYm94X2dldAogICAgYnl0ZSAiZGVmYXVsdCIKICAgIGNvdmVyIDIKICAgIHNlbGVjdAogICAgYnl0ZSAiZGVmYXVsdCIKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gc2VsZi5ib3hfbWFwLm1heWJlKGtleV8xKQogICAgYm94X2dldAogICAgYnVyeSAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4MAogICAgLy8gYXNzZXJ0IG5vdCBleGlzdHMKICAgICEKICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTMtODEKICAgIC8vICAgICBzZWxmLmJveF9tYXAgPSBCb3hNYXAoVUludDY0LCBTdHJpbmcpCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHNldF9ib3hlcyhzZWxmLCBhOiBVSW50NjQsIGI6IEJ5dGVzLCBjOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIC8vICAgICBzZWxmLmJveF9hLnZhbHVlID0gYQogICAgLy8gICAgIHNlbGYuYm94X2IudmFsdWUgPSBiCiAgICAvLyAgICAgc2VsZi5ib3hfYy52YWx1ZSA9IGMKICAgIC8vIAogICAgLy8gICAgIHNlbGYuYm94X2EudmFsdWUgKz0gMwogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiByZWFkX2JveGVzKHNlbGYpIC0+IHR1cGxlW1VJbnQ2NCwgQnl0ZXMsIGFyYzQuU3RyaW5nXToKICAgIC8vICAgICByZXR1cm4gc2VsZi5ib3hfYS52YWx1ZSwgc2VsZi5ib3hfYi52YWx1ZSwgc2VsZi5ib3hfYy52YWx1ZQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hlc19leGlzdChzZWxmKSAtPiB0dXBsZVtib29sLCBib29sLCBib29sXToKICAgIC8vICAgICByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzbGljZV9ib3goc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBib3hfMCA9IEJveChCeXRlcywga2V5PWIiMCIpCiAgICAvLyAgICAgYm94XzAudmFsdWUgPSBCeXRlcyhiIlRlc3RpbmcgdGVzdGluZyAxMjMiKQogICAgLy8gICAgIGFzc2VydCBib3hfMC52YWx1ZVswOjddID09IGIiVGVzdGluZyIKICAgIC8vIAogICAgLy8gICAgIHNlbGYuYm94X2MudmFsdWUgPSBhcmM0LlN0cmluZygiSGVsbG8iKQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWzI6MTBdID09IGIiSGVsbG8iCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGFyYzRfYm94KHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAgYm94X2QgPSBCb3goU3RhdGljSW50cywga2V5PWIiZCIpCiAgICAvLyAgICAgYm94X2QudmFsdWUgPSBTdGF0aWNJbnRzKGFyYzQuVUludDgoMCksIGFyYzQuVUludDgoMSksIGFyYzQuVUludDgoMiksIGFyYzQuVUludDgoMykpCiAgICAvLyAKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbMF0gPT0gMAogICAgLy8gICAgIGFzc2VydCBib3hfZC52YWx1ZVsxXSA9PSAxCiAgICAvLyAgICAgYXNzZXJ0IGJveF9kLnZhbHVlWzJdID09IDIKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbM10gPT0gMwogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfYmxvYihzZWxmKSAtPiBOb25lOgogICAgLy8gICAgIGJveF9ibG9iID0gQm94UmVmKGtleT1iImJsb2IiKQogICAgLy8gICAgIHNlbmRlcl9ieXRlcyA9IFR4bi5zZW5kZXIuYnl0ZXMKICAgIC8vICAgICBhcHBfYWRkcmVzcyA9IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MuYnl0ZXMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuY3JlYXRlKHNpemU9ODAwMCkKICAgIC8vICAgICBib3hfYmxvYi5yZXBsYWNlKDAsIHNlbmRlcl9ieXRlcykKICAgIC8vICAgICBib3hfYmxvYi5zcGxpY2UoMCwgMCwgYXBwX2FkZHJlc3MpCiAgICAvLyAgICAgZmlyc3RfNjQgPSBib3hfYmxvYi5leHRyYWN0KDAsIDMyICogMikKICAgIC8vICAgICBhc3NlcnQgZmlyc3RfNjQgPT0gYXBwX2FkZHJlc3MgKyBzZW5kZXJfYnl0ZXMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuZGVsZXRlKCkKICAgIC8vIAogICAgLy8gICAgIHZhbHVlLCBleGlzdHMgPSBib3hfYmxvYi5tYXliZSgpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBleGlzdHMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuZ2V0KGRlZmF1bHQ9c2VuZGVyX2J5dGVzKSA9PSBzZW5kZXJfYnl0ZXMKICAgIC8vICAgICBib3hfYmxvYi5wdXQoc2VuZGVyX2J5dGVzICsgYXBwX2FkZHJlc3MpCiAgICAvLyAgICAgYXNzZXJ0IGJveF9ibG9iLCAiQmxvYiBleGlzdHMiCiAgICAvLyAgICAgYXNzZXJ0IGJveF9ibG9iLmxlbmd0aCA9PSA2NAogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX3Rlc3Qoc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBrZXlfMCA9IFVJbnQ2NCgwKQogICAgLy8gICAgIGtleV8xID0gVUludDY0KDEpCiAgICAvLyAgICAgdmFsdWUgPSBTdHJpbmcoIkhtbW1tbSIpCiAgICAvLyAgICAgc2VsZi5ib3hfbWFwW2tleV8wXSA9IHZhbHVlCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X21hcFtrZXlfMF0uYnl0ZXMubGVuZ3RoID09IHZhbHVlLmJ5dGVzLmxlbmd0aAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAubGVuZ3RoKGtleV8wKSA9PSB2YWx1ZS5ieXRlcy5sZW5ndGgKICAgIC8vIAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAuZ2V0KGtleV8xLCBkZWZhdWx0PVN0cmluZygiZGVmYXVsdCIpKSA9PSBTdHJpbmcoImRlZmF1bHQiKQogICAgLy8gICAgIHZhbHVlLCBleGlzdHMgPSBzZWxmLmJveF9tYXAubWF5YmUoa2V5XzEpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBleGlzdHMKICAgIC8vICAgICBhc3NlcnQga2V5XzAgaW4gc2VsZi5ib3hfbWFwCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBhc3NlcnQga2V5XzAgaW4gc2VsZi5ib3hfbWFwCiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfc2V0KGtleTogdWludDY0LCB2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CmJveF9tYXBfc2V0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODMtODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfc2V0KHNlbGYsIGtleTogVUludDY0LCB2YWx1ZTogU3RyaW5nKSAtPiBOb25lOgogICAgcHJvdG8gMiAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4NQogICAgLy8gc2VsZi5ib3hfbWFwW2tleV0gPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0yCiAgICBpdG9iCiAgICBkdXAKICAgIGJveF9kZWwKICAgIHBvcAogICAgZnJhbWVfZGlnIC0xCiAgICBib3hfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX2dldChrZXk6IHVpbnQ2NCkgLT4gYnl0ZXM6CmJveF9tYXBfZ2V0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODctODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfZ2V0KHNlbGYsIGtleTogVUludDY0KSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojg5CiAgICAvLyByZXR1cm4gc2VsZi5ib3hfbWFwW2tleV0KICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIEJveCBtdXN0IGV4aXN0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX2V4aXN0cyhrZXk6IHVpbnQ2NCkgLT4gdWludDY0Ogpib3hfbWFwX2V4aXN0czoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjkxLTkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX2V4aXN0cyhzZWxmLCBrZXk6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIHByb3RvIDEgMQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTMtOTMKICAgIC8vICAgICBzZWxmLmJveF9tYXAgPSBCb3hNYXAoVUludDY0LCBTdHJpbmcpCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHNldF9ib3hlcyhzZWxmLCBhOiBVSW50NjQsIGI6IEJ5dGVzLCBjOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIC8vICAgICBzZWxmLmJveF9hLnZhbHVlID0gYQogICAgLy8gICAgIHNlbGYuYm94X2IudmFsdWUgPSBiCiAgICAvLyAgICAgc2VsZi5ib3hfYy52YWx1ZSA9IGMKICAgIC8vIAogICAgLy8gICAgIHNlbGYuYm94X2EudmFsdWUgKz0gMwogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiByZWFkX2JveGVzKHNlbGYpIC0+IHR1cGxlW1VJbnQ2NCwgQnl0ZXMsIGFyYzQuU3RyaW5nXToKICAgIC8vICAgICByZXR1cm4gc2VsZi5ib3hfYS52YWx1ZSwgc2VsZi5ib3hfYi52YWx1ZSwgc2VsZi5ib3hfYy52YWx1ZQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hlc19leGlzdChzZWxmKSAtPiB0dXBsZVtib29sLCBib29sLCBib29sXToKICAgIC8vICAgICByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzbGljZV9ib3goc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBib3hfMCA9IEJveChCeXRlcywga2V5PWIiMCIpCiAgICAvLyAgICAgYm94XzAudmFsdWUgPSBCeXRlcyhiIlRlc3RpbmcgdGVzdGluZyAxMjMiKQogICAgLy8gICAgIGFzc2VydCBib3hfMC52YWx1ZVswOjddID09IGIiVGVzdGluZyIKICAgIC8vIAogICAgLy8gICAgIHNlbGYuYm94X2MudmFsdWUgPSBhcmM0LlN0cmluZygiSGVsbG8iKQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWzI6MTBdID09IGIiSGVsbG8iCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGFyYzRfYm94KHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAgYm94X2QgPSBCb3goU3RhdGljSW50cywga2V5PWIiZCIpCiAgICAvLyAgICAgYm94X2QudmFsdWUgPSBTdGF0aWNJbnRzKGFyYzQuVUludDgoMCksIGFyYzQuVUludDgoMSksIGFyYzQuVUludDgoMiksIGFyYzQuVUludDgoMykpCiAgICAvLyAKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbMF0gPT0gMAogICAgLy8gICAgIGFzc2VydCBib3hfZC52YWx1ZVsxXSA9PSAxCiAgICAvLyAgICAgYXNzZXJ0IGJveF9kLnZhbHVlWzJdID09IDIKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbM10gPT0gMwogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfYmxvYihzZWxmKSAtPiBOb25lOgogICAgLy8gICAgIGJveF9ibG9iID0gQm94UmVmKGtleT1iImJsb2IiKQogICAgLy8gICAgIHNlbmRlcl9ieXRlcyA9IFR4bi5zZW5kZXIuYnl0ZXMKICAgIC8vICAgICBhcHBfYWRkcmVzcyA9IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MuYnl0ZXMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuY3JlYXRlKHNpemU9ODAwMCkKICAgIC8vICAgICBib3hfYmxvYi5yZXBsYWNlKDAsIHNlbmRlcl9ieXRlcykKICAgIC8vICAgICBib3hfYmxvYi5zcGxpY2UoMCwgMCwgYXBwX2FkZHJlc3MpCiAgICAvLyAgICAgZmlyc3RfNjQgPSBib3hfYmxvYi5leHRyYWN0KDAsIDMyICogMikKICAgIC8vICAgICBhc3NlcnQgZmlyc3RfNjQgPT0gYXBwX2FkZHJlc3MgKyBzZW5kZXJfYnl0ZXMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuZGVsZXRlKCkKICAgIC8vIAogICAgLy8gICAgIHZhbHVlLCBleGlzdHMgPSBib3hfYmxvYi5tYXliZSgpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBleGlzdHMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuZ2V0KGRlZmF1bHQ9c2VuZGVyX2J5dGVzKSA9PSBzZW5kZXJfYnl0ZXMKICAgIC8vICAgICBib3hfYmxvYi5wdXQoc2VuZGVyX2J5dGVzICsgYXBwX2FkZHJlc3MpCiAgICAvLyAgICAgYXNzZXJ0IGJveF9ibG9iLCAiQmxvYiBleGlzdHMiCiAgICAvLyAgICAgYXNzZXJ0IGJveF9ibG9iLmxlbmd0aCA9PSA2NAogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX3Rlc3Qoc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBrZXlfMCA9IFVJbnQ2NCgwKQogICAgLy8gICAgIGtleV8xID0gVUludDY0KDEpCiAgICAvLyAgICAgdmFsdWUgPSBTdHJpbmcoIkhtbW1tbSIpCiAgICAvLyAgICAgc2VsZi5ib3hfbWFwW2tleV8wXSA9IHZhbHVlCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X21hcFtrZXlfMF0uYnl0ZXMubGVuZ3RoID09IHZhbHVlLmJ5dGVzLmxlbmd0aAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAubGVuZ3RoKGtleV8wKSA9PSB2YWx1ZS5ieXRlcy5sZW5ndGgKICAgIC8vIAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAuZ2V0KGtleV8xLCBkZWZhdWx0PVN0cmluZygiZGVmYXVsdCIpKSA9PSBTdHJpbmcoImRlZmF1bHQiKQogICAgLy8gICAgIHZhbHVlLCBleGlzdHMgPSBzZWxmLmJveF9tYXAubWF5YmUoa2V5XzEpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBleGlzdHMKICAgIC8vICAgICBhc3NlcnQga2V5XzAgaW4gc2VsZi5ib3hfbWFwCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfc2V0KHNlbGYsIGtleTogVUludDY0LCB2YWx1ZTogU3RyaW5nKSAtPiBOb25lOgogICAgLy8gICAgIHNlbGYuYm94X21hcFtrZXldID0gdmFsdWUKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9nZXQoc2VsZiwga2V5OiBVSW50NjQpIC0+IFN0cmluZzoKICAgIC8vICAgICByZXR1cm4gc2VsZi5ib3hfbWFwW2tleV0KICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9leGlzdHMoc2VsZiwga2V5OiBVSW50NjQpIC0+IGJvb2w6CiAgICAvLyAgICAgcmV0dXJuIGtleSBpbiBzZWxmLmJveF9tYXAKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo5MwogICAgLy8gcmV0dXJuIGtleSBpbiBzZWxmLmJveF9tYXAKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDE0CiAgICBtZXRob2QgInNldF9ib3hlcyh1aW50NjQsYnl0ZVtdLHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJyZWFkX2JveGVzKCkodWludDY0LGJ5dGVbXSxzdHJpbmcpIgogICAgbWV0aG9kICJib3hlc19leGlzdCgpKGJvb2wsYm9vbCxib29sKSIKICAgIG1ldGhvZCAic2xpY2VfYm94KCl2b2lkIgogICAgbWV0aG9kICJhcmM0X2JveCgpdm9pZCIKICAgIG1ldGhvZCAiYm94X2Jsb2IoKXZvaWQiCiAgICBtZXRob2QgImJveF9tYXBfdGVzdCgpdm9pZCIKICAgIG1ldGhvZCAiYm94X21hcF9zZXQodWludDY0LHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJib3hfbWFwX2dldCh1aW50NjQpc3RyaW5nIgogICAgbWV0aG9kICJib3hfbWFwX2V4aXN0cyh1aW50NjQpYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fc2V0X2JveGVzX3JvdXRlQDIgbWFpbl9yZWFkX2JveGVzX3JvdXRlQDMgbWFpbl9ib3hlc19leGlzdF9yb3V0ZUA0IG1haW5fc2xpY2VfYm94X3JvdXRlQDUgbWFpbl9hcmM0X2JveF9yb3V0ZUA2IG1haW5fYm94X2Jsb2Jfcm91dGVANyBtYWluX2JveF9tYXBfdGVzdF9yb3V0ZUA4IG1haW5fYm94X21hcF9zZXRfcm91dGVAOSBtYWluX2JveF9tYXBfZ2V0X3JvdXRlQDEwIG1haW5fYm94X21hcF9leGlzdHNfcm91dGVAMTEKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fc2V0X2JveGVzX3JvdXRlQDI6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBzZXRfYm94ZXMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fcmVhZF9ib3hlc19yb3V0ZUAzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiByZWFkX2JveGVzCiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgc3Vic3RyaW5nIDYgOAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBieXRlIDB4MDAwYwogICAgY29uY2F0CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaW50IDEyCiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JveGVzX2V4aXN0X3JvdXRlQDQ6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJveGVzX2V4aXN0CiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgY292ZXIgMgogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMwogICAgc2V0Yml0CiAgICBzd2FwCiAgICBpbnQgMAogICAgZ2V0Yml0CiAgICB1bmNvdmVyIDIKICAgIGludCAxCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgc3dhcAogICAgaW50IDAKICAgIGdldGJpdAogICAgaW50IDIKICAgIHN3YXAKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9zbGljZV9ib3hfcm91dGVANToKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgc2xpY2VfYm94CiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2FyYzRfYm94X3JvdXRlQDY6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGFyYzRfYm94CiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JveF9ibG9iX3JvdXRlQDc6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJveF9ibG9iCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JveF9tYXBfdGVzdF9yb3V0ZUA4OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBib3hfbWFwX3Rlc3QKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYm94X21hcF9zZXRfcm91dGVAOToKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgKICAgIC8vIGNsYXNzIEJveENvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIGJveF9tYXBfc2V0CiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JveF9tYXBfZ2V0X3JvdXRlQDEwOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib3hfbWFwX2dldAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYm94X21hcF9leGlzdHNfcm91dGVAMTE6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIGJveF9tYXBfZXhpc3RzCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTQ6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3Quc2V0X2JveGVzKGE6IHVpbnQ2NCwgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiB2b2lkOgpzZXRfYm94ZXM6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNS0xNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgc2V0X2JveGVzKHNlbGYsIGE6IFVJbnQ2NCwgYjogQnl0ZXMsIGM6IGFyYzQuU3RyaW5nKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNwogICAgLy8gc2VsZi5ib3hfYS52YWx1ZSA9IGEKICAgIGZyYW1lX2RpZyAtMwogICAgaXRvYgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0KQogICAgYnl0ZSAiYm94X2EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNwogICAgLy8gc2VsZi5ib3hfYS52YWx1ZSA9IGEKICAgIHN3YXAKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExCiAgICAvLyBzZWxmLmJveF9iID0gQm94KEJ5dGVzLCBrZXk9ImIiKQogICAgYnl0ZSAiYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE4CiAgICAvLyBzZWxmLmJveF9iLnZhbHVlID0gYgogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMQogICAgLy8gc2VsZi5ib3hfYiA9IEJveChCeXRlcywga2V5PSJiIikKICAgIGJ5dGUgImIiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxOAogICAgLy8gc2VsZi5ib3hfYi52YWx1ZSA9IGIKICAgIGZyYW1lX2RpZyAtMgogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYuYm94X2MgPSBCb3goYXJjNC5TdHJpbmcsIGtleT1iIkJPWF9DIikKICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxOQogICAgLy8gc2VsZi5ib3hfYy52YWx1ZSA9IGMKICAgIGJveF9kZWwKICAgIHBvcAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYuYm94X2MgPSBCb3goYXJjNC5TdHJpbmcsIGtleT1iIkJPWF9DIikKICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxOQogICAgLy8gc2VsZi5ib3hfYy52YWx1ZSA9IGMKICAgIGZyYW1lX2RpZyAtMQogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0KQogICAgYnl0ZSAiYm94X2EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyMQogICAgLy8gc2VsZi5ib3hfYS52YWx1ZSArPSAzCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBhc3NlcnQgLy8gQm94IG11c3QgZXhpc3QKICAgIGludCAzCiAgICArCiAgICBpdG9iCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMAogICAgLy8gc2VsZi5ib3hfYSA9IEJveChVSW50NjQpCiAgICBieXRlICJib3hfYSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjIxCiAgICAvLyBzZWxmLmJveF9hLnZhbHVlICs9IDMKICAgIHN3YXAKICAgIGJveF9wdXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LnJlYWRfYm94ZXMoKSAtPiB1aW50NjQsIGJ5dGVzLCBieXRlczoKcmVhZF9ib3hlczoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjIzLTI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiByZWFkX2JveGVzKHNlbGYpIC0+IHR1cGxlW1VJbnQ2NCwgQnl0ZXMsIGFyYzQuU3RyaW5nXToKICAgIHByb3RvIDAgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0KQogICAgYnl0ZSAiYm94X2EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNQogICAgLy8gcmV0dXJuIHNlbGYuYm94X2EudmFsdWUsIHNlbGYuYm94X2IudmFsdWUsIHNlbGYuYm94X2MudmFsdWUKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTEKICAgIC8vIHNlbGYuYm94X2IgPSBCb3goQnl0ZXMsIGtleT0iYiIpCiAgICBieXRlICJiIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjUKICAgIC8vIHJldHVybiBzZWxmLmJveF9hLnZhbHVlLCBzZWxmLmJveF9iLnZhbHVlLCBzZWxmLmJveF9jLnZhbHVlCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gQm94IG11c3QgZXhpc3QKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjUKICAgIC8vIHJldHVybiBzZWxmLmJveF9hLnZhbHVlLCBzZWxmLmJveF9iLnZhbHVlLCBzZWxmLmJveF9jLnZhbHVlCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gQm94IG11c3QgZXhpc3QKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveGVzX2V4aXN0KCkgLT4gdWludDY0LCB1aW50NjQsIHVpbnQ2NDoKYm94ZXNfZXhpc3Q6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNy0yOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94ZXNfZXhpc3Qoc2VsZikgLT4gdHVwbGVbYm9vbCwgYm9vbCwgYm9vbF06CiAgICBwcm90byAwIDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBzZWxmLmJveF9hID0gQm94KFVJbnQ2NCkKICAgIGJ5dGUgImJveF9hIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjkKICAgIC8vIHJldHVybiBib29sKHNlbGYuYm94X2EpLCBib29sKHNlbGYuYm94X2IpLCBib29sKHNlbGYuYm94X2MpCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExCiAgICAvLyBzZWxmLmJveF9iID0gQm94KEJ5dGVzLCBrZXk9ImIiKQogICAgYnl0ZSAiYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5zbGljZV9ib3goKSAtPiB2b2lkOgpzbGljZV9ib3g6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozMS0zMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgc2xpY2VfYm94KHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjMzCiAgICAvLyBib3hfMCA9IEJveChCeXRlcywga2V5PWIiMCIpCiAgICBieXRlIDB4MzAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjM0CiAgICAvLyBib3hfMC52YWx1ZSA9IEJ5dGVzKGIiVGVzdGluZyB0ZXN0aW5nIDEyMyIpCiAgICBib3hfZGVsCiAgICBwb3AKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjMzCiAgICAvLyBib3hfMCA9IEJveChCeXRlcywga2V5PWIiMCIpCiAgICBieXRlIDB4MzAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjM0CiAgICAvLyBib3hfMC52YWx1ZSA9IEJ5dGVzKGIiVGVzdGluZyB0ZXN0aW5nIDEyMyIpCiAgICBieXRlICJUZXN0aW5nIHRlc3RpbmcgMTIzIgogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzMKICAgIC8vIGJveF8wID0gQm94KEJ5dGVzLCBrZXk9YiIwIikKICAgIGJ5dGUgMHgzMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzUKICAgIC8vIGFzc2VydCBib3hfMC52YWx1ZVswOjddID09IGIiVGVzdGluZyIKICAgIGJveF9sZW4KICAgIHBvcAogICAgZHVwCiAgICBpbnQgMAogICAgZGlnIDIKICAgIHNlbGVjdAogICAgc3dhcAogICAgaW50IDcKICAgIGRpZyAxCiAgICA8CiAgICBpbnQgNwogICAgc3dhcAogICAgc2VsZWN0CiAgICBkaWcgMQogICAgLQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzMKICAgIC8vIGJveF8wID0gQm94KEJ5dGVzLCBrZXk9YiIwIikKICAgIGJ5dGUgMHgzMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzUKICAgIC8vIGFzc2VydCBib3hfMC52YWx1ZVswOjddID09IGIiVGVzdGluZyIKICAgIGNvdmVyIDIKICAgIGJveF9leHRyYWN0CiAgICBieXRlICJUZXN0aW5nIgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYuYm94X2MgPSBCb3goYXJjNC5TdHJpbmcsIGtleT1iIkJPWF9DIikKICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozNwogICAgLy8gc2VsZi5ib3hfYy52YWx1ZSA9IGFyYzQuU3RyaW5nKCJIZWxsbyIpCiAgICBib3hfZGVsCiAgICBwb3AKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzcKICAgIC8vIHNlbGYuYm94X2MudmFsdWUgPSBhcmM0LlN0cmluZygiSGVsbG8iKQogICAgYnl0ZSAiXHgwMFx4MDVIZWxsbyIKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzgKICAgIC8vIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWzI6MTBdID09IGIiSGVsbG8iCiAgICBib3hfbGVuCiAgICBwb3AKICAgIGludCAyCiAgICBkaWcgMQogICAgPAogICAgc3dhcAogICAgZHVwCiAgICBpbnQgMgogICAgdW5jb3ZlciAzCiAgICBzZWxlY3QKICAgIHN3YXAKICAgIGludCAxMAogICAgZGlnIDEKICAgIDwKICAgIGludCAxMAogICAgc3dhcAogICAgc2VsZWN0CiAgICBkaWcgMQogICAgLQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYuYm94X2MgPSBCb3goYXJjNC5TdHJpbmcsIGtleT1iIkJPWF9DIikKICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozOAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbMjoxMF0gPT0gYiJIZWxsbyIKICAgIGNvdmVyIDIKICAgIGJveF9leHRyYWN0CiAgICBieXRlICJIZWxsbyIKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmFyYzRfYm94KCkgLT4gdm9pZDoKYXJjNF9ib3g6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0MC00MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYXJjNF9ib3goc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDIKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1iImQiKQogICAgYnl0ZSAweDY0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0MwogICAgLy8gYm94X2QudmFsdWUgPSBTdGF0aWNJbnRzKGFyYzQuVUludDgoMCksIGFyYzQuVUludDgoMSksIGFyYzQuVUludDgoMiksIGFyYzQuVUludDgoMykpCiAgICBieXRlIDB4MDAwMTAyMDMKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQyCiAgICAvLyBib3hfZCA9IEJveChTdGF0aWNJbnRzLCBrZXk9YiJkIikKICAgIGJ5dGUgMHg2NAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDUKICAgIC8vIGFzc2VydCBib3hfZC52YWx1ZVswXSA9PSAwCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gQm94IG11c3QgZXhpc3QKICAgIGV4dHJhY3QgMCAxCiAgICBieXRlIDB4MDAKICAgIGI9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0MgogICAgLy8gYm94X2QgPSBCb3goU3RhdGljSW50cywga2V5PWIiZCIpCiAgICBieXRlIDB4NjQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ2CiAgICAvLyBhc3NlcnQgYm94X2QudmFsdWVbMV0gPT0gMQogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIEJveCBtdXN0IGV4aXN0CiAgICBleHRyYWN0IDEgMQogICAgYnl0ZSAweDAxCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDIKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1iImQiKQogICAgYnl0ZSAweDY0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0NwogICAgLy8gYXNzZXJ0IGJveF9kLnZhbHVlWzJdID09IDIKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBCb3ggbXVzdCBleGlzdAogICAgZXh0cmFjdCAyIDEKICAgIGJ5dGUgMHgwMgogICAgYj09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQyCiAgICAvLyBib3hfZCA9IEJveChTdGF0aWNJbnRzLCBrZXk9YiJkIikKICAgIGJ5dGUgMHg2NAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDgKICAgIC8vIGFzc2VydCBib3hfZC52YWx1ZVszXSA9PSAzCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gQm94IG11c3QgZXhpc3QKICAgIGV4dHJhY3QgMyAxCiAgICBieXRlIDB4MDMKICAgIGI9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfYmxvYigpIC0+IHZvaWQ6CmJveF9ibG9iOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTAtNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9ibG9iKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU0CiAgICAvLyBhcHBfYWRkcmVzcyA9IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MuYnl0ZXMKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MwogICAgLy8gc2VuZGVyX2J5dGVzID0gVHhuLnNlbmRlci5ieXRlcwogICAgdHhuIFNlbmRlcgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTIKICAgIC8vIGJveF9ibG9iID0gQm94UmVmKGtleT0iYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTUKICAgIC8vIGFzc2VydCBib3hfYmxvYi5jcmVhdGUoc2l6ZT04MDAwKQogICAgaW50IDgwMDAKICAgIGJveF9jcmVhdGUKICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTIKICAgIC8vIGJveF9ibG9iID0gQm94UmVmKGtleT0iYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTYKICAgIC8vIGJveF9ibG9iLnJlcGxhY2UoMCwgc2VuZGVyX2J5dGVzKQogICAgaW50IDAKICAgIGRpZyAyCiAgICBib3hfcmVwbGFjZQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTIKICAgIC8vIGJveF9ibG9iID0gQm94UmVmKGtleT0iYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTcKICAgIC8vIGJveF9ibG9iLnNwbGljZSgwLCAwLCBhcHBfYWRkcmVzcykKICAgIGludCAwCiAgICBkdXAKICAgIGRpZyA0CiAgICBib3hfc3BsaWNlCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MgogICAgLy8gYm94X2Jsb2IgPSBCb3hSZWYoa2V5PSJibG9iIikKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1OAogICAgLy8gZmlyc3RfNjQgPSBib3hfYmxvYi5leHRyYWN0KDAsIDMyICogMikKICAgIGludCAwCiAgICBpbnQgNjQKICAgIGJveF9leHRyYWN0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1OQogICAgLy8gYXNzZXJ0IGZpcnN0XzY0ID09IGFwcF9hZGRyZXNzICsgc2VuZGVyX2J5dGVzCiAgICBkaWcgMgogICAgZGlnIDIKICAgIGNvbmNhdAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTIKICAgIC8vIGJveF9ibG9iID0gQm94UmVmKGtleT0iYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjAKICAgIC8vIGFzc2VydCBib3hfYmxvYi5kZWxldGUoKQogICAgYm94X2RlbAogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MgogICAgLy8gYm94X2Jsb2IgPSBCb3hSZWYoa2V5PSJibG9iIikKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo2MgogICAgLy8gdmFsdWUsIGV4aXN0cyA9IGJveF9ibG9iLm1heWJlKCkKICAgIGJveF9nZXQKICAgIGJ1cnkgMQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjMKICAgIC8vIGFzc2VydCBub3QgZXhpc3RzCiAgICAhCiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBib3hfYmxvYiA9IEJveFJlZihrZXk9ImJsb2IiKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY0CiAgICAvLyBhc3NlcnQgYm94X2Jsb2IuZ2V0KGRlZmF1bHQ9c2VuZGVyX2J5dGVzKSA9PSBzZW5kZXJfYnl0ZXMKICAgIGJveF9nZXQKICAgIGRpZyAyCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo2NQogICAgLy8gYm94X2Jsb2IucHV0KHNlbmRlcl9ieXRlcyArIGFwcF9hZGRyZXNzKQogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1MgogICAgLy8gYm94X2Jsb2IgPSBCb3hSZWYoa2V5PSJibG9iIikKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo2NQogICAgLy8gYm94X2Jsb2IucHV0KHNlbmRlcl9ieXRlcyArIGFwcF9hZGRyZXNzKQogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTIKICAgIC8vIGJveF9ibG9iID0gQm94UmVmKGtleT0iYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjYKICAgIC8vIGFzc2VydCBib3hfYmxvYiwgIkJsb2IgZXhpc3RzIgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICBhc3NlcnQgLy8gQmxvYiBleGlzdHMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBib3hfYmxvYiA9IEJveFJlZihrZXk9ImJsb2IiKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBhc3NlcnQgYm94X2Jsb2IubGVuZ3RoID09IDY0CiAgICBib3hfbGVuCiAgICBhc3NlcnQgLy8gYm94IGV4aXN0cwogICAgaW50IDY0CiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX3Rlc3QoKSAtPiB2b2lkOgpib3hfbWFwX3Rlc3Q6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF90ZXN0KHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjcxCiAgICAvLyBrZXlfMCA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyBzZWxmLmJveF9tYXBba2V5XzBdID0gdmFsdWUKICAgIGl0b2IKICAgIGR1cAogICAgYm94X2RlbAogICAgcG9wCiAgICBkdXAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjczCiAgICAvLyB2YWx1ZSA9IFN0cmluZygiSG1tbW1tIikKICAgIGJ5dGUgIkhtbW1tbSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyBzZWxmLmJveF9tYXBba2V5XzBdID0gdmFsdWUKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfbWFwW2tleV8wXS5ieXRlcy5sZW5ndGggPT0gdmFsdWUuYnl0ZXMubGVuZ3RoCiAgICBkdXAKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBib3ggZXhpc3RzCiAgICBpbnQgNgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzYKICAgIC8vIGFzc2VydCBzZWxmLmJveF9tYXAubGVuZ3RoKGtleV8wKSA9PSB2YWx1ZS5ieXRlcy5sZW5ndGgKICAgIGR1cAogICAgYm94X2xlbgogICAgYXNzZXJ0IC8vIGJveCBleGlzdHMKICAgIGludCA2CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3MgogICAgLy8ga2V5XzEgPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3OAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X21hcC5nZXQoa2V5XzEsIGRlZmF1bHQ9U3RyaW5nKCJkZWZhdWx0IikpID09IFN0cmluZygiZGVmYXVsdCIpCiAgICBpdG9iCiAgICBkdXAKICAgIGJveF9nZXQKICAgIGJ5dGUgImRlZmF1bHQiCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGJ5dGUgImRlZmF1bHQiCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3OQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IHNlbGYuYm94X21hcC5tYXliZShrZXlfMSkKICAgIGJveF9nZXQKICAgIGJ1cnkgMQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODAKICAgIC8vIGFzc2VydCBub3QgZXhpc3RzCiAgICAhCiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzLTgxCiAgICAvLyAgICAgc2VsZi5ib3hfbWFwID0gQm94TWFwKFVJbnQ2NCwgU3RyaW5nLCBrZXlfcHJlZml4PSIiKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzZXRfYm94ZXMoc2VsZiwgYTogVUludDY0LCBiOiBCeXRlcywgYzogYXJjNC5TdHJpbmcpIC0+IE5vbmU6CiAgICAvLyAgICAgc2VsZi5ib3hfYS52YWx1ZSA9IGEKICAgIC8vICAgICBzZWxmLmJveF9iLnZhbHVlID0gYgogICAgLy8gICAgIHNlbGYuYm94X2MudmFsdWUgPSBjCiAgICAvLyAKICAgIC8vICAgICBzZWxmLmJveF9hLnZhbHVlICs9IDMKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgcmVhZF9ib3hlcyhzZWxmKSAtPiB0dXBsZVtVSW50NjQsIEJ5dGVzLCBhcmM0LlN0cmluZ106CiAgICAvLyAgICAgcmV0dXJuIHNlbGYuYm94X2EudmFsdWUsIHNlbGYuYm94X2IudmFsdWUsIHNlbGYuYm94X2MudmFsdWUKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94ZXNfZXhpc3Qoc2VsZikgLT4gdHVwbGVbYm9vbCwgYm9vbCwgYm9vbF06CiAgICAvLyAgICAgcmV0dXJuIGJvb2woc2VsZi5ib3hfYSksIGJvb2woc2VsZi5ib3hfYiksIGJvb2woc2VsZi5ib3hfYykKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgc2xpY2VfYm94KHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAgYm94XzAgPSBCb3goQnl0ZXMsIGtleT1iIjAiKQogICAgLy8gICAgIGJveF8wLnZhbHVlID0gQnl0ZXMoYiJUZXN0aW5nIHRlc3RpbmcgMTIzIikKICAgIC8vICAgICBhc3NlcnQgYm94XzAudmFsdWVbMDo3XSA9PSBiIlRlc3RpbmciCiAgICAvLyAKICAgIC8vICAgICBzZWxmLmJveF9jLnZhbHVlID0gYXJjNC5TdHJpbmcoIkhlbGxvIikKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1syOjEwXSA9PSBiIkhlbGxvIgogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBhcmM0X2JveChzZWxmKSAtPiBOb25lOgogICAgLy8gICAgIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1iImQiKQogICAgLy8gICAgIGJveF9kLnZhbHVlID0gU3RhdGljSW50cyhhcmM0LlVJbnQ4KDApLCBhcmM0LlVJbnQ4KDEpLCBhcmM0LlVJbnQ4KDIpLCBhcmM0LlVJbnQ4KDMpKQogICAgLy8gCiAgICAvLyAgICAgYXNzZXJ0IGJveF9kLnZhbHVlWzBdID09IDAKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbMV0gPT0gMQogICAgLy8gICAgIGFzc2VydCBib3hfZC52YWx1ZVsyXSA9PSAyCiAgICAvLyAgICAgYXNzZXJ0IGJveF9kLnZhbHVlWzNdID09IDMKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X2Jsb2Ioc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBib3hfYmxvYiA9IEJveFJlZihrZXk9ImJsb2IiKQogICAgLy8gICAgIHNlbmRlcl9ieXRlcyA9IFR4bi5zZW5kZXIuYnl0ZXMKICAgIC8vICAgICBhcHBfYWRkcmVzcyA9IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MuYnl0ZXMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuY3JlYXRlKHNpemU9ODAwMCkKICAgIC8vICAgICBib3hfYmxvYi5yZXBsYWNlKDAsIHNlbmRlcl9ieXRlcykKICAgIC8vICAgICBib3hfYmxvYi5zcGxpY2UoMCwgMCwgYXBwX2FkZHJlc3MpCiAgICAvLyAgICAgZmlyc3RfNjQgPSBib3hfYmxvYi5leHRyYWN0KDAsIDMyICogMikKICAgIC8vICAgICBhc3NlcnQgZmlyc3RfNjQgPT0gYXBwX2FkZHJlc3MgKyBzZW5kZXJfYnl0ZXMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuZGVsZXRlKCkKICAgIC8vIAogICAgLy8gICAgIHZhbHVlLCBleGlzdHMgPSBib3hfYmxvYi5tYXliZSgpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBleGlzdHMKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IuZ2V0KGRlZmF1bHQ9c2VuZGVyX2J5dGVzKSA9PSBzZW5kZXJfYnl0ZXMKICAgIC8vICAgICBib3hfYmxvYi5wdXQoc2VuZGVyX2J5dGVzICsgYXBwX2FkZHJlc3MpCiAgICAvLyAgICAgYXNzZXJ0IGJveF9ibG9iLCAiQmxvYiBleGlzdHMiCiAgICAvLyAgICAgYXNzZXJ0IGJveF9ibG9iLmxlbmd0aCA9PSA2NAogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX3Rlc3Qoc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBrZXlfMCA9IFVJbnQ2NCgwKQogICAgLy8gICAgIGtleV8xID0gVUludDY0KDEpCiAgICAvLyAgICAgdmFsdWUgPSBTdHJpbmcoIkhtbW1tbSIpCiAgICAvLyAgICAgc2VsZi5ib3hfbWFwW2tleV8wXSA9IHZhbHVlCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X21hcFtrZXlfMF0uYnl0ZXMubGVuZ3RoID09IHZhbHVlLmJ5dGVzLmxlbmd0aAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAubGVuZ3RoKGtleV8wKSA9PSB2YWx1ZS5ieXRlcy5sZW5ndGgKICAgIC8vIAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAuZ2V0KGtleV8xLCBkZWZhdWx0PVN0cmluZygiZGVmYXVsdCIpKSA9PSBTdHJpbmcoImRlZmF1bHQiKQogICAgLy8gICAgIHZhbHVlLCBleGlzdHMgPSBzZWxmLmJveF9tYXAubWF5YmUoa2V5XzEpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBleGlzdHMKICAgIC8vICAgICBhc3NlcnQga2V5XzAgaW4gc2VsZi5ib3hfbWFwCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBhc3NlcnQga2V5XzAgaW4gc2VsZi5ib3hfbWFwCiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfc2V0KGtleTogdWludDY0LCB2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CmJveF9tYXBfc2V0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODMtODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfc2V0KHNlbGYsIGtleTogVUludDY0LCB2YWx1ZTogU3RyaW5nKSAtPiBOb25lOgogICAgcHJvdG8gMiAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4NQogICAgLy8gc2VsZi5ib3hfbWFwW2tleV0gPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0yCiAgICBpdG9iCiAgICBkdXAKICAgIGJveF9kZWwKICAgIHBvcAogICAgZnJhbWVfZGlnIC0xCiAgICBib3hfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX2dldChrZXk6IHVpbnQ2NCkgLT4gYnl0ZXM6CmJveF9tYXBfZ2V0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODctODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfZ2V0KHNlbGYsIGtleTogVUludDY0KSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojg5CiAgICAvLyByZXR1cm4gc2VsZi5ib3hfbWFwW2tleV0KICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIEJveCBtdXN0IGV4aXN0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX2V4aXN0cyhrZXk6IHVpbnQ2NCkgLT4gdWludDY0Ogpib3hfbWFwX2V4aXN0czoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjkxLTkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX2V4aXN0cyhzZWxmLCBrZXk6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIHByb3RvIDEgMQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTMtOTMKICAgIC8vICAgICBzZWxmLmJveF9tYXAgPSBCb3hNYXAoVUludDY0LCBTdHJpbmcsIGtleV9wcmVmaXg9IiIpCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHNldF9ib3hlcyhzZWxmLCBhOiBVSW50NjQsIGI6IEJ5dGVzLCBjOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIC8vICAgICBzZWxmLmJveF9hLnZhbHVlID0gYQogICAgLy8gICAgIHNlbGYuYm94X2IudmFsdWUgPSBiCiAgICAvLyAgICAgc2VsZi5ib3hfYy52YWx1ZSA9IGMKICAgIC8vIAogICAgLy8gICAgIHNlbGYuYm94X2EudmFsdWUgKz0gMwogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiByZWFkX2JveGVzKHNlbGYpIC0+IHR1cGxlW1VJbnQ2NCwgQnl0ZXMsIGFyYzQuU3RyaW5nXToKICAgIC8vICAgICByZXR1cm4gc2VsZi5ib3hfYS52YWx1ZSwgc2VsZi5ib3hfYi52YWx1ZSwgc2VsZi5ib3hfYy52YWx1ZQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hlc19leGlzdChzZWxmKSAtPiB0dXBsZVtib29sLCBib29sLCBib29sXToKICAgIC8vICAgICByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzbGljZV9ib3goc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBib3hfMCA9IEJveChCeXRlcywga2V5PWIiMCIpCiAgICAvLyAgICAgYm94XzAudmFsdWUgPSBCeXRlcyhiIlRlc3RpbmcgdGVzdGluZyAxMjMiKQogICAgLy8gICAgIGFzc2VydCBib3hfMC52YWx1ZVswOjddID09IGIiVGVzdGluZyIKICAgIC8vIAogICAgLy8gICAgIHNlbGYuYm94X2MudmFsdWUgPSBhcmM0LlN0cmluZygiSGVsbG8iKQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWzI6MTBdID09IGIiSGVsbG8iCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGFyYzRfYm94KHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAgYm94X2QgPSBCb3goU3RhdGljSW50cywga2V5PWIiZCIpCiAgICAvLyAgICAgYm94X2QudmFsdWUgPSBTdGF0aWNJbnRzKGFyYzQuVUludDgoMCksIGFyYzQuVUludDgoMSksIGFyYzQuVUludDgoMiksIGFyYzQuVUludDgoMykpCiAgICAvLyAKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbMF0gPT0gMAogICAgLy8gICAgIGFzc2VydCBib3hfZC52YWx1ZVsxXSA9PSAxCiAgICAvLyAgICAgYXNzZXJ0IGJveF9kLnZhbHVlWzJdID09IDIKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbM10gPT0gMwogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfYmxvYihzZWxmKSAtPiBOb25lOgogICAgLy8gICAgIGJveF9ibG9iID0gQm94UmVmKGtleT0iYmxvYiIpCiAgICAvLyAgICAgc2VuZGVyX2J5dGVzID0gVHhuLnNlbmRlci5ieXRlcwogICAgLy8gICAgIGFwcF9hZGRyZXNzID0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcy5ieXRlcwogICAgLy8gICAgIGFzc2VydCBib3hfYmxvYi5jcmVhdGUoc2l6ZT04MDAwKQogICAgLy8gICAgIGJveF9ibG9iLnJlcGxhY2UoMCwgc2VuZGVyX2J5dGVzKQogICAgLy8gICAgIGJveF9ibG9iLnNwbGljZSgwLCAwLCBhcHBfYWRkcmVzcykKICAgIC8vICAgICBmaXJzdF82NCA9IGJveF9ibG9iLmV4dHJhY3QoMCwgMzIgKiAyKQogICAgLy8gICAgIGFzc2VydCBmaXJzdF82NCA9PSBhcHBfYWRkcmVzcyArIHNlbmRlcl9ieXRlcwogICAgLy8gICAgIGFzc2VydCBib3hfYmxvYi5kZWxldGUoKQogICAgLy8gCiAgICAvLyAgICAgdmFsdWUsIGV4aXN0cyA9IGJveF9ibG9iLm1heWJlKCkKICAgIC8vICAgICBhc3NlcnQgbm90IGV4aXN0cwogICAgLy8gICAgIGFzc2VydCBib3hfYmxvYi5nZXQoZGVmYXVsdD1zZW5kZXJfYnl0ZXMpID09IHNlbmRlcl9ieXRlcwogICAgLy8gICAgIGJveF9ibG9iLnB1dChzZW5kZXJfYnl0ZXMgKyBhcHBfYWRkcmVzcykKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IsICJCbG9iIGV4aXN0cyIKICAgIC8vICAgICBhc3NlcnQgYm94X2Jsb2IubGVuZ3RoID09IDY0CiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfdGVzdChzZWxmKSAtPiBOb25lOgogICAgLy8gICAgIGtleV8wID0gVUludDY0KDApCiAgICAvLyAgICAga2V5XzEgPSBVSW50NjQoMSkKICAgIC8vICAgICB2YWx1ZSA9IFN0cmluZygiSG1tbW1tIikKICAgIC8vICAgICBzZWxmLmJveF9tYXBba2V5XzBdID0gdmFsdWUKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfbWFwW2tleV8wXS5ieXRlcy5sZW5ndGggPT0gdmFsdWUuYnl0ZXMubGVuZ3RoCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X21hcC5sZW5ndGgoa2V5XzApID09IHZhbHVlLmJ5dGVzLmxlbmd0aAogICAgLy8gCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X21hcC5nZXQoa2V5XzEsIGRlZmF1bHQ9U3RyaW5nKCJkZWZhdWx0IikpID09IFN0cmluZygiZGVmYXVsdCIpCiAgICAvLyAgICAgdmFsdWUsIGV4aXN0cyA9IHNlbGYuYm94X21hcC5tYXliZShrZXlfMSkKICAgIC8vICAgICBhc3NlcnQgbm90IGV4aXN0cwogICAgLy8gICAgIGFzc2VydCBrZXlfMCBpbiBzZWxmLmJveF9tYXAKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9zZXQoc2VsZiwga2V5OiBVSW50NjQsIHZhbHVlOiBTdHJpbmcpIC0+IE5vbmU6CiAgICAvLyAgICAgc2VsZi5ib3hfbWFwW2tleV0gPSB2YWx1ZQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX2dldChzZWxmLCBrZXk6IFVJbnQ2NCkgLT4gU3RyaW5nOgogICAgLy8gICAgIHJldHVybiBzZWxmLmJveF9tYXBba2V5XQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX2V4aXN0cyhzZWxmLCBrZXk6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIC8vICAgICByZXR1cm4ga2V5IGluIHNlbGYuYm94X21hcAogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjkzCiAgICAvLyByZXR1cm4ga2V5IGluIHNlbGYuYm94X21hcAogICAgcmV0c3ViCg==", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/examples/box_storage/out/BoxContract.destructured.ir b/examples/box_storage/out/BoxContract.destructured.ir index ec74b8aec..300a63b83 100644 --- a/examples/box_storage/out/BoxContract.destructured.ir +++ b/examples/box_storage/out/BoxContract.destructured.ir @@ -145,83 +145,81 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_del_res%0#0: bool = (box_del "0") - (box_put "0" "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "0") - (assert box_exists%0#0) // Box must exist - let tmp%1#0: uint64 = (select box_len%0#0 0u box_len%0#0) - let tmp%2#0: bool = (< 7u box_len%0#0) - let tmp%3#0: uint64 = (select box_len%0#0 7u tmp%2#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%1#0) - let tmp%7#0: bytes = (box_extract "0" tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let tmp%9#0: bool = (< 2u box_len%1#0) - let tmp%10#0: uint64 = (select box_len%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u box_len%1#0) - let tmp%12#0: uint64 = (select box_len%1#0 10u tmp%11#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%10#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let box_del_res%0#0: bool = (box_del 0x30) + (box_put 0x30 "Testing testing 123") + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len 0x30) + let tmp%3#0: uint64 = (select tmp%0#0 0u tmp%0#0) + let tmp%4#0: bool = (< 7u tmp%0#0) + let tmp%5#0: uint64 = (select tmp%0#0 7u tmp%4#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%3#0) + let tmp%9#0: bytes = (box_extract 0x30 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let tmp%13#0: bool = (< 2u tmp%11#0) + let tmp%14#0: uint64 = (select tmp%11#0 2u tmp%13#0) + let tmp%15#0: bool = (< 10u tmp%11#0) + let tmp%16#0: uint64 = (select tmp%11#0 10u tmp%15#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%14#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: block@0: // L40 - (box_put "d" 0x00010203) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "d") + (box_put 0x64 0x00010203) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get 0x64) (assert box_exists%0#0) // Box must exist let reinterpret_biguint%0#0: biguint = ((extract 0 1) box_value%0#0) let tmp%0#0: bool = (b== reinterpret_biguint%0#0 0x00) (assert tmp%0#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "d") + let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get 0x64) (assert box_exists%1#0) // Box must exist let reinterpret_biguint%2#0: biguint = ((extract 1 1) box_value%1#0) let tmp%1#0: bool = (b== reinterpret_biguint%2#0 0x01) (assert tmp%1#0) - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "d") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x64) (assert box_exists%2#0) // Box must exist let reinterpret_biguint%4#0: biguint = ((extract 2 1) box_value%2#0) let tmp%2#0: bool = (b== reinterpret_biguint%4#0 0x02) (assert tmp%2#0) - let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get "d") + let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get 0x64) (assert box_exists%3#0) // Box must exist let reinterpret_biguint%6#0: biguint = ((extract 3 1) box_value%3#0) let tmp%3#0: bool = (b== reinterpret_biguint%6#0 0x03) @@ -245,17 +243,17 @@ contract examples.box_storage.contract.BoxContract: let (value#0: bytes, exists#0: bool) = (box_get "blob") let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "blob") - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get "blob") + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put "blob" tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len "blob") - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len "blob") - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "blob") + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len "blob") + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return @@ -264,24 +262,24 @@ contract examples.box_storage.contract.BoxContract: let tmp%0#0: bytes = (itob 0u) let box_del_res%0#0: bool = (box_del tmp%0#0) (box_put tmp%0#0 "Hmmmmm") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) - (assert box_exists%0#0) // Box must exist - let tmp%3#0: bool = (== box_len%0#0 6u) - (assert tmp%3#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len tmp%0#0) - (assert box_exists%1#0) // Box must exist - let tmp%6#0: bool = (== box_len%1#0 6u) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob 1u) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get tmp%7#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%0#0) + (assert check%0#0) // box exists + let tmp%5#0: bool = (== value%0#0 6u) + (assert tmp%5#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%0#0) + (assert check%1#0) // box exists + let tmp%9#0: bool = (== value%1#0 6u) (assert tmp%9#0) - let (value#1: bytes, exists#0: bool) = (box_get tmp%7#0) - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len tmp%0#0) - (assert box_exists%4#0) + let tmp%10#0: bytes = (itob 1u) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%10#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let (value#1: bytes, exists#0: bool) = (box_get tmp%10#0) + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: diff --git a/examples/box_storage/out/BoxContract.ssa.ir b/examples/box_storage/out/BoxContract.ssa.ir index a09ce0f3d..d5aa48360 100644 --- a/examples/box_storage/out/BoxContract.ssa.ir +++ b/examples/box_storage/out/BoxContract.ssa.ir @@ -162,75 +162,73 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_0#0: bytes = "0" + let box_0#0: bytes = 0x30 let box_del_res%0#0: bool = (box_del box_0#0) (box_put box_0#0 "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len box_0#0) - (assert box_exists%0#0) // Box must exist - let awst_tmp%0#0: uint64 = box_len%0#0 - let tmp%0#0: bool = (< 0u awst_tmp%0#0) - let tmp%1#0: uint64 = (select awst_tmp%0#0 0u tmp%0#0) - let tmp%2#0: bool = (< 7u awst_tmp%0#0) - let tmp%3#0: uint64 = (select awst_tmp%0#0 7u tmp%2#0) - let tmp%4#0: bool = (< 0u awst_tmp%0#0) - let tmp%5#0: uint64 = (select awst_tmp%0#0 0u tmp%4#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%5#0) - let tmp%7#0: bytes = (box_extract box_0#0 tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let awst_tmp%1#0: uint64 = box_len%1#0 - let tmp%9#0: bool = (< 2u awst_tmp%1#0) - let tmp%10#0: uint64 = (select awst_tmp%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u awst_tmp%1#0) - let tmp%12#0: uint64 = (select awst_tmp%1#0 10u tmp%11#0) + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len box_0#0) + let awst_tmp%0#0: uint64 = tmp%0#0 + let tmp%2#0: bool = (< 0u awst_tmp%0#0) + let tmp%3#0: uint64 = (select awst_tmp%0#0 0u tmp%2#0) + let tmp%4#0: bool = (< 7u awst_tmp%0#0) + let tmp%5#0: uint64 = (select awst_tmp%0#0 7u tmp%4#0) + let tmp%6#0: bool = (< 0u awst_tmp%0#0) + let tmp%7#0: uint64 = (select awst_tmp%0#0 0u tmp%6#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%7#0) + let tmp%9#0: bytes = (box_extract box_0#0 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let awst_tmp%1#0: uint64 = tmp%11#0 let tmp%13#0: bool = (< 2u awst_tmp%1#0) let tmp%14#0: uint64 = (select awst_tmp%1#0 2u tmp%13#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%14#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let tmp%15#0: bool = (< 10u awst_tmp%1#0) + let tmp%16#0: uint64 = (select awst_tmp%1#0 10u tmp%15#0) + let tmp%17#0: bool = (< 2u awst_tmp%1#0) + let tmp%18#0: uint64 = (select awst_tmp%1#0 2u tmp%17#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%18#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: block@0: // L40 - let box_d#0: bytes = "d" + let box_d#0: bytes = 0x64 let array_data%0#0: bytes = 0x let array_data%0#1: bytes = (concat array_data%0#0 0x00) let array_data%0#2: bytes = (concat array_data%0#1 0x01) @@ -282,22 +280,22 @@ contract examples.box_storage.contract.BoxContract: (assert tmp%2#0) let tmp%3#0: bool = (box_del box_blob#0) (assert tmp%3#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get box_blob#0) - let value#0: bytes = box_value%0#0 - let exists#0: bool = box_exists%0#0 + let (tuple_assignment%0#0: bytes, tuple_assignment%1#0: bool) = (box_get box_blob#0) + let value#0: bytes = tuple_assignment%0#0 + let exists#0: bool = tuple_assignment%1#0 let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get box_blob#0) - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get box_blob#0) + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put box_blob#0 tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len box_blob#0) - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len box_blob#0) - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len box_blob#0) + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len box_blob#0) + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return @@ -307,63 +305,63 @@ contract examples.box_storage.contract.BoxContract: let key_1#0: uint64 = 1u let value#0: bytes = "Hmmmmm" let tmp%0#0: bytes = (itob key_0#0) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let box_del_res%0#0: bool = (box_del compound_key%0#0) - (box_put compound_key%0#0 value#0) - let tmp%1#0: bytes = (itob key_0#0) - let compound_key%1#0: bytes = (concat "" tmp%1#0) - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len compound_key%1#0) - (assert box_exists%0#0) // Box must exist - let tmp%2#0: uint64 = (len value#0) - let tmp%3#0: bool = (== box_len%0#0 tmp%2#0) - (assert tmp%3#0) - let tmp%4#0: bytes = (itob key_0#0) - let compound_key%2#0: bytes = (concat "" tmp%4#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len compound_key%2#0) - (assert box_exists%1#0) // Box must exist - let tmp%5#0: uint64 = (len value#0) - let tmp%6#0: bool = (== box_len%1#0 tmp%5#0) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob key_1#0) - let compound_key%3#0: bytes = (concat "" tmp%7#0) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get compound_key%3#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let tmp%1#0: bytes = (concat "" tmp%0#0) + let box_del_res%0#0: bool = (box_del tmp%1#0) + (box_put tmp%1#0 value#0) + let tmp%2#0: bytes = (itob key_0#0) + let tmp%3#0: bytes = (concat "" tmp%2#0) + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%3#0) + (assert check%0#0) // box exists + let tmp%4#0: uint64 = (len value#0) + let tmp%5#0: bool = (== value%0#0 tmp%4#0) + (assert tmp%5#0) + let tmp%6#0: bytes = (itob key_0#0) + let tmp%7#0: bytes = (concat "" tmp%6#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%7#0) + (assert check%1#0) // box exists + let tmp%8#0: uint64 = (len value#0) + let tmp%9#0: bool = (== value%1#0 tmp%8#0) (assert tmp%9#0) let tmp%10#0: bytes = (itob key_1#0) - let compound_key%4#0: bytes = (concat "" tmp%10#0) - let (box_value%1#0: bytes, box_exists%3#0: bool) = (box_get compound_key%4#0) - let value#1: bytes = box_value%1#0 - let exists#0: bool = box_exists%3#0 - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let tmp%12#0: bytes = (itob key_0#0) - let compound_key%5#0: bytes = (concat "" tmp%12#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len compound_key%5#0) - (assert box_exists%4#0) + let tmp%11#0: bytes = (concat "" tmp%10#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%11#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let tmp%14#0: bytes = (itob key_1#0) + let tmp%15#0: bytes = (concat "" tmp%14#0) + let (tuple_assignment%0#0: bytes, tuple_assignment%1#0: bool) = (box_get tmp%15#0) + let value#1: bytes = tuple_assignment%0#0 + let exists#0: bool = tuple_assignment%1#0 + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let tmp%17#0: bytes = (itob key_0#0) + let tmp%18#0: bytes = (concat "" tmp%17#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%18#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: block@0: // L83 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let box_del_res%0#0: bool = (box_del compound_key%0#0) - (box_put compound_key%0#0 value#0) + let tmp%1#0: bytes = (concat "" tmp%0#0) + let box_del_res%0#0: bool = (box_del tmp%1#0) + (box_put tmp%1#0 value#0) return subroutine examples.box_storage.contract.BoxContract.box_map_get(key: uint64) -> bytes: block@0: // L87 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get compound_key%0#0) + let tmp%1#0: bytes = (concat "" tmp%0#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get tmp%1#0) (assert box_exists%0#0) // Box must exist return box_value%0#0 subroutine examples.box_storage.contract.BoxContract.box_map_exists(key: uint64) -> bool: block@0: // L91 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len compound_key%0#0) + let tmp%1#0: bytes = (concat "" tmp%0#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%1#0) return box_exists%0#0 program clear-state: diff --git a/examples/box_storage/out/BoxContract.ssa.opt_pass_1.ir b/examples/box_storage/out/BoxContract.ssa.opt_pass_1.ir index 47c0b8163..86ee8445b 100644 --- a/examples/box_storage/out/BoxContract.ssa.opt_pass_1.ir +++ b/examples/box_storage/out/BoxContract.ssa.opt_pass_1.ir @@ -149,62 +149,60 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_del_res%0#0: bool = (box_del "0") - (box_put "0" "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "0") - (assert box_exists%0#0) // Box must exist - let tmp%1#0: uint64 = (select box_len%0#0 0u box_len%0#0) - let tmp%2#0: bool = (< 7u box_len%0#0) - let tmp%3#0: uint64 = (select box_len%0#0 7u tmp%2#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%1#0) - let tmp%7#0: bytes = (box_extract "0" tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let tmp%9#0: bool = (< 2u box_len%1#0) - let tmp%10#0: uint64 = (select box_len%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u box_len%1#0) - let tmp%12#0: uint64 = (select box_len%1#0 10u tmp%11#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%10#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let box_del_res%0#0: bool = (box_del 0x30) + (box_put 0x30 "Testing testing 123") + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len 0x30) + let tmp%3#0: uint64 = (select tmp%0#0 0u tmp%0#0) + let tmp%4#0: bool = (< 7u tmp%0#0) + let tmp%5#0: uint64 = (select tmp%0#0 7u tmp%4#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%3#0) + let tmp%9#0: bytes = (box_extract 0x30 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let tmp%13#0: bool = (< 2u tmp%11#0) + let tmp%14#0: uint64 = (select tmp%11#0 2u tmp%13#0) + let tmp%15#0: bool = (< 10u tmp%11#0) + let tmp%16#0: uint64 = (select tmp%11#0 10u tmp%15#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%14#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: @@ -213,26 +211,26 @@ contract examples.box_storage.contract.BoxContract: let array_data%0#2: bytes = (concat array_data%0#1 0x01) let array_data%0#3: bytes = (concat array_data%0#2 0x02) let array_data%0#4: bytes = (concat array_data%0#3 0x03) - (box_put "d" array_data%0#4) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "d") + (box_put 0x64 array_data%0#4) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get 0x64) (assert box_exists%0#0) // Box must exist let item_index%0#0: uint64 = 0u let reinterpret_biguint%0#0: biguint = (extract3 box_value%0#0 item_index%0#0 1u) let tmp%0#0: bool = (b== reinterpret_biguint%0#0 0x00) (assert tmp%0#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "d") + let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get 0x64) (assert box_exists%1#0) // Box must exist let item_index%1#0: uint64 = 1u let reinterpret_biguint%2#0: biguint = (extract3 box_value%1#0 item_index%1#0 1u) let tmp%1#0: bool = (b== reinterpret_biguint%2#0 0x01) (assert tmp%1#0) - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "d") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x64) (assert box_exists%2#0) // Box must exist let item_index%2#0: uint64 = 2u let reinterpret_biguint%4#0: biguint = (extract3 box_value%2#0 item_index%2#0 1u) let tmp%2#0: bool = (b== reinterpret_biguint%4#0 0x02) (assert tmp%2#0) - let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get "d") + let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get 0x64) (assert box_exists%3#0) // Box must exist let item_index%3#0: uint64 = 3u let reinterpret_biguint%6#0: biguint = (extract3 box_value%3#0 item_index%3#0 1u) @@ -257,17 +255,17 @@ contract examples.box_storage.contract.BoxContract: let (value#0: bytes, exists#0: bool) = (box_get "blob") let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "blob") - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get "blob") + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put "blob" tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len "blob") - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len "blob") - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "blob") + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len "blob") + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return @@ -276,49 +274,49 @@ contract examples.box_storage.contract.BoxContract: let tmp%0#0: bytes = (itob 0u) let box_del_res%0#0: bool = (box_del tmp%0#0) (box_put tmp%0#0 "Hmmmmm") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) - (assert box_exists%0#0) // Box must exist - let tmp%2#0: uint64 = 6u - let tmp%3#0: bool = (== box_len%0#0 tmp%2#0) - (assert tmp%3#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len tmp%0#0) - (assert box_exists%1#0) // Box must exist - let tmp%5#0: uint64 = 6u - let tmp%6#0: bool = (== box_len%1#0 tmp%5#0) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob 1u) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get tmp%7#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%0#0) + (assert check%0#0) // box exists + let tmp%4#0: uint64 = 6u + let tmp%5#0: bool = (== value%0#0 tmp%4#0) + (assert tmp%5#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%0#0) + (assert check%1#0) // box exists + let tmp%8#0: uint64 = 6u + let tmp%9#0: bool = (== value%1#0 tmp%8#0) (assert tmp%9#0) - let (value#1: bytes, exists#0: bool) = (box_get tmp%7#0) - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len tmp%0#0) - (assert box_exists%4#0) + let tmp%10#0: bytes = (itob 1u) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%10#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let (value#1: bytes, exists#0: bool) = (box_get tmp%10#0) + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: block@0: // L83 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = tmp%0#0 - let box_del_res%0#0: bool = (box_del compound_key%0#0) - (box_put compound_key%0#0 value#0) + let tmp%1#0: bytes = tmp%0#0 + let box_del_res%0#0: bool = (box_del tmp%1#0) + (box_put tmp%1#0 value#0) return subroutine examples.box_storage.contract.BoxContract.box_map_get(key: uint64) -> bytes: block@0: // L87 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = tmp%0#0 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get compound_key%0#0) + let tmp%1#0: bytes = tmp%0#0 + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get tmp%1#0) (assert box_exists%0#0) // Box must exist return box_value%0#0 subroutine examples.box_storage.contract.BoxContract.box_map_exists(key: uint64) -> bool: block@0: // L91 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = tmp%0#0 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len compound_key%0#0) + let tmp%1#0: bytes = tmp%0#0 + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%1#0) return box_exists%0#0 program clear-state: diff --git a/examples/box_storage/out/BoxContract.ssa.opt_pass_2.ir b/examples/box_storage/out/BoxContract.ssa.opt_pass_2.ir index a6910692e..b25b77d1a 100644 --- a/examples/box_storage/out/BoxContract.ssa.opt_pass_2.ir +++ b/examples/box_storage/out/BoxContract.ssa.opt_pass_2.ir @@ -145,62 +145,60 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_del_res%0#0: bool = (box_del "0") - (box_put "0" "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "0") - (assert box_exists%0#0) // Box must exist - let tmp%1#0: uint64 = (select box_len%0#0 0u box_len%0#0) - let tmp%2#0: bool = (< 7u box_len%0#0) - let tmp%3#0: uint64 = (select box_len%0#0 7u tmp%2#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%1#0) - let tmp%7#0: bytes = (box_extract "0" tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let tmp%9#0: bool = (< 2u box_len%1#0) - let tmp%10#0: uint64 = (select box_len%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u box_len%1#0) - let tmp%12#0: uint64 = (select box_len%1#0 10u tmp%11#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%10#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let box_del_res%0#0: bool = (box_del 0x30) + (box_put 0x30 "Testing testing 123") + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len 0x30) + let tmp%3#0: uint64 = (select tmp%0#0 0u tmp%0#0) + let tmp%4#0: bool = (< 7u tmp%0#0) + let tmp%5#0: uint64 = (select tmp%0#0 7u tmp%4#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%3#0) + let tmp%9#0: bytes = (box_extract 0x30 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let tmp%13#0: bool = (< 2u tmp%11#0) + let tmp%14#0: uint64 = (select tmp%11#0 2u tmp%13#0) + let tmp%15#0: bool = (< 10u tmp%11#0) + let tmp%16#0: uint64 = (select tmp%11#0 10u tmp%15#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%14#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: @@ -208,23 +206,23 @@ contract examples.box_storage.contract.BoxContract: let array_data%0#2: bytes = 0x0001 let array_data%0#3: bytes = (concat array_data%0#2 0x02) let array_data%0#4: bytes = (concat array_data%0#3 0x03) - (box_put "d" array_data%0#4) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "d") + (box_put 0x64 array_data%0#4) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get 0x64) (assert box_exists%0#0) // Box must exist let reinterpret_biguint%0#0: biguint = ((extract 0 1) box_value%0#0) let tmp%0#0: bool = (b== reinterpret_biguint%0#0 0x00) (assert tmp%0#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "d") + let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get 0x64) (assert box_exists%1#0) // Box must exist let reinterpret_biguint%2#0: biguint = ((extract 1 1) box_value%1#0) let tmp%1#0: bool = (b== reinterpret_biguint%2#0 0x01) (assert tmp%1#0) - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "d") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x64) (assert box_exists%2#0) // Box must exist let reinterpret_biguint%4#0: biguint = ((extract 2 1) box_value%2#0) let tmp%2#0: bool = (b== reinterpret_biguint%4#0 0x02) (assert tmp%2#0) - let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get "d") + let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get 0x64) (assert box_exists%3#0) // Box must exist let reinterpret_biguint%6#0: biguint = ((extract 3 1) box_value%3#0) let tmp%3#0: bool = (b== reinterpret_biguint%6#0 0x03) @@ -248,17 +246,17 @@ contract examples.box_storage.contract.BoxContract: let (value#0: bytes, exists#0: bool) = (box_get "blob") let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "blob") - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get "blob") + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put "blob" tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len "blob") - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len "blob") - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "blob") + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len "blob") + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return @@ -267,24 +265,24 @@ contract examples.box_storage.contract.BoxContract: let tmp%0#0: bytes = (itob 0u) let box_del_res%0#0: bool = (box_del tmp%0#0) (box_put tmp%0#0 "Hmmmmm") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) - (assert box_exists%0#0) // Box must exist - let tmp%3#0: bool = (== box_len%0#0 6u) - (assert tmp%3#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len tmp%0#0) - (assert box_exists%1#0) // Box must exist - let tmp%6#0: bool = (== box_len%1#0 6u) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob 1u) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get tmp%7#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%0#0) + (assert check%0#0) // box exists + let tmp%5#0: bool = (== value%0#0 6u) + (assert tmp%5#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%0#0) + (assert check%1#0) // box exists + let tmp%9#0: bool = (== value%1#0 6u) (assert tmp%9#0) - let (value#1: bytes, exists#0: bool) = (box_get tmp%7#0) - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len tmp%0#0) - (assert box_exists%4#0) + let tmp%10#0: bytes = (itob 1u) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%10#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let (value#1: bytes, exists#0: bool) = (box_get tmp%10#0) + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: diff --git a/examples/box_storage/out/BoxContract.ssa.opt_pass_3.ir b/examples/box_storage/out/BoxContract.ssa.opt_pass_3.ir index 0c078bbac..185cb73db 100644 --- a/examples/box_storage/out/BoxContract.ssa.opt_pass_3.ir +++ b/examples/box_storage/out/BoxContract.ssa.opt_pass_3.ir @@ -145,85 +145,83 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_del_res%0#0: bool = (box_del "0") - (box_put "0" "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "0") - (assert box_exists%0#0) // Box must exist - let tmp%1#0: uint64 = (select box_len%0#0 0u box_len%0#0) - let tmp%2#0: bool = (< 7u box_len%0#0) - let tmp%3#0: uint64 = (select box_len%0#0 7u tmp%2#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%1#0) - let tmp%7#0: bytes = (box_extract "0" tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let tmp%9#0: bool = (< 2u box_len%1#0) - let tmp%10#0: uint64 = (select box_len%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u box_len%1#0) - let tmp%12#0: uint64 = (select box_len%1#0 10u tmp%11#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%10#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let box_del_res%0#0: bool = (box_del 0x30) + (box_put 0x30 "Testing testing 123") + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len 0x30) + let tmp%3#0: uint64 = (select tmp%0#0 0u tmp%0#0) + let tmp%4#0: bool = (< 7u tmp%0#0) + let tmp%5#0: uint64 = (select tmp%0#0 7u tmp%4#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%3#0) + let tmp%9#0: bytes = (box_extract 0x30 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let tmp%13#0: bool = (< 2u tmp%11#0) + let tmp%14#0: uint64 = (select tmp%11#0 2u tmp%13#0) + let tmp%15#0: bool = (< 10u tmp%11#0) + let tmp%16#0: uint64 = (select tmp%11#0 10u tmp%15#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%14#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: block@0: // L40 let array_data%0#3: bytes = 0x000102 let array_data%0#4: bytes = (concat array_data%0#3 0x03) - (box_put "d" array_data%0#4) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "d") + (box_put 0x64 array_data%0#4) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get 0x64) (assert box_exists%0#0) // Box must exist let reinterpret_biguint%0#0: biguint = ((extract 0 1) box_value%0#0) let tmp%0#0: bool = (b== reinterpret_biguint%0#0 0x00) (assert tmp%0#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "d") + let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get 0x64) (assert box_exists%1#0) // Box must exist let reinterpret_biguint%2#0: biguint = ((extract 1 1) box_value%1#0) let tmp%1#0: bool = (b== reinterpret_biguint%2#0 0x01) (assert tmp%1#0) - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "d") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x64) (assert box_exists%2#0) // Box must exist let reinterpret_biguint%4#0: biguint = ((extract 2 1) box_value%2#0) let tmp%2#0: bool = (b== reinterpret_biguint%4#0 0x02) (assert tmp%2#0) - let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get "d") + let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get 0x64) (assert box_exists%3#0) // Box must exist let reinterpret_biguint%6#0: biguint = ((extract 3 1) box_value%3#0) let tmp%3#0: bool = (b== reinterpret_biguint%6#0 0x03) @@ -247,17 +245,17 @@ contract examples.box_storage.contract.BoxContract: let (value#0: bytes, exists#0: bool) = (box_get "blob") let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "blob") - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get "blob") + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put "blob" tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len "blob") - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len "blob") - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "blob") + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len "blob") + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return @@ -266,24 +264,24 @@ contract examples.box_storage.contract.BoxContract: let tmp%0#0: bytes = (itob 0u) let box_del_res%0#0: bool = (box_del tmp%0#0) (box_put tmp%0#0 "Hmmmmm") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) - (assert box_exists%0#0) // Box must exist - let tmp%3#0: bool = (== box_len%0#0 6u) - (assert tmp%3#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len tmp%0#0) - (assert box_exists%1#0) // Box must exist - let tmp%6#0: bool = (== box_len%1#0 6u) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob 1u) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get tmp%7#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%0#0) + (assert check%0#0) // box exists + let tmp%5#0: bool = (== value%0#0 6u) + (assert tmp%5#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%0#0) + (assert check%1#0) // box exists + let tmp%9#0: bool = (== value%1#0 6u) (assert tmp%9#0) - let (value#1: bytes, exists#0: bool) = (box_get tmp%7#0) - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len tmp%0#0) - (assert box_exists%4#0) + let tmp%10#0: bytes = (itob 1u) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%10#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let (value#1: bytes, exists#0: bool) = (box_get tmp%10#0) + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: diff --git a/examples/box_storage/out/BoxContract.ssa.opt_pass_4.ir b/examples/box_storage/out/BoxContract.ssa.opt_pass_4.ir index 19d297a1d..006c76fa8 100644 --- a/examples/box_storage/out/BoxContract.ssa.opt_pass_4.ir +++ b/examples/box_storage/out/BoxContract.ssa.opt_pass_4.ir @@ -145,84 +145,82 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_del_res%0#0: bool = (box_del "0") - (box_put "0" "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "0") - (assert box_exists%0#0) // Box must exist - let tmp%1#0: uint64 = (select box_len%0#0 0u box_len%0#0) - let tmp%2#0: bool = (< 7u box_len%0#0) - let tmp%3#0: uint64 = (select box_len%0#0 7u tmp%2#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%1#0) - let tmp%7#0: bytes = (box_extract "0" tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let tmp%9#0: bool = (< 2u box_len%1#0) - let tmp%10#0: uint64 = (select box_len%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u box_len%1#0) - let tmp%12#0: uint64 = (select box_len%1#0 10u tmp%11#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%10#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let box_del_res%0#0: bool = (box_del 0x30) + (box_put 0x30 "Testing testing 123") + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len 0x30) + let tmp%3#0: uint64 = (select tmp%0#0 0u tmp%0#0) + let tmp%4#0: bool = (< 7u tmp%0#0) + let tmp%5#0: uint64 = (select tmp%0#0 7u tmp%4#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%3#0) + let tmp%9#0: bytes = (box_extract 0x30 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let tmp%13#0: bool = (< 2u tmp%11#0) + let tmp%14#0: uint64 = (select tmp%11#0 2u tmp%13#0) + let tmp%15#0: bool = (< 10u tmp%11#0) + let tmp%16#0: uint64 = (select tmp%11#0 10u tmp%15#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%14#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: block@0: // L40 let array_data%0#4: bytes = 0x00010203 - (box_put "d" array_data%0#4) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "d") + (box_put 0x64 array_data%0#4) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get 0x64) (assert box_exists%0#0) // Box must exist let reinterpret_biguint%0#0: biguint = ((extract 0 1) box_value%0#0) let tmp%0#0: bool = (b== reinterpret_biguint%0#0 0x00) (assert tmp%0#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "d") + let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get 0x64) (assert box_exists%1#0) // Box must exist let reinterpret_biguint%2#0: biguint = ((extract 1 1) box_value%1#0) let tmp%1#0: bool = (b== reinterpret_biguint%2#0 0x01) (assert tmp%1#0) - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "d") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x64) (assert box_exists%2#0) // Box must exist let reinterpret_biguint%4#0: biguint = ((extract 2 1) box_value%2#0) let tmp%2#0: bool = (b== reinterpret_biguint%4#0 0x02) (assert tmp%2#0) - let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get "d") + let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get 0x64) (assert box_exists%3#0) // Box must exist let reinterpret_biguint%6#0: biguint = ((extract 3 1) box_value%3#0) let tmp%3#0: bool = (b== reinterpret_biguint%6#0 0x03) @@ -246,17 +244,17 @@ contract examples.box_storage.contract.BoxContract: let (value#0: bytes, exists#0: bool) = (box_get "blob") let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "blob") - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get "blob") + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put "blob" tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len "blob") - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len "blob") - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "blob") + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len "blob") + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return @@ -265,24 +263,24 @@ contract examples.box_storage.contract.BoxContract: let tmp%0#0: bytes = (itob 0u) let box_del_res%0#0: bool = (box_del tmp%0#0) (box_put tmp%0#0 "Hmmmmm") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) - (assert box_exists%0#0) // Box must exist - let tmp%3#0: bool = (== box_len%0#0 6u) - (assert tmp%3#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len tmp%0#0) - (assert box_exists%1#0) // Box must exist - let tmp%6#0: bool = (== box_len%1#0 6u) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob 1u) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get tmp%7#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%0#0) + (assert check%0#0) // box exists + let tmp%5#0: bool = (== value%0#0 6u) + (assert tmp%5#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%0#0) + (assert check%1#0) // box exists + let tmp%9#0: bool = (== value%1#0 6u) (assert tmp%9#0) - let (value#1: bytes, exists#0: bool) = (box_get tmp%7#0) - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len tmp%0#0) - (assert box_exists%4#0) + let tmp%10#0: bytes = (itob 1u) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%10#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let (value#1: bytes, exists#0: bool) = (box_get tmp%10#0) + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: diff --git a/examples/box_storage/out/BoxContract.ssa.opt_pass_5.ir b/examples/box_storage/out/BoxContract.ssa.opt_pass_5.ir index a4f1199b8..d6677bc38 100644 --- a/examples/box_storage/out/BoxContract.ssa.opt_pass_5.ir +++ b/examples/box_storage/out/BoxContract.ssa.opt_pass_5.ir @@ -145,83 +145,81 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_del_res%0#0: bool = (box_del "0") - (box_put "0" "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "0") - (assert box_exists%0#0) // Box must exist - let tmp%1#0: uint64 = (select box_len%0#0 0u box_len%0#0) - let tmp%2#0: bool = (< 7u box_len%0#0) - let tmp%3#0: uint64 = (select box_len%0#0 7u tmp%2#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%1#0) - let tmp%7#0: bytes = (box_extract "0" tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let tmp%9#0: bool = (< 2u box_len%1#0) - let tmp%10#0: uint64 = (select box_len%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u box_len%1#0) - let tmp%12#0: uint64 = (select box_len%1#0 10u tmp%11#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%10#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let box_del_res%0#0: bool = (box_del 0x30) + (box_put 0x30 "Testing testing 123") + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len 0x30) + let tmp%3#0: uint64 = (select tmp%0#0 0u tmp%0#0) + let tmp%4#0: bool = (< 7u tmp%0#0) + let tmp%5#0: uint64 = (select tmp%0#0 7u tmp%4#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%3#0) + let tmp%9#0: bytes = (box_extract 0x30 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let tmp%13#0: bool = (< 2u tmp%11#0) + let tmp%14#0: uint64 = (select tmp%11#0 2u tmp%13#0) + let tmp%15#0: bool = (< 10u tmp%11#0) + let tmp%16#0: uint64 = (select tmp%11#0 10u tmp%15#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%14#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: block@0: // L40 - (box_put "d" 0x00010203) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "d") + (box_put 0x64 0x00010203) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get 0x64) (assert box_exists%0#0) // Box must exist let reinterpret_biguint%0#0: biguint = ((extract 0 1) box_value%0#0) let tmp%0#0: bool = (b== reinterpret_biguint%0#0 0x00) (assert tmp%0#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "d") + let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get 0x64) (assert box_exists%1#0) // Box must exist let reinterpret_biguint%2#0: biguint = ((extract 1 1) box_value%1#0) let tmp%1#0: bool = (b== reinterpret_biguint%2#0 0x01) (assert tmp%1#0) - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "d") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x64) (assert box_exists%2#0) // Box must exist let reinterpret_biguint%4#0: biguint = ((extract 2 1) box_value%2#0) let tmp%2#0: bool = (b== reinterpret_biguint%4#0 0x02) (assert tmp%2#0) - let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get "d") + let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get 0x64) (assert box_exists%3#0) // Box must exist let reinterpret_biguint%6#0: biguint = ((extract 3 1) box_value%3#0) let tmp%3#0: bool = (b== reinterpret_biguint%6#0 0x03) @@ -245,17 +243,17 @@ contract examples.box_storage.contract.BoxContract: let (value#0: bytes, exists#0: bool) = (box_get "blob") let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "blob") - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get "blob") + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put "blob" tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len "blob") - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len "blob") - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "blob") + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len "blob") + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return @@ -264,24 +262,24 @@ contract examples.box_storage.contract.BoxContract: let tmp%0#0: bytes = (itob 0u) let box_del_res%0#0: bool = (box_del tmp%0#0) (box_put tmp%0#0 "Hmmmmm") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) - (assert box_exists%0#0) // Box must exist - let tmp%3#0: bool = (== box_len%0#0 6u) - (assert tmp%3#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len tmp%0#0) - (assert box_exists%1#0) // Box must exist - let tmp%6#0: bool = (== box_len%1#0 6u) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob 1u) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get tmp%7#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%0#0) + (assert check%0#0) // box exists + let tmp%5#0: bool = (== value%0#0 6u) + (assert tmp%5#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%0#0) + (assert check%1#0) // box exists + let tmp%9#0: bool = (== value%1#0 6u) (assert tmp%9#0) - let (value#1: bytes, exists#0: bool) = (box_get tmp%7#0) - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len tmp%0#0) - (assert box_exists%4#0) + let tmp%10#0: bytes = (itob 1u) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%10#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let (value#1: bytes, exists#0: bool) = (box_get tmp%10#0) + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: diff --git a/examples/box_storage/out/client_BoxContract.py b/examples/box_storage/out/client_BoxContract.py index bb40d2ee4..82c56dc1f 100644 --- a/examples/box_storage/out/client_BoxContract.py +++ b/examples/box_storage/out/client_BoxContract.py @@ -10,7 +10,7 @@ class BoxContract(algopy.arc4.ARC4Client, typing.Protocol): @algopy.arc4.abimethod def set_boxes( self, - a: algopy.arc4.UInt64, + a: algopy.arc4.UIntN[typing.Literal[64]], b: algopy.arc4.DynamicBytes, c: algopy.arc4.String, ) -> None: ... @@ -18,7 +18,7 @@ def set_boxes( @algopy.arc4.abimethod def read_boxes( self, - ) -> algopy.arc4.Tuple[algopy.arc4.UInt64, algopy.arc4.DynamicBytes, algopy.arc4.String]: ... + ) -> algopy.arc4.Tuple[algopy.arc4.UIntN[typing.Literal[64]], algopy.arc4.DynamicBytes, algopy.arc4.String]: ... @algopy.arc4.abimethod def boxes_exist( @@ -48,18 +48,18 @@ def box_map_test( @algopy.arc4.abimethod def box_map_set( self, - key: algopy.arc4.UInt64, + key: algopy.arc4.UIntN[typing.Literal[64]], value: algopy.arc4.String, ) -> None: ... @algopy.arc4.abimethod def box_map_get( self, - key: algopy.arc4.UInt64, + key: algopy.arc4.UIntN[typing.Literal[64]], ) -> algopy.arc4.String: ... @algopy.arc4.abimethod def box_map_exists( self, - key: algopy.arc4.UInt64, + key: algopy.arc4.UIntN[typing.Literal[64]], ) -> algopy.arc4.Bool: ... diff --git a/examples/box_storage/out/contract.awst b/examples/box_storage/out/contract.awst index a4d10e191..aa463a098 100644 --- a/examples/box_storage/out/contract.awst +++ b/examples/box_storage/out/contract.awst @@ -1,98 +1,98 @@ contract BoxContract { boxes { - ['BOX_A']: algopy.UInt64 - ['b']: algopy.Bytes - ['BOX_C']: algopy.arc4.String - ['']: algopy.UInt64 => algopy.String + ['box_a']: uint64 + ['b']: bytes + [hex<"424F585F43">]: arc4.string + ['']: uint64 => string } constructor() { } - abimethod set_boxes(a: algopy.UInt64, b: algopy.Bytes, c: algopy.arc4.String): None + abimethod set_boxes(a: uint64, b: bytes, c: arc4.string): void { - this.box_a.value: algopy.UInt64 = a - this.box_b.value: algopy.Bytes = b - this.box_c.value: algopy.arc4.String = c - this.box_a.value += 3u + this.box_a: uint64 = a + this.box_b: bytes = b + this.box_c: arc4.string = c + this.box_a += 3u } - abimethod read_boxes(): tuple[algopy.UInt64, algopy.Bytes, algopy.arc4.String] + abimethod read_boxes(): tuple { - return (this.box_a.value, this.box_b.value, this.box_c.value) + return (this.box_a, this.box_b, this.box_c) } - abimethod boxes_exist(): tuple[bool, bool, bool] + abimethod boxes_exist(): tuple { - return (STATE_EXISTS(this.box_a.key), STATE_EXISTS(this.box_b.key), STATE_EXISTS(this.box_c.key)) + return (STATE_EXISTS(this.box_a), STATE_EXISTS(this.box_b), STATE_EXISTS(this.box_c)) } - abimethod slice_box(): None + abimethod slice_box(): void { - box_0: algopy.Box[algopy.Bytes] = Box('0') - box_0.value: algopy.Bytes = 'Testing testing 123' - assert(box_extract(box_0.key, select(SINGLE_EVAL(id=0, source=len(box_0.key)), 0u, 0u < SINGLE_EVAL(id=0, source=len(box_0.key))), select(SINGLE_EVAL(id=0, source=len(box_0.key)), 7u, 7u < SINGLE_EVAL(id=0, source=len(box_0.key))) - select(SINGLE_EVAL(id=0, source=len(box_0.key)), 0u, 0u < SINGLE_EVAL(id=0, source=len(box_0.key)))) == 'Testing') - this.box_c.value: algopy.arc4.String = arc4_encode('Hello', algopy.arc4.String) - assert(box_extract(this.box_c.key, select(SINGLE_EVAL(id=1, source=len(this.box_c.key)), 2u, 2u < SINGLE_EVAL(id=1, source=len(this.box_c.key))), select(SINGLE_EVAL(id=1, source=len(this.box_c.key)), 10u, 10u < SINGLE_EVAL(id=1, source=len(this.box_c.key))) - select(SINGLE_EVAL(id=1, source=len(this.box_c.key)), 2u, 2u < SINGLE_EVAL(id=1, source=len(this.box_c.key)))) == 'Hello') + box_0: bytes = hex<"30"> + Box[box_0]: bytes = 'Testing testing 123' + assert(box_extract(box_0, select(SINGLE_EVAL(id=0, source=box_len(box_0)[0]), 0u, 0u < SINGLE_EVAL(id=0, source=box_len(box_0)[0])), select(SINGLE_EVAL(id=0, source=box_len(box_0)[0]), 7u, 7u < SINGLE_EVAL(id=0, source=box_len(box_0)[0])) - select(SINGLE_EVAL(id=0, source=box_len(box_0)[0]), 0u, 0u < SINGLE_EVAL(id=0, source=box_len(box_0)[0]))) == 'Testing') + this.box_c: arc4.string = arc4_encode('Hello', arc4.string) + assert(box_extract(hex<"424F585F43">, select(SINGLE_EVAL(id=1, source=box_len(hex<"424F585F43">)[0]), 2u, 2u < SINGLE_EVAL(id=1, source=box_len(hex<"424F585F43">)[0])), select(SINGLE_EVAL(id=1, source=box_len(hex<"424F585F43">)[0]), 10u, 10u < SINGLE_EVAL(id=1, source=box_len(hex<"424F585F43">)[0])) - select(SINGLE_EVAL(id=1, source=box_len(hex<"424F585F43">)[0]), 2u, 2u < SINGLE_EVAL(id=1, source=box_len(hex<"424F585F43">)[0]))) == 'Hello') } - abimethod arc4_box(): None + abimethod arc4_box(): void { - box_d: algopy.Box[algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]]] = Box('d') - box_d.value: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] = new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]](0arc4u8, 1arc4u8, 2arc4u8, 3arc4u8) - assert(reinterpret_cast(box_d.value[0u]) == reinterpret_cast(0arc4u8)) - assert(reinterpret_cast(box_d.value[1u]) == reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(box_d.value[2u]) == reinterpret_cast(2arc4u8)) - assert(reinterpret_cast(box_d.value[3u]) == reinterpret_cast(3arc4u8)) + box_d: bytes = hex<"64"> + Box[box_d]: arc4.static_array = new arc4.static_array(0arc4u8, 1arc4u8, 2arc4u8, 3arc4u8) + assert(reinterpret_cast(Box[box_d][0u]) == reinterpret_cast(0arc4u8)) + assert(reinterpret_cast(Box[box_d][1u]) == reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(Box[box_d][2u]) == reinterpret_cast(2arc4u8)) + assert(reinterpret_cast(Box[box_d][3u]) == reinterpret_cast(3arc4u8)) } - abimethod box_blob(): None + abimethod box_blob(): void { - box_blob: algopy.BoxRef = BoxRef('blob') - sender_bytes: algopy.Bytes = reinterpret_cast(txn()) - app_address: algopy.Bytes = reinterpret_cast(global()) + box_blob: bytes = 'blob' + sender_bytes: bytes = reinterpret_cast(txn()) + app_address: bytes = reinterpret_cast(global()) assert(box_create(box_blob, 8000u)) box_replace(box_blob, 0u, sender_bytes) box_splice(box_blob, 0u, 0u, app_address) - first_64: algopy.Bytes = box_extract(box_blob, 0u, 64u) + first_64: bytes = box_extract(box_blob, 0u, 64u) assert(first_64 == app_address + sender_bytes) assert(box_del(box_blob)) - (value, exists): tuple[algopy.Bytes, bool] = STATE_GET_EX(box_blob.key) + (value, exists): tuple = STATE_GET_EX(Box[box_blob]) assert(!(exists)) - assert(STATE_GET(box_blob.key, default=sender_bytes) == sender_bytes) + assert(STATE_GET(Box[box_blob], default=sender_bytes) == sender_bytes) box_put(box_blob, sender_bytes + app_address) - assert(STATE_EXISTS(box_blob.key), comment="Blob exists") - assert(len(box_blob.key) == 64u) + assert(STATE_EXISTS(Box[box_blob]), comment="Blob exists") + assert(checked_maybe(box_len(box_blob)) == 64u) } - abimethod box_map_test(): None + abimethod box_map_test(): void { - key_0: algopy.UInt64 = 0u - key_1: algopy.UInt64 = 1u - value: algopy.String = 'Hmmmmm' - this.box_map.value: algopy.String = value - assert(len(this.box_map.key) == len(reinterpret_cast(value))) - assert(len(this.box_map.key) == len(reinterpret_cast(value))) - assert(STATE_GET(this.box_map.key, default='default') == 'default') - (value, exists): tuple[algopy.String, bool] = STATE_GET_EX(this.box_map.key) + key_0: uint64 = 0u + key_1: uint64 = 1u + value: string = 'Hmmmmm' + Box[concat('', BytesRaw(key_0))]: string = value + assert(checked_maybe(box_len(concat('', BytesRaw(key_0)))) == len(reinterpret_cast(value))) + assert(checked_maybe(box_len(concat('', BytesRaw(key_0)))) == len(reinterpret_cast(value))) + assert(STATE_GET(Box[concat('', BytesRaw(key_1))], default='default') == 'default') + (value, exists): tuple = STATE_GET_EX(Box[concat('', BytesRaw(key_1))]) assert(!(exists)) - assert(STATE_EXISTS(this.box_map.key)) + assert(STATE_EXISTS(Box[concat('', BytesRaw(key_0))])) } - abimethod box_map_set(key: algopy.UInt64, value: algopy.String): None + abimethod box_map_set(key: uint64, value: string): void { - this.box_map.value: algopy.String = value + Box[concat('', BytesRaw(key))]: string = value } - abimethod box_map_get(key: algopy.UInt64): algopy.String + abimethod box_map_get(key: uint64): string { - return this.box_map.value + return Box[concat('', BytesRaw(key))] } - abimethod box_map_exists(key: algopy.UInt64): bool + abimethod box_map_exists(key: uint64): bool { - return STATE_EXISTS(this.box_map.key) + return STATE_EXISTS(Box[concat('', BytesRaw(key))]) } } \ No newline at end of file diff --git a/examples/box_storage/out_O2/BoxContract.approval.teal b/examples/box_storage/out_O2/BoxContract.approval.teal index 419d07d65..ab6e4f04b 100644 --- a/examples/box_storage/out_O2/BoxContract.approval.teal +++ b/examples/box_storage/out_O2/BoxContract.approval.teal @@ -227,7 +227,7 @@ set_boxes: proto 3 0 frame_dig -3 itob - byte "BOX_A" + byte "box_a" swap box_put byte "b" @@ -236,13 +236,13 @@ set_boxes: byte "b" frame_dig -2 box_put - byte "BOX_C" + byte 0x424f585f43 box_del pop - byte "BOX_C" + byte 0x424f585f43 frame_dig -1 box_put - byte "BOX_A" + byte "box_a" box_get swap btoi @@ -251,7 +251,7 @@ set_boxes: int 3 + itob - byte "BOX_A" + byte "box_a" swap box_put retsub @@ -260,7 +260,7 @@ set_boxes: // examples.box_storage.contract.BoxContract.read_boxes() -> uint64, bytes, bytes: read_boxes: proto 0 3 - byte "BOX_A" + byte "box_a" box_get swap btoi @@ -269,7 +269,7 @@ read_boxes: byte "b" box_get assert // Box must exist - byte "BOX_C" + byte 0x424f585f43 box_get assert // Box must exist retsub @@ -278,13 +278,13 @@ read_boxes: // examples.box_storage.contract.BoxContract.boxes_exist() -> uint64, uint64, uint64: boxes_exist: proto 0 3 - byte "BOX_A" + byte "box_a" box_len bury 1 byte "b" box_len bury 1 - byte "BOX_C" + byte 0x424f585f43 box_len bury 1 retsub @@ -293,15 +293,15 @@ boxes_exist: // examples.box_storage.contract.BoxContract.slice_box() -> void: slice_box: proto 0 0 - byte "0" + byte 0x30 box_del pop - byte "0" + byte 0x30 byte "Testing testing 123" box_put - byte "0" + byte 0x30 box_len - assert // Box must exist + pop dup int 0 dig 2 @@ -315,21 +315,21 @@ slice_box: select dig 1 - - byte "0" + byte 0x30 cover 2 box_extract byte "Testing" == assert - byte "BOX_C" + byte 0x424f585f43 box_del pop - byte "BOX_C" + byte 0x424f585f43 byte "\x00\x05Hello" box_put - byte "BOX_C" + byte 0x424f585f43 box_len - assert // Box must exist + pop int 2 dig 1 < @@ -347,7 +347,7 @@ slice_box: select dig 1 - - byte "BOX_C" + byte 0x424f585f43 cover 2 box_extract byte "Hello" @@ -359,31 +359,31 @@ slice_box: // examples.box_storage.contract.BoxContract.arc4_box() -> void: arc4_box: proto 0 0 - byte "d" + byte 0x64 byte 0x00010203 box_put - byte "d" + byte 0x64 box_get assert // Box must exist extract 0 1 byte 0x00 b== assert - byte "d" + byte 0x64 box_get assert // Box must exist extract 1 1 byte 0x01 b== assert - byte "d" + byte 0x64 box_get assert // Box must exist extract 2 1 byte 0x02 b== assert - byte "d" + byte 0x64 box_get assert // Box must exist extract 3 1 @@ -447,7 +447,7 @@ box_blob: assert // Blob exists byte "blob" box_len - assert // Box must exist + assert // box exists int 64 == assert @@ -467,13 +467,13 @@ box_map_test: box_put dup box_len - assert // Box must exist + assert // box exists int 6 == assert dup box_len - assert // Box must exist + assert // box exists int 6 == assert diff --git a/examples/box_storage/out_O2/BoxContract.destructured.ir b/examples/box_storage/out_O2/BoxContract.destructured.ir index ec74b8aec..300a63b83 100644 --- a/examples/box_storage/out_O2/BoxContract.destructured.ir +++ b/examples/box_storage/out_O2/BoxContract.destructured.ir @@ -145,83 +145,81 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_del_res%0#0: bool = (box_del "0") - (box_put "0" "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "0") - (assert box_exists%0#0) // Box must exist - let tmp%1#0: uint64 = (select box_len%0#0 0u box_len%0#0) - let tmp%2#0: bool = (< 7u box_len%0#0) - let tmp%3#0: uint64 = (select box_len%0#0 7u tmp%2#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%1#0) - let tmp%7#0: bytes = (box_extract "0" tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let tmp%9#0: bool = (< 2u box_len%1#0) - let tmp%10#0: uint64 = (select box_len%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u box_len%1#0) - let tmp%12#0: uint64 = (select box_len%1#0 10u tmp%11#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%10#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let box_del_res%0#0: bool = (box_del 0x30) + (box_put 0x30 "Testing testing 123") + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len 0x30) + let tmp%3#0: uint64 = (select tmp%0#0 0u tmp%0#0) + let tmp%4#0: bool = (< 7u tmp%0#0) + let tmp%5#0: uint64 = (select tmp%0#0 7u tmp%4#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%3#0) + let tmp%9#0: bytes = (box_extract 0x30 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let tmp%13#0: bool = (< 2u tmp%11#0) + let tmp%14#0: uint64 = (select tmp%11#0 2u tmp%13#0) + let tmp%15#0: bool = (< 10u tmp%11#0) + let tmp%16#0: uint64 = (select tmp%11#0 10u tmp%15#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%14#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: block@0: // L40 - (box_put "d" 0x00010203) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "d") + (box_put 0x64 0x00010203) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get 0x64) (assert box_exists%0#0) // Box must exist let reinterpret_biguint%0#0: biguint = ((extract 0 1) box_value%0#0) let tmp%0#0: bool = (b== reinterpret_biguint%0#0 0x00) (assert tmp%0#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "d") + let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get 0x64) (assert box_exists%1#0) // Box must exist let reinterpret_biguint%2#0: biguint = ((extract 1 1) box_value%1#0) let tmp%1#0: bool = (b== reinterpret_biguint%2#0 0x01) (assert tmp%1#0) - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "d") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x64) (assert box_exists%2#0) // Box must exist let reinterpret_biguint%4#0: biguint = ((extract 2 1) box_value%2#0) let tmp%2#0: bool = (b== reinterpret_biguint%4#0 0x02) (assert tmp%2#0) - let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get "d") + let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get 0x64) (assert box_exists%3#0) // Box must exist let reinterpret_biguint%6#0: biguint = ((extract 3 1) box_value%3#0) let tmp%3#0: bool = (b== reinterpret_biguint%6#0 0x03) @@ -245,17 +243,17 @@ contract examples.box_storage.contract.BoxContract: let (value#0: bytes, exists#0: bool) = (box_get "blob") let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "blob") - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get "blob") + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put "blob" tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len "blob") - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len "blob") - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "blob") + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len "blob") + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return @@ -264,24 +262,24 @@ contract examples.box_storage.contract.BoxContract: let tmp%0#0: bytes = (itob 0u) let box_del_res%0#0: bool = (box_del tmp%0#0) (box_put tmp%0#0 "Hmmmmm") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) - (assert box_exists%0#0) // Box must exist - let tmp%3#0: bool = (== box_len%0#0 6u) - (assert tmp%3#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len tmp%0#0) - (assert box_exists%1#0) // Box must exist - let tmp%6#0: bool = (== box_len%1#0 6u) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob 1u) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get tmp%7#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%0#0) + (assert check%0#0) // box exists + let tmp%5#0: bool = (== value%0#0 6u) + (assert tmp%5#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%0#0) + (assert check%1#0) // box exists + let tmp%9#0: bool = (== value%1#0 6u) (assert tmp%9#0) - let (value#1: bytes, exists#0: bool) = (box_get tmp%7#0) - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len tmp%0#0) - (assert box_exists%4#0) + let tmp%10#0: bytes = (itob 1u) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%10#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let (value#1: bytes, exists#0: bool) = (box_get tmp%10#0) + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%0#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: diff --git a/examples/box_storage/out_unoptimized/BoxContract.approval.teal b/examples/box_storage/out_unoptimized/BoxContract.approval.teal index e705a90bd..62698646f 100644 --- a/examples/box_storage/out_unoptimized/BoxContract.approval.teal +++ b/examples/box_storage/out_unoptimized/BoxContract.approval.teal @@ -310,21 +310,21 @@ set_boxes: frame_dig -3 itob // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:17 // self.box_a.value = a swap box_put // box_storage/contract.py:11 - // self.box_b = Box(Bytes, key=b"b") + // self.box_b = Box(Bytes, key="b") byte "b" // box_storage/contract.py:18 // self.box_b.value = b box_del pop // box_storage/contract.py:11 - // self.box_b = Box(Bytes, key=b"b") + // self.box_b = Box(Bytes, key="b") byte "b" // box_storage/contract.py:18 // self.box_b.value = b @@ -332,21 +332,21 @@ set_boxes: box_put // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:19 // self.box_c.value = c box_del pop // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:19 // self.box_c.value = c frame_dig -1 box_put // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:21 // self.box_a.value += 3 box_get @@ -358,8 +358,8 @@ set_boxes: + itob // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:21 // self.box_a.value += 3 swap @@ -374,8 +374,8 @@ read_boxes: // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: proto 0 3 // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:25 // return self.box_a.value, self.box_b.value, self.box_c.value box_get @@ -384,7 +384,7 @@ read_boxes: swap assert // Box must exist // box_storage/contract.py:11 - // self.box_b = Box(Bytes, key=b"b") + // self.box_b = Box(Bytes, key="b") byte "b" // box_storage/contract.py:25 // return self.box_a.value, self.box_b.value, self.box_c.value @@ -392,7 +392,7 @@ read_boxes: assert // Box must exist // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:25 // return self.box_a.value, self.box_b.value, self.box_c.value box_get @@ -410,15 +410,15 @@ boxes_exist: // def boxes_exist(self) -> tuple[bool, bool, bool]: proto 0 3 // box_storage/contract.py:10 - // self.box_a = Box(UInt64, key=b"BOX_A") - byte "BOX_A" + // self.box_a = Box(UInt64) + byte "box_a" // box_storage/contract.py:29 // return bool(self.box_a), bool(self.box_b), bool(self.box_c) box_len swap pop // box_storage/contract.py:11 - // self.box_b = Box(Bytes, key=b"b") + // self.box_b = Box(Bytes, key="b") byte "b" // box_storage/contract.py:29 // return bool(self.box_a), bool(self.box_b), bool(self.box_c) @@ -427,7 +427,7 @@ boxes_exist: pop // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:29 // return bool(self.box_a), bool(self.box_b), bool(self.box_c) box_len @@ -447,25 +447,25 @@ slice_box: proto 0 0 // box_storage/contract.py:33 // box_0 = Box(Bytes, key=b"0") - byte "0" + byte 0x30 // box_storage/contract.py:34 // box_0.value = Bytes(b"Testing testing 123") box_del pop // box_storage/contract.py:33 // box_0 = Box(Bytes, key=b"0") - byte "0" + byte 0x30 // box_storage/contract.py:34 // box_0.value = Bytes(b"Testing testing 123") byte "Testing testing 123" box_put // box_storage/contract.py:33 // box_0 = Box(Bytes, key=b"0") - byte "0" + byte 0x30 // box_storage/contract.py:35 // assert box_0.value[0:7] == b"Testing" box_len - assert // Box must exist + pop int 0 dig 1 < @@ -494,7 +494,7 @@ slice_box: - // box_storage/contract.py:33 // box_0 = Box(Bytes, key=b"0") - byte "0" + byte 0x30 // box_storage/contract.py:35 // assert box_0.value[0:7] == b"Testing" uncover 2 @@ -505,25 +505,25 @@ slice_box: assert // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:37 // self.box_c.value = arc4.String("Hello") box_del pop // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:37 // self.box_c.value = arc4.String("Hello") byte "\x00\x05Hello" box_put // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:38 // assert self.box_c.value.bytes[2:10] == b"Hello" box_len - assert // Box must exist + pop int 2 dig 1 < @@ -552,7 +552,7 @@ slice_box: - // box_storage/contract.py:12 // self.box_c = Box(arc4.String, key=b"BOX_C") - byte "BOX_C" + byte 0x424f585f43 // box_storage/contract.py:38 // assert self.box_c.value.bytes[2:10] == b"Hello" uncover 2 @@ -583,14 +583,14 @@ arc4_box: concat // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:43 // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) swap box_put // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:45 // assert box_d.value[0] == 0 box_get @@ -605,7 +605,7 @@ arc4_box: assert // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:46 // assert box_d.value[1] == 1 box_get @@ -620,7 +620,7 @@ arc4_box: assert // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:47 // assert box_d.value[2] == 2 box_get @@ -635,7 +635,7 @@ arc4_box: assert // box_storage/contract.py:42 // box_d = Box(StaticInts, key=b"d") - byte "d" + byte 0x64 // box_storage/contract.py:48 // assert box_d.value[3] == 3 box_get @@ -665,7 +665,7 @@ box_blob: global CurrentApplicationAddress swap // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:55 // assert box_blob.create(size=8000) @@ -673,7 +673,7 @@ box_blob: box_create assert // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:56 // box_blob.replace(0, sender_bytes) @@ -681,7 +681,7 @@ box_blob: dig 2 box_replace // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:57 // box_blob.splice(0, 0, app_address) @@ -690,7 +690,7 @@ box_blob: dig 4 box_splice // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:58 // first_64 = box_blob.extract(0, 32 * 2) @@ -705,14 +705,14 @@ box_blob: == assert // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:60 // assert box_blob.delete() box_del assert // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:62 // value, exists = box_blob.maybe() @@ -724,7 +724,7 @@ box_blob: ! assert // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:64 // assert box_blob.get(default=sender_bytes) == sender_bytes @@ -742,14 +742,14 @@ box_blob: swap concat // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:65 // box_blob.put(sender_bytes + app_address) swap box_put // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:66 // assert box_blob, "Blob exists" @@ -758,12 +758,12 @@ box_blob: pop assert // Blob exists // box_storage/contract.py:52 - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") byte "blob" // box_storage/contract.py:67 // assert box_blob.length == 64 box_len - assert // Box must exist + assert // box exists int 64 == assert @@ -783,7 +783,7 @@ box_map_test: // self.box_map[key_0] = value itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:74 // self.box_map[key_0] = value @@ -805,14 +805,14 @@ box_map_test: // assert self.box_map[key_0].bytes.length == value.bytes.length itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:75 // assert self.box_map[key_0].bytes.length == value.bytes.length swap concat box_len - assert // Box must exist + assert // box exists // box_storage/contract.py:73 // value = String("Hmmmmm") byte "Hmmmmm" @@ -828,14 +828,14 @@ box_map_test: // assert self.box_map.length(key_0) == value.bytes.length itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:76 // assert self.box_map.length(key_0) == value.bytes.length swap concat box_len - assert // Box must exist + assert // box exists // box_storage/contract.py:73 // value = String("Hmmmmm") byte "Hmmmmm" @@ -851,7 +851,7 @@ box_map_test: // assert self.box_map.get(key_1, default=String("default")) == String("default") itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:78 // assert self.box_map.get(key_1, default=String("default")) == String("default") @@ -873,7 +873,7 @@ box_map_test: // value, exists = self.box_map.maybe(key_1) itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:79 // value, exists = self.box_map.maybe(key_1) @@ -890,7 +890,7 @@ box_map_test: // key_0 = UInt64(0) int 0 // box_storage/contract.py:13-81 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") // // @arc4.abimethod // def set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None: @@ -929,7 +929,7 @@ box_map_test: // // @arc4.abimethod // def box_blob(self) -> None: - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") // sender_bytes = Txn.sender.bytes // app_address = Global.current_application_address.bytes // assert box_blob.create(size=8000) @@ -961,10 +961,10 @@ box_map_test: // assert key_0 in self.box_map itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:13-81 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") // // @arc4.abimethod // def set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None: @@ -1003,7 +1003,7 @@ box_map_test: // // @arc4.abimethod // def box_blob(self) -> None: - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") // sender_bytes = Txn.sender.bytes // app_address = Global.current_application_address.bytes // assert box_blob.create(size=8000) @@ -1055,7 +1055,7 @@ box_map_set: frame_dig -2 itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:85 // self.box_map[key] = value @@ -1080,7 +1080,7 @@ box_map_get: frame_dig -1 itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:89 // return self.box_map[key] @@ -1098,7 +1098,7 @@ box_map_exists: // def box_map_exists(self, key: UInt64) -> bool: proto 1 1 // box_storage/contract.py:13-93 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") // // @arc4.abimethod // def set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None: @@ -1137,7 +1137,7 @@ box_map_exists: // // @arc4.abimethod // def box_blob(self) -> None: - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") // sender_bytes = Txn.sender.bytes // app_address = Global.current_application_address.bytes // assert box_blob.create(size=8000) @@ -1182,10 +1182,10 @@ box_map_exists: frame_dig -1 itob // box_storage/contract.py:13 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" // box_storage/contract.py:13-93 - // self.box_map = BoxMap(UInt64, String) + // self.box_map = BoxMap(UInt64, String, key_prefix="") // // @arc4.abimethod // def set_boxes(self, a: UInt64, b: Bytes, c: arc4.String) -> None: @@ -1224,7 +1224,7 @@ box_map_exists: // // @arc4.abimethod // def box_blob(self) -> None: - // box_blob = BoxRef(key=b"blob") + // box_blob = BoxRef(key="blob") // sender_bytes = Txn.sender.bytes // app_address = Global.current_application_address.bytes // assert box_blob.create(size=8000) diff --git a/examples/box_storage/out_unoptimized/BoxContract.destructured.ir b/examples/box_storage/out_unoptimized/BoxContract.destructured.ir index cf64be729..2f9eabbf6 100644 --- a/examples/box_storage/out_unoptimized/BoxContract.destructured.ir +++ b/examples/box_storage/out_unoptimized/BoxContract.destructured.ir @@ -156,69 +156,67 @@ contract examples.box_storage.contract.BoxContract: subroutine examples.box_storage.contract.BoxContract.set_boxes(a: uint64, b: bytes, c: bytes) -> void: block@0: // L15 let new_box_value%0#0: bytes = (itob a#0) - (box_put "BOX_A" new_box_value%0#0) + (box_put "box_a" new_box_value%0#0) let box_del_res%0#0: bool = (box_del "b") (box_put "b" b#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" c#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 c#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let new_box_value%1#0: uint64 = (+ box_value_uint64%0#0 3u) let new_box_value%2#0: bytes = (itob new_box_value%1#0) - (box_put "BOX_A" new_box_value%2#0) + (box_put "box_a" new_box_value%2#0) return subroutine examples.box_storage.contract.BoxContract.read_boxes() -> : block@0: // L23 - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "BOX_A") + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "box_a") let box_value_uint64%0#0: uint64 = (btoi box_value%0#0) (assert box_exists%0#0) // Box must exist let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "b") (assert box_exists%1#0) // Box must exist - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "BOX_C") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x424f585f43) (assert box_exists%2#0) // Box must exist return box_value_uint64%0#0 box_value%1#0 box_value%2#0 subroutine examples.box_storage.contract.BoxContract.boxes_exist() -> : block@0: // L27 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "BOX_A") + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "box_a") let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "b") - let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len "BOX_C") + let (box_len%2#0: uint64, box_exists%2#0: bool) = (box_len 0x424f585f43) return box_exists%0#0 box_exists%1#0 box_exists%2#0 subroutine examples.box_storage.contract.BoxContract.slice_box() -> void: block@0: // L31 - let box_del_res%0#0: bool = (box_del "0") - (box_put "0" "Testing testing 123") - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "0") - (assert box_exists%0#0) // Box must exist - let awst_tmp%0#0: uint64 = box_len%0#0 - let tmp%0#0: bool = (< 0u awst_tmp%0#0) - let tmp%1#0: uint64 = (select awst_tmp%0#0 0u tmp%0#0) - let tmp%2#0: bool = (< 7u awst_tmp%0#0) - let tmp%3#0: uint64 = (select awst_tmp%0#0 7u tmp%2#0) - let tmp%4#0: bool = (< 0u awst_tmp%0#0) - let tmp%5#0: uint64 = (select awst_tmp%0#0 0u tmp%4#0) - let tmp%6#0: uint64 = (- tmp%3#0 tmp%5#0) - let tmp%7#0: bytes = (box_extract "0" tmp%1#0 tmp%6#0) - let tmp%8#0: bool = (== tmp%7#0 "Testing") - (assert tmp%8#0) - let box_del_res%1#0: bool = (box_del "BOX_C") - (box_put "BOX_C" "\x00\x05Hello") - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len "BOX_C") - (assert box_exists%1#0) // Box must exist - let awst_tmp%1#0: uint64 = box_len%1#0 - let tmp%9#0: bool = (< 2u awst_tmp%1#0) - let tmp%10#0: uint64 = (select awst_tmp%1#0 2u tmp%9#0) - let tmp%11#0: bool = (< 10u awst_tmp%1#0) - let tmp%12#0: uint64 = (select awst_tmp%1#0 10u tmp%11#0) + let box_del_res%0#0: bool = (box_del 0x30) + (box_put 0x30 "Testing testing 123") + let (tmp%0#0: uint64, tmp%1#0: bool) = (box_len 0x30) + let awst_tmp%0#0: uint64 = tmp%0#0 + let tmp%2#0: bool = (< 0u awst_tmp%0#0) + let tmp%3#0: uint64 = (select awst_tmp%0#0 0u tmp%2#0) + let tmp%4#0: bool = (< 7u awst_tmp%0#0) + let tmp%5#0: uint64 = (select awst_tmp%0#0 7u tmp%4#0) + let tmp%6#0: bool = (< 0u awst_tmp%0#0) + let tmp%7#0: uint64 = (select awst_tmp%0#0 0u tmp%6#0) + let tmp%8#0: uint64 = (- tmp%5#0 tmp%7#0) + let tmp%9#0: bytes = (box_extract 0x30 tmp%3#0 tmp%8#0) + let tmp%10#0: bool = (== tmp%9#0 "Testing") + (assert tmp%10#0) + let box_del_res%1#0: bool = (box_del 0x424f585f43) + (box_put 0x424f585f43 "\x00\x05Hello") + let (tmp%11#0: uint64, tmp%12#0: bool) = (box_len 0x424f585f43) + let awst_tmp%1#0: uint64 = tmp%11#0 let tmp%13#0: bool = (< 2u awst_tmp%1#0) let tmp%14#0: uint64 = (select awst_tmp%1#0 2u tmp%13#0) - let tmp%15#0: uint64 = (- tmp%12#0 tmp%14#0) - let tmp%16#0: bytes = (box_extract "BOX_C" tmp%10#0 tmp%15#0) - let tmp%17#0: bool = (== tmp%16#0 "Hello") - (assert tmp%17#0) + let tmp%15#0: bool = (< 10u awst_tmp%1#0) + let tmp%16#0: uint64 = (select awst_tmp%1#0 10u tmp%15#0) + let tmp%17#0: bool = (< 2u awst_tmp%1#0) + let tmp%18#0: uint64 = (select awst_tmp%1#0 2u tmp%17#0) + let tmp%19#0: uint64 = (- tmp%16#0 tmp%18#0) + let tmp%20#0: bytes = (box_extract 0x424f585f43 tmp%14#0 tmp%19#0) + let tmp%21#0: bool = (== tmp%20#0 "Hello") + (assert tmp%21#0) return subroutine examples.box_storage.contract.BoxContract.arc4_box() -> void: @@ -227,26 +225,26 @@ contract examples.box_storage.contract.BoxContract: let array_data%0#1: bytes = (concat array_data%0#1 0x01) let array_data%0#1: bytes = (concat array_data%0#1 0x02) let array_data%0#1: bytes = (concat array_data%0#1 0x03) - (box_put "d" array_data%0#1) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "d") + (box_put 0x64 array_data%0#1) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get 0x64) (assert box_exists%0#0) // Box must exist let item_index%0#0: uint64 = (* 0u 1u) let reinterpret_biguint%0#0: biguint = (extract3 box_value%0#0 item_index%0#0 1u) let tmp%0#0: bool = (b== reinterpret_biguint%0#0 0x00) (assert tmp%0#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "d") + let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get 0x64) (assert box_exists%1#0) // Box must exist let item_index%1#0: uint64 = (* 1u 1u) let reinterpret_biguint%2#0: biguint = (extract3 box_value%1#0 item_index%1#0 1u) let tmp%1#0: bool = (b== reinterpret_biguint%2#0 0x01) (assert tmp%1#0) - let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get "d") + let (box_value%2#0: bytes, box_exists%2#0: bool) = (box_get 0x64) (assert box_exists%2#0) // Box must exist let item_index%2#0: uint64 = (* 2u 1u) let reinterpret_biguint%4#0: biguint = (extract3 box_value%2#0 item_index%2#0 1u) let tmp%2#0: bool = (b== reinterpret_biguint%4#0 0x02) (assert tmp%2#0) - let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get "d") + let (box_value%3#0: bytes, box_exists%3#0: bool) = (box_get 0x64) (assert box_exists%3#0) // Box must exist let item_index%3#0: uint64 = (* 3u 1u) let reinterpret_biguint%6#0: biguint = (extract3 box_value%3#0 item_index%3#0 1u) @@ -268,83 +266,83 @@ contract examples.box_storage.contract.BoxContract: (assert tmp%2#0) let tmp%3#0: bool = (box_del "blob") (assert tmp%3#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get "blob") - let exists#0: bool = box_exists%0#0 + let (tuple_assignment%0#0: bytes, tuple_assignment%1#0: bool) = (box_get "blob") + let exists#0: bool = tuple_assignment%1#0 let tmp%4#0: bool = (! exists#0) (assert tmp%4#0) - let (box_value%1#0: bytes, box_exists%1#0: bool) = (box_get "blob") - let tmp%5#0: bytes = (select sender_bytes#0 box_value%1#0 box_exists%1#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get "blob") + let tmp%5#0: bytes = (select sender_bytes#0 None_get_ex%0#0 None_get_ex%1#0) let tmp%6#0: bool = (== tmp%5#0 sender_bytes#0) (assert tmp%6#0) let tmp%7#0: bytes = (concat sender_bytes#0 app_address#0) (box_put "blob" tmp%7#0) - let (box_len%0#0: uint64, box_exists%2#0: bool) = (box_len "blob") - (assert box_exists%2#0) // Blob exists - let (box_len%1#0: uint64, box_exists%3#0: bool) = (box_len "blob") - (assert box_exists%3#0) // Box must exist - let tmp%8#0: bool = (== box_len%1#0 64u) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len "blob") + (assert box_exists%0#0) // Blob exists + let (value%0#0: uint64, check%0#0: bool) = (box_len "blob") + (assert check%0#0) // box exists + let tmp%8#0: bool = (== value%0#0 64u) (assert tmp%8#0) return subroutine examples.box_storage.contract.BoxContract.box_map_test() -> void: block@0: // L69 let tmp%0#0: bytes = (itob 0u) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let box_del_res%0#0: bool = (box_del compound_key%0#0) - (box_put compound_key%0#0 "Hmmmmm") - let tmp%1#0: bytes = (itob 0u) - let compound_key%1#0: bytes = (concat "" tmp%1#0) - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len compound_key%1#0) - (assert box_exists%0#0) // Box must exist - let tmp%2#0: uint64 = (len "Hmmmmm") - let tmp%3#0: bool = (== box_len%0#0 tmp%2#0) - (assert tmp%3#0) - let tmp%4#0: bytes = (itob 0u) - let compound_key%2#0: bytes = (concat "" tmp%4#0) - let (box_len%1#0: uint64, box_exists%1#0: bool) = (box_len compound_key%2#0) - (assert box_exists%1#0) // Box must exist - let tmp%5#0: uint64 = (len "Hmmmmm") - let tmp%6#0: bool = (== box_len%1#0 tmp%5#0) - (assert tmp%6#0) - let tmp%7#0: bytes = (itob 1u) - let compound_key%3#0: bytes = (concat "" tmp%7#0) - let (box_value%0#0: bytes, box_exists%2#0: bool) = (box_get compound_key%3#0) - let tmp%8#0: bytes = (select "default" box_value%0#0 box_exists%2#0) - let tmp%9#0: bool = (== tmp%8#0 "default") + let tmp%1#0: bytes = (concat "" tmp%0#0) + let box_del_res%0#0: bool = (box_del tmp%1#0) + (box_put tmp%1#0 "Hmmmmm") + let tmp%2#0: bytes = (itob 0u) + let tmp%3#0: bytes = (concat "" tmp%2#0) + let (value%0#0: uint64, check%0#0: bool) = (box_len tmp%3#0) + (assert check%0#0) // box exists + let tmp%4#0: uint64 = (len "Hmmmmm") + let tmp%5#0: bool = (== value%0#0 tmp%4#0) + (assert tmp%5#0) + let tmp%6#0: bytes = (itob 0u) + let tmp%7#0: bytes = (concat "" tmp%6#0) + let (value%1#0: uint64, check%1#0: bool) = (box_len tmp%7#0) + (assert check%1#0) // box exists + let tmp%8#0: uint64 = (len "Hmmmmm") + let tmp%9#0: bool = (== value%1#0 tmp%8#0) (assert tmp%9#0) let tmp%10#0: bytes = (itob 1u) - let compound_key%4#0: bytes = (concat "" tmp%10#0) - let (box_value%1#0: bytes, box_exists%3#0: bool) = (box_get compound_key%4#0) - let exists#0: bool = box_exists%3#0 - let tmp%11#0: bool = (! exists#0) - (assert tmp%11#0) - let tmp%12#0: bytes = (itob 0u) - let compound_key%5#0: bytes = (concat "" tmp%12#0) - let (box_len%2#0: uint64, box_exists%4#0: bool) = (box_len compound_key%5#0) - (assert box_exists%4#0) + let tmp%11#0: bytes = (concat "" tmp%10#0) + let (None_get_ex%0#0: bytes, None_get_ex%1#0: bool) = (box_get tmp%11#0) + let tmp%12#0: bytes = (select "default" None_get_ex%0#0 None_get_ex%1#0) + let tmp%13#0: bool = (== tmp%12#0 "default") + (assert tmp%13#0) + let tmp%14#0: bytes = (itob 1u) + let tmp%15#0: bytes = (concat "" tmp%14#0) + let (tuple_assignment%0#0: bytes, tuple_assignment%1#0: bool) = (box_get tmp%15#0) + let exists#0: bool = tuple_assignment%1#0 + let tmp%16#0: bool = (! exists#0) + (assert tmp%16#0) + let tmp%17#0: bytes = (itob 0u) + let tmp%18#0: bytes = (concat "" tmp%17#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%18#0) + (assert box_exists%0#0) return subroutine examples.box_storage.contract.BoxContract.box_map_set(key: uint64, value: bytes) -> void: block@0: // L83 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let box_del_res%0#0: bool = (box_del compound_key%0#0) - (box_put compound_key%0#0 value#0) + let tmp%1#0: bytes = (concat "" tmp%0#0) + let box_del_res%0#0: bool = (box_del tmp%1#0) + (box_put tmp%1#0 value#0) return subroutine examples.box_storage.contract.BoxContract.box_map_get(key: uint64) -> bytes: block@0: // L87 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get compound_key%0#0) + let tmp%1#0: bytes = (concat "" tmp%0#0) + let (box_value%0#0: bytes, box_exists%0#0: bool) = (box_get tmp%1#0) (assert box_exists%0#0) // Box must exist return box_value%0#0 subroutine examples.box_storage.contract.BoxContract.box_map_exists(key: uint64) -> bool: block@0: // L91 let tmp%0#0: bytes = (itob key#0) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len compound_key%0#0) + let tmp%1#0: bytes = (concat "" tmp%0#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%1#0) return box_exists%0#0 program clear-state: diff --git a/examples/box_storage/puya.log b/examples/box_storage/puya.log index e35103068..b6962cfac 100644 --- a/examples/box_storage/puya.log +++ b/examples/box_storage/puya.log @@ -401,7 +401,7 @@ debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "b") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -436,34 +436,34 @@ debug: Optimizing subroutine examples.box_storage.contract.BoxContract.slice_box debug: Splitting parallel copies prior to optimization debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation -debug: Found equivalence set: box_len%0#0, awst_tmp%0#0 -debug: Replacing {awst_tmp%0#0} with box_len%0#0 made 6 modifications -debug: Found equivalence set: box_len%1#0, awst_tmp%1#0 -debug: Replacing {awst_tmp%1#0} with box_len%1#0 made 6 modifications +debug: Found equivalence set: tmp%0#0, awst_tmp%0#0 +debug: Replacing {awst_tmp%0#0} with tmp%0#0 made 6 modifications +debug: Found equivalence set: tmp%11#0, awst_tmp%1#0 +debug: Replacing {awst_tmp%1#0} with tmp%11#0 made 6 modifications debug: Optimizer: Intrinsic Simplifier -debug: Simplified (select box_len%0#0 0u tmp%0#0) to (select box_len%0#0 0u box_len%0#0) -debug: Simplified (select box_len%0#0 0u tmp%4#0) to (select box_len%0#0 0u box_len%0#0) +debug: Simplified (select tmp%0#0 0u tmp%2#0) to (select tmp%0#0 0u tmp%0#0) +debug: Simplified (select tmp%0#0 0u tmp%6#0) to (select tmp%0#0 0u tmp%0#0) debug: Optimizer: Remove Unused Variables debug: Removing unused variable box_0#0 -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "0") -debug: Removing unused variable tmp%0#0 -debug: Removing unused variable tmp%4#0 -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del 0x30) +debug: Removing unused variable tmp%2#0 +debug: Removing unused variable tmp%6#0 +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump debug: Optimizer: Remove Empty Blocks debug: Optimizer: Remove Unreachable Blocks debug: Optimizer: Repeated Expression Elimination -debug: Replacing redundant declaration let tmp%5#0: uint64 = (select box_len%0#0 0u box_len%0#0) with copy of existing registers [Register(ir_type=uint64, name='tmp%1', version=0, source_location=box_storage/contract.py:35:15-31)] -debug: Replacing redundant declaration let tmp%13#0: bool = (< 2u box_len%1#0) with copy of existing registers [Register(ir_type=bool, name='tmp%9', version=0, source_location=box_storage/contract.py:38:15-43)] -debug: Found equivalence set: tmp%1#0, tmp%5#0 -debug: Replacing {tmp%5#0} with tmp%1#0 made 1 modifications -debug: Found equivalence set: tmp%9#0, tmp%13#0 -debug: Replacing {tmp%13#0} with tmp%9#0 made 1 modifications -debug: Replacing redundant declaration let tmp%14#0: uint64 = (select box_len%1#0 2u tmp%9#0) with copy of existing registers [Register(ir_type=uint64, name='tmp%10', version=0, source_location=box_storage/contract.py:38:15-43)] -debug: Found equivalence set: tmp%10#0, tmp%14#0 -debug: Replacing {tmp%14#0} with tmp%10#0 made 1 modifications +debug: Replacing redundant declaration let tmp%7#0: uint64 = (select tmp%0#0 0u tmp%0#0) with copy of existing registers [Register(ir_type=uint64, name='tmp%3', version=0, source_location=box_storage/contract.py:35:15-31)] +debug: Replacing redundant declaration let tmp%17#0: bool = (< 2u tmp%11#0) with copy of existing registers [Register(ir_type=bool, name='tmp%13', version=0, source_location=box_storage/contract.py:38:15-43)] +debug: Found equivalence set: tmp%3#0, tmp%7#0 +debug: Replacing {tmp%7#0} with tmp%3#0 made 1 modifications +debug: Found equivalence set: tmp%13#0, tmp%17#0 +debug: Replacing {tmp%17#0} with tmp%13#0 made 1 modifications +debug: Replacing redundant declaration let tmp%18#0: uint64 = (select tmp%11#0 2u tmp%13#0) with copy of existing registers [Register(ir_type=uint64, name='tmp%14', version=0, source_location=box_storage/contract.py:38:15-43)] +debug: Found equivalence set: tmp%14#0, tmp%18#0 +debug: Replacing {tmp%18#0} with tmp%14#0 made 1 modifications debug: Optimizing subroutine examples.box_storage.contract.BoxContract.arc4_box debug: Splitting parallel copies prior to optimization debug: Optimizer: Constant Replacer @@ -491,10 +491,10 @@ debug: Optimizing subroutine examples.box_storage.contract.BoxContract.box_blob debug: Splitting parallel copies prior to optimization debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation -debug: Found equivalence set: box_value%0#0, value#0 -debug: Replacing {box_value%0#0} with value#0 made 1 modifications -debug: Found equivalence set: box_exists%0#0, exists#0 -debug: Replacing {box_exists%0#0} with exists#0 made 1 modifications +debug: Found equivalence set: tuple_assignment%0#0, value#0 +debug: Replacing {tuple_assignment%0#0} with value#0 made 1 modifications +debug: Found equivalence set: tuple_assignment%1#0, exists#0 +debug: Replacing {tuple_assignment%1#0} with exists#0 made 1 modifications debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Removing unused variable box_blob#0 @@ -508,38 +508,38 @@ debug: Optimizing subroutine examples.box_storage.contract.BoxContract.box_map_t debug: Splitting parallel copies prior to optimization debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation -debug: Found equivalence set: box_value%1#0, value#1 -debug: Replacing {box_value%1#0} with value#1 made 1 modifications -debug: Found equivalence set: box_exists%3#0, exists#0 -debug: Replacing {box_exists%3#0} with exists#0 made 1 modifications +debug: Found equivalence set: tuple_assignment%0#0, value#1 +debug: Replacing {tuple_assignment%0#0} with value#1 made 1 modifications +debug: Found equivalence set: tuple_assignment%1#0, exists#0 +debug: Replacing {tuple_assignment%1#0} with exists#0 made 1 modifications debug: Optimizer: Intrinsic Simplifier debug: Simplified (concat "" tmp%0#0) to tmp%0#0 -debug: Simplified (concat "" tmp%1#0) to tmp%1#0 +debug: Simplified (concat "" tmp%2#0) to tmp%2#0 debug: Simplified (len "Hmmmmm") to 6u -debug: Simplified (concat "" tmp%4#0) to tmp%4#0 +debug: Simplified (concat "" tmp%6#0) to tmp%6#0 debug: Simplified (len "Hmmmmm") to 6u -debug: Simplified (concat "" tmp%7#0) to tmp%7#0 debug: Simplified (concat "" tmp%10#0) to tmp%10#0 -debug: Simplified (concat "" tmp%12#0) to tmp%12#0 +debug: Simplified (concat "" tmp%14#0) to tmp%14#0 +debug: Simplified (concat "" tmp%17#0) to tmp%17#0 debug: Optimizer: Remove Unused Variables debug: Removing unused variable key_0#0 debug: Removing unused variable key_1#0 debug: Removing unused variable value#0 -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del compound_key%0#0) +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del tmp%1#0) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump debug: Optimizer: Remove Empty Blocks debug: Optimizer: Remove Unreachable Blocks debug: Optimizer: Repeated Expression Elimination -debug: Replacing redundant declaration let tmp%1#0: bytes = (itob 0u) with copy of existing registers [Register(ir_type=bytes, name='tmp%0', version=0, source_location=box_storage/contract.py:74:8-27)] -debug: Replacing redundant declaration let tmp%4#0: bytes = (itob 0u) with copy of existing registers [Register(ir_type=bytes, name='tmp%0', version=0, source_location=box_storage/contract.py:74:8-27)] -debug: Replacing redundant declaration let tmp%10#0: bytes = (itob 1u) with copy of existing registers [Register(ir_type=bytes, name='tmp%7', version=0, source_location=box_storage/contract.py:78:15-65)] -debug: Replacing redundant declaration let tmp%12#0: bytes = (itob 0u) with copy of existing registers [Register(ir_type=bytes, name='tmp%0', version=0, source_location=box_storage/contract.py:74:8-27)] -debug: Found equivalence set: tmp%0#0, compound_key%0#0, tmp%1#0, compound_key%1#0, tmp%4#0, compound_key%2#0, tmp%12#0, compound_key%5#0 -debug: Replacing {compound_key%0#0, tmp%1#0, compound_key%1#0, tmp%4#0, compound_key%2#0, tmp%12#0, compound_key%5#0} with tmp%0#0 made 5 modifications -debug: Found equivalence set: tmp%7#0, compound_key%3#0, tmp%10#0, compound_key%4#0 -debug: Replacing {compound_key%3#0, tmp%10#0, compound_key%4#0} with tmp%7#0 made 2 modifications +debug: Replacing redundant declaration let tmp%2#0: bytes = (itob 0u) with copy of existing registers [Register(ir_type=bytes, name='tmp%0', version=0, source_location=box_storage/contract.py:74:8-27)] +debug: Replacing redundant declaration let tmp%6#0: bytes = (itob 0u) with copy of existing registers [Register(ir_type=bytes, name='tmp%0', version=0, source_location=box_storage/contract.py:74:8-27)] +debug: Replacing redundant declaration let tmp%14#0: bytes = (itob 1u) with copy of existing registers [Register(ir_type=bytes, name='tmp%10', version=0, source_location=box_storage/contract.py:78:15-65)] +debug: Replacing redundant declaration let tmp%17#0: bytes = (itob 0u) with copy of existing registers [Register(ir_type=bytes, name='tmp%0', version=0, source_location=box_storage/contract.py:74:8-27)] +debug: Found equivalence set: tmp%0#0, tmp%1#0, tmp%2#0, tmp%3#0, tmp%6#0, tmp%7#0, tmp%17#0, tmp%18#0 +debug: Replacing {tmp%1#0, tmp%2#0, tmp%3#0, tmp%6#0, tmp%7#0, tmp%17#0, tmp%18#0} with tmp%0#0 made 5 modifications +debug: Found equivalence set: tmp%10#0, tmp%11#0, tmp%14#0, tmp%15#0 +debug: Replacing {tmp%11#0, tmp%14#0, tmp%15#0} with tmp%10#0 made 2 modifications debug: Optimizing subroutine examples.box_storage.contract.BoxContract.box_map_set debug: Splitting parallel copies prior to optimization debug: Optimizer: Constant Replacer @@ -547,7 +547,7 @@ debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Simplified (concat "" tmp%0#0) to tmp%0#0 debug: Optimizer: Remove Unused Variables -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del compound_key%0#0) +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del tmp%1#0) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -617,7 +617,7 @@ debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "b") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -651,8 +651,8 @@ debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "0") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del 0x30) +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -697,8 +697,8 @@ debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del tmp%0#0) -debug: Removing unused variable tmp%2#0 -debug: Removing unused variable tmp%5#0 +debug: Removing unused variable tmp%4#0 +debug: Removing unused variable tmp%8#0 debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -708,8 +708,8 @@ debug: Optimizer: Repeated Expression Elimination debug: Optimizing subroutine examples.box_storage.contract.BoxContract.box_map_set debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation -debug: Found equivalence set: tmp%0#0, compound_key%0#0 -debug: Replacing {compound_key%0#0} with tmp%0#0 made 2 modifications +debug: Found equivalence set: tmp%0#0, tmp%1#0 +debug: Replacing {tmp%1#0} with tmp%0#0 made 2 modifications debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del tmp%0#0) @@ -722,8 +722,8 @@ debug: Optimizer: Repeated Expression Elimination debug: Optimizing subroutine examples.box_storage.contract.BoxContract.box_map_get debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation -debug: Found equivalence set: tmp%0#0, compound_key%0#0 -debug: Replacing {compound_key%0#0} with tmp%0#0 made 1 modifications +debug: Found equivalence set: tmp%0#0, tmp%1#0 +debug: Replacing {tmp%1#0} with tmp%0#0 made 1 modifications debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Optimizer: Inner Txn Field Replacer @@ -735,8 +735,8 @@ debug: Optimizer: Repeated Expression Elimination debug: Optimizing subroutine examples.box_storage.contract.BoxContract.box_map_exists debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation -debug: Found equivalence set: tmp%0#0, compound_key%0#0 -debug: Replacing {compound_key%0#0} with tmp%0#0 made 1 modifications +debug: Found equivalence set: tmp%0#0, tmp%1#0 +debug: Replacing {tmp%1#0} with tmp%0#0 made 1 modifications debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Optimizer: Inner Txn Field Replacer @@ -775,7 +775,7 @@ debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "b") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -809,8 +809,8 @@ debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "0") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del 0x30) +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -917,7 +917,7 @@ debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "b") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -951,8 +951,8 @@ debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "0") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del 0x30) +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -1059,7 +1059,7 @@ debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "b") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -1093,8 +1093,8 @@ debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "0") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del 0x30) +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -1200,7 +1200,7 @@ debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "b") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -1234,8 +1234,8 @@ debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del "0") -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del "BOX_C") +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del 0x30) +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%1#0: bool = (box_del 0x424f585f43) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -1585,56 +1585,52 @@ debug: Inserted boxes_exist_block@0.ops[6]: 'store box_exists%1#0 to l-stack (co debug: Replaced boxes_exist_block@0.ops[15]: 'load box_exists%1#0' with 'load box_exists%1#0 from l-stack (no copy)' debug: Inserted boxes_exist_block@0.ops[2]: 'store box_exists%0#0 to l-stack (copy)' debug: Replaced boxes_exist_block@0.ops[15]: 'load box_exists%0#0' with 'load box_exists%0#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[25]: 'store tmp%3#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[27]: 'load tmp%3#0' with 'load tmp%3#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[35]: 'store tmp%7#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[37]: 'load tmp%7#0' with 'load tmp%7#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[40]: 'store tmp%8#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[42]: 'load tmp%8#0' with 'load tmp%8#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[73]: 'store tmp%12#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[75]: 'load tmp%12#0' with 'load tmp%12#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[83]: 'store tmp%16#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[85]: 'load tmp%16#0' with 'load tmp%16#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[88]: 'store tmp%17#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[90]: 'load tmp%17#0' with 'load tmp%17#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[8]: 'store box_exists%0#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[11]: 'load box_exists%0#0' with 'load box_exists%0#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[14]: 'store box_len%0#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[16]: 'load box_len%0#0' with 'load box_len%0#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[54]: 'store box_exists%1#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[57]: 'load box_exists%1#0' with 'load box_exists%1#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[10]: 'store box_len%0#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[14]: 'load box_len%0#0' with 'load box_len%0#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[22]: 'store box_len%0#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[25]: 'load box_len%0#0' with 'load box_len%0#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[24]: 'store tmp%2#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[28]: 'load tmp%2#0' with 'load tmp%2#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[35]: 'store tmp%6#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[39]: 'load tmp%6#0' with 'load tmp%6#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[65]: 'store box_len%1#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[68]: 'load box_len%1#0' with 'load box_len%1#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[67]: 'store tmp%9#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[71]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[76]: 'store box_len%1#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[79]: 'load box_len%1#0' with 'load box_len%1#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[78]: 'store tmp%11#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[82]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[89]: 'store tmp%15#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[93]: 'load tmp%15#0' with 'load tmp%15#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[18]: 'store box_len%0#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[22]: 'load box_len%0#0' with 'load box_len%0#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[35]: 'store tmp%1#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[40]: 'load tmp%1#0' with 'load tmp%1#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[62]: 'store box_len%1#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[67]: 'load box_len%1#0' with 'load box_len%1#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[91]: 'store tmp%10#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[96]: 'load tmp%10#0' with 'load tmp%10#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[73]: 'store box_len%1#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[79]: 'load box_len%1#0' with 'load box_len%1#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[20]: 'store tmp%1#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[35]: 'load tmp%1#0' with 'load tmp%1#0 from l-stack (no copy)' -debug: Inserted slice_box_block@0.ops[78]: 'store tmp%10#0 to l-stack (copy)' -debug: Replaced slice_box_block@0.ops[93]: 'load tmp%10#0' with 'load tmp%10#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[9]: 'store tmp%0#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[11]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[24]: 'store tmp%5#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[26]: 'load tmp%5#0' with 'load tmp%5#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[34]: 'store tmp%9#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[36]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[39]: 'store tmp%10#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[41]: 'load tmp%10#0' with 'load tmp%10#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[70]: 'store tmp%16#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[72]: 'load tmp%16#0' with 'load tmp%16#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[80]: 'store tmp%20#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[82]: 'load tmp%20#0' with 'load tmp%20#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[85]: 'store tmp%21#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[87]: 'load tmp%21#0' with 'load tmp%21#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[12]: 'store tmp%0#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[14]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[53]: 'store tmp%11#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[56]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[19]: 'store tmp%0#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[22]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[21]: 'store tmp%4#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[25]: 'load tmp%4#0' with 'load tmp%4#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[32]: 'store tmp%8#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[36]: 'load tmp%8#0' with 'load tmp%8#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[60]: 'store tmp%11#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[63]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[62]: 'store tmp%13#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[66]: 'load tmp%13#0' with 'load tmp%13#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[71]: 'store tmp%11#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[74]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[73]: 'store tmp%15#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[77]: 'load tmp%15#0' with 'load tmp%15#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[84]: 'store tmp%19#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[88]: 'load tmp%19#0' with 'load tmp%19#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[15]: 'store tmp%0#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[19]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[32]: 'store tmp%3#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[37]: 'load tmp%3#0' with 'load tmp%3#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[85]: 'store tmp%14#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[90]: 'load tmp%14#0' with 'load tmp%14#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[67]: 'store tmp%11#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[73]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[17]: 'store tmp%3#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[32]: 'load tmp%3#0' with 'load tmp%3#0 from l-stack (no copy)' +debug: Inserted slice_box_block@0.ops[72]: 'store tmp%14#0 to l-stack (copy)' +debug: Replaced slice_box_block@0.ops[87]: 'load tmp%14#0' with 'load tmp%14#0 from l-stack (no copy)' debug: Inserted arc4_box_block@0.ops[11]: 'store reinterpret_biguint%0#0 to l-stack (copy)' debug: Replaced arc4_box_block@0.ops[13]: 'load reinterpret_biguint%0#0' with 'load reinterpret_biguint%0#0 from l-stack (no copy)' debug: Inserted arc4_box_block@0.ops[16]: 'store tmp%0#0 to l-stack (copy)' @@ -1685,18 +1681,18 @@ debug: Inserted box_blob_block@0.ops[28]: 'store tmp%1#0 to l-stack (copy)' debug: Replaced box_blob_block@0.ops[31]: 'load tmp%1#0' with 'load tmp%1#0 from l-stack (no copy)' debug: Inserted box_blob_block@0.ops[45]: 'store exists#0 to l-stack (copy)' debug: Replaced box_blob_block@0.ops[48]: 'load exists#0' with 'load exists#0 from l-stack (no copy)' -debug: Inserted box_blob_block@0.ops[57]: 'store box_value%1#0 to l-stack (copy)' -debug: Replaced box_blob_block@0.ops[60]: 'load box_value%1#0' with 'load box_value%1#0 from l-stack (no copy)' +debug: Inserted box_blob_block@0.ops[57]: 'store None_get_ex%0#0 to l-stack (copy)' +debug: Replaced box_blob_block@0.ops[60]: 'load None_get_ex%0#0' with 'load None_get_ex%0#0 from l-stack (no copy)' debug: Inserted box_blob_block@0.ops[75]: 'store tmp%7#0 to l-stack (copy)' debug: Replaced box_blob_block@0.ops[78]: 'load tmp%7#0' with 'load tmp%7#0 from l-stack (no copy)' -debug: Inserted box_blob_block@0.ops[82]: 'store box_exists%2#0 to l-stack (copy)' -debug: Replaced box_blob_block@0.ops[85]: 'load box_exists%2#0' with 'load box_exists%2#0 from l-stack (no copy)' -debug: Inserted box_blob_block@0.ops[89]: 'store box_exists%3#0 to l-stack (copy)' -debug: Replaced box_blob_block@0.ops[92]: 'load box_exists%3#0' with 'load box_exists%3#0 from l-stack (no copy)' -debug: Inserted box_blob_block@0.ops[91]: 'store box_len%1#0 to l-stack (copy)' -debug: Replaced box_blob_block@0.ops[95]: 'load box_len%1#0' with 'load box_len%1#0 from l-stack (no copy)' -debug: Inserted box_blob_block@0.ops[56]: 'store box_exists%1#0 to l-stack (copy)' -debug: Replaced box_blob_block@0.ops[62]: 'load box_exists%1#0' with 'load box_exists%1#0 from l-stack (no copy)' +debug: Inserted box_blob_block@0.ops[82]: 'store box_exists%0#0 to l-stack (copy)' +debug: Replaced box_blob_block@0.ops[85]: 'load box_exists%0#0' with 'load box_exists%0#0 from l-stack (no copy)' +debug: Inserted box_blob_block@0.ops[89]: 'store check%0#0 to l-stack (copy)' +debug: Replaced box_blob_block@0.ops[92]: 'load check%0#0' with 'load check%0#0 from l-stack (no copy)' +debug: Inserted box_blob_block@0.ops[91]: 'store value%0#0 to l-stack (copy)' +debug: Replaced box_blob_block@0.ops[95]: 'load value%0#0' with 'load value%0#0 from l-stack (no copy)' +debug: Inserted box_blob_block@0.ops[56]: 'store None_get_ex%1#0 to l-stack (copy)' +debug: Replaced box_blob_block@0.ops[62]: 'load None_get_ex%1#0' with 'load None_get_ex%1#0 from l-stack (no copy)' debug: Inserted box_blob_block@0.ops[24]: 'store first_64#0 to l-stack (copy)' debug: Replaced box_blob_block@0.ops[31]: 'load first_64#0' with 'load first_64#0 from l-stack (no copy)' debug: Inserted box_blob_block@0.ops[69]: 'store sender_bytes#0 to l-stack (copy)' @@ -1717,42 +1713,42 @@ debug: Inserted box_blob_block@0.ops[31]: 'store app_address#0 to l-stack (copy) debug: Replaced box_blob_block@0.ops[83]: 'load app_address#0' with 'load app_address#0 from l-stack (no copy)' debug: Inserted box_map_test_block@0.ops[2]: 'store tmp%0#0 to l-stack (copy)' debug: Replaced box_map_test_block@0.ops[4]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[19]: 'store tmp%3#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[21]: 'load tmp%3#0' with 'load tmp%3#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[32]: 'store tmp%6#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[34]: 'load tmp%6#0' with 'load tmp%6#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[38]: 'store tmp%7#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[40]: 'load tmp%7#0' with 'load tmp%7#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[48]: 'store tmp%8#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[50]: 'load tmp%8#0' with 'load tmp%8#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[53]: 'store tmp%9#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[55]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[63]: 'store tmp%11#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[65]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[12]: 'store box_exists%0#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[15]: 'load box_exists%0#0' with 'load box_exists%0#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[26]: 'store box_exists%1#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[29]: 'load box_exists%1#0' with 'load box_exists%1#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[45]: 'store box_value%0#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[48]: 'load box_value%0#0' with 'load box_value%0#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[19]: 'store tmp%5#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[21]: 'load tmp%5#0' with 'load tmp%5#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[32]: 'store tmp%9#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[34]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[38]: 'store tmp%10#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[40]: 'load tmp%10#0' with 'load tmp%10#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[48]: 'store tmp%12#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[50]: 'load tmp%12#0' with 'load tmp%12#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[53]: 'store tmp%13#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[55]: 'load tmp%13#0' with 'load tmp%13#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[63]: 'store tmp%16#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[65]: 'load tmp%16#0' with 'load tmp%16#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[12]: 'store check%0#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[15]: 'load check%0#0' with 'load check%0#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[26]: 'store check%1#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[29]: 'load check%1#0' with 'load check%1#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[45]: 'store None_get_ex%0#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[48]: 'load None_get_ex%0#0' with 'load None_get_ex%0#0 from l-stack (no copy)' debug: Inserted box_map_test_block@0.ops[62]: 'store exists#0 to l-stack (copy)' debug: Replaced box_map_test_block@0.ops[65]: 'load exists#0' with 'load exists#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[73]: 'store box_exists%4#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[76]: 'load box_exists%4#0' with 'load box_exists%4#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[73]: 'store box_exists%0#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[76]: 'load box_exists%0#0' with 'load box_exists%0#0 from l-stack (no copy)' debug: Inserted box_map_test_block@0.ops[5]: 'store tmp%0#0 to l-stack (copy)' debug: Replaced box_map_test_block@0.ops[8]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' debug: Inserted box_map_test_block@0.ops[9]: 'store tmp%0#0 to l-stack (copy)' debug: Replaced box_map_test_block@0.ops[12]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[16]: 'store box_len%0#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[20]: 'load box_len%0#0' with 'load box_len%0#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[31]: 'store box_len%1#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[35]: 'load box_len%1#0' with 'load box_len%1#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[48]: 'store box_exists%2#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[54]: 'load box_exists%2#0' with 'load box_exists%2#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[16]: 'store value%0#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[20]: 'load value%0#0' with 'load value%0#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[31]: 'store value%1#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[35]: 'load value%1#0' with 'load value%1#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[48]: 'store None_get_ex%1#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[54]: 'load None_get_ex%1#0' with 'load None_get_ex%1#0 from l-stack (no copy)' debug: Inserted box_map_test_block@0.ops[13]: 'store tmp%0#0 to l-stack (copy)' debug: Replaced box_map_test_block@0.ops[28]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' -debug: Inserted box_map_test_block@0.ops[48]: 'store tmp%7#0 to l-stack (copy)' -debug: Replaced box_map_test_block@0.ops[67]: 'load tmp%7#0' with 'load tmp%7#0 from l-stack (no copy)' +debug: Inserted box_map_test_block@0.ops[48]: 'store tmp%10#0 to l-stack (copy)' +debug: Replaced box_map_test_block@0.ops[67]: 'load tmp%10#0' with 'load tmp%10#0 from l-stack (no copy)' debug: Inserted box_map_test_block@0.ops[29]: 'store tmp%0#0 to l-stack (copy)' debug: Replaced box_map_test_block@0.ops[79]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' debug: Inserted box_map_set_block@0.ops[2]: 'store tmp%0#0 to l-stack (copy)' diff --git a/examples/calculator/out/contract.awst b/examples/calculator/out/contract.awst index f454f9c9e..56fdac0cf 100644 --- a/examples/calculator/out/contract.awst +++ b/examples/calculator/out/contract.awst @@ -3,10 +3,10 @@ SUB = 2 MUL = 3 DIV = 4 -subroutine itoa(i: algopy.UInt64): algopy.Bytes +subroutine itoa(i: uint64): bytes { - digits: algopy.Bytes = '0123456789' - radix: algopy.UInt64 = len(digits) + digits: bytes = '0123456789' + radix: uint64 = len(digits) if (i < radix) { return digits[i] } @@ -15,28 +15,28 @@ subroutine itoa(i: algopy.UInt64): algopy.Bytes contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - num_args: algopy.UInt64 = txn() + num_args: uint64 = txn() if (num_args == 0u) { - a: algopy.UInt64 = 0u - b: algopy.UInt64 = 0u - action: algopy.UInt64 = 0u + a: uint64 = 0u + b: uint64 = 0u + action: uint64 = 0u log(itob(a)) log(itob(b)) } else { assert(num_args == 3u, comment="Expected 3 args") - action_b: algopy.Bytes = txna() - action: algopy.UInt64 = btoi(action_b) - a_bytes: algopy.Bytes = txna() - b_bytes: algopy.Bytes = txna() + action_b: bytes = txna() + action: uint64 = btoi(action_b) + a_bytes: bytes = txna() + b_bytes: bytes = txna() log(a_bytes) log(b_bytes) - a: algopy.UInt64 = btoi(a_bytes) - b: algopy.UInt64 = btoi(b_bytes) + a: uint64 = btoi(a_bytes) + b: uint64 = btoi(b_bytes) } - result: algopy.UInt64 = this::do_calc(action, a, b) - result_b: algopy.Bytes = examples.calculator.contract::itoa(a) + this::op(action) + examples.calculator.contract::itoa(b) + ' = ' + examples.calculator.contract::itoa(result) + result: uint64 = this::do_calc(action, a, b) + result_b: bytes = examples.calculator.contract::itoa(a) + this::op(action) + examples.calculator.contract::itoa(b) + ' = ' + examples.calculator.contract::itoa(result) log(result_b) return 1u } @@ -46,7 +46,7 @@ contract MyContract return true } - subroutine op(action: algopy.UInt64): algopy.Bytes + subroutine op(action: uint64): bytes { if (action == 1u) { return ' + ' @@ -67,7 +67,7 @@ contract MyContract } } - subroutine do_calc(maybe_action: algopy.UInt64, a: algopy.UInt64, b: algopy.UInt64): algopy.UInt64 + subroutine do_calc(maybe_action: uint64, a: uint64, b: uint64): uint64 { if (maybe_action == 1u) { return this::add(a, b) @@ -88,22 +88,22 @@ contract MyContract } } - subroutine add(a: algopy.UInt64, b: algopy.UInt64): algopy.UInt64 + subroutine add(a: uint64, b: uint64): uint64 { return a + b } - subroutine sub(a: algopy.UInt64, b: algopy.UInt64): algopy.UInt64 + subroutine sub(a: uint64, b: uint64): uint64 { return a - b } - subroutine mul(a: algopy.UInt64, b: algopy.UInt64): algopy.UInt64 + subroutine mul(a: uint64, b: uint64): uint64 { return a * b } - subroutine div(a: algopy.UInt64, b: algopy.UInt64): algopy.UInt64 + subroutine div(a: uint64, b: uint64): uint64 { return a // b } diff --git a/examples/global_state/out/AppStateContract.approval.mir b/examples/global_state/out/AppStateContract.approval.mir index 4fa757ade..fc1e6aefc 100644 --- a/examples/global_state/out/AppStateContract.approval.mir +++ b/examples/global_state/out/AppStateContract.approval.mir @@ -35,13 +35,13 @@ main_entrypoint@2: pop // global_int_full_exists%1#0 self.global_int_full global_state/contract.py:24 // virtual: load global_int_full_exists%1#0 from l-stack (no copy) global_int_full_exists%1#0 assert self.global_int_full global_state/contract.py:24 assert // assert self.global_int_full global_state/contract.py:24 - int 0 // 0 self.global_int_full global_state/contract.py:25 + int 0 // 0 self.global_int_full.value global_state/contract.py:25 byte "global_int_full" // 0,"global_int_full" self.global_int_full global_state/contract.py:6 - app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_int_full global_state/contract.py:25 - // virtual: store global_int_full_exists%2#0 to l-stack (no copy) global_int_full_exists%2#0,{app_global_get_ex}.0 self.global_int_full global_state/contract.py:25 - // virtual: store global_int_full_value%0#0 to l-stack (no copy) global_int_full_value%0#0,global_int_full_exists%2#0 self.global_int_full global_state/contract.py:25 - // virtual: load global_int_full_exists%2#0 from l-stack (no copy) global_int_full_value%0#0,global_int_full_exists%2#0 self.global_int_full global_state/contract.py:25 - assert // check global_int_full exists // global_int_full_value%0#0 self.global_int_full global_state/contract.py:25 + app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_int_full.value global_state/contract.py:25 + // virtual: store global_int_full_exists%2#0 to l-stack (no copy) global_int_full_exists%2#0,{app_global_get_ex}.0 self.global_int_full.value global_state/contract.py:25 + // virtual: store global_int_full_value%0#0 to l-stack (no copy) global_int_full_value%0#0,global_int_full_exists%2#0 self.global_int_full.value global_state/contract.py:25 + // virtual: load global_int_full_exists%2#0 from l-stack (no copy) global_int_full_value%0#0,global_int_full_exists%2#0 self.global_int_full.value global_state/contract.py:25 + assert // check global_int_full exists // global_int_full_value%0#0 self.global_int_full.value global_state/contract.py:25 // virtual: load global_int_full_value%0#0 from l-stack (no copy) global_int_full_value%0#0 self.global_int_full.value == 55 global_state/contract.py:25 int 55 // global_int_full_value%0#0,55 55 global_state/contract.py:25 == // {==} self.global_int_full.value == 55 global_state/contract.py:25 @@ -61,7 +61,7 @@ main_entrypoint@2: byte "global_int_no_default" // "global_int_no_default" self.global_int_no_default global_state/contract.py:8 int 44 // "global_int_no_default",44 UInt64(44) global_state/contract.py:27 app_global_put // self.global_int_no_default.value = UInt64(44) global_state/contract.py:27 - int 0 // 0 self.global_int_no_default global_state/contract.py:28 + int 0 // 0 self.global_int_no_default.maybe global_state/contract.py:28 byte "global_int_no_default" // 0,"global_int_no_default" self.global_int_no_default global_state/contract.py:8 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_int_no_default.maybe() global_state/contract.py:28 // virtual: store i_exists#0 to l-stack (no copy) i_exists#0,{app_global_get_ex}.0 self.global_int_no_default.maybe() global_state/contract.py:28 @@ -94,20 +94,20 @@ main_entrypoint@2: pop // global_bytes_full_exists%1#0 self.global_bytes_full global_state/contract.py:33 // virtual: load global_bytes_full_exists%1#0 from l-stack (no copy) global_bytes_full_exists%1#0 assert self.global_bytes_full global_state/contract.py:33 assert // assert self.global_bytes_full global_state/contract.py:33 - int 0 // 0 self.global_bytes_full global_state/contract.py:34 + int 0 // 0 self.global_bytes_full.value global_state/contract.py:34 byte "global_bytes_full" // 0,"global_bytes_full" self.global_bytes_full global_state/contract.py:10 - app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_full global_state/contract.py:34 - // virtual: store global_bytes_full_exists%2#0 to l-stack (no copy) global_bytes_full_exists%2#0,{app_global_get_ex}.0 self.global_bytes_full global_state/contract.py:34 - // virtual: store global_bytes_full_value%0#0 to l-stack (no copy) global_bytes_full_value%0#0,global_bytes_full_exists%2#0 self.global_bytes_full global_state/contract.py:34 - // virtual: load global_bytes_full_exists%2#0 from l-stack (no copy) global_bytes_full_value%0#0,global_bytes_full_exists%2#0 self.global_bytes_full global_state/contract.py:34 - assert // check global_bytes_full exists // global_bytes_full_value%0#0 self.global_bytes_full global_state/contract.py:34 + app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_full.value global_state/contract.py:34 + // virtual: store global_bytes_full_exists%2#0 to l-stack (no copy) global_bytes_full_exists%2#0,{app_global_get_ex}.0 self.global_bytes_full.value global_state/contract.py:34 + // virtual: store global_bytes_full_value%0#0 to l-stack (no copy) global_bytes_full_value%0#0,global_bytes_full_exists%2#0 self.global_bytes_full.value global_state/contract.py:34 + // virtual: load global_bytes_full_exists%2#0 from l-stack (no copy) global_bytes_full_value%0#0,global_bytes_full_exists%2#0 self.global_bytes_full.value global_state/contract.py:34 + assert // check global_bytes_full exists // global_bytes_full_value%0#0 self.global_bytes_full.value global_state/contract.py:34 // virtual: load global_bytes_full_value%0#0 from l-stack (no copy) global_bytes_full_value%0#0 self.global_bytes_full.value == b"Hello" global_state/contract.py:34 byte "Hello" // global_bytes_full_value%0#0,"Hello" b"Hello" global_state/contract.py:34 == // {==} self.global_bytes_full.value == b"Hello" global_state/contract.py:34 // virtual: store tmp%5#0 to l-stack (no copy) tmp%5#0 self.global_bytes_full.value == b"Hello" global_state/contract.py:34 // virtual: load tmp%5#0 from l-stack (no copy) tmp%5#0 assert self.global_bytes_full.value == b"Hello" global_state/contract.py:34 assert // assert self.global_bytes_full.value == b"Hello" global_state/contract.py:34 - int 0 // 0 self.global_bytes_full global_state/contract.py:35 + int 0 // 0 self.global_bytes_full.get global_state/contract.py:35 byte "global_bytes_full" // 0,"global_bytes_full" self.global_bytes_full global_state/contract.py:10 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_full.get(Bytes(b"default")) global_state/contract.py:35 cover 1 // store global_bytes_full_get_ex%1#0 to l-stack (no copy) global_bytes_full_get_ex%1#0,{app_global_get_ex}.0 self.global_bytes_full.get(Bytes(b"default")) global_state/contract.py:35 @@ -136,7 +136,7 @@ main_entrypoint@2: byte "global_bytes_no_default" // "global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:12 byte "World" // "global_bytes_no_default","World" b"World" global_state/contract.py:37 app_global_put // self.global_bytes_no_default.value = Bytes(b"World") global_state/contract.py:37 - int 0 // 0 self.global_bytes_no_default global_state/contract.py:38 + int 0 // 0 self.global_bytes_no_default.maybe global_state/contract.py:38 byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:12 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_no_default.maybe() global_state/contract.py:38 // virtual: store b_exists#0 to l-stack (no copy) b_exists#0,{app_global_get_ex}.0 self.global_bytes_no_default.maybe() global_state/contract.py:38 @@ -151,7 +151,7 @@ main_entrypoint@2: assert // assert b_value == b"World" global_state/contract.py:40 byte "global_bytes_no_default" // "global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:12 app_global_del // del self.global_bytes_no_default.value global_state/contract.py:41 - int 0 // 0 self.global_bytes_no_default global_state/contract.py:42 + int 0 // 0 self.global_bytes_no_default.maybe global_state/contract.py:42 byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:12 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_no_default.maybe() global_state/contract.py:42 cover 1 // store b_exists#0 to l-stack (no copy) b_exists#0,{app_global_get_ex}.0 self.global_bytes_no_default.maybe() global_state/contract.py:42 @@ -161,7 +161,7 @@ main_entrypoint@2: // virtual: store tmp%10#0 to l-stack (no copy) tmp%10#0 not b_exists global_state/contract.py:43 // virtual: load tmp%10#0 from l-stack (no copy) tmp%10#0 assert not b_exists global_state/contract.py:43 assert // assert not b_exists global_state/contract.py:43 - int 0 // 0 self.global_bytes_no_default global_state/contract.py:45 + int 0 // 0 self.global_bytes_no_default.get global_state/contract.py:45 byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:12 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_no_default.get(Bytes(b"default")) global_state/contract.py:45 cover 1 // store global_bytes_no_default_get_ex%1#0 to l-stack (no copy) global_bytes_no_default_get_ex%1#0,{app_global_get_ex}.0 self.global_bytes_no_default.get(Bytes(b"default")) global_state/contract.py:45 @@ -197,13 +197,13 @@ main_entrypoint@2: byte "global_bool_no_default" // "global_bool_no_default" self.global_bool_no_default global_state/contract.py:16 int 1 // "global_bool_no_default",1 True global_state/contract.py:51 app_global_put // self.global_bool_no_default.value = True global_state/contract.py:51 - int 0 // 0 alue'\nassert not self.global_bool_full global_state/contract.py:53-54 + int 0 // 0 alue'\nassert not self.global_bool_full.value global_state/contract.py:53-54 byte "global_bool_full" // 0,"global_bool_full" self.global_bool_full global_state/contract.py:14 - app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 alue'\nassert not self.global_bool_full global_state/contract.py:53-54 - // virtual: store global_bool_full_exists%2#0 to l-stack (no copy) global_bool_full_exists%2#0,{app_global_get_ex}.0 alue'\nassert not self.global_bool_full global_state/contract.py:53-54 - // virtual: store global_bool_full_value%0#0 to l-stack (no copy) global_bool_full_value%0#0,global_bool_full_exists%2#0 alue'\nassert not self.global_bool_full global_state/contract.py:53-54 - // virtual: load global_bool_full_exists%2#0 from l-stack (no copy) global_bool_full_value%0#0,global_bool_full_exists%2#0 alue'\nassert not self.global_bool_full global_state/contract.py:53-54 - assert // check global_bool_full exists // global_bool_full_value%0#0 alue'\nassert not self.global_bool_full global_state/contract.py:53-54 + app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 alue'\nassert not self.global_bool_full.value global_state/contract.py:53-54 + // virtual: store global_bool_full_exists%2#0 to l-stack (no copy) global_bool_full_exists%2#0,{app_global_get_ex}.0 alue'\nassert not self.global_bool_full.value global_state/contract.py:53-54 + // virtual: store global_bool_full_value%0#0 to l-stack (no copy) global_bool_full_value%0#0,global_bool_full_exists%2#0 alue'\nassert not self.global_bool_full.value global_state/contract.py:53-54 + // virtual: load global_bool_full_exists%2#0 from l-stack (no copy) global_bool_full_value%0#0,global_bool_full_exists%2#0 alue'\nassert not self.global_bool_full.value global_state/contract.py:53-54 + assert // check global_bool_full exists // global_bool_full_value%0#0 alue'\nassert not self.global_bool_full.value global_state/contract.py:53-54 // virtual: load global_bool_full_value%0#0 from l-stack (no copy) global_bool_full_value%0#0 t 'value'\nassert not self.global_bool_full.value global_state/contract.py:53-54 ! // {!} t 'value'\nassert not self.global_bool_full.value global_state/contract.py:53-54 // virtual: store tmp%14#0 to l-stack (no copy) tmp%14#0 t 'value'\nassert not self.global_bool_full.value global_state/contract.py:53-54 @@ -218,13 +218,13 @@ main_entrypoint@2: assert // check global_bool_simplified exists // global_bool_simplified_value%0#0 self.global_bool_simplified global_state/contract.py:55 // virtual: load global_bool_simplified_value%0#0 from l-stack (no copy) global_bool_simplified_value%0#0 assert self.global_bool_simplified global_state/contract.py:55 assert // assert self.global_bool_simplified global_state/contract.py:55 - int 0 // 0 self.global_bool_no_default global_state/contract.py:56 + int 0 // 0 self.global_bool_no_default.value global_state/contract.py:56 byte "global_bool_no_default" // 0,"global_bool_no_default" self.global_bool_no_default global_state/contract.py:16 - app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bool_no_default global_state/contract.py:56 - // virtual: store global_bool_no_default_exists%2#0 to l-stack (no copy) global_bool_no_default_exists%2#0,{app_global_get_ex}.0 self.global_bool_no_default global_state/contract.py:56 - // virtual: store global_bool_no_default_value%0#0 to l-stack (no copy) global_bool_no_default_value%0#0,global_bool_no_default_exists%2#0 self.global_bool_no_default global_state/contract.py:56 - // virtual: load global_bool_no_default_exists%2#0 from l-stack (no copy) global_bool_no_default_value%0#0,global_bool_no_default_exists%2#0 self.global_bool_no_default global_state/contract.py:56 - assert // check global_bool_no_default exists // global_bool_no_default_value%0#0 self.global_bool_no_default global_state/contract.py:56 + app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bool_no_default.value global_state/contract.py:56 + // virtual: store global_bool_no_default_exists%2#0 to l-stack (no copy) global_bool_no_default_exists%2#0,{app_global_get_ex}.0 self.global_bool_no_default.value global_state/contract.py:56 + // virtual: store global_bool_no_default_value%0#0 to l-stack (no copy) global_bool_no_default_value%0#0,global_bool_no_default_exists%2#0 self.global_bool_no_default.value global_state/contract.py:56 + // virtual: load global_bool_no_default_exists%2#0 from l-stack (no copy) global_bool_no_default_value%0#0,global_bool_no_default_exists%2#0 self.global_bool_no_default.value global_state/contract.py:56 + assert // check global_bool_no_default exists // global_bool_no_default_value%0#0 self.global_bool_no_default.value global_state/contract.py:56 // virtual: load global_bool_no_default_value%0#0 from l-stack (no copy) global_bool_no_default_value%0#0 assert self.global_bool_no_default.value global_state/contract.py:56 assert // assert self.global_bool_no_default.value global_state/contract.py:56 int 1 // 1 True global_state/contract.py:58 diff --git a/examples/global_state/out/contract.awst b/examples/global_state/out/contract.awst index 896b0132b..5dacce493 100644 --- a/examples/global_state/out/contract.awst +++ b/examples/global_state/out/contract.awst @@ -1,26 +1,26 @@ contract AppStateContract { globals { - ['global_int_simplified']: algopy.UInt64 - ['global_bytes_simplified']: algopy.Bytes + ['global_int_simplified']: uint64 + ['global_bytes_simplified']: bytes ['global_bool_simplified']: bool - ['global_int_full']: algopy.UInt64 - ['global_int_no_default']: algopy.UInt64 - ['global_bytes_full']: algopy.Bytes - ['global_bytes_no_default']: algopy.Bytes + ['global_int_full']: uint64 + ['global_int_no_default']: uint64 + ['global_bytes_full']: bytes + ['global_bytes_no_default']: bytes ['global_bool_full']: bool ['global_bool_no_default']: bool - ['global_asset']: algopy.Asset - ['global_application']: algopy.Application - ['global_account']: algopy.Account + ['global_asset']: asset + ['global_application']: application + ['global_account']: account } constructor() { - this.global_int_full: algopy.UInt64 = 55u - this.global_int_simplified: algopy.UInt64 = 33u - this.global_bytes_full: algopy.Bytes = 'Hello' - this.global_bytes_simplified: algopy.Bytes = 'Hello' + this.global_int_full: uint64 = 55u + this.global_int_simplified: uint64 = 33u + this.global_bytes_full: bytes = 'Hello' + this.global_bytes_simplified: bytes = 'Hello' this.global_bool_full: bool = false this.global_bool_simplified: bool = true } @@ -31,8 +31,8 @@ contract AppStateContract assert(STATE_EXISTS(this.global_int_full)) assert(this.global_int_full == 55u) assert(!(STATE_EXISTS(this.global_int_no_default))) - this.global_int_no_default: algopy.UInt64 = 44u - (i_value, i_exists): tuple[algopy.UInt64, bool] = STATE_GET_EX(this.global_int_no_default) + this.global_int_no_default: uint64 = 44u + (i_value, i_exists): tuple = STATE_GET_EX(this.global_int_no_default) assert(i_exists) assert(i_value == 44u) assert(this.global_bytes_simplified == 'Hello') @@ -40,12 +40,12 @@ contract AppStateContract assert(this.global_bytes_full == 'Hello') assert(STATE_GET(this.global_bytes_full, default='default') == 'Hello') assert(!(STATE_EXISTS(this.global_bytes_no_default))) - this.global_bytes_no_default: algopy.Bytes = 'World' - (b_value, b_exists): tuple[algopy.Bytes, bool] = STATE_GET_EX(this.global_bytes_no_default) + this.global_bytes_no_default: bytes = 'World' + (b_value, b_exists): tuple = STATE_GET_EX(this.global_bytes_no_default) assert(b_exists) assert(b_value == 'World') STATE_DELETE(this.global_bytes_no_default) - (b_value, b_exists): tuple[algopy.Bytes, bool] = STATE_GET_EX(this.global_bytes_no_default) + (b_value, b_exists): tuple = STATE_GET_EX(this.global_bytes_no_default) assert(!(b_exists)) assert(STATE_GET(this.global_bytes_no_default, default='default') == 'default') assert(STATE_EXISTS(this.global_bool_full)) diff --git a/examples/hello_world/out/contract.awst b/examples/hello_world/out/contract.awst index 15068f274..70fddf93c 100644 --- a/examples/hello_world/out/contract.awst +++ b/examples/hello_world/out/contract.awst @@ -2,7 +2,7 @@ contract HelloWorldContract { approval_program(): bool { - name: algopy.Bytes = txna() + name: bytes = txna() log('Hello, ' + name) return true } diff --git a/examples/hello_world_arc4/out/contract.awst b/examples/hello_world_arc4/out/contract.awst index 35220e88b..8ab8e6571 100644 --- a/examples/hello_world_arc4/out/contract.awst +++ b/examples/hello_world_arc4/out/contract.awst @@ -1,6 +1,6 @@ contract HelloWorldContract { - abimethod hello(name: algopy.String): algopy.String + abimethod hello(name: string): string { return 'Hello, ' + name } diff --git a/examples/local_state/out/local_state_contract.awst b/examples/local_state/out/local_state_contract.awst index d38b67452..34d932560 100644 --- a/examples/local_state/out/local_state_contract.awst +++ b/examples/local_state/out/local_state_contract.awst @@ -1,7 +1,7 @@ contract LocalStateContract { locals { - ['local']: algopy.Bytes + ['local']: bytes ['local_bool']: bool } @@ -11,7 +11,7 @@ contract LocalStateContract approval_program(): bool { - if (txn() == reinterpret_cast(0u)) { + if (txn() == reinterpret_cast(0u)) { return true } if (!(txn() IS IN (NoOp, OptIn))) { @@ -20,7 +20,7 @@ contract LocalStateContract if (txn() == 0u) { return false } - method: algopy.Bytes = txna() + method: bytes = txna() if (txn() == 1u) { if (method == 'get_guaranteed_data') { log(this::get_guaranteed_data(txn())) @@ -60,29 +60,29 @@ contract LocalStateContract return true } - subroutine get_guaranteed_data(for_account: algopy.Account): algopy.Bytes + subroutine get_guaranteed_data(for_account: account): bytes { return this.local[for_account] } - subroutine get_data_with_default(for_account: algopy.Account, default: algopy.Bytes): algopy.Bytes + subroutine get_data_with_default(for_account: account, default: bytes): bytes { return STATE_GET(this.local[for_account], default=default) } - subroutine get_data_or_assert(for_account: algopy.Account): algopy.Bytes + subroutine get_data_or_assert(for_account: account): bytes { - (result, exists): tuple[algopy.Bytes, bool] = STATE_GET_EX(this.local[for_account]) + (result, exists): tuple = STATE_GET_EX(this.local[for_account]) assert(exists, comment="no data for account") return result } - subroutine set_data(for_account: algopy.Account, value: algopy.Bytes): None + subroutine set_data(for_account: account, value: bytes): void { - this.local[for_account]: algopy.Bytes = value + this.local[for_account]: bytes = value } - subroutine delete_data(for_account: algopy.Account): None + subroutine delete_data(for_account: account): void { STATE_DELETE(this.local[for_account]) } diff --git a/examples/local_state/out/local_state_with_offsets.awst b/examples/local_state/out/local_state_with_offsets.awst index 3c6603211..b351e94b1 100644 --- a/examples/local_state/out/local_state_with_offsets.awst +++ b/examples/local_state/out/local_state_with_offsets.awst @@ -1,7 +1,7 @@ contract LocalStateContract { locals { - ['local']: algopy.Bytes + ['local']: bytes } constructor() @@ -10,7 +10,7 @@ contract LocalStateContract approval_program(): bool { - if (txn() == reinterpret_cast(0u)) { + if (txn() == reinterpret_cast(0u)) { return true } if (!(txn() IS IN (NoOp, OptIn))) { @@ -19,8 +19,8 @@ contract LocalStateContract if (txn() < 1u) { return false } - offset: algopy.UInt64 = btoi(txna()) - method: algopy.Bytes = txna() + offset: uint64 = btoi(txna()) + method: bytes = txna() if (txn() == 2u) { if (method == 'get_guaranteed_data') { log(this::get_guaranteed_data(offset)) @@ -60,29 +60,29 @@ contract LocalStateContract return true } - subroutine get_guaranteed_data(for_account: algopy.UInt64): algopy.Bytes + subroutine get_guaranteed_data(for_account: uint64): bytes { return this.local[for_account] } - subroutine get_data_with_default(for_account: algopy.UInt64, default: algopy.Bytes): algopy.Bytes + subroutine get_data_with_default(for_account: uint64, default: bytes): bytes { return STATE_GET(this.local[for_account], default=default) } - subroutine get_data_or_assert(for_account: algopy.UInt64): algopy.Bytes + subroutine get_data_or_assert(for_account: uint64): bytes { - (result, exists): tuple[algopy.Bytes, bool] = STATE_GET_EX(this.local[for_account]) + (result, exists): tuple = STATE_GET_EX(this.local[for_account]) assert(exists, comment="no data for account") return result } - subroutine set_data(for_account: algopy.UInt64, value: algopy.Bytes): None + subroutine set_data(for_account: uint64, value: bytes): void { - this.local[for_account]: algopy.Bytes = value + this.local[for_account]: bytes = value } - subroutine delete_data(for_account: algopy.UInt64): None + subroutine delete_data(for_account: uint64): void { STATE_DELETE(this.local[for_account]) } diff --git a/examples/merkle/out/contract.awst b/examples/merkle/out/contract.awst index fb10025bc..2eec88a68 100644 --- a/examples/merkle/out/contract.awst +++ b/examples/merkle/out/contract.awst @@ -1,30 +1,30 @@ contract MerkleTree { globals { - ['root']: algopy.Bytes + ['root']: bytes } - abimethod create(root: algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[32]]): None + abimethod create(root: arc4.static_array): void { - this.root: algopy.Bytes = reinterpret_cast(root) + this.root: bytes = reinterpret_cast(root) } - abimethod verify(proof: algopy.arc4.DynamicArray[algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[32]]], leaf: algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[32]]): bool + abimethod verify(proof: arc4.dynamic_array>, leaf: arc4.static_array): bool { - return this.root == examples.merkle.contract::compute_root_hash(proof, reinterpret_cast(leaf)) + return this.root == examples.merkle.contract::compute_root_hash(proof, reinterpret_cast(leaf)) } } -subroutine compute_root_hash(proof: algopy.arc4.DynamicArray[algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[32]]], leaf: algopy.Bytes): algopy.Bytes +subroutine compute_root_hash(proof: arc4.dynamic_array>, leaf: bytes): bytes { - computed: algopy.Bytes = leaf + computed: bytes = leaf for idx in range(0u, extract_uint16(proof, 0u), 1u) { - computed: algopy.Bytes = examples.merkle.contract::hash_pair(computed, reinterpret_cast(proof[idx])) + computed: bytes = examples.merkle.contract::hash_pair(computed, reinterpret_cast(proof[idx])) } return computed } -subroutine hash_pair(a: algopy.Bytes, b: algopy.Bytes): algopy.Bytes +subroutine hash_pair(a: bytes, b: bytes): bytes { - return sha256((reinterpret_cast(a) < reinterpret_cast(b)) ? (a + b) : (b + a)) + return sha256((reinterpret_cast(a) < reinterpret_cast(b)) ? (a + b) : (b + a)) } \ No newline at end of file diff --git a/examples/tictactoe/out/TicTacToeContract.approval.mir b/examples/tictactoe/out/TicTacToeContract.approval.mir index 16d541419..013b34a0e 100644 --- a/examples/tictactoe/out/TicTacToeContract.approval.mir +++ b/examples/tictactoe/out/TicTacToeContract.approval.mir @@ -744,7 +744,7 @@ play_else_body@2: // virtual: store tmp%3#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%3#0 Txn.sender tictactoe/tictactoe.py:54 global ZeroAddress // (𝕡) move.0#0,move.1#0 | tmp%3#0,{global} Account() tictactoe/tictactoe.py:55 // virtual: store tmp%4#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%3#0,tmp%4#0 Account() tictactoe/tictactoe.py:55 - int 0 // (𝕡) move.0#0,move.1#0 | tmp%3#0,tmp%4#0,0 self.challenger tictactoe/tictactoe.py:54 + int 0 // (𝕡) move.0#0,move.1#0 | tmp%3#0,tmp%4#0,0 self.challenger.get tictactoe/tictactoe.py:54 byte "challenger" // (𝕡) move.0#0,move.1#0 | tmp%3#0,tmp%4#0,0,"challenger" self.challenger tictactoe/tictactoe.py:17 app_global_get_ex // (𝕡) move.0#0,move.1#0 | tmp%3#0,tmp%4#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.challenger.get(\ndefault=Account()\n) tictactoe/tictactoe.py:54-56 swap // store challenger_get_ex%1#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%3#0,tmp%4#0,challenger_get_ex%1#0,{app_global_get_ex}.0 self.challenger.get(\ndefault=Account()\n) tictactoe/tictactoe.py:54-56 diff --git a/examples/tictactoe/out/client_TicTacToeContract.py b/examples/tictactoe/out/client_TicTacToeContract.py index e03e794f0..9e812a189 100644 --- a/examples/tictactoe/out/client_TicTacToeContract.py +++ b/examples/tictactoe/out/client_TicTacToeContract.py @@ -10,22 +10,22 @@ class TicTacToeContract(algopy.arc4.ARC4Client, typing.Protocol): @algopy.arc4.abimethod(create='allow') def new_game( self, - move: algopy.arc4.Tuple[algopy.arc4.UInt64, algopy.arc4.UInt64], + move: algopy.arc4.Tuple[algopy.arc4.UIntN[typing.Literal[64]], algopy.arc4.UIntN[typing.Literal[64]]], ) -> None: ... @algopy.arc4.abimethod def join_game( self, - move: algopy.arc4.Tuple[algopy.arc4.UInt64, algopy.arc4.UInt64], + move: algopy.arc4.Tuple[algopy.arc4.UIntN[typing.Literal[64]], algopy.arc4.UIntN[typing.Literal[64]]], ) -> None: ... @algopy.arc4.abimethod def whose_turn( self, - ) -> algopy.arc4.UInt8: ... + ) -> algopy.arc4.UIntN[typing.Literal[8]]: ... @algopy.arc4.abimethod def play( self, - move: algopy.arc4.Tuple[algopy.arc4.UInt64, algopy.arc4.UInt64], + move: algopy.arc4.Tuple[algopy.arc4.UIntN[typing.Literal[64]], algopy.arc4.UIntN[typing.Literal[64]]], ) -> None: ... diff --git a/examples/tictactoe/out/tictactoe.awst b/examples/tictactoe/out/tictactoe.awst index 39bd97463..c7be4da3b 100644 --- a/examples/tictactoe/out/tictactoe.awst +++ b/examples/tictactoe/out/tictactoe.awst @@ -6,18 +6,18 @@ DRAW = 3 contract TicTacToeContract { globals { - ['host']: algopy.Account - ['game']: algopy.arc4.StaticArray[algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[3]], typing.Literal[3]] - ['turns']: algopy.UInt64 - ['challenger']: algopy.Account - ['winner']: algopy.arc4.UInt8 + ['host']: account + ['game']: arc4.static_array, 3> + ['turns']: uint64 + ['challenger']: account + ['winner']: arc4.uint8 } constructor() { } - abimethod new_game(move: tuple[algopy.UInt64, algopy.UInt64]): None + abimethod new_game(move: tuple): void { if (reinterpret_cast(txn())) { if (STATE_EXISTS(this.challenger)) { @@ -26,69 +26,69 @@ contract TicTacToeContract STATE_DELETE(this.challenger) STATE_DELETE(this.winner) } - this.host: algopy.Account = txn() - this.game: algopy.arc4.StaticArray[algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[3]], typing.Literal[3]] = reinterpret_cast(bzero(9u)) - (column, row): tuple[algopy.UInt64, algopy.UInt64] = move + this.host: account = txn() + this.game: arc4.static_array, 3> = reinterpret_cast, 3>>(bzero(9u)) + (column, row): tuple = move assert(column < 3u and row < 3u, comment="Move must be in range") - this.game[row][column]: algopy.arc4.UInt8 = 1arc4u8 - this.turns: algopy.UInt64 = 0u + this.game[row][column]: arc4.uint8 = 1arc4u8 + this.turns: uint64 = 0u } - abimethod join_game(move: tuple[algopy.UInt64, algopy.UInt64]): None + abimethod join_game(move: tuple): void { assert(!(STATE_EXISTS(this.challenger)), comment="Host already has a challenger") - this.challenger: algopy.Account = txn() + this.challenger: account = txn() this::make_move(2arc4u8, move) } - abimethod whose_turn(): algopy.arc4.UInt8 + abimethod whose_turn(): arc4.uint8 { return (reinterpret_cast(this.turns % 2u)) ? (1arc4u8) : (2arc4u8) } - abimethod play(move: tuple[algopy.UInt64, algopy.UInt64]): None + abimethod play(move: tuple): void { assert(!(STATE_EXISTS(this.winner)), comment="Game is already finished") if (reinterpret_cast(this.turns % 2u)) { assert(txn() == this.host, comment="It is the host's turn") - player: algopy.arc4.UInt8 = 1arc4u8 + player: arc4.uint8 = 1arc4u8 } else { assert(txn() == STATE_GET(this.challenger, default=global()), comment="It is the challenger's turn") - player: algopy.arc4.UInt8 = 2arc4u8 + player: arc4.uint8 = 2arc4u8 } this::make_move(player, move) } - subroutine make_move(player: algopy.arc4.UInt8, move: tuple[algopy.UInt64, algopy.UInt64]): None + subroutine make_move(player: arc4.uint8, move: tuple): void { - (column, row): tuple[algopy.UInt64, algopy.UInt64] = move + (column, row): tuple = move assert(column < 3u and row < 3u, comment="Move must be in range") - assert(reinterpret_cast(this.game[row][column]) == reinterpret_cast(0arc4u8), comment="Square is already taken") - this.game[row][column]: algopy.arc4.UInt8 = player + assert(reinterpret_cast(this.game[row][column]) == reinterpret_cast(0arc4u8), comment="Square is already taken") + this.game[row][column]: arc4.uint8 = player this.turns += 1u if (this::did_win(player, column=column, row=row)) { - this.winner: algopy.arc4.UInt8 = player + this.winner: arc4.uint8 = player } else { if (this.turns == 9u) { - this.winner: algopy.arc4.UInt8 = 3arc4u8 + this.winner: arc4.uint8 = 3arc4u8 } } } - subroutine did_win(player: algopy.arc4.UInt8, column: algopy.UInt64, row: algopy.UInt64): bool + subroutine did_win(player: arc4.uint8, column: uint64, row: uint64): bool { - g: algopy.arc4.StaticArray[algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[3]], typing.Literal[3]] = this.game.copy() - if (reinterpret_cast(g[row][0u]) == reinterpret_cast(SINGLE_EVAL(id=0, source=g[row][1u])) and reinterpret_cast(SINGLE_EVAL(id=0, source=g[row][1u])) == reinterpret_cast(g[row][2u])) { + g: arc4.static_array, 3> = this.game.copy() + if (reinterpret_cast(g[row][0u]) == reinterpret_cast(SINGLE_EVAL(id=0, source=g[row][1u])) and reinterpret_cast(SINGLE_EVAL(id=0, source=g[row][1u])) == reinterpret_cast(g[row][2u])) { return true } - if (reinterpret_cast(g[0u][column]) == reinterpret_cast(SINGLE_EVAL(id=1, source=g[1u][column])) and reinterpret_cast(SINGLE_EVAL(id=1, source=g[1u][column])) == reinterpret_cast(g[2u][column])) { + if (reinterpret_cast(g[0u][column]) == reinterpret_cast(SINGLE_EVAL(id=1, source=g[1u][column])) and reinterpret_cast(SINGLE_EVAL(id=1, source=g[1u][column])) == reinterpret_cast(g[2u][column])) { return true } - if (reinterpret_cast(player) == reinterpret_cast(g[1u][1u])) { - if (reinterpret_cast(g[0u][0u]) == reinterpret_cast(player) and reinterpret_cast(player) == reinterpret_cast(g[2u][2u])) { + if (reinterpret_cast(player) == reinterpret_cast(g[1u][1u])) { + if (reinterpret_cast(g[0u][0u]) == reinterpret_cast(player) and reinterpret_cast(player) == reinterpret_cast(g[2u][2u])) { return true } - if (reinterpret_cast(g[0u][2u]) == reinterpret_cast(player) and reinterpret_cast(player) == reinterpret_cast(g[2u][0u])) { + if (reinterpret_cast(g[0u][2u]) == reinterpret_cast(player) and reinterpret_cast(player) == reinterpret_cast(g[2u][0u])) { return true } } diff --git a/examples/voting/out/VotingRoundApp.approval.mir b/examples/voting/out/VotingRoundApp.approval.mir index 26e751925..ba3547fad 100644 --- a/examples/voting/out/VotingRoundApp.approval.mir +++ b/examples/voting/out/VotingRoundApp.approval.mir @@ -395,7 +395,7 @@ bootstrap_block@0: // virtual: store tmp%7#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | tally_box_size#0,tmp%7#0 fund_min_bal_req.amount == min_balance_req voting/voting.py:106 // virtual: load tmp%7#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0 | tally_box_size#0,tmp%7#0 assert (\nfund_min_bal_req.amount == min_balance_req\n), "Payment must be for the exact min balan... voting/voting.py:105-107 assert // Payment must be for the exact min balance requirement // (𝕡) fund_min_bal_req#0 | tally_box_size#0 assert (\nfund_min_bal_req.amount == min_balance_req\n), "Payment must be for the exact min balan... voting/voting.py:105-107 - byte "V" // (𝕡) fund_min_bal_req#0 | tally_box_size#0,"V" b"V" voting/voting.py:55 + byte "V" // (𝕡) fund_min_bal_req#0 | tally_box_size#0,"V" "V" voting/voting.py:55 swap // load tally_box_size#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0 | "V",tally_box_size#0 self.tally_box.create(size=tally_box_size) voting/voting.py:108 box_create // (𝕡) fund_min_bal_req#0 | {box_create} self.tally_box.create(size=tally_box_size) voting/voting.py:108 // virtual: store tmp%8#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | tmp%8#0 self.tally_box.create(size=tally_box_size) voting/voting.py:108 @@ -841,7 +841,7 @@ get_vote_from_box: proto 1 1 // (𝕡) index#0 | @subroutine\ndef get_vote_from_box(self, index: UInt64) -> UInt64: voting/voting.py:239-240 get_vote_from_box_block@0: - byte "V" // (𝕡) index#0 | "V" b"V" voting/voting.py:55 + byte "V" // (𝕡) index#0 | "V" "V" voting/voting.py:55 frame_dig -1 // load index#0 from parameters (𝕡) index#0 | "V",index#0 self.tally_box.extract(index, VOTE_COUNT_BYTES) voting/voting.py:241 int 8 // (𝕡) index#0 | "V",index#0,8 VOTE_COUNT_BYTES voting/voting.py:241 box_extract // (𝕡) index#0 | {box_extract} self.tally_box.extract(index, VOTE_COUNT_BYTES) voting/voting.py:241 @@ -1006,10 +1006,10 @@ already_voted: already_voted_block@0: txn Sender // {txn} Txn.sender voting/voting.py:215 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Txn.sender voting/voting.py:215 - // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 BoxMap(Account, VoteIndexArray)\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id... voting/voting.py:56-215 - box_len // {box_len}.0,{box_len}.1 BoxMap(Account, VoteIndexArray)\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id... voting/voting.py:56-215 - swap // store box_exists%0#0 to l-stack (no copy) box_exists%0#0,{box_len}.0 BoxMap(Account, VoteIndexArray)\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id... voting/voting.py:56-215 - pop // box_exists%0#0 BoxMap(Account, VoteIndexArray)\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id... voting/voting.py:56-215 + // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 "")\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id: String,\nsnapshot_public_k... voting/voting.py:56-215 + box_len // {box_len}.0,{box_len}.1 "")\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id: String,\nsnapshot_public_k... voting/voting.py:56-215 + swap // store box_exists%0#0 to l-stack (no copy) box_exists%0#0,{box_len}.0 "")\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id: String,\nsnapshot_public_k... voting/voting.py:56-215 + pop // box_exists%0#0 "")\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id: String,\nsnapshot_public_k... voting/voting.py:56-215 // virtual: load box_exists%0#0 from l-stack (no copy) box_exists%0#0 return Txn.sender in self.votes_by_account voting/voting.py:215 retsub // box_exists%0#0 return Txn.sender in self.votes_by_account voting/voting.py:215 @@ -1228,7 +1228,7 @@ increment_vote_in_box_block@0: // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) index#0 | tmp%0#0 op.itob(current_vote + 1) voting/voting.py:246 itob // (𝕡) index#0 | {itob} op.itob(current_vote + 1) voting/voting.py:246 // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) index#0 | tmp%1#0 op.itob(current_vote + 1) voting/voting.py:246 - byte "V" // (𝕡) index#0 | tmp%1#0,"V" b"V" voting/voting.py:55 + byte "V" // (𝕡) index#0 | tmp%1#0,"V" "V" voting/voting.py:55 frame_dig -1 // load index#0 from parameters (𝕡) index#0 | tmp%1#0,"V",index#0 self.tally_box.replace(index, op.itob(current_vote + 1)) voting/voting.py:246 uncover 2 // load tmp%1#0 from l-stack (no copy) (𝕡) index#0 | "V",index#0,tmp%1#0 self.tally_box.replace(index, op.itob(current_vote + 1)) voting/voting.py:246 box_replace // (𝕡) index#0 | self.tally_box.replace(index, op.itob(current_vote + 1)) voting/voting.py:246 diff --git a/examples/voting/out/VotingRoundApp.approval.teal b/examples/voting/out/VotingRoundApp.approval.teal index 46d37f5db..d80483291 100644 --- a/examples/voting/out/VotingRoundApp.approval.teal +++ b/examples/voting/out/VotingRoundApp.approval.teal @@ -372,7 +372,7 @@ bootstrap: // ), "Payment must be for the exact min balance requirement" assert // Payment must be for the exact min balance requirement // voting/voting.py:55 - // self.tally_box = BoxRef(key=b"V") + // self.tally_box = BoxRef(key="V") byte "V" // voting/voting.py:108 // assert self.tally_box.create(size=tally_box_size) @@ -969,7 +969,7 @@ get_vote_from_box: // def get_vote_from_box(self, index: UInt64) -> UInt64: proto 1 1 // voting/voting.py:55 - // self.tally_box = BoxRef(key=b"V") + // self.tally_box = BoxRef(key="V") byte "V" // voting/voting.py:241 // return op.btoi(self.tally_box.extract(index, VOTE_COUNT_BYTES)) @@ -1142,7 +1142,7 @@ already_voted: // return Txn.sender in self.votes_by_account txn Sender // voting/voting.py:56-215 - // self.votes_by_account = BoxMap(Account, VoteIndexArray) + // self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") // // @arc4.abimethod(create="require") // def create( @@ -1526,7 +1526,7 @@ increment_vote_in_box: + itob // voting/voting.py:55 - // self.tally_box = BoxRef(key=b"V") + // self.tally_box = BoxRef(key="V") byte "V" // voting/voting.py:246 // self.tally_box.replace(index, op.itob(current_vote + 1)) diff --git a/examples/voting/out/VotingRoundApp.arc32.json b/examples/voting/out/VotingRoundApp.arc32.json index bd7c08967..d611ed888 100644 --- a/examples/voting/out/VotingRoundApp.arc32.json +++ b/examples/voting/out/VotingRoundApp.arc32.json @@ -51,7 +51,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICBtZXRob2QgImNyZWF0ZShzdHJpbmcsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDY0LHVpbnQ4W10sdWludDY0LHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJib290c3RyYXAocGF5KXZvaWQiCiAgICBtZXRob2QgImNsb3NlKCl2b2lkIgogICAgbWV0aG9kICJnZXRfcHJlY29uZGl0aW9ucyhieXRlW10pKHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCkiCiAgICBtZXRob2QgInZvdGUocGF5LGJ5dGVbXSx1aW50OFtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX2NyZWF0ZV9yb3V0ZUAzIG1haW5fYm9vdHN0cmFwX3JvdXRlQDQgbWFpbl9jbG9zZV9yb3V0ZUA1IG1haW5fZ2V0X3ByZWNvbmRpdGlvbnNfcm91dGVANiBtYWluX3ZvdGVfcm91dGVANwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl9jcmVhdGVfcm91dGVAMzoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjQ5CiAgICAvLyBjbGFzcyBWb3RpbmdSb3VuZEFwcChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgZXh0cmFjdCAyIDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgY2FsbHN1YiBjcmVhdGUKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYm9vdHN0cmFwX3JvdXRlQDQ6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib290c3RyYXAKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fY2xvc2Vfcm91dGVANToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgY2xvc2UKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X3ByZWNvbmRpdGlvbnNfcm91dGVANjoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgY2FsbHN1YiBnZXRfcHJlY29uZGl0aW9ucwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92b3RlX3JvdXRlQDc6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjQ5CiAgICAvLyBjbGFzcyBWb3RpbmdSb3VuZEFwcChBUkM0Q29udHJhY3QpOgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB2b3RlCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5jcmVhdGUodm90ZV9pZDogYnl0ZXMsIHNuYXBzaG90X3B1YmxpY19rZXk6IGJ5dGVzLCBtZXRhZGF0YV9pcGZzX2NpZDogYnl0ZXMsIHN0YXJ0X3RpbWU6IHVpbnQ2NCwgZW5kX3RpbWU6IHVpbnQ2NCwgb3B0aW9uX2NvdW50czogYnl0ZXMsIHF1b3J1bTogdWludDY0LCBuZnRfaW1hZ2VfdXJsOiBieXRlcykgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1OC02OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICAvLyBkZWYgY3JlYXRlKAogICAgLy8gICAgIHNlbGYsCiAgICAvLyAgICAgdm90ZV9pZDogU3RyaW5nLAogICAgLy8gICAgIHNuYXBzaG90X3B1YmxpY19rZXk6IEJ5dGVzLAogICAgLy8gICAgIG1ldGFkYXRhX2lwZnNfY2lkOiBTdHJpbmcsCiAgICAvLyAgICAgc3RhcnRfdGltZTogVUludDY0LAogICAgLy8gICAgIGVuZF90aW1lOiBVSW50NjQsCiAgICAvLyAgICAgb3B0aW9uX2NvdW50czogVm90ZUluZGV4QXJyYXksCiAgICAvLyAgICAgcXVvcnVtOiBVSW50NjQsCiAgICAvLyAgICAgbmZ0X2ltYWdlX3VybDogU3RyaW5nLAogICAgLy8gKSAtPiBOb25lOgogICAgcHJvdG8gOCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjcwCiAgICAvLyBhc3NlcnQgc3RhcnRfdGltZSA8IGVuZF90aW1lLCAiRW5kIHRpbWUgc2hvdWxkIGJlIGFmdGVyIHN0YXJ0IHRpbWUiCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgPAogICAgYXNzZXJ0IC8vIEVuZCB0aW1lIHNob3VsZCBiZSBhZnRlciBzdGFydCB0aW1lCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjcxCiAgICAvLyBhc3NlcnQgZW5kX3RpbWUgPj0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAsICJFbmQgdGltZSBzaG91bGQgYmUgaW4gdGhlIGZ1dHVyZSIKICAgIGZyYW1lX2RpZyAtNAogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgPj0KICAgIGFzc2VydCAvLyBFbmQgdGltZSBzaG91bGQgYmUgaW4gdGhlIGZ1dHVyZQogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3MwogICAgLy8gc2VsZi52b3RlX2lkID0gdm90ZV9pZAogICAgYnl0ZSAidm90ZV9pZCIKICAgIGZyYW1lX2RpZyAtOAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzQKICAgIC8vIHNlbGYuc25hcHNob3RfcHVibGljX2tleSA9IHNuYXBzaG90X3B1YmxpY19rZXkKICAgIGJ5dGUgInNuYXBzaG90X3B1YmxpY19rZXkiCiAgICBmcmFtZV9kaWcgLTcKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc1CiAgICAvLyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkID0gbWV0YWRhdGFfaXBmc19jaWQKICAgIGJ5dGUgIm1ldGFkYXRhX2lwZnNfY2lkIgogICAgZnJhbWVfZGlnIC02CiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NgogICAgLy8gc2VsZi5zdGFydF90aW1lID0gc3RhcnRfdGltZQogICAgYnl0ZSAic3RhcnRfdGltZSIKICAgIGZyYW1lX2RpZyAtNQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzcKICAgIC8vIHNlbGYuZW5kX3RpbWUgPSBlbmRfdGltZQogICAgYnl0ZSAiZW5kX3RpbWUiCiAgICBmcmFtZV9kaWcgLTQKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc4CiAgICAvLyBzZWxmLnF1b3J1bSA9IHF1b3J1bQogICAgYnl0ZSAicXVvcnVtIgogICAgZnJhbWVfZGlnIC0yCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3OQogICAgLy8gc2VsZi5uZnRfaW1hZ2VfdXJsID0gbmZ0X2ltYWdlX3VybAogICAgYnl0ZSAibmZ0X2ltYWdlX3VybCIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODAKICAgIC8vIHNlbGYuc3RvcmVfb3B0aW9uX2NvdW50cyhvcHRpb25fY291bnRzLmNvcHkoKSkKICAgIGZyYW1lX2RpZyAtMwogICAgY2FsbHN1YiBzdG9yZV9vcHRpb25fY291bnRzCiAgICBwb3AKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuc3RvcmVfb3B0aW9uX2NvdW50cyhvcHRpb25fY291bnRzOiBieXRlcykgLT4gYnl0ZXM6CnN0b3JlX29wdGlvbl9jb3VudHM6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxNy0yMTgKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgc3RvcmVfb3B0aW9uX2NvdW50cyhzZWxmLCBvcHRpb25fY291bnRzOiBWb3RlSW5kZXhBcnJheSkgLT4gTm9uZToKICAgIHByb3RvIDEgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTkKICAgIC8vIGFzc2VydCBvcHRpb25fY291bnRzLmxlbmd0aCwgIm9wdGlvbl9jb3VudHMgc2hvdWxkIGJlIG5vbi1lbXB0eSIKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkdXBuIDIKICAgIGFzc2VydCAvLyBvcHRpb25fY291bnRzIHNob3VsZCBiZSBub24tZW1wdHkKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjIwCiAgICAvLyBhc3NlcnQgb3B0aW9uX2NvdW50cy5sZW5ndGggPD0gMTEyLCAiQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gMTEyIHF1ZXN0aW9ucyIKICAgIGludCAxMTIKICAgIDw9CiAgICBhc3NlcnQgLy8gQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gMTEyIHF1ZXN0aW9ucwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjIKICAgIC8vIHRvdGFsX29wdGlvbnMgPSBVSW50NjQoMCkKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyMwogICAgLy8gZm9yIGl0ZW0gaW4gb3B0aW9uX2NvdW50czoKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAyIDAKICAgIGludCAwCgpzdG9yZV9vcHRpb25fY291bnRzX2Zvcl9oZWFkZXJAMToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjIzCiAgICAvLyBmb3IgaXRlbSBpbiBvcHRpb25fY291bnRzOgogICAgZnJhbWVfZGlnIDMKICAgIGZyYW1lX2RpZyAwCiAgICA8CiAgICBieiBzdG9yZV9vcHRpb25fY291bnRzX2FmdGVyX2ZvckA0CiAgICBmcmFtZV9kaWcgMgogICAgZnJhbWVfZGlnIDMKICAgIGR1cAogICAgY292ZXIgMgogICAgaW50IDEKICAgIGV4dHJhY3QzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyNAogICAgLy8gdG90YWxfb3B0aW9ucyArPSBpdGVtLm5hdGl2ZQogICAgYnRvaQogICAgZnJhbWVfZGlnIDEKICAgICsKICAgIGZyYW1lX2J1cnkgMQogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2J1cnkgMwogICAgYiBzdG9yZV9vcHRpb25fY291bnRzX2Zvcl9oZWFkZXJAMQoKc3RvcmVfb3B0aW9uX2NvdW50c19hZnRlcl9mb3JANDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI1CiAgICAvLyBhc3NlcnQgdG90YWxfb3B0aW9ucyA8PSAxMjgsICJDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMjggdm90ZSBvcHRpb25zIgogICAgZnJhbWVfZGlnIDEKICAgIGR1cAogICAgaW50IDEyOAogICAgPD0KICAgIGFzc2VydCAvLyBDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMjggdm90ZSBvcHRpb25zCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyNwogICAgLy8gc2VsZi5vcHRpb25fY291bnRzID0gb3B0aW9uX2NvdW50cy5jb3B5KCkKICAgIGJ5dGUgIm9wdGlvbl9jb3VudHMiCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyOAogICAgLy8gc2VsZi50b3RhbF9vcHRpb25zID0gdG90YWxfb3B0aW9ucwogICAgYnl0ZSAidG90YWxfb3B0aW9ucyIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICBmcmFtZV9kaWcgLTEKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5ib290c3RyYXAoZnVuZF9taW5fYmFsX3JlcTogdWludDY0KSAtPiB2b2lkOgpib290c3RyYXA6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjgyLTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib290c3RyYXAoc2VsZiwgZnVuZF9taW5fYmFsX3JlcTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24pIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODQKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5pc19ib290c3RyYXBwZWQsICJNdXN0IG5vdCBiZSBhbHJlYWR5IGJvb3RzdHJhcHBlZCIKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUxCiAgICAvLyBzZWxmLmlzX2Jvb3RzdHJhcHBlZCA9IEZhbHNlCiAgICBieXRlICJpc19ib290c3RyYXBwZWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojg0CiAgICAvLyBhc3NlcnQgbm90IHNlbGYuaXNfYm9vdHN0cmFwcGVkLCAiTXVzdCBub3QgYmUgYWxyZWFkeSBib290c3RyYXBwZWQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIGlzX2Jvb3RzdHJhcHBlZCBleGlzdHMKICAgICEKICAgIGFzc2VydCAvLyBNdXN0IG5vdCBiZSBhbHJlYWR5IGJvb3RzdHJhcHBlZAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1MQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBGYWxzZQogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4NQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBUcnVlCiAgICBpbnQgMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODgKICAgIC8vIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojg3LTg5CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gKSwgIlBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcyIKICAgIGFzc2VydCAvLyBQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MKICAgIC8vIHZvdGluZy92b3RpbmcucHk6OTEKICAgIC8vIHRhbGx5X2JveF9zaXplID0gc2VsZi50b3RhbF9vcHRpb25zICogVk9URV9DT1VOVF9CWVRFUwogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI4CiAgICAvLyBzZWxmLnRvdGFsX29wdGlvbnMgPSB0b3RhbF9vcHRpb25zCiAgICBieXRlICJ0b3RhbF9vcHRpb25zIgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo5MQogICAgLy8gdGFsbHlfYm94X3NpemUgPSBzZWxmLnRvdGFsX29wdGlvbnMgKiBWT1RFX0NPVU5UX0JZVEVTCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHRvdGFsX29wdGlvbnMgZXhpc3RzCiAgICBpbnQgOAogICAgKgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDEtMTAyCiAgICAvLyAjIHRhbGx5IGJveCB2YWx1ZQogICAgLy8gKyAodGFsbHlfYm94X3NpemUgKiBCT1hfQllURV9NSU5fQkFMQU5DRSkKICAgIGR1cAogICAgaW50IDQwMAogICAgKgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo5My0xMDAKICAgIC8vICMgbWluaW11bSBiYWxhbmNlIHJlcSBmb3I6IEFMR09zICsgVm90ZSByZXN1bHQgTkZUIGFzc2V0CiAgICAvLyBBU1NFVF9NSU5fQkFMQU5DRSAqIDIKICAgIC8vICMgY3JlYXRlIE5GVCBmZWUKICAgIC8vICsgMTAwMAogICAgLy8gIyB0YWxseSBib3gKICAgIC8vICsgQk9YX0ZMQVRfTUlOX0JBTEFOQ0UKICAgIC8vICMgdGFsbHkgYm94IGtleSAiViIKICAgIC8vICsgQk9YX0JZVEVfTUlOX0JBTEFOQ0UKICAgIGludCAyMDM5MDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6OTMtMTAyCiAgICAvLyAjIG1pbmltdW0gYmFsYW5jZSByZXEgZm9yOiBBTEdPcyArIFZvdGUgcmVzdWx0IE5GVCBhc3NldAogICAgLy8gQVNTRVRfTUlOX0JBTEFOQ0UgKiAyCiAgICAvLyAjIGNyZWF0ZSBORlQgZmVlCiAgICAvLyArIDEwMDAKICAgIC8vICMgdGFsbHkgYm94CiAgICAvLyArIEJPWF9GTEFUX01JTl9CQUxBTkNFCiAgICAvLyAjIHRhbGx5IGJveCBrZXkgIlYiCiAgICAvLyArIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICAvLyAjIHRhbGx5IGJveCB2YWx1ZQogICAgLy8gKyAodGFsbHlfYm94X3NpemUgKiBCT1hfQllURV9NSU5fQkFMQU5DRSkKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTA0CiAgICAvLyBsb2cobWluX2JhbGFuY2VfcmVxKQogICAgZHVwCiAgICBpdG9iCiAgICBsb2cKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTA2CiAgICAvLyBmdW5kX21pbl9iYWxfcmVxLmFtb3VudCA9PSBtaW5fYmFsYW5jZV9yZXEKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgQW1vdW50CiAgICA9PQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDUtMTA3CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXEuYW1vdW50ID09IG1pbl9iYWxhbmNlX3JlcQogICAgLy8gKSwgIlBheW1lbnQgbXVzdCBiZSBmb3IgdGhlIGV4YWN0IG1pbiBiYWxhbmNlIHJlcXVpcmVtZW50IgogICAgYXNzZXJ0IC8vIFBheW1lbnQgbXVzdCBiZSBmb3IgdGhlIGV4YWN0IG1pbiBiYWxhbmNlIHJlcXVpcmVtZW50CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU1CiAgICAvLyBzZWxmLnRhbGx5X2JveCA9IEJveFJlZihrZXk9YiJWIikKICAgIGJ5dGUgIlYiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEwOAogICAgLy8gYXNzZXJ0IHNlbGYudGFsbHlfYm94LmNyZWF0ZShzaXplPXRhbGx5X2JveF9zaXplKQogICAgc3dhcAogICAgYm94X2NyZWF0ZQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmNsb3NlKCkgLT4gdm9pZDoKY2xvc2U6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExMC0xMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGNsb3NlKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIGludCAwCiAgICBkdXAKICAgIGJ5dGUgIiIKICAgIGR1cG4gMgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTIKICAgIC8vIGVuc3VyZV9idWRnZXQoMjAwMDAsIGZlZV9zb3VyY2U9T3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCAyMDAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTMKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5jbG9zZV90aW1lLCAiQWxyZWFkeSBjbG9zZWQiCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1NAogICAgLy8gc2VsZi5jbG9zZV90aW1lID0gR2xvYmFsU3RhdGUoVUludDY0KQogICAgYnl0ZSAiY2xvc2VfdGltZSIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTEzCiAgICAvLyBhc3NlcnQgbm90IHNlbGYuY2xvc2VfdGltZSwgIkFscmVhZHkgY2xvc2VkIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgIQogICAgYXNzZXJ0IC8vIEFscmVhZHkgY2xvc2VkCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU0CiAgICAvLyBzZWxmLmNsb3NlX3RpbWUgPSBHbG9iYWxTdGF0ZShVSW50NjQpCiAgICBieXRlICJjbG9zZV90aW1lIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTQKICAgIC8vIHNlbGYuY2xvc2VfdGltZS52YWx1ZSA9IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wCiAgICBnbG9iYWwgTGF0ZXN0VGltZXN0YW1wCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTkKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3MwogICAgLy8gc2VsZi52b3RlX2lkID0gdm90ZV9pZAogICAgYnl0ZSAidm90ZV9pZCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE5CiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayB2b3RlX2lkIGV4aXN0cwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTE4CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICBieXRlICJ7XCJzdGFuZGFyZFwiOlwiYXJjNjlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTExOQogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjAKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIGJ5dGUgIi5cIixcInByb3BlcnRpZXNcIjp7XCJtZXRhZGF0YVwiOlwiaXBmczovLyIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyMAogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjEKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzUKICAgIC8vIHNlbGYubWV0YWRhdGFfaXBmc19jaWQgPSBtZXRhZGF0YV9pcGZzX2NpZAogICAgYnl0ZSAibWV0YWRhdGFfaXBmc19jaWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyMQogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIG1ldGFkYXRhX2lwZnNfY2lkIGV4aXN0cwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTIxCiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTIyCiAgICAvLyArICciLCJpZCI6IicKICAgIGJ5dGUgIlwiLFwiaWRcIjpcIiIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyMgogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTIzCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzMKICAgIC8vIHNlbGYudm90ZV9pZCA9IHZvdGVfaWQKICAgIGJ5dGUgInZvdGVfaWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyMwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgdm90ZV9pZCBleGlzdHMKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyMwogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyNAogICAgLy8gKyAnIiwicXVvcnVtIjonCiAgICBieXRlICJcIixcInF1b3J1bVwiOiIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyNAogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnIiwicXVvcnVtIjonCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTI1CiAgICAvLyArIGl0b2Eoc2VsZi5xdW9ydW0pCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3OAogICAgLy8gc2VsZi5xdW9ydW0gPSBxdW9ydW0KICAgIGJ5dGUgInF1b3J1bSIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTI1CiAgICAvLyArIGl0b2Eoc2VsZi5xdW9ydW0pCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHF1b3J1bSBleGlzdHMKICAgIGNhbGxzdWIgaXRvYQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTI1CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICciLCJxdW9ydW0iOicKICAgIC8vICsgaXRvYShzZWxmLnF1b3J1bSkKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjYKICAgIC8vICsgJywidm90ZXJDb3VudCI6JwogICAgYnl0ZSAiLFwidm90ZXJDb3VudFwiOiIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyNgogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnIiwicXVvcnVtIjonCiAgICAvLyArIGl0b2Eoc2VsZi5xdW9ydW0pCiAgICAvLyArICcsInZvdGVyQ291bnQiOicKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjcKICAgIC8vICsgaXRvYShzZWxmLnZvdGVyX2NvdW50KQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTItNTMKICAgIC8vICMgVGhlIG1pbmltdW0gbnVtYmVyIG9mIHZvdGVycyB3aG8gaGF2ZSB2b3RlZAogICAgLy8gc2VsZi52b3Rlcl9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidm90ZXJfY291bnQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyNwogICAgLy8gKyBpdG9hKHNlbGYudm90ZXJfY291bnQpCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHZvdGVyX2NvdW50IGV4aXN0cwogICAgY2FsbHN1YiBpdG9hCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjcKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgLy8gKyBpdG9hKHNlbGYucXVvcnVtKQogICAgLy8gKyAnLCJ2b3RlckNvdW50IjonCiAgICAvLyArIGl0b2Eoc2VsZi52b3Rlcl9jb3VudCkKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjgKICAgIC8vICsgJywidGFsbGllcyI6WycKICAgIGJ5dGUgIixcInRhbGxpZXNcIjpbIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTI4CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICciLCJxdW9ydW0iOicKICAgIC8vICsgaXRvYShzZWxmLnF1b3J1bSkKICAgIC8vICsgJywidm90ZXJDb3VudCI6JwogICAgLy8gKyBpdG9hKHNlbGYudm90ZXJfY291bnQpCiAgICAvLyArICcsInRhbGxpZXMiOlsnCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTMxCiAgICAvLyBjdXJyZW50X2luZGV4ID0gVUludDY0KDApCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzIKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCwgcXVlc3Rpb25fb3B0aW9ucyBpbiB1ZW51bWVyYXRlKHNlbGYub3B0aW9uX2NvdW50cyk6CiAgICBkdXAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI3CiAgICAvLyBzZWxmLm9wdGlvbl9jb3VudHMgPSBvcHRpb25fY291bnRzLmNvcHkoKQogICAgYnl0ZSAib3B0aW9uX2NvdW50cyIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTMyCiAgICAvLyBmb3IgcXVlc3Rpb25faW5kZXgsIHF1ZXN0aW9uX29wdGlvbnMgaW4gdWVudW1lcmF0ZShzZWxmLm9wdGlvbl9jb3VudHMpOgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBvcHRpb25fY291bnRzIGV4aXN0cwogICAgZHVwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIGV4dHJhY3QgMiAwCiAgICBpbnQgMAoKY2xvc2VfZm9yX2hlYWRlckAxOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzIKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCwgcXVlc3Rpb25fb3B0aW9ucyBpbiB1ZW51bWVyYXRlKHNlbGYub3B0aW9uX2NvdW50cyk6CiAgICBmcmFtZV9kaWcgOQogICAgZnJhbWVfZGlnIDcKICAgIDwKICAgIGJ6IGNsb3NlX2FmdGVyX2ZvckAxNQogICAgZnJhbWVfZGlnIDgKICAgIGZyYW1lX2RpZyA5CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludCAxCiAgICBleHRyYWN0MwogICAgZnJhbWVfYnVyeSAxCiAgICBmcmFtZV9kaWcgNQogICAgZnJhbWVfYnVyeSAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzMwogICAgLy8gaWYgcXVlc3Rpb25faW5kZXggPiAwOgogICAgYnogY2xvc2VfYWZ0ZXJfaWZfZWxzZUA0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNAogICAgLy8gbm90ZSArPSAiLCIKICAgIGZyYW1lX2RpZyA1CiAgICBieXRlICIsIgogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IDAKCmNsb3NlX2FmdGVyX2lmX2Vsc2VANDoKICAgIGZyYW1lX2RpZyAwCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgNQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzUKICAgIC8vIGlmIHF1ZXN0aW9uX29wdGlvbnMgPiAwOgogICAgZnJhbWVfZGlnIDEKICAgIGJ5dGUgMHgwMAogICAgYj4KICAgIGZyYW1lX2RpZyA2CiAgICBmcmFtZV9idXJ5IDIKICAgIHN3YXAKICAgIGZyYW1lX2J1cnkgMAogICAgYnogY2xvc2VfYWZ0ZXJfaWZfZWxzZUAxMwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzYKICAgIC8vIG5vdGUgKz0gIlsiCiAgICBmcmFtZV9kaWcgNQogICAgYnl0ZSAiWyIKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSA1CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNwogICAgLy8gZm9yIG9wdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25fb3B0aW9ucy5uYXRpdmUpOgogICAgZnJhbWVfZGlnIDEKICAgIGJ0b2kKICAgIGZyYW1lX2J1cnkgNAogICAgaW50IDAKICAgIGZyYW1lX2J1cnkgMwoKY2xvc2VfZm9yX2hlYWRlckA2OgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzcKICAgIC8vIGZvciBvcHRpb25faW5kZXggaW4gdXJhbmdlKHF1ZXN0aW9uX29wdGlvbnMubmF0aXZlKToKICAgIGZyYW1lX2RpZyAzCiAgICBmcmFtZV9kaWcgNAogICAgPAogICAgYnogY2xvc2VfYWZ0ZXJfZm9yQDEyCiAgICBmcmFtZV9kaWcgNQogICAgZnJhbWVfYnVyeSAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzOAogICAgLy8gaWYgb3B0aW9uX2luZGV4ID4gMDoKICAgIGZyYW1lX2RpZyAzCiAgICBieiBjbG9zZV9hZnRlcl9pZl9lbHNlQDkKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM5CiAgICAvLyBub3RlICs9ICIsIgogICAgZnJhbWVfZGlnIDUKICAgIGJ5dGUgIiwiCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgMAoKY2xvc2VfYWZ0ZXJfaWZfZWxzZUA5OgogICAgZnJhbWVfZGlnIDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQwCiAgICAvLyB2b3Rlc19mb3Jfb3B0aW9uID0gc2VsZi5nZXRfdm90ZV9mcm9tX2JveChjdXJyZW50X2luZGV4KQogICAgZnJhbWVfZGlnIDYKICAgIGR1cAogICAgY292ZXIgMgogICAgY2FsbHN1YiBnZXRfdm90ZV9mcm9tX2JveAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDEKICAgIC8vIG5vdGUgKz0gaXRvYSh2b3Rlc19mb3Jfb3B0aW9uKQogICAgY2FsbHN1YiBpdG9hCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgNQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDIKICAgIC8vIGN1cnJlbnRfaW5kZXggKz0gMQogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2J1cnkgNgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzcKICAgIC8vIGZvciBvcHRpb25faW5kZXggaW4gdXJhbmdlKHF1ZXN0aW9uX29wdGlvbnMubmF0aXZlKToKICAgIGZyYW1lX2RpZyAzCiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSAzCiAgICBiIGNsb3NlX2Zvcl9oZWFkZXJANgoKY2xvc2VfYWZ0ZXJfZm9yQDEyOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDMKICAgIC8vIG5vdGUgKz0gIl0iCiAgICBmcmFtZV9kaWcgNQogICAgYnl0ZSAiXSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIDYKICAgIGZyYW1lX2J1cnkgMgogICAgZnJhbWVfYnVyeSAwCgpjbG9zZV9hZnRlcl9pZl9lbHNlQDEzOgogICAgZnJhbWVfZGlnIDIKICAgIGZyYW1lX2J1cnkgNgogICAgZnJhbWVfZGlnIDAKICAgIGZyYW1lX2J1cnkgNQogICAgZnJhbWVfZGlnIDkKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDkKICAgIGIgY2xvc2VfZm9yX2hlYWRlckAxCgpjbG9zZV9hZnRlcl9mb3JAMTU6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0NAogICAgLy8gbm90ZSArPSAiXX19IgogICAgZnJhbWVfZGlnIDUKICAgIGJ5dGUgIl19fSIKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDYtMTU2CiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgIHRvdGFsPTEsCiAgICAvLyAgICAgZGVjaW1hbHM9MCwKICAgIC8vICAgICBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIC8vICAgICBhc3NldF9uYW1lPSJbVk9URSBSRVNVTFRdICIgKyBzZWxmLnZvdGVfaWQsCiAgICAvLyAgICAgdW5pdF9uYW1lPSJWT1RFUlNMVCIsCiAgICAvLyAgICAgdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIC8vICAgICBub3RlPW5vdGUsCiAgICAvLyAgICAgZmVlPUdsb2JhbC5taW5fdHhuX2ZlZSwKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgaXR4bl9iZWdpbgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNTQKICAgIC8vIGZlZT1HbG9iYWwubWluX3R4bl9mZWUsCiAgICBnbG9iYWwgTWluVHhuRmVlCiAgICBzd2FwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE1MAogICAgLy8gYXNzZXRfbmFtZT0iW1ZPVEUgUkVTVUxUXSAiICsgc2VsZi52b3RlX2lkLAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzMKICAgIC8vIHNlbGYudm90ZV9pZCA9IHZvdGVfaWQKICAgIGJ5dGUgInZvdGVfaWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE1MAogICAgLy8gYXNzZXRfbmFtZT0iW1ZPVEUgUkVTVUxUXSAiICsgc2VsZi52b3RlX2lkLAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayB2b3RlX2lkIGV4aXN0cwogICAgYnl0ZSAiW1ZPVEUgUkVTVUxUXSAiCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUyCiAgICAvLyB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzkKICAgIC8vIHNlbGYubmZ0X2ltYWdlX3VybCA9IG5mdF9pbWFnZV91cmwKICAgIGJ5dGUgIm5mdF9pbWFnZV91cmwiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE1MgogICAgLy8gdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgbmZ0X2ltYWdlX3VybCBleGlzdHMKICAgIHVuY292ZXIgMgogICAgaXR4bl9maWVsZCBOb3RlCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VVJMCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE1MQogICAgLy8gdW5pdF9uYW1lPSJWT1RFUlNMVCIsCiAgICBieXRlICJWT1RFUlNMVCIKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRVbml0TmFtZQogICAgaXR4bl9maWVsZCBDb25maWdBc3NldE5hbWUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ5CiAgICAvLyBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0RGVmYXVsdEZyb3plbgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDgKICAgIC8vIGRlY2ltYWxzPTAsCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBDb25maWdBc3NldERlY2ltYWxzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0NwogICAgLy8gdG90YWw9MSwKICAgIGludCAxCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VG90YWwKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ2CiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgaW50IGFjZmcKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0Ni0xNTYKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICAvLyAgICAgdG90YWw9MSwKICAgIC8vICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgIGRlZmF1bHRfZnJvemVuPUZhbHNlLAogICAgLy8gICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgLy8gICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gKQogICAgLy8gLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDUKICAgIC8vIHNlbGYubmZ0X2Fzc2V0X2lkID0gKAogICAgYnl0ZSAibmZ0X2Fzc2V0X2lkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDYtMTU3CiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgIHRvdGFsPTEsCiAgICAvLyAgICAgZGVjaW1hbHM9MCwKICAgIC8vICAgICBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIC8vICAgICBhc3NldF9uYW1lPSJbVk9URSBSRVNVTFRdICIgKyBzZWxmLnZvdGVfaWQsCiAgICAvLyAgICAgdW5pdF9uYW1lPSJWT1RFUlNMVCIsCiAgICAvLyAgICAgdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIC8vICAgICBub3RlPW5vdGUsCiAgICAvLyAgICAgZmVlPUdsb2JhbC5taW5fdHhuX2ZlZSwKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgLy8gLmNyZWF0ZWRfYXNzZXQuaWQKICAgIGl0eG4gQ3JlYXRlZEFzc2V0SUQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ1LTE1OAogICAgLy8gc2VsZi5uZnRfYXNzZXRfaWQgPSAoCiAgICAvLyAgICAgaXR4bi5Bc3NldENvbmZpZygKICAgIC8vICAgICAgICAgdG90YWw9MSwKICAgIC8vICAgICAgICAgZGVjaW1hbHM9MCwKICAgIC8vICAgICAgICAgZGVmYXVsdF9mcm96ZW49RmFsc2UsCiAgICAvLyAgICAgICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICAgICAgdW5pdF9uYW1lPSJWT1RFUlNMVCIsCiAgICAvLyAgICAgICAgIHVybD1zZWxmLm5mdF9pbWFnZV91cmwsCiAgICAvLyAgICAgICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICAgICAgZmVlPUdsb2JhbC5taW5fdHhuX2ZlZSwKICAgIC8vICAgICApCiAgICAvLyAgICAgLnN1Ym1pdCgpCiAgICAvLyAgICAgLmNyZWF0ZWRfYXNzZXQuaWQKICAgIC8vICkKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyBhbGdvcHkuZW5zdXJlX2J1ZGdldChyZXF1aXJlZF9idWRnZXQ6IHVpbnQ2NCwgZmVlX3NvdXJjZTogdWludDY0KSAtPiB2b2lkOgplbnN1cmVfYnVkZ2V0OgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjExLTE3CiAgICBwcm90byAyIDAKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToxOAogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMTAKICAgICsKCmVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDE6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MTkKICAgIGZyYW1lX2RpZyAwCiAgICBnbG9iYWwgT3Bjb2RlQnVkZ2V0CiAgICA+CiAgICBieiBlbnN1cmVfYnVkZ2V0X2FmdGVyX3doaWxlQDcKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyMAogICAgaXR4bl9iZWdpbgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjIxCiAgICBpbnQgYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjIyCiAgICBpbnQgRGVsZXRlQXBwbGljYXRpb24KICAgIGl0eG5fZmllbGQgT25Db21wbGV0aW9uCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjMKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQXBwcm92YWxQcm9ncmFtCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjQKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyNS0yOQogICAgZnJhbWVfZGlnIC0xCiAgICBzd2l0Y2ggZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8wQDMgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8xQDQKICAgIGIgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDYKCmVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMEAzOgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjI3CiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIGIgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDYKCmVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMUA0OgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjI5CiAgICBnbG9iYWwgTWluVHhuRmVlCiAgICBpdHhuX2ZpZWxkIEZlZQoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDY6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MzAKICAgIGl0eG5fc3VibWl0CiAgICBiIGVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDEKCmVuc3VyZV9idWRnZXRfYWZ0ZXJfd2hpbGVANzoKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuaXRvYShpOiB1aW50NjQpIC0+IGJ5dGVzOgppdG9hOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNDktMjUwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGl0b2EoaTogVUludDY0KSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUzCiAgICAvLyBpZiBpIDwgcmFkaXg6CiAgICBmcmFtZV9kaWcgLTEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUyCiAgICAvLyByYWRpeCA9IGRpZ2l0cy5sZW5ndGgKICAgIGludCAxMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTMKICAgIC8vIGlmIGkgPCByYWRpeDoKICAgIDwKICAgIGJ6IGl0b2FfYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1NAogICAgLy8gcmV0dXJuIFN0cmluZy5mcm9tX2J5dGVzKGRpZ2l0c1tpXSkKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDEKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUxCiAgICAvLyBkaWdpdHMgPSBCeXRlcyhiIjAxMjM0NTY3ODkiKQogICAgYnl0ZSAiMDEyMzQ1Njc4OSIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjU0CiAgICAvLyByZXR1cm4gU3RyaW5nLmZyb21fYnl0ZXMoZGlnaXRzW2ldKQogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIHJldHN1YgoKaXRvYV9hZnRlcl9pZl9lbHNlQDI6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1NQogICAgLy8gcmV0dXJuIGl0b2EoaSAvLyByYWRpeCkgKyBTdHJpbmcuZnJvbV9ieXRlcyhkaWdpdHNbaSAlIHJhZGl4XSkKICAgIGZyYW1lX2RpZyAtMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTIKICAgIC8vIHJhZGl4ID0gZGlnaXRzLmxlbmd0aAogICAgaW50IDEwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1NQogICAgLy8gcmV0dXJuIGl0b2EoaSAvLyByYWRpeCkgKyBTdHJpbmcuZnJvbV9ieXRlcyhkaWdpdHNbaSAlIHJhZGl4XSkKICAgIC8KICAgIGNhbGxzdWIgaXRvYQogICAgZnJhbWVfZGlnIC0xCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MgogICAgLy8gcmFkaXggPSBkaWdpdHMubGVuZ3RoCiAgICBpbnQgMTAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjU1CiAgICAvLyByZXR1cm4gaXRvYShpIC8vIHJhZGl4KSArIFN0cmluZy5mcm9tX2J5dGVzKGRpZ2l0c1tpICUgcmFkaXhdKQogICAgJQogICAgZHVwCiAgICBpbnQgMQogICAgKwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTEKICAgIC8vIGRpZ2l0cyA9IEJ5dGVzKGIiMDEyMzQ1Njc4OSIpCiAgICBieXRlICIwMTIzNDU2Nzg5IgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTUKICAgIC8vIHJldHVybiBpdG9hKGkgLy8gcmFkaXgpICsgU3RyaW5nLmZyb21fYnl0ZXMoZGlnaXRzW2kgJSByYWRpeF0pCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICBjb25jYXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuZ2V0X3ZvdGVfZnJvbV9ib3goaW5kZXg6IHVpbnQ2NCkgLT4gdWludDY0OgpnZXRfdm90ZV9mcm9tX2JveDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjM5LTI0MAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBnZXRfdm90ZV9mcm9tX2JveChzZWxmLCBpbmRleDogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTUKICAgIC8vIHNlbGYudGFsbHlfYm94ID0gQm94UmVmKGtleT1iIlYiKQogICAgYnl0ZSAiViIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQxCiAgICAvLyByZXR1cm4gb3AuYnRvaShzZWxmLnRhbGx5X2JveC5leHRyYWN0KGluZGV4LCBWT1RFX0NPVU5UX0JZVEVTKSkKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDgKICAgIGJveF9leHRyYWN0CiAgICBidG9pCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmdldF9wcmVjb25kaXRpb25zKHNpZ25hdHVyZTogYnl0ZXMpIC0+IGJ5dGVzOgpnZXRfcHJlY29uZGl0aW9uczoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTYwLTE2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICAvLyBkZWYgZ2V0X3ByZWNvbmRpdGlvbnMoc2VsZiwgc2lnbmF0dXJlOiBCeXRlcykgLT4gVm90aW5nUHJlY29uZGl0aW9uczoKICAgIHByb3RvIDEgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjMKICAgIC8vIGlzX3ZvdGluZ19vcGVuPWFyYzQuVUludDY0KHNlbGYudm90aW5nX29wZW4oKSksCiAgICBjYWxsc3ViIHZvdGluZ19vcGVuCiAgICBpdG9iCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2NAogICAgLy8gaXNfYWxsb3dlZF90b192b3RlPWFyYzQuVUludDY0KHNlbGYuYWxsb3dlZF90b192b3RlKHNpZ25hdHVyZSkpLAogICAgZnJhbWVfZGlnIC0xCiAgICBjYWxsc3ViIGFsbG93ZWRfdG9fdm90ZQogICAgaXRvYgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjUKICAgIC8vIGhhc19hbHJlYWR5X3ZvdGVkPWFyYzQuVUludDY0KHNlbGYuYWxyZWFkeV92b3RlZCgpKSwKICAgIGNhbGxzdWIgYWxyZWFkeV92b3RlZAogICAgaXRvYgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjYKICAgIC8vIGN1cnJlbnRfdGltZT1hcmM0LlVJbnQ2NChHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCksCiAgICBnbG9iYWwgTGF0ZXN0VGltZXN0YW1wCiAgICBpdG9iCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2Mi0xNjcKICAgIC8vIHJldHVybiBWb3RpbmdQcmVjb25kaXRpb25zKAogICAgLy8gICAgIGlzX3ZvdGluZ19vcGVuPWFyYzQuVUludDY0KHNlbGYudm90aW5nX29wZW4oKSksCiAgICAvLyAgICAgaXNfYWxsb3dlZF90b192b3RlPWFyYzQuVUludDY0KHNlbGYuYWxsb3dlZF90b192b3RlKHNpZ25hdHVyZSkpLAogICAgLy8gICAgIGhhc19hbHJlYWR5X3ZvdGVkPWFyYzQuVUludDY0KHNlbGYuYWxyZWFkeV92b3RlZCgpKSwKICAgIC8vICAgICBjdXJyZW50X3RpbWU9YXJjNC5VSW50NjQoR2xvYmFsLmxhdGVzdF90aW1lc3RhbXApLAogICAgLy8gKQogICAgdW5jb3ZlciAzCiAgICB1bmNvdmVyIDMKICAgIGNvbmNhdAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC52b3Rpbmdfb3BlbigpIC0+IHVpbnQ2NDoKdm90aW5nX29wZW46CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwNS0yMDYKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgdm90aW5nX29wZW4oc2VsZikgLT4gYm9vbDoKICAgIHByb3RvIDAgMQogICAgYnl0ZSAiIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDgKICAgIC8vIHNlbGYuaXNfYm9vdHN0cmFwcGVkCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1MQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBGYWxzZQogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDgKICAgIC8vIHNlbGYuaXNfYm9vdHN0cmFwcGVkCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIGlzX2Jvb3RzdHJhcHBlZCBleGlzdHMKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA4LTIxMAogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQKICAgIC8vIGFuZCBub3Qgc2VsZi5jbG9zZV90aW1lCiAgICAvLyBhbmQgc2VsZi5zdGFydF90aW1lIDw9IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wIDw9IHNlbGYuZW5kX3RpbWUKICAgIGJ6IHZvdGluZ19vcGVuX2Jvb2xfZmFsc2VANQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDkKICAgIC8vIGFuZCBub3Qgc2VsZi5jbG9zZV90aW1lCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1NAogICAgLy8gc2VsZi5jbG9zZV90aW1lID0gR2xvYmFsU3RhdGUoVUludDY0KQogICAgYnl0ZSAiY2xvc2VfdGltZSIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA5CiAgICAvLyBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYm56IHZvdGluZ19vcGVuX2Jvb2xfZmFsc2VANQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTAKICAgIC8vIGFuZCBzZWxmLnN0YXJ0X3RpbWUgPD0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPD0gc2VsZi5lbmRfdGltZQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzYKICAgIC8vIHNlbGYuc3RhcnRfdGltZSA9IHN0YXJ0X3RpbWUKICAgIGJ5dGUgInN0YXJ0X3RpbWUiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxMAogICAgLy8gYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHN0YXJ0X3RpbWUgZXhpc3RzCiAgICBnbG9iYWwgTGF0ZXN0VGltZXN0YW1wCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMAogICAgPD0KICAgIGJ6IHZvdGluZ19vcGVuX2Jvb2xfZmFsc2VANQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzcKICAgIC8vIHNlbGYuZW5kX3RpbWUgPSBlbmRfdGltZQogICAgYnl0ZSAiZW5kX3RpbWUiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxMAogICAgLy8gYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIGVuZF90aW1lIGV4aXN0cwogICAgZnJhbWVfZGlnIDAKICAgID49CiAgICBieiB2b3Rpbmdfb3Blbl9ib29sX2ZhbHNlQDUKICAgIGludCAxCiAgICBiIHZvdGluZ19vcGVuX2Jvb2xfbWVyZ2VANgoKdm90aW5nX29wZW5fYm9vbF9mYWxzZUA1OgogICAgaW50IDAKCnZvdGluZ19vcGVuX2Jvb2xfbWVyZ2VANjoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA3LTIxMQogICAgLy8gcmV0dXJuICgKICAgIC8vICAgICBzZWxmLmlzX2Jvb3RzdHJhcHBlZAogICAgLy8gICAgIGFuZCBub3Qgc2VsZi5jbG9zZV90aW1lCiAgICAvLyAgICAgYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICAvLyApCiAgICBzd2FwCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmFsbG93ZWRfdG9fdm90ZShzaWduYXR1cmU6IGJ5dGVzKSAtPiB1aW50NjQ6CmFsbG93ZWRfdG9fdm90ZToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjMwLTIzMQogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBhbGxvd2VkX3RvX3ZvdGUoc2VsZiwgc2lnbmF0dXJlOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDEgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMzIKICAgIC8vIGVuc3VyZV9idWRnZXQoMjAwMCkKICAgIGludCAyMDAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzNAogICAgLy8gVHhuLnNlbmRlci5ieXRlcywKICAgIHR4biBTZW5kZXIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjM2CiAgICAvLyBzZWxmLnNuYXBzaG90X3B1YmxpY19rZXksCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NAogICAgLy8gc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5ID0gc25hcHNob3RfcHVibGljX2tleQogICAgYnl0ZSAic25hcHNob3RfcHVibGljX2tleSIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjM2CiAgICAvLyBzZWxmLnNuYXBzaG90X3B1YmxpY19rZXksCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNuYXBzaG90X3B1YmxpY19rZXkgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzMy0yMzcKICAgIC8vIHJldHVybiBvcC5lZDI1NTE5dmVyaWZ5X2JhcmUoCiAgICAvLyAgICAgVHhuLnNlbmRlci5ieXRlcywKICAgIC8vICAgICBzaWduYXR1cmUsCiAgICAvLyAgICAgc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5LAogICAgLy8gKQogICAgZnJhbWVfZGlnIC0xCiAgICBzd2FwCiAgICBlZDI1NTE5dmVyaWZ5X2JhcmUKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuYWxyZWFkeV92b3RlZCgpIC0+IHVpbnQ2NDoKYWxyZWFkeV92b3RlZDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjEzLTIxNAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBhbHJlYWR5X3ZvdGVkKHNlbGYpIC0+IGJvb2w6CiAgICBwcm90byAwIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjE1CiAgICAvLyByZXR1cm4gVHhuLnNlbmRlciBpbiBzZWxmLnZvdGVzX2J5X2FjY291bnQKICAgIHR4biBTZW5kZXIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTYtMjE1CiAgICAvLyAgICAgc2VsZi52b3Rlc19ieV9hY2NvdW50ID0gQm94TWFwKEFjY291bnQsIFZvdGVJbmRleEFycmF5KQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIC8vIGRlZiBjcmVhdGUoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICB2b3RlX2lkOiBTdHJpbmcsCiAgICAvLyAgICAgc25hcHNob3RfcHVibGljX2tleTogQnl0ZXMsCiAgICAvLyAgICAgbWV0YWRhdGFfaXBmc19jaWQ6IFN0cmluZywKICAgIC8vICAgICBzdGFydF90aW1lOiBVSW50NjQsCiAgICAvLyAgICAgZW5kX3RpbWU6IFVJbnQ2NCwKICAgIC8vICAgICBvcHRpb25fY291bnRzOiBWb3RlSW5kZXhBcnJheSwKICAgIC8vICAgICBxdW9ydW06IFVJbnQ2NCwKICAgIC8vICAgICBuZnRfaW1hZ2VfdXJsOiBTdHJpbmcsCiAgICAvLyApIC0+IE5vbmU6CiAgICAvLyAgICAgYXNzZXJ0IHN0YXJ0X3RpbWUgPCBlbmRfdGltZSwgIkVuZCB0aW1lIHNob3VsZCBiZSBhZnRlciBzdGFydCB0aW1lIgogICAgLy8gICAgIGFzc2VydCBlbmRfdGltZSA+PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCwgIkVuZCB0aW1lIHNob3VsZCBiZSBpbiB0aGUgZnV0dXJlIgogICAgLy8gCiAgICAvLyAgICAgc2VsZi52b3RlX2lkID0gdm90ZV9pZAogICAgLy8gICAgIHNlbGYuc25hcHNob3RfcHVibGljX2tleSA9IHNuYXBzaG90X3B1YmxpY19rZXkKICAgIC8vICAgICBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkID0gbWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICAgICBzZWxmLnN0YXJ0X3RpbWUgPSBzdGFydF90aW1lCiAgICAvLyAgICAgc2VsZi5lbmRfdGltZSA9IGVuZF90aW1lCiAgICAvLyAgICAgc2VsZi5xdW9ydW0gPSBxdW9ydW0KICAgIC8vICAgICBzZWxmLm5mdF9pbWFnZV91cmwgPSBuZnRfaW1hZ2VfdXJsCiAgICAvLyAgICAgc2VsZi5zdG9yZV9vcHRpb25fY291bnRzKG9wdGlvbl9jb3VudHMuY29weSgpKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib290c3RyYXAoc2VsZiwgZnVuZF9taW5fYmFsX3JlcTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24pIC0+IE5vbmU6CiAgICAvLyAgICAgYXNzZXJ0IG5vdCBzZWxmLmlzX2Jvb3RzdHJhcHBlZCwgIk11c3Qgbm90IGJlIGFscmVhZHkgYm9vdHN0cmFwcGVkIgogICAgLy8gICAgIHNlbGYuaXNfYm9vdHN0cmFwcGVkID0gVHJ1ZQogICAgLy8gCiAgICAvLyAgICAgYXNzZXJ0ICgKICAgIC8vICAgICAgICAgZnVuZF9taW5fYmFsX3JlcS5yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzCiAgICAvLyAgICAgKSwgIlBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcyIKICAgIC8vIAogICAgLy8gICAgIHRhbGx5X2JveF9zaXplID0gc2VsZi50b3RhbF9vcHRpb25zICogVk9URV9DT1VOVF9CWVRFUwogICAgLy8gICAgIG1pbl9iYWxhbmNlX3JlcSA9ICgKICAgIC8vICAgICAgICAgIyBtaW5pbXVtIGJhbGFuY2UgcmVxIGZvcjogQUxHT3MgKyBWb3RlIHJlc3VsdCBORlQgYXNzZXQKICAgIC8vICAgICAgICAgQVNTRVRfTUlOX0JBTEFOQ0UgKiAyCiAgICAvLyAgICAgICAgICMgY3JlYXRlIE5GVCBmZWUKICAgIC8vICAgICAgICAgKyAxMDAwCiAgICAvLyAgICAgICAgICMgdGFsbHkgYm94CiAgICAvLyAgICAgICAgICsgQk9YX0ZMQVRfTUlOX0JBTEFOQ0UKICAgIC8vICAgICAgICAgIyB0YWxseSBib3gga2V5ICJWIgogICAgLy8gICAgICAgICArIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICAvLyAgICAgICAgICMgdGFsbHkgYm94IHZhbHVlCiAgICAvLyAgICAgICAgICsgKHRhbGx5X2JveF9zaXplICogQk9YX0JZVEVfTUlOX0JBTEFOQ0UpCiAgICAvLyAgICAgKQogICAgLy8gICAgIGxvZyhtaW5fYmFsYW5jZV9yZXEpCiAgICAvLyAgICAgYXNzZXJ0ICgKICAgIC8vICAgICAgICAgZnVuZF9taW5fYmFsX3JlcS5hbW91bnQgPT0gbWluX2JhbGFuY2VfcmVxCiAgICAvLyAgICAgKSwgIlBheW1lbnQgbXVzdCBiZSBmb3IgdGhlIGV4YWN0IG1pbiBiYWxhbmNlIHJlcXVpcmVtZW50IgogICAgLy8gICAgIGFzc2VydCBzZWxmLnRhbGx5X2JveC5jcmVhdGUoc2l6ZT10YWxseV9ib3hfc2l6ZSkKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgY2xvc2Uoc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBlbnN1cmVfYnVkZ2V0KDIwMDAwLCBmZWVfc291cmNlPU9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBzZWxmLmNsb3NlX3RpbWUsICJBbHJlYWR5IGNsb3NlZCIKICAgIC8vICAgICBzZWxmLmNsb3NlX3RpbWUudmFsdWUgPSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcAogICAgLy8gCiAgICAvLyAgICAgbm90ZSA9ICgKICAgIC8vICAgICAgICAgJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gICAgICAgICAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyAgICAgICAgICsgc2VsZi52b3RlX2lkCiAgICAvLyAgICAgICAgICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICAgICAgICAgKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyAgICAgICAgICsgJyIsImlkIjoiJwogICAgLy8gICAgICAgICArIHNlbGYudm90ZV9pZAogICAgLy8gICAgICAgICArICciLCJxdW9ydW0iOicKICAgIC8vICAgICAgICAgKyBpdG9hKHNlbGYucXVvcnVtKQogICAgLy8gICAgICAgICArICcsInZvdGVyQ291bnQiOicKICAgIC8vICAgICAgICAgKyBpdG9hKHNlbGYudm90ZXJfY291bnQpCiAgICAvLyAgICAgICAgICsgJywidGFsbGllcyI6WycKICAgIC8vICAgICApCiAgICAvLyAKICAgIC8vICAgICBjdXJyZW50X2luZGV4ID0gVUludDY0KDApCiAgICAvLyAgICAgZm9yIHF1ZXN0aW9uX2luZGV4LCBxdWVzdGlvbl9vcHRpb25zIGluIHVlbnVtZXJhdGUoc2VsZi5vcHRpb25fY291bnRzKToKICAgIC8vICAgICAgICAgaWYgcXVlc3Rpb25faW5kZXggPiAwOgogICAgLy8gICAgICAgICAgICAgbm90ZSArPSAiLCIKICAgIC8vICAgICAgICAgaWYgcXVlc3Rpb25fb3B0aW9ucyA+IDA6CiAgICAvLyAgICAgICAgICAgICBub3RlICs9ICJbIgogICAgLy8gICAgICAgICAgICAgZm9yIG9wdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25fb3B0aW9ucy5uYXRpdmUpOgogICAgLy8gICAgICAgICAgICAgICAgIGlmIG9wdGlvbl9pbmRleCA+IDA6CiAgICAvLyAgICAgICAgICAgICAgICAgICAgIG5vdGUgKz0gIiwiCiAgICAvLyAgICAgICAgICAgICAgICAgdm90ZXNfZm9yX29wdGlvbiA9IHNlbGYuZ2V0X3ZvdGVfZnJvbV9ib3goY3VycmVudF9pbmRleCkKICAgIC8vICAgICAgICAgICAgICAgICBub3RlICs9IGl0b2Eodm90ZXNfZm9yX29wdGlvbikKICAgIC8vICAgICAgICAgICAgICAgICBjdXJyZW50X2luZGV4ICs9IDEKICAgIC8vICAgICAgICAgICAgIG5vdGUgKz0gIl0iCiAgICAvLyAgICAgbm90ZSArPSAiXX19IgogICAgLy8gICAgIHNlbGYubmZ0X2Fzc2V0X2lkID0gKAogICAgLy8gICAgICAgICBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgICAgICAgICAgdG90YWw9MSwKICAgIC8vICAgICAgICAgICAgIGRlY2ltYWxzPTAsCiAgICAvLyAgICAgICAgICAgICBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIC8vICAgICAgICAgICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICAgICAgICAgIHVuaXRfbmFtZT0iVk9URVJTTFQiLAogICAgLy8gICAgICAgICAgICAgdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIC8vICAgICAgICAgICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICAgICAgICAgIGZlZT1HbG9iYWwubWluX3R4bl9mZWUsCiAgICAvLyAgICAgICAgICkKICAgIC8vICAgICAgICAgLnN1Ym1pdCgpCiAgICAvLyAgICAgICAgIC5jcmVhdGVkX2Fzc2V0LmlkCiAgICAvLyAgICAgKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIC8vIGRlZiBnZXRfcHJlY29uZGl0aW9ucyhzZWxmLCBzaWduYXR1cmU6IEJ5dGVzKSAtPiBWb3RpbmdQcmVjb25kaXRpb25zOgogICAgLy8gICAgIHJldHVybiBWb3RpbmdQcmVjb25kaXRpb25zKAogICAgLy8gICAgICAgICBpc192b3Rpbmdfb3Blbj1hcmM0LlVJbnQ2NChzZWxmLnZvdGluZ19vcGVuKCkpLAogICAgLy8gICAgICAgICBpc19hbGxvd2VkX3RvX3ZvdGU9YXJjNC5VSW50NjQoc2VsZi5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlKSksCiAgICAvLyAgICAgICAgIGhhc19hbHJlYWR5X3ZvdGVkPWFyYzQuVUludDY0KHNlbGYuYWxyZWFkeV92b3RlZCgpKSwKICAgIC8vICAgICAgICAgY3VycmVudF90aW1lPWFyYzQuVUludDY0KEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wKSwKICAgIC8vICAgICApCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZvdGUoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBmdW5kX21pbl9iYWxfcmVxOiBndHhuLlBheW1lbnRUcmFuc2FjdGlvbiwKICAgIC8vICAgICBzaWduYXR1cmU6IEJ5dGVzLAogICAgLy8gICAgIGFuc3dlcl9pZHM6IFZvdGVJbmRleEFycmF5LAogICAgLy8gKSAtPiBOb25lOgogICAgLy8gICAgIGVuc3VyZV9idWRnZXQoNzcwMCwgZmVlX3NvdXJjZT1PcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgLy8gICAgICMgQ2hlY2sgdm90aW5nIHByZWNvbmRpdGlvbnMKICAgIC8vICAgICBhc3NlcnQgc2VsZi5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlKSwgIk5vdCBhbGxvd2VkIHRvIHZvdGUiCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYudm90aW5nX29wZW4oKSwgIlZvdGluZyBub3Qgb3BlbiIKICAgIC8vICAgICBhc3NlcnQgbm90IHNlbGYuYWxyZWFkeV92b3RlZCgpLCAiQWxyZWFkeSB2b3RlZCIKICAgIC8vICAgICBxdWVzdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHMubGVuZ3RoCiAgICAvLyAgICAgYXNzZXJ0IGFuc3dlcl9pZHMubGVuZ3RoID09IHF1ZXN0aW9uc19jb3VudCwgIk51bWJlciBvZiBhbnN3ZXJzIGluY29ycmVjdCIKICAgIC8vICAgICAjIENoZWNrIHZvdGVyIGJveCBpcyBmdW5kZWQKICAgIC8vICAgICBtaW5fYmFsX3JlcSA9IEJPWF9GTEFUX01JTl9CQUxBTkNFICsgKAogICAgLy8gICAgICAgICAoMzIgKyAyICsgVk9URV9JTkRFWF9CWVRFUyAqIGFuc3dlcl9pZHMubGVuZ3RoKSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICAvLyAgICAgKQogICAgLy8gICAgIGFzc2VydCAoCiAgICAvLyAgICAgICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gICAgICksICJQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MiCiAgICAvLyAKICAgIC8vICAgICBsb2cobWluX2JhbF9yZXEpCiAgICAvLyAgICAgYXNzZXJ0IGZ1bmRfbWluX2JhbF9yZXEuYW1vdW50ID09IG1pbl9iYWxfcmVxLCAiUGF5bWVudCBtdXN0IGJlIHRoZSBleGFjdCBtaW4gYmFsYW5jZSIKICAgIC8vICAgICAjIFJlY29yZCB0aGUgdm90ZSBmb3IgZWFjaCBxdWVzdGlvbgogICAgLy8gICAgIGN1bXVsYXRpdmVfb2Zmc2V0ID0gVUludDY0KDApCiAgICAvLyAgICAgZm9yIHF1ZXN0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbnNfY291bnQpOgogICAgLy8gICAgICAgICAjIExvYWQgdGhlIHVzZXIncyB2b3RlIGZvciB0aGlzIHF1ZXN0aW9uCiAgICAvLyAgICAgICAgIGFuc3dlcl9vcHRpb25faW5kZXggPSBhbnN3ZXJfaWRzW3F1ZXN0aW9uX2luZGV4XS5uYXRpdmUKICAgIC8vICAgICAgICAgb3B0aW9uc19jb3VudCA9IHNlbGYub3B0aW9uX2NvdW50c1txdWVzdGlvbl9pbmRleF0ubmF0aXZlCiAgICAvLyAgICAgICAgIGFzc2VydCBhbnN3ZXJfb3B0aW9uX2luZGV4IDwgb3B0aW9uc19jb3VudCwgIkFuc3dlciBvcHRpb24gaW5kZXggaW52YWxpZCIKICAgIC8vICAgICAgICAgc2VsZi5pbmNyZW1lbnRfdm90ZV9pbl9ib3goY3VtdWxhdGl2ZV9vZmZzZXQgKyBhbnN3ZXJfb3B0aW9uX2luZGV4KQogICAgLy8gICAgICAgICBjdW11bGF0aXZlX29mZnNldCArPSBvcHRpb25zX2NvdW50CiAgICAvLyAgICAgICAgIHNlbGYudm90ZXNfYnlfYWNjb3VudFtUeG4uc2VuZGVyXSA9IGFuc3dlcl9pZHMuY29weSgpCiAgICAvLyAgICAgICAgIHNlbGYudm90ZXJfY291bnQgKz0gMQogICAgLy8gCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHZvdGluZ19vcGVuKHNlbGYpIC0+IGJvb2w6CiAgICAvLyAgICAgcmV0dXJuICgKICAgIC8vICAgICAgICAgc2VsZi5pc19ib290c3RyYXBwZWQKICAgIC8vICAgICAgICAgYW5kIG5vdCBzZWxmLmNsb3NlX3RpbWUKICAgIC8vICAgICAgICAgYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICAvLyAgICAgKQogICAgLy8gCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGFscmVhZHlfdm90ZWQoc2VsZikgLT4gYm9vbDoKICAgIC8vICAgICByZXR1cm4gVHhuLnNlbmRlciBpbiBzZWxmLnZvdGVzX2J5X2FjY291bnQKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTUKICAgIC8vIHJldHVybiBUeG4uc2VuZGVyIGluIHNlbGYudm90ZXNfYnlfYWNjb3VudAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC52b3RlKGZ1bmRfbWluX2JhbF9yZXE6IHVpbnQ2NCwgc2lnbmF0dXJlOiBieXRlcywgYW5zd2VyX2lkczogYnl0ZXMpIC0+IHZvaWQ6CnZvdGU6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2OS0xNzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZvdGUoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBmdW5kX21pbl9iYWxfcmVxOiBndHhuLlBheW1lbnRUcmFuc2FjdGlvbiwKICAgIC8vICAgICBzaWduYXR1cmU6IEJ5dGVzLAogICAgLy8gICAgIGFuc3dlcl9pZHM6IFZvdGVJbmRleEFycmF5LAogICAgLy8gKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE3NgogICAgLy8gZW5zdXJlX2J1ZGdldCg3NzAwLCBmZWVfc291cmNlPU9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgNzcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNzctMTc4CiAgICAvLyAjIENoZWNrIHZvdGluZyBwcmVjb25kaXRpb25zCiAgICAvLyBhc3NlcnQgc2VsZi5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlKSwgIk5vdCBhbGxvd2VkIHRvIHZvdGUiCiAgICBmcmFtZV9kaWcgLTIKICAgIGNhbGxzdWIgYWxsb3dlZF90b192b3RlCiAgICBhc3NlcnQgLy8gTm90IGFsbG93ZWQgdG8gdm90ZQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNzkKICAgIC8vIGFzc2VydCBzZWxmLnZvdGluZ19vcGVuKCksICJWb3Rpbmcgbm90IG9wZW4iCiAgICBjYWxsc3ViIHZvdGluZ19vcGVuCiAgICBhc3NlcnQgLy8gVm90aW5nIG5vdCBvcGVuCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4MAogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLmFscmVhZHlfdm90ZWQoKSwgIkFscmVhZHkgdm90ZWQiCiAgICBjYWxsc3ViIGFscmVhZHlfdm90ZWQKICAgICEKICAgIGFzc2VydCAvLyBBbHJlYWR5IHZvdGVkCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4MQogICAgLy8gcXVlc3Rpb25zX2NvdW50ID0gc2VsZi5vcHRpb25fY291bnRzLmxlbmd0aAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI3CiAgICAvLyBzZWxmLm9wdGlvbl9jb3VudHMgPSBvcHRpb25fY291bnRzLmNvcHkoKQogICAgYnl0ZSAib3B0aW9uX2NvdW50cyIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgxCiAgICAvLyBxdWVzdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHMubGVuZ3RoCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIG9wdGlvbl9jb3VudHMgZXhpc3RzCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGR1cAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODIKICAgIC8vIGFzc2VydCBhbnN3ZXJfaWRzLmxlbmd0aCA9PSBxdWVzdGlvbnNfY291bnQsICJOdW1iZXIgb2YgYW5zd2VycyBpbmNvcnJlY3QiCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBkdXAKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBOdW1iZXIgb2YgYW5zd2VycyBpbmNvcnJlY3QKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTg1CiAgICAvLyAoMzIgKyAyICsgVk9URV9JTkRFWF9CWVRFUyAqIGFuc3dlcl9pZHMubGVuZ3RoKSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICBpbnQgMzQKICAgICsKICAgIGludCA0MDAKICAgICoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgzLTE4NAogICAgLy8gIyBDaGVjayB2b3RlciBib3ggaXMgZnVuZGVkCiAgICAvLyBtaW5fYmFsX3JlcSA9IEJPWF9GTEFUX01JTl9CQUxBTkNFICsgKAogICAgaW50IDI1MDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgzLTE4NgogICAgLy8gIyBDaGVjayB2b3RlciBib3ggaXMgZnVuZGVkCiAgICAvLyBtaW5fYmFsX3JlcSA9IEJPWF9GTEFUX01JTl9CQUxBTkNFICsgKAogICAgLy8gICAgICgzMiArIDIgKyBWT1RFX0lOREVYX0JZVEVTICogYW5zd2VyX2lkcy5sZW5ndGgpICogQk9YX0JZVEVfTUlOX0JBTEFOQ0UKICAgIC8vICkKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTg4CiAgICAvLyBmdW5kX21pbl9iYWxfcmVxLnJlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgUmVjZWl2ZXIKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICA9PQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODctMTg5CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gKSwgIlBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcyIKICAgIGFzc2VydCAvLyBQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTkxCiAgICAvLyBsb2cobWluX2JhbF9yZXEpCiAgICBkdXAKICAgIGl0b2IKICAgIGxvZwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTIKICAgIC8vIGFzc2VydCBmdW5kX21pbl9iYWxfcmVxLmFtb3VudCA9PSBtaW5fYmFsX3JlcSwgIlBheW1lbnQgbXVzdCBiZSB0aGUgZXhhY3QgbWluIGJhbGFuY2UiCiAgICBmcmFtZV9kaWcgLTMKICAgIGd0eG5zIEFtb3VudAogICAgPT0KICAgIGFzc2VydCAvLyBQYXltZW50IG11c3QgYmUgdGhlIGV4YWN0IG1pbiBiYWxhbmNlCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5My0xOTQKICAgIC8vICMgUmVjb3JkIHRoZSB2b3RlIGZvciBlYWNoIHF1ZXN0aW9uCiAgICAvLyBjdW11bGF0aXZlX29mZnNldCA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTk1CiAgICAvLyBmb3IgcXVlc3Rpb25faW5kZXggaW4gdXJhbmdlKHF1ZXN0aW9uc19jb3VudCk6CiAgICBkdXAKCnZvdGVfZm9yX2hlYWRlckAxOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTUKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25zX2NvdW50KToKICAgIGZyYW1lX2RpZyAzCiAgICBmcmFtZV9kaWcgMAogICAgPAogICAgYnogdm90ZV9hZnRlcl9mb3JANQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTYtMTk3CiAgICAvLyAjIExvYWQgdGhlIHVzZXIncyB2b3RlIGZvciB0aGlzIHF1ZXN0aW9uCiAgICAvLyBhbnN3ZXJfb3B0aW9uX2luZGV4ID0gYW5zd2VyX2lkc1txdWVzdGlvbl9pbmRleF0ubmF0aXZlCiAgICBmcmFtZV9kaWcgMwogICAgZHVwCiAgICBmcmFtZV9kaWcgMQogICAgPAogICAgYXNzZXJ0IC8vIEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMiAwCiAgICBkaWcgMQogICAgaW50IDEKICAgIGV4dHJhY3QzCiAgICBidG9pCiAgICBzd2FwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5OAogICAgLy8gb3B0aW9uc19jb3VudCA9IHNlbGYub3B0aW9uX2NvdW50c1txdWVzdGlvbl9pbmRleF0ubmF0aXZlCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjcKICAgIC8vIHNlbGYub3B0aW9uX2NvdW50cyA9IG9wdGlvbl9jb3VudHMuY29weSgpCiAgICBieXRlICJvcHRpb25fY291bnRzIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTgKICAgIC8vIG9wdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHNbcXVlc3Rpb25faW5kZXhdLm5hdGl2ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBvcHRpb25fY291bnRzIGV4aXN0cwogICAgZHVwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGRpZyAyCiAgICA+CiAgICBhc3NlcnQgLy8gSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGV4dHJhY3QgMiAwCiAgICBkaWcgMQogICAgaW50IDEKICAgIGV4dHJhY3QzCiAgICBidG9pCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5OQogICAgLy8gYXNzZXJ0IGFuc3dlcl9vcHRpb25faW5kZXggPCBvcHRpb25zX2NvdW50LCAiQW5zd2VyIG9wdGlvbiBpbmRleCBpbnZhbGlkIgogICAgZGlnIDIKICAgIGRpZyAxCiAgICA8CiAgICBhc3NlcnQgLy8gQW5zd2VyIG9wdGlvbiBpbmRleCBpbnZhbGlkCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMAogICAgLy8gc2VsZi5pbmNyZW1lbnRfdm90ZV9pbl9ib3goY3VtdWxhdGl2ZV9vZmZzZXQgKyBhbnN3ZXJfb3B0aW9uX2luZGV4KQogICAgZnJhbWVfZGlnIDIKICAgIGR1cAogICAgdW5jb3ZlciA0CiAgICArCiAgICBjYWxsc3ViIGluY3JlbWVudF92b3RlX2luX2JveAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDEKICAgIC8vIGN1bXVsYXRpdmVfb2Zmc2V0ICs9IG9wdGlvbnNfY291bnQKICAgICsKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDIKICAgIC8vIHNlbGYudm90ZXNfYnlfYWNjb3VudFtUeG4uc2VuZGVyXSA9IGFuc3dlcl9pZHMuY29weSgpCiAgICB0eG4gU2VuZGVyCiAgICBkdXAKICAgIGJveF9kZWwKICAgIHBvcAogICAgZnJhbWVfZGlnIC0xCiAgICBib3hfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMwogICAgLy8gc2VsZi52b3Rlcl9jb3VudCArPSAxCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1Mi01MwogICAgLy8gIyBUaGUgbWluaW11bSBudW1iZXIgb2Ygdm90ZXJzIHdobyBoYXZlIHZvdGVkCiAgICAvLyBzZWxmLnZvdGVyX2NvdW50ID0gVUludDY0KDApCiAgICBieXRlICJ2b3Rlcl9jb3VudCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjAzCiAgICAvLyBzZWxmLnZvdGVyX2NvdW50ICs9IDEKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgdm90ZXJfY291bnQgZXhpc3RzCiAgICBpbnQgMQogICAgKwogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1Mi01MwogICAgLy8gIyBUaGUgbWluaW11bSBudW1iZXIgb2Ygdm90ZXJzIHdobyBoYXZlIHZvdGVkCiAgICAvLyBzZWxmLnZvdGVyX2NvdW50ID0gVUludDY0KDApCiAgICBieXRlICJ2b3Rlcl9jb3VudCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjAzCiAgICAvLyBzZWxmLnZvdGVyX2NvdW50ICs9IDEKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5NQogICAgLy8gZm9yIHF1ZXN0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbnNfY291bnQpOgogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2J1cnkgMwogICAgYiB2b3RlX2Zvcl9oZWFkZXJAMQoKdm90ZV9hZnRlcl9mb3JANToKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuaW5jcmVtZW50X3ZvdGVfaW5fYm94KGluZGV4OiB1aW50NjQpIC0+IHZvaWQ6CmluY3JlbWVudF92b3RlX2luX2JveDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQzLTI0NAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBpbmNyZW1lbnRfdm90ZV9pbl9ib3goc2VsZiwgaW5kZXg6IFVJbnQ2NCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNDUKICAgIC8vIGN1cnJlbnRfdm90ZSA9IHNlbGYuZ2V0X3ZvdGVfZnJvbV9ib3goaW5kZXgpCiAgICBmcmFtZV9kaWcgLTEKICAgIGNhbGxzdWIgZ2V0X3ZvdGVfZnJvbV9ib3gKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQ2CiAgICAvLyBzZWxmLnRhbGx5X2JveC5yZXBsYWNlKGluZGV4LCBvcC5pdG9iKGN1cnJlbnRfdm90ZSArIDEpKQogICAgaW50IDEKICAgICsKICAgIGl0b2IKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTUKICAgIC8vIHNlbGYudGFsbHlfYm94ID0gQm94UmVmKGtleT1iIlYiKQogICAgYnl0ZSAiViIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQ2CiAgICAvLyBzZWxmLnRhbGx5X2JveC5yZXBsYWNlKGluZGV4LCBvcC5pdG9iKGN1cnJlbnRfdm90ZSArIDEpKQogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJveF9yZXBsYWNlCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUwCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1MQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBGYWxzZQogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUyLTUzCiAgICAvLyAjIFRoZSBtaW5pbXVtIG51bWJlciBvZiB2b3RlcnMgd2hvIGhhdmUgdm90ZWQKICAgIC8vIHNlbGYudm90ZXJfY291bnQgPSBVSW50NjQoMCkKICAgIGJ5dGUgInZvdGVyX2NvdW50IgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICBtZXRob2QgImNyZWF0ZShzdHJpbmcsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDY0LHVpbnQ4W10sdWludDY0LHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJib290c3RyYXAocGF5KXZvaWQiCiAgICBtZXRob2QgImNsb3NlKCl2b2lkIgogICAgbWV0aG9kICJnZXRfcHJlY29uZGl0aW9ucyhieXRlW10pKHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCkiCiAgICBtZXRob2QgInZvdGUocGF5LGJ5dGVbXSx1aW50OFtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX2NyZWF0ZV9yb3V0ZUAzIG1haW5fYm9vdHN0cmFwX3JvdXRlQDQgbWFpbl9jbG9zZV9yb3V0ZUA1IG1haW5fZ2V0X3ByZWNvbmRpdGlvbnNfcm91dGVANiBtYWluX3ZvdGVfcm91dGVANwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl9jcmVhdGVfcm91dGVAMzoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjQ5CiAgICAvLyBjbGFzcyBWb3RpbmdSb3VuZEFwcChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgZXh0cmFjdCAyIDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgY2FsbHN1YiBjcmVhdGUKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYm9vdHN0cmFwX3JvdXRlQDQ6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib290c3RyYXAKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fY2xvc2Vfcm91dGVANToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgY2xvc2UKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fZ2V0X3ByZWNvbmRpdGlvbnNfcm91dGVANjoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgY2FsbHN1YiBnZXRfcHJlY29uZGl0aW9ucwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92b3RlX3JvdXRlQDc6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjQ5CiAgICAvLyBjbGFzcyBWb3RpbmdSb3VuZEFwcChBUkM0Q29udHJhY3QpOgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB2b3RlCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5jcmVhdGUodm90ZV9pZDogYnl0ZXMsIHNuYXBzaG90X3B1YmxpY19rZXk6IGJ5dGVzLCBtZXRhZGF0YV9pcGZzX2NpZDogYnl0ZXMsIHN0YXJ0X3RpbWU6IHVpbnQ2NCwgZW5kX3RpbWU6IHVpbnQ2NCwgb3B0aW9uX2NvdW50czogYnl0ZXMsIHF1b3J1bTogdWludDY0LCBuZnRfaW1hZ2VfdXJsOiBieXRlcykgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1OC02OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICAvLyBkZWYgY3JlYXRlKAogICAgLy8gICAgIHNlbGYsCiAgICAvLyAgICAgdm90ZV9pZDogU3RyaW5nLAogICAgLy8gICAgIHNuYXBzaG90X3B1YmxpY19rZXk6IEJ5dGVzLAogICAgLy8gICAgIG1ldGFkYXRhX2lwZnNfY2lkOiBTdHJpbmcsCiAgICAvLyAgICAgc3RhcnRfdGltZTogVUludDY0LAogICAgLy8gICAgIGVuZF90aW1lOiBVSW50NjQsCiAgICAvLyAgICAgb3B0aW9uX2NvdW50czogVm90ZUluZGV4QXJyYXksCiAgICAvLyAgICAgcXVvcnVtOiBVSW50NjQsCiAgICAvLyAgICAgbmZ0X2ltYWdlX3VybDogU3RyaW5nLAogICAgLy8gKSAtPiBOb25lOgogICAgcHJvdG8gOCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjcwCiAgICAvLyBhc3NlcnQgc3RhcnRfdGltZSA8IGVuZF90aW1lLCAiRW5kIHRpbWUgc2hvdWxkIGJlIGFmdGVyIHN0YXJ0IHRpbWUiCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgPAogICAgYXNzZXJ0IC8vIEVuZCB0aW1lIHNob3VsZCBiZSBhZnRlciBzdGFydCB0aW1lCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjcxCiAgICAvLyBhc3NlcnQgZW5kX3RpbWUgPj0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAsICJFbmQgdGltZSBzaG91bGQgYmUgaW4gdGhlIGZ1dHVyZSIKICAgIGZyYW1lX2RpZyAtNAogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgPj0KICAgIGFzc2VydCAvLyBFbmQgdGltZSBzaG91bGQgYmUgaW4gdGhlIGZ1dHVyZQogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3MwogICAgLy8gc2VsZi52b3RlX2lkID0gdm90ZV9pZAogICAgYnl0ZSAidm90ZV9pZCIKICAgIGZyYW1lX2RpZyAtOAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzQKICAgIC8vIHNlbGYuc25hcHNob3RfcHVibGljX2tleSA9IHNuYXBzaG90X3B1YmxpY19rZXkKICAgIGJ5dGUgInNuYXBzaG90X3B1YmxpY19rZXkiCiAgICBmcmFtZV9kaWcgLTcKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc1CiAgICAvLyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkID0gbWV0YWRhdGFfaXBmc19jaWQKICAgIGJ5dGUgIm1ldGFkYXRhX2lwZnNfY2lkIgogICAgZnJhbWVfZGlnIC02CiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NgogICAgLy8gc2VsZi5zdGFydF90aW1lID0gc3RhcnRfdGltZQogICAgYnl0ZSAic3RhcnRfdGltZSIKICAgIGZyYW1lX2RpZyAtNQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzcKICAgIC8vIHNlbGYuZW5kX3RpbWUgPSBlbmRfdGltZQogICAgYnl0ZSAiZW5kX3RpbWUiCiAgICBmcmFtZV9kaWcgLTQKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc4CiAgICAvLyBzZWxmLnF1b3J1bSA9IHF1b3J1bQogICAgYnl0ZSAicXVvcnVtIgogICAgZnJhbWVfZGlnIC0yCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3OQogICAgLy8gc2VsZi5uZnRfaW1hZ2VfdXJsID0gbmZ0X2ltYWdlX3VybAogICAgYnl0ZSAibmZ0X2ltYWdlX3VybCIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODAKICAgIC8vIHNlbGYuc3RvcmVfb3B0aW9uX2NvdW50cyhvcHRpb25fY291bnRzLmNvcHkoKSkKICAgIGZyYW1lX2RpZyAtMwogICAgY2FsbHN1YiBzdG9yZV9vcHRpb25fY291bnRzCiAgICBwb3AKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuc3RvcmVfb3B0aW9uX2NvdW50cyhvcHRpb25fY291bnRzOiBieXRlcykgLT4gYnl0ZXM6CnN0b3JlX29wdGlvbl9jb3VudHM6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxNy0yMTgKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgc3RvcmVfb3B0aW9uX2NvdW50cyhzZWxmLCBvcHRpb25fY291bnRzOiBWb3RlSW5kZXhBcnJheSkgLT4gTm9uZToKICAgIHByb3RvIDEgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTkKICAgIC8vIGFzc2VydCBvcHRpb25fY291bnRzLmxlbmd0aCwgIm9wdGlvbl9jb3VudHMgc2hvdWxkIGJlIG5vbi1lbXB0eSIKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkdXBuIDIKICAgIGFzc2VydCAvLyBvcHRpb25fY291bnRzIHNob3VsZCBiZSBub24tZW1wdHkKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjIwCiAgICAvLyBhc3NlcnQgb3B0aW9uX2NvdW50cy5sZW5ndGggPD0gMTEyLCAiQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gMTEyIHF1ZXN0aW9ucyIKICAgIGludCAxMTIKICAgIDw9CiAgICBhc3NlcnQgLy8gQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gMTEyIHF1ZXN0aW9ucwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjIKICAgIC8vIHRvdGFsX29wdGlvbnMgPSBVSW50NjQoMCkKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyMwogICAgLy8gZm9yIGl0ZW0gaW4gb3B0aW9uX2NvdW50czoKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAyIDAKICAgIGludCAwCgpzdG9yZV9vcHRpb25fY291bnRzX2Zvcl9oZWFkZXJAMToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjIzCiAgICAvLyBmb3IgaXRlbSBpbiBvcHRpb25fY291bnRzOgogICAgZnJhbWVfZGlnIDMKICAgIGZyYW1lX2RpZyAwCiAgICA8CiAgICBieiBzdG9yZV9vcHRpb25fY291bnRzX2FmdGVyX2ZvckA0CiAgICBmcmFtZV9kaWcgMgogICAgZnJhbWVfZGlnIDMKICAgIGR1cAogICAgY292ZXIgMgogICAgaW50IDEKICAgIGV4dHJhY3QzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyNAogICAgLy8gdG90YWxfb3B0aW9ucyArPSBpdGVtLm5hdGl2ZQogICAgYnRvaQogICAgZnJhbWVfZGlnIDEKICAgICsKICAgIGZyYW1lX2J1cnkgMQogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2J1cnkgMwogICAgYiBzdG9yZV9vcHRpb25fY291bnRzX2Zvcl9oZWFkZXJAMQoKc3RvcmVfb3B0aW9uX2NvdW50c19hZnRlcl9mb3JANDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI1CiAgICAvLyBhc3NlcnQgdG90YWxfb3B0aW9ucyA8PSAxMjgsICJDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMjggdm90ZSBvcHRpb25zIgogICAgZnJhbWVfZGlnIDEKICAgIGR1cAogICAgaW50IDEyOAogICAgPD0KICAgIGFzc2VydCAvLyBDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMjggdm90ZSBvcHRpb25zCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyNwogICAgLy8gc2VsZi5vcHRpb25fY291bnRzID0gb3B0aW9uX2NvdW50cy5jb3B5KCkKICAgIGJ5dGUgIm9wdGlvbl9jb3VudHMiCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyOAogICAgLy8gc2VsZi50b3RhbF9vcHRpb25zID0gdG90YWxfb3B0aW9ucwogICAgYnl0ZSAidG90YWxfb3B0aW9ucyIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICBmcmFtZV9kaWcgLTEKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5ib290c3RyYXAoZnVuZF9taW5fYmFsX3JlcTogdWludDY0KSAtPiB2b2lkOgpib290c3RyYXA6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjgyLTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib290c3RyYXAoc2VsZiwgZnVuZF9taW5fYmFsX3JlcTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24pIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODQKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5pc19ib290c3RyYXBwZWQsICJNdXN0IG5vdCBiZSBhbHJlYWR5IGJvb3RzdHJhcHBlZCIKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUxCiAgICAvLyBzZWxmLmlzX2Jvb3RzdHJhcHBlZCA9IEZhbHNlCiAgICBieXRlICJpc19ib290c3RyYXBwZWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojg0CiAgICAvLyBhc3NlcnQgbm90IHNlbGYuaXNfYm9vdHN0cmFwcGVkLCAiTXVzdCBub3QgYmUgYWxyZWFkeSBib290c3RyYXBwZWQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIGlzX2Jvb3RzdHJhcHBlZCBleGlzdHMKICAgICEKICAgIGFzc2VydCAvLyBNdXN0IG5vdCBiZSBhbHJlYWR5IGJvb3RzdHJhcHBlZAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1MQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBGYWxzZQogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4NQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBUcnVlCiAgICBpbnQgMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODgKICAgIC8vIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojg3LTg5CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gKSwgIlBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcyIKICAgIGFzc2VydCAvLyBQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MKICAgIC8vIHZvdGluZy92b3RpbmcucHk6OTEKICAgIC8vIHRhbGx5X2JveF9zaXplID0gc2VsZi50b3RhbF9vcHRpb25zICogVk9URV9DT1VOVF9CWVRFUwogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI4CiAgICAvLyBzZWxmLnRvdGFsX29wdGlvbnMgPSB0b3RhbF9vcHRpb25zCiAgICBieXRlICJ0b3RhbF9vcHRpb25zIgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo5MQogICAgLy8gdGFsbHlfYm94X3NpemUgPSBzZWxmLnRvdGFsX29wdGlvbnMgKiBWT1RFX0NPVU5UX0JZVEVTCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHRvdGFsX29wdGlvbnMgZXhpc3RzCiAgICBpbnQgOAogICAgKgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDEtMTAyCiAgICAvLyAjIHRhbGx5IGJveCB2YWx1ZQogICAgLy8gKyAodGFsbHlfYm94X3NpemUgKiBCT1hfQllURV9NSU5fQkFMQU5DRSkKICAgIGR1cAogICAgaW50IDQwMAogICAgKgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo5My0xMDAKICAgIC8vICMgbWluaW11bSBiYWxhbmNlIHJlcSBmb3I6IEFMR09zICsgVm90ZSByZXN1bHQgTkZUIGFzc2V0CiAgICAvLyBBU1NFVF9NSU5fQkFMQU5DRSAqIDIKICAgIC8vICMgY3JlYXRlIE5GVCBmZWUKICAgIC8vICsgMTAwMAogICAgLy8gIyB0YWxseSBib3gKICAgIC8vICsgQk9YX0ZMQVRfTUlOX0JBTEFOQ0UKICAgIC8vICMgdGFsbHkgYm94IGtleSAiViIKICAgIC8vICsgQk9YX0JZVEVfTUlOX0JBTEFOQ0UKICAgIGludCAyMDM5MDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6OTMtMTAyCiAgICAvLyAjIG1pbmltdW0gYmFsYW5jZSByZXEgZm9yOiBBTEdPcyArIFZvdGUgcmVzdWx0IE5GVCBhc3NldAogICAgLy8gQVNTRVRfTUlOX0JBTEFOQ0UgKiAyCiAgICAvLyAjIGNyZWF0ZSBORlQgZmVlCiAgICAvLyArIDEwMDAKICAgIC8vICMgdGFsbHkgYm94CiAgICAvLyArIEJPWF9GTEFUX01JTl9CQUxBTkNFCiAgICAvLyAjIHRhbGx5IGJveCBrZXkgIlYiCiAgICAvLyArIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICAvLyAjIHRhbGx5IGJveCB2YWx1ZQogICAgLy8gKyAodGFsbHlfYm94X3NpemUgKiBCT1hfQllURV9NSU5fQkFMQU5DRSkKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTA0CiAgICAvLyBsb2cobWluX2JhbGFuY2VfcmVxKQogICAgZHVwCiAgICBpdG9iCiAgICBsb2cKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTA2CiAgICAvLyBmdW5kX21pbl9iYWxfcmVxLmFtb3VudCA9PSBtaW5fYmFsYW5jZV9yZXEKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgQW1vdW50CiAgICA9PQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDUtMTA3CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXEuYW1vdW50ID09IG1pbl9iYWxhbmNlX3JlcQogICAgLy8gKSwgIlBheW1lbnQgbXVzdCBiZSBmb3IgdGhlIGV4YWN0IG1pbiBiYWxhbmNlIHJlcXVpcmVtZW50IgogICAgYXNzZXJ0IC8vIFBheW1lbnQgbXVzdCBiZSBmb3IgdGhlIGV4YWN0IG1pbiBiYWxhbmNlIHJlcXVpcmVtZW50CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU1CiAgICAvLyBzZWxmLnRhbGx5X2JveCA9IEJveFJlZihrZXk9IlYiKQogICAgYnl0ZSAiViIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTA4CiAgICAvLyBhc3NlcnQgc2VsZi50YWxseV9ib3guY3JlYXRlKHNpemU9dGFsbHlfYm94X3NpemUpCiAgICBzd2FwCiAgICBib3hfY3JlYXRlCiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuY2xvc2UoKSAtPiB2b2lkOgpjbG9zZToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTEwLTExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgY2xvc2Uoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgaW50IDAKICAgIGR1cAogICAgYnl0ZSAiIgogICAgZHVwbiAyCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExMgogICAgLy8gZW5zdXJlX2J1ZGdldCgyMDAwMCwgZmVlX3NvdXJjZT1PcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDIwMDAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExMwogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLmNsb3NlX3RpbWUsICJBbHJlYWR5IGNsb3NlZCIKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU0CiAgICAvLyBzZWxmLmNsb3NlX3RpbWUgPSBHbG9iYWxTdGF0ZShVSW50NjQpCiAgICBieXRlICJjbG9zZV90aW1lIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTMKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5jbG9zZV90aW1lLCAiQWxyZWFkeSBjbG9zZWQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYnVyeSAxCiAgICAhCiAgICBhc3NlcnQgLy8gQWxyZWFkeSBjbG9zZWQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTQKICAgIC8vIHNlbGYuY2xvc2VfdGltZSA9IEdsb2JhbFN0YXRlKFVJbnQ2NCkKICAgIGJ5dGUgImNsb3NlX3RpbWUiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNAogICAgLy8gc2VsZi5jbG9zZV90aW1lLnZhbHVlID0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAKICAgIGdsb2JhbCBMYXRlc3RUaW1lc3RhbXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExOQogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjczCiAgICAvLyBzZWxmLnZvdGVfaWQgPSB2b3RlX2lkCiAgICBieXRlICJ2b3RlX2lkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTkKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHZvdGVfaWQgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMTgKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIGJ5dGUgIntcInN0YW5kYXJkXCI6XCJhcmM2OVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTE5CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyMAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgYnl0ZSAiLlwiLFwicHJvcGVydGllc1wiOntcIm1ldGFkYXRhXCI6XCJpcGZzOi8vIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTIwCiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyMQogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NQogICAgLy8gc2VsZi5tZXRhZGF0YV9pcGZzX2NpZCA9IG1ldGFkYXRhX2lwZnNfY2lkCiAgICBieXRlICJtZXRhZGF0YV9pcGZzX2NpZCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTIxCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgbWV0YWRhdGFfaXBmc19jaWQgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjEKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjIKICAgIC8vICsgJyIsImlkIjoiJwogICAgYnl0ZSAiXCIsXCJpZFwiOlwiIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTIyCiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjMKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3MwogICAgLy8gc2VsZi52b3RlX2lkID0gdm90ZV9pZAogICAgYnl0ZSAidm90ZV9pZCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTIzCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayB2b3RlX2lkIGV4aXN0cwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTIzCiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTI0CiAgICAvLyArICciLCJxdW9ydW0iOicKICAgIGJ5dGUgIlwiLFwicXVvcnVtXCI6IgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTI0CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICciLCJxdW9ydW0iOicKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjUKICAgIC8vICsgaXRvYShzZWxmLnF1b3J1bSkKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc4CiAgICAvLyBzZWxmLnF1b3J1bSA9IHF1b3J1bQogICAgYnl0ZSAicXVvcnVtIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjUKICAgIC8vICsgaXRvYShzZWxmLnF1b3J1bSkKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgcXVvcnVtIGV4aXN0cwogICAgY2FsbHN1YiBpdG9hCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjUKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgLy8gKyBpdG9hKHNlbGYucXVvcnVtKQogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyNgogICAgLy8gKyAnLCJ2b3RlckNvdW50IjonCiAgICBieXRlICIsXCJ2b3RlckNvdW50XCI6IgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTI2CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICciLCJxdW9ydW0iOicKICAgIC8vICsgaXRvYShzZWxmLnF1b3J1bSkKICAgIC8vICsgJywidm90ZXJDb3VudCI6JwogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyNwogICAgLy8gKyBpdG9hKHNlbGYudm90ZXJfY291bnQpCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1Mi01MwogICAgLy8gIyBUaGUgbWluaW11bSBudW1iZXIgb2Ygdm90ZXJzIHdobyBoYXZlIHZvdGVkCiAgICAvLyBzZWxmLnZvdGVyX2NvdW50ID0gVUludDY0KDApCiAgICBieXRlICJ2b3Rlcl9jb3VudCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTI3CiAgICAvLyArIGl0b2Eoc2VsZi52b3Rlcl9jb3VudCkKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgdm90ZXJfY291bnQgZXhpc3RzCiAgICBjYWxsc3ViIGl0b2EKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyNwogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnIiwicXVvcnVtIjonCiAgICAvLyArIGl0b2Eoc2VsZi5xdW9ydW0pCiAgICAvLyArICcsInZvdGVyQ291bnQiOicKICAgIC8vICsgaXRvYShzZWxmLnZvdGVyX2NvdW50KQogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyOAogICAgLy8gKyAnLCJ0YWxsaWVzIjpbJwogICAgYnl0ZSAiLFwidGFsbGllc1wiOlsiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjgKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgLy8gKyBpdG9hKHNlbGYucXVvcnVtKQogICAgLy8gKyAnLCJ2b3RlckNvdW50IjonCiAgICAvLyArIGl0b2Eoc2VsZi52b3Rlcl9jb3VudCkKICAgIC8vICsgJywidGFsbGllcyI6WycKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzEKICAgIC8vIGN1cnJlbnRfaW5kZXggPSBVSW50NjQoMCkKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzMgogICAgLy8gZm9yIHF1ZXN0aW9uX2luZGV4LCBxdWVzdGlvbl9vcHRpb25zIGluIHVlbnVtZXJhdGUoc2VsZi5vcHRpb25fY291bnRzKToKICAgIGR1cAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjcKICAgIC8vIHNlbGYub3B0aW9uX2NvdW50cyA9IG9wdGlvbl9jb3VudHMuY29weSgpCiAgICBieXRlICJvcHRpb25fY291bnRzIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzIKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCwgcXVlc3Rpb25fb3B0aW9ucyBpbiB1ZW51bWVyYXRlKHNlbGYub3B0aW9uX2NvdW50cyk6CiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIG9wdGlvbl9jb3VudHMgZXhpc3RzCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgZXh0cmFjdCAyIDAKICAgIGludCAwCgpjbG9zZV9mb3JfaGVhZGVyQDE6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzMgogICAgLy8gZm9yIHF1ZXN0aW9uX2luZGV4LCBxdWVzdGlvbl9vcHRpb25zIGluIHVlbnVtZXJhdGUoc2VsZi5vcHRpb25fY291bnRzKToKICAgIGZyYW1lX2RpZyA5CiAgICBmcmFtZV9kaWcgNwogICAgPAogICAgYnogY2xvc2VfYWZ0ZXJfZm9yQDE1CiAgICBmcmFtZV9kaWcgOAogICAgZnJhbWVfZGlnIDkKICAgIGR1cAogICAgY292ZXIgMgogICAgaW50IDEKICAgIGV4dHJhY3QzCiAgICBmcmFtZV9idXJ5IDEKICAgIGZyYW1lX2RpZyA1CiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTMzCiAgICAvLyBpZiBxdWVzdGlvbl9pbmRleCA+IDA6CiAgICBieiBjbG9zZV9hZnRlcl9pZl9lbHNlQDQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM0CiAgICAvLyBub3RlICs9ICIsIgogICAgZnJhbWVfZGlnIDUKICAgIGJ5dGUgIiwiCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgMAoKY2xvc2VfYWZ0ZXJfaWZfZWxzZUA0OgogICAgZnJhbWVfZGlnIDAKICAgIGR1cAogICAgZnJhbWVfYnVyeSA1CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNQogICAgLy8gaWYgcXVlc3Rpb25fb3B0aW9ucyA+IDA6CiAgICBmcmFtZV9kaWcgMQogICAgYnl0ZSAweDAwCiAgICBiPgogICAgZnJhbWVfZGlnIDYKICAgIGZyYW1lX2J1cnkgMgogICAgc3dhcAogICAgZnJhbWVfYnVyeSAwCiAgICBieiBjbG9zZV9hZnRlcl9pZl9lbHNlQDEzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNgogICAgLy8gbm90ZSArPSAiWyIKICAgIGZyYW1lX2RpZyA1CiAgICBieXRlICJbIgogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IDUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM3CiAgICAvLyBmb3Igb3B0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbl9vcHRpb25zLm5hdGl2ZSk6CiAgICBmcmFtZV9kaWcgMQogICAgYnRvaQogICAgZnJhbWVfYnVyeSA0CiAgICBpbnQgMAogICAgZnJhbWVfYnVyeSAzCgpjbG9zZV9mb3JfaGVhZGVyQDY6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNwogICAgLy8gZm9yIG9wdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25fb3B0aW9ucy5uYXRpdmUpOgogICAgZnJhbWVfZGlnIDMKICAgIGZyYW1lX2RpZyA0CiAgICA8CiAgICBieiBjbG9zZV9hZnRlcl9mb3JAMTIKICAgIGZyYW1lX2RpZyA1CiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM4CiAgICAvLyBpZiBvcHRpb25faW5kZXggPiAwOgogICAgZnJhbWVfZGlnIDMKICAgIGJ6IGNsb3NlX2FmdGVyX2lmX2Vsc2VAOQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzkKICAgIC8vIG5vdGUgKz0gIiwiCiAgICBmcmFtZV9kaWcgNQogICAgYnl0ZSAiLCIKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAwCgpjbG9zZV9hZnRlcl9pZl9lbHNlQDk6CiAgICBmcmFtZV9kaWcgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDAKICAgIC8vIHZvdGVzX2Zvcl9vcHRpb24gPSBzZWxmLmdldF92b3RlX2Zyb21fYm94KGN1cnJlbnRfaW5kZXgpCiAgICBmcmFtZV9kaWcgNgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBjYWxsc3ViIGdldF92b3RlX2Zyb21fYm94CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0MQogICAgLy8gbm90ZSArPSBpdG9hKHZvdGVzX2Zvcl9vcHRpb24pCiAgICBjYWxsc3ViIGl0b2EKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSA1CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0MgogICAgLy8gY3VycmVudF9pbmRleCArPSAxCiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSA2CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNwogICAgLy8gZm9yIG9wdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25fb3B0aW9ucy5uYXRpdmUpOgogICAgZnJhbWVfZGlnIDMKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDMKICAgIGIgY2xvc2VfZm9yX2hlYWRlckA2CgpjbG9zZV9hZnRlcl9mb3JAMTI6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0MwogICAgLy8gbm90ZSArPSAiXSIKICAgIGZyYW1lX2RpZyA1CiAgICBieXRlICJdIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgNgogICAgZnJhbWVfYnVyeSAyCiAgICBmcmFtZV9idXJ5IDAKCmNsb3NlX2FmdGVyX2lmX2Vsc2VAMTM6CiAgICBmcmFtZV9kaWcgMgogICAgZnJhbWVfYnVyeSA2CiAgICBmcmFtZV9kaWcgMAogICAgZnJhbWVfYnVyeSA1CiAgICBmcmFtZV9kaWcgOQogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2J1cnkgOQogICAgYiBjbG9zZV9mb3JfaGVhZGVyQDEKCmNsb3NlX2FmdGVyX2ZvckAxNToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ0CiAgICAvLyBub3RlICs9ICJdfX0iCiAgICBmcmFtZV9kaWcgNQogICAgYnl0ZSAiXX19IgogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0Ni0xNTYKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICAvLyAgICAgdG90YWw9MSwKICAgIC8vICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgIGRlZmF1bHRfZnJvemVuPUZhbHNlLAogICAgLy8gICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgLy8gICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gKQogICAgLy8gLnN1Ym1pdCgpCiAgICBpdHhuX2JlZ2luCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE1NAogICAgLy8gZmVlPUdsb2JhbC5taW5fdHhuX2ZlZSwKICAgIGdsb2JhbCBNaW5UeG5GZWUKICAgIHN3YXAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUwCiAgICAvLyBhc3NldF9uYW1lPSJbVk9URSBSRVNVTFRdICIgKyBzZWxmLnZvdGVfaWQsCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3MwogICAgLy8gc2VsZi52b3RlX2lkID0gdm90ZV9pZAogICAgYnl0ZSAidm90ZV9pZCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUwCiAgICAvLyBhc3NldF9uYW1lPSJbVk9URSBSRVNVTFRdICIgKyBzZWxmLnZvdGVfaWQsCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHZvdGVfaWQgZXhpc3RzCiAgICBieXRlICJbVk9URSBSRVNVTFRdICIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNTIKICAgIC8vIHVybD1zZWxmLm5mdF9pbWFnZV91cmwsCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3OQogICAgLy8gc2VsZi5uZnRfaW1hZ2VfdXJsID0gbmZ0X2ltYWdlX3VybAogICAgYnl0ZSAibmZ0X2ltYWdlX3VybCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUyCiAgICAvLyB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBuZnRfaW1hZ2VfdXJsIGV4aXN0cwogICAgdW5jb3ZlciAyCiAgICBpdHhuX2ZpZWxkIE5vdGUKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRVUkwKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUxCiAgICAvLyB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIGJ5dGUgIlZPVEVSU0xUIgogICAgaXR4bl9maWVsZCBDb25maWdBc3NldFVuaXROYW1lCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0TmFtZQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDkKICAgIC8vIGRlZmF1bHRfZnJvemVuPUZhbHNlLAogICAgaW50IDAKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXREZWZhdWx0RnJvemVuCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0OAogICAgLy8gZGVjaW1hbHM9MCwKICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0RGVjaW1hbHMKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ3CiAgICAvLyB0b3RhbD0xLAogICAgaW50IDEKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRUb3RhbAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDYKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICBpbnQgYWNmZwogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ2LTE1NgogICAgLy8gaXR4bi5Bc3NldENvbmZpZygKICAgIC8vICAgICB0b3RhbD0xLAogICAgLy8gICAgIGRlY2ltYWxzPTAsCiAgICAvLyAgICAgZGVmYXVsdF9mcm96ZW49RmFsc2UsCiAgICAvLyAgICAgYXNzZXRfbmFtZT0iW1ZPVEUgUkVTVUxUXSAiICsgc2VsZi52b3RlX2lkLAogICAgLy8gICAgIHVuaXRfbmFtZT0iVk9URVJTTFQiLAogICAgLy8gICAgIHVybD1zZWxmLm5mdF9pbWFnZV91cmwsCiAgICAvLyAgICAgbm90ZT1ub3RlLAogICAgLy8gICAgIGZlZT1HbG9iYWwubWluX3R4bl9mZWUsCiAgICAvLyApCiAgICAvLyAuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0NQogICAgLy8gc2VsZi5uZnRfYXNzZXRfaWQgPSAoCiAgICBieXRlICJuZnRfYXNzZXRfaWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0Ni0xNTcKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICAvLyAgICAgdG90YWw9MSwKICAgIC8vICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgIGRlZmF1bHRfZnJvemVuPUZhbHNlLAogICAgLy8gICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgLy8gICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gKQogICAgLy8gLnN1Ym1pdCgpCiAgICAvLyAuY3JlYXRlZF9hc3NldC5pZAogICAgaXR4biBDcmVhdGVkQXNzZXRJRAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDUtMTU4CiAgICAvLyBzZWxmLm5mdF9hc3NldF9pZCA9ICgKICAgIC8vICAgICBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgICAgICB0b3RhbD0xLAogICAgLy8gICAgICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgICAgICBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIC8vICAgICAgICAgYXNzZXRfbmFtZT0iW1ZPVEUgUkVTVUxUXSAiICsgc2VsZi52b3RlX2lkLAogICAgLy8gICAgICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICAgICAgdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIC8vICAgICAgICAgbm90ZT1ub3RlLAogICAgLy8gICAgICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gICAgICkKICAgIC8vICAgICAuc3VibWl0KCkKICAgIC8vICAgICAuY3JlYXRlZF9hc3NldC5pZAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIGFsZ29weS5lbnN1cmVfYnVkZ2V0KHJlcXVpcmVkX2J1ZGdldDogdWludDY0LCBmZWVfc291cmNlOiB1aW50NjQpIC0+IHZvaWQ6CmVuc3VyZV9idWRnZXQ6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MTEtMTcKICAgIHByb3RvIDIgMAogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjE4CiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAxMAogICAgKwoKZW5zdXJlX2J1ZGdldF93aGlsZV90b3BAMToKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToxOQogICAgZnJhbWVfZGlnIDAKICAgIGdsb2JhbCBPcGNvZGVCdWRnZXQKICAgID4KICAgIGJ6IGVuc3VyZV9idWRnZXRfYWZ0ZXJfd2hpbGVANwogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjIwCiAgICBpdHhuX2JlZ2luCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjEKICAgIGludCBhcHBsCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjIKICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgaXR4bl9maWVsZCBPbkNvbXBsZXRpb24KICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyMwogICAgYnl0ZSAweDA2ODEwMQogICAgaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyNAogICAgYnl0ZSAweDA2ODEwMQogICAgaXR4bl9maWVsZCBDbGVhclN0YXRlUHJvZ3JhbQogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjI1LTI5CiAgICBmcmFtZV9kaWcgLTEKICAgIHN3aXRjaCBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzBAMyBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzFANAogICAgYiBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANgoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8wQDM6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjcKICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgYiBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANgoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8xQDQ6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjkKICAgIGdsb2JhbCBNaW5UeG5GZWUKICAgIGl0eG5fZmllbGQgRmVlCgplbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANjoKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weTozMAogICAgaXR4bl9zdWJtaXQKICAgIGIgZW5zdXJlX2J1ZGdldF93aGlsZV90b3BAMQoKZW5zdXJlX2J1ZGdldF9hZnRlcl93aGlsZUA3OgogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5pdG9hKGk6IHVpbnQ2NCkgLT4gYnl0ZXM6Cml0b2E6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI0OS0yNTAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgaXRvYShpOiBVSW50NjQpIC0+IFN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTMKICAgIC8vIGlmIGkgPCByYWRpeDoKICAgIGZyYW1lX2RpZyAtMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTIKICAgIC8vIHJhZGl4ID0gZGlnaXRzLmxlbmd0aAogICAgaW50IDEwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MwogICAgLy8gaWYgaSA8IHJhZGl4OgogICAgPAogICAgYnogaXRvYV9hZnRlcl9pZl9lbHNlQDIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjU0CiAgICAvLyByZXR1cm4gU3RyaW5nLmZyb21fYnl0ZXMoZGlnaXRzW2ldKQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMQogICAgKwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTEKICAgIC8vIGRpZ2l0cyA9IEJ5dGVzKGIiMDEyMzQ1Njc4OSIpCiAgICBieXRlICIwMTIzNDU2Nzg5IgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTQKICAgIC8vIHJldHVybiBTdHJpbmcuZnJvbV9ieXRlcyhkaWdpdHNbaV0pCiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgcmV0c3ViCgppdG9hX2FmdGVyX2lmX2Vsc2VAMjoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjU1CiAgICAvLyByZXR1cm4gaXRvYShpIC8vIHJhZGl4KSArIFN0cmluZy5mcm9tX2J5dGVzKGRpZ2l0c1tpICUgcmFkaXhdKQogICAgZnJhbWVfZGlnIC0xCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MgogICAgLy8gcmFkaXggPSBkaWdpdHMubGVuZ3RoCiAgICBpbnQgMTAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjU1CiAgICAvLyByZXR1cm4gaXRvYShpIC8vIHJhZGl4KSArIFN0cmluZy5mcm9tX2J5dGVzKGRpZ2l0c1tpICUgcmFkaXhdKQogICAgLwogICAgY2FsbHN1YiBpdG9hCiAgICBmcmFtZV9kaWcgLTEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUyCiAgICAvLyByYWRpeCA9IGRpZ2l0cy5sZW5ndGgKICAgIGludCAxMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTUKICAgIC8vIHJldHVybiBpdG9hKGkgLy8gcmFkaXgpICsgU3RyaW5nLmZyb21fYnl0ZXMoZGlnaXRzW2kgJSByYWRpeF0pCiAgICAlCiAgICBkdXAKICAgIGludCAxCiAgICArCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MQogICAgLy8gZGlnaXRzID0gQnl0ZXMoYiIwMTIzNDU2Nzg5IikKICAgIGJ5dGUgIjAxMjM0NTY3ODkiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1NQogICAgLy8gcmV0dXJuIGl0b2EoaSAvLyByYWRpeCkgKyBTdHJpbmcuZnJvbV9ieXRlcyhkaWdpdHNbaSAlIHJhZGl4XSkKICAgIGNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5nZXRfdm90ZV9mcm9tX2JveChpbmRleDogdWludDY0KSAtPiB1aW50NjQ6CmdldF92b3RlX2Zyb21fYm94OgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMzktMjQwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGdldF92b3RlX2Zyb21fYm94KHNlbGYsIGluZGV4OiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1NQogICAgLy8gc2VsZi50YWxseV9ib3ggPSBCb3hSZWYoa2V5PSJWIikKICAgIGJ5dGUgIlYiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI0MQogICAgLy8gcmV0dXJuIG9wLmJ0b2koc2VsZi50YWxseV9ib3guZXh0cmFjdChpbmRleCwgVk9URV9DT1VOVF9CWVRFUykpCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCA4CiAgICBib3hfZXh0cmFjdAogICAgYnRvaQogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5nZXRfcHJlY29uZGl0aW9ucyhzaWduYXR1cmU6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X3ByZWNvbmRpdGlvbnM6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2MC0xNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgLy8gZGVmIGdldF9wcmVjb25kaXRpb25zKHNlbGYsIHNpZ25hdHVyZTogQnl0ZXMpIC0+IFZvdGluZ1ByZWNvbmRpdGlvbnM6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTYzCiAgICAvLyBpc192b3Rpbmdfb3Blbj1hcmM0LlVJbnQ2NChzZWxmLnZvdGluZ19vcGVuKCkpLAogICAgY2FsbHN1YiB2b3Rpbmdfb3BlbgogICAgaXRvYgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjQKICAgIC8vIGlzX2FsbG93ZWRfdG9fdm90ZT1hcmM0LlVJbnQ2NChzZWxmLmFsbG93ZWRfdG9fdm90ZShzaWduYXR1cmUpKSwKICAgIGZyYW1lX2RpZyAtMQogICAgY2FsbHN1YiBhbGxvd2VkX3RvX3ZvdGUKICAgIGl0b2IKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTY1CiAgICAvLyBoYXNfYWxyZWFkeV92b3RlZD1hcmM0LlVJbnQ2NChzZWxmLmFscmVhZHlfdm90ZWQoKSksCiAgICBjYWxsc3ViIGFscmVhZHlfdm90ZWQKICAgIGl0b2IKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTY2CiAgICAvLyBjdXJyZW50X3RpbWU9YXJjNC5VSW50NjQoR2xvYmFsLmxhdGVzdF90aW1lc3RhbXApLAogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgaXRvYgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjItMTY3CiAgICAvLyByZXR1cm4gVm90aW5nUHJlY29uZGl0aW9ucygKICAgIC8vICAgICBpc192b3Rpbmdfb3Blbj1hcmM0LlVJbnQ2NChzZWxmLnZvdGluZ19vcGVuKCkpLAogICAgLy8gICAgIGlzX2FsbG93ZWRfdG9fdm90ZT1hcmM0LlVJbnQ2NChzZWxmLmFsbG93ZWRfdG9fdm90ZShzaWduYXR1cmUpKSwKICAgIC8vICAgICBoYXNfYWxyZWFkeV92b3RlZD1hcmM0LlVJbnQ2NChzZWxmLmFscmVhZHlfdm90ZWQoKSksCiAgICAvLyAgICAgY3VycmVudF90aW1lPWFyYzQuVUludDY0KEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wKSwKICAgIC8vICkKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAudm90aW5nX29wZW4oKSAtPiB1aW50NjQ6CnZvdGluZ19vcGVuOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDUtMjA2CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHZvdGluZ19vcGVuKHNlbGYpIC0+IGJvb2w6CiAgICBwcm90byAwIDEKICAgIGJ5dGUgIiIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA4CiAgICAvLyBzZWxmLmlzX2Jvb3RzdHJhcHBlZAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTEKICAgIC8vIHNlbGYuaXNfYm9vdHN0cmFwcGVkID0gRmFsc2UKICAgIGJ5dGUgImlzX2Jvb3RzdHJhcHBlZCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA4CiAgICAvLyBzZWxmLmlzX2Jvb3RzdHJhcHBlZAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBpc19ib290c3RyYXBwZWQgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwOC0yMTAKICAgIC8vIHNlbGYuaXNfYm9vdHN0cmFwcGVkCiAgICAvLyBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgLy8gYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICBieiB2b3Rpbmdfb3Blbl9ib29sX2ZhbHNlQDUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA5CiAgICAvLyBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTQKICAgIC8vIHNlbGYuY2xvc2VfdGltZSA9IEdsb2JhbFN0YXRlKFVJbnQ2NCkKICAgIGJ5dGUgImNsb3NlX3RpbWUiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwOQogICAgLy8gYW5kIG5vdCBzZWxmLmNsb3NlX3RpbWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgIGJueiB2b3Rpbmdfb3Blbl9ib29sX2ZhbHNlQDUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjEwCiAgICAvLyBhbmQgc2VsZi5zdGFydF90aW1lIDw9IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wIDw9IHNlbGYuZW5kX3RpbWUKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc2CiAgICAvLyBzZWxmLnN0YXJ0X3RpbWUgPSBzdGFydF90aW1lCiAgICBieXRlICJzdGFydF90aW1lIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTAKICAgIC8vIGFuZCBzZWxmLnN0YXJ0X3RpbWUgPD0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPD0gc2VsZi5lbmRfdGltZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzdGFydF90aW1lIGV4aXN0cwogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgZHVwCiAgICBmcmFtZV9idXJ5IDAKICAgIDw9CiAgICBieiB2b3Rpbmdfb3Blbl9ib29sX2ZhbHNlQDUKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc3CiAgICAvLyBzZWxmLmVuZF90aW1lID0gZW5kX3RpbWUKICAgIGJ5dGUgImVuZF90aW1lIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTAKICAgIC8vIGFuZCBzZWxmLnN0YXJ0X3RpbWUgPD0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPD0gc2VsZi5lbmRfdGltZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBlbmRfdGltZSBleGlzdHMKICAgIGZyYW1lX2RpZyAwCiAgICA+PQogICAgYnogdm90aW5nX29wZW5fYm9vbF9mYWxzZUA1CiAgICBpbnQgMQogICAgYiB2b3Rpbmdfb3Blbl9ib29sX21lcmdlQDYKCnZvdGluZ19vcGVuX2Jvb2xfZmFsc2VANToKICAgIGludCAwCgp2b3Rpbmdfb3Blbl9ib29sX21lcmdlQDY6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwNy0yMTEKICAgIC8vIHJldHVybiAoCiAgICAvLyAgICAgc2VsZi5pc19ib290c3RyYXBwZWQKICAgIC8vICAgICBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgLy8gICAgIGFuZCBzZWxmLnN0YXJ0X3RpbWUgPD0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPD0gc2VsZi5lbmRfdGltZQogICAgLy8gKQogICAgc3dhcAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlOiBieXRlcykgLT4gdWludDY0OgphbGxvd2VkX3RvX3ZvdGU6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzMC0yMzEKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgYWxsb3dlZF90b192b3RlKHNlbGYsIHNpZ25hdHVyZTogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjMyCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDIwMDApCiAgICBpbnQgMjAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMzQKICAgIC8vIFR4bi5zZW5kZXIuYnl0ZXMsCiAgICB0eG4gU2VuZGVyCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzNgogICAgLy8gc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5LAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzQKICAgIC8vIHNlbGYuc25hcHNob3RfcHVibGljX2tleSA9IHNuYXBzaG90X3B1YmxpY19rZXkKICAgIGJ5dGUgInNuYXBzaG90X3B1YmxpY19rZXkiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzNgogICAgLy8gc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5LAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzbmFwc2hvdF9wdWJsaWNfa2V5IGV4aXN0cwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMzMtMjM3CiAgICAvLyByZXR1cm4gb3AuZWQyNTUxOXZlcmlmeV9iYXJlKAogICAgLy8gICAgIFR4bi5zZW5kZXIuYnl0ZXMsCiAgICAvLyAgICAgc2lnbmF0dXJlLAogICAgLy8gICAgIHNlbGYuc25hcHNob3RfcHVibGljX2tleSwKICAgIC8vICkKICAgIGZyYW1lX2RpZyAtMQogICAgc3dhcAogICAgZWQyNTUxOXZlcmlmeV9iYXJlCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmFscmVhZHlfdm90ZWQoKSAtPiB1aW50NjQ6CmFscmVhZHlfdm90ZWQ6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxMy0yMTQKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgYWxyZWFkeV92b3RlZChzZWxmKSAtPiBib29sOgogICAgcHJvdG8gMCAxCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxNQogICAgLy8gcmV0dXJuIFR4bi5zZW5kZXIgaW4gc2VsZi52b3Rlc19ieV9hY2NvdW50CiAgICB0eG4gU2VuZGVyCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU2LTIxNQogICAgLy8gICAgIHNlbGYudm90ZXNfYnlfYWNjb3VudCA9IEJveE1hcChBY2NvdW50LCBWb3RlSW5kZXhBcnJheSwga2V5X3ByZWZpeD0iIikKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICAvLyBkZWYgY3JlYXRlKAogICAgLy8gICAgIHNlbGYsCiAgICAvLyAgICAgdm90ZV9pZDogU3RyaW5nLAogICAgLy8gICAgIHNuYXBzaG90X3B1YmxpY19rZXk6IEJ5dGVzLAogICAgLy8gICAgIG1ldGFkYXRhX2lwZnNfY2lkOiBTdHJpbmcsCiAgICAvLyAgICAgc3RhcnRfdGltZTogVUludDY0LAogICAgLy8gICAgIGVuZF90aW1lOiBVSW50NjQsCiAgICAvLyAgICAgb3B0aW9uX2NvdW50czogVm90ZUluZGV4QXJyYXksCiAgICAvLyAgICAgcXVvcnVtOiBVSW50NjQsCiAgICAvLyAgICAgbmZ0X2ltYWdlX3VybDogU3RyaW5nLAogICAgLy8gKSAtPiBOb25lOgogICAgLy8gICAgIGFzc2VydCBzdGFydF90aW1lIDwgZW5kX3RpbWUsICJFbmQgdGltZSBzaG91bGQgYmUgYWZ0ZXIgc3RhcnQgdGltZSIKICAgIC8vICAgICBhc3NlcnQgZW5kX3RpbWUgPj0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAsICJFbmQgdGltZSBzaG91bGQgYmUgaW4gdGhlIGZ1dHVyZSIKICAgIC8vIAogICAgLy8gICAgIHNlbGYudm90ZV9pZCA9IHZvdGVfaWQKICAgIC8vICAgICBzZWxmLnNuYXBzaG90X3B1YmxpY19rZXkgPSBzbmFwc2hvdF9wdWJsaWNfa2V5CiAgICAvLyAgICAgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZCA9IG1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyAgICAgc2VsZi5zdGFydF90aW1lID0gc3RhcnRfdGltZQogICAgLy8gICAgIHNlbGYuZW5kX3RpbWUgPSBlbmRfdGltZQogICAgLy8gICAgIHNlbGYucXVvcnVtID0gcXVvcnVtCiAgICAvLyAgICAgc2VsZi5uZnRfaW1hZ2VfdXJsID0gbmZ0X2ltYWdlX3VybAogICAgLy8gICAgIHNlbGYuc3RvcmVfb3B0aW9uX2NvdW50cyhvcHRpb25fY291bnRzLmNvcHkoKSkKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm9vdHN0cmFwKHNlbGYsIGZ1bmRfbWluX2JhbF9yZXE6IGd0eG4uUGF5bWVudFRyYW5zYWN0aW9uKSAtPiBOb25lOgogICAgLy8gICAgIGFzc2VydCBub3Qgc2VsZi5pc19ib290c3RyYXBwZWQsICJNdXN0IG5vdCBiZSBhbHJlYWR5IGJvb3RzdHJhcHBlZCIKICAgIC8vICAgICBzZWxmLmlzX2Jvb3RzdHJhcHBlZCA9IFRydWUKICAgIC8vIAogICAgLy8gICAgIGFzc2VydCAoCiAgICAvLyAgICAgICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gICAgICksICJQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MiCiAgICAvLyAKICAgIC8vICAgICB0YWxseV9ib3hfc2l6ZSA9IHNlbGYudG90YWxfb3B0aW9ucyAqIFZPVEVfQ09VTlRfQllURVMKICAgIC8vICAgICBtaW5fYmFsYW5jZV9yZXEgPSAoCiAgICAvLyAgICAgICAgICMgbWluaW11bSBiYWxhbmNlIHJlcSBmb3I6IEFMR09zICsgVm90ZSByZXN1bHQgTkZUIGFzc2V0CiAgICAvLyAgICAgICAgIEFTU0VUX01JTl9CQUxBTkNFICogMgogICAgLy8gICAgICAgICAjIGNyZWF0ZSBORlQgZmVlCiAgICAvLyAgICAgICAgICsgMTAwMAogICAgLy8gICAgICAgICAjIHRhbGx5IGJveAogICAgLy8gICAgICAgICArIEJPWF9GTEFUX01JTl9CQUxBTkNFCiAgICAvLyAgICAgICAgICMgdGFsbHkgYm94IGtleSAiViIKICAgIC8vICAgICAgICAgKyBCT1hfQllURV9NSU5fQkFMQU5DRQogICAgLy8gICAgICAgICAjIHRhbGx5IGJveCB2YWx1ZQogICAgLy8gICAgICAgICArICh0YWxseV9ib3hfc2l6ZSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFKQogICAgLy8gICAgICkKICAgIC8vICAgICBsb2cobWluX2JhbGFuY2VfcmVxKQogICAgLy8gICAgIGFzc2VydCAoCiAgICAvLyAgICAgICAgIGZ1bmRfbWluX2JhbF9yZXEuYW1vdW50ID09IG1pbl9iYWxhbmNlX3JlcQogICAgLy8gICAgICksICJQYXltZW50IG11c3QgYmUgZm9yIHRoZSBleGFjdCBtaW4gYmFsYW5jZSByZXF1aXJlbWVudCIKICAgIC8vICAgICBhc3NlcnQgc2VsZi50YWxseV9ib3guY3JlYXRlKHNpemU9dGFsbHlfYm94X3NpemUpCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGNsb3NlKHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAgZW5zdXJlX2J1ZGdldCgyMDAwMCwgZmVlX3NvdXJjZT1PcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgLy8gICAgIGFzc2VydCBub3Qgc2VsZi5jbG9zZV90aW1lLCAiQWxyZWFkeSBjbG9zZWQiCiAgICAvLyAgICAgc2VsZi5jbG9zZV90aW1lLnZhbHVlID0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAKICAgIC8vIAogICAgLy8gICAgIG5vdGUgPSAoCiAgICAvLyAgICAgICAgICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICAgICAgICAgJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gICAgICAgICArIHNlbGYudm90ZV9pZAogICAgLy8gICAgICAgICArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyAgICAgICAgICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gICAgICAgICArICciLCJpZCI6IicKICAgIC8vICAgICAgICAgKyBzZWxmLnZvdGVfaWQKICAgIC8vICAgICAgICAgKyAnIiwicXVvcnVtIjonCiAgICAvLyAgICAgICAgICsgaXRvYShzZWxmLnF1b3J1bSkKICAgIC8vICAgICAgICAgKyAnLCJ2b3RlckNvdW50IjonCiAgICAvLyAgICAgICAgICsgaXRvYShzZWxmLnZvdGVyX2NvdW50KQogICAgLy8gICAgICAgICArICcsInRhbGxpZXMiOlsnCiAgICAvLyAgICAgKQogICAgLy8gCiAgICAvLyAgICAgY3VycmVudF9pbmRleCA9IFVJbnQ2NCgwKQogICAgLy8gICAgIGZvciBxdWVzdGlvbl9pbmRleCwgcXVlc3Rpb25fb3B0aW9ucyBpbiB1ZW51bWVyYXRlKHNlbGYub3B0aW9uX2NvdW50cyk6CiAgICAvLyAgICAgICAgIGlmIHF1ZXN0aW9uX2luZGV4ID4gMDoKICAgIC8vICAgICAgICAgICAgIG5vdGUgKz0gIiwiCiAgICAvLyAgICAgICAgIGlmIHF1ZXN0aW9uX29wdGlvbnMgPiAwOgogICAgLy8gICAgICAgICAgICAgbm90ZSArPSAiWyIKICAgIC8vICAgICAgICAgICAgIGZvciBvcHRpb25faW5kZXggaW4gdXJhbmdlKHF1ZXN0aW9uX29wdGlvbnMubmF0aXZlKToKICAgIC8vICAgICAgICAgICAgICAgICBpZiBvcHRpb25faW5kZXggPiAwOgogICAgLy8gICAgICAgICAgICAgICAgICAgICBub3RlICs9ICIsIgogICAgLy8gICAgICAgICAgICAgICAgIHZvdGVzX2Zvcl9vcHRpb24gPSBzZWxmLmdldF92b3RlX2Zyb21fYm94KGN1cnJlbnRfaW5kZXgpCiAgICAvLyAgICAgICAgICAgICAgICAgbm90ZSArPSBpdG9hKHZvdGVzX2Zvcl9vcHRpb24pCiAgICAvLyAgICAgICAgICAgICAgICAgY3VycmVudF9pbmRleCArPSAxCiAgICAvLyAgICAgICAgICAgICBub3RlICs9ICJdIgogICAgLy8gICAgIG5vdGUgKz0gIl19fSIKICAgIC8vICAgICBzZWxmLm5mdF9hc3NldF9pZCA9ICgKICAgIC8vICAgICAgICAgaXR4bi5Bc3NldENvbmZpZygKICAgIC8vICAgICAgICAgICAgIHRvdGFsPTEsCiAgICAvLyAgICAgICAgICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgICAgICAgICAgZGVmYXVsdF9mcm96ZW49RmFsc2UsCiAgICAvLyAgICAgICAgICAgICBhc3NldF9uYW1lPSJbVk9URSBSRVNVTFRdICIgKyBzZWxmLnZvdGVfaWQsCiAgICAvLyAgICAgICAgICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICAgICAgICAgIHVybD1zZWxmLm5mdF9pbWFnZV91cmwsCiAgICAvLyAgICAgICAgICAgICBub3RlPW5vdGUsCiAgICAvLyAgICAgICAgICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gICAgICAgICApCiAgICAvLyAgICAgICAgIC5zdWJtaXQoKQogICAgLy8gICAgICAgICAuY3JlYXRlZF9hc3NldC5pZAogICAgLy8gICAgICkKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICAvLyBkZWYgZ2V0X3ByZWNvbmRpdGlvbnMoc2VsZiwgc2lnbmF0dXJlOiBCeXRlcykgLT4gVm90aW5nUHJlY29uZGl0aW9uczoKICAgIC8vICAgICByZXR1cm4gVm90aW5nUHJlY29uZGl0aW9ucygKICAgIC8vICAgICAgICAgaXNfdm90aW5nX29wZW49YXJjNC5VSW50NjQoc2VsZi52b3Rpbmdfb3BlbigpKSwKICAgIC8vICAgICAgICAgaXNfYWxsb3dlZF90b192b3RlPWFyYzQuVUludDY0KHNlbGYuYWxsb3dlZF90b192b3RlKHNpZ25hdHVyZSkpLAogICAgLy8gICAgICAgICBoYXNfYWxyZWFkeV92b3RlZD1hcmM0LlVJbnQ2NChzZWxmLmFscmVhZHlfdm90ZWQoKSksCiAgICAvLyAgICAgICAgIGN1cnJlbnRfdGltZT1hcmM0LlVJbnQ2NChHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCksCiAgICAvLyAgICAgKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB2b3RlKAogICAgLy8gICAgIHNlbGYsCiAgICAvLyAgICAgZnVuZF9taW5fYmFsX3JlcTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24sCiAgICAvLyAgICAgc2lnbmF0dXJlOiBCeXRlcywKICAgIC8vICAgICBhbnN3ZXJfaWRzOiBWb3RlSW5kZXhBcnJheSwKICAgIC8vICkgLT4gTm9uZToKICAgIC8vICAgICBlbnN1cmVfYnVkZ2V0KDc3MDAsIGZlZV9zb3VyY2U9T3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIC8vICAgICAjIENoZWNrIHZvdGluZyBwcmVjb25kaXRpb25zCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYWxsb3dlZF90b192b3RlKHNpZ25hdHVyZSksICJOb3QgYWxsb3dlZCB0byB2b3RlIgogICAgLy8gICAgIGFzc2VydCBzZWxmLnZvdGluZ19vcGVuKCksICJWb3Rpbmcgbm90IG9wZW4iCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBzZWxmLmFscmVhZHlfdm90ZWQoKSwgIkFscmVhZHkgdm90ZWQiCiAgICAvLyAgICAgcXVlc3Rpb25zX2NvdW50ID0gc2VsZi5vcHRpb25fY291bnRzLmxlbmd0aAogICAgLy8gICAgIGFzc2VydCBhbnN3ZXJfaWRzLmxlbmd0aCA9PSBxdWVzdGlvbnNfY291bnQsICJOdW1iZXIgb2YgYW5zd2VycyBpbmNvcnJlY3QiCiAgICAvLyAgICAgIyBDaGVjayB2b3RlciBib3ggaXMgZnVuZGVkCiAgICAvLyAgICAgbWluX2JhbF9yZXEgPSBCT1hfRkxBVF9NSU5fQkFMQU5DRSArICgKICAgIC8vICAgICAgICAgKDMyICsgMiArIFZPVEVfSU5ERVhfQllURVMgKiBhbnN3ZXJfaWRzLmxlbmd0aCkgKiBCT1hfQllURV9NSU5fQkFMQU5DRQogICAgLy8gICAgICkKICAgIC8vICAgICBhc3NlcnQgKAogICAgLy8gICAgICAgICBmdW5kX21pbl9iYWxfcmVxLnJlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICAgICApLCAiUGF5bWVudCBtdXN0IGJlIHRvIGFwcCBhZGRyZXNzIgogICAgLy8gCiAgICAvLyAgICAgbG9nKG1pbl9iYWxfcmVxKQogICAgLy8gICAgIGFzc2VydCBmdW5kX21pbl9iYWxfcmVxLmFtb3VudCA9PSBtaW5fYmFsX3JlcSwgIlBheW1lbnQgbXVzdCBiZSB0aGUgZXhhY3QgbWluIGJhbGFuY2UiCiAgICAvLyAgICAgIyBSZWNvcmQgdGhlIHZvdGUgZm9yIGVhY2ggcXVlc3Rpb24KICAgIC8vICAgICBjdW11bGF0aXZlX29mZnNldCA9IFVJbnQ2NCgwKQogICAgLy8gICAgIGZvciBxdWVzdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25zX2NvdW50KToKICAgIC8vICAgICAgICAgIyBMb2FkIHRoZSB1c2VyJ3Mgdm90ZSBmb3IgdGhpcyBxdWVzdGlvbgogICAgLy8gICAgICAgICBhbnN3ZXJfb3B0aW9uX2luZGV4ID0gYW5zd2VyX2lkc1txdWVzdGlvbl9pbmRleF0ubmF0aXZlCiAgICAvLyAgICAgICAgIG9wdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHNbcXVlc3Rpb25faW5kZXhdLm5hdGl2ZQogICAgLy8gICAgICAgICBhc3NlcnQgYW5zd2VyX29wdGlvbl9pbmRleCA8IG9wdGlvbnNfY291bnQsICJBbnN3ZXIgb3B0aW9uIGluZGV4IGludmFsaWQiCiAgICAvLyAgICAgICAgIHNlbGYuaW5jcmVtZW50X3ZvdGVfaW5fYm94KGN1bXVsYXRpdmVfb2Zmc2V0ICsgYW5zd2VyX29wdGlvbl9pbmRleCkKICAgIC8vICAgICAgICAgY3VtdWxhdGl2ZV9vZmZzZXQgKz0gb3B0aW9uc19jb3VudAogICAgLy8gICAgICAgICBzZWxmLnZvdGVzX2J5X2FjY291bnRbVHhuLnNlbmRlcl0gPSBhbnN3ZXJfaWRzLmNvcHkoKQogICAgLy8gICAgICAgICBzZWxmLnZvdGVyX2NvdW50ICs9IDEKICAgIC8vIAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiB2b3Rpbmdfb3BlbihzZWxmKSAtPiBib29sOgogICAgLy8gICAgIHJldHVybiAoCiAgICAvLyAgICAgICAgIHNlbGYuaXNfYm9vdHN0cmFwcGVkCiAgICAvLyAgICAgICAgIGFuZCBub3Qgc2VsZi5jbG9zZV90aW1lCiAgICAvLyAgICAgICAgIGFuZCBzZWxmLnN0YXJ0X3RpbWUgPD0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPD0gc2VsZi5lbmRfdGltZQogICAgLy8gICAgICkKICAgIC8vIAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBhbHJlYWR5X3ZvdGVkKHNlbGYpIC0+IGJvb2w6CiAgICAvLyAgICAgcmV0dXJuIFR4bi5zZW5kZXIgaW4gc2VsZi52b3Rlc19ieV9hY2NvdW50CiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjE1CiAgICAvLyByZXR1cm4gVHhuLnNlbmRlciBpbiBzZWxmLnZvdGVzX2J5X2FjY291bnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAudm90ZShmdW5kX21pbl9iYWxfcmVxOiB1aW50NjQsIHNpZ25hdHVyZTogYnl0ZXMsIGFuc3dlcl9pZHM6IGJ5dGVzKSAtPiB2b2lkOgp2b3RlOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjktMTc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB2b3RlKAogICAgLy8gICAgIHNlbGYsCiAgICAvLyAgICAgZnVuZF9taW5fYmFsX3JlcTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24sCiAgICAvLyAgICAgc2lnbmF0dXJlOiBCeXRlcywKICAgIC8vICAgICBhbnN3ZXJfaWRzOiBWb3RlSW5kZXhBcnJheSwKICAgIC8vICkgLT4gTm9uZToKICAgIHByb3RvIDMgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNzYKICAgIC8vIGVuc3VyZV9idWRnZXQoNzcwMCwgZmVlX3NvdXJjZT1PcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDc3MDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTc3LTE3OAogICAgLy8gIyBDaGVjayB2b3RpbmcgcHJlY29uZGl0aW9ucwogICAgLy8gYXNzZXJ0IHNlbGYuYWxsb3dlZF90b192b3RlKHNpZ25hdHVyZSksICJOb3QgYWxsb3dlZCB0byB2b3RlIgogICAgZnJhbWVfZGlnIC0yCiAgICBjYWxsc3ViIGFsbG93ZWRfdG9fdm90ZQogICAgYXNzZXJ0IC8vIE5vdCBhbGxvd2VkIHRvIHZvdGUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTc5CiAgICAvLyBhc3NlcnQgc2VsZi52b3Rpbmdfb3BlbigpLCAiVm90aW5nIG5vdCBvcGVuIgogICAgY2FsbHN1YiB2b3Rpbmdfb3BlbgogICAgYXNzZXJ0IC8vIFZvdGluZyBub3Qgb3BlbgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODAKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5hbHJlYWR5X3ZvdGVkKCksICJBbHJlYWR5IHZvdGVkIgogICAgY2FsbHN1YiBhbHJlYWR5X3ZvdGVkCiAgICAhCiAgICBhc3NlcnQgLy8gQWxyZWFkeSB2b3RlZAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODEKICAgIC8vIHF1ZXN0aW9uc19jb3VudCA9IHNlbGYub3B0aW9uX2NvdW50cy5sZW5ndGgKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyNwogICAgLy8gc2VsZi5vcHRpb25fY291bnRzID0gb3B0aW9uX2NvdW50cy5jb3B5KCkKICAgIGJ5dGUgIm9wdGlvbl9jb3VudHMiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4MQogICAgLy8gcXVlc3Rpb25zX2NvdW50ID0gc2VsZi5vcHRpb25fY291bnRzLmxlbmd0aAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBvcHRpb25fY291bnRzIGV4aXN0cwogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkdXAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgyCiAgICAvLyBhc3NlcnQgYW5zd2VyX2lkcy5sZW5ndGggPT0gcXVlc3Rpb25zX2NvdW50LCAiTnVtYmVyIG9mIGFuc3dlcnMgaW5jb3JyZWN0IgogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGR1cAogICAgY292ZXIgMgogICAgZHVwCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gTnVtYmVyIG9mIGFuc3dlcnMgaW5jb3JyZWN0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4NQogICAgLy8gKDMyICsgMiArIFZPVEVfSU5ERVhfQllURVMgKiBhbnN3ZXJfaWRzLmxlbmd0aCkgKiBCT1hfQllURV9NSU5fQkFMQU5DRQogICAgaW50IDM0CiAgICArCiAgICBpbnQgNDAwCiAgICAqCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4My0xODQKICAgIC8vICMgQ2hlY2sgdm90ZXIgYm94IGlzIGZ1bmRlZAogICAgLy8gbWluX2JhbF9yZXEgPSBCT1hfRkxBVF9NSU5fQkFMQU5DRSArICgKICAgIGludCAyNTAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4My0xODYKICAgIC8vICMgQ2hlY2sgdm90ZXIgYm94IGlzIGZ1bmRlZAogICAgLy8gbWluX2JhbF9yZXEgPSBCT1hfRkxBVF9NSU5fQkFMQU5DRSArICgKICAgIC8vICAgICAoMzIgKyAyICsgVk9URV9JTkRFWF9CWVRFUyAqIGFuc3dlcl9pZHMubGVuZ3RoKSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICAvLyApCiAgICArCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4OAogICAgLy8gZnVuZF9taW5fYmFsX3JlcS5yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzCiAgICBmcmFtZV9kaWcgLTMKICAgIGd0eG5zIFJlY2VpdmVyCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgPT0KICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTg3LTE4OQogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBmdW5kX21pbl9iYWxfcmVxLnJlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICksICJQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MiCiAgICBhc3NlcnQgLy8gUGF5bWVudCBtdXN0IGJlIHRvIGFwcCBhZGRyZXNzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5MQogICAgLy8gbG9nKG1pbl9iYWxfcmVxKQogICAgZHVwCiAgICBpdG9iCiAgICBsb2cKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTkyCiAgICAvLyBhc3NlcnQgZnVuZF9taW5fYmFsX3JlcS5hbW91bnQgPT0gbWluX2JhbF9yZXEsICJQYXltZW50IG11c3QgYmUgdGhlIGV4YWN0IG1pbiBiYWxhbmNlIgogICAgZnJhbWVfZGlnIC0zCiAgICBndHhucyBBbW91bnQKICAgID09CiAgICBhc3NlcnQgLy8gUGF5bWVudCBtdXN0IGJlIHRoZSBleGFjdCBtaW4gYmFsYW5jZQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTMtMTk0CiAgICAvLyAjIFJlY29yZCB0aGUgdm90ZSBmb3IgZWFjaCBxdWVzdGlvbgogICAgLy8gY3VtdWxhdGl2ZV9vZmZzZXQgPSBVSW50NjQoMCkKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5NQogICAgLy8gZm9yIHF1ZXN0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbnNfY291bnQpOgogICAgZHVwCgp2b3RlX2Zvcl9oZWFkZXJAMToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTk1CiAgICAvLyBmb3IgcXVlc3Rpb25faW5kZXggaW4gdXJhbmdlKHF1ZXN0aW9uc19jb3VudCk6CiAgICBmcmFtZV9kaWcgMwogICAgZnJhbWVfZGlnIDAKICAgIDwKICAgIGJ6IHZvdGVfYWZ0ZXJfZm9yQDUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTk2LTE5NwogICAgLy8gIyBMb2FkIHRoZSB1c2VyJ3Mgdm90ZSBmb3IgdGhpcyBxdWVzdGlvbgogICAgLy8gYW5zd2VyX29wdGlvbl9pbmRleCA9IGFuc3dlcl9pZHNbcXVlc3Rpb25faW5kZXhdLm5hdGl2ZQogICAgZnJhbWVfZGlnIDMKICAgIGR1cAogICAgZnJhbWVfZGlnIDEKICAgIDwKICAgIGFzc2VydCAvLyBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgZGlnIDEKICAgIGludCAxCiAgICBleHRyYWN0MwogICAgYnRvaQogICAgc3dhcAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTgKICAgIC8vIG9wdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHNbcXVlc3Rpb25faW5kZXhdLm5hdGl2ZQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI3CiAgICAvLyBzZWxmLm9wdGlvbl9jb3VudHMgPSBvcHRpb25fY291bnRzLmNvcHkoKQogICAgYnl0ZSAib3B0aW9uX2NvdW50cyIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTk4CiAgICAvLyBvcHRpb25zX2NvdW50ID0gc2VsZi5vcHRpb25fY291bnRzW3F1ZXN0aW9uX2luZGV4XS5uYXRpdmUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgb3B0aW9uX2NvdW50cyBleGlzdHMKICAgIGR1cAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkaWcgMgogICAgPgogICAgYXNzZXJ0IC8vIEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBleHRyYWN0IDIgMAogICAgZGlnIDEKICAgIGludCAxCiAgICBleHRyYWN0MwogICAgYnRvaQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTkKICAgIC8vIGFzc2VydCBhbnN3ZXJfb3B0aW9uX2luZGV4IDwgb3B0aW9uc19jb3VudCwgIkFuc3dlciBvcHRpb24gaW5kZXggaW52YWxpZCIKICAgIGRpZyAyCiAgICBkaWcgMQogICAgPAogICAgYXNzZXJ0IC8vIEFuc3dlciBvcHRpb24gaW5kZXggaW52YWxpZAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDAKICAgIC8vIHNlbGYuaW5jcmVtZW50X3ZvdGVfaW5fYm94KGN1bXVsYXRpdmVfb2Zmc2V0ICsgYW5zd2VyX29wdGlvbl9pbmRleCkKICAgIGZyYW1lX2RpZyAyCiAgICBkdXAKICAgIHVuY292ZXIgNAogICAgKwogICAgY2FsbHN1YiBpbmNyZW1lbnRfdm90ZV9pbl9ib3gKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjAxCiAgICAvLyBjdW11bGF0aXZlX29mZnNldCArPSBvcHRpb25zX2NvdW50CiAgICArCiAgICBmcmFtZV9idXJ5IDIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjAyCiAgICAvLyBzZWxmLnZvdGVzX2J5X2FjY291bnRbVHhuLnNlbmRlcl0gPSBhbnN3ZXJfaWRzLmNvcHkoKQogICAgdHhuIFNlbmRlcgogICAgZHVwCiAgICBib3hfZGVsCiAgICBwb3AKICAgIGZyYW1lX2RpZyAtMQogICAgYm94X3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDMKICAgIC8vIHNlbGYudm90ZXJfY291bnQgKz0gMQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTItNTMKICAgIC8vICMgVGhlIG1pbmltdW0gbnVtYmVyIG9mIHZvdGVycyB3aG8gaGF2ZSB2b3RlZAogICAgLy8gc2VsZi52b3Rlcl9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidm90ZXJfY291bnQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMwogICAgLy8gc2VsZi52b3Rlcl9jb3VudCArPSAxCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHZvdGVyX2NvdW50IGV4aXN0cwogICAgaW50IDEKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTItNTMKICAgIC8vICMgVGhlIG1pbmltdW0gbnVtYmVyIG9mIHZvdGVycyB3aG8gaGF2ZSB2b3RlZAogICAgLy8gc2VsZi52b3Rlcl9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidm90ZXJfY291bnQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMwogICAgLy8gc2VsZi52b3Rlcl9jb3VudCArPSAxCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTUKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25zX2NvdW50KToKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDMKICAgIGIgdm90ZV9mb3JfaGVhZGVyQDEKCnZvdGVfYWZ0ZXJfZm9yQDU6CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmluY3JlbWVudF92b3RlX2luX2JveChpbmRleDogdWludDY0KSAtPiB2b2lkOgppbmNyZW1lbnRfdm90ZV9pbl9ib3g6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI0My0yNDQKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgaW5jcmVtZW50X3ZvdGVfaW5fYm94KHNlbGYsIGluZGV4OiBVSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQ1CiAgICAvLyBjdXJyZW50X3ZvdGUgPSBzZWxmLmdldF92b3RlX2Zyb21fYm94KGluZGV4KQogICAgZnJhbWVfZGlnIC0xCiAgICBjYWxsc3ViIGdldF92b3RlX2Zyb21fYm94CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI0NgogICAgLy8gc2VsZi50YWxseV9ib3gucmVwbGFjZShpbmRleCwgb3AuaXRvYihjdXJyZW50X3ZvdGUgKyAxKSkKICAgIGludCAxCiAgICArCiAgICBpdG9iCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU1CiAgICAvLyBzZWxmLnRhbGx5X2JveCA9IEJveFJlZihrZXk9IlYiKQogICAgYnl0ZSAiViIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQ2CiAgICAvLyBzZWxmLnRhbGx5X2JveC5yZXBsYWNlKGluZGV4LCBvcC5pdG9iKGN1cnJlbnRfdm90ZSArIDEpKQogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJveF9yZXBsYWNlCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUwCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1MQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBGYWxzZQogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUyLTUzCiAgICAvLyAjIFRoZSBtaW5pbXVtIG51bWJlciBvZiB2b3RlcnMgd2hvIGhhdmUgdm90ZWQKICAgIC8vIHNlbGYudm90ZXJfY291bnQgPSBVSW50NjQoMCkKICAgIGJ5dGUgInZvdGVyX2NvdW50IgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjQ5CiAgICAvLyBjbGFzcyBWb3RpbmdSb3VuZEFwcChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/examples/voting/out/VotingRoundApp.ssa.ir b/examples/voting/out/VotingRoundApp.ssa.ir index 4ca5f0c5b..a5b37d96d 100644 --- a/examples/voting/out/VotingRoundApp.ssa.ir +++ b/examples/voting/out/VotingRoundApp.ssa.ir @@ -467,8 +467,8 @@ contract examples.voting.voting.VotingRoundApp: subroutine examples.voting.voting.VotingRoundApp.already_voted() -> bool: block@0: // L213 let tmp%0#0: bytes = (txn Sender) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len compound_key%0#0) + let tmp%1#0: bytes = (concat "" tmp%0#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%1#0) return box_exists%0#0 subroutine examples.voting.voting.VotingRoundApp.vote(fund_min_bal_req: uint64, signature: bytes, answer_ids: bytes) -> void: @@ -535,9 +535,9 @@ contract examples.voting.voting.VotingRoundApp: let cumulative_offset#2: uint64 = (+ cumulative_offset#3 options_count#0) let copy%0#0: bytes = answer_ids#0 let tmp%20#0: bytes = (txn Sender) - let compound_key%0#0: bytes = (concat "" tmp%20#0) - let box_del_res%0#0: bool = (box_del compound_key%0#0) - (box_put compound_key%0#0 copy%0#0) + let tmp%21#0: bytes = (concat "" tmp%20#0) + let box_del_res%0#0: bool = (box_del tmp%21#0) + (box_put tmp%21#0 copy%0#0) let (voter_count_value%0#0: uint64, voter_count_exists%0#0: bool) = (app_global_get_ex 0u "voter_count") (assert voter_count_exists%0#0) // check voter_count exists let new_state_value%0#0: uint64 = (+ voter_count_value%0#0 1u) diff --git a/examples/voting/out/VotingRoundApp.ssa.opt_pass_1.ir b/examples/voting/out/VotingRoundApp.ssa.opt_pass_1.ir index 9cd6ff9d0..fb728b031 100644 --- a/examples/voting/out/VotingRoundApp.ssa.opt_pass_1.ir +++ b/examples/voting/out/VotingRoundApp.ssa.opt_pass_1.ir @@ -372,8 +372,8 @@ contract examples.voting.voting.VotingRoundApp: subroutine examples.voting.voting.VotingRoundApp.already_voted() -> bool: block@0: // L213 let tmp%0#0: bytes = (txn Sender) - let compound_key%0#0: bytes = tmp%0#0 - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len compound_key%0#0) + let tmp%1#0: bytes = tmp%0#0 + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%1#0) return box_exists%0#0 subroutine examples.voting.voting.VotingRoundApp.vote(fund_min_bal_req: uint64, signature: bytes, answer_ids: bytes) -> void: diff --git a/examples/voting/out/client_VotingRoundApp.py b/examples/voting/out/client_VotingRoundApp.py index 32bb23791..394fb0fe6 100644 --- a/examples/voting/out/client_VotingRoundApp.py +++ b/examples/voting/out/client_VotingRoundApp.py @@ -6,10 +6,10 @@ import algopy class VotingPreconditions(algopy.arc4.Struct): - is_voting_open: algopy.arc4.UInt64 - is_allowed_to_vote: algopy.arc4.UInt64 - has_already_voted: algopy.arc4.UInt64 - current_time: algopy.arc4.UInt64 + is_voting_open: algopy.arc4.UIntN[typing.Literal[64]] + is_allowed_to_vote: algopy.arc4.UIntN[typing.Literal[64]] + has_already_voted: algopy.arc4.UIntN[typing.Literal[64]] + current_time: algopy.arc4.UIntN[typing.Literal[64]] class VotingRoundApp(algopy.arc4.ARC4Client, typing.Protocol): @algopy.arc4.abimethod(create='require') @@ -18,10 +18,10 @@ def create( vote_id: algopy.arc4.String, snapshot_public_key: algopy.arc4.DynamicBytes, metadata_ipfs_cid: algopy.arc4.String, - start_time: algopy.arc4.UInt64, - end_time: algopy.arc4.UInt64, - option_counts: algopy.arc4.DynamicArray[algopy.arc4.UInt8], - quorum: algopy.arc4.UInt64, + start_time: algopy.arc4.UIntN[typing.Literal[64]], + end_time: algopy.arc4.UIntN[typing.Literal[64]], + option_counts: algopy.arc4.DynamicArray[algopy.arc4.UIntN[typing.Literal[8]]], + quorum: algopy.arc4.UIntN[typing.Literal[64]], nft_image_url: algopy.arc4.String, ) -> None: ... @@ -47,5 +47,5 @@ def vote( self, fund_min_bal_req: algopy.gtxn.PaymentTransaction, signature: algopy.arc4.DynamicBytes, - answer_ids: algopy.arc4.DynamicArray[algopy.arc4.UInt8], + answer_ids: algopy.arc4.DynamicArray[algopy.arc4.UIntN[typing.Literal[8]]], ) -> None: ... diff --git a/examples/voting/out/voting.awst b/examples/voting/out/voting.awst index 13dff59a3..8d29d7320 100644 --- a/examples/voting/out/voting.awst +++ b/examples/voting/out/voting.awst @@ -5,84 +5,84 @@ BOX_BYTE_MIN_BALANCE = 400 ASSET_MIN_BALANCE = 100000 struct VotingPreconditions { - is_voting_open: algopy.arc4.UInt64 - is_allowed_to_vote: algopy.arc4.UInt64 - has_already_voted: algopy.arc4.UInt64 - current_time: algopy.arc4.UInt64 + is_voting_open: arc4.uint64 + is_allowed_to_vote: arc4.uint64 + has_already_voted: arc4.uint64 + current_time: arc4.uint64 } contract VotingRoundApp { globals { ['is_bootstrapped']: bool - ['voter_count']: algopy.UInt64 - ['vote_id']: algopy.String - ['snapshot_public_key']: algopy.Bytes - ['metadata_ipfs_cid']: algopy.String - ['start_time']: algopy.UInt64 - ['end_time']: algopy.UInt64 - ['quorum']: algopy.UInt64 - ['nft_image_url']: algopy.String - ['nft_asset_id']: algopy.UInt64 - ['option_counts']: algopy.arc4.DynamicArray[algopy.arc4.UInt8] - ['total_options']: algopy.UInt64 - ['close_time']: algopy.UInt64 + ['voter_count']: uint64 + ['vote_id']: string + ['snapshot_public_key']: bytes + ['metadata_ipfs_cid']: string + ['start_time']: uint64 + ['end_time']: uint64 + ['quorum']: uint64 + ['nft_image_url']: string + ['nft_asset_id']: uint64 + ['option_counts']: arc4.dynamic_array + ['total_options']: uint64 + ['close_time']: uint64 } boxes { - ['V']: algopy.Bytes - ['']: algopy.Account => algopy.arc4.DynamicArray[algopy.arc4.UInt8] + ['V']: bytes + ['']: account => arc4.dynamic_array } constructor() { this.is_bootstrapped: bool = false - this.voter_count: algopy.UInt64 = 0u + this.voter_count: uint64 = 0u } - abimethod create(vote_id: algopy.String, snapshot_public_key: algopy.Bytes, metadata_ipfs_cid: algopy.String, start_time: algopy.UInt64, end_time: algopy.UInt64, option_counts: algopy.arc4.DynamicArray[algopy.arc4.UInt8], quorum: algopy.UInt64, nft_image_url: algopy.String): None + abimethod create(vote_id: string, snapshot_public_key: bytes, metadata_ipfs_cid: string, start_time: uint64, end_time: uint64, option_counts: arc4.dynamic_array, quorum: uint64, nft_image_url: string): void { assert(start_time < end_time, comment="End time should be after start time") assert(end_time >= global(), comment="End time should be in the future") - this.vote_id: algopy.String = vote_id - this.snapshot_public_key: algopy.Bytes = snapshot_public_key - this.metadata_ipfs_cid: algopy.String = metadata_ipfs_cid - this.start_time: algopy.UInt64 = start_time - this.end_time: algopy.UInt64 = end_time - this.quorum: algopy.UInt64 = quorum - this.nft_image_url: algopy.String = nft_image_url + this.vote_id: string = vote_id + this.snapshot_public_key: bytes = snapshot_public_key + this.metadata_ipfs_cid: string = metadata_ipfs_cid + this.start_time: uint64 = start_time + this.end_time: uint64 = end_time + this.quorum: uint64 = quorum + this.nft_image_url: string = nft_image_url this::store_option_counts(option_counts.copy()) } - abimethod bootstrap(fund_min_bal_req: algopy.gtxn.PaymentTransaction): None + abimethod bootstrap(fund_min_bal_req: group_transaction_pay): void { assert(!(this.is_bootstrapped), comment="Must not be already bootstrapped") this.is_bootstrapped: bool = true assert(gtxns(fund_min_bal_req) == global(), comment="Payment must be to app address") - tally_box_size: algopy.UInt64 = this.total_options * 8u - min_balance_req: algopy.UInt64 = 203900u + tally_box_size * 400u + tally_box_size: uint64 = this.total_options * 8u + min_balance_req: uint64 = 203900u + tally_box_size * 400u log(itob(min_balance_req)) assert(gtxns(fund_min_bal_req) == min_balance_req, comment="Payment must be for the exact min balance requirement") - assert(box_create(this.tally_box, tally_box_size)) + assert(box_create('V', tally_box_size)) } - abimethod close(): None + abimethod close(): void { algopy::ensure_budget(required_budget=20000u, fee_source=0u) assert(!(STATE_EXISTS(this.close_time)), comment="Already closed") - this.close_time: algopy.UInt64 = global() - note: algopy.String = '{"standard":"arc69","description":"This is a voting result NFT for voting round with ID ' + this.vote_id + '.","properties":{"metadata":"ipfs://' + this.metadata_ipfs_cid + '","id":"' + this.vote_id + '","quorum":' + examples.voting.voting::itoa(this.quorum) + ',"voterCount":' + examples.voting.voting::itoa(this.voter_count) + ',"tallies":[' - current_index: algopy.UInt64 = 0u + this.close_time: uint64 = global() + note: string = '{"standard":"arc69","description":"This is a voting result NFT for voting round with ID ' + this.vote_id + '.","properties":{"metadata":"ipfs://' + this.metadata_ipfs_cid + '","id":"' + this.vote_id + '","quorum":' + examples.voting.voting::itoa(this.quorum) + ',"voterCount":' + examples.voting.voting::itoa(this.voter_count) + ',"tallies":[' + current_index: uint64 = 0u for (question_index, question_options) in enumerate(this.option_counts) { if (question_index > 0u) { note += ',' } - if (reinterpret_cast(question_options) > reinterpret_cast(0arc4u8)) { + if (reinterpret_cast(question_options) > reinterpret_cast(0arc4u8)) { note += '[' - for option_index in range(0u, arc4_decode(question_options, algopy.UInt64), 1u) { + for option_index in range(0u, arc4_decode(question_options, uint64), 1u) { if (option_index > 0u) { note += ',' } - votes_for_option: algopy.UInt64 = this::get_vote_from_box(current_index) + votes_for_option: uint64 = this::get_vote_from_box(current_index) note += examples.voting.voting::itoa(votes_for_option) current_index += 1u } @@ -90,34 +90,34 @@ contract VotingRoundApp } } note += ']}}' - this.nft_asset_id: algopy.UInt64 = reinterpret_cast(submit_txn(create_inner_transaction(Fee=global(), TypeEnum=acfg, ConfigAssetTotal=1u, ConfigAssetDecimals=0u, ConfigAssetDefaultFrozen=false, ConfigAssetName='[VOTE RESULT] ' + this.vote_id, ConfigAssetUnitName='VOTERSLT', ConfigAssetURL=this.nft_image_url, Note=note)).CreatedAssetID) + this.nft_asset_id: uint64 = reinterpret_cast(submit_txn(create_inner_transaction(Fee=global(), TypeEnum=acfg, ConfigAssetTotal=1u, ConfigAssetDecimals=0u, ConfigAssetDefaultFrozen=false, ConfigAssetName='[VOTE RESULT] ' + this.vote_id, ConfigAssetUnitName='VOTERSLT', ConfigAssetURL=this.nft_image_url, Note=note)).CreatedAssetID) } - abimethod get_preconditions(signature: algopy.Bytes): examples.voting.voting.VotingPreconditions + abimethod get_preconditions(signature: bytes): arc4.struct { - return new examples.voting.voting.VotingPreconditions(is_voting_open=arc4_encode(this::voting_open(), algopy.arc4.UInt64), is_allowed_to_vote=arc4_encode(this::allowed_to_vote(signature), algopy.arc4.UInt64), has_already_voted=arc4_encode(this::already_voted(), algopy.arc4.UInt64), current_time=arc4_encode(global(), algopy.arc4.UInt64)) + return new arc4.struct(is_voting_open=arc4_encode(this::voting_open(), arc4.uint64), is_allowed_to_vote=arc4_encode(this::allowed_to_vote(signature), arc4.uint64), has_already_voted=arc4_encode(this::already_voted(), arc4.uint64), current_time=arc4_encode(global(), arc4.uint64)) } - abimethod vote(fund_min_bal_req: algopy.gtxn.PaymentTransaction, signature: algopy.Bytes, answer_ids: algopy.arc4.DynamicArray[algopy.arc4.UInt8]): None + abimethod vote(fund_min_bal_req: group_transaction_pay, signature: bytes, answer_ids: arc4.dynamic_array): void { algopy::ensure_budget(required_budget=7700u, fee_source=0u) assert(this::allowed_to_vote(signature), comment="Not allowed to vote") assert(this::voting_open(), comment="Voting not open") assert(!(this::already_voted()), comment="Already voted") - questions_count: algopy.UInt64 = extract_uint16(this.option_counts, 0u) + questions_count: uint64 = extract_uint16(this.option_counts, 0u) assert(extract_uint16(answer_ids, 0u) == questions_count, comment="Number of answers incorrect") - min_bal_req: algopy.UInt64 = 2500u + 34u + 1u * extract_uint16(answer_ids, 0u) * 400u + min_bal_req: uint64 = 2500u + 34u + 1u * extract_uint16(answer_ids, 0u) * 400u assert(gtxns(fund_min_bal_req) == global(), comment="Payment must be to app address") log(itob(min_bal_req)) assert(gtxns(fund_min_bal_req) == min_bal_req, comment="Payment must be the exact min balance") - cumulative_offset: algopy.UInt64 = 0u + cumulative_offset: uint64 = 0u for question_index in range(0u, questions_count, 1u) { - answer_option_index: algopy.UInt64 = arc4_decode(answer_ids[question_index], algopy.UInt64) - options_count: algopy.UInt64 = arc4_decode(this.option_counts[question_index], algopy.UInt64) + answer_option_index: uint64 = arc4_decode(answer_ids[question_index], uint64) + options_count: uint64 = arc4_decode(this.option_counts[question_index], uint64) assert(answer_option_index < options_count, comment="Answer option index invalid") this::increment_vote_in_box(cumulative_offset + answer_option_index) cumulative_offset += options_count - this.votes_by_account.value: algopy.arc4.DynamicArray[algopy.arc4.UInt8] = answer_ids.copy() + Box[concat('', BytesRaw(txn()))]: arc4.dynamic_array = answer_ids.copy() this.voter_count += 1u } } @@ -129,46 +129,46 @@ contract VotingRoundApp subroutine already_voted(): bool { - return STATE_EXISTS(this.votes_by_account.key) + return STATE_EXISTS(Box[concat('', BytesRaw(txn()))]) } - subroutine store_option_counts(option_counts: algopy.arc4.DynamicArray[algopy.arc4.UInt8]): None + subroutine store_option_counts(option_counts: arc4.dynamic_array): void { assert(reinterpret_cast(extract_uint16(option_counts, 0u)), comment="option_counts should be non-empty") assert(extract_uint16(option_counts, 0u) <= 112u, comment="Can't have more than 112 questions") - total_options: algopy.UInt64 = 0u + total_options: uint64 = 0u for item in option_counts { - total_options += arc4_decode(item, algopy.UInt64) + total_options += arc4_decode(item, uint64) } assert(total_options <= 128u, comment="Can't have more than 128 vote options") - this.option_counts: algopy.arc4.DynamicArray[algopy.arc4.UInt8] = option_counts.copy() - this.total_options: algopy.UInt64 = total_options + this.option_counts: arc4.dynamic_array = option_counts.copy() + this.total_options: uint64 = total_options } - subroutine allowed_to_vote(signature: algopy.Bytes): bool + subroutine allowed_to_vote(signature: bytes): bool { algopy::ensure_budget(required_budget=2000u, fee_source=0u) - return ed25519verify_bare(reinterpret_cast(txn()), signature, this.snapshot_public_key) + return ed25519verify_bare(reinterpret_cast(txn()), signature, this.snapshot_public_key) } - subroutine get_vote_from_box(index: algopy.UInt64): algopy.UInt64 + subroutine get_vote_from_box(index: uint64): uint64 { - return btoi(box_extract(this.tally_box, index, 8u)) + return btoi(box_extract('V', index, 8u)) } - subroutine increment_vote_in_box(index: algopy.UInt64): None + subroutine increment_vote_in_box(index: uint64): void { - current_vote: algopy.UInt64 = this::get_vote_from_box(index) - box_replace(this.tally_box, index, itob(current_vote + 1u)) + current_vote: uint64 = this::get_vote_from_box(index) + box_replace('V', index, itob(current_vote + 1u)) } } -subroutine itoa(i: algopy.UInt64): algopy.String +subroutine itoa(i: uint64): string { - digits: algopy.Bytes = '0123456789' - radix: algopy.UInt64 = len(digits) + digits: bytes = '0123456789' + radix: uint64 = len(digits) if (i < radix) { - return reinterpret_cast(digits[i]) + return reinterpret_cast(digits[i]) } - return examples.voting.voting::itoa(i // radix) + reinterpret_cast(digits[i % radix]) + return examples.voting.voting::itoa(i // radix) + reinterpret_cast(digits[i % radix]) } \ No newline at end of file diff --git a/examples/voting/out_unoptimized/VotingRoundApp.approval.teal b/examples/voting/out_unoptimized/VotingRoundApp.approval.teal index 633dfff5a..a4b6e95f3 100644 --- a/examples/voting/out_unoptimized/VotingRoundApp.approval.teal +++ b/examples/voting/out_unoptimized/VotingRoundApp.approval.teal @@ -419,7 +419,7 @@ bootstrap: // ), "Payment must be for the exact min balance requirement" assert // Payment must be for the exact min balance requirement // voting/voting.py:55 - // self.tally_box = BoxRef(key=b"V") + // self.tally_box = BoxRef(key="V") byte "V" // voting/voting.py:108 // assert self.tally_box.create(size=tally_box_size) @@ -1041,7 +1041,7 @@ get_vote_from_box: // def get_vote_from_box(self, index: UInt64) -> UInt64: proto 1 1 // voting/voting.py:55 - // self.tally_box = BoxRef(key=b"V") + // self.tally_box = BoxRef(key="V") byte "V" // voting/voting.py:241 // return op.btoi(self.tally_box.extract(index, VOTE_COUNT_BYTES)) @@ -1219,10 +1219,10 @@ already_voted: // return Txn.sender in self.votes_by_account txn Sender // voting/voting.py:56 - // self.votes_by_account = BoxMap(Account, VoteIndexArray) + // self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") byte "" // voting/voting.py:56-215 - // self.votes_by_account = BoxMap(Account, VoteIndexArray) + // self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") // // @arc4.abimethod(create="require") // def create( @@ -1576,7 +1576,7 @@ vote_for_header@1: frame_dig -1 txn Sender // voting/voting.py:56 - // self.votes_by_account = BoxMap(Account, VoteIndexArray) + // self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") byte "" // voting/voting.py:202 // self.votes_by_account[Txn.sender] = answer_ids.copy() @@ -1636,7 +1636,7 @@ increment_vote_in_box: + itob // voting/voting.py:55 - // self.tally_box = BoxRef(key=b"V") + // self.tally_box = BoxRef(key="V") byte "V" // voting/voting.py:246 // self.tally_box.replace(index, op.itob(current_vote + 1)) diff --git a/examples/voting/out_unoptimized/VotingRoundApp.destructured.ir b/examples/voting/out_unoptimized/VotingRoundApp.destructured.ir index 824551df5..03182c3cf 100644 --- a/examples/voting/out_unoptimized/VotingRoundApp.destructured.ir +++ b/examples/voting/out_unoptimized/VotingRoundApp.destructured.ir @@ -404,8 +404,8 @@ contract examples.voting.voting.VotingRoundApp: subroutine examples.voting.voting.VotingRoundApp.already_voted() -> bool: block@0: // L213 let tmp%0#0: bytes = (txn Sender) - let compound_key%0#0: bytes = (concat "" tmp%0#0) - let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len compound_key%0#0) + let tmp%1#0: bytes = (concat "" tmp%0#0) + let (box_len%0#0: uint64, box_exists%0#0: bool) = (box_len tmp%1#0) return box_exists%0#0 subroutine examples.voting.voting.VotingRoundApp.vote(fund_min_bal_req: uint64, signature: bytes, answer_ids: bytes) -> void: @@ -470,9 +470,9 @@ contract examples.voting.voting.VotingRoundApp: let cumulative_offset#0: uint64 = (+ cumulative_offset#0 options_count#0) let copy%0#0: bytes = answer_ids#0 let tmp%20#0: bytes = (txn Sender) - let compound_key%0#0: bytes = (concat "" tmp%20#0) - let box_del_res%0#0: bool = (box_del compound_key%0#0) - (box_put compound_key%0#0 copy%0#0) + let tmp%21#0: bytes = (concat "" tmp%20#0) + let box_del_res%0#0: bool = (box_del tmp%21#0) + (box_put tmp%21#0 copy%0#0) let (voter_count_value%0#0: uint64, voter_count_exists%0#0: bool) = (app_global_get_ex 0u "voter_count") (assert voter_count_exists%0#0) // check voter_count exists let new_state_value%0#0: uint64 = (+ voter_count_value%0#0 1u) diff --git a/examples/voting/puya.log b/examples/voting/puya.log index 955c1f3d0..9c95227b2 100644 --- a/examples/voting/puya.log +++ b/examples/voting/puya.log @@ -840,7 +840,7 @@ debug: Simplified (* question_index#0 1u) to question_index#0 debug: Simplified (* question_index#0 1u) to question_index#0 debug: Simplified (concat "" tmp%20#0) to tmp%20#0 debug: Optimizer: Remove Unused Variables -debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del compound_key%0#0) +debug: Not removing unused assignment since source is not marked as pure: let box_del_res%0#0: bool = (box_del tmp%21#0) debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump @@ -857,8 +857,8 @@ debug: Found equivalence set: tmp%4#0, tmp%6#0, tmp%7#0, array_length%0#0 debug: Replacing {tmp%6#0, tmp%7#0, array_length%0#0} with tmp%4#0 made 2 modifications debug: Found equivalence set: question_index#0, item_index%0#0, item_index%1#0 debug: Replacing {item_index%0#0, item_index%1#0} with question_index#0 made 2 modifications -debug: Found equivalence set: tmp%20#0, compound_key%0#0 -debug: Replacing {compound_key%0#0} with tmp%20#0 made 2 modifications +debug: Found equivalence set: tmp%20#0, tmp%21#0 +debug: Replacing {tmp%21#0} with tmp%20#0 made 2 modifications debug: Optimizing subroutine examples.voting.voting.VotingRoundApp.increment_vote_in_box debug: Splitting parallel copies prior to optimization debug: Optimizer: Constant Replacer @@ -1027,8 +1027,8 @@ debug: Optimizer: Repeated Expression Elimination debug: Optimizing subroutine examples.voting.voting.VotingRoundApp.already_voted debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation -debug: Found equivalence set: tmp%0#0, compound_key%0#0 -debug: Replacing {compound_key%0#0} with tmp%0#0 made 1 modifications +debug: Found equivalence set: tmp%0#0, tmp%1#0 +debug: Replacing {tmp%1#0} with tmp%0#0 made 1 modifications debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables debug: Optimizer: Inner Txn Field Replacer diff --git a/examples/voting/voting.py b/examples/voting/voting.py index 5c0b41a9d..fa3dcef07 100644 --- a/examples/voting/voting.py +++ b/examples/voting/voting.py @@ -52,8 +52,8 @@ def __init__(self) -> None: # The minimum number of voters who have voted self.voter_count = UInt64(0) self.close_time = GlobalState(UInt64) - self.tally_box = BoxRef(key=b"V") - self.votes_by_account = BoxMap(Account, VoteIndexArray) + self.tally_box = BoxRef(key="V") + self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") @arc4.abimethod(create="require") def create( diff --git a/pyproject.toml b/pyproject.toml index 0bdd19a45..8bbb7c66c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -214,6 +214,7 @@ ignore = [ "RET503", # false negatives when involving typing.Never, covered by mypy anyway "RET504", "RET505", # stylistic choices for readability "S101", # allow asserts + "TCH001", "TCH002", # don't require things to be in a type checking block # TODO: REMOVE ALL THE BELOW AFTER REFACTORING BUILDING CODE vvv "C901", # is too complex (> 10) "PLR0911", # Too many return statements (> 6) diff --git a/src/puya/arc32.py b/src/puya/arc32.py index 3b1907b67..c07ada3be 100644 --- a/src/puya/arc32.py +++ b/src/puya/arc32.py @@ -7,7 +7,7 @@ from pathlib import Path from puya import log -from puya.arc4_util import arc4_to_wtype +from puya.arc4_util import arc4_to_pytype from puya.awst_build import constants from puya.errors import InternalError from puya.models import ( @@ -297,7 +297,7 @@ def _abi_arg(arg: ARC4MethodArg, struct: ARC32StructDef | None) -> str: def _arc4_type_to_algopy_cls(typ: str) -> str: - return arc4_to_wtype(typ).stub_name + return str(arc4_to_pytype(typ)) def _arc4_method_to_decorator(method: ARC4Method) -> str: diff --git a/src/puya/awst/function_traverser.py b/src/puya/awst/function_traverser.py index 4b0d07843..37d68e901 100644 --- a/src/puya/awst/function_traverser.py +++ b/src/puya/awst/function_traverser.py @@ -140,11 +140,12 @@ def visit_single_evaluation(self, expr: awst_nodes.SingleEvaluation) -> None: expr.source.accept(self) def visit_app_state_expression(self, expr: awst_nodes.AppStateExpression) -> None: - pass + expr.key.accept(self) def visit_app_account_state_expression( self, expr: awst_nodes.AppAccountStateExpression ) -> None: + expr.key.accept(self) expr.account.accept(self) def visit_new_array(self, expr: awst_nodes.NewArray) -> None: @@ -281,20 +282,8 @@ def visit_state_get(self, expr: awst_nodes.StateGet) -> None: def visit_state_exists(self, expr: awst_nodes.StateExists) -> None: expr.field.accept(self) - def visit_box_length(self, expr: awst_nodes.BoxLength) -> None: - expr.box_key.accept(self) - - def visit_box_proxy_expression(self, expr: awst_nodes.BoxProxyExpression) -> None: - expr.key.accept(self) - def visit_box_value_expression(self, expr: awst_nodes.BoxValueExpression) -> None: - expr.proxy.accept(self) - - def visit_box_proxy_field(self, expr: awst_nodes.BoxProxyField) -> None: - pass - - def visit_box_key_expression(self, expr: awst_nodes.BoxKeyExpression) -> None: - expr.proxy.accept(self) + expr.key.accept(self) def visit_bytes_raw(self, expr: awst_nodes.BytesRaw) -> None: expr.expr.accept(self) diff --git a/src/puya/awst/nodes.py b/src/puya/awst/nodes.py index ca6b13ab0..d5e85f219 100644 --- a/src/puya/awst/nodes.py +++ b/src/puya/awst/nodes.py @@ -162,7 +162,7 @@ def wtype_is_one_of(*one_of_these: WType | type[WType]) -> _WTypeIsOneOf: @attrs.frozen -class Literal(Node): +class Literal(Node): # TODO: yeet me """These shouldn't appear in the final AWST. They are temporarily constructed during evaluation of sub-expressions, when we encounter @@ -947,7 +947,7 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: @attrs.frozen class AppStateExpression(Expression): key: Expression = attrs.field(validator=wtype_is_bytes) - field_name: str | None + member_name: str | None def accept(self, visitor: ExpressionVisitor[T]) -> T: return visitor.visit_app_state_expression(self) @@ -956,15 +956,24 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: @attrs.frozen class AppAccountStateExpression(Expression): key: Expression = attrs.field(validator=wtype_is_bytes) + member_name: str | None account: Expression = attrs.field( validator=[expression_has_wtype(wtypes.account_wtype, wtypes.uint64_wtype)] ) - field_name: str | None def accept(self, visitor: ExpressionVisitor[T]) -> T: return visitor.visit_app_account_state_expression(self) +@attrs.frozen +class BoxValueExpression(Expression): + key: Expression = attrs.field(validator=wtype_is_bytes) + member_name: str | None + + def accept(self, visitor: ExpressionVisitor[T]) -> T: + return visitor.visit_box_value_expression(self) + + @attrs.frozen(init=False, eq=False, hash=False) # use identity equality class SingleEvaluation(Expression): """caveat emptor""" @@ -1000,6 +1009,13 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: return visitor.visit_reinterpret_cast(self) +StorageExpression = AppStateExpression | AppAccountStateExpression | BoxValueExpression +# Expression types that are valid on the left hand side of assignment *statements* +# Note that some of these can be recursive/nested, eg: +# obj.field[index].another_field = 123 +Lvalue = VarExpression | FieldExpression | IndexExpression | TupleExpression | StorageExpression + + @attrs.frozen class NewArray(Expression): wtype: wtypes.WArray | wtypes.ARC4Array @@ -1054,8 +1070,7 @@ class AssignmentStatement(Statement): def __attrs_post_init__(self) -> None: if self.value.wtype != self.target.wtype: raise CodeError( - f"Assignment target type {self.target.wtype}" - f" differs from expression value type {self.value.wtype}", + "assignment target type differs from expression value type", self.source_location, ) if self.value.wtype == wtypes.void_wtype: @@ -1082,13 +1097,12 @@ class AssignmentExpression(Expression): def __init__(self, value: Expression, target: Lvalue, source_location: SourceLocation): if isinstance(target, TupleExpression): raise CodeError( - "Tuple unpacking in assignment expressions is not supported", + "tuple unpacking in assignment expressions is not supported", target.source_location, ) if value.wtype != target.wtype: raise CodeError( - f"Assignment target type {target.wtype}" - f" differs from expression value type {value.wtype}", + "assignment target type differs from expression value type", source_location, ) if value.wtype == wtypes.void_wtype: @@ -1510,26 +1524,6 @@ def accept(self, visitor: StatementVisitor[T]) -> T: return visitor.visit_for_in_loop(self) -StateExpression: t.TypeAlias = "AppStateExpression | AppAccountStateExpression | BoxKeyExpression" - - -def _get_state_expression_value_wtype(expr: StateExpression) -> wtypes.WType: - match expr: - case AppStateExpression(wtype=content_wtype): - return content_wtype - case AppAccountStateExpression(wtype=content_wtype): - return content_wtype - case BoxKeyExpression(proxy=proxy): - match proxy.wtype: - case wtypes.box_ref_proxy_type: - return wtypes.bytes_wtype - case wtypes.WBoxProxy(content_wtype=content_wtype): - return content_wtype - case wtypes.WBoxMapProxy(content_wtype=content_wtype): - return content_wtype - raise InternalError("Unexpected type of StateExpression") - - @attrs.frozen class StateGet(Expression): """ @@ -1537,21 +1531,20 @@ class StateGet(Expression): can just use the underlying StateExpression """ - field: StateExpression + field: StorageExpression default: Expression = attrs.field() wtype: WType = attrs.field(init=False) @default.validator def _check_default(self, _attribute: object, default: Expression) -> None: - content_wtype = _get_state_expression_value_wtype(self.field) - if content_wtype != default.wtype: + if self.field.wtype != default.wtype: raise CodeError( "Default state value should match storage type", default.source_location ) @wtype.default def _wtype_factory(self) -> WType: - return _get_state_expression_value_wtype(self.field) + return self.field.wtype def accept(self, visitor: ExpressionVisitor[T]) -> T: return visitor.visit_state_get(self) @@ -1559,13 +1552,13 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: @attrs.frozen class StateGetEx(Expression): - field: StateExpression + field: StorageExpression wtype: wtypes.WTuple = attrs.field(init=False) @wtype.default def _wtype_factory(self) -> wtypes.WTuple: return wtypes.WTuple( - (_get_state_expression_value_wtype(self.field), wtypes.bool_wtype), + (self.field.wtype, wtypes.bool_wtype), self.source_location, ) @@ -1575,7 +1568,7 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: @attrs.frozen class StateExists(Expression): - field: StateExpression + field: StorageExpression wtype: WType = attrs.field(default=wtypes.bool_wtype, init=False) def accept(self, visitor: ExpressionVisitor[T]) -> T: @@ -1584,7 +1577,7 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: @attrs.frozen class StateDelete(Statement): - field: StateExpression + field: StorageExpression def accept(self, visitor: StatementVisitor[T]) -> T: return visitor.visit_state_delete(self) @@ -1616,40 +1609,6 @@ class ModuleStatement(Node, ABC): def accept(self, visitor: ModuleStatementVisitor[T]) -> T: ... -@attrs.frozen -class BoxProxyField(Expression): # TODO: yeet me - """ - An expression representing a box proxy class instance stored on a contract field. - - wtype will be WBoxProxy or wtypes.box_ref_proxy_type - """ - - field_name: str - wtype: wtypes.WType = attrs.field( - validator=wtype_is_one_of(wtypes.box_ref_proxy_type, wtypes.WBoxProxy, wtypes.WBoxMapProxy) - ) - - def accept(self, visitor: ExpressionVisitor[T]) -> T: - return visitor.visit_box_proxy_field(self) - - -@attrs.frozen -class BoxProxyExpression(Expression): - """ - An expression representing the box proxy class 'instance' - - wtype will be WBoxProxy or wtypes.box_ref_proxy_type - """ - - key: Expression - wtype: wtypes.WType = attrs.field( - validator=wtype_is_one_of(wtypes.box_ref_proxy_type, wtypes.WBoxProxy, wtypes.WBoxMapProxy) - ) - - def accept(self, visitor: ExpressionVisitor[T]) -> T: - return visitor.visit_box_proxy_expression(self) - - @attrs.frozen class BytesRaw(Expression): """Get the raw bytes of a scalar expression. @@ -1663,60 +1622,6 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: return visitor.visit_bytes_raw(self) -@attrs.frozen -class BoxKeyExpression(Expression): - """ - An expression for reading the key of a box from a box proxy - """ - - wtype = attrs.field(default=wtypes.bytes_wtype, init=False) - proxy: Expression = attrs.field() - item_key: Expression | None = attrs.field(default=None) - - @item_key.validator - def _validate_item_key(self, _instance: object, item_key: Expression | None) -> None: - is_map_proxy = isinstance(self.proxy.wtype, wtypes.WBoxMapProxy) - if item_key and not is_map_proxy: - raise InternalError(f"item_key only valid for wtype of {wtypes.WBoxMapProxy}") - if not item_key and is_map_proxy: - raise InternalError(f"item_key required for wtype of {wtypes.WBoxMapProxy}") - - def accept(self, visitor: ExpressionVisitor[T]) -> T: - return visitor.visit_box_key_expression(self) - - -@attrs.frozen -class BoxValueExpression(Expression): - """ - An expression for reading the value of a box. - - wtype will be the value type of the box - """ - - proxy: Expression - item_key: Expression | None = attrs.field(default=None) - - @item_key.validator - def _validate_item_key(self, _instance: object, item_key: Expression | None) -> None: - is_map_proxy = isinstance(self.proxy.wtype, wtypes.WBoxMapProxy) - if item_key and not is_map_proxy: - raise InternalError(f"item_key only valid for wtype of {wtypes.WBoxMapProxy}") - if not item_key and is_map_proxy: - raise InternalError(f"item_key required for wtype of {wtypes.WBoxMapProxy}") - - def accept(self, visitor: ExpressionVisitor[T]) -> T: - return visitor.visit_box_value_expression(self) - - -@attrs.frozen -class BoxLength(Expression): - box_key: BoxKeyExpression = attrs.field() - wtype = attrs.field(default=wtypes.uint64_wtype, init=False) - - def accept(self, visitor: ExpressionVisitor[T]) -> T: - return visitor.visit_box_length(self) - - @attrs.frozen class ConstantDeclaration(ModuleStatement): value: ConstantValue @@ -1846,9 +1751,7 @@ class ContractFragment(ModuleStatement): symtable: Mapping[str, ContractMethod | AppStorageDefinition] = attrs.field(init=False) @symtable.default - def _symtable_factory( - self, - ) -> Mapping[str, ContractMethod | AppStorageDefinition]: + def _symtable_factory(self) -> Mapping[str, ContractMethod | AppStorageDefinition]: result: dict[str, ContractMethod | AppStorageDefinition] = {**self.app_state} all_subs = itertools.chain( filter(None, (self.init, self.approval_program, self.clear_program)), @@ -1949,17 +1852,3 @@ class Module: @cached_property def symtable(self) -> Mapping[str, ModuleStatement]: return {stmt.name: stmt for stmt in self.body} - - -# Expression types that are valid on the left hand side of assignment *statements* -# Note that some of these can be recursive/nested, eg: -# obj.field[index].another_field = 123 -Lvalue = ( - VarExpression - | FieldExpression - | IndexExpression - | TupleExpression - | AppStateExpression - | AppAccountStateExpression - | BoxValueExpression -) diff --git a/src/puya/awst/to_code_visitor.py b/src/puya/awst/to_code_visitor.py index 61f50eb2d..18199cb09 100644 --- a/src/puya/awst/to_code_visitor.py +++ b/src/puya/awst/to_code_visitor.py @@ -52,26 +52,6 @@ def visit_module(self, module: nodes.Module) -> str: result.extend(lines) return "\n".join(result).strip() - def visit_box_value_expression(self, expr: nodes.BoxValueExpression) -> str: - return f"{expr.proxy.accept(self)}.value" - - def visit_box_proxy_expression(self, expr: nodes.BoxProxyExpression) -> str: - if expr.wtype == wtypes.box_ref_proxy_type: - return f"BoxRef({expr.key.accept(self)})" - return f"Box({expr.key.accept(self)})" - - def visit_box_key_expression(self, expr: nodes.BoxKeyExpression) -> str: - match expr.proxy: - case nodes.BoxProxyExpression(key=key): - return key.accept(self) - case nodes.BoxProxyField(field_name=field): - return f"this.{field}.key" - case _: - return f"{expr.proxy.accept(self)}.key" - - def visit_box_length(self, expr: nodes.BoxLength) -> str: - return f"len({expr.box_key.accept(self)})" - def visit_arc4_decode(self, expr: nodes.ARC4Decode) -> str: return f"arc4_decode({expr.value.accept(self)}, {expr.wtype})" @@ -90,19 +70,22 @@ def visit_single_evaluation(self, expr: nodes.SingleEvaluation) -> str: ) def visit_app_state_expression(self, expr: nodes.AppStateExpression) -> str: - if expr.field_name is not None: - return f"this.{expr.field_name}" + if expr.member_name is not None: + return f"this.{expr.member_name}" else: return f"GlobalState[{expr.key.accept(self)}]" def visit_app_account_state_expression(self, expr: nodes.AppAccountStateExpression) -> str: - if expr.field_name is not None: - return f"this.{expr.field_name}[{expr.account.accept(self)}]" + if expr.member_name is not None: + return f"this.{expr.member_name}[{expr.account.accept(self)}]" else: return f"LocalState[{expr.key.accept}, {expr.account.accept(self)}]" - def visit_box_proxy_field(self, expr: nodes.BoxProxyField) -> str: - return f"this.{expr.field_name}" + def visit_box_value_expression(self, expr: nodes.BoxValueExpression) -> str: + if expr.member_name is not None: + return f"this.{expr.member_name}" + else: + return f"Box[{expr.key.accept(self)}]" def visit_new_array(self, expr: nodes.NewArray) -> str: args = ", ".join(a.accept(self) for a in expr.values) diff --git a/src/puya/awst/visitors.py b/src/puya/awst/visitors.py index 9bea8378b..65303afcc 100644 --- a/src/puya/awst/visitors.py +++ b/src/puya/awst/visitors.py @@ -261,17 +261,5 @@ def visit_intersection_slice_expression( @abstractmethod def visit_box_value_expression(self, expr: puya.awst.nodes.BoxValueExpression) -> T: ... - @abstractmethod - def visit_box_length(self, expr: puya.awst.nodes.BoxLength) -> T: ... - - @abstractmethod - def visit_box_proxy_field(self, expr: puya.awst.nodes.BoxProxyField) -> T: ... - - @abstractmethod - def visit_box_proxy_expression(self, expr: puya.awst.nodes.BoxProxyExpression) -> T: ... - - @abstractmethod - def visit_box_key_expression(self, expr: puya.awst.nodes.BoxKeyExpression) -> T: ... - @abstractmethod def visit_bytes_raw(self, expr: puya.awst.nodes.BytesRaw) -> T: ... diff --git a/src/puya/awst/wtypes.py b/src/puya/awst/wtypes.py index 38b53514e..7f1b99248 100644 --- a/src/puya/awst/wtypes.py +++ b/src/puya/awst/wtypes.py @@ -23,13 +23,12 @@ def _all_literals_invalid(_value: object) -> bool: @attrs.frozen(str=False, kw_only=True) class WType: name: str - stub_name: str immutable: bool = True scalar: bool = True # is this a single value on the stack? is_valid_literal: LiteralValidator = attrs.field(default=_all_literals_invalid, eq=False) def __str__(self) -> str: - return self.stub_name + return self.name def is_valid_bool_literal(value: object) -> typing.TypeGuard[bool]: @@ -75,64 +74,54 @@ def is_valid_utf8_literal(value: object) -> typing.TypeGuard[str]: void_wtype: typing.Final = WType( name="void", - stub_name="None", ) bool_wtype: typing.Final = WType( name="bool", - stub_name="bool", is_valid_literal=is_valid_bool_literal, ) uint64_wtype: typing.Final = WType( name="uint64", - stub_name=constants.CLS_UINT64_ALIAS, is_valid_literal=is_valid_uint64_literal, ) biguint_wtype: typing.Final = WType( name="biguint", - stub_name=constants.CLS_BIGUINT_ALIAS, is_valid_literal=is_valid_biguint_literal, ) bytes_wtype: typing.Final = WType( name="bytes", - stub_name=constants.CLS_BYTES_ALIAS, is_valid_literal=is_valid_bytes_literal, ) string_wtype: typing.Final = WType( name="string", - stub_name=constants.CLS_STRING_ALIAS, is_valid_literal=is_valid_utf8_literal, ) asset_wtype: typing.Final = WType( name="asset", - stub_name=constants.CLS_ASSET_ALIAS, is_valid_literal=is_valid_uint64_literal, ) -state_key: typing.Final = WType( - name="state_key", - stub_name="n/a", # TODO: seperation - is_valid_literal=_bytes_literal_validator(max_size=algo_constants.MAX_STATE_KEY_LENGTH), -) -box_key: typing.Final = WType( - name="box_key", - stub_name="n/a", # TODO: seperation - is_valid_literal=_bytes_literal_validator( - min_size=algo_constants.MIN_BOX_KEY_LENGTH, max_size=algo_constants.MAX_BOX_KEY_LENGTH - ), -) +# TODO: take the below approach and use everywhere +# state_key: typing.Final = WType( +# name="state_key", +# is_valid_literal=_bytes_literal_validator(max_size=algo_constants.MAX_STATE_KEY_LENGTH), +# ) +# box_key: typing.Final = WType( +# name="box_key", +# is_valid_literal=_bytes_literal_validator( +# min_size=algo_constants.MIN_BOX_KEY_LENGTH, max_size=algo_constants.MAX_BOX_KEY_LENGTH +# ), +# ) account_wtype: typing.Final = WType( name="account", - stub_name=constants.CLS_ACCOUNT_ALIAS, is_valid_literal=is_valid_account_literal, ) application_wtype: typing.Final = WType( name="application", - stub_name=constants.CLS_APPLICATION_ALIAS, is_valid_literal=is_valid_uint64_literal, ) @@ -148,11 +137,7 @@ def from_type(cls, transaction_type: constants.TransactionType | None) -> "WGrou name = "group_transaction" if transaction_type: name = f"{name}_{transaction_type.name}" - return cls( - transaction_type=transaction_type, - stub_name=constants.TRANSACTION_TYPE_TO_CLS[transaction_type].gtxn, - name=name, - ) + return cls(name=name, transaction_type=transaction_type) # TODO only allow int literals below max group size @@ -169,11 +154,7 @@ def from_type( name = "inner_transaction_fields" if transaction_type: name = f"{name}_{transaction_type.name}" - return cls( - transaction_type=transaction_type, - stub_name=constants.TRANSACTION_TYPE_TO_CLS[transaction_type].itxn_fields, - name=name, - ) + return cls(name=name, transaction_type=transaction_type) @attrs.define @@ -186,47 +167,7 @@ def from_type(cls, transaction_type: constants.TransactionType | None) -> "WInne name = "inner_transaction" if transaction_type: name = f"{name}_{transaction_type.name}" - return cls( - transaction_type=transaction_type, - stub_name=constants.TRANSACTION_TYPE_TO_CLS[transaction_type].itxn_result, - name=name, - ) - - -@attrs.define -class WBoxProxy(WType): - content_wtype: WType = attrs.field() - - @classmethod - def from_content_type(cls, content_wtype: WType) -> "WBoxProxy": - return cls( - content_wtype=content_wtype, - name=f"box_proxy[{content_wtype.name}]", - stub_name=f"{constants.CLS_BOX_PROXY_ALIAS}[{content_wtype.stub_name}]", - ) - - -@attrs.define -class WBoxMapProxy(WType): - key_wtype: WType - content_wtype: WType - - @classmethod - def from_key_and_content_type(cls, key_wtype: WType, content_wtype: WType) -> "WBoxMapProxy": - return cls( - key_wtype=key_wtype, - content_wtype=content_wtype, - name=f"box_map_proxy[{key_wtype.name},{content_wtype.name}]", - stub_name=( - f"{constants.CLS_BOX_MAP_PROXY_ALIAS}" - f"[{key_wtype.stub_name}, {content_wtype.stub_name}]" - ), - ) - - -box_ref_proxy_type: typing.Final = WType( - name="box_ref_proxy", stub_name=constants.CLS_BOX_REF_PROXY_ALIAS -) + return cls(name=name, transaction_type=transaction_type) @typing.final @@ -237,7 +178,6 @@ class WStructType(WType): def __init__( self, - python_name: str, # TODO: yeet me fields: Mapping[str, WType], immutable: bool, # noqa: FBT001 source_location: SourceLocation | None, @@ -253,12 +193,7 @@ def __init__( ) + ">" ) - self.__attrs_init__( - name=name, - stub_name=python_name, - immutable=immutable, - fields=fields, - ) + self.__attrs_init__(name=name, fields=fields, immutable=immutable) @typing.final @@ -271,12 +206,7 @@ def __init__(self, element_type: WType, source_location: SourceLocation | None): if element_type == void_wtype: raise CodeError("array element type cannot be void", source_location) name = f"array<{element_type.name}>" - self.__attrs_init__( - name=name, - stub_name=f"{constants.CLS_ARRAY_ALIAS}[{element_type}]", - immutable=False, - element_type=element_type, - ) + self.__attrs_init__(name=name, element_type=element_type, immutable=False) @typing.final @@ -292,8 +222,7 @@ def __init__(self, types: Iterable[WType], source_location: SourceLocation | Non if void_wtype in types: raise CodeError("tuple should not contain void types", source_location) name = f"tuple<{','.join([t.name for t in types])}>" - python_name = f"tuple[{', '.join(map(str, types))}]" - self.__attrs_init__(name=name, stub_name=python_name, types=types) + self.__attrs_init__(name=name, types=types) @attrs.frozen @@ -318,20 +247,13 @@ def __init__( *, name: str | None = None, alias: str | None = None, - stub_name: str | None = None, ): if not (n % 8 == 0): raise CodeError("Bit size must be multiple of 8", source_location) if not (8 <= n <= 512): raise CodeError("Bit size must be between 8 and 512 inclusive", source_location) name = name or f"arc4.uint{n}" - if stub_name is None: - if n.bit_count() == 1: # quick way to check for power of 2 - stub_name = f"{constants.ARC4_PREFIX}UInt{n}" - else: - base_cls = constants.CLS_ARC4_UINTN if n <= 64 else constants.CLS_ARC4_BIG_UINTN - stub_name = f"{base_cls}[typing.Literal[{n}]]" - self.__attrs_init__(n=n, name=name, stub_name=stub_name, alias=alias) + self.__attrs_init__(name=name, n=n, alias=alias) @typing.final @@ -359,10 +281,7 @@ def __init__(self, types: Iterable[WType], source_location: SourceLocation | Non # then the overall value is also mutable immutable = immutable and typ.immutable name = f"arc4.tuple<{','.join([t.name for t in types])}>" - python_name = f"{constants.CLS_ARC4_TUPLE}[{', '.join(map(str, types))}]" - self.__attrs_init__( - name=name, stub_name=python_name, types=tuple(arc4_types), immutable=immutable - ) + self.__attrs_init__(name=name, types=tuple(arc4_types), immutable=immutable) @typing.final @@ -372,43 +291,41 @@ class ARC4UFixedNxM(ARC4Type): m: int def __init__(self, bits: int, precision: int, source_location: SourceLocation | None): - n = bits - m = precision - if not (n % 8 == 0): + if not (bits % 8 == 0): raise CodeError("Bit size must be multiple of 8", source_location) - if not (8 <= n <= 512): + if not (8 <= bits <= 512): raise CodeError("Bit size must be between 8 and 512 inclusive", source_location) - if not (1 <= m <= 160): + if not (1 <= precision <= 160): raise CodeError("Precision must be between 1 and 160 inclusive", source_location) - name = f"arc4.ufixed{n}x{m}" - base_cls = constants.CLS_ARC4_UFIXEDNXM if n <= 64 else constants.CLS_ARC4_BIG_UFIXEDNXM - - def is_valid_literal(value: object) -> bool: - import decimal - - if not isinstance(value, decimal.Decimal): - return False - sign, digits, exponent = value.as_tuple() - if sign != 0: # is negative - return False - if not isinstance(exponent, int): # is infinite - return False - # note: input is expected to be quantized correctly already - if -exponent != m: # wrong precision - return False - adjusted_int = int("".join(map(str, digits))) - return adjusted_int.bit_length() <= n - self.__attrs_init__( - n=n, - m=m, - name=name, - stub_name=f"{base_cls}[typing.Literal[{n}], typing.Literal[{m}]]", - is_valid_literal=is_valid_literal, + name=f"arc4.ufixed{bits}x{precision}", + n=bits, + m=precision, + is_valid_literal=_make_ufixed_literal_validator(precision=precision, bits=bits), ) +def _make_ufixed_literal_validator(*, bits: int, precision: int) -> LiteralValidator: + def validator(value: object) -> bool: + import decimal + + if not isinstance(value, decimal.Decimal): + return False + sign, digits, exponent = value.as_tuple() + if sign != 0: # is negative + return False + if not isinstance(exponent, int): # is infinite + return False + # note: input is expected to be quantized correctly already + if -exponent != precision: # wrong precision + return False + adjusted_int = int("".join(map(str, digits))) + return adjusted_int.bit_length() <= bits + + return validator + + @attrs.frozen(str=False, kw_only=True) class ARC4Array(ARC4Type): element_type: ARC4Type @@ -418,7 +335,6 @@ class ARC4Array(ARC4Type): @typing.final @attrs.frozen(str=False, kw_only=True, init=False) class ARC4DynamicArray(ARC4Array): - def __init__( self, element_type: WType, @@ -427,18 +343,13 @@ def __init__( name: str | None = None, alias: str | None = None, is_valid_literal: LiteralValidator | None = None, - stub_name: str | None = None, ): if not isinstance(element_type, ARC4Type): raise CodeError("ARC4 arrays must have ARC4 encoded element type", source_location) name = name or f"arc4.dynamic_array<{element_type.name}>" is_valid_literal = is_valid_literal or typing.cast(LiteralValidator, attrs.NOTHING) self.__attrs_init__( - name=name, - element_type=element_type, - stub_name=stub_name or f"{constants.CLS_ARC4_DYNAMIC_ARRAY}[{element_type}]", - alias=alias, - is_valid_literal=is_valid_literal, + name=name, element_type=element_type, alias=alias, is_valid_literal=is_valid_literal ) @@ -455,7 +366,6 @@ def __init__( *, alias: str | None = None, name: str | None = None, - stub_name: str | None = None, ): if not isinstance(element_type, ARC4Type): raise CodeError("ARC4 arrays must have ARC4 encoded element type", source_location) @@ -463,16 +373,7 @@ def __init__( raise CodeError("ARC4 static array size must be non-negative", source_location) name = name or f"arc4.static_array<{element_type.name}, {array_size}>" self.__attrs_init__( - array_size=array_size, - name=name, - element_type=element_type, - stub_name=stub_name - or ( - f"{constants.CLS_ARC4_STATIC_ARRAY}[" - f"{element_type}, typing.Literal[{array_size}]" - f"]" - ), - alias=alias, + name=name, element_type=element_type, array_size=array_size, alias=alias ) @@ -493,7 +394,6 @@ def types(self) -> Sequence[WType]: def __init__( self, - python_name: str, # TODO: yeet me fields: Mapping[str, WType], immutable: bool, # noqa: FBT001 source_location: SourceLocation | None, @@ -527,23 +427,16 @@ def __init__( ) + ">" ) - self.__attrs_init__( - name=name, - stub_name=python_name, - immutable=immutable, - fields=arc4_fields, - ) + self.__attrs_init__(name=name, fields=arc4_fields, immutable=immutable) arc4_string_wtype: typing.Final = ARC4Type( name="arc4.string", - stub_name=constants.CLS_ARC4_STRING, alias="string", is_valid_literal=is_valid_utf8_literal, ) arc4_bool_wtype: typing.Final = ARC4Type( name="arc4.bool", - stub_name=constants.CLS_ARC4_BOOL, alias="bool", is_valid_literal=is_valid_bool_literal, ) @@ -552,20 +445,17 @@ def __init__( name="arc4.byte", alias="byte", source_location=None, - stub_name=constants.CLS_ARC4_BYTE, ) arc4_dynamic_bytes: typing.Final = ARC4DynamicArray( # TODO: REMOVE ME name="arc4.dynamic_bytes", element_type=arc4_byte_type, is_valid_literal=is_valid_bytes_literal, - stub_name=constants.CLS_ARC4_DYNAMIC_BYTES, source_location=None, ) arc4_address_type: typing.Final = ARC4StaticArray( - array_size=32, name="arc4.address", element_type=arc4_byte_type, - stub_name=constants.CLS_ARC4_ADDRESS, + array_size=32, alias="address", source_location=None, ) diff --git a/src/puya/awst_build/contract.py b/src/puya/awst_build/contract.py index 6da50e5ea..f651f8f49 100644 --- a/src/puya/awst_build/contract.py +++ b/src/puya/awst_build/contract.py @@ -223,24 +223,22 @@ def visit_function( arc4_decorator_loc, ) else: - ret_wtype = ret_pytype.wtype - arg_wtypes = [a.wtype for a in arg_pytypes] - for arg_wtype in arg_wtypes: + for arg_type in arg_pytypes: if not ( - wtypes.is_arc4_argument_type(arg_wtype) - or wtypes.has_arc4_equivalent_type(arg_wtype) + wtypes.is_arc4_argument_type(arg_type.wtype) + or wtypes.has_arc4_equivalent_type(arg_type.wtype) ): self._error( - f"Invalid argument type for an ARC4 method: {arg_wtype}", + f"Invalid argument type for an ARC4 method: {arg_type}", arc4_decorator_loc, ) if not ( - ret_wtype is wtypes.void_wtype - or wtypes.is_arc4_encoded_type(ret_wtype) - or wtypes.has_arc4_equivalent_type(ret_wtype) + ret_pytype == pytypes.NoneType + or wtypes.is_arc4_encoded_type(ret_pytype.wtype) + or wtypes.has_arc4_equivalent_type(ret_pytype.wtype) ): self._error( - f"Invalid return type for an ARC4 method: {ret_wtype}", + f"Invalid return type for an ARC4 method: {ret_pytype}", arc4_decorator_loc, ) # TODO: validate against super-class configs?? diff --git a/src/puya/awst_build/eb/_storage.py b/src/puya/awst_build/eb/_storage.py new file mode 100644 index 000000000..15623189b --- /dev/null +++ b/src/puya/awst_build/eb/_storage.py @@ -0,0 +1,144 @@ +from __future__ import annotations + +import typing + +from puya.awst import wtypes +from puya.awst.nodes import ( + BytesConstant, + BytesEncoding, + BytesRaw, + ContractReference, + Expression, + Literal, + Lvalue, + Statement, +) +from puya.awst_build import pytypes +from puya.awst_build.contract_data import AppStorageDeclaration +from puya.awst_build.eb.base import ExpressionBuilder, StorageProxyConstructorResult +from puya.errors import CodeError + +if typing.TYPE_CHECKING: + + from puya.parse import SourceLocation + + +class StorageProxyDefinitionBuilder(StorageProxyConstructorResult): + def __init__( + self, + typ: pytypes.StorageProxyType | pytypes.StorageMapProxyType, + location: SourceLocation, + description: str | None, + initial_value: Expression | None = None, + ): + super().__init__(location) + self._typ = typ + self.description = description + self._initial_value = initial_value + + @property + def pytype(self) -> pytypes.StorageProxyType | pytypes.StorageMapProxyType: + return self._typ + + @typing.override + @property + def initial_value(self) -> Expression | None: + return self._initial_value + + @typing.override + def build_definition( + self, + member_name: str, + defined_in: ContractReference, + typ: pytypes.PyType, + location: SourceLocation, + ) -> AppStorageDeclaration: + return AppStorageDeclaration( + description=self.description, + member_name=member_name, + key_override=None, + source_location=location, + typ=typ, + defined_in=defined_in, + ) + + @typing.override + def rvalue(self) -> Expression: + return self._assign_first(self.source_location) + + @typing.override + def lvalue(self) -> Lvalue: + raise CodeError(f"{self._typ} is not valid as an assignment target", self.source_location) + + @typing.override + def delete(self, location: SourceLocation) -> Statement: + raise self._assign_first(location) + + @typing.override + def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: + return self._assign_first(location) + + @typing.override + def unary_plus(self, location: SourceLocation) -> ExpressionBuilder: + return self._assign_first(location) + + @typing.override + def unary_minus(self, location: SourceLocation) -> ExpressionBuilder: + return self._assign_first(location) + + @typing.override + def bitwise_invert(self, location: SourceLocation) -> ExpressionBuilder: + return self._assign_first(location) + + @typing.override + def contains( + self, item: ExpressionBuilder | Literal, location: SourceLocation + ) -> ExpressionBuilder: + return self._assign_first(location) + + def _assign_first(self, location: SourceLocation) -> typing.Never: + raise CodeError( + f"{self._typ} with inferred" + f" key{'_prefix' if isinstance(self._typ, pytypes.StorageMapProxyType) else ''}" + " must be assigned to an instance variable before being used", + location, + ) + + +def extract_key_override( + key_arg: ExpressionBuilder | Literal | None, location: SourceLocation, *, is_prefix: bool +) -> Expression | None: + key_override: Expression | None + match key_arg: + case None: + key_override = None + case Literal(value=bytes(bytes_value), source_location=key_lit_loc): + key_override = BytesConstant( + value=bytes_value, encoding=BytesEncoding.unknown, source_location=key_lit_loc + ) + case Literal(value=str(str_value), source_location=key_lit_loc): + key_override = BytesConstant( + value=str_value.encode("utf8"), + encoding=BytesEncoding.utf8, + source_location=key_lit_loc, + ) + case ExpressionBuilder(value_type=wtypes.bytes_wtype) as eb: + key_override = eb.rvalue() + case ExpressionBuilder(value_type=wtypes.string_wtype) as eb: + key_override = BytesRaw(expr=eb.rvalue(), source_location=location) + case _: + raise CodeError( + f"invalid type for key{'_prefix' if is_prefix else ''} argument", + key_arg.source_location, + ) + return key_override + + +def extract_description(descr_arg: ExpressionBuilder | Literal | None) -> str | None: + match descr_arg: + case None: + return None + case Literal(value=str(str_value)): + return str_value + case _: + raise CodeError("description should be a str literal", descr_arg.source_location) diff --git a/src/puya/awst_build/eb/app_account_state.py b/src/puya/awst_build/eb/app_account_state.py index a03dac126..e7a30cf3b 100644 --- a/src/puya/awst_build/eb/app_account_state.py +++ b/src/puya/awst_build/eb/app_account_state.py @@ -1,4 +1,5 @@ -from collections.abc import Sequence +import typing +from collections.abc import Callable, Sequence import mypy.nodes import mypy.types @@ -7,7 +8,7 @@ from puya.awst.nodes import ( AppAccountStateExpression, BytesConstant, - BytesEncoding, + ContractReference, Expression, IntegerConstant, Literal, @@ -17,59 +18,223 @@ StateGetEx, Statement, ) -from puya.awst_build import constants, pytypes +from puya.awst_build import pytypes from puya.awst_build.contract_data import AppStorageDeclaration +from puya.awst_build.eb._storage import ( + StorageProxyDefinitionBuilder, + extract_description, + extract_key_override, +) from puya.awst_build.eb.base import ( ExpressionBuilder, + FunctionBuilder, GenericClassExpressionBuilder, - IntermediateExpressionBuilder, - StateProxyDefinitionBuilder, - StateProxyMemberBuilder, + StorageProxyConstructorResult, TypeClassExpressionBuilder, + ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder from puya.awst_build.eb.tuple import TupleExpressionBuilder from puya.awst_build.eb.value_proxy import ValueProxyExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import convert_literal_to_expr, expect_operand_wtype, get_arg_mapping -from puya.errors import CodeError, InternalError +from puya.errors import CodeError from puya.parse import SourceLocation -class AppAccountStateExpressionBuilder(StateProxyMemberBuilder): - def __init__(self, state_decl: AppStorageDeclaration, location: SourceLocation): - assert state_decl.typ.generic is pytypes.GenericLocalStateType - super().__init__(location) - self.state_decl = state_decl +class AppAccountStateClassExpressionBuilder(TypeClassExpressionBuilder[pytypes.StorageProxyType]): + def __init__(self, typ: pytypes.PyType, location: SourceLocation) -> None: + assert isinstance(typ, pytypes.StorageProxyType) + assert typ.generic == pytypes.GenericLocalStateType + self._typ = typ + super().__init__(typ, location) + + @typing.override + def call( + self, + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_kinds: list[mypy.nodes.ArgKind], + arg_names: list[str | None], + location: SourceLocation, + ) -> ExpressionBuilder: + return _init(args, arg_typs, arg_names, location, result_type=self._typ) + + +class AppAccountStateGenericClassExpressionBuilder(GenericClassExpressionBuilder): + @typing.override + def call( + self, + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_kinds: list[mypy.nodes.ArgKind], + arg_names: list[str | None], + location: SourceLocation, + ) -> ExpressionBuilder: + return _init(args, arg_typs, arg_names, location, result_type=None) + + +def _init( + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_names: list[str | None], + location: SourceLocation, + *, + result_type: pytypes.StorageProxyType | None, +) -> ExpressionBuilder: + type_arg_name = "type_" + arg_mapping = get_arg_mapping( + positional_arg_names=[type_arg_name], + args=zip(arg_names, zip(args, arg_typs, strict=True), strict=True), + location=location, + ) + try: + _, type_arg_typ = arg_mapping.pop(type_arg_name) + except KeyError as ex: + raise CodeError("Required positional argument missing", location) from ex + + key_arg, _ = arg_mapping.pop("key", (None, None)) + descr_arg, _ = arg_mapping.pop("description", (None, None)) + if arg_mapping: + raise CodeError(f"Unrecognised keyword argument(s): {", ".join(arg_mapping)}", location) + + match type_arg_typ: + case pytypes.TypeType(typ=content): + pass + case _: + raise CodeError("First argument must be a type reference", location) + if result_type is None: + result_type = pytypes.GenericLocalStateType.parameterise([content], location) + elif result_type.content != content: + raise CodeError( + "App account state explicit type annotation does not match first argument" + " - suggest to remove the explicit type annotation," + " it shouldn't be required", + location, + ) + + key_override = extract_key_override(key_arg, location, is_prefix=False) + description = extract_description(descr_arg) + if key_override is None: + return StorageProxyDefinitionBuilder( + result_type, location=location, description=description + ) + return _AppAccountStateExpressionBuilderFromConstructor( + key_override=key_override, typ=result_type, description=description + ) + + +class AppAccountStateExpressionBuilder(ValueExpressionBuilder[pytypes.StorageProxyType]): + def __init__(self, expr: Expression, typ: pytypes.PyType, member_name: str | None = None): + assert isinstance(typ, pytypes.StorageProxyType) + assert typ.generic == pytypes.GenericLocalStateType + self._member_name = member_name + super().__init__(typ, expr) + + def _build_field( + self, + index: ExpressionBuilder | Literal, + location: SourceLocation, + ) -> AppAccountStateExpression: + index_expr = convert_literal_to_expr(index, wtypes.uint64_wtype) + match index_expr: + case IntegerConstant(value=account_offset): + # https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/#resource-availability + # Note that the sender address is implicitly included in the array, + # but doesn't count towards the limit of 4, so the <= 4 below is correct + # and intended + if not (0 <= account_offset <= 4): + raise CodeError( + "Account index should be between 0 and 4 inclusive", index.source_location + ) + case Expression(wtype=(wtypes.uint64_wtype | wtypes.account_wtype)): + pass + case _: + raise CodeError( + "Invalid index argument - must be either an Address or a UInt64", + index.source_location, + ) + return AppAccountStateExpression( + key=self.expr, + member_name=self._member_name, + account=index_expr, + wtype=self.pytype.content.wtype, + source_location=location, + ) def index( self, index: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: - expr = _build_field(self.state_decl, index, location) - return AppAccountStateForAccountExpressionBuilder(expr) + expr = self._build_field(index, location) + return AppAccountStateForAccountExpressionBuilder(self.pytype.content, expr) def contains( self, item: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: exists_expr = StateExists( - field=_build_field(self.state_decl, item, location), source_location=location + field=self._build_field(item, location), source_location=location ) return BoolExpressionBuilder(exists_expr) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "get": - return AppAccountStateGetMethodBuilder(self.state_decl, location) + return _Get(self.pytype.content, self._build_field, location) case "maybe": - return AppAccountStateMaybeMethodBuilder(self.state_decl, location) + return _Maybe(self.pytype.content, self._build_field, location) return super().member_access(name, location) -class AppAccountStateGetMethodBuilder(IntermediateExpressionBuilder): - def __init__(self, state_decl: AppStorageDeclaration, location: SourceLocation): +class _AppAccountStateExpressionBuilderFromConstructor( + AppAccountStateExpressionBuilder, StorageProxyConstructorResult +): + def __init__( + self, key_override: Expression, typ: pytypes.StorageProxyType, description: str | None + ): + super().__init__(key_override, typ, member_name=None) + self.description = description + + @typing.override + @property + def initial_value(self) -> Expression | None: + return None + + @typing.override + def build_definition( + self, + member_name: str, + defined_in: ContractReference, + typ: pytypes.PyType, + location: SourceLocation, + ) -> AppStorageDeclaration: + key_override = self.expr + if not isinstance(key_override, BytesConstant): + raise CodeError( + f"assigning {typ} to a member variable requires a constant value for key", + location, + ) + return AppStorageDeclaration( + description=self.description, + member_name=member_name, + key_override=key_override, + source_location=location, + typ=typ, + defined_in=defined_in, + ) + + +FieldBuilder = Callable[[ExpressionBuilder | Literal, SourceLocation], AppAccountStateExpression] + + +class _Get(FunctionBuilder): + def __init__( + self, content_typ: pytypes.PyType, field_builder: FieldBuilder, location: SourceLocation + ): super().__init__(location) - self.state_decl = state_decl + self._content_typ = content_typ + self._build_field = field_builder + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -84,23 +249,25 @@ def call( default_arg, item = args else: item, default_arg = args - default_expr = expect_operand_wtype( - default_arg, target_wtype=self.state_decl.definition.storage_wtype - ) + default_expr = expect_operand_wtype(default_arg, target_wtype=self._content_typ.wtype) expr = StateGet( - field=_build_field(self.state_decl, item, location), + field=self._build_field(item, location), default=default_expr, source_location=location, ) - return var_expression(expr) + return builder_for_instance(self._content_typ, expr) -class AppAccountStateMaybeMethodBuilder(IntermediateExpressionBuilder): - def __init__(self, state_decl: AppStorageDeclaration, location: SourceLocation): +class _Maybe(FunctionBuilder): + def __init__( + self, content_typ: pytypes.PyType, field_builder: FieldBuilder, location: SourceLocation + ): super().__init__(location) - self.state_decl = state_decl + self._content_typ = content_typ + self._build_field = field_builder + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -111,146 +278,18 @@ def call( ) -> ExpressionBuilder: match args: case [item]: - field = _build_field(self.state_decl, item, location) + field = self._build_field(item, location) app_local_get_ex = StateGetEx(field=field, source_location=location) - return TupleExpressionBuilder(app_local_get_ex) + result_typ = pytypes.GenericTupleType.parameterise( + [self._content_typ, pytypes.BoolType], location + ) + return TupleExpressionBuilder(app_local_get_ex, result_typ) case _: raise CodeError("Invalid/unhandled arguments", location) class AppAccountStateForAccountExpressionBuilder(ValueProxyExpressionBuilder): - def __init__(self, expr: AppAccountStateExpression): - self.__field = expr - self.wtype = expr.wtype - super().__init__(expr) + expr: AppAccountStateExpression # TODO: remove "lies" def delete(self, location: SourceLocation) -> Statement: - return StateDelete(field=self.__field, source_location=location) - - -class AppAccountStateClassExpressionBuilder(GenericClassExpressionBuilder): - def __init__(self, location: SourceLocation): - super().__init__(location) - self._storage: wtypes.WType | None = None - - def index_multiple( - self, indexes: Sequence[ExpressionBuilder | Literal], location: SourceLocation - ) -> ExpressionBuilder: - if self._storage is not None: - raise InternalError("Multiple indexing of Local?", location) - match indexes: - case [TypeClassExpressionBuilder() as typ_class_eb]: - self.source_location += location - self._storage = typ_class_eb.produces() - return self - raise CodeError( - "Invalid indexing, only a single type arg is supported " - "(you can also omit the type argument entirely as it should be redundant)", - location, - ) - - def call( - self, - args: Sequence[ExpressionBuilder | Literal], - arg_typs: Sequence[pytypes.PyType], - arg_kinds: list[mypy.nodes.ArgKind], - arg_names: list[str | None], - location: SourceLocation, - ) -> ExpressionBuilder: - type_arg_name = "type_" - arg_mapping = get_arg_mapping( - positional_arg_names=[type_arg_name], - args=zip(arg_names, args, strict=True), - location=location, - ) - try: - type_arg = arg_mapping.pop(type_arg_name) - except KeyError as ex: - raise CodeError("Required positional argument missing", location) from ex - - key_arg = arg_mapping.pop("key", None) - descr_arg = arg_mapping.pop("description", None) - if arg_mapping: - raise CodeError( - f"Unrecognised keyword argument(s): {", ".join(arg_mapping)}", location - ) - - match type_arg: - case TypeClassExpressionBuilder() as typ_class_eb: - storage_wtype = typ_class_eb.produces() - case _: - raise CodeError("First argument must be a type reference", location) - if self._storage is not None and self._storage != storage_wtype: - raise CodeError( - "App account state explicit type annotation does not match first argument" - " - suggest to remove the explicit type annotation," - " it shouldn't be required", - location, - ) - - match key_arg: - case None: - key_override = None - case Literal(value=bytes(bytes_value), source_location=key_lit_loc): - key_override = BytesConstant( - value=bytes_value, encoding=BytesEncoding.unknown, source_location=key_lit_loc - ) - case Literal(value=str(str_value), source_location=key_lit_loc): - key_override = BytesConstant( - value=str_value.encode("utf8"), - encoding=BytesEncoding.utf8, - source_location=key_lit_loc, - ) - case _: - raise CodeError("key should be a string or bytes literal", key_arg.source_location) - - match descr_arg: - case None: - description = None - case Literal(value=str(str_value)): - description = str_value - case _: - raise CodeError( - "description should be a string literal", descr_arg.source_location - ) - - return AppAccountStateProxyDefinitionBuilder( - location=location, - storage=storage_wtype, - key_override=key_override, - description=description, - ) - - -class AppAccountStateProxyDefinitionBuilder(StateProxyDefinitionBuilder): - python_name = constants.CLS_LOCAL_STATE_ALIAS - - -def _build_field( - state_decl: AppStorageDeclaration, index: ExpressionBuilder | Literal, location: SourceLocation -) -> AppAccountStateExpression: - index_expr = convert_literal_to_expr(index, wtypes.uint64_wtype) - match index_expr: - case IntegerConstant(value=account_offset): - # https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/#resource-availability - # Note that the sender address is implicitly included in the array, - # but doesn't count towards the limit of 4, so the <= 4 below is correct - # and intended - if not (0 <= account_offset <= 4): - raise CodeError( - "Account index should be between 0 and 4 inclusive", index.source_location - ) - case Expression(wtype=(wtypes.uint64_wtype | wtypes.account_wtype)): - pass - case _: - raise CodeError( - "Invalid index argument - must be either an Address or a UInt64", - index.source_location, - ) - return AppAccountStateExpression( - key=state_decl.key, - field_name=state_decl.member_name, - account=index_expr, - wtype=state_decl.definition.storage_wtype, - source_location=location, - ) + return StateDelete(field=self.expr, source_location=location) diff --git a/src/puya/awst_build/eb/app_state.py b/src/puya/awst_build/eb/app_state.py index d185c9d8e..0940666f6 100644 --- a/src/puya/awst_build/eb/app_state.py +++ b/src/puya/awst_build/eb/app_state.py @@ -4,12 +4,10 @@ import mypy.nodes -from puya.awst import wtypes from puya.awst.nodes import ( AppStateExpression, - BoolConstant, BytesConstant, - BytesEncoding, + ContractReference, Expression, Literal, Not, @@ -20,51 +18,43 @@ Statement, ) from puya.awst_build import constants, pytypes +from puya.awst_build.contract_data import AppStorageDeclaration +from puya.awst_build.eb._storage import ( + StorageProxyDefinitionBuilder, + extract_description, + extract_key_override, +) from puya.awst_build.eb.base import ( ExpressionBuilder, + FunctionBuilder, GenericClassExpressionBuilder, - IntermediateExpressionBuilder, - StateProxyDefinitionBuilder, - StateProxyMemberBuilder, + StorageProxyConstructorResult, TypeClassExpressionBuilder, + ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder from puya.awst_build.eb.tuple import TupleExpressionBuilder from puya.awst_build.eb.value_proxy import ValueProxyExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import expect_operand_wtype, get_arg_mapping -from puya.errors import CodeError, InternalError +from puya.errors import CodeError if typing.TYPE_CHECKING: from collections.abc import Sequence import mypy.types - from puya.awst_build.contract_data import AppStorageDeclaration from puya.parse import SourceLocation -class AppStateClassExpressionBuilder(GenericClassExpressionBuilder): - def __init__(self, location: SourceLocation): - super().__init__(location) - self._storage: wtypes.WType | None = None - - def index_multiple( - self, indexes: Sequence[ExpressionBuilder | Literal], location: SourceLocation - ) -> ExpressionBuilder: - if self._storage is not None: - raise InternalError("Multiple indexing of GlobalState?", location) - match indexes: - case [TypeClassExpressionBuilder() as typ_class_eb]: - self.source_location += location - self._storage = typ_class_eb.produces() - return self - raise CodeError( - "Invalid indexing, only a single type arg is supported " - "(you can also omit the type argument entirely as it should be redundant)", - location, - ) +class AppStateClassExpressionBuilder(TypeClassExpressionBuilder[pytypes.StorageProxyType]): + def __init__(self, typ: pytypes.PyType, location: SourceLocation) -> None: + assert isinstance(typ, pytypes.StorageProxyType) + assert typ.generic == pytypes.GenericGlobalStateType + self._typ = typ + super().__init__(typ, location) + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -73,90 +63,89 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: - type_or_value_arg_name = "type_or_initial_value" - arg_mapping = get_arg_mapping( - positional_arg_names=[type_or_value_arg_name], - args=zip(arg_names, args, strict=True), - location=location, - ) - try: - first_arg = arg_mapping.pop(type_or_value_arg_name) - except KeyError as ex: - raise CodeError("Required positional argument missing", location) from ex - - key_arg = arg_mapping.pop("key", None) - descr_arg = arg_mapping.pop("description", None) - if arg_mapping: - raise CodeError( - f"Unrecognised keyword argument(s): {", ".join(arg_mapping)}", location - ) + return _init(args, arg_typs, arg_names, location, result_type=self._typ) - match first_arg: - case TypeClassExpressionBuilder() as typ_class_eb: - storage_wtype = typ_class_eb.produces() - initial_value = None - case ExpressionBuilder(value_type=wtypes.WType() as storage_wtype) as value_eb: - initial_value = value_eb.rvalue() - case Literal(value=bool(bool_value), source_location=source_location): - initial_value = BoolConstant(value=bool_value, source_location=source_location) - storage_wtype = wtypes.bool_wtype - case _: - raise CodeError( - "First argument must be a type reference or an initial value", location - ) - if self._storage is not None and self._storage != storage_wtype: +class AppStateGenericClassExpressionBuilder(GenericClassExpressionBuilder): + @typing.override + def call( + self, + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_kinds: list[mypy.nodes.ArgKind], + arg_names: list[str | None], + location: SourceLocation, + ) -> ExpressionBuilder: + return _init(args, arg_typs, arg_names, location, result_type=None) + + +def _init( + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_names: list[str | None], + location: SourceLocation, + *, + result_type: pytypes.StorageProxyType | None, +) -> ExpressionBuilder: + type_or_value_arg_name = "type_or_initial_value" + arg_mapping = get_arg_mapping( + positional_arg_names=[type_or_value_arg_name], + args=zip(arg_names, zip(args, arg_typs, strict=True), strict=True), + location=location, + ) + try: + first_arg, first_arg_typ = arg_mapping.pop(type_or_value_arg_name) + except KeyError as ex: + raise CodeError("Required positional argument missing", location) from ex + + key_arg, _ = arg_mapping.pop("key", (None, None)) + descr_arg, _ = arg_mapping.pop("description", (None, None)) + if arg_mapping: + raise CodeError(f"Unrecognised keyword argument(s): {", ".join(arg_mapping)}", location) + + match first_arg_typ: + case pytypes.TypeType(typ=content): + initial_value = None + case pytypes.PyType() as content: + initial_value = expect_operand_wtype(first_arg, content.wtype) + case _: raise CodeError( - f"{constants.CLS_GLOBAL_STATE_ALIAS} explicit type annotation" - f" does not match first argument - suggest to remove the explicit type annotation," - " it shouldn't be required", - location, + "First argument must be a type reference or an initial value", location ) - match key_arg: - case None: - key_override = None - case Literal(value=bytes(bytes_value), source_location=key_lit_loc): - key_override = BytesConstant( - value=bytes_value, encoding=BytesEncoding.unknown, source_location=key_lit_loc - ) - case Literal(value=str(str_value), source_location=key_lit_loc): - key_override = BytesConstant( - value=str_value.encode("utf8"), - encoding=BytesEncoding.utf8, - source_location=key_lit_loc, - ) - case _: - raise CodeError("key should be a string or bytes literal", key_arg.source_location) - - match descr_arg: - case None: - description = None - case Literal(value=str(str_value)): - description = str_value - case _: - raise CodeError( - "description should be a string literal", descr_arg.source_location - ) - - return AppStateProxyDefinitionBuilder( - location=location, - storage=storage_wtype, - key_override=key_override, - description=description, - initial_value=initial_value, + if result_type is None: + result_type = pytypes.GenericGlobalStateType.parameterise([content], location) + elif result_type.content != content: + raise CodeError( + f"{constants.CLS_GLOBAL_STATE_ALIAS} explicit type annotation" + f" does not match first argument - suggest to remove the explicit type annotation," + " it shouldn't be required", + location, ) + key_override = extract_key_override(key_arg, location, is_prefix=False) + description = extract_description(descr_arg) + if key_override is None: + return StorageProxyDefinitionBuilder( + result_type, location=location, description=description, initial_value=initial_value + ) + return _AppStateExpressionBuilderFromConstructor( + key_override=key_override, + typ=result_type, + description=description, + initial_value=initial_value, + ) -class AppStateProxyDefinitionBuilder(StateProxyDefinitionBuilder): - python_name = constants.CLS_GLOBAL_STATE_ALIAS +class AppStateExpressionBuilder(ValueExpressionBuilder[pytypes.StorageProxyType]): -class AppStateExpressionBuilder(StateProxyMemberBuilder): - def __init__(self, state_decl: AppStorageDeclaration, location: SourceLocation) -> None: - self.state_decl = state_decl - super().__init__(location) + def __init__(self, expr: Expression, typ: pytypes.PyType, member_name: str | None = None): + assert isinstance(typ, pytypes.StorageProxyType) + assert typ.generic == pytypes.GenericGlobalStateType + self._member_name = member_name + super().__init__(typ, expr) + @typing.override def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: exists_expr = StateExists(field=self._build_field(location), source_location=location) if negate: @@ -165,32 +154,80 @@ def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> Expres expr = exists_expr return BoolExpressionBuilder(expr) + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: - field = self._build_field(self.source_location) + field = self._build_field(location) match name: case "value": - return AppStateValueExpressionBuilder(field) + return AppStateValueExpressionBuilder(self.pytype.content, field) case "get": - return AppStateGetExpressionBuilder(field, location=self.source_location) + return _Get(field, self.pytype.content, location=self.source_location) case "maybe": - return AppStateMaybeExpressionBuilder(field, location=self.source_location) + return _Maybe(self.pytype.content, field, location=self.source_location) case _: return super().member_access(name, location) def _build_field(self, location: SourceLocation) -> AppStateExpression: return AppStateExpression( - key=self.state_decl.key, - field_name=self.state_decl.member_name, - wtype=self.state_decl.definition.storage_wtype, + key=self.expr, + wtype=self.pytype.content.wtype, + member_name=self._member_name, + source_location=location, + ) + + +class _AppStateExpressionBuilderFromConstructor( + AppStateExpressionBuilder, StorageProxyConstructorResult +): + def __init__( + self, + key_override: Expression, + typ: pytypes.StorageProxyType, + description: str | None, + initial_value: Expression | None, + ): + super().__init__(key_override, typ, member_name=None) + self.description = description + self._initial_value = initial_value + + @typing.override + @property + def initial_value(self) -> Expression | None: + return self._initial_value + + @typing.override + def build_definition( + self, + member_name: str, + defined_in: ContractReference, + typ: pytypes.PyType, + location: SourceLocation, + ) -> AppStorageDeclaration: + key_override = self.expr + if not isinstance(key_override, BytesConstant): + raise CodeError( + f"assigning {typ} to a member variable requires a constant value for key", + location, + ) + return AppStorageDeclaration( + description=self.description, + member_name=member_name, + key_override=key_override, source_location=location, + typ=typ, + defined_in=defined_in, ) -class AppStateMaybeExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, field: AppStateExpression, location: SourceLocation) -> None: +class _Maybe(FunctionBuilder): + def __init__( + self, content_type: pytypes.PyType, field: AppStateExpression, location: SourceLocation + ) -> None: super().__init__(location) + self._typ = content_type self.field = field + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -202,14 +239,19 @@ def call( if args: raise CodeError("Unexpected/unhandled arguments", location) expr = StateGetEx(field=self.field, source_location=location) - return TupleExpressionBuilder(expr) + result_typ = pytypes.GenericTupleType.parameterise([self._typ, pytypes.BoolType], location) + return TupleExpressionBuilder(expr, result_typ) -class AppStateGetExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, field: AppStateExpression, location: SourceLocation) -> None: +class _Get(FunctionBuilder): + def __init__( + self, field: AppStateExpression, content_type: pytypes.PyType, location: SourceLocation + ) -> None: super().__init__(location) self.field = field + self.content_type = content_type + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -221,17 +263,14 @@ def call( if len(args) != 1: raise CodeError(f"Expected 1 argument, got {len(args)}", location) (default_arg,) = args - default_expr = expect_operand_wtype(default_arg, target_wtype=self.field.wtype) + default_expr = expect_operand_wtype(default_arg, target_wtype=self.content_type.wtype) expr = StateGet(field=self.field, default=default_expr, source_location=location) - return var_expression(expr) + return builder_for_instance(self.content_type, expr) class AppStateValueExpressionBuilder(ValueProxyExpressionBuilder): - expr: AppStateExpression - - def __init__(self, expr: AppStateExpression): - self.wtype = expr.wtype - super().__init__(expr) + expr: AppStateExpression # TODO: remove "lies" + @typing.override def delete(self, location: SourceLocation) -> Statement: return StateDelete(field=self.expr, source_location=location) diff --git a/src/puya/awst_build/eb/arc4/_utils.py b/src/puya/awst_build/eb/arc4/_utils.py index e20f59c0b..81d63f7c8 100644 --- a/src/puya/awst_build/eb/arc4/_utils.py +++ b/src/puya/awst_build/eb/arc4/_utils.py @@ -16,7 +16,7 @@ from puya.awst_build.arc4_utils import arc4_encode from puya.awst_build.eb.base import ExpressionBuilder from puya.awst_build.utils import convert_literal -from puya.errors import CodeError +from puya.errors import CodeError, InternalError if typing.TYPE_CHECKING: from collections.abc import Sequence @@ -29,7 +29,7 @@ def convert_arc4_literal( literal: awst_nodes.Literal, - target_wtype: wtypes.ARC4Type, + target_wtype: wtypes.WType, loc: SourceLocation | None = None, ) -> awst_nodes.Expression: literal_value: typing.Any = literal.value @@ -63,47 +63,43 @@ def convert_arc4_literal( raise CodeError( f"Too many decimals, expected max of {fixed_wtype.m}", loc ) from ex - return DecimalConstant( - source_location=loc, - value=q, - wtype=fixed_wtype, - ) + return DecimalConstant(value=q, wtype=fixed_wtype, source_location=loc) case wtypes.arc4_dynamic_bytes: - return awst_nodes.ARC4Encode( - value=awst_nodes.BytesConstant( - value=literal_value, - source_location=loc, - encoding=awst_nodes.BytesEncoding.unknown, - ), + native_value: Expression = awst_nodes.BytesConstant( + value=literal_value, source_location=loc, - wtype=target_wtype, + encoding=awst_nodes.BytesEncoding.unknown, ) - case wtypes.arc4_string_wtype: - if isinstance(literal_value, str): - try: - literal_bytes = literal_value.encode("utf8") - except ValueError: - pass - else: - return awst_nodes.ARC4Encode( - value=awst_nodes.BytesConstant( - value=literal_bytes, - source_location=loc, - encoding=awst_nodes.BytesEncoding.utf8, - ), - source_location=loc, - wtype=target_wtype, - ) - case wtypes.arc4_bool_wtype: - return awst_nodes.ARC4Encode( - value=awst_nodes.BoolConstant( - value=literal_value, + case wtypes.arc4_string_wtype if isinstance(literal_value, str): + try: + literal_bytes = literal_value.encode("utf8") + except ValueError as ex: + raise CodeError(f"Can't UTF8 encode {literal_value!r}", loc) from ex + else: + native_value = awst_nodes.BytesConstant( + value=literal_bytes, + encoding=awst_nodes.BytesEncoding.utf8, source_location=loc, - ), + ) + case wtypes.arc4_bool_wtype: + native_value = awst_nodes.BoolConstant( + value=literal_value, source_location=loc, - wtype=target_wtype, ) - raise CodeError(f"Can't construct {target_wtype} from Python literal {literal_value}", loc) + + case wtypes.ARC4Type(): + raise CodeError( + f"Can't construct {target_wtype} from Python literal {literal_value}", loc + ) + case _: + raise InternalError( + f"Expected arc4 type for literal conversion target, got: {target_wtype}", loc + ) + return awst_nodes.ARC4Encode( + value=native_value, + wtype=target_wtype, + source_location=loc, + ) def expect_arc4_operand_wtype( diff --git a/src/puya/awst_build/eb/arc4/abi_call.py b/src/puya/awst_build/eb/arc4/abi_call.py index 12ae66485..05245fd45 100644 --- a/src/puya/awst_build/eb/arc4/abi_call.py +++ b/src/puya/awst_build/eb/arc4/abi_call.py @@ -36,11 +36,16 @@ get_arc4_args_and_signature, ) from puya.awst_build.eb.arc4.base import ARC4FromLogBuilder -from puya.awst_build.eb.base import ExpressionBuilder, IntermediateExpressionBuilder +from puya.awst_build.eb.base import ( + ExpressionBuilder, + FunctionBuilder, + TypeClassExpressionBuilder, +) from puya.awst_build.eb.subroutine import BaseClassSubroutineInvokerExpressionBuilder +from puya.awst_build.eb.transaction import InnerTransactionExpressionBuilder from puya.awst_build.eb.transaction.fields import get_field_python_name from puya.awst_build.eb.transaction.inner_params import get_field_expr -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.tuple import TupleExpressionBuilder from puya.awst_build.utils import get_decorators_by_fullname, resolve_method_from_type_info from puya.errors import CodeError, InternalError @@ -75,14 +80,15 @@ } -class ARC4ClientClassExpressionBuilder(IntermediateExpressionBuilder): +class ARC4ClientClassExpressionBuilder(TypeClassExpressionBuilder): def __init__( self, context: ASTConversionModuleContext, + typ: pytypes.PyType, source_location: SourceLocation, type_info: mypy.nodes.TypeInfo, ): - super().__init__(source_location) + super().__init__(typ, source_location) self.context = context self.type_info = type_info @@ -105,7 +111,7 @@ def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilde return ARC4ClientMethodExpressionBuilder(self.context, func_or_dec, location) -class ARC4ClientMethodExpressionBuilder(IntermediateExpressionBuilder): +class ARC4ClientMethodExpressionBuilder(FunctionBuilder): def __init__( self, context: ASTConversionModuleContext, # TODO: yeet me @@ -130,7 +136,7 @@ def call( ) -class ABICallGenericClassExpressionBuilder(IntermediateExpressionBuilder): +class ABICallGenericClassExpressionBuilder(FunctionBuilder): @typing.override def call( self, @@ -143,7 +149,7 @@ def call( return _abi_call(args, arg_typs, arg_kinds, arg_names, location, abi_return_type=None) -class ABICallClassExpressionBuilder(IntermediateExpressionBuilder): +class ABICallClassExpressionBuilder(FunctionBuilder): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.PseudoGenericFunctionType) self.abi_return_type = typ.return_type @@ -224,14 +230,12 @@ def _abi_call( location, ) - return var_expression( - _create_abi_call_expr( - signature, - arc4_args, - abi_return_type, - abi_call_expr.transaction_kwargs, - location, - ) + return _create_abi_call_expr( + signature, + arc4_args, + abi_return_type, + abi_call_expr.transaction_kwargs, + location, ) @@ -277,7 +281,7 @@ def _create_abi_call_expr( declared_result_pytype: pytypes.PyType | None, transaction_kwargs: dict[str, ExpressionBuilder | Literal], location: SourceLocation, -) -> Expression: +) -> ExpressionBuilder: if signature.return_type is None: raise InternalError("Expected ARC4Signature.return_type to be defined", location) abi_arg_exprs: list[Expression] = [ @@ -356,6 +360,7 @@ def append_ref_arg(ref_list: list[Expression], arg_expr: Expression) -> None: bad_args = "', '".join(transaction_kwargs) raise CodeError(f"Unknown arguments: '{bad_args}'", location) + itxn_result_pytype = pytypes.InnerTransactionResultTypes[constants.TransactionType.appl] create_itxn = CreateInnerTransaction( fields=fields, wtype=wtypes.WInnerTransactionFields.from_type(constants.TransactionType.appl), @@ -364,11 +369,11 @@ def append_ref_arg(ref_list: list[Expression], arg_expr: Expression) -> None: itxn = SubmitInnerTransaction( itxns=(create_itxn,), source_location=location, - wtype=wtypes.WInnerTransaction.from_type(constants.TransactionType.appl), + wtype=itxn_result_pytype.wtype, ) if not _is_typed(declared_result_pytype): - return itxn + return InnerTransactionExpressionBuilder(itxn, itxn_result_pytype) itxn_tmp = SingleEvaluation(itxn) last_log = InnerTransactionField( source_location=location, @@ -376,9 +381,7 @@ def append_ref_arg(ref_list: list[Expression], arg_expr: Expression) -> None: field=TxnFields.last_log, wtype=TxnFields.last_log.wtype, ) - abi_result = ARC4FromLogBuilder.abi_expr_from_log( - signature.return_type.wtype, last_log, location - ) + abi_result = ARC4FromLogBuilder.abi_expr_from_log(signature.return_type, last_log, location) # the declared result wtype may be different to the arc4 signature return wtype # due to automatic conversion of ARC4 -> native types if declared_result_pytype != signature.return_type: @@ -395,13 +398,12 @@ def append_ref_arg(ref_list: list[Expression], arg_expr: Expression) -> None: else: raise InternalError("Return type does not match signature type", location) - return TupleExpression.from_items( - ( - abi_result, - itxn_tmp, - ), - location, + result_pytype = pytypes.GenericTupleType.parameterise( + [declared_result_pytype, itxn_result_pytype], location ) + tuple_expr = TupleExpression.from_items((abi_result, itxn_tmp), location) + assert tuple_expr.wtype == result_pytype.wtype # TODO: fixme + return TupleExpressionBuilder(tuple_expr, result_pytype) def _add_array_exprs( diff --git a/src/puya/awst_build/eb/arc4/arrays.py b/src/puya/awst_build/eb/arc4/arrays.py index 529c282a3..c46aeb56b 100644 --- a/src/puya/awst_build/eb/arc4/arrays.py +++ b/src/puya/awst_build/eb/arc4/arrays.py @@ -3,7 +3,7 @@ import typing from abc import ABC -from puya import arc4_util, log +from puya import log from puya.algo_constants import ENCODED_ADDRESS_LENGTH from puya.awst import wtypes from puya.awst.nodes import ( @@ -33,17 +33,13 @@ from puya.awst_build import intrinsic_factory, pytypes from puya.awst_build.eb._utils import bool_eval_to_constant, get_bytes_expr, get_bytes_expr_builder from puya.awst_build.eb.arc4._utils import expect_arc4_operand_wtype -from puya.awst_build.eb.arc4.base import ( - CopyBuilder, - arc4_bool_bytes, - arc4_compare_bytes, -) +from puya.awst_build.eb.arc4.base import CopyBuilder, arc4_bool_bytes, arc4_compare_bytes from puya.awst_build.eb.base import ( BuilderBinaryOp, BuilderComparisonOp, ExpressionBuilder, + FunctionBuilder, GenericClassExpressionBuilder, - IntermediateExpressionBuilder, Iteration, ValueExpressionBuilder, ) @@ -51,10 +47,10 @@ from puya.awst_build.eb.bytes_backed import BytesBackedClassExpressionBuilder from puya.awst_build.eb.reference_types.account import AccountExpressionBuilder from puya.awst_build.eb.uint64 import UInt64ExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.eb.void import VoidExpressionBuilder from puya.awst_build.utils import expect_operand_wtype, require_expression_builder -from puya.errors import CodeError, InternalError +from puya.errors import CodeError if typing.TYPE_CHECKING: from collections.abc import Sequence @@ -82,31 +78,28 @@ def call( require_expression_builder(a, msg="Array arguments must be non literals").rvalue() for a in args ] - element_wtype = non_literal_args[0].wtype - wtype = arc4_util.make_dynamic_array_wtype(element_wtype, location) + element_type = arg_typs[0] for a in non_literal_args: - expect_operand_wtype(a, wtype.element_type) + expect_operand_wtype(a, element_type.wtype) + typ = pytypes.GenericARC4DynamicArrayType.parameterise([element_type], location) + wtype = typ.wtype + assert isinstance(wtype, wtypes.ARC4DynamicArray) return DynamicArrayExpressionBuilder( - NewArray( - source_location=location, - values=tuple(non_literal_args), - wtype=wtype, - ) + NewArray(values=tuple(non_literal_args), wtype=wtype, source_location=location), typ ) -class DynamicArrayClassExpressionBuilder( - BytesBackedClassExpressionBuilder[wtypes.ARC4DynamicArray] -): +class DynamicArrayClassExpressionBuilder(BytesBackedClassExpressionBuilder[pytypes.ArrayType]): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.ArrayType) assert typ.generic == pytypes.GenericARC4DynamicArrayType assert typ.size is None wtype = typ.wtype assert isinstance(wtype, wtypes.ARC4DynamicArray) - super().__init__(wtype, location) + self._wtype = wtype + super().__init__(typ, location) @typing.override def call( @@ -121,16 +114,13 @@ def call( require_expression_builder(a, msg="Array arguments must be non literals").rvalue() for a in args ] - wtype = self.produces() + wtype = self._wtype for a in non_literal_args: expect_operand_wtype(a, wtype.element_type) return DynamicArrayExpressionBuilder( - NewArray( - source_location=location, - values=tuple(non_literal_args), - wtype=wtype, - ) + NewArray(values=tuple(non_literal_args), wtype=wtype, source_location=location), + self._pytype, ) @@ -150,30 +140,36 @@ def call( require_expression_builder(a, msg="Array arguments must be non literals").rvalue() for a in args ] - element_wtype = non_literal_args[0].wtype + element_type = arg_typs[0] array_size = len(non_literal_args) - wtype = arc4_util.make_static_array_wtype(element_wtype, array_size, location) + typ = pytypes.GenericARC4StaticArrayType.parameterise( + [element_type, pytypes.TypingLiteralType(value=array_size, source_location=None)], + location, + ) for a in non_literal_args: - expect_operand_wtype(a, wtype.element_type) - + expect_operand_wtype(a, element_type.wtype) + wtype = typ.wtype + assert isinstance(wtype, wtypes.ARC4StaticArray) return StaticArrayExpressionBuilder( NewArray( source_location=location, values=tuple(non_literal_args), wtype=wtype, - ) + ), + typ, ) -class StaticArrayClassExpressionBuilder(BytesBackedClassExpressionBuilder[wtypes.ARC4StaticArray]): +class StaticArrayClassExpressionBuilder(BytesBackedClassExpressionBuilder[pytypes.ArrayType]): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.ArrayType) assert typ.generic == pytypes.GenericARC4StaticArrayType assert typ.size is not None wtype = typ.wtype assert isinstance(wtype, wtypes.ARC4StaticArray) - super().__init__(wtype, location) + self._wtype = wtype + super().__init__(typ, location) @typing.override def call( @@ -188,7 +184,7 @@ def call( require_expression_builder(a, msg="Array arguments must be non literals").rvalue() for a in args ] - wtype = self.produces() + wtype = self._wtype if wtype.array_size != len(non_literal_args): raise CodeError( f"StaticArray should be initialized with {wtype.array_size} values", @@ -199,18 +195,14 @@ def call( expect_operand_wtype(a, wtype.element_type) return StaticArrayExpressionBuilder( - NewArray( - source_location=location, - values=tuple(non_literal_args), - wtype=wtype, - ) + NewArray(values=tuple(non_literal_args), wtype=wtype, source_location=location), + self.produces2(), ) -class AddressClassExpressionBuilder(BytesBackedClassExpressionBuilder[wtypes.ARC4StaticArray]): - +class AddressClassExpressionBuilder(BytesBackedClassExpressionBuilder[pytypes.ArrayType]): def __init__(self, location: SourceLocation): - super().__init__(wtypes.arc4_address_type, location) + super().__init__(pytypes.ARC4AddressType, location) @typing.override def call( @@ -257,16 +249,19 @@ def call( f" {wtypes.account_wtype} or {wtypes.bytes_wtype}, or a string literal", location=location, ) - return StaticArrayExpressionBuilder( + return AddressExpressionBuilder( ReinterpretCast(expr=address_bytes, wtype=wtype, source_location=location) ) -class ARC4ArrayExpressionBuilder(ValueExpressionBuilder, ABC): - wtype: wtypes.ARC4DynamicArray | wtypes.ARC4StaticArray +class _ARC4ArrayExpressionBuilder(ValueExpressionBuilder[pytypes.ArrayType], ABC): + def __init__(self, expr: Expression, typ: pytypes.ArrayType): + self.pytyp = typ + super().__init__(typ, expr) + @typing.override def iterate(self) -> Iteration: - if not self.wtype.element_type.immutable: + if not self.pytype.items.wtype.immutable: logger.error( "Cannot directly iterate an ARC4 array of mutable objects," " construct a for-loop over the indexes via urange(.length) instead", @@ -274,6 +269,7 @@ def iterate(self) -> Iteration: ) return self.rvalue() + @typing.override def index( self, index: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: @@ -290,39 +286,38 @@ def index( ) else: index_expr = expect_operand_wtype(index, wtypes.uint64_wtype) - return var_expression( - IndexExpression( - source_location=location, - base=self.expr, - index=index_expr, - wtype=self.wtype.element_type, - ) + result_expr = IndexExpression( + base=self.expr, + index=index_expr, + wtype=self.pytype.items.wtype, + source_location=location, ) + return builder_for_instance(self.pytyp.items, result_expr) + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "bytes": return get_bytes_expr_builder(self.expr) case "copy": - return CopyBuilder(self.expr, location) + return CopyBuilder(self.expr, location, self.pytyp) case _: return super().member_access(name, location) + @typing.override def compare( self, other: ExpressionBuilder | Literal, op: BuilderComparisonOp, location: SourceLocation ) -> ExpressionBuilder: return arc4_compare_bytes(self, op, other, location) -class DynamicArrayExpressionBuilder(ARC4ArrayExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.ARC4DynamicArray) - self.wtype: wtypes.ARC4DynamicArray = expr.wtype - super().__init__(expr) +class DynamicArrayExpressionBuilder(_ARC4ArrayExpressionBuilder): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.ArrayType) + super().__init__(expr, typ) + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: - match name: case "length": return UInt64ExpressionBuilder( @@ -334,14 +329,15 @@ def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilde ) ) case "append": - return AppendExpressionBuilder(self.expr, location) + return _Append(self.expr, self.pytyp, location) case "extend": - return ExtendExpressionBuilder(self.expr, location) + return _Extend(self.expr, self.pytyp, location) case "pop": - return PopExpressionBuilder(self.expr, location) + return _Pop(self.expr, self.pytyp, location) case _: return super().member_access(name, location) + @typing.override def augmented_assignment( self, op: BuilderBinaryOp, rhs: ExpressionBuilder | Literal, location: SourceLocation ) -> Statement: @@ -352,10 +348,10 @@ def augmented_assignment( base=self.expr, other=match_array_concat_arg( (rhs,), - self.wtype.element_type, + self.pytype.items.wtype, source_location=location, msg="Array concat expects array or tuple of the same element type. " - f"Element type: {self.wtype.element_type}", + f"Element type: {self.pytype.items}", ), source_location=location, wtype=wtypes.arc4_string_wtype, @@ -364,6 +360,7 @@ def augmented_assignment( case _: return super().augmented_assignment(op, rhs, location) + @typing.override def binary_op( self, other: ExpressionBuilder | Literal, @@ -377,10 +374,10 @@ def binary_op( lhs = self.expr rhs = match_array_concat_arg( (other,), - self.wtype.element_type, + self.pytype.items.wtype, source_location=location, msg="Array concat expects array or tuple of the same element type. " - f"Element type: {self.wtype.element_type}", + f"Element type: {self.pytype.items}", ) if reverse: @@ -391,12 +388,14 @@ def binary_op( right=rhs, source_location=location, wtype=self.wtype, - ) + ), + self.pytyp, ) case _: return super().binary_op(other, op, location, reverse=reverse) + @typing.override def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: return arc4_bool_bytes( expr=self.expr, @@ -406,16 +405,13 @@ def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> Expres ) -class AppendExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, expr: Expression, location: SourceLocation): +class _Append(FunctionBuilder): + def __init__(self, expr: Expression, typ: pytypes.ArrayType, location: SourceLocation): super().__init__(location) self.expr = expr - if not isinstance(expr.wtype, wtypes.ARC4DynamicArray): - raise InternalError( - "AppendExpressionBuilder can only be instantiated with an arc4.DynamicArray" - ) - self.wtype: wtypes.ARC4DynamicArray = expr.wtype + self.typ = typ + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -425,7 +421,7 @@ def call( location: SourceLocation, ) -> ExpressionBuilder: - args_expr = [expect_arc4_operand_wtype(a, self.wtype.element_type) for a in args] + args_expr = [expect_arc4_operand_wtype(a, self.typ.items.wtype) for a in args] args_tuple = TupleExpression.from_items(args_expr, location) return VoidExpressionBuilder( ArrayExtend( @@ -437,16 +433,13 @@ def call( ) -class PopExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, expr: Expression, location: SourceLocation): +class _Pop(FunctionBuilder): + def __init__(self, expr: Expression, typ: pytypes.ArrayType, location: SourceLocation): super().__init__(location) self.expr = expr - if not isinstance(expr.wtype, wtypes.ARC4DynamicArray): - raise InternalError( - "AppendExpressionBuilder can only be instantiated with an arc4.DynamicArray" - ) - self.wtype: wtypes.ARC4DynamicArray = expr.wtype + self.typ = typ + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -457,25 +450,21 @@ def call( ) -> ExpressionBuilder: match args: case []: - return var_expression( - ArrayPop( - base=self.expr, source_location=location, wtype=self.wtype.element_type - ) + result_expr = ArrayPop( + base=self.expr, source_location=location, wtype=self.typ.items.wtype ) + return builder_for_instance(self.typ.items, result_expr) case _: raise CodeError("Invalid/Unhandled arguments", location) -class ExtendExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, expr: Expression, location: SourceLocation): +class _Extend(FunctionBuilder): + def __init__(self, expr: Expression, typ: pytypes.ArrayType, location: SourceLocation): super().__init__(location) self.expr = expr - if not isinstance(expr.wtype, wtypes.ARC4DynamicArray): - raise InternalError( - "AppendExpressionBuilder can only be instantiated with an arc4.DynamicArray" - ) - self.wtype: wtypes.ARC4DynamicArray = expr.wtype + self.typ = typ + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -486,10 +475,10 @@ def call( ) -> ExpressionBuilder: other = match_array_concat_arg( args, - self.wtype.element_type, + self.typ.items.wtype, source_location=location, msg="Extend expects an arc4.StaticArray or arc4.DynamicArray of the same element " - f"type. Expected array or tuple of {self.wtype.element_type}", + f"type. Expected array or tuple of {self.typ.items}", ) return VoidExpressionBuilder( ArrayExtend( @@ -521,42 +510,48 @@ def match_array_concat_arg( raise CodeError(msg, source_location) -class StaticArrayExpressionBuilder(ARC4ArrayExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.ARC4StaticArray) - self.wtype: wtypes.ARC4StaticArray = expr.wtype - super().__init__(expr) +class StaticArrayExpressionBuilder(_ARC4ArrayExpressionBuilder): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.ArrayType) + size = typ.size + assert size is not None + self._size = size + super().__init__(expr, typ) + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "length": return UInt64ExpressionBuilder( - UInt64Constant(value=self.wtype.array_size, source_location=location) + UInt64Constant(value=self._size, source_location=location) ) case _: return super().member_access(name, location) + @typing.override def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: - if self.wtype.alias != "address": - return bool_eval_to_constant( - value=self.wtype.array_size > 0, location=location, negate=negate - ) - else: - cmp_with_zero_expr = BytesComparisonExpression( - lhs=get_bytes_expr(self.expr), - operator=EqualityComparison.eq if negate else EqualityComparison.ne, - rhs=intrinsic_factory.zero_address(location, as_type=wtypes.bytes_wtype), - source_location=location, - ) + return bool_eval_to_constant(value=self._size > 0, location=location, negate=negate) + + +class AddressExpressionBuilder(StaticArrayExpressionBuilder): + def __init__(self, expr: Expression): + super().__init__(expr, pytypes.ARC4AddressType) + + @typing.override + def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: + cmp_with_zero_expr = BytesComparisonExpression( + lhs=get_bytes_expr(self.expr), + operator=EqualityComparison.eq if negate else EqualityComparison.ne, + rhs=intrinsic_factory.zero_address(location, as_type=wtypes.bytes_wtype), + source_location=location, + ) - return BoolExpressionBuilder(cmp_with_zero_expr) + return BoolExpressionBuilder(cmp_with_zero_expr) + @typing.override def compare( self, other: ExpressionBuilder | Literal, op: BuilderComparisonOp, location: SourceLocation ) -> ExpressionBuilder: - if self.wtype.alias != "address": - return super().compare(other, op=op, location=location) match other: case Literal(value=str(str_value), source_location=literal_loc): rhs = get_bytes_expr(AddressConstant(value=str_value, source_location=literal_loc)) @@ -572,8 +567,7 @@ def compare( ) return BoolExpressionBuilder(cmp_expr) - -class AddressExpressionBuilder(StaticArrayExpressionBuilder): + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "native": diff --git a/src/puya/awst_build/eb/arc4/base.py b/src/puya/awst_build/eb/arc4/base.py index 73cbe9e4d..4421e6bed 100644 --- a/src/puya/awst_build/eb/arc4/base.py +++ b/src/puya/awst_build/eb/arc4/base.py @@ -26,13 +26,13 @@ from puya.awst_build.eb.base import ( BuilderComparisonOp, ExpressionBuilder, - IntermediateExpressionBuilder, + FunctionBuilder, ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder from puya.awst_build.eb.bytes_backed import BytesBackedClassExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression -from puya.errors import CodeError, InternalError +from puya.awst_build.eb.var_factory import builder_for_instance +from puya.errors import CodeError if typing.TYPE_CHECKING: from collections.abc import Sequence @@ -44,16 +44,16 @@ logger = log.get_logger(__name__) -_TARC4Type = typing_extensions.TypeVar( - "_TARC4Type", bound=wtypes.ARC4Type, default=wtypes.ARC4Type +_TPyType_co = typing_extensions.TypeVar( + "_TPyType_co", bound=pytypes.PyType, default=pytypes.PyType, covariant=True ) -class ARC4ClassExpressionBuilder(BytesBackedClassExpressionBuilder[_TARC4Type], abc.ABC): +class ARC4ClassExpressionBuilder(BytesBackedClassExpressionBuilder[_TPyType_co], abc.ABC): def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: match name: case "from_log": - return ARC4FromLogBuilder(location, self.produces()) + return ARC4FromLogBuilder(location, self.produces2()) case _: return super().member_access(name, location) @@ -66,14 +66,14 @@ def get_integer_literal_value(eb_or_literal: ExpressionBuilder | Literal, purpos raise CodeError(f"{purpose} must be compile time constant") -class ARC4FromLogBuilder(IntermediateExpressionBuilder): - def __init__(self, location: SourceLocation, wtype: wtypes.WType): +class ARC4FromLogBuilder(FunctionBuilder): + def __init__(self, location: SourceLocation, typ: pytypes.PyType): super().__init__(location=location) - self.wtype = wtype + self.typ = typ @classmethod def abi_expr_from_log( - cls, wtype: wtypes.WType, value: Expression, location: SourceLocation + cls, typ: pytypes.PyType, value: Expression, location: SourceLocation ) -> Expression: tmp_value = SingleEvaluation(value) arc4_value = intrinsic_factory.extract(tmp_value, start=4, loc=location) @@ -97,11 +97,12 @@ def abi_expr_from_log( comment="ARC4 prefix is valid", ) return ReinterpretCast( - source_location=location, expr=checked_arc4_value, - wtype=wtype, + wtype=typ.wtype, + source_location=location, ) + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -112,16 +113,19 @@ def call( ) -> ExpressionBuilder: match args: case [ExpressionBuilder() as eb]: - return var_expression(self.abi_expr_from_log(self.wtype, eb.rvalue(), location)) + result_expr = self.abi_expr_from_log(self.typ, eb.rvalue(), location) + return builder_for_instance(self.typ, result_expr) case _: raise CodeError("Invalid/unhandled arguments", location) -class CopyBuilder(IntermediateExpressionBuilder): - def __init__(self, expr: Expression, location: SourceLocation): +class CopyBuilder(FunctionBuilder): + def __init__(self, expr: Expression, location: SourceLocation, typ: pytypes.PyType): + self._typ = typ super().__init__(location) self.expr = expr + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -132,45 +136,40 @@ def call( ) -> ExpressionBuilder: match args: case []: - return var_expression( - Copy(value=self.expr, wtype=self.expr.wtype, source_location=location) + expr_result = Copy( + value=self.expr, wtype=self.expr.wtype, source_location=location ) + return builder_for_instance(self._typ, expr_result) raise CodeError("Invalid/Unexpected arguments", location) -def native_eb(expr: Expression, location: SourceLocation) -> ExpressionBuilder: - # TODO: could determine EB here instead of using var_expression - match expr.wtype: - case wtypes.arc4_string_wtype | wtypes.arc4_dynamic_bytes | wtypes.arc4_bool_wtype: - pass - case wtypes.ARC4UIntN() | wtypes.ARC4UFixedNxM() | wtypes.ARC4Tuple(): - pass - case _: - raise InternalError("Unsupported wtype for ARC4Decode", location) - return var_expression( - ARC4Decode( - source_location=location, - value=expr, - wtype=wtypes.arc4_to_avm_equivalent_wtype(expr.wtype, location), - ) - ) - +class ARC4EncodedExpressionBuilder(ValueExpressionBuilder[_TPyType_co], abc.ABC): + def __init__(self, pytype: _TPyType_co, expr: Expression, native_pytype: pytypes.PyType): + super().__init__(pytype, expr) + self._native_pytype = native_pytype -class ARC4EncodedExpressionBuilder(ValueExpressionBuilder, abc.ABC): - def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: + @typing.override + def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "native": - return native_eb(self.expr, location) + result_expr: Expression = ARC4Decode( + value=self.expr, + wtype=self._native_pytype.wtype, + source_location=location, + ) + return builder_for_instance(self._native_pytype, result_expr) case "bytes": return get_bytes_expr_builder(self.expr) case _: - raise CodeError(f"Unrecognised member of bytes: {name}", location) + return super().member_access(name, location) + @typing.override def compare( self, other: ExpressionBuilder | Literal, op: BuilderComparisonOp, location: SourceLocation ) -> ExpressionBuilder: return arc4_compare_bytes(self, op, other, location) + @typing.override @abc.abstractmethod def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: # TODO: lift this up to ValueExpressionBuilder diff --git a/src/puya/awst_build/eb/arc4/bool.py b/src/puya/awst_build/eb/arc4/bool.py index 5169e65f6..0b5df646a 100644 --- a/src/puya/awst_build/eb/arc4/bool.py +++ b/src/puya/awst_build/eb/arc4/bool.py @@ -5,6 +5,7 @@ from puya import log from puya.awst import wtypes from puya.awst.nodes import ARC4Encode, BoolConstant, Expression, Literal +from puya.awst_build import pytypes from puya.awst_build.eb.arc4.base import ( ARC4ClassExpressionBuilder, ARC4EncodedExpressionBuilder, @@ -18,10 +19,7 @@ import mypy.nodes - from puya.awst_build import pytypes - from puya.awst_build.eb.base import ( - ExpressionBuilder, - ) + from puya.awst_build.eb.base import ExpressionBuilder from puya.parse import SourceLocation logger = log.get_logger(__name__) @@ -29,7 +27,7 @@ class ARC4BoolClassExpressionBuilder(ARC4ClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.arc4_bool_wtype, location) + super().__init__(pytypes.ARC4BoolType, location) @typing.override def call( @@ -49,17 +47,16 @@ def call( raise CodeError( f"arc4.Bool expects exactly one parameter of type {wtypes.bool_wtype}" ) + wtype = self.produces() + assert isinstance(wtype, wtypes.ARC4Type) return ARC4BoolExpressionBuilder( - ARC4Encode( - value=native_bool, - source_location=location, - wtype=self.produces(), - ) + ARC4Encode(value=native_bool, wtype=wtype, source_location=location) ) class ARC4BoolExpressionBuilder(ARC4EncodedExpressionBuilder): - wtype = wtypes.arc4_bool_wtype + def __init__(self, expr: Expression): + super().__init__(pytypes.ARC4BoolType, expr, native_pytype=pytypes.BoolType) def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: return arc4_bool_bytes(self.expr, false_bytes=b"\x00", location=location, negate=negate) diff --git a/src/puya/awst_build/eb/arc4/dynamic_bytes.py b/src/puya/awst_build/eb/arc4/dynamic_bytes.py index b61e6cacc..72a66bd8e 100644 --- a/src/puya/awst_build/eb/arc4/dynamic_bytes.py +++ b/src/puya/awst_build/eb/arc4/dynamic_bytes.py @@ -3,11 +3,13 @@ import typing from puya.awst import wtypes -from puya.awst.nodes import ARC4Encode, Literal, NewArray, ReinterpretCast +from puya.awst.nodes import ARC4Encode, Expression, Literal, NewArray, ReinterpretCast +from puya.awst_build import pytypes +from puya.awst_build.arc4_utils import arc4_decode from puya.awst_build.eb.arc4._utils import convert_arc4_literal from puya.awst_build.eb.arc4.arrays import DynamicArrayExpressionBuilder -from puya.awst_build.eb.arc4.base import native_eb from puya.awst_build.eb.base import ExpressionBuilder +from puya.awst_build.eb.bytes import BytesExpressionBuilder from puya.awst_build.eb.bytes_backed import BytesBackedClassExpressionBuilder from puya.errors import CodeError @@ -16,15 +18,12 @@ import mypy.nodes - from puya.awst_build import pytypes from puya.parse import SourceLocation -class DynamicBytesClassExpressionBuilder( - BytesBackedClassExpressionBuilder[wtypes.ARC4DynamicArray] -): +class DynamicBytesClassExpressionBuilder(BytesBackedClassExpressionBuilder[pytypes.ArrayType]): def __init__(self, location: SourceLocation): - super().__init__(location=location, wtype=wtypes.arc4_dynamic_bytes) + super().__init__(pytypes.ARC4DynamicBytesType, location) @typing.override def call( @@ -35,49 +34,47 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: + wtype = self.produces() + assert isinstance(wtype, wtypes.ARC4DynamicArray) match args: case [Literal(value=bytes()) as literal]: return DynamicBytesExpressionBuilder( - convert_arc4_literal(literal, self.produces(), location) + convert_arc4_literal(literal, wtype, location) ) case [ExpressionBuilder(value_type=wtypes.bytes_wtype) as eb]: return DynamicBytesExpressionBuilder( - ARC4Encode(value=eb.rvalue(), source_location=location, wtype=self.produces()) + ARC4Encode(value=eb.rvalue(), source_location=location, wtype=wtype) ) - non_literal_args = tuple(_coerce_to_byte(a).rvalue() for a in args) - wtype = self.produces() + non_literal_args = tuple(_coerce_to_byte(a) for a in args) return DynamicBytesExpressionBuilder( NewArray(values=non_literal_args, wtype=wtype, source_location=location) ) -def _coerce_to_byte(arg: ExpressionBuilder | Literal) -> ExpressionBuilder: - from puya.awst_build.eb.arc4 import UIntNExpressionBuilder - +def _coerce_to_byte(arg: ExpressionBuilder | Literal) -> Expression: match arg: case Literal(value=int()) as literal: - return UIntNExpressionBuilder(convert_arc4_literal(literal, wtypes.arc4_byte_type)) + return convert_arc4_literal(literal, wtypes.arc4_byte_type) case ExpressionBuilder(value_type=wtypes.ARC4UIntN(n=8) as wtype) as eb: if wtype != wtypes.arc4_byte_type: - return UIntNExpressionBuilder( - ReinterpretCast( - expr=arg.rvalue(), - wtype=wtypes.arc4_byte_type, - source_location=arg.source_location, - ) + return ReinterpretCast( + expr=arg.rvalue(), + wtype=wtypes.arc4_byte_type, + source_location=arg.source_location, ) - return eb + return eb.rvalue() case _: raise CodeError("Expected a Byte, UInt64 or int type", arg.source_location) class DynamicBytesExpressionBuilder(DynamicArrayExpressionBuilder): - wtype = wtypes.arc4_dynamic_bytes + def __init__(self, expr: Expression): + super().__init__(expr, pytypes.ARC4DynamicBytesType) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "native": - return native_eb(self.expr, location) + return BytesExpressionBuilder(arc4_decode(self.expr, wtypes.bytes_wtype, location)) case _: return super().member_access(name, location) diff --git a/src/puya/awst_build/eb/arc4/emit.py b/src/puya/awst_build/eb/arc4/emit.py index a2ffa47f9..cdb6b5f73 100644 --- a/src/puya/awst_build/eb/arc4/emit.py +++ b/src/puya/awst_build/eb/arc4/emit.py @@ -1,24 +1,15 @@ from __future__ import annotations +import typing from typing import TYPE_CHECKING import mypy.nodes from puya.arc4_util import pytype_to_arc4, wtype_to_arc4 -from puya.awst import wtypes -from puya.awst.nodes import ( - Literal, - MethodConstant, -) +from puya.awst.nodes import Literal, MethodConstant from puya.awst_build import intrinsic_factory, pytypes -from puya.awst_build.eb.arc4._utils import ( - arc4_tuple_from_items, - get_arc4_args_and_signature, -) -from puya.awst_build.eb.base import ( - ExpressionBuilder, - IntermediateExpressionBuilder, -) +from puya.awst_build.eb.arc4._utils import arc4_tuple_from_items, get_arc4_args_and_signature +from puya.awst_build.eb.base import ExpressionBuilder, FunctionBuilder from puya.awst_build.eb.void import VoidExpressionBuilder from puya.errors import CodeError @@ -30,7 +21,8 @@ from puya.parse import SourceLocation -class EmitBuilder(IntermediateExpressionBuilder): +class EmitBuilder(FunctionBuilder): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -41,9 +33,9 @@ def call( ) -> ExpressionBuilder: match args: case [ - ExpressionBuilder(value_type=wtypes.ARC4Struct() as struct_type) as event_arg_eb - ]: - event_name = struct_type.stub_name.split(".")[-1] + ExpressionBuilder(pytype=pytypes.StructType() as struct_type) as event_arg_eb + ] if pytypes.ARC4StructBaseType in struct_type.mro: + event_name = struct_type.name.split(".")[-1] event_arg = event_arg_eb.rvalue() case [Literal(value=str(event_str)), *event_args]: arc4_args, signature = get_arc4_args_and_signature( diff --git a/src/puya/awst_build/eb/arc4/numeric.py b/src/puya/awst_build/eb/arc4/numeric.py index 0fd524493..725f56cca 100644 --- a/src/puya/awst_build/eb/arc4/numeric.py +++ b/src/puya/awst_build/eb/arc4/numeric.py @@ -36,11 +36,8 @@ logger = log.get_logger(__name__) +# TODO: tests for (attempted) use without generics class NumericARC4ClassExpressionBuilder(ARC4ClassExpressionBuilder, abc.ABC): - def __init__(self, wtype: wtypes.ARC4UIntN | wtypes.ARC4UFixedNxM, location: SourceLocation): - super().__init__(wtype, location) - self._wtype = wtype - @typing.override def call( self, @@ -51,6 +48,7 @@ def call( location: SourceLocation, ) -> ExpressionBuilder: wtype = self.produces() + assert isinstance(wtype, wtypes.ARC4UIntN | wtypes.ARC4UFixedNxM) match args: case []: zero_literal = Literal(value=self.zero_literal(), source_location=location) @@ -74,7 +72,7 @@ def call( "Invalid/unhandled arguments", location, ) - return self._value_builder()(expr) + return self._value_builder()(expr, self.produces2()) @classmethod @abc.abstractmethod @@ -82,66 +80,57 @@ def zero_literal(cls) -> ConstantValue: ... @classmethod @abc.abstractmethod - def _value_builder(cls) -> type[ARC4EncodedExpressionBuilder]: ... + def _value_builder(cls) -> type[UIntNExpressionBuilder | UFixedNxMExpressionBuilder]: ... class ByteClassExpressionBuilder(NumericARC4ClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.arc4_byte_type, location) + super().__init__(pytypes.ARC4ByteType, location) @classmethod def zero_literal(cls) -> ConstantValue: return 0 @classmethod - def _value_builder(cls) -> type[ARC4EncodedExpressionBuilder]: + def _value_builder(cls) -> type[UIntNExpressionBuilder]: return UIntNExpressionBuilder -class UIntNClassExpressionBuilder(NumericARC4ClassExpressionBuilder, abc.ABC): - def __init__(self, typ: pytypes.PyType, location: SourceLocation): - assert isinstance(typ, pytypes.ARC4UIntNType) - wtype = typ.wtype - assert isinstance(wtype, wtypes.ARC4UIntN) - super().__init__(wtype, location) - +class UIntNClassExpressionBuilder(NumericARC4ClassExpressionBuilder): @classmethod def zero_literal(cls) -> ConstantValue: return 0 @classmethod - def _value_builder(cls) -> type[ARC4EncodedExpressionBuilder]: + def _value_builder(cls) -> type[UIntNExpressionBuilder]: return UIntNExpressionBuilder class UFixedNxMClassExpressionBuilder(NumericARC4ClassExpressionBuilder): - def __init__(self, typ: pytypes.PyType, location: SourceLocation): - assert isinstance(typ, pytypes.ARC4UFixedNxMType) - wtype = typ.wtype - assert isinstance(wtype, wtypes.ARC4UFixedNxM) - super().__init__(wtype, location) - @classmethod def zero_literal(cls) -> ConstantValue: return "0.0" @classmethod - def _value_builder(cls) -> type[ARC4EncodedExpressionBuilder]: + def _value_builder(cls) -> type[UFixedNxMExpressionBuilder]: return UFixedNxMExpressionBuilder -class UIntNExpressionBuilder(ARC4EncodedExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.ARC4UIntN) - self.wtype: wtypes.ARC4UIntN = expr.wtype - super().__init__(expr) +class UIntNExpressionBuilder(ARC4EncodedExpressionBuilder[pytypes.ARC4UIntNType]): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.ARC4UIntNType) + if typ == pytypes.ARC4ByteType or typ.generic == pytypes.GenericARC4UIntNType: + native_pytype = pytypes.UInt64Type + else: + assert typ.generic == pytypes.GenericARC4BigUIntNType + native_pytype = pytypes.BigUIntType + super().__init__(typ, expr, native_pytype=native_pytype) def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: return arc4_bool_bytes( self.expr, - false_bytes=b"\x00" * (self.wtype.n // 8), + false_bytes=b"\x00" * (self.pytype.bits // 8), location=location, negate=negate, ) @@ -179,17 +168,20 @@ def compare( return BoolExpressionBuilder(cmp_expr) -class UFixedNxMExpressionBuilder(ARC4EncodedExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.ARC4UFixedNxM) - self.wtype: wtypes.ARC4UFixedNxM = expr.wtype - super().__init__(expr) +class UFixedNxMExpressionBuilder(ARC4EncodedExpressionBuilder[pytypes.ARC4UFixedNxMType]): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.ARC4UFixedNxMType) + if typ.generic == pytypes.GenericARC4UFixedNxMType: + native_pytype = pytypes.UInt64Type + else: + assert typ.generic == pytypes.GenericARC4BigUFixedNxMType + native_pytype = pytypes.BigUIntType + super().__init__(typ, expr, native_pytype=native_pytype) def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: return arc4_bool_bytes( self.expr, - false_bytes=b"\x00" * (self.wtype.n // 8), + false_bytes=b"\x00" * (self.pytype.bits // 8), location=location, negate=negate, ) diff --git a/src/puya/awst_build/eb/arc4/string.py b/src/puya/awst_build/eb/arc4/string.py index ecfddbb49..9f42556d6 100644 --- a/src/puya/awst_build/eb/arc4/string.py +++ b/src/puya/awst_build/eb/arc4/string.py @@ -18,6 +18,7 @@ Statement, StringConstant, ) +from puya.awst_build import pytypes from puya.awst_build.eb._utils import get_bytes_expr from puya.awst_build.eb.arc4.base import ( ARC4ClassExpressionBuilder, @@ -33,7 +34,6 @@ import mypy.nodes - from puya.awst_build import pytypes from puya.parse import SourceLocation logger = log.get_logger(__name__) @@ -41,7 +41,7 @@ class StringClassExpressionBuilder(ARC4ClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.arc4_string_wtype, location) + super().__init__(pytypes.ARC4StringType, location) @typing.override def call( @@ -91,7 +91,8 @@ def expect_string_or_bytes( class StringExpressionBuilder(ARC4EncodedExpressionBuilder): - wtype = wtypes.arc4_string_wtype + def __init__(self, expr: Expression): + super().__init__(pytypes.ARC4StringType, expr, native_pytype=pytypes.StringType) def augmented_assignment( self, op: BuilderBinaryOp, rhs: ExpressionBuilder | Literal, location: SourceLocation diff --git a/src/puya/awst_build/eb/arc4/struct.py b/src/puya/awst_build/eb/arc4/struct.py index de1f090ad..7a9af0904 100644 --- a/src/puya/awst_build/eb/arc4/struct.py +++ b/src/puya/awst_build/eb/arc4/struct.py @@ -10,7 +10,7 @@ from puya.awst_build.eb.arc4.base import CopyBuilder, arc4_compare_bytes from puya.awst_build.eb.base import BuilderComparisonOp, ExpressionBuilder, ValueExpressionBuilder from puya.awst_build.eb.bytes_backed import BytesBackedClassExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import get_arg_mapping, require_expression_builder from puya.errors import CodeError @@ -25,13 +25,14 @@ logger = log.get_logger(__name__) -class ARC4StructClassExpressionBuilder(BytesBackedClassExpressionBuilder[wtypes.ARC4Struct]): +class ARC4StructClassExpressionBuilder(BytesBackedClassExpressionBuilder[pytypes.StructType]): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.StructType) # assert pytypes.ARC4StructBaseType in typ.mro TODO? wtype = typ.wtype assert isinstance(wtype, wtypes.ARC4Struct) - super().__init__(wtype, location) + self._wtype = wtype + super().__init__(typ, location) @typing.override def call( @@ -42,7 +43,7 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: - wtype = self.produces() + wtype = self._wtype ordered_field_names = wtype.names field_mapping = get_arg_mapping( positional_arg_names=ordered_field_names, @@ -63,33 +64,29 @@ def call( raise CodeError(f"Unexpected keyword arguments: {' '.join(field_mapping)}", location) return ARC4StructExpressionBuilder( - NewStruct(wtype=wtype, values=values, source_location=location) + NewStruct(wtype=wtype, values=values, source_location=location), self.produces2() ) -class ARC4StructExpressionBuilder(ValueExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.ARC4Struct) - self.wtype: wtypes.ARC4Struct = expr.wtype - super().__init__(expr) +class ARC4StructExpressionBuilder(ValueExpressionBuilder[pytypes.StructType]): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.StructType) + super().__init__(typ, expr) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: - case field_name if field_name in self.wtype.fields: - # TODO: use pytype - return var_expression( - FieldExpression( - source_location=location, - base=self.expr, - name=field_name, - wtype=self.wtype.fields[field_name], - ) + case field_name if self.pytype and (field := self.pytype.fields.get(field_name)): + result_expr = FieldExpression( + base=self.expr, + name=field_name, + wtype=field.wtype, + source_location=location, ) + return builder_for_instance(field, result_expr) case "bytes": return get_bytes_expr_builder(self.expr) case "copy": - return CopyBuilder(self.expr, location) + return CopyBuilder(self.expr, location, self.pytype) case _: return super().member_access(name, location) diff --git a/src/puya/awst_build/eb/arc4/tuple.py b/src/puya/awst_build/eb/arc4/tuple.py index 42e4f3193..fe2d99882 100644 --- a/src/puya/awst_build/eb/arc4/tuple.py +++ b/src/puya/awst_build/eb/arc4/tuple.py @@ -9,7 +9,7 @@ from puya.awst_build.eb._utils import bool_eval_to_constant from puya.awst_build.eb.arc4.base import ARC4ClassExpressionBuilder, ARC4EncodedExpressionBuilder from puya.awst_build.eb.base import ExpressionBuilder, GenericClassExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.errors import CodeError if typing.TYPE_CHECKING: @@ -34,20 +34,24 @@ def call( ) -> ExpressionBuilder: match args: case [ExpressionBuilder(value_type=wtypes.WTuple(types=item_types)) as eb]: + (at,) = arg_typs + assert isinstance(at, pytypes.TupleType) + typ = pytypes.GenericARC4TupleType.parameterise(at.items, location) wtype = arc4_util.make_tuple_wtype(item_types, location) return ARC4TupleExpressionBuilder( - ARC4Encode(value=eb.rvalue(), wtype=wtype, source_location=location) + ARC4Encode(value=eb.rvalue(), wtype=wtype, source_location=location), typ ) raise CodeError("Invalid/unhandled arguments", location) -class ARC4TupleClassExpressionBuilder(ARC4ClassExpressionBuilder[wtypes.ARC4Tuple]): +class ARC4TupleClassExpressionBuilder(ARC4ClassExpressionBuilder[pytypes.TupleType]): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.TupleType) assert typ.generic == pytypes.GenericARC4TupleType wtype = typ.wtype assert isinstance(wtype, wtypes.ARC4Tuple) - super().__init__(wtype, location) + self._wtype = wtype + super().__init__(typ, location) @typing.override def call( @@ -61,7 +65,7 @@ def call( match args: case [ExpressionBuilder(value_type=wtypes.WTuple() as tuple_wtype) as eb]: - wtype = self.produces() + wtype = self._wtype if wtype.types != tuple_wtype.types: expected_type = wtypes.WTuple(wtype.types, location) raise CodeError( @@ -69,18 +73,18 @@ def call( location, ) return ARC4TupleExpressionBuilder( - ARC4Encode(value=eb.rvalue(), wtype=wtype, source_location=location) + ARC4Encode(value=eb.rvalue(), wtype=wtype, source_location=location), + self.produces2(), ) raise CodeError("Invalid/unhandled arguments", location) -class ARC4TupleExpressionBuilder(ARC4EncodedExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.ARC4Tuple) - self.wtype: wtypes.ARC4Tuple = expr.wtype - super().__init__(expr) +class ARC4TupleExpressionBuilder(ARC4EncodedExpressionBuilder[pytypes.TupleType]): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.TupleType) + native_pytype = pytypes.GenericTupleType.parameterise(typ.items, expr.source_location) + super().__init__(typ, expr, native_pytype=native_pytype) def index( self, index: ExpressionBuilder | Literal, location: SourceLocation @@ -88,22 +92,21 @@ def index( index_expr_or_literal = index match index_expr_or_literal: case Literal(value=int(index_value)) as index_literal: - try: - self.wtype.types[index_value] - except IndexError as ex: - raise CodeError( - "Tuple index out of bounds", index_literal.source_location - ) from ex - # TODO: use pytype - return var_expression( - TupleItemExpression( - base=self.expr, - index=index_value, - source_location=location, - ) - ) + pass case _: raise CodeError("arc4.Tuple can only be indexed by int constants") + try: + item_typ = self.pytype.items[index_value] + except IndexError as ex: + raise CodeError("Tuple index out of bounds", index_literal.source_location) from ex + return builder_for_instance( + item_typ, + TupleItemExpression( + base=self.expr, + index=index_value, + source_location=location, + ), + ) def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: return bool_eval_to_constant(value=True, location=location, negate=negate) diff --git a/src/puya/awst_build/eb/array.py b/src/puya/awst_build/eb/array.py index 40b6b1699..e4f43778b 100644 --- a/src/puya/awst_build/eb/array.py +++ b/src/puya/awst_build/eb/array.py @@ -9,18 +9,15 @@ from puya.awst_build import pytypes from puya.awst_build.eb.base import ( ExpressionBuilder, + FunctionBuilder, GenericClassExpressionBuilder, - IntermediateExpressionBuilder, Iteration, TypeClassExpressionBuilder, ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder from puya.awst_build.eb.void import VoidExpressionBuilder -from puya.awst_build.utils import ( - expect_operand_wtype, - require_expression_builder, -) +from puya.awst_build.utils import expect_operand_wtype, require_expression_builder from puya.errors import CodeError from puya.parse import SourceLocation @@ -41,25 +38,28 @@ def call( require_expression_builder(a, msg="Array arguments must be non literals").rvalue() for a in args ] - expected_type = non_literal_args[0].wtype + expected_type = arg_typs[0] for a in non_literal_args: - expect_operand_wtype(a, expected_type) - array_wtype = wtypes.WArray(expected_type, location) + expect_operand_wtype(a, expected_type.wtype) + array_type = pytypes.GenericArrayType.parameterise([expected_type], location) + wtype = array_type.wtype + assert isinstance(wtype, wtypes.WArray) array_expr = NewArray( values=tuple(non_literal_args), - wtype=array_wtype, + wtype=wtype, source_location=location, ) - return ArrayExpressionBuilder(array_expr) + return ArrayExpressionBuilder(array_expr, array_type) -class ArrayClassExpressionBuilder(TypeClassExpressionBuilder[wtypes.WArray]): +class ArrayClassExpressionBuilder(TypeClassExpressionBuilder[pytypes.ArrayType]): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.ArrayType) assert typ.generic == pytypes.GenericArrayType wtype = typ.wtype assert isinstance(wtype, wtypes.WArray) - super().__init__(wtype, location) + self._wtype = wtype + super().__init__(typ, location) @typing.override def call( @@ -74,24 +74,21 @@ def call( require_expression_builder(a, msg="Array arguments must be non literals").rvalue() for a in args ] - array_wtype = self.produces() - expected_type = array_wtype.element_type + array_type = self.produces2() for a in non_literal_args: - expect_operand_wtype(a, expected_type) + expect_operand_wtype(a, array_type.items.wtype) array_expr = NewArray( values=tuple(non_literal_args), - wtype=array_wtype, + wtype=self._wtype, source_location=location, ) - return ArrayExpressionBuilder(array_expr) + return ArrayExpressionBuilder(array_expr, array_type) -class ArrayExpressionBuilder(ValueExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.WArray) - self.wtype: wtypes.WArray = expr.wtype - super().__init__(expr) +class ArrayExpressionBuilder(ValueExpressionBuilder[pytypes.ArrayType]): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.ArrayType) + super().__init__(typ, expr) def iterate(self) -> Iteration: return self.rvalue() @@ -99,18 +96,18 @@ def iterate(self) -> Iteration: def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "append": - return ArrayAppenderExpressionBuilder(self.expr) + return _Append(self.expr) return super().member_access(name, location) def contains( self, item: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: - item_expr = expect_operand_wtype(item, self.wtype.element_type) + item_expr = expect_operand_wtype(item, self.pytype.items.wtype) contains_expr = Contains(source_location=location, item=item_expr, sequence=self.expr) return BoolExpressionBuilder(contains_expr) -class ArrayAppenderExpressionBuilder(IntermediateExpressionBuilder): +class _Append(FunctionBuilder): def __init__(self, array: Expression): assert isinstance(array.wtype, wtypes.WArray) super().__init__(array.source_location) diff --git a/src/puya/awst_build/eb/base.py b/src/puya/awst_build/eb/base.py index dde8d36a1..da7572329 100644 --- a/src/puya/awst_build/eb/base.py +++ b/src/puya/awst_build/eb/base.py @@ -8,7 +8,6 @@ from puya.awst import wtypes from puya.awst.nodes import ( - BytesConstant, ContractReference, Expression, FieldExpression, @@ -16,12 +15,11 @@ Literal, Lvalue, Range, - ReinterpretCast, Statement, TupleExpression, TupleItemExpression, ) -from puya.awst_build.contract_data import AppStorageDeclaration +from puya.awst_build import pytypes from puya.errors import CodeError, InternalError if typing.TYPE_CHECKING: @@ -30,7 +28,7 @@ import mypy.nodes import mypy.types - from puya.awst_build import pytypes + from puya.awst_build.contract_data import AppStorageDeclaration from puya.parse import SourceLocation __all__ = [ @@ -38,8 +36,8 @@ "BuilderComparisonOp", "BuilderBinaryOp", "ExpressionBuilder", - "StateProxyDefinitionBuilder", - "StateProxyMemberBuilder", + "StorageProxyConstructorResult", + "FunctionBuilder", "IntermediateExpressionBuilder", "TypeClassExpressionBuilder", "GenericClassExpressionBuilder", @@ -112,14 +110,21 @@ def contains( ) -> ExpressionBuilder: ... @property + @typing.final def value_type(self) -> wtypes.WType | None: - return None + if self.pytype is None: + return None + return self.pytype.wtype + + @property + @abc.abstractmethod + def pytype(self) -> pytypes.PyType | None: ... @property def _type_description(self) -> str: - if self.value_type is None: + if self.pytype is None: return type(self).__name__ - return self.value_type.stub_name + return str(self.pytype) def compare( self, other: ExpressionBuilder | Literal, op: BuilderComparisonOp, location: SourceLocation @@ -168,6 +173,7 @@ def index( """Handle self[index]""" raise CodeError(f"{self._type_description} does not support indexing", location) + @typing.final def index_multiple( self, indexes: Sequence[ExpressionBuilder | Literal], location: SourceLocation ) -> ExpressionBuilder: @@ -208,7 +214,7 @@ def iterate(self) -> Iteration: ) -class IntermediateExpressionBuilder(ExpressionBuilder): +class IntermediateExpressionBuilder(ExpressionBuilder, abc.ABC): """Never valid as an assignment source OR target""" def rvalue(self) -> Expression: @@ -247,95 +253,57 @@ def _not_a_value(self, location: SourceLocation) -> typing.Never: raise CodeError(f"{self._type_description} is not a value", location) -class StateProxyMemberBuilder(IntermediateExpressionBuilder): - state_decl: AppStorageDeclaration +class FunctionBuilder(IntermediateExpressionBuilder): + @property + def pytype(self) -> None: # TODO: give function type + return None -class StateProxyDefinitionBuilder(ExpressionBuilder, abc.ABC): - python_name: str +class StorageProxyConstructorResult(ExpressionBuilder, abc.ABC): + @typing.override + @property + @abc.abstractmethod + def pytype(self) -> pytypes.StorageProxyType | pytypes.StorageMapProxyType: ... - def __init__( - self, - location: SourceLocation, - storage: wtypes.WType, - key_override: BytesConstant | None, - description: str | None, - initial_value: Expression | None = None, - ): - super().__init__(location) - self.storage = storage - self.key_override = key_override - self.description = description - self.initial_value = initial_value + @property + @abc.abstractmethod + def initial_value(self) -> Expression | None: ... + @abc.abstractmethod def build_definition( self, member_name: str, defined_in: ContractReference, typ: pytypes.PyType, location: SourceLocation, - ) -> AppStorageDeclaration: - return AppStorageDeclaration( - description=self.description, - member_name=member_name, - key_override=self.key_override, - source_location=location, - typ=typ, - defined_in=defined_in, - ) - - def rvalue(self) -> Expression: - return self._assign_first(self.source_location) - - def lvalue(self) -> Lvalue: - raise CodeError( - f"{self.python_name} is not valid as an assignment target", self.source_location - ) - - def delete(self, location: SourceLocation) -> Statement: - raise self._assign_first(location) - - def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: - return self._assign_first(location) - - def unary_plus(self, location: SourceLocation) -> ExpressionBuilder: - return self._assign_first(location) - - def unary_minus(self, location: SourceLocation) -> ExpressionBuilder: - return self._assign_first(location) - - def bitwise_invert(self, location: SourceLocation) -> ExpressionBuilder: - return self._assign_first(location) - - def contains( - self, item: ExpressionBuilder | Literal, location: SourceLocation - ) -> ExpressionBuilder: - return self._assign_first(location) - - def _assign_first(self, location: SourceLocation) -> typing.Never: - raise CodeError( - f"{self.python_name} should be assigned to an instance variable before being used", - location, - ) + ) -> AppStorageDeclaration: ... -_TWType_co = typing_extensions.TypeVar( - "_TWType_co", bound=wtypes.WType, default=wtypes.WType, covariant=True +_TPyType_co = typing_extensions.TypeVar( + "_TPyType_co", bound=pytypes.PyType, default=pytypes.PyType, covariant=True ) class TypeClassExpressionBuilder( - IntermediateExpressionBuilder, typing.Generic[_TWType_co], abc.ABC + IntermediateExpressionBuilder, typing.Generic[_TPyType_co], abc.ABC ): # TODO: better error messages for rvalue/lvalue/delete - def __init__(self, wtype: _TWType_co, location: SourceLocation): + def __init__(self, pytype: _TPyType_co, location: SourceLocation): super().__init__(location) - self._wtype = wtype + self._pytype = pytype + + @property + def pytype(self) -> pytypes.TypeType: + return pytypes.TypeType(self._pytype) @typing.final - def produces(self) -> _TWType_co: - return self._wtype + def produces2(self) -> _TPyType_co: + return self._pytype + + @typing.final + def produces(self) -> wtypes.WType: + return self._pytype.wtype @typing.override @abc.abstractmethod @@ -350,6 +318,11 @@ def call( class GenericClassExpressionBuilder(IntermediateExpressionBuilder, abc.ABC): + @typing.override + @property + def pytype(self) -> None: # TODO: ?? + return None + @typing.override @abc.abstractmethod def call( @@ -369,41 +342,53 @@ def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilde ) -class ValueExpressionBuilder(ExpressionBuilder): - wtype: wtypes.WType +class ValueExpressionBuilder(ExpressionBuilder, typing.Generic[_TPyType_co]): - def __init__(self, expr: Expression): + def __init__(self, pytype: _TPyType_co, expr: Expression): super().__init__(expr.source_location) + self._pytype = pytype self.__expr = expr if expr.wtype != self.wtype: raise InternalError( - f"Invalid type of expression for {self.wtype}: {expr.wtype}", + f"Invalid WType of {str(self.pytype)!r} expression for: {expr.wtype}", expr.source_location, ) + @typing.override + @typing.final + @property + def pytype(self) -> _TPyType_co: + return self._pytype + + @typing.final + @property + def wtype(self) -> wtypes.WType: + return self._pytype.wtype + @property def expr(self) -> Expression: return self.__expr + @typing.override def lvalue(self) -> Lvalue: resolved = self.rvalue() return _validate_lvalue(resolved) + @typing.override def rvalue(self) -> Expression: return self.expr - @property - def value_type(self) -> wtypes.WType: - return self.wtype - + @typing.override def delete(self, location: SourceLocation) -> Statement: - raise CodeError(f"{self.wtype} is not valid as del target", location) + raise CodeError(f"{self.pytype} is not valid as del target", location) + @typing.override def index( self, index: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: - raise CodeError(f"{self.wtype} does not support indexing", location) + raise CodeError(f"{self.pytype} does not support indexing", location) + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -412,50 +397,58 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: - raise CodeError(f"{self.wtype} does not support calling", location) + raise CodeError(f"{self.pytype} does not support calling", location) + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: - raise CodeError(f"Unrecognised member of {self.wtype}: {name}", location) + raise CodeError(f"Unrecognised member of {self.pytype}: {name}", location) + @typing.override def iterate(self) -> Iteration: """Produce target of ForInLoop""" - raise CodeError(f"{self.wtype} does not support iteration", self.source_location) + raise CodeError(f"{self.pytype} does not support iteration", self.source_location) + @typing.override def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: # TODO: this should be abstract, we always want to consider this for types - raise CodeError(f"{self.wtype} does not support boolean evaluation", location) + raise CodeError(f"{self.pytype} does not support boolean evaluation", location) + @typing.override def unary_plus(self, location: SourceLocation) -> ExpressionBuilder: - raise CodeError(f"{self.wtype} does not support unary plus operator", location) + raise CodeError(f"{self.pytype} does not support unary plus operator", location) + @typing.override def unary_minus(self, location: SourceLocation) -> ExpressionBuilder: - raise CodeError(f"{self.wtype} does not support unary minus operator", location) + raise CodeError(f"{self.pytype} does not support unary minus operator", location) + @typing.override def bitwise_invert(self, location: SourceLocation) -> ExpressionBuilder: - raise CodeError(f"{self.wtype} does not support bitwise inversion", location) + raise CodeError(f"{self.pytype} does not support bitwise inversion", location) + @typing.override def contains( self, item: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: - raise CodeError(f"{self.wtype} does not support in/not in checks", location) + raise CodeError(f"{self.pytype} does not support in/not in checks", location) def _validate_lvalue(resolved: Expression) -> Lvalue: if isinstance(resolved, TupleItemExpression): raise CodeError("Tuple items cannot be reassigned", resolved.source_location) if not isinstance(resolved, Lvalue): # type: ignore[arg-type,misc] - raise CodeError( - f"{resolved.wtype.stub_name} expression is not valid as assignment target", - resolved.source_location, - ) - if isinstance(resolved, IndexExpression | FieldExpression) and resolved.base.wtype.immutable: - raise CodeError( - "expression is not valid as assignment target" - f" ({resolved.base.wtype.stub_name} is immutable)", - resolved.source_location, - ) - if isinstance(resolved, ReinterpretCast): - _validate_lvalue(resolved.expr) + raise CodeError("expression is not valid as assignment target", resolved.source_location) + if isinstance(resolved, IndexExpression): + if resolved.base.wtype.immutable: + raise CodeError( + "expression is not valid as assignment target - collection is immutable", + resolved.source_location, + ) + elif isinstance(resolved, FieldExpression): + if resolved.base.wtype.immutable: + raise CodeError( + "expression is not valid as assignment target - object is immutable", + resolved.source_location, + ) elif isinstance(resolved, TupleExpression): for item in resolved.items: _validate_lvalue(item) diff --git a/src/puya/awst_build/eb/biguint.py b/src/puya/awst_build/eb/biguint.py index ce3a585ec..9c56d20e8 100644 --- a/src/puya/awst_build/eb/biguint.py +++ b/src/puya/awst_build/eb/biguint.py @@ -19,6 +19,7 @@ ReinterpretCast, Statement, ) +from puya.awst_build import pytypes from puya.awst_build.eb._utils import uint64_to_biguint from puya.awst_build.eb.base import ( BuilderBinaryOp, @@ -37,7 +38,6 @@ import mypy.types - from puya.awst_build import pytypes from puya.parse import SourceLocation logger = log.get_logger(__name__) @@ -45,7 +45,7 @@ class BigUIntClassExpressionBuilder(BytesBackedClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.biguint_wtype, location) + super().__init__(pytypes.BigUIntType, location) @typing.override def call( @@ -71,7 +71,8 @@ def call( class BigUIntExpressionBuilder(ValueExpressionBuilder): - wtype = wtypes.biguint_wtype + def __init__(self, expr: Expression): + super().__init__(pytypes.BigUIntType, expr) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: diff --git a/src/puya/awst_build/eb/bool.py b/src/puya/awst_build/eb/bool.py index 4b2a678f1..80d4a4e47 100644 --- a/src/puya/awst_build/eb/bool.py +++ b/src/puya/awst_build/eb/bool.py @@ -5,14 +5,15 @@ import mypy.nodes from puya import log -from puya.awst import wtypes from puya.awst.nodes import ( BoolConstant, + Expression, Literal, Not, NumericComparison, NumericComparisonExpression, ) +from puya.awst_build import pytypes from puya.awst_build.eb.base import ( BuilderComparisonOp, ExpressionBuilder, @@ -27,7 +28,6 @@ import mypy.types - from puya.awst_build import pytypes from puya.parse import SourceLocation logger = log.get_logger(__name__) @@ -35,7 +35,7 @@ class BoolClassExpressionBuilder(TypeClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.bool_wtype, location) + super().__init__(pytypes.BoolType, location) @typing.override def call( @@ -57,7 +57,8 @@ def call( class BoolExpressionBuilder(ValueExpressionBuilder): - wtype = wtypes.bool_wtype + def __init__(self, expr: Expression): + super().__init__(pytypes.BoolType, expr) def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: if not negate: diff --git a/src/puya/awst_build/eb/box/_common.py b/src/puya/awst_build/eb/box/_common.py index 5943b6270..6a00028e6 100644 --- a/src/puya/awst_build/eb/box/_common.py +++ b/src/puya/awst_build/eb/box/_common.py @@ -1,34 +1,28 @@ +import abc +import typing from collections.abc import Sequence import mypy.nodes -from puya.awst.nodes import ( - BoxKeyExpression, - Literal, - StateGet, - StateGetEx, -) +from puya.awst.nodes import BoxValueExpression, Literal, StateGet, StateGetEx from puya.awst_build import pytypes -from puya.awst_build.eb.base import ( - ExpressionBuilder, - IntermediateExpressionBuilder, -) +from puya.awst_build.eb.base import ExpressionBuilder, FunctionBuilder from puya.awst_build.eb.tuple import TupleExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression -from puya.awst_build.utils import ( - expect_operand_wtype, -) +from puya.awst_build.eb.var_factory import builder_for_instance +from puya.awst_build.utils import expect_operand_wtype from puya.errors import CodeError from puya.parse import SourceLocation -class BoxKeyExpressionIntermediateExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, box_key_expression: BoxKeyExpression) -> None: - super().__init__(box_key_expression.source_location) - self.box_key = box_key_expression +class _BoxKeyExpressionIntermediateExpressionBuilder(FunctionBuilder, abc.ABC): + def __init__(self, box: BoxValueExpression, content_type: pytypes.PyType) -> None: + super().__init__(box.source_location) + self.box = box + self.content_type = content_type -class BoxGetExpressionBuilder(BoxKeyExpressionIntermediateExpressionBuilder): +class BoxGetExpressionBuilder(_BoxKeyExpressionIntermediateExpressionBuilder): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -40,14 +34,15 @@ def call( if len(args) != 1: raise CodeError(f"Expected 1 argument, got {len(args)}", location) (default_arg,) = args - default_expr = expect_operand_wtype(default_arg, target_wtype=self.box_key.wtype) - # TODO: use pytype - return var_expression( - StateGet(field=self.box_key, default=default_expr, source_location=location) + default_expr = expect_operand_wtype(default_arg, target_wtype=self.content_type.wtype) + return builder_for_instance( + self.content_type, + StateGet(field=self.box, default=default_expr, source_location=location), ) -class BoxMaybeExpressionBuilder(BoxKeyExpressionIntermediateExpressionBuilder): +class BoxMaybeExpressionBuilder(_BoxKeyExpressionIntermediateExpressionBuilder): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -61,7 +56,8 @@ def call( return TupleExpressionBuilder( StateGetEx( - field=self.box_key, + field=self.box, source_location=location, - ) + ), + pytypes.GenericTupleType.parameterise([self.content_type, pytypes.BoolType], location), ) diff --git a/src/puya/awst_build/eb/box/_util.py b/src/puya/awst_build/eb/box/_util.py index 68aca2ab3..85c7322be 100644 --- a/src/puya/awst_build/eb/box/_util.py +++ b/src/puya/awst_build/eb/box/_util.py @@ -1,10 +1,12 @@ from puya.awst import wtypes from puya.awst.nodes import ( - BoxKeyExpression, - BoxLength, + BoxValueExpression, + CheckedMaybe, + Expression, IntrinsicCall, Literal, SingleEvaluation, + TupleItemExpression, UInt64Constant, ) from puya.awst_build.eb.base import BuilderBinaryOp, ExpressionBuilder @@ -16,19 +18,29 @@ def index_box_bytes( - box_key: BoxKeyExpression, + box: BoxValueExpression, index: ExpressionBuilder | Literal, location: SourceLocation, ) -> ExpressionBuilder: - len_expr = BoxLength(box_key=box_key, source_location=location) - begin_index_expr = eval_slice_component(len_expr, index, location) - assert begin_index_expr, "Index expression cannot evaluate to None" + if isinstance(index, ExpressionBuilder): + # no negatives + begin_index_expr = index.rvalue() + elif not isinstance(index.value, int): + raise CodeError("Invalid literal index type", index.source_location) + elif index.value >= 0: + begin_index_expr = UInt64Constant(value=index.value, source_location=index.source_location) + else: + box_length = box_length_unchecked(box, location) + box_length_builder = UInt64ExpressionBuilder(box_length) + begin_index_expr = box_length_builder.binary_op( + index, BuilderBinaryOp.sub, location, reverse=False + ).rvalue() return BytesExpressionBuilder( IntrinsicCall( op_code="box_extract", stack_args=[ - box_key, + box.key, begin_index_expr, UInt64Constant(value=1, source_location=location), ], @@ -39,7 +51,7 @@ def index_box_bytes( def slice_box_bytes( - box_key: BoxKeyExpression, + box: BoxValueExpression, begin_index: ExpressionBuilder | Literal | None, end_index: ExpressionBuilder | Literal | None, stride: ExpressionBuilder | Literal | None, @@ -47,7 +59,7 @@ def slice_box_bytes( ) -> ExpressionBuilder: if stride: raise CodeError("Stride is not supported when slicing boxes", location) - len_expr = SingleEvaluation(BoxLength(box_key=box_key, source_location=location)) + len_expr = SingleEvaluation(box_length_unchecked(box, location)) begin_index_expr = eval_slice_component(len_expr, begin_index, location) or UInt64Constant( value=0, source_location=location @@ -64,12 +76,37 @@ def slice_box_bytes( return BytesExpressionBuilder( IntrinsicCall( op_code="box_extract", - stack_args=[ - box_key, - begin_index_expr, - length_expr, - ], + stack_args=[box.key, begin_index_expr, length_expr], source_location=location, wtype=wtypes.bytes_wtype, ) ) + + +def box_length_unchecked(box: BoxValueExpression, location: SourceLocation) -> Expression: + box_len_expr = _box_len(box.key, location) + box_length = TupleItemExpression( + base=box_len_expr, + index=0, + source_location=location, + ) + return box_length + + +def box_length_checked(box: BoxValueExpression, location: SourceLocation) -> Expression: + box_len_expr = _box_len(box.key, location) + if box.member_name: + comment = f"box {box.member_name} exists" + else: + comment = "box exists" + return CheckedMaybe(box_len_expr, comment=comment) + + +def _box_len(box_key: Expression, location: SourceLocation) -> IntrinsicCall: + assert box_key.wtype == wtypes.bytes_wtype + return IntrinsicCall( + op_code="box_len", + wtype=wtypes.WTuple([wtypes.uint64_wtype, wtypes.bool_wtype], source_location=location), + stack_args=[box_key], + source_location=location, + ) diff --git a/src/puya/awst_build/eb/box/box.py b/src/puya/awst_build/eb/box/box.py index bc4776b9d..954fe1b69 100644 --- a/src/puya/awst_build/eb/box/box.py +++ b/src/puya/awst_build/eb/box/box.py @@ -5,10 +5,10 @@ from puya.awst import wtypes from puya.awst.nodes import ( - BoxKeyExpression, - BoxLength, - BoxProxyExpression, BoxValueExpression, + BytesConstant, + BytesRaw, + ContractReference, Expression, Literal, Not, @@ -16,29 +16,33 @@ StateExists, Statement, ) -from puya.awst_build import constants, pytypes -from puya.awst_build.eb._utils import get_bytes_expr +from puya.awst_build import pytypes +from puya.awst_build.contract_data import AppStorageDeclaration +from puya.awst_build.eb._storage import StorageProxyDefinitionBuilder, extract_key_override from puya.awst_build.eb.base import ( ExpressionBuilder, GenericClassExpressionBuilder, + StorageProxyConstructorResult, TypeClassExpressionBuilder, ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder from puya.awst_build.eb.box._common import BoxGetExpressionBuilder, BoxMaybeExpressionBuilder -from puya.awst_build.eb.box._util import index_box_bytes, slice_box_bytes +from puya.awst_build.eb.box._util import box_length_checked, index_box_bytes, slice_box_bytes from puya.awst_build.eb.uint64 import UInt64ExpressionBuilder from puya.awst_build.eb.value_proxy import ValueProxyExpressionBuilder -from puya.awst_build.utils import ( - expect_operand_wtype, - get_arg_mapping, - require_type_class_eb, -) -from puya.errors import CodeError, InternalError +from puya.awst_build.utils import get_arg_mapping +from puya.errors import CodeError from puya.parse import SourceLocation -class BoxClassGenericExpressionBuilder(GenericClassExpressionBuilder): +class BoxClassExpressionBuilder(TypeClassExpressionBuilder[pytypes.StorageProxyType]): + def __init__(self, typ: pytypes.PyType, location: SourceLocation) -> None: + assert isinstance(typ, pytypes.StorageProxyType) + assert typ.generic == pytypes.GenericBoxType + self._typ = typ + super().__init__(typ, location) + @typing.override def call( self, @@ -48,31 +52,10 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: - arg_map = get_arg_mapping( - positional_arg_names=("_type",), - args=zip(arg_names, args, strict=True), - location=location, - ) - type_arg_wtype = require_type_class_eb(arg_map.pop("_type")).produces() - wtype = wtypes.WBoxProxy.from_content_type(type_arg_wtype) - key = expect_operand_wtype(arg_map.pop("key"), wtypes.bytes_wtype) - - if arg_map: - raise CodeError("Invalid/unhandled arguments", location) - - return BoxProxyExpressionBuilder( - expr=BoxProxyExpression(key=key, wtype=wtype, source_location=location) - ) + return _init(args, arg_typs, arg_names, location, result_type=self._typ) -class BoxClassExpressionBuilder(TypeClassExpressionBuilder[wtypes.WBoxProxy]): - def __init__(self, typ: pytypes.PyType, location: SourceLocation) -> None: - assert isinstance(typ, pytypes.StorageProxyType) - assert typ.generic == pytypes.GenericBoxType - wtype = typ.wtype - assert isinstance(wtype, wtypes.WBoxProxy) - super().__init__(wtype, location) - +class BoxClassGenericExpressionBuilder(GenericClassExpressionBuilder): @typing.override def call( self, @@ -82,67 +65,82 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: - arg_map = get_arg_mapping( - positional_arg_names=("_type",), - args=zip(arg_names, args, strict=True), - location=location, + return _init(args, arg_typs, arg_names, location, result_type=None) + + +def _init( + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_names: list[str | None], + location: SourceLocation, + *, + result_type: pytypes.StorageProxyType | None, +) -> ExpressionBuilder: + type_arg_name = "type_" + arg_mapping = get_arg_mapping( + positional_arg_names=[type_arg_name], + args=zip(arg_names, zip(args, arg_typs, strict=True), strict=True), + location=location, + ) + try: + _, type_arg_typ = arg_mapping.pop(type_arg_name) + except KeyError as ex: + raise CodeError("Required positional argument missing", location) from ex + + key_arg, _ = arg_mapping.pop("key", (None, None)) + descr_arg, _ = arg_mapping.pop("description", (None, None)) + if arg_mapping: + raise CodeError(f"Unrecognised keyword argument(s): {", ".join(arg_mapping)}", location) + + match type_arg_typ: + case pytypes.TypeType(typ=content): + pass + case _: + raise CodeError("First argument must be a type reference", location) + if result_type is None: + result_type = pytypes.GenericBoxType.parameterise([content], location) + elif result_type.content != content: + raise CodeError( + f"{result_type.generic} explicit type annotation" + f" does not match first argument - suggest to remove the explicit type annotation," + " it shouldn't be required", + location, ) - type_arg_wtype = require_type_class_eb(arg_map.pop("_type")).produces() - wtype = self.produces() - if wtype.content_wtype != type_arg_wtype: - raise CodeError( - f"{constants.CLS_BOX_PROXY} explicit type annotation" - f" does not match first argument - suggest to remove the explicit type annotation," - " it shouldn't be required", - location, - ) - key = expect_operand_wtype(arg_map.pop("key"), wtypes.bytes_wtype) + key_override = extract_key_override(key_arg, location, is_prefix=False) + if key_override is None: + return StorageProxyDefinitionBuilder(result_type, location=location, description=None) + return _BoxProxyExpressionBuilderFromConstructor(key_override=key_override, typ=result_type) - if arg_map: - raise CodeError("Invalid/unhandled arguments", location) - return BoxProxyExpressionBuilder( - expr=BoxProxyExpression(key=key, wtype=wtype, source_location=location) - ) - - -class BoxProxyExpressionBuilder(ValueExpressionBuilder): - wtype: wtypes.WBoxProxy - python_name = constants.CLS_BOX_PROXY - - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - if not isinstance(expr.wtype, wtypes.WBoxProxy): - raise InternalError( - "BoxProxyExpressionBuilder can only be created with expressions of " - f"wtype {wtypes.WBoxProxy}", - expr.source_location, - ) - self.wtype = expr.wtype - super().__init__(expr) - - def _box_key_expr(self, location: SourceLocation) -> BoxKeyExpression: - return BoxKeyExpression( - proxy=self.expr, +class BoxProxyExpressionBuilder(ValueExpressionBuilder[pytypes.StorageProxyType]): + def __init__(self, expr: Expression, typ: pytypes.PyType, member_name: str | None = None): + assert isinstance(typ, pytypes.StorageProxyType) + assert typ.generic == pytypes.GenericBoxType + self._typ = typ + self._member_name = member_name + super().__init__(typ, expr) + + def _box_key_expr(self, location: SourceLocation) -> BoxValueExpression: + return BoxValueExpression( + key=self.expr, + wtype=self._typ.content.wtype, + member_name=self._member_name, source_location=location, ) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "value": - return BoxValueExpressionBuilder( - box_key=self._box_key_expr(location), - box_value=BoxValueExpression( - wtype=self.wtype.content_wtype, - proxy=self.expr, - source_location=location, - ), - ) + return BoxValueExpressionBuilder(self._typ.content, self._box_key_expr(location)) case "get": - return BoxGetExpressionBuilder(self._box_key_expr(location)) + return BoxGetExpressionBuilder( + self._box_key_expr(location), content_type=self._typ.content + ) case "maybe": - return BoxMaybeExpressionBuilder(self._box_key_expr(location)) + return BoxMaybeExpressionBuilder( + self._box_key_expr(location), content_type=self._typ.content + ) return super().member_access(name, location) @@ -156,26 +154,53 @@ def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> Expres ) +class _BoxProxyExpressionBuilderFromConstructor( + BoxProxyExpressionBuilder, StorageProxyConstructorResult +): + def __init__(self, key_override: Expression, typ: pytypes.StorageProxyType): + super().__init__(key_override, typ, member_name=None) + + @typing.override + @property + def initial_value(self) -> Expression | None: + return None + + @typing.override + def build_definition( + self, + member_name: str, + defined_in: ContractReference, + typ: pytypes.PyType, + location: SourceLocation, + ) -> AppStorageDeclaration: + key_override = self.expr + if not isinstance(key_override, BytesConstant): + raise CodeError( + f"assigning {typ} to a member variable requires a constant value for key", + location, + ) + return AppStorageDeclaration( + description=None, + member_name=member_name, + key_override=key_override, + source_location=location, + typ=typ, + defined_in=defined_in, + ) + + class BoxValueExpressionBuilder(ValueProxyExpressionBuilder): - def __init__(self, *, box_key: BoxKeyExpression, box_value: BoxValueExpression) -> None: - self.wtype = box_value.wtype - super().__init__(box_value) - self.box_key = box_key - self.box_value = box_value + expr: BoxValueExpression # TODO: remove "lies" def delete(self, location: SourceLocation) -> Statement: - return StateDelete(field=self.box_key, source_location=location) + return StateDelete(field=self.expr, source_location=location) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "length": - return UInt64ExpressionBuilder( - BoxLength(box_key=self.box_key, source_location=location) - ) + return UInt64ExpressionBuilder(box_length_checked(self.expr, location)) case "bytes": - return BoxValueBytesExpressionBuilder( - box_key=self.box_key, box_value=self.box_value - ) + return BoxValueBytesExpressionBuilder(self.expr, location) case _: return super().member_access(name, location) @@ -184,7 +209,7 @@ def index( ) -> ExpressionBuilder: if self.wtype != wtypes.bytes_wtype: return super().index(index, location) - return index_box_bytes(self.box_key, index, location) + return index_box_bytes(self.expr, index, location) def slice_index( self, @@ -196,29 +221,25 @@ def slice_index( if self.wtype != wtypes.bytes_wtype: return super().slice_index(begin_index, end_index, stride, location) - return slice_box_bytes(self.box_key, begin_index, end_index, stride, location) + return slice_box_bytes(self.expr, begin_index, end_index, stride, location) class BoxValueBytesExpressionBuilder(ValueProxyExpressionBuilder): - def __init__(self, *, box_key: BoxKeyExpression, box_value: BoxValueExpression) -> None: - self.wtype = wtypes.bytes_wtype - super().__init__(get_bytes_expr(box_value)) - self.box_key = box_key - self.box_value = box_value + def __init__(self, expr: BoxValueExpression, location: SourceLocation) -> None: + self._typed = expr + super().__init__(pytypes.BytesType, BytesRaw(expr=expr, source_location=location)) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "length": - return UInt64ExpressionBuilder( - BoxLength(box_key=self.box_key, source_location=location) - ) + return UInt64ExpressionBuilder(box_length_checked(self._typed, location)) case _: return super().member_access(name, location) def index( self, index: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: - return index_box_bytes(self.box_key, index, location) + return index_box_bytes(self._typed, index, location) def slice_index( self, @@ -227,4 +248,4 @@ def slice_index( stride: ExpressionBuilder | Literal | None, location: SourceLocation, ) -> ExpressionBuilder: - return slice_box_bytes(self.box_key, begin_index, end_index, stride, location) + return slice_box_bytes(self._typed, begin_index, end_index, stride, location) diff --git a/src/puya/awst_build/eb/box/box_map.py b/src/puya/awst_build/eb/box/box_map.py index a1cc5edf2..98a69f401 100644 --- a/src/puya/awst_build/eb/box/box_map.py +++ b/src/puya/awst_build/eb/box/box_map.py @@ -5,41 +5,45 @@ from puya.awst import wtypes from puya.awst.nodes import ( - BoxKeyExpression, - BoxLength, - BoxProxyExpression, BoxValueExpression, + BytesConstant, BytesRaw, + ContractReference, Expression, Literal, StateExists, StateGet, StateGetEx, ) -from puya.awst_build import constants, pytypes +from puya.awst_build import intrinsic_factory, pytypes +from puya.awst_build.contract_data import AppStorageDeclaration +from puya.awst_build.eb._storage import StorageProxyDefinitionBuilder, extract_key_override from puya.awst_build.eb.base import ( ExpressionBuilder, + FunctionBuilder, GenericClassExpressionBuilder, - IntermediateExpressionBuilder, + StorageProxyConstructorResult, TypeClassExpressionBuilder, ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder +from puya.awst_build.eb.box._util import box_length_checked from puya.awst_build.eb.box.box import BoxValueExpressionBuilder from puya.awst_build.eb.tuple import TupleExpressionBuilder from puya.awst_build.eb.uint64 import UInt64ExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression -from puya.awst_build.utils import ( - expect_operand_wtype, - get_arg_mapping, - require_expression_builder, - require_type_class_eb, -) -from puya.errors import CodeError, InternalError +from puya.awst_build.eb.var_factory import builder_for_instance +from puya.awst_build.utils import expect_operand_wtype, get_arg_mapping, require_expression_builder +from puya.errors import CodeError from puya.parse import SourceLocation -class BoxMapClassGenericExpressionBuilder(GenericClassExpressionBuilder): +class BoxMapClassExpressionBuilder(TypeClassExpressionBuilder[pytypes.StorageMapProxyType]): + def __init__(self, typ: pytypes.PyType, location: SourceLocation) -> None: + assert isinstance(typ, pytypes.StorageMapProxyType) + assert typ.generic == pytypes.GenericBoxMapType + self._typ = typ + super().__init__(typ, location) + @typing.override def call( self, @@ -49,38 +53,10 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: - arg_map = get_arg_mapping( - positional_arg_names=( - "key_type", - "_type", - ), - args=zip(arg_names, args, strict=True), - location=location, - ) - key_wtype = require_type_class_eb(arg_map.pop("key_type")).produces() - content_wtype = require_type_class_eb(arg_map.pop("_type")).produces() - wtype = wtypes.WBoxMapProxy.from_key_and_content_type(key_wtype, content_wtype) - key_prefix = expect_operand_wtype( - arg_map.pop("key_prefix", Literal(value=b"", source_location=location)), - wtypes.bytes_wtype, - ) + return _init(args, arg_typs, arg_names, location, result_type=self._typ) - if arg_map: - raise CodeError("Invalid/unhandled arguments", location) - - return BoxMapProxyExpressionBuilder( - expr=BoxProxyExpression(key=key_prefix, wtype=wtype, source_location=location) - ) - - -class BoxMapClassExpressionBuilder(TypeClassExpressionBuilder[wtypes.WBoxMapProxy]): - def __init__(self, typ: pytypes.PyType, location: SourceLocation) -> None: - assert isinstance(typ, pytypes.StorageMapProxyType) - assert typ.generic == pytypes.GenericBoxMapType - wtype = typ.wtype - assert isinstance(wtype, wtypes.WBoxMapProxy) - super().__init__(wtype, location) +class BoxMapClassGenericExpressionBuilder(GenericClassExpressionBuilder): @typing.override def call( self, @@ -90,119 +66,146 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: - arg_map = get_arg_mapping( - positional_arg_names=( - "key_type", - "_type", - ), - args=zip(arg_names, args, strict=True), - location=location, - ) - key_wtype = require_type_class_eb(arg_map.pop("key_type")).produces() - content_wtype = require_type_class_eb(arg_map.pop("_type")).produces() - wtype = self.produces() - if wtype != wtypes.WBoxMapProxy.from_key_and_content_type(key_wtype, content_wtype): - raise CodeError( - f"{constants.CLS_BOX_MAP_PROXY} explicit type annotation" - f" does not match first argument - suggest to remove the explicit type annotation," - " it shouldn't be required", - location, - ) + return _init(args, arg_typs, arg_names, location, result_type=None) - key_prefix = expect_operand_wtype( - arg_map.pop("key_prefix", Literal(value=b"", source_location=location)), - wtypes.bytes_wtype, - ) - - if arg_map: - raise CodeError("Invalid/unhandled arguments", location) - - return BoxMapProxyExpressionBuilder( - expr=BoxProxyExpression(key=key_prefix, wtype=wtype, source_location=location) - ) +def _init( + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_names: list[str | None], + location: SourceLocation, + *, + result_type: pytypes.StorageMapProxyType | None, +) -> ExpressionBuilder: + key_type_arg_name = "key_type" + value_type_arg_name = "value_type" + arg_mapping = get_arg_mapping( + positional_arg_names=[key_type_arg_name, value_type_arg_name], + args=zip(arg_names, zip(args, arg_typs, strict=True), strict=True), + location=location, + ) + try: + _, key_type_arg_typ = arg_mapping.pop(key_type_arg_name) + _, value_type_arg_typ = arg_mapping.pop(value_type_arg_name) + except KeyError as ex: + raise CodeError("Required positional argument missing", location) from ex -def _box_key_expr( - box_map_proxy: Expression, key: ExpressionBuilder | Literal, location: SourceLocation -) -> BoxKeyExpression: - if not isinstance(box_map_proxy.wtype, wtypes.WBoxMapProxy): - raise InternalError(f"box_map_proxy must be wtype of {wtypes.WBoxMapProxy}", location) - key_eb = require_expression_builder(key).rvalue() - item_key = BytesRaw(expr=key_eb, source_location=location) - return BoxKeyExpression(proxy=box_map_proxy, item_key=item_key, source_location=location) + key_prefix_arg, _ = arg_mapping.pop("key_prefix", (None, None)) + if arg_mapping: + raise CodeError(f"Unrecognised keyword argument(s): {", ".join(arg_mapping)}", location) + match key_type_arg_typ, value_type_arg_typ: + case pytypes.TypeType(typ=key), pytypes.TypeType(typ=content): + pass + case _: + raise CodeError("First and second arguments must be type references", location) + if result_type is None: + result_type = pytypes.GenericBoxMapType.parameterise([key, content], location) + elif not (result_type.key == key and result_type.content == content): + raise CodeError( + f"{result_type.generic} explicit type annotation" + f" does not match type arguments - suggest to remove the explicit type annotation," + " it shouldn't be required", + location, + ) -def _box_value_expr( - box_map_proxy: Expression, key: ExpressionBuilder | Literal, location: SourceLocation -) -> BoxValueExpression: - if not isinstance(box_map_proxy.wtype, wtypes.WBoxMapProxy): - raise InternalError(f"box_map_proxy must be wtype of {wtypes.WBoxMapProxy}", location) - key_eb = require_expression_builder(key).rvalue() - item_key = BytesRaw(expr=key_eb, source_location=location) - return BoxValueExpression( - proxy=box_map_proxy, - wtype=box_map_proxy.wtype.content_wtype, - item_key=item_key, - source_location=location, + key_prefix_override = extract_key_override(key_prefix_arg, location, is_prefix=True) + if key_prefix_override is None: + return StorageProxyDefinitionBuilder(result_type, location=location, description=None) + return _BoxMapProxyExpressionBuilderFromConstructor( + key_prefix_override=key_prefix_override, typ=result_type ) -class BoxMapProxyExpressionBuilder(ValueExpressionBuilder): - wtype: wtypes.WBoxMapProxy - python_name = constants.CLS_BOX_MAP_PROXY - - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - if not isinstance(expr.wtype, wtypes.WBoxMapProxy): - raise InternalError( - "BoxMapProxyExpressionBuilder can only be created with expressions of " - f"wtype {wtypes.WBoxMapProxy}", - expr.source_location, - ) - self.wtype = expr.wtype - super().__init__(expr) +class BoxMapProxyExpressionBuilder(ValueExpressionBuilder[pytypes.StorageMapProxyType]): + def __init__(self, expr: Expression, typ: pytypes.PyType, member_name: str | None = None): + assert isinstance(typ, pytypes.StorageMapProxyType) + assert typ.generic == pytypes.GenericBoxMapType + self._typ = typ + self._member_name = member_name + super().__init__(typ, expr) + @typing.override def index( self, index: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: return BoxValueExpressionBuilder( - box_value=_box_value_expr(self.expr, index, location), - box_key=_box_key_expr(self.expr, index, location), + self._typ.content, + _box_value_expr(self.expr, index, location, self._typ.content.wtype), ) + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "length": - return BoxMapLengthMethodExpressionBuilder(location, box_map_expr=self.expr) + return _Length(location, self.expr, self._typ) case "maybe": - return BoxMapMaybeMethodExpressionBuilder(location, box_map_expr=self.expr) + return _Maybe(location, self.expr, self._typ) case "get": - return BoxMapGetMethodExpressionBuilder(location, box_map_expr=self.expr) + return _Get(location, self.expr, self._typ) case _: return super().member_access(name, location) + @typing.override def contains( self, item: ExpressionBuilder | Literal, location: SourceLocation ) -> ExpressionBuilder: box_exists = StateExists( - field=_box_key_expr(self.expr, item, location), + field=_box_value_expr(self.expr, item, location, self._typ.content.wtype), source_location=location, ) return BoolExpressionBuilder(box_exists) -class BoxMapMethodExpressionBuilder(IntermediateExpressionBuilder): - box_wtype: wtypes.WBoxMapProxy +class _BoxMapProxyExpressionBuilderFromConstructor( + BoxMapProxyExpressionBuilder, StorageProxyConstructorResult +): + def __init__(self, key_prefix_override: Expression, typ: pytypes.StorageMapProxyType): + super().__init__(key_prefix_override, typ, member_name=None) + + @typing.override + @property + def initial_value(self) -> Expression | None: + return None + + @typing.override + def build_definition( + self, + member_name: str, + defined_in: ContractReference, + typ: pytypes.PyType, + location: SourceLocation, + ) -> AppStorageDeclaration: + key_override = self.expr + if not isinstance(key_override, BytesConstant): + raise CodeError( + f"assigning {typ} to a member variable requires a constant value for key_prefix", + location, + ) + return AppStorageDeclaration( + description=None, + member_name=member_name, + key_override=key_override, + source_location=location, + typ=typ, + defined_in=defined_in, + ) + - def __init__(self, location: SourceLocation, box_map_expr: Expression) -> None: +class _MethodBase(FunctionBuilder): + def __init__( + self, + location: SourceLocation, + box_map_expr: Expression, + box_type: pytypes.StorageMapProxyType, + ) -> None: super().__init__(location) self.box_map_expr = box_map_expr - if not isinstance(box_map_expr.wtype, wtypes.WBoxMapProxy): - raise InternalError(f"box_map_expr wtype must be {wtypes.WBoxMapProxy}", location) - self.box_wtype = box_map_expr.wtype + self.box_type = box_type -class BoxMapLengthMethodExpressionBuilder(BoxMapMethodExpressionBuilder): +class _Length(_MethodBase): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -216,14 +219,17 @@ def call( if args_map: raise CodeError("Invalid/unexpected args", location) return UInt64ExpressionBuilder( - BoxLength( - box_key=_box_key_expr(self.box_map_expr, item_key, location), - source_location=location, + box_length_checked( + _box_value_expr( + self.box_map_expr, item_key, location, self.box_type.content.wtype + ), + location, ) ) -class BoxMapGetMethodExpressionBuilder(BoxMapMethodExpressionBuilder): +class _Get(_MethodBase): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -234,20 +240,16 @@ def call( ) -> ExpressionBuilder: args_map = get_arg_mapping(("key", "default"), zip(arg_names, args, strict=True), location) item_key = args_map.pop("key") - default_value = expect_operand_wtype(args_map.pop("default"), self.box_wtype.content_wtype) + default_value = expect_operand_wtype(args_map.pop("default"), self.box_type.content.wtype) if args_map: raise CodeError("Invalid/unexpected args", location) - # TODO: use pytype - return var_expression( - StateGet( - default=default_value, - field=_box_key_expr(self.box_map_expr, item_key, location), - source_location=location, - ) - ) + key = _box_value_expr(self.box_map_expr, item_key, location, self.box_type.content.wtype) + result_expr = StateGet(default=default_value, field=key, source_location=location) + return builder_for_instance(self.box_type.content, result_expr) -class BoxMapMaybeMethodExpressionBuilder(BoxMapMethodExpressionBuilder): +class _Maybe(_MethodBase): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -260,9 +262,35 @@ def call( item_key = args_map.pop("key") if args_map: raise CodeError("Invalid/unexpected args", location) + + result_typ = pytypes.GenericTupleType.parameterise( + [self.box_type.content, pytypes.BoolType], location + ) return TupleExpressionBuilder( StateGetEx( - field=_box_key_expr(self.box_map_expr, item_key, location), + field=_box_value_expr( + self.box_map_expr, item_key, location, self.box_type.content.wtype + ), source_location=location, - ) + ), + result_typ, ) + + +def _box_value_expr( + key_prefix: Expression, + key: ExpressionBuilder | Literal, + location: SourceLocation, + content_type: wtypes.WType, +) -> BoxValueExpression: + prefix = expect_operand_wtype(key_prefix, wtypes.bytes_wtype) + key_data = require_expression_builder(key).rvalue() + if key_data.wtype != wtypes.bytes_wtype: + key_data = BytesRaw(expr=key_data, source_location=location) + full_key = intrinsic_factory.concat(prefix, key_data, location) + return BoxValueExpression( + key=full_key, + wtype=content_type, + member_name=None, # TODO: can/should we set this?? + source_location=location, + ) diff --git a/src/puya/awst_build/eb/box/box_ref.py b/src/puya/awst_build/eb/box/box_ref.py index c406af37f..42b7c8594 100644 --- a/src/puya/awst_build/eb/box/box_ref.py +++ b/src/puya/awst_build/eb/box/box_ref.py @@ -5,38 +5,42 @@ from puya.awst import wtypes from puya.awst.nodes import ( - BoxKeyExpression, - BoxLength, - BoxProxyExpression, + BoxValueExpression, + BytesConstant, + ContractReference, Expression, IntrinsicCall, Literal, Not, StateExists, ) -from puya.awst_build import constants, pytypes +from puya.awst_build import pytypes +from puya.awst_build.contract_data import AppStorageDeclaration +from puya.awst_build.eb._storage import StorageProxyDefinitionBuilder, extract_key_override from puya.awst_build.eb.base import ( ExpressionBuilder, - IntermediateExpressionBuilder, + FunctionBuilder, + StorageProxyConstructorResult, TypeClassExpressionBuilder, ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder from puya.awst_build.eb.box._common import BoxGetExpressionBuilder, BoxMaybeExpressionBuilder +from puya.awst_build.eb.box._util import box_length_checked from puya.awst_build.eb.uint64 import UInt64ExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.eb.void import VoidExpressionBuilder from puya.awst_build.utils import ( expect_operand_wtype, get_arg_mapping, ) -from puya.errors import CodeError, InternalError +from puya.errors import CodeError from puya.parse import SourceLocation -class BoxRefClassExpressionBuilder(TypeClassExpressionBuilder): +class BoxRefClassExpressionBuilder(TypeClassExpressionBuilder[pytypes.StorageProxyType]): def __init__(self, location: SourceLocation) -> None: - super().__init__(wtypes.box_ref_proxy_type, location) + super().__init__(pytypes.BoxRefType, location) @typing.override def call( @@ -47,40 +51,37 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: - arg_map = get_arg_mapping( + arg_mapping = get_arg_mapping( positional_arg_names=(), args=zip(arg_names, args, strict=True), location=location, ) - key = expect_operand_wtype(arg_map.pop("key"), wtypes.bytes_wtype) - - if arg_map: + key_arg = arg_mapping.pop("key", None) + if arg_mapping: raise CodeError("Invalid/unhandled arguments", location) - return BoxRefProxyExpressionBuilder( - expr=BoxProxyExpression(key=key, wtype=self.produces(), source_location=location) - ) - - -class BoxRefProxyExpressionBuilder(ValueExpressionBuilder): - def __init__(self, expr: Expression) -> None: - if expr.wtype != wtypes.box_ref_proxy_type: - raise InternalError( - "BoxRefProxyExpressionBuilder can only be created with expressions of " - f"wtype {wtypes.box_ref_proxy_type}", - expr.source_location, + key_override = extract_key_override(key_arg, location, is_prefix=False) + if key_override is None: + return StorageProxyDefinitionBuilder( + self.produces2(), location=location, description=None ) - self.wtype = expr.wtype + return _BoxRefProxyExpressionBuilderFromConstructor(expr=key_override) - super().__init__(expr) - self.python_name = constants.CLS_BOX_REF_PROXY - def _box_key_expr(self, location: SourceLocation) -> BoxKeyExpression: - return BoxKeyExpression( - proxy=self.expr, +class BoxRefProxyExpressionBuilder(ValueExpressionBuilder[pytypes.StorageProxyType]): + def __init__(self, expr: Expression, member_name: str | None = None): + super().__init__(pytypes.BoxRefType, expr) + self._member_name = member_name + + def _box_key_expr(self, location: SourceLocation) -> BoxValueExpression: + return BoxValueExpression( + key=self.expr, source_location=location, + wtype=wtypes.bytes_wtype, + member_name=self._member_name, ) + @typing.override def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: box_exists = StateExists( field=self._box_key_expr(location), @@ -90,64 +91,101 @@ def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> Expres Not(expr=box_exists, source_location=location) if negate else box_exists ) + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "create": - return BoxRefCreateExpressionBuilder(location, box_proxy=self.expr) + return _Create(location, box_proxy=self.expr) case "delete": - return BoxRefIntrinsicMethodExpressionBuilder( + return _IntrinsicMethod( location, box_proxy=self.expr, op_code="box_del", arg_wtypes=(), args=(), - return_wtype=wtypes.bool_wtype, + return_type=pytypes.BoolType, ) case "extract": - return BoxRefIntrinsicMethodExpressionBuilder( + return _IntrinsicMethod( location, box_proxy=self.expr, op_code="box_extract", arg_wtypes=(wtypes.uint64_wtype, wtypes.uint64_wtype), args=("start_index", "length"), - return_wtype=wtypes.bytes_wtype, + return_type=pytypes.BytesType, ) case "resize": raise NotImplementedError("TODO: BoxRef.resize handler") case "replace": - return BoxRefIntrinsicMethodExpressionBuilder( + return _IntrinsicMethod( location, box_proxy=self.expr, op_code="box_replace", arg_wtypes=(wtypes.uint64_wtype, wtypes.bytes_wtype), args=("start_index", "value"), - return_wtype=wtypes.void_wtype, + return_type=pytypes.NoneType, ) case "splice": - return BoxRefIntrinsicMethodExpressionBuilder( + return _IntrinsicMethod( location, box_proxy=self.expr, op_code="box_splice", arg_wtypes=(wtypes.uint64_wtype, wtypes.uint64_wtype, wtypes.bytes_wtype), args=("start_index", "length", "value"), - return_wtype=wtypes.void_wtype, + return_type=pytypes.NoneType, ) case "get": - return BoxGetExpressionBuilder(self._box_key_expr(location)) + return BoxGetExpressionBuilder( + self._box_key_expr(location), content_type=pytypes.BytesType + ) case "put": - return BoxRefPutExpressionBuilder(location, box_proxy=self.expr) + return _Put(location, box_proxy=self.expr) case "maybe": - return BoxMaybeExpressionBuilder(self._box_key_expr(location)) + return BoxMaybeExpressionBuilder( + self._box_key_expr(location), content_type=pytypes.BytesType + ) case "length": return UInt64ExpressionBuilder( - BoxLength(box_key=self._box_key_expr(location), source_location=location) + box_length_checked(self._box_key_expr(location), location) ) case _: return super().member_access(name, location) -class BoxRefIntrinsicMethodExpressionBuilder(IntermediateExpressionBuilder): +class _BoxRefProxyExpressionBuilderFromConstructor( + BoxRefProxyExpressionBuilder, StorageProxyConstructorResult +): + @typing.override + @property + def initial_value(self) -> Expression | None: + return None + + @typing.override + def build_definition( + self, + member_name: str, + defined_in: ContractReference, + typ: pytypes.PyType, + location: SourceLocation, + ) -> AppStorageDeclaration: + key_override = self.expr + if not isinstance(key_override, BytesConstant): + raise CodeError( + f"assigning {typ} to a member variable requires a constant value for key", + location, + ) + return AppStorageDeclaration( + description=None, + member_name=member_name, + key_override=key_override, + source_location=location, + typ=typ, + defined_in=defined_in, + ) + + +class _IntrinsicMethod(FunctionBuilder): def __init__( self, location: SourceLocation, @@ -155,7 +193,7 @@ def __init__( box_proxy: Expression, op_code: str, arg_wtypes: Sequence[wtypes.WType], - return_wtype: wtypes.WType, + return_type: pytypes.PyType, args: Sequence[str], ) -> None: super().__init__(location) @@ -163,8 +201,9 @@ def __init__( self.op_code = op_code self.arg_wtypes = arg_wtypes self.args = args - self.return_wtype = return_wtype + self.return_type = return_type + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -183,21 +222,21 @@ def call( raise CodeError(f"Missing required arg '{er.args[0]}'", location) from None if args_map: raise CodeError("Invalid/unexpected args", location) - return var_expression( - IntrinsicCall( - op_code=self.op_code, - stack_args=[self.box_proxy, *stack_args], - wtype=self.return_wtype, - source_location=location, - ) + result_expr = IntrinsicCall( + op_code=self.op_code, + stack_args=[self.box_proxy, *stack_args], + wtype=self.return_type.wtype, + source_location=location, ) + return builder_for_instance(self.return_type, result_expr) -class BoxRefCreateExpressionBuilder(IntermediateExpressionBuilder): +class _Create(FunctionBuilder): def __init__(self, location: SourceLocation, *, box_proxy: Expression) -> None: super().__init__(location) self.box_proxy = box_proxy + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -221,11 +260,12 @@ def call( ) -class BoxRefPutExpressionBuilder(IntermediateExpressionBuilder): +class _Put(FunctionBuilder): def __init__(self, location: SourceLocation, *, box_proxy: Expression) -> None: super().__init__(location) self.box_proxy = box_proxy + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], diff --git a/src/puya/awst_build/eb/bytes.py b/src/puya/awst_build/eb/bytes.py index 7169a6dbf..3e95251f0 100644 --- a/src/puya/awst_build/eb/bytes.py +++ b/src/puya/awst_build/eb/bytes.py @@ -32,7 +32,7 @@ BuilderBinaryOp, BuilderComparisonOp, ExpressionBuilder, - IntermediateExpressionBuilder, + FunctionBuilder, Iteration, TypeClassExpressionBuilder, ValueExpressionBuilder, @@ -58,7 +58,7 @@ class BytesClassExpressionBuilder(TypeClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.bytes_wtype, location) + super().__init__(pytypes.BytesType, location) @typing.override def call( @@ -96,11 +96,12 @@ def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilde ) -class BytesFromEncodedStrBuilder(IntermediateExpressionBuilder): +class BytesFromEncodedStrBuilder(FunctionBuilder): def __init__(self, location: SourceLocation, encoding: BytesEncoding): super().__init__(location=location) self.encoding = encoding + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -142,7 +143,8 @@ def call( class BytesExpressionBuilder(ValueExpressionBuilder): - wtype = wtypes.bytes_wtype + def __init__(self, expr: Expression): + super().__init__(pytypes.BytesType, expr) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: diff --git a/src/puya/awst_build/eb/bytes_backed.py b/src/puya/awst_build/eb/bytes_backed.py index c61ae9bce..33b87b7e1 100644 --- a/src/puya/awst_build/eb/bytes_backed.py +++ b/src/puya/awst_build/eb/bytes_backed.py @@ -8,20 +8,34 @@ from puya.awst import wtypes from puya.awst.nodes import BytesConstant, BytesEncoding, Expression, Literal, ReinterpretCast from puya.awst_build import pytypes -from puya.awst_build.eb.base import ( - ExpressionBuilder, - IntermediateExpressionBuilder, - TypeClassExpressionBuilder, -) -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.base import ExpressionBuilder, FunctionBuilder, TypeClassExpressionBuilder +from puya.awst_build.eb.var_factory import builder_for_instance from puya.errors import CodeError from puya.parse import SourceLocation +_TPyType_co = typing_extensions.TypeVar( + "_TPyType_co", bound=pytypes.PyType, default=pytypes.PyType, covariant=True +) + + +class BytesBackedClassExpressionBuilder(TypeClassExpressionBuilder[_TPyType_co], abc.ABC): + @typing.override + def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: + typ = self.produces2() + match name: + case "from_bytes": + return _FromBytes(typ, location) + case _: + raise CodeError( + f"{name} is not a valid class or static method on {typ}", + location, + ) + -class FromBytesBuilder(IntermediateExpressionBuilder): - def __init__(self, result_wtype: wtypes.WType, location: SourceLocation): +class _FromBytes(FunctionBuilder): + def __init__(self, result_type: pytypes.PyType, location: SourceLocation): super().__init__(location) - self.result_wtype = result_wtype + self.result_type = result_type @typing.override def call( @@ -41,25 +55,7 @@ def call( arg = eb.rvalue() case _: raise CodeError("Invalid/unhandled arguments", location) - return var_expression( - ReinterpretCast(source_location=location, wtype=self.result_wtype, expr=arg) + result_expr = ReinterpretCast( + source_location=location, wtype=self.result_type.wtype, expr=arg ) - - -_TWType_co = typing_extensions.TypeVar( - "_TWType_co", bound=wtypes.WType, default=wtypes.WType, covariant=True -) - - -class BytesBackedClassExpressionBuilder(TypeClassExpressionBuilder[_TWType_co], abc.ABC): - @typing.override - def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: - wtype = self.produces() - match name: - case "from_bytes": - return FromBytesBuilder(wtype, location) - case _: - raise CodeError( - f"{name} is not a valid class or static method on {wtype}", - location, - ) + return builder_for_instance(self.result_type, result_expr) diff --git a/src/puya/awst_build/eb/contracts.py b/src/puya/awst_build/eb/contracts.py index 0e86287a7..7f9cd63d7 100644 --- a/src/puya/awst_build/eb/contracts.py +++ b/src/puya/awst_build/eb/contracts.py @@ -1,20 +1,26 @@ +import typing +from collections.abc import Sequence + import mypy.nodes import mypy.types from puya import log -from puya.awst import wtypes from puya.awst.nodes import ( AppStateExpression, BaseClassSubroutineTarget, - BoxProxyField, InstanceSubroutineTarget, + Literal, ) from puya.awst_build import pytypes from puya.awst_build.context import ASTConversionModuleContext from puya.awst_build.contract_data import AppStorageDeclaration from puya.awst_build.eb.app_account_state import AppAccountStateExpressionBuilder from puya.awst_build.eb.app_state import AppStateExpressionBuilder -from puya.awst_build.eb.base import ExpressionBuilder, IntermediateExpressionBuilder +from puya.awst_build.eb.base import ( + ExpressionBuilder, + IntermediateExpressionBuilder, + TypeClassExpressionBuilder, +) from puya.awst_build.eb.box import ( BoxMapProxyExpressionBuilder, BoxProxyExpressionBuilder, @@ -24,26 +30,39 @@ BaseClassSubroutineInvokerExpressionBuilder, SubroutineInvokerExpressionBuilder, ) -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import qualified_class_name, resolve_method_from_type_info -from puya.errors import CodeError, InternalError +from puya.errors import CodeError from puya.parse import SourceLocation logger = log.get_logger(__name__) -class ContractTypeExpressionBuilder(IntermediateExpressionBuilder): +class ContractTypeExpressionBuilder(TypeClassExpressionBuilder): def __init__( self, context: ASTConversionModuleContext, + pytype: pytypes.PyType, type_info: mypy.nodes.TypeInfo, location: SourceLocation, ): - super().__init__(location) + super().__init__(pytype, location) self.context = context self._type_info = type_info self._cref = qualified_class_name(type_info) + @typing.override + def call( + self, + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_kinds: list[mypy.nodes.ArgKind], + arg_names: list[str | None], + location: SourceLocation, + ) -> ExpressionBuilder: + raise CodeError("Cannot instantiate contract classes", location) + + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: func_or_dec = resolve_method_from_type_info(self._type_info, name, location) if func_or_dec is None: @@ -65,6 +84,12 @@ def __init__( self.context = context self._type_info = type_info + @typing.override + @property + def pytype(self) -> None: + return None # TODO ? + + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: state_decl = self.context.state_defs(qualified_class_name(self._type_info)).get(name) if state_decl is not None: @@ -89,46 +114,31 @@ def _builder_for_storage_access( storage_decl: AppStorageDeclaration, location: SourceLocation ) -> ExpressionBuilder: match storage_decl.typ: - case pytypes.BoxRefType: - return BoxRefProxyExpressionBuilder( - BoxProxyField( - source_location=storage_decl.source_location, - wtype=wtypes.box_ref_proxy_type, - field_name=storage_decl.member_name, - ) + case pytypes.PyType(generic=pytypes.GenericLocalStateType): + return AppAccountStateExpressionBuilder( + storage_decl.key, storage_decl.typ, storage_decl.member_name + ) + case pytypes.PyType(generic=pytypes.GenericGlobalStateType): + return AppStateExpressionBuilder( + storage_decl.key, storage_decl.typ, storage_decl.member_name ) + case pytypes.BoxRefType: + return BoxRefProxyExpressionBuilder(storage_decl.key, storage_decl.member_name) case pytypes.PyType(generic=pytypes.GenericBoxType): return BoxProxyExpressionBuilder( - BoxProxyField( - source_location=storage_decl.source_location, - wtype=wtypes.WBoxProxy.from_content_type( - storage_decl.definition.storage_wtype - ), - field_name=storage_decl.member_name, - ) + storage_decl.key, storage_decl.typ, storage_decl.member_name ) case pytypes.PyType(generic=pytypes.GenericBoxMapType): - if storage_decl.definition.key_wtype is None: - raise InternalError("BoxMap should have key WType", location) return BoxMapProxyExpressionBuilder( - BoxProxyField( - source_location=storage_decl.source_location, - wtype=wtypes.WBoxMapProxy.from_key_and_content_type( - storage_decl.definition.key_wtype, storage_decl.definition.storage_wtype - ), - field_name=storage_decl.member_name, - ) + storage_decl.key, storage_decl.typ, storage_decl.member_name ) - case pytypes.PyType(generic=pytypes.GenericLocalStateType): - return AppAccountStateExpressionBuilder(storage_decl, location) - case pytypes.PyType(generic=pytypes.GenericGlobalStateType): - return AppStateExpressionBuilder(storage_decl, location) - case _: - return var_expression( + case content_type: + return builder_for_instance( + content_type, AppStateExpression( key=storage_decl.key, - field_name=storage_decl.member_name, - wtype=storage_decl.definition.storage_wtype, + member_name=storage_decl.member_name, + wtype=content_type.wtype, source_location=location, - ) + ), ) diff --git a/src/puya/awst_build/eb/ensure_budget.py b/src/puya/awst_build/eb/ensure_budget.py index be15c1a52..45b7ca011 100644 --- a/src/puya/awst_build/eb/ensure_budget.py +++ b/src/puya/awst_build/eb/ensure_budget.py @@ -12,11 +12,8 @@ SubroutineCallExpression, UInt64Constant, ) -from puya.awst_build.eb.base import ( - ExpressionBuilder, - IntermediateExpressionBuilder, - TypeClassExpressionBuilder, -) +from puya.awst_build import pytypes +from puya.awst_build.eb.base import ExpressionBuilder, FunctionBuilder, TypeClassExpressionBuilder from puya.awst_build.eb.void import VoidExpressionBuilder from puya.awst_build.utils import expect_operand_wtype, get_arg_mapping from puya.errors import CodeError @@ -26,11 +23,10 @@ import mypy.types - from puya.awst_build import pytypes from puya.parse import SourceLocation -class EnsureBudgetBuilder(IntermediateExpressionBuilder): +class EnsureBudgetBuilder(FunctionBuilder): @typing.override def call( self, @@ -91,7 +87,7 @@ def call( class OpUpFeeSourceClassBuilder(TypeClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.uint64_wtype, location) + super().__init__(pytypes.UInt64Type, location) @typing.override def call( diff --git a/src/puya/awst_build/eb/intrinsics.py b/src/puya/awst_build/eb/intrinsics.py index ccd947355..9d85d98c1 100644 --- a/src/puya/awst_build/eb/intrinsics.py +++ b/src/puya/awst_build/eb/intrinsics.py @@ -5,13 +5,16 @@ from puya import log from puya.awst.nodes import Expression, IntrinsicCall, Literal, MethodConstant from puya.awst_build.constants import ARC4_SIGNATURE_ALIAS -from puya.awst_build.eb.base import ExpressionBuilder, IntermediateExpressionBuilder +from puya.awst_build.eb.base import ( + ExpressionBuilder, + FunctionBuilder, + IntermediateExpressionBuilder, +) from puya.awst_build.eb.bytes import BytesExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.intrinsic_models import FunctionOpMapping, PropertyOpMapping from puya.awst_build.utils import convert_literal, get_arg_mapping from puya.errors import CodeError -from puya.utils import StableSet if typing.TYPE_CHECKING: from collections.abc import Mapping, Sequence @@ -24,7 +27,7 @@ logger = log.get_logger(__name__) -class Arc4SignatureBuilder(IntermediateExpressionBuilder): +class Arc4SignatureBuilder(FunctionBuilder): @typing.override def call( self, @@ -54,6 +57,11 @@ def __init__(self, type_name: str, data: Mapping[str, str], location: SourceLoca self._type_name = type_name self._data = data + @typing.override + @property + def pytype(self) -> None: # TODO: ?? + return None + @typing.override def call( self, @@ -84,6 +92,11 @@ def __init__( self._type_name = type_name self._data = data + @typing.override + @property + def pytype(self) -> None: # TODO: ?? + return None + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: mapping = self._data.get(name) @@ -96,13 +109,13 @@ def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilde wtype=mapping.typ.wtype, source_location=location, ) - return var_expression(intrinsic_expr) + return builder_for_instance(mapping.typ, intrinsic_expr) else: fullname = ".".join((self._type_name, name)) return IntrinsicFunctionExpressionBuilder(fullname, mapping, location) -class IntrinsicFunctionExpressionBuilder(IntermediateExpressionBuilder): +class IntrinsicFunctionExpressionBuilder(FunctionBuilder): def __init__( self, fullname: str, mappings: Sequence[FunctionOpMapping], location: SourceLocation ) -> None: @@ -123,20 +136,17 @@ def call( primary_mapping = self._mappings[0] # TODO: remove this assumption func_arg_names = (*primary_mapping.literal_arg_names, *primary_mapping.stack_inputs.keys()) - resolved_args: list[Expression | Literal] = [ - a.rvalue() if isinstance(a, ExpressionBuilder) else a for a in args - ] arg_mapping = get_arg_mapping( - func_arg_names, args=zip(arg_names, resolved_args, strict=False), location=location + func_arg_names, args=zip(arg_names, args, strict=False), location=location ) intrinsic_expr = _map_call( self._mappings, callee=self._fullname, node_location=location, args=arg_mapping ) - return var_expression(intrinsic_expr) + return intrinsic_expr def _best_op_mapping( - op_mappings: Sequence[FunctionOpMapping], args: dict[str, Expression | Literal] + op_mappings: Sequence[FunctionOpMapping], args: dict[str, ExpressionBuilder | Literal] ) -> FunctionOpMapping: """Find op mapping that matches as many arguments to immediate args as possible""" literal_arg_names = {arg_name for arg_name, arg in args.items() if isinstance(arg, Literal)} @@ -151,8 +161,8 @@ def _map_call( ast_mapper: Sequence[FunctionOpMapping], callee: str, node_location: SourceLocation, - args: dict[str, Expression | Literal], -) -> IntrinsicCall: + args: dict[str, ExpressionBuilder | Literal], +) -> ExpressionBuilder: if len(ast_mapper) == 1: (op_mapping,) = ast_mapper else: @@ -183,26 +193,23 @@ def _map_call( stack_args = list[Expression]() for arg_name, allowed_pytypes in op_mapping.stack_inputs.items(): - allowed_types = StableSet.from_iter( # TODO: use PyTypes instead - pt.wtype for pt in allowed_pytypes - ) arg_in = args.pop(arg_name, None) if arg_in is None: logger.error(f"Missing expected argument {arg_name}", location=node_location) - elif isinstance(arg_in, Expression): - # TODO this is identity based, match types instead? - if arg_in.wtype not in allowed_types: + elif isinstance(arg_in, ExpressionBuilder): + if arg_in.pytype not in allowed_pytypes: logger.error( - f'Invalid argument type "{arg_in.wtype}"' + f'Invalid argument type "{arg_in.pytype}"' f' for argument "{arg_name}" when calling {callee}', location=arg_in.source_location, ) - stack_args.append(arg_in) + stack_args.append(arg_in.rvalue()) else: literal_value = arg_in.value - for allowed_type in allowed_types: - if allowed_type.is_valid_literal(literal_value): - literal_expr = convert_literal(arg_in, allowed_type) + for allowed_type in allowed_pytypes: + allowed_wtype = allowed_type.wtype # TODO yeet me + if allowed_wtype.is_valid_literal(literal_value): + literal_expr = convert_literal(arg_in, allowed_wtype) stack_args.append(literal_expr) break else: @@ -214,10 +221,11 @@ def _map_call( for arg_node in args.values(): logger.error("Unexpected argument", location=arg_node.source_location) - return IntrinsicCall( + result_expr = IntrinsicCall( op_code=op_mapping.op_code, wtype=op_mapping.result.wtype, immediates=immediates, stack_args=stack_args, source_location=node_location, ) + return builder_for_instance(op_mapping.result, result_expr) diff --git a/src/puya/awst_build/eb/log.py b/src/puya/awst_build/eb/log.py index 9a55af440..c0b48cea6 100644 --- a/src/puya/awst_build/eb/log.py +++ b/src/puya/awst_build/eb/log.py @@ -13,10 +13,7 @@ UInt64Constant, ) from puya.awst_build import intrinsic_factory, pytypes -from puya.awst_build.eb.base import ( - ExpressionBuilder, - IntermediateExpressionBuilder, -) +from puya.awst_build.eb.base import ExpressionBuilder, FunctionBuilder from puya.awst_build.eb.void import VoidExpressionBuilder from puya.awst_build.utils import expect_operand_wtype from puya.errors import CodeError @@ -29,7 +26,8 @@ from puya.parse import SourceLocation -class LogBuilder(IntermediateExpressionBuilder): +class LogBuilder(FunctionBuilder): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], diff --git a/src/puya/awst_build/eb/reference_types/account.py b/src/puya/awst_build/eb/reference_types/account.py index 61bd0c881..8e409f6e5 100644 --- a/src/puya/awst_build/eb/reference_types/account.py +++ b/src/puya/awst_build/eb/reference_types/account.py @@ -2,8 +2,6 @@ import typing -from immutabledict import immutabledict - from puya import log from puya.algo_constants import ENCODED_ADDRESS_LENGTH from puya.awst import wtypes @@ -23,11 +21,7 @@ UInt64Constant, ) from puya.awst_build import intrinsic_factory, pytypes -from puya.awst_build.eb.base import ( - BuilderComparisonOp, - ExpressionBuilder, - IntermediateExpressionBuilder, -) +from puya.awst_build.eb.base import BuilderComparisonOp, ExpressionBuilder, FunctionBuilder from puya.awst_build.eb.bool import BoolExpressionBuilder from puya.awst_build.eb.bytes_backed import BytesBackedClassExpressionBuilder from puya.awst_build.eb.reference_types.base import ReferenceValueExpressionBuilder @@ -47,7 +41,7 @@ class AccountClassExpressionBuilder(BytesBackedClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.account_wtype, location) + super().__init__(pytypes.AccountType, location) @typing.override def call( @@ -94,11 +88,78 @@ def call( return AccountExpressionBuilder(value) -class AccountOptedInExpressionBuilder(IntermediateExpressionBuilder): +class AccountExpressionBuilder(ReferenceValueExpressionBuilder): + def __init__(self, expr: Expression): + native_type = pytypes.BytesType + native_access_member = "bytes" + field_mapping = { + "balance": ("AcctBalance", pytypes.UInt64Type), + "min_balance": ("AcctMinBalance", pytypes.UInt64Type), + "auth_address": ("AcctAuthAddr", pytypes.AccountType), + "total_num_uint": ("AcctTotalNumUint", pytypes.UInt64Type), + "total_num_byte_slice": ("AcctTotalNumByteSlice", pytypes.UInt64Type), + "total_extra_app_pages": ("AcctTotalExtraAppPages", pytypes.UInt64Type), + "total_apps_created": ("AcctTotalAppsCreated", pytypes.UInt64Type), + "total_apps_opted_in": ("AcctTotalAppsOptedIn", pytypes.UInt64Type), + "total_assets_created": ("AcctTotalAssetsCreated", pytypes.UInt64Type), + "total_assets": ("AcctTotalAssets", pytypes.UInt64Type), + "total_boxes": ("AcctTotalBoxes", pytypes.UInt64Type), + "total_box_bytes": ("AcctTotalBoxBytes", pytypes.UInt64Type), + } + field_op_code = "acct_params_get" + field_bool_comment = "account funded" + super().__init__( + expr, + typ=pytypes.AccountType, + native_type=native_type, + native_access_member=native_access_member, + field_mapping=field_mapping, + field_op_code=field_op_code, + field_bool_comment=field_bool_comment, + ) + + @typing.override + def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: + if name == "is_opted_in": + return _IsOptedIn(self.expr, location) + return super().member_access(name, location) + + @typing.override + def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: + cmp_with_zero_expr = BytesComparisonExpression( + source_location=location, + lhs=self.expr, + operator=EqualityComparison.eq if negate else EqualityComparison.ne, + rhs=intrinsic_factory.zero_address(location), + ) + + return BoolExpressionBuilder(cmp_with_zero_expr) + + @typing.override + def compare( + self, other: ExpressionBuilder | Literal, op: BuilderComparisonOp, location: SourceLocation + ) -> ExpressionBuilder: + other_expr = convert_literal_to_expr(other, self.wtype) + if not ( + other_expr.wtype == self.wtype # can only compare with other Accounts? + and op in (BuilderComparisonOp.eq, BuilderComparisonOp.ne) + ): + return NotImplemented + cmp_expr = BytesComparisonExpression( + source_location=location, + lhs=self.expr, + operator=EqualityComparison(op.value), + rhs=other_expr, + ) + return BoolExpressionBuilder(cmp_expr) + + +class _IsOptedIn(FunctionBuilder): def __init__(self, expr: Expression, source_location: SourceLocation): super().__init__(source_location) self.expr = expr + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -134,59 +195,3 @@ def call( ) ) raise CodeError("Unexpected argument", location) - - -class AccountExpressionBuilder(ReferenceValueExpressionBuilder): - wtype = wtypes.account_wtype - native_wtype = wtypes.bytes_wtype - native_access_member = "bytes" - field_mapping = immutabledict( - { - "balance": ("AcctBalance", wtypes.uint64_wtype), - "min_balance": ("AcctMinBalance", wtypes.uint64_wtype), - "auth_address": ("AcctAuthAddr", wtypes.account_wtype), - "total_num_uint": ("AcctTotalNumUint", wtypes.uint64_wtype), - "total_num_byte_slice": ("AcctTotalNumByteSlice", wtypes.uint64_wtype), - "total_extra_app_pages": ("AcctTotalExtraAppPages", wtypes.uint64_wtype), - "total_apps_created": ("AcctTotalAppsCreated", wtypes.uint64_wtype), - "total_apps_opted_in": ("AcctTotalAppsOptedIn", wtypes.uint64_wtype), - "total_assets_created": ("AcctTotalAssetsCreated", wtypes.uint64_wtype), - "total_assets": ("AcctTotalAssets", wtypes.uint64_wtype), - "total_boxes": ("AcctTotalBoxes", wtypes.uint64_wtype), - "total_box_bytes": ("AcctTotalBoxBytes", wtypes.uint64_wtype), - } - ) - field_op_code = "acct_params_get" - field_bool_comment = "account funded" - - def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: - if name == "is_opted_in": - return AccountOptedInExpressionBuilder(self.expr, location) - return super().member_access(name, location) - - def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: - cmp_with_zero_expr = BytesComparisonExpression( - source_location=location, - lhs=self.expr, - operator=EqualityComparison.eq if negate else EqualityComparison.ne, - rhs=intrinsic_factory.zero_address(location), - ) - - return BoolExpressionBuilder(cmp_with_zero_expr) - - def compare( - self, other: ExpressionBuilder | Literal, op: BuilderComparisonOp, location: SourceLocation - ) -> ExpressionBuilder: - other_expr = convert_literal_to_expr(other, self.wtype) - if not ( - other_expr.wtype == self.wtype # can only compare with other Accounts? - and op in (BuilderComparisonOp.eq, BuilderComparisonOp.ne) - ): - return NotImplemented - cmp_expr = BytesComparisonExpression( - source_location=location, - lhs=self.expr, - operator=EqualityComparison(op.value), - rhs=other_expr, - ) - return BoolExpressionBuilder(cmp_expr) diff --git a/src/puya/awst_build/eb/reference_types/application.py b/src/puya/awst_build/eb/reference_types/application.py index f36c81c91..264629f2b 100644 --- a/src/puya/awst_build/eb/reference_types/application.py +++ b/src/puya/awst_build/eb/reference_types/application.py @@ -2,11 +2,10 @@ import typing -from immutabledict import immutabledict - from puya import log from puya.awst import wtypes from puya.awst.nodes import Expression, Literal, ReinterpretCast, UInt64Constant +from puya.awst_build import pytypes from puya.awst_build.eb.base import ExpressionBuilder, TypeClassExpressionBuilder from puya.awst_build.eb.reference_types.base import UInt64BackedReferenceValueExpressionBuilder from puya.awst_build.utils import expect_operand_wtype @@ -16,7 +15,6 @@ import mypy.nodes - from puya.awst_build import pytypes from puya.parse import SourceLocation @@ -25,7 +23,7 @@ class ApplicationClassExpressionBuilder(TypeClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.application_wtype, location) + super().__init__(pytypes.ApplicationType, location) @typing.override def call( @@ -54,20 +52,26 @@ def call( class ApplicationExpressionBuilder(UInt64BackedReferenceValueExpressionBuilder): - wtype = wtypes.application_wtype - native_access_member = "id" - field_mapping = immutabledict( - { - "approval_program": ("AppApprovalProgram", wtypes.bytes_wtype), - "clear_state_program": ("AppClearStateProgram", wtypes.bytes_wtype), - "global_num_uint": ("AppGlobalNumUint", wtypes.uint64_wtype), - "global_num_bytes": ("AppGlobalNumByteSlice", wtypes.uint64_wtype), - "local_num_uint": ("AppLocalNumUint", wtypes.uint64_wtype), - "local_num_bytes": ("AppLocalNumByteSlice", wtypes.uint64_wtype), - "extra_program_pages": ("AppExtraProgramPages", wtypes.uint64_wtype), - "creator": ("AppCreator", wtypes.account_wtype), - "address": ("AppAddress", wtypes.account_wtype), + def __init__(self, expr: Expression): + native_access_member = "id" + field_mapping = { + "approval_program": ("AppApprovalProgram", pytypes.BytesType), + "clear_state_program": ("AppClearStateProgram", pytypes.BytesType), + "global_num_uint": ("AppGlobalNumUint", pytypes.UInt64Type), + "global_num_bytes": ("AppGlobalNumByteSlice", pytypes.UInt64Type), + "local_num_uint": ("AppLocalNumUint", pytypes.UInt64Type), + "local_num_bytes": ("AppLocalNumByteSlice", pytypes.UInt64Type), + "extra_program_pages": ("AppExtraProgramPages", pytypes.UInt64Type), + "creator": ("AppCreator", pytypes.AccountType), + "address": ("AppAddress", pytypes.AccountType), } - ) - field_op_code = "app_params_get" - field_bool_comment = "application exists" + field_op_code = "app_params_get" + field_bool_comment = "application exists" + super().__init__( + expr, + typ=pytypes.ApplicationType, + native_access_member=native_access_member, + field_mapping=field_mapping, + field_op_code=field_op_code, + field_bool_comment=field_bool_comment, + ) diff --git a/src/puya/awst_build/eb/reference_types/asset.py b/src/puya/awst_build/eb/reference_types/asset.py index 738eb848a..b6ebbb2f1 100644 --- a/src/puya/awst_build/eb/reference_types/asset.py +++ b/src/puya/awst_build/eb/reference_types/asset.py @@ -2,8 +2,6 @@ import typing -from immutabledict import immutabledict - from puya import log from puya.awst import wtypes from puya.awst.nodes import ( @@ -14,13 +12,14 @@ ReinterpretCast, UInt64Constant, ) +from puya.awst_build import pytypes from puya.awst_build.eb.base import ( ExpressionBuilder, - IntermediateExpressionBuilder, + FunctionBuilder, TypeClassExpressionBuilder, ) from puya.awst_build.eb.reference_types.base import UInt64BackedReferenceValueExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import expect_operand_wtype from puya.errors import CodeError @@ -29,7 +28,6 @@ import mypy.nodes - from puya.awst_build import pytypes from puya.parse import SourceLocation @@ -38,7 +36,7 @@ class AssetClassExpressionBuilder(TypeClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.asset_wtype, location) + super().__init__(pytypes.AssetType, location) @typing.override def call( @@ -67,17 +65,18 @@ def call( ASSET_HOLDING_FIELD_MAPPING: typing.Final = { - "balance": ("AssetBalance", wtypes.uint64_wtype), - "frozen": ("AssetFrozen", wtypes.bool_wtype), + "balance": ("AssetBalance", pytypes.UInt64Type), + "frozen": ("AssetFrozen", pytypes.BoolType), } -class AssetHoldingExpressionBuilder(IntermediateExpressionBuilder): +class AssetHoldingExpressionBuilder(FunctionBuilder): def __init__(self, asset: Expression, holding_field: str, location: SourceLocation): self.asset = asset self.holding_field = holding_field super().__init__(location) + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -89,42 +88,48 @@ def call( match args: case [ExpressionBuilder() as eb]: account_expr = expect_operand_wtype(eb, wtypes.account_wtype) - immediate, wtype = ASSET_HOLDING_FIELD_MAPPING[self.holding_field] + immediate, typ = ASSET_HOLDING_FIELD_MAPPING[self.holding_field] asset_params_get = IntrinsicCall( source_location=location, - wtype=wtypes.WTuple((wtype, wtypes.bool_wtype), location), + wtype=wtypes.WTuple((typ.wtype, wtypes.bool_wtype), location), op_code="asset_holding_get", immediates=[immediate], stack_args=[account_expr, self.asset], ) - return var_expression( - CheckedMaybe(asset_params_get, comment="account opted into asset") + return builder_for_instance( + typ, CheckedMaybe(asset_params_get, comment="account opted into asset") ) case _: raise CodeError("Invalid/unhandled arguments", location) class AssetExpressionBuilder(UInt64BackedReferenceValueExpressionBuilder): - wtype = wtypes.asset_wtype - native_access_member = "id" - field_mapping = immutabledict( - { - "total": ("AssetTotal", wtypes.uint64_wtype), - "decimals": ("AssetDecimals", wtypes.uint64_wtype), - "default_frozen": ("AssetDefaultFrozen", wtypes.bool_wtype), - "unit_name": ("AssetUnitName", wtypes.bytes_wtype), - "name": ("AssetName", wtypes.bytes_wtype), - "url": ("AssetURL", wtypes.bytes_wtype), - "metadata_hash": ("AssetMetadataHash", wtypes.bytes_wtype), - "manager": ("AssetManager", wtypes.account_wtype), - "reserve": ("AssetReserve", wtypes.account_wtype), - "freeze": ("AssetFreeze", wtypes.account_wtype), - "clawback": ("AssetClawback", wtypes.account_wtype), - "creator": ("AssetCreator", wtypes.account_wtype), + def __init__(self, expr: Expression): + native_access_member = "id" + field_mapping = { + "total": ("AssetTotal", pytypes.UInt64Type), + "decimals": ("AssetDecimals", pytypes.UInt64Type), + "default_frozen": ("AssetDefaultFrozen", pytypes.BoolType), + "unit_name": ("AssetUnitName", pytypes.BytesType), + "name": ("AssetName", pytypes.BytesType), + "url": ("AssetURL", pytypes.BytesType), + "metadata_hash": ("AssetMetadataHash", pytypes.BytesType), + "manager": ("AssetManager", pytypes.AccountType), + "reserve": ("AssetReserve", pytypes.AccountType), + "freeze": ("AssetFreeze", pytypes.AccountType), + "clawback": ("AssetClawback", pytypes.AccountType), + "creator": ("AssetCreator", pytypes.AccountType), } - ) - field_op_code = "asset_params_get" - field_bool_comment = "asset exists" + field_op_code = "asset_params_get" + field_bool_comment = "asset exists" + super().__init__( + expr, + typ=pytypes.AssetType, + native_access_member=native_access_member, + field_mapping=field_mapping, + field_op_code=field_op_code, + field_bool_comment=field_bool_comment, + ) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: if name in ASSET_HOLDING_FIELD_MAPPING: diff --git a/src/puya/awst_build/eb/reference_types/base.py b/src/puya/awst_build/eb/reference_types/base.py index d6df37267..ae9834d34 100644 --- a/src/puya/awst_build/eb/reference_types/base.py +++ b/src/puya/awst_build/eb/reference_types/base.py @@ -2,6 +2,8 @@ import typing +from immutabledict import immutabledict + from puya.awst import wtypes from puya.awst.nodes import ( CheckedMaybe, @@ -13,51 +15,85 @@ NumericComparisonExpression, ReinterpretCast, ) +from puya.awst_build import pytypes from puya.awst_build.eb.base import ( BuilderComparisonOp, ExpressionBuilder, ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import convert_literal_to_expr if typing.TYPE_CHECKING: - from immutabledict import immutabledict + + from collections.abc import Mapping from puya.parse import SourceLocation class ReferenceValueExpressionBuilder(ValueExpressionBuilder): - native_wtype: wtypes.WType - native_access_member: str - field_mapping: immutabledict[str, tuple[str, wtypes.WType]] - field_op_code: str - field_bool_comment: str + def __init__( + self, + expr: Expression, + *, + typ: pytypes.PyType, + native_type: pytypes.PyType, + native_access_member: str, + field_mapping: Mapping[str, tuple[str, pytypes.PyType]], + field_op_code: str, + field_bool_comment: str, + ): + super().__init__(typ, expr) + self.native_type = native_type + self.native_access_member = native_access_member + self.field_mapping = immutabledict[str, tuple[str, pytypes.PyType]](field_mapping) + self.field_op_code = field_op_code + self.field_bool_comment = field_bool_comment + @typing.override def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: if name == self.native_access_member: native_cast = ReinterpretCast( - source_location=location, wtype=self.native_wtype, expr=self.expr + expr=self.expr, wtype=self.native_type.wtype, source_location=location ) - return var_expression(native_cast) + return builder_for_instance(self.native_type, native_cast) if name in self.field_mapping: - immediate, wtype = self.field_mapping[name] + immediate, typ = self.field_mapping[name] acct_params_get = IntrinsicCall( source_location=location, - wtype=wtypes.WTuple((wtype, wtypes.bool_wtype), location), + wtype=wtypes.WTuple((typ.wtype, wtypes.bool_wtype), location), op_code=self.field_op_code, immediates=[immediate], stack_args=[self.expr], ) checked_maybe = CheckedMaybe(acct_params_get, comment=self.field_bool_comment) - return var_expression(checked_maybe) + return builder_for_instance(typ, checked_maybe) return super().member_access(name, location) class UInt64BackedReferenceValueExpressionBuilder(ReferenceValueExpressionBuilder): - native_wtype = wtypes.uint64_wtype + def __init__( + self, + expr: Expression, + *, + typ: pytypes.PyType, + native_access_member: str, + field_mapping: Mapping[str, tuple[str, pytypes.PyType]], + field_op_code: str, + field_bool_comment: str, + ): + super().__init__( + expr, + typ=typ, + native_type=pytypes.UInt64Type, + native_access_member=native_access_member, + field_mapping=field_mapping, + field_op_code=field_op_code, + field_bool_comment=field_bool_comment, + ) + @typing.override def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: as_bool = ReinterpretCast( expr=self.expr, @@ -70,6 +106,7 @@ def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> Expres expr = as_bool return BoolExpressionBuilder(expr) + @typing.override def compare( self, other: ExpressionBuilder | Literal, op: BuilderComparisonOp, location: SourceLocation ) -> ExpressionBuilder: diff --git a/src/puya/awst_build/eb/string.py b/src/puya/awst_build/eb/string.py index 3ac2c37f9..a47c999c7 100644 --- a/src/puya/awst_build/eb/string.py +++ b/src/puya/awst_build/eb/string.py @@ -30,7 +30,7 @@ BuilderBinaryOp, BuilderComparisonOp, ExpressionBuilder, - IntermediateExpressionBuilder, + FunctionBuilder, ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder @@ -52,7 +52,7 @@ class StringClassExpressionBuilder(BytesBackedClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.string_wtype, location) + super().__init__(pytypes.StringType, location) @typing.override def call( @@ -77,9 +77,10 @@ def call( class StringExpressionBuilder(ValueExpressionBuilder): - wtype = wtypes.string_wtype + def __init__(self, expr: Expression): + super().__init__(pytypes.StringType, expr) - def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: + def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: match name: case "bytes": return get_bytes_expr_builder(self.expr) @@ -90,7 +91,7 @@ def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilde case "join": return _StringJoin(self.expr, location) case _: - raise CodeError(f"Unrecognised member of {self.wtype}: {name}", location) + return super().member_access(name, location) def augmented_assignment( self, op: BuilderBinaryOp, rhs: ExpressionBuilder | Literal, location: SourceLocation @@ -173,12 +174,13 @@ def contains( return BoolExpressionBuilder(is_substring_expr) -class _StringStartsOrEndsWith(IntermediateExpressionBuilder): +class _StringStartsOrEndsWith(FunctionBuilder): def __init__(self, base: Expression, location: SourceLocation, *, at_start: bool): super().__init__(location) self._base = base self._at_start = at_start + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -229,11 +231,12 @@ def call( return BoolExpressionBuilder(cond) -class _StringJoin(IntermediateExpressionBuilder): +class _StringJoin(FunctionBuilder): def __init__(self, base: Expression, location: SourceLocation): super().__init__(location) self._base = base + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], diff --git a/src/puya/awst_build/eb/struct.py b/src/puya/awst_build/eb/struct.py index ae2866bea..f44c3e317 100644 --- a/src/puya/awst_build/eb/struct.py +++ b/src/puya/awst_build/eb/struct.py @@ -3,7 +3,6 @@ import mypy.nodes import mypy.types -from puya.awst import wtypes from puya.awst.nodes import Expression, FieldExpression, Literal from puya.awst_build import pytypes from puya.awst_build.eb.base import ( @@ -11,18 +10,16 @@ TypeClassExpressionBuilder, ValueExpressionBuilder, ) -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.errors import CodeError from puya.parse import SourceLocation -class StructSubclassExpressionBuilder(TypeClassExpressionBuilder[wtypes.WStructType]): +class StructSubclassExpressionBuilder(TypeClassExpressionBuilder[pytypes.StructType]): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.StructType) # assert pytypes.StructBaseType in typ.mro TODO? - wtype = typ.wtype - assert isinstance(wtype, wtypes.WStructType) - super().__init__(wtype, location) + super().__init__(typ, location) def call( self, @@ -35,17 +32,15 @@ def call( raise NotImplementedError -class StructExpressionBuilder(ValueExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.WStructType) - self.wtype: wtypes.WStructType = expr.wtype - super().__init__(expr) +class StructExpressionBuilder(ValueExpressionBuilder[pytypes.StructType]): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.StructType) + super().__init__(typ, expr) def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder: try: - field_wtype = self.wtype.fields[name] + field_type = self.pytype.fields[name] except KeyError as ex: raise CodeError(f"Invalid struct field: {name}", location) from ex - field_expr = FieldExpression(location, field_wtype, self.expr, name) - return var_expression(field_expr) + field_expr = FieldExpression(location, field_type.wtype, self.expr, name) + return builder_for_instance(field_type, field_expr) diff --git a/src/puya/awst_build/eb/subroutine.py b/src/puya/awst_build/eb/subroutine.py index f52320d1a..4bb79d82f 100644 --- a/src/puya/awst_build/eb/subroutine.py +++ b/src/puya/awst_build/eb/subroutine.py @@ -1,3 +1,4 @@ +import typing from collections.abc import Sequence import mypy.nodes @@ -14,8 +15,8 @@ ) from puya.awst_build import pytypes from puya.awst_build.context import ASTConversionModuleContext -from puya.awst_build.eb.base import ExpressionBuilder, IntermediateExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.base import ExpressionBuilder, FunctionBuilder +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import require_expression_builder from puya.errors import CodeError from puya.parse import SourceLocation @@ -23,7 +24,7 @@ logger = log.get_logger(__name__) -class SubroutineInvokerExpressionBuilder(IntermediateExpressionBuilder): +class SubroutineInvokerExpressionBuilder(FunctionBuilder): def __init__( self, context: ASTConversionModuleContext, @@ -36,6 +37,7 @@ def __init__( self.target = target self.func_type = func_type + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -71,7 +73,7 @@ def call( args=call_args, wtype=result_pytyp.wtype, ) - return var_expression(call_expr) + return builder_for_instance(result_pytyp, call_expr) class BaseClassSubroutineInvokerExpressionBuilder(SubroutineInvokerExpressionBuilder): @@ -88,6 +90,7 @@ def __init__( raise CodeError(f"Couldn't resolve signature of {node.fullname!r}", location) super().__init__(context, target, location, func_type) + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], diff --git a/src/puya/awst_build/eb/template_variables.py b/src/puya/awst_build/eb/template_variables.py index c26e5d8dd..1060bcf6d 100644 --- a/src/puya/awst_build/eb/template_variables.py +++ b/src/puya/awst_build/eb/template_variables.py @@ -5,14 +5,14 @@ from puya.awst.nodes import Literal, TemplateVar from puya.awst_build import pytypes -from puya.awst_build.eb.base import ExpressionBuilder, IntermediateExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.base import ExpressionBuilder, FunctionBuilder +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import get_arg_mapping from puya.errors import CodeError from puya.parse import SourceLocation -class GenericTemplateVariableExpressionBuilder(IntermediateExpressionBuilder): +class GenericTemplateVariableExpressionBuilder(FunctionBuilder): @typing.override def call( self, @@ -25,10 +25,10 @@ def call( raise CodeError("TemplateVar usage requires type parameter", location) -class TemplateVariableExpressionBuilder(IntermediateExpressionBuilder): +class TemplateVariableExpressionBuilder(FunctionBuilder): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.PseudoGenericFunctionType) - self._wtype = typ.return_type.wtype + self.result_type = typ.return_type super().__init__(location) @typing.override @@ -67,13 +67,12 @@ def call( match var_name: case Literal(value=str(str_value)): - return var_expression( - TemplateVar( - name=prefix_value + str_value, - wtype=self._wtype, - source_location=location, - ) + result_expr = TemplateVar( + name=prefix_value + str_value, + wtype=self.result_type.wtype, + source_location=location, ) + return builder_for_instance(self.result_type, result_expr) case _: raise CodeError( "TemplateVars must be declared using a string literal for the variable name" diff --git a/src/puya/awst_build/eb/transaction/base.py b/src/puya/awst_build/eb/transaction/base.py index 01dab823f..505994d8d 100644 --- a/src/puya/awst_build/eb/transaction/base.py +++ b/src/puya/awst_build/eb/transaction/base.py @@ -5,19 +5,19 @@ from puya.awst import wtypes from puya.awst.nodes import TXN_FIELDS -from puya.awst_build.eb.base import ( - ExpressionBuilder, - ValueExpressionBuilder, -) +from puya.awst_build import pytypes +from puya.awst_build.eb.base import ExpressionBuilder, ValueExpressionBuilder from puya.awst_build.eb.transaction.fields import get_field_python_name -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.errors import InternalError if typing.TYPE_CHECKING: from puya.awst.nodes import Expression, Literal, TxnField from puya.parse import SourceLocation -_PYTHON_MEMBER_FIELD_MAP = {get_field_python_name(f): f for f in TXN_FIELDS} +_PYTHON_MEMBER_FIELD_MAP = { + get_field_python_name(f): (f, pytypes.from_basic_wtype(f.wtype)) for f in TXN_FIELDS +} class BaseTransactionExpressionBuilder(ValueExpressionBuilder, abc.ABC): @@ -25,16 +25,20 @@ class BaseTransactionExpressionBuilder(ValueExpressionBuilder, abc.ABC): def get_field_value(self, field: TxnField, location: SourceLocation) -> Expression: ... @abc.abstractmethod - def get_array_member(self, field: TxnField, location: SourceLocation) -> ExpressionBuilder: ... + def get_array_member( + self, field: TxnField, typ: pytypes.PyType, location: SourceLocation + ) -> ExpressionBuilder: ... def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: - if field := _PYTHON_MEMBER_FIELD_MAP[name]: - if field.is_array: - return self.get_array_member(field, location) - else: - expr = self.get_field_value(field, location) - return var_expression(expr) - return super().member_access(name, location) + field_data = _PYTHON_MEMBER_FIELD_MAP.get(name) + if field_data is None: + return super().member_access(name, location) + field, typ = field_data + if field.is_array: + return self.get_array_member(field, typ, location) + else: + expr = self.get_field_value(field, location) + return builder_for_instance(typ, expr) _WType = typing.TypeVar("_WType", bound=wtypes.WType) diff --git a/src/puya/awst_build/eb/transaction/group.py b/src/puya/awst_build/eb/transaction/group.py index e718c676b..65561db62 100644 --- a/src/puya/awst_build/eb/transaction/group.py +++ b/src/puya/awst_build/eb/transaction/group.py @@ -1,6 +1,5 @@ from __future__ import annotations -import abc import typing from puya.awst import wtypes @@ -16,16 +15,10 @@ TxnField, UInt64Constant, ) -from puya.awst_build.eb.base import ( - ExpressionBuilder, - IntermediateExpressionBuilder, - TypeClassExpressionBuilder, -) -from puya.awst_build.eb.transaction.base import ( - BaseTransactionExpressionBuilder, - expect_wtype, -) -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build import pytypes +from puya.awst_build.eb.base import ExpressionBuilder, FunctionBuilder, TypeClassExpressionBuilder +from puya.awst_build.eb.transaction.base import BaseTransactionExpressionBuilder +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import expect_operand_wtype from puya.errors import CodeError @@ -34,15 +27,44 @@ import mypy.nodes - from puya.awst_build import pytypes from puya.parse import SourceLocation +class GroupTransactionClassExpressionBuilder( + TypeClassExpressionBuilder[pytypes.TransactionRelatedType] +): + @typing.override + def call( + self, + args: Sequence[ExpressionBuilder | Literal], + arg_typs: Sequence[pytypes.PyType], + arg_kinds: list[mypy.nodes.ArgKind], + arg_names: list[str | None], + location: SourceLocation, + ) -> ExpressionBuilder: + match args: + case [ExpressionBuilder() as eb]: + group_index = expect_operand_wtype(eb, wtypes.uint64_wtype) + case [Literal(value=int(int_value), source_location=loc)]: + group_index = UInt64Constant(value=int_value, source_location=loc) + case _: + raise CodeError("Invalid/unhandled arguments", location) + typ = self.produces2() + wtype = typ.wtype + txn = ( + check_transaction_type(group_index, wtype, location) + if isinstance(wtype, wtypes.WGroupTransaction) and wtype.transaction_type is not None + else ReinterpretCast(expr=group_index, wtype=wtype, source_location=location) + ) + return GroupTransactionExpressionBuilder(txn, typ) + + class GroupTransactionExpressionBuilder(BaseTransactionExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - self.wtype = expect_wtype(expr, wtypes.WGroupTransaction) - super().__init__(expr) + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert typ == pytypes.GroupTransactionBaseType or isinstance( + typ, pytypes.TransactionRelatedType + ) + super().__init__(typ, expr) def get_field_value(self, field: TxnField, location: SourceLocation) -> Expression: return IntrinsicCall( @@ -53,21 +75,26 @@ def get_field_value(self, field: TxnField, location: SourceLocation) -> Expressi stack_args=[self.expr], ) - def get_array_member(self, field: TxnField, location: SourceLocation) -> ExpressionBuilder: - return GroupTransactionArrayExpressionBuilder(self.expr, field, location) + def get_array_member( + self, field: TxnField, typ: pytypes.PyType, location: SourceLocation + ) -> ExpressionBuilder: + return _ArrayItem(self.expr, field, typ, location) -class GroupTransactionArrayExpressionBuilder(IntermediateExpressionBuilder): +class _ArrayItem(FunctionBuilder): def __init__( self, transaction: Expression, field: TxnField, + typ: pytypes.PyType, location: SourceLocation, ): super().__init__(location) + self.typ = typ self.transaction = transaction self.field = field + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -81,13 +108,13 @@ def call( (arg,) = args index_expr = expect_operand_wtype(arg, wtypes.uint64_wtype) expr = IntrinsicCall( - source_location=location, - wtype=self.field.wtype, op_code="gtxnsas", immediates=[self.field.immediate], stack_args=[self.transaction, index_expr], + wtype=self.typ.wtype, + source_location=location, ) - return var_expression(expr) + return builder_for_instance(self.typ, expr) def check_transaction_type( @@ -123,35 +150,3 @@ def check_transaction_type( comment=f"transaction type is {expected_transaction_type.transaction_type.name}", ), ) - - -class GroupTransactionClassExpressionBuilder( - TypeClassExpressionBuilder[wtypes.WGroupTransaction], abc.ABC -): - def __init__(self, location: SourceLocation, wtype: wtypes.WGroupTransaction): - super().__init__(wtype, location) - self.wtype = wtype - - @typing.override - def call( - self, - args: Sequence[ExpressionBuilder | Literal], - arg_typs: Sequence[pytypes.PyType], - arg_kinds: list[mypy.nodes.ArgKind], - arg_names: list[str | None], - location: SourceLocation, - ) -> ExpressionBuilder: - match args: - case [ExpressionBuilder() as eb]: - group_index = expect_operand_wtype(eb, wtypes.uint64_wtype) - case [Literal(value=int(int_value), source_location=loc)]: - group_index = UInt64Constant(value=int_value, source_location=loc) - case _: - raise CodeError("Invalid/unhandled arguments", location) - wtype = self.wtype - txn = ( - check_transaction_type(group_index, wtype, location) - if isinstance(wtype, wtypes.WGroupTransaction) and wtype.transaction_type is not None - else ReinterpretCast(expr=group_index, wtype=wtype, source_location=location) - ) - return GroupTransactionExpressionBuilder(txn) diff --git a/src/puya/awst_build/eb/transaction/inner.py b/src/puya/awst_build/eb/transaction/inner.py index c58eb0062..9ae5e2cbe 100644 --- a/src/puya/awst_build/eb/transaction/inner.py +++ b/src/puya/awst_build/eb/transaction/inner.py @@ -10,17 +10,15 @@ SubmitInnerTransaction, TxnField, ) +from puya.awst_build import pytypes from puya.awst_build.eb.base import ( ExpressionBuilder, - IntermediateExpressionBuilder, + FunctionBuilder, TypeClassExpressionBuilder, ) -from puya.awst_build.eb.transaction.base import ( - BaseTransactionExpressionBuilder, - expect_wtype, -) +from puya.awst_build.eb.transaction.base import BaseTransactionExpressionBuilder from puya.awst_build.eb.tuple import TupleExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import expect_operand_wtype from puya.errors import CodeError @@ -29,22 +27,14 @@ import mypy.nodes - from puya.awst_build import pytypes from puya.awst_build.constants import TransactionType from puya.parse import SourceLocation -class InnerTransactionArrayExpressionBuilder(IntermediateExpressionBuilder): - def __init__( - self, - transaction: Expression, - field: TxnField, - location: SourceLocation, - ): - super().__init__(location) - self.transaction = transaction - self.field = field - +class InnerTransactionClassExpressionBuilder( + TypeClassExpressionBuilder[pytypes.TransactionRelatedType] +): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -52,27 +42,19 @@ def call( arg_kinds: list[mypy.nodes.ArgKind], arg_names: list[str | None], location: SourceLocation, - ) -> ExpressionBuilder: - match args: - case [(ExpressionBuilder() | Literal(value=int())) as eb]: - index_expr = expect_operand_wtype(eb, wtypes.uint64_wtype) - expr = InnerTransactionField( - source_location=location, - wtype=self.field.wtype, - itxn=self.transaction, - field=self.field, - array_index=index_expr, - ) - return var_expression(expr) - case _: - raise CodeError("Invalid/unhandled arguments", location) + ) -> typing.Never: + typ = self.produces2() + params_typ = pytypes.InnerTransactionFieldsetTypes[typ.transaction_type] + raise CodeError( + f"{typ} cannot be instantiated directly, create a {params_typ} and submit instead", + location, + ) class InnerTransactionExpressionBuilder(BaseTransactionExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - self.wtype = expect_wtype(expr, wtypes.WInnerTransaction) - super().__init__(expr) + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.TransactionRelatedType) + super().__init__(typ, expr) def get_field_value(self, field: TxnField, location: SourceLocation) -> Expression: return InnerTransactionField( @@ -82,14 +64,24 @@ def get_field_value(self, field: TxnField, location: SourceLocation) -> Expressi wtype=field.wtype, ) - def get_array_member(self, field: TxnField, location: SourceLocation) -> ExpressionBuilder: - return InnerTransactionArrayExpressionBuilder(self.expr, field, location) + def get_array_member( + self, field: TxnField, typ: pytypes.PyType, location: SourceLocation + ) -> ExpressionBuilder: + return _ArrayItem(self.expr, field, typ, location) -class InnerTransactionClassExpressionBuilder(TypeClassExpressionBuilder[wtypes.WInnerTransaction]): - def __init__(self, location: SourceLocation, wtype: wtypes.WInnerTransaction): - super().__init__(wtype, location) - self.wtype = wtype +class _ArrayItem(FunctionBuilder): + def __init__( + self, + transaction: Expression, + field: TxnField, + typ: pytypes.PyType, + location: SourceLocation, + ): + super().__init__(location) + self.typ = typ + self.transaction = transaction + self.field = field @typing.override def call( @@ -99,13 +91,20 @@ def call( arg_kinds: list[mypy.nodes.ArgKind], arg_names: list[str | None], location: SourceLocation, - ) -> typing.Never: - params_wtype = wtypes.WInnerTransactionFields.from_type(self.wtype.transaction_type) - raise CodeError( - f"{self.wtype} cannot be instantiated directly, " - f"create a {params_wtype} and submit instead", - location, - ) + ) -> ExpressionBuilder: + match args: + case [(ExpressionBuilder() | Literal(value=int())) as eb]: + index_expr = expect_operand_wtype(eb, wtypes.uint64_wtype) + expr = InnerTransactionField( + itxn=self.transaction, + field=self.field, + array_index=index_expr, + wtype=self.typ.wtype, + source_location=location, + ) + return builder_for_instance(self.typ, expr) + case _: + raise CodeError("Invalid/unhandled arguments", location) def _get_transaction_type_from_arg( @@ -118,7 +117,8 @@ def _get_transaction_type_from_arg( raise CodeError("Expected an InnerTxnParams argument", literal_or_expr.source_location) -class SubmitInnerTransactionExpressionBuilder(IntermediateExpressionBuilder): +class SubmitInnerTransactionExpressionBuilder(FunctionBuilder): + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -129,12 +129,16 @@ def call( ) -> ExpressionBuilder: if len(args) > 1: transaction_types = {a: _get_transaction_type_from_arg(a) for a in args} + result_typ = pytypes.GenericTupleType.parameterise( + [ + pytypes.InnerTransactionResultTypes[_get_transaction_type_from_arg(a)] + for a in args + ], + location, + ) return TupleExpressionBuilder( SubmitInnerTransaction( - wtype=wtypes.WTuple( - (wtypes.WInnerTransaction.from_type(transaction_types[a]) for a in args), - location, - ), + wtype=result_typ.wtype, itxns=tuple( expect_operand_wtype( a, wtypes.WInnerTransactionFields.from_type(transaction_types[a]) @@ -142,6 +146,7 @@ def call( for a in args ), source_location=location, - ) + ), + result_typ, ) raise CodeError("submit_txns must be called with 2 or more parameters") diff --git a/src/puya/awst_build/eb/transaction/inner_params.py b/src/puya/awst_build/eb/transaction/inner_params.py index e4e699b94..8b5a3ef65 100644 --- a/src/puya/awst_build/eb/transaction/inner_params.py +++ b/src/puya/awst_build/eb/transaction/inner_params.py @@ -15,9 +15,11 @@ UInt64Constant, UpdateInnerTransaction, ) +from puya.awst_build import pytypes +from puya.awst_build.constants import TransactionType from puya.awst_build.eb.base import ( ExpressionBuilder, - IntermediateExpressionBuilder, + FunctionBuilder, TypeClassExpressionBuilder, ValueExpressionBuilder, ) @@ -32,7 +34,6 @@ import mypy.nodes - from puya.awst_build import pytypes from puya.parse import SourceLocation _parameter_mapping: typing.Final = {get_field_python_name(f): f for f in INNER_PARAM_TXN_FIELDS} @@ -84,11 +85,8 @@ def _maybe_transform_program_field_expr( class InnerTxnParamsClassExpressionBuilder( - TypeClassExpressionBuilder[wtypes.WInnerTransactionFields] + TypeClassExpressionBuilder[pytypes.TransactionRelatedType] ): - def __init__(self, source_location: SourceLocation, wtype: wtypes.WInnerTransactionFields): - super().__init__(wtype, source_location) - @typing.override def call( self, @@ -104,7 +102,7 @@ def call( value=0, ) } - transaction_type = self.produces().transaction_type + transaction_type = self.produces2().transaction_type if transaction_type: transaction_fields[TxnFields.type] = UInt64Constant( source_location=self.source_location, @@ -118,21 +116,44 @@ def call( ) field, expression = get_field_expr(arg_name, arg) transaction_fields[field] = expression + typ = self.produces2() + wtype = typ.wtype + assert isinstance(wtype, wtypes.WInnerTransactionFields) return InnerTxnParamsExpressionBuilder( CreateInnerTransaction( - wtype=self.produces(), fields=transaction_fields, + wtype=wtype, source_location=location, - ) + ), + typ, ) -class ParamsSubmitExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, expr: Expression, location: SourceLocation) -> None: +class InnerTxnParamsExpressionBuilder(ValueExpressionBuilder[pytypes.TransactionRelatedType]): + def __init__(self, expr: Expression, typ: pytypes.TransactionRelatedType): + assert isinstance(typ, pytypes.TransactionRelatedType) + super().__init__(typ, expr) + + @typing.override + def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: + if name == "submit": + return _Submit(self.expr, self.pytype.transaction_type, location) + elif name == "set": + return _Set(self.expr, location) + elif name == "copy": + return _Copy(self.expr, self.pytype, location) + return super().member_access(name, location) + + +class _Submit(FunctionBuilder): + def __init__( + self, expr: Expression, txn_type: TransactionType | None, location: SourceLocation + ) -> None: super().__init__(location) - self.wtype = expect_wtype(expr, wtypes.WInnerTransactionFields) + self._txn_type = txn_type self.expr = expr + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -145,21 +166,28 @@ def call( if args: raise CodeError(f"Unexpected arguments for {self.expr}", location) + result_typ = pytypes.InnerTransactionResultTypes[self._txn_type] return InnerTransactionExpressionBuilder( SubmitInnerTransaction( - wtype=wtypes.WInnerTransaction.from_type(self.wtype.transaction_type), itxns=(self.expr,), + wtype=result_typ.wtype, source_location=location, - ) + ), + result_typ, ) -class CopyInnerTxnParamsExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, expr: Expression, location: SourceLocation) -> None: +class _Copy(FunctionBuilder): + def __init__( + self, expr: Expression, typ: pytypes.TransactionRelatedType, location: SourceLocation + ) -> None: super().__init__(location) + self._typ = typ self.wtype = expect_wtype(expr, wtypes.WInnerTransactionFields) + assert typ.wtype == self.wtype self.expr = expr + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -175,15 +203,17 @@ def call( wtype=self.wtype, value=self.expr, source_location=location, - ) + ), + self._typ, ) -class SetInnerTxnParamsExpressionBuilder(IntermediateExpressionBuilder): +class _Set(FunctionBuilder): def __init__(self, expr: Expression, source_location: SourceLocation): super().__init__(source_location) self.expr = expr + @typing.override def call( self, args: Sequence[ExpressionBuilder | Literal], @@ -209,21 +239,3 @@ def call( source_location=location, ) ) - - -class InnerTxnParamsExpressionBuilder(ValueExpressionBuilder): - wtype: wtypes.WInnerTransactionFields - - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - self.wtype = expect_wtype(expr, wtypes.WInnerTransactionFields) - super().__init__(expr) - - def member_access(self, name: str, location: SourceLocation) -> ExpressionBuilder | Literal: - if name == "submit": - return ParamsSubmitExpressionBuilder(self.expr, location) - elif name == "set": - return SetInnerTxnParamsExpressionBuilder(self.expr, location) - elif name == "copy": - return CopyInnerTxnParamsExpressionBuilder(self.expr, location) - return super().member_access(name, location) diff --git a/src/puya/awst_build/eb/tuple.py b/src/puya/awst_build/eb/tuple.py index cf0e554d7..e7b0420d9 100644 --- a/src/puya/awst_build/eb/tuple.py +++ b/src/puya/awst_build/eb/tuple.py @@ -7,7 +7,6 @@ from puya.awst import wtypes from puya.awst.nodes import ( BinaryBooleanOperator, - BoolConstant, BooleanBinaryOperation, Contains, Expression, @@ -29,7 +28,7 @@ ValueExpressionBuilder, ) from puya.awst_build.eb.bool import BoolExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.awst_build.utils import require_expression_builder from puya.errors import CodeError from puya.parse import SourceLocation @@ -48,19 +47,21 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: + typ = pytypes.GenericTupleType.parameterise(arg_typs, location) tuple_expr = TupleExpression.from_items( [require_expression_builder(a).rvalue() for a in args], location ) - return TupleExpressionBuilder(tuple_expr) + return TupleExpressionBuilder(tuple_expr, typ) -class TupleTypeExpressionBuilder(TypeClassExpressionBuilder[wtypes.WTuple]): +class TupleTypeExpressionBuilder(TypeClassExpressionBuilder[pytypes.TupleType]): def __init__(self, typ: pytypes.PyType, location: SourceLocation): assert isinstance(typ, pytypes.TupleType) assert typ.generic == pytypes.GenericTupleType wtype = typ.wtype assert isinstance(wtype, wtypes.WTuple) - super().__init__(wtype, location) + self._wtype = wtype + super().__init__(typ, location) @typing.override def call( @@ -71,20 +72,19 @@ def call( arg_names: list[str | None], location: SourceLocation, ) -> ExpressionBuilder: + tuple_expr = TupleExpression( items=[require_expression_builder(a).rvalue() for a in args], - wtype=self.produces(), + wtype=self._wtype, source_location=location, ) - return TupleExpressionBuilder(tuple_expr) + return TupleExpressionBuilder(tuple_expr, self.produces2()) -class TupleExpressionBuilder(ValueExpressionBuilder): - def __init__(self, expr: Expression, typ: pytypes.PyType | None = None): # TODO - self.pytyp = typ - assert isinstance(expr.wtype, wtypes.WTuple) - self.wtype: wtypes.WTuple = expr.wtype - super().__init__(expr) +class TupleExpressionBuilder(ValueExpressionBuilder[pytypes.TupleType]): + def __init__(self, expr: Expression, typ: pytypes.PyType): + assert isinstance(typ, pytypes.TupleType) + super().__init__(typ, expr) def index( self, index: ExpressionBuilder | Literal, location: SourceLocation @@ -94,25 +94,26 @@ def index( # result type, but also we can statically validate that value index_expr_or_literal = index match index_expr_or_literal: - case Literal(value=int(index_value)) as index_literal: - try: - self.wtype.types[index_value] - except IndexError as ex: - raise CodeError( - "Tuple index out of bounds", index_literal.source_location - ) from ex - item_expr = TupleItemExpression( - base=self.expr, - index=index_value, - source_location=location, - ) - return var_expression(item_expr) + case Literal(value=int(index_value)): + return self._index(index_value, location) case _: raise CodeError( "tuples can only be indexed by int constants", index_expr_or_literal.source_location, ) + def _index(self, index_value: int, location: SourceLocation) -> ExpressionBuilder: + try: + item_typ = self.pytype.items[index_value] + except IndexError as ex: + raise CodeError("Tuple index out of bounds", location) from ex + item_expr = TupleItemExpression( + base=self.expr, + index=index_value, + source_location=location, + ) + return builder_for_instance(item_typ, item_expr) + def slice_index( self, begin_index: ExpressionBuilder | Literal | None, @@ -125,11 +126,12 @@ def slice_index( start_expr, start_idx = self._convert_index(begin_index) end_expr, end_idx = self._convert_index(end_index) - slice_types = self.wtype.types[start_idx:end_idx] + slice_types = self.pytype.items[start_idx:end_idx] if not slice_types: raise CodeError("Empty slices are not supported", location) - updated_wtype = wtypes.WTuple(slice_types, location) + updated_type = pytypes.GenericTupleType.parameterise(slice_types, location) + updated_wtype = updated_type.wtype return TupleExpressionBuilder( SliceExpression( source_location=location, @@ -137,7 +139,8 @@ def slice_index( begin_index=start_expr, end_index=end_expr, wtype=updated_wtype, - ) + ), + updated_type, ) def _convert_index( @@ -148,8 +151,8 @@ def _convert_index( expr = None idx = None case Literal(value=int(idx), source_location=start_loc): - positive_idx = positive_index(idx, self.wtype.types) - positive_idx_clamped = clamp(positive_idx, low=0, high=len(self.wtype.types) - 1) + positive_idx = positive_index(idx, self.pytype.items) + positive_idx_clamped = clamp(positive_idx, low=0, high=len(self.pytype.items) - 1) expr = UInt64Constant(value=positive_idx_clamped, source_location=start_loc) case _: raise CodeError( @@ -187,23 +190,19 @@ def compare( case _: raise CodeError(f"The {op} operator on the tuple type is not supported", location) - other_expr = require_expression_builder(other).rvalue() - if self.wtype != other_expr.wtype: - return BoolExpressionBuilder( - BoolConstant(value=result_if_types_differ, source_location=location) - ) - - def get_index(expr: Expression, idx: int) -> ExpressionBuilder: - item = TupleItemExpression(base=expr, index=idx, source_location=location) - return var_expression(item) + other_eb = require_expression_builder(other) + if not isinstance(other_eb, TupleExpressionBuilder): + return NotImplemented + if self.pytype.items != other_eb.pytype.items: + return bool_eval_to_constant(value=result_if_types_differ, location=location) def compare_at_index(idx: int) -> Expression: - left = get_index(self.expr, idx) - right = get_index(other_expr, idx) + left = self._index(idx, location) + right = other_eb._index(idx, location) # noqa: SLF001 return left.compare(right, op=op, location=location).rvalue() result = compare_at_index(0) - for i in range(1, len(self.wtype.types)): + for i in range(1, len(self.pytype.items)): result = BooleanBinaryOperation( left=result, right=compare_at_index(i), diff --git a/src/puya/awst_build/eb/type_registry.py b/src/puya/awst_build/eb/type_registry.py index ff2fcee05..60d12b368 100644 --- a/src/puya/awst_build/eb/type_registry.py +++ b/src/puya/awst_build/eb/type_registry.py @@ -2,7 +2,6 @@ from collections.abc import Callable import puya.awst_build.eb.arc4.dynamic_bytes -from puya.awst import wtypes from puya.awst.nodes import Expression from puya.awst_build import constants, pytypes from puya.awst_build.eb import ( @@ -32,7 +31,6 @@ from puya.parse import SourceLocation __all__ = [ - "var_expression", "builder_for_instance", "builder_for_type", ] @@ -67,8 +65,8 @@ pytypes.GenericBoxType: box.BoxClassGenericExpressionBuilder, pytypes.BoxRefType: box.BoxRefClassExpressionBuilder, pytypes.GenericBoxMapType: box.BoxMapClassGenericExpressionBuilder, - pytypes.GenericLocalStateType: app_account_state.AppAccountStateClassExpressionBuilder, - pytypes.GenericGlobalStateType: app_state.AppStateClassExpressionBuilder, + pytypes.GenericLocalStateType: app_account_state.AppAccountStateGenericClassExpressionBuilder, + pytypes.GenericGlobalStateType: app_state.AppStateGenericClassExpressionBuilder, pytypes.ARC4AddressType: arc4.AddressClassExpressionBuilder, pytypes.ARC4BoolType: arc4.ARC4BoolClassExpressionBuilder, pytypes.ARC4ByteType: arc4.ByteClassExpressionBuilder, @@ -87,7 +85,7 @@ pytypes.UInt64Type: uint64.UInt64ClassExpressionBuilder, **{ gtxn_pytyp: functools.partial( - transaction.GroupTransactionClassExpressionBuilder, wtype=gtxn_pytyp.wtype + transaction.GroupTransactionClassExpressionBuilder, gtxn_pytyp ) for gtxn_pytyp in ( pytypes.GroupTransactionBaseType, @@ -96,13 +94,13 @@ }, **{ itxn_fieldset_pytyp: functools.partial( - transaction.InnerTxnParamsClassExpressionBuilder, wtype=itxn_fieldset_pytyp.wtype + transaction.InnerTxnParamsClassExpressionBuilder, itxn_fieldset_pytyp ) for itxn_fieldset_pytyp in pytypes.InnerTransactionFieldsetTypes.values() }, **{ itxn_result_pytyp: functools.partial( - transaction.InnerTransactionClassExpressionBuilder, wtype=itxn_result_pytyp.wtype + transaction.InnerTransactionClassExpressionBuilder, itxn_result_pytyp ) for itxn_result_pytyp in pytypes.InnerTransactionResultTypes.values() }, @@ -114,6 +112,8 @@ pytypes.reversedGenericType: unsigned_builtins.ReversedFunctionExpressionBuilder, pytypes.GenericTemplateVarType: template_variables.TemplateVariableExpressionBuilder, pytypes.GenericABICallWithReturnType: arc4.ABICallClassExpressionBuilder, + pytypes.GenericLocalStateType: app_account_state.AppAccountStateClassExpressionBuilder, + pytypes.GenericGlobalStateType: app_state.AppStateClassExpressionBuilder, pytypes.GenericBoxType: box.BoxClassExpressionBuilder, pytypes.GenericBoxMapType: box.BoxMapClassExpressionBuilder, pytypes.GenericARC4TupleType: arc4.ARC4TupleClassExpressionBuilder, @@ -132,44 +132,11 @@ } ExpressionBuilderFromExpressionFactory = Callable[[Expression], ExpressionBuilder] -WTYPE_TO_BUILDER: dict[ - wtypes.WType | type[wtypes.WType], ExpressionBuilderFromExpressionFactory -] = { - wtypes.ARC4DynamicArray: arc4.DynamicArrayExpressionBuilder, - wtypes.ARC4Struct: arc4.ARC4StructExpressionBuilder, - wtypes.ARC4StaticArray: arc4.StaticArrayExpressionBuilder, - wtypes.ARC4Tuple: arc4.ARC4TupleExpressionBuilder, - wtypes.ARC4UFixedNxM: arc4.UFixedNxMExpressionBuilder, - wtypes.ARC4UIntN: arc4.UIntNExpressionBuilder, - wtypes.WArray: array.ArrayExpressionBuilder, - wtypes.WStructType: struct.StructExpressionBuilder, - wtypes.WTuple: tuple_.TupleExpressionBuilder, - wtypes.arc4_bool_wtype: arc4.ARC4BoolExpressionBuilder, - wtypes.arc4_string_wtype: arc4.StringExpressionBuilder, - wtypes.arc4_dynamic_bytes: arc4.DynamicBytesExpressionBuilder, - wtypes.arc4_address_type: arc4.AddressExpressionBuilder, - wtypes.account_wtype: account.AccountExpressionBuilder, - wtypes.application_wtype: application.ApplicationExpressionBuilder, - wtypes.asset_wtype: asset.AssetExpressionBuilder, - wtypes.biguint_wtype: biguint.BigUIntExpressionBuilder, - wtypes.bool_wtype: bool_.BoolExpressionBuilder, - wtypes.bytes_wtype: bytes_.BytesExpressionBuilder, - wtypes.string_wtype: string.StringExpressionBuilder, - wtypes.uint64_wtype: uint64.UInt64ExpressionBuilder, - wtypes.void_wtype: void.VoidExpressionBuilder, - wtypes.WGroupTransaction: transaction.GroupTransactionExpressionBuilder, - wtypes.WInnerTransaction: transaction.InnerTransactionExpressionBuilder, - wtypes.WInnerTransactionFields: transaction.InnerTxnParamsExpressionBuilder, - wtypes.WBoxProxy: box.BoxProxyExpressionBuilder, - wtypes.WBoxMapProxy: box.BoxMapProxyExpressionBuilder, - wtypes.box_ref_proxy_type: box.BoxRefProxyExpressionBuilder, -} - - PYTYPE_TO_BUILDER: dict[pytypes.PyType, ExpressionBuilderFromExpressionFactory] = { pytypes.ARC4BoolType: arc4.ARC4BoolExpressionBuilder, pytypes.ARC4StringType: arc4.StringExpressionBuilder, pytypes.ARC4DynamicBytesType: arc4.DynamicBytesExpressionBuilder, + pytypes.ARC4ByteType: functools.partial(arc4.UIntNExpressionBuilder, typ=pytypes.ARC4ByteType), pytypes.ARC4AddressType: arc4.AddressExpressionBuilder, pytypes.AccountType: account.AccountExpressionBuilder, pytypes.ApplicationType: application.ApplicationExpressionBuilder, @@ -221,6 +188,8 @@ pytypes.GenericARC4BigUFixedNxMType: arc4.UFixedNxMExpressionBuilder, pytypes.GenericARC4UIntNType: arc4.UIntNExpressionBuilder, pytypes.GenericARC4BigUIntNType: arc4.UIntNExpressionBuilder, + pytypes.GenericGlobalStateType: app_state.AppStateExpressionBuilder, + pytypes.GenericLocalStateType: app_account_state.AppAccountStateExpressionBuilder, } PYTYPE_BASE_TO_BUILDER: dict[pytypes.PyType, ExpressionBuilderFromExpressionAndPyTypeFactory] = { pytypes.ARC4StructBaseType: arc4.ARC4StructExpressionBuilder, @@ -239,19 +208,6 @@ def builder_for_instance(pytyp: pytypes.PyType, expr: Expression) -> ExpressionB raise InternalError(f"No builder for instance: {pytyp}", expr.source_location) -def var_expression(expr: Expression) -> ExpressionBuilder: - try: - builder = WTYPE_TO_BUILDER[expr.wtype] - except KeyError: - try: - builder = WTYPE_TO_BUILDER[type(expr.wtype)] - except KeyError: - raise InternalError( - f"Unable to map wtype {expr.wtype!r} to expression builder", expr.source_location - ) from None - return builder(expr) - - def builder_for_type(pytyp: pytypes.PyType, expr_loc: SourceLocation) -> ExpressionBuilder: if tb := PYTYPE_TO_TYPE_BUILDER.get(pytyp): return tb(expr_loc) diff --git a/src/puya/awst_build/eb/uint64.py b/src/puya/awst_build/eb/uint64.py index 4609bb34e..0bd989b6a 100644 --- a/src/puya/awst_build/eb/uint64.py +++ b/src/puya/awst_build/eb/uint64.py @@ -22,6 +22,7 @@ UInt64UnaryOperation, UInt64UnaryOperator, ) +from puya.awst_build import pytypes from puya.awst_build.eb.base import ( BuilderBinaryOp, BuilderComparisonOp, @@ -38,7 +39,6 @@ import mypy.types - from puya.awst_build import pytypes from puya.parse import SourceLocation logger = log.get_logger(__name__) @@ -46,7 +46,7 @@ class UInt64ClassExpressionBuilder(TypeClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.uint64_wtype, location) + super().__init__(pytypes.UInt64Type, location) @typing.override def call( @@ -70,7 +70,8 @@ def call( class UInt64ExpressionBuilder(ValueExpressionBuilder): - wtype = wtypes.uint64_wtype + def __init__(self, expr: Expression): + super().__init__(pytypes.UInt64Type, expr) def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> ExpressionBuilder: as_bool = ReinterpretCast( diff --git a/src/puya/awst_build/eb/unsigned_builtins.py b/src/puya/awst_build/eb/unsigned_builtins.py index 5a800108b..f3dbd811f 100644 --- a/src/puya/awst_build/eb/unsigned_builtins.py +++ b/src/puya/awst_build/eb/unsigned_builtins.py @@ -15,15 +15,14 @@ Reversed, UInt64Constant, ) +from puya.awst_build import pytypes from puya.awst_build.eb.base import ( ExpressionBuilder, IntermediateExpressionBuilder, Iteration, + TypeClassExpressionBuilder, ) -from puya.awst_build.utils import ( - expect_operand_wtype, - require_expression_builder, -) +from puya.awst_build.utils import expect_operand_wtype, require_expression_builder from puya.errors import CodeError if typing.TYPE_CHECKING: @@ -31,13 +30,15 @@ import mypy.types - from puya.awst_build import pytypes from puya.parse import SourceLocation logger = log.get_logger(__name__) -class UnsignedRangeBuilder(IntermediateExpressionBuilder): +class UnsignedRangeBuilder(TypeClassExpressionBuilder): + def __init__(self, location: SourceLocation): + super().__init__(pytypes.urangeType, location) + @typing.override def call( self, @@ -79,15 +80,19 @@ def __init__(self, sequence: Range): super().__init__(location=sequence.source_location) self.sequence = sequence + @typing.override + @property + def pytype(self) -> None: # TODO: ?? + return None + @typing.override def iterate(self) -> Iteration: return self.sequence -class UnsignedEnumerateBuilder(IntermediateExpressionBuilder): - def __init__(self, typ: pytypes.PyType | None, location: SourceLocation): # TODO: remove None - self._pytyp = typ - super().__init__(location) +class UnsignedEnumerateBuilder(TypeClassExpressionBuilder): + def __init__(self, typ: pytypes.PyType, location: SourceLocation): + super().__init__(typ, location) @typing.override def call( @@ -117,6 +122,11 @@ def __init__(self, sequence: Expression | Range, location: SourceLocation): super().__init__(location) self._sequence = sequence + @typing.override + @property + def pytype(self) -> None: # TODO: ?? + return None + @typing.override def iterate(self) -> Iteration: return Enumeration( @@ -125,10 +135,9 @@ def iterate(self) -> Iteration: ) -class ReversedFunctionExpressionBuilder(IntermediateExpressionBuilder): - def __init__(self, typ: pytypes.PyType | None, location: SourceLocation): # TODO: remove None - self._pytyp = typ - super().__init__(location) +class ReversedFunctionExpressionBuilder(TypeClassExpressionBuilder): + def __init__(self, typ: pytypes.PyType, location: SourceLocation): + super().__init__(typ, location) @typing.override def call( @@ -157,6 +166,11 @@ def __init__(self, sequence: Expression | Range, location: SourceLocation): super().__init__(location) self._sequence = sequence + @typing.override + @property + def pytype(self) -> None: # TODO: ?? + return None + @typing.override def iterate(self) -> Iteration: return Reversed( diff --git a/src/puya/awst_build/eb/value_proxy.py b/src/puya/awst_build/eb/value_proxy.py index a1153ad6b..e9bf0e4d0 100644 --- a/src/puya/awst_build/eb/value_proxy.py +++ b/src/puya/awst_build/eb/value_proxy.py @@ -3,7 +3,7 @@ import mypy.nodes import mypy.types -from puya.awst.nodes import Literal, Statement +from puya.awst.nodes import Expression, Literal, Statement from puya.awst_build import pytypes from puya.awst_build.eb.base import ( BuilderBinaryOp, @@ -12,14 +12,17 @@ Iteration, ValueExpressionBuilder, ) -from puya.awst_build.eb.var_factory import var_expression +from puya.awst_build.eb.var_factory import builder_for_instance from puya.parse import SourceLocation class ValueProxyExpressionBuilder(ValueExpressionBuilder): + def __init__(self, typ: pytypes.PyType, expr: Expression): + super().__init__(typ, expr) + @property def _proxied(self) -> ExpressionBuilder: - return var_expression(self.expr) + return builder_for_instance(self.pytype, self.expr) def delete(self, location: SourceLocation) -> Statement: return self._proxied.delete(location) diff --git a/src/puya/awst_build/eb/var_factory.py b/src/puya/awst_build/eb/var_factory.py index d9ce99c7a..506ea9865 100644 --- a/src/puya/awst_build/eb/var_factory.py +++ b/src/puya/awst_build/eb/var_factory.py @@ -1,8 +1,16 @@ from puya.awst.nodes import Expression +from puya.awst_build import pytypes from puya.awst_build.eb.base import ExpressionBuilder +from puya.parse import SourceLocation -def var_expression(expr: Expression) -> ExpressionBuilder: +def builder_for_instance(pytyp: pytypes.PyType, expr: Expression) -> ExpressionBuilder: from puya.awst_build.eb import type_registry - return type_registry.var_expression(expr) + return type_registry.builder_for_instance(pytyp, expr) + + +def builder_for_type(pytyp: pytypes.PyType, expr_loc: SourceLocation) -> ExpressionBuilder: + from puya.awst_build.eb import type_registry + + return type_registry.builder_for_type(pytyp, expr_loc) diff --git a/src/puya/awst_build/eb/void.py b/src/puya/awst_build/eb/void.py index 0f71472c9..2b87d9520 100644 --- a/src/puya/awst_build/eb/void.py +++ b/src/puya/awst_build/eb/void.py @@ -3,8 +3,7 @@ import mypy.nodes -from puya.awst import wtypes -from puya.awst.nodes import Literal +from puya.awst.nodes import Expression, Literal from puya.awst_build import pytypes from puya.awst_build.eb.base import ( ExpressionBuilder, @@ -17,7 +16,7 @@ class VoidTypeExpressionBuilder(TypeClassExpressionBuilder): def __init__(self, location: SourceLocation): - super().__init__(wtypes.void_wtype, location) + super().__init__(pytypes.NoneType, location) @typing.override def call( @@ -33,7 +32,8 @@ def call( class VoidExpressionBuilder(ValueExpressionBuilder): - wtype = wtypes.void_wtype + def __init__(self, expr: Expression): + super().__init__(pytypes.NoneType, expr) def lvalue(self) -> typing.Never: raise CodeError( diff --git a/src/puya/awst_build/pytypes.py b/src/puya/awst_build/pytypes.py index a2add4a5a..e56c8cb22 100644 --- a/src/puya/awst_build/pytypes.py +++ b/src/puya/awst_build/pytypes.py @@ -215,7 +215,6 @@ class TupleType(PyType): @typing.final @attrs.frozen class ArrayType(PyType): - generic: _GenericType items: PyType size: int | None wtype: wtypes.WType @@ -231,7 +230,7 @@ class StorageProxyType(PyType): @typing.final @attrs.frozen class StorageMapProxyType(PyType): - generic: _GenericType + generic: PyType key: PyType content: PyType wtype: wtypes.WType @@ -301,7 +300,7 @@ def __init__( field_wtypes = {name: field_typ.wtype for name, field_typ in fields.items()} # TODO: this is a bit of a kludge wtype_cls: Callable[ - [str, Mapping[str, wtypes.WType], bool, SourceLocation | None], wtypes.WType + [Mapping[str, wtypes.WType], bool, SourceLocation | None], wtypes.WType ] if base is ARC4StructBaseType: wtype_cls = wtypes.ARC4Struct @@ -309,7 +308,7 @@ def __init__( wtype_cls = wtypes.WStructType else: raise InternalError(f"Unknown struct base type: {base}", source_location) - wtype = wtype_cls(name, field_wtypes, frozen, source_location) + wtype = wtype_cls(field_wtypes, frozen, source_location) self.__attrs_init__( bases=[base], mro=[base], @@ -396,19 +395,10 @@ def __attrs_post_init__(self) -> None: name=constants.CLS_ARC4_BOOL, wtype=wtypes.arc4_bool_wtype, ) -ARC4DynamicBytesType: typing.Final[PyType] = _SimpleType( - name=constants.CLS_ARC4_DYNAMIC_BYTES, - wtype=wtypes.arc4_dynamic_bytes, -) -ARC4AddressType: typing.Final[PyType] = _SimpleType( - name=constants.CLS_ARC4_ADDRESS, - wtype=wtypes.arc4_address_type, -) @attrs.frozen class ARC4UIntNType(PyType): - generic: _GenericType bits: int wtype: wtypes.WType @@ -467,15 +457,6 @@ def parameterise( ) -ARC4ByteType: typing.Final[PyType] = _register_builtin( - ARC4UIntNType( - generic=GenericARC4UIntNType, - name=constants.CLS_ARC4_BYTE, - wtype=wtypes.arc4_byte_type, - bits=8, - ) -) - ARC4UIntN_Aliases: typing.Final = immutabledict[int, ARC4UIntNType]( { (_bits := 2**_exp): _register_builtin( @@ -487,6 +468,16 @@ def parameterise( for _exp in range(3, 10) } ) +ARC4ByteType: typing.Final = _register_builtin( + ARC4UIntNType( + generic=None, + name=constants.CLS_ARC4_BYTE, + wtype=wtypes.arc4_byte_type, + bits=8, + bases=[ARC4UIntN_Aliases[8]], + mro=[ARC4UIntN_Aliases[8]], + ) +) @attrs.frozen @@ -586,9 +577,9 @@ def wtype(self) -> typing.Never: def _make_array_parameterise( typ: Callable[[wtypes.WType, SourceLocation | None], wtypes.WType] -) -> _Parameterise: +) -> _Parameterise[ArrayType]: def parameterise( - self: _GenericType, args: _TypeArgs, source_location: SourceLocation | None + self: _GenericType[ArrayType], args: _TypeArgs, source_location: SourceLocation | None ) -> ArrayType: try: (arg,) = args @@ -617,6 +608,16 @@ def parameterise( name=constants.CLS_ARC4_DYNAMIC_ARRAY, parameterise=_make_array_parameterise(wtypes.ARC4DynamicArray), ) +ARC4DynamicBytesType: typing.Final = _register_builtin( + ArrayType( + name=constants.CLS_ARC4_DYNAMIC_BYTES, + wtype=wtypes.arc4_dynamic_bytes, + size=0, + items=ARC4ByteType, + bases=[GenericARC4DynamicArrayType.parameterise([ARC4ByteType], source_location=None)], + mro=[GenericARC4DynamicArrayType.parameterise([ARC4ByteType], source_location=None)], + ) +) def _make_fixed_array_parameterise( @@ -635,7 +636,7 @@ def parameterise( if size < 0: raise CodeError("Array size should be non-negative", source_location) - name = f"{self.name}[{items.name}, {size_t.name}]]" + name = f"{self.name}[{items.name}, {size_t.name}]" return ArrayType( generic=self, name=name, @@ -651,55 +652,51 @@ def parameterise( name=constants.CLS_ARC4_STATIC_ARRAY, parameterise=_make_fixed_array_parameterise(wtypes.ARC4StaticArray), ) +ARC4AddressType: typing.Final = _register_builtin( + ArrayType( + name=constants.CLS_ARC4_ADDRESS, + wtype=wtypes.arc4_address_type, + size=32, + generic=None, + items=ARC4ByteType, + bases=[ + GenericARC4StaticArrayType.parameterise( + [ARC4ByteType, TypingLiteralType(value=32, source_location=None)], + source_location=None, + ) + ], + mro=[ + GenericARC4StaticArrayType.parameterise( + [ARC4ByteType, TypingLiteralType(value=32, source_location=None)], + source_location=None, + ) + ], + ) +) -def _make_storage_parameterise(key_type: wtypes.WType) -> _Parameterise: - def parameterise( - self: _GenericType, args: _TypeArgs, source_location: SourceLocation | None - ) -> StorageProxyType: - try: - (arg,) = args - except ValueError: - raise CodeError( - f"Expected a single type parameter, got {len(args)} parameters", source_location - ) from None - name = f"{self.name}[{arg.name}]" - return StorageProxyType( - generic=self, - name=name, - content=arg, - wtype=key_type, - ) - - return parameterise - - -def _make_storage_parameterise_todo_remove_me( - key_type: Callable[[wtypes.WType], wtypes.WType] -) -> _Parameterise: - def parameterise( - self: _GenericType, args: _TypeArgs, source_location: SourceLocation | None - ) -> StorageProxyType: - try: - (arg,) = args - except ValueError: - raise CodeError( - f"Expected a single type parameter, got {len(args)} parameters", source_location - ) from None - - name = f"{self.name}[{arg.name}]" - return StorageProxyType( - generic=self, - name=name, - content=arg, - wtype=key_type(arg.wtype), - ) - - return parameterise +def _storage_parameterise( + self: _GenericType[StorageProxyType], args: _TypeArgs, source_location: SourceLocation | None +) -> StorageProxyType: + try: + (arg,) = args + except ValueError: + raise CodeError( + f"Expected a single type parameter, got {len(args)} parameters", source_location + ) from None + name = f"{self.name}[{arg.name}]" + return StorageProxyType( + generic=self, + name=name, + content=arg, + wtype=wtypes.bytes_wtype, + ) def _parameterise_storage_map( - self: _GenericType, args: _TypeArgs, source_location: SourceLocation | None + self: _GenericType[StorageMapProxyType], + args: _TypeArgs, + source_location: SourceLocation | None, ) -> StorageMapProxyType: try: key, content = args @@ -713,34 +710,27 @@ def _parameterise_storage_map( name=name, key=key, content=content, - # TODO: maybe bytes since it will just be the prefix? - # would have to change strategy in _gather_global_direct_storages if so - # wtype=wtypes.box_key, - # TODO: FIXME - wtype=wtypes.WBoxMapProxy.from_key_and_content_type(key.wtype, content.wtype), + wtype=wtypes.bytes_wtype, ) GenericGlobalStateType: typing.Final = _GenericType( name=constants.CLS_GLOBAL_STATE, - parameterise=_make_storage_parameterise(wtypes.state_key), + parameterise=_storage_parameterise, ) GenericLocalStateType: typing.Final = _GenericType( name=constants.CLS_LOCAL_STATE, - parameterise=_make_storage_parameterise(wtypes.state_key), + parameterise=_storage_parameterise, ) GenericBoxType: typing.Final = _GenericType( name=constants.CLS_BOX_PROXY, - # TODO: FIXME - # parameterise=_make_storage_parameterise(wtypes.box_key), - parameterise=_make_storage_parameterise_todo_remove_me(wtypes.WBoxProxy.from_content_type), + parameterise=_storage_parameterise, ) BoxRefType: typing.Final = _register_builtin( StorageProxyType( name=constants.CLS_BOX_REF_PROXY, content=BytesType, - # wtype=wtypes.box_key, - wtype=wtypes.box_ref_proxy_type, # TODO: fixme + wtype=wtypes.bytes_wtype, generic=None, ) ) @@ -753,22 +743,21 @@ def _parameterise_storage_map( GroupTransactionBaseType: typing.Final[PyType] = _SimpleType( name=constants.CLS_TRANSACTION_BASE, - wtype=wtypes.WGroupTransaction( - transaction_type=None, - stub_name=constants.CLS_TRANSACTION_BASE, - name="group_transaction_base", - ), + wtype=wtypes.WGroupTransaction(name="group_transaction_base", transaction_type=None), ) -def _make_txn_types(kind: constants.TransactionType | None) -> tuple[PyType, PyType, PyType]: - gtxn_type = _make_gtxn_type(kind) - itxn_fieldset_type = _make_itxn_fieldset_type(kind) - itxn_result_type = _make_itxn_result_type(kind) - return gtxn_type, itxn_fieldset_type, itxn_result_type +@attrs.frozen +class TransactionRelatedType(PyType): + wtype: wtypes.WType + transaction_type: constants.TransactionType | None + """None implies "any" type""" + + def __attrs_post_init__(self) -> None: + _register_builtin(self) -def _make_gtxn_type(kind: constants.TransactionType | None) -> PyType: +def _make_gtxn_type(kind: constants.TransactionType | None) -> TransactionRelatedType: if kind is None: wtype_name = "group_transaction" cls_name = "Transaction" @@ -776,17 +765,14 @@ def _make_gtxn_type(kind: constants.TransactionType | None) -> PyType: wtype_name = f"group_transaction_{kind.name}" cls_name = f"{_TXN_TYPE_NAMES[kind]}Transaction" stub_name = f"{constants.ALGOPY_PREFIX}gtxn.{cls_name}" - return _SimpleType( + return TransactionRelatedType( name=stub_name, - wtype=wtypes.WGroupTransaction( - name=wtype_name, - transaction_type=kind, - stub_name=stub_name, - ), + transaction_type=kind, + wtype=wtypes.WGroupTransaction(name=wtype_name, transaction_type=kind), ) -def _make_itxn_fieldset_type(kind: constants.TransactionType | None) -> PyType: +def _make_itxn_fieldset_type(kind: constants.TransactionType | None) -> TransactionRelatedType: if kind is None: wtype_name = "inner_transaction_fields" cls_name = "InnerTransaction" @@ -794,15 +780,14 @@ def _make_itxn_fieldset_type(kind: constants.TransactionType | None) -> PyType: wtype_name = f"inner_transaction_fields_{kind.name}" cls_name = _TXN_TYPE_NAMES[kind] stub_name = f"{constants.ALGOPY_PREFIX}itxn.{cls_name}" - return _SimpleType( + return TransactionRelatedType( name=stub_name, - wtype=wtypes.WInnerTransactionFields( - name=wtype_name, transaction_type=kind, stub_name=stub_name - ), + transaction_type=kind, + wtype=wtypes.WInnerTransactionFields(name=wtype_name, transaction_type=kind), ) -def _make_itxn_result_type(kind: constants.TransactionType | None) -> PyType: +def _make_itxn_result_type(kind: constants.TransactionType | None) -> TransactionRelatedType: if kind is None: wtype_name = "inner_transaction" cls_name = "InnerTransactionResult" @@ -810,11 +795,10 @@ def _make_itxn_result_type(kind: constants.TransactionType | None) -> PyType: wtype_name = f"inner_transaction_{kind.name}" cls_name = f"{_TXN_TYPE_NAMES[kind]}InnerTransaction" stub_name = f"{constants.ALGOPY_PREFIX}itxn.{cls_name}" - return _SimpleType( + return TransactionRelatedType( name=stub_name, - wtype=wtypes.WInnerTransaction( - name=wtype_name, transaction_type=kind, stub_name=stub_name - ), + transaction_type=kind, + wtype=wtypes.WInnerTransaction(name=wtype_name, transaction_type=kind), ) @@ -831,15 +815,15 @@ def _make_itxn_result_type(kind: constants.TransactionType | None) -> PyType: None, *constants.TransactionType, ] -GroupTransactionTypes: typing.Final[Mapping[constants.TransactionType | None, PyType]] = { - kind: _make_gtxn_type(kind) for kind in _all_txn_kinds -} -InnerTransactionFieldsetTypes: typing.Final[Mapping[constants.TransactionType | None, PyType]] = { - kind: _make_itxn_fieldset_type(kind) for kind in _all_txn_kinds -} -InnerTransactionResultTypes: typing.Final[Mapping[constants.TransactionType | None, PyType]] = { - kind: _make_itxn_result_type(kind) for kind in _all_txn_kinds -} +GroupTransactionTypes: typing.Final[ + Mapping[constants.TransactionType | None, TransactionRelatedType] +] = {kind: _make_gtxn_type(kind) for kind in _all_txn_kinds} +InnerTransactionFieldsetTypes: typing.Final[ + Mapping[constants.TransactionType | None, TransactionRelatedType] +] = {kind: _make_itxn_fieldset_type(kind) for kind in _all_txn_kinds} +InnerTransactionResultTypes: typing.Final[ + Mapping[constants.TransactionType | None, TransactionRelatedType] +] = {kind: _make_itxn_result_type(kind) for kind in _all_txn_kinds} @attrs.frozen(kw_only=True) @@ -967,3 +951,30 @@ def _parameterise_pseudo_generic_function_type( name=f"{constants.ALGOPY_PREFIX}_template_variables._TemplateVarMethod", parameterise=_parameterise_pseudo_generic_function_type, ) + + +__BASIC_WTYPE_MAP: typing.Final[Mapping[wtypes.WType, PyType]] = { + wtypes.void_wtype: NoneType, + wtypes.uint64_wtype: UInt64Type, + wtypes.bytes_wtype: BytesType, + wtypes.bool_wtype: BoolType, + wtypes.account_wtype: AccountType, + wtypes.biguint_wtype: BigUIntType, + wtypes.asset_wtype: AssetType, + wtypes.application_wtype: ApplicationType, +} + + +def from_basic_wtype(wtype: wtypes.WType) -> PyType: + """For mapping from basic WTypes _only_. + + These should all be types that are found in the langspec, basically. + + This is only meant for use when there are no other reasonable alternatives. + """ + assert wtype.scalar + assert type(wtype) is wtypes.WType + try: + return __BASIC_WTYPE_MAP[wtype] + except KeyError as ex: + raise InternalError(f"Unable to map basic WType '{wtype}' back to PyType") from ex diff --git a/src/puya/awst_build/subroutine.py b/src/puya/awst_build/subroutine.py index eaae39153..05506f5bc 100644 --- a/src/puya/awst_build/subroutine.py +++ b/src/puya/awst_build/subroutine.py @@ -20,9 +20,7 @@ Block, BoolConstant, BooleanBinaryOperation, - BoxProxyExpression, BreakStatement, - BytesConstant, CompileTimeConstantExpression, ConditionalExpression, ContinueStatement, @@ -50,7 +48,6 @@ from puya.awst_build import constants, pytypes from puya.awst_build.base_mypy_visitor import BaseMyPyVisitor from puya.awst_build.context import ASTConversionModuleContext -from puya.awst_build.contract_data import AppStorageDeclaration from puya.awst_build.eb import type_registry from puya.awst_build.eb.arc4 import ( ARC4BoolClassExpressionBuilder, @@ -60,7 +57,7 @@ BuilderBinaryOp, BuilderComparisonOp, ExpressionBuilder, - StateProxyDefinitionBuilder, + StorageProxyConstructorResult, ) from puya.awst_build.eb.bool import BoolClassExpressionBuilder from puya.awst_build.eb.contracts import ( @@ -75,7 +72,6 @@ from puya.awst_build.eb.subroutine import SubroutineInvokerExpressionBuilder from puya.awst_build.eb.type_registry import builder_for_instance, builder_for_type from puya.awst_build.eb.uint64 import UInt64ExpressionBuilder -from puya.awst_build.eb.var_factory import var_expression from puya.awst_build.exceptions import TypeUnionError from puya.awst_build.utils import ( bool_eval, @@ -328,21 +324,25 @@ def visit_assignment_stmt(self, stmt: mypy.nodes.AssignmentStmt) -> Sequence[Sta ) rvalue = require_expression_builder(stmt.rvalue.accept(self)) rvalue_pytyp = self.context.mypy_expr_node_type(stmt.rvalue) - if rvalue_pytyp is pytypes.BoxRefType or isinstance( - rvalue_pytyp, pytypes.StorageProxyType | pytypes.StorageMapProxyType - ): + if isinstance(rvalue, StorageProxyConstructorResult): try: (lvalue,) = stmt.lvalues except ValueError: # this is true regardless of whether it's a self assignment or not, # these are objects so aliasing is an issue in terms of semantic compatibility raise CodeError( - f"{rvalue_pytyp} can only be assigned to a single variable", stmt_loc + f"{rvalue.pytype} can only be assigned to a single variable", stmt_loc ) from None if is_self_member(lvalue): - return self._handle_proxy_assignment(lvalue, rvalue, rvalue_pytyp, stmt_loc) + return self._handle_proxy_assignment(lvalue, rvalue, stmt_loc) + elif rvalue.initial_value is not None: + raise CodeError( + "providing an initial value is only allowed" + " when assigning to a member variable", + stmt_loc, + ) elif len(stmt.lvalues) > 1: - rvalue = temporary_assignment_if_required2(rvalue_pytyp, rvalue) + rvalue = temporary_assignment_if_required(rvalue_pytyp, rvalue) return [ AssignmentStatement( @@ -356,48 +356,32 @@ def visit_assignment_stmt(self, stmt: mypy.nodes.AssignmentStmt) -> Sequence[Sta def _handle_proxy_assignment( self, lvalue: mypy.nodes.MemberExpr, - rvalue: ExpressionBuilder, - rvalue_pytyp: pytypes.PyType, + rvalue: StorageProxyConstructorResult, stmt_loc: SourceLocation, ) -> Sequence[Statement]: if self.contract_method_info is None: raise InternalError("Assignment to self outside of a contract class", stmt_loc) if self.func_def.name != "__init__": raise CodeError( - f"{rvalue_pytyp.generic or rvalue_pytyp}" + f"{rvalue.pytype.generic or rvalue.pytype}" " can only be assigned to a member variable in the __init__ method", stmt_loc, ) cref = self.contract_method_info.cref - if isinstance(rvalue, StateProxyDefinitionBuilder): - return self._handle_state_proxy_assignment( - cref, lvalue, rvalue, rvalue_pytyp, stmt_loc - ) - else: - return self._handle_box_proxy_assignment(cref, lvalue, rvalue, rvalue_pytyp, stmt_loc) - - def _handle_state_proxy_assignment( - self, - cref: ContractReference, - lvalue: mypy.nodes.MemberExpr, - rvalue: StateProxyDefinitionBuilder, - rvalue_pytyp: pytypes.PyType, - stmt_loc: SourceLocation, - ) -> Sequence[Statement]: member_name = lvalue.name member_loc = self._location(lvalue) - defn = rvalue.build_definition(member_name, cref, rvalue_pytyp, member_loc) + defn = rvalue.build_definition(member_name, cref, rvalue.pytype, member_loc) self.context.add_state_def(cref, defn) if rvalue.initial_value is None: return [] - elif rvalue_pytyp.generic is not pytypes.GenericGlobalStateType: + elif rvalue.pytype.generic != pytypes.GenericGlobalStateType: raise InternalError( - f"Don't know how to do initialise-on-declaration for {rvalue_pytyp}", stmt_loc + f"Don't know how to do initialise-on-declaration for {rvalue.pytype}", stmt_loc ) else: global_state_target = AppStateExpression( key=defn.key, - field_name=defn.member_name, + member_name=defn.member_name, wtype=defn.definition.storage_wtype, source_location=defn.source_location, ) @@ -409,34 +393,6 @@ def _handle_state_proxy_assignment( ) ] - def _handle_box_proxy_assignment( - self, - cref: ContractReference, - lvalue: mypy.nodes.MemberExpr, - rvalue: ExpressionBuilder, - rvalue_pytyp: pytypes.PyType, - stmt_loc: SourceLocation, - ) -> Sequence[Statement]: - member_name = lvalue.name - key = rvalue.rvalue() - match key: - case BoxProxyExpression(key=BytesConstant() as key_override): - defn = AppStorageDeclaration( - member_name=member_name, - key_override=key_override, - source_location=key.source_location, - typ=rvalue_pytyp, - description=None, - defined_in=cref, - ) - self.context.add_state_def(cref, defn) - return [] - raise CodeError( - f"{rvalue_pytyp} must be declared with compile time static keys" - f" when assigned to 'self'", - stmt_loc, - ) - def resolve_lvalue(self, lvalue: mypy.nodes.Expression) -> Lvalue: builder_or_literal = lvalue.accept(self) builder = require_expression_builder(builder_or_literal) @@ -548,21 +504,20 @@ def visit_return_stmt(self, stmt: mypy.nodes.ReturnStmt) -> ReturnStatement | No ) return ReturnStatement(source_location=loc, value=None) - returning = require_expression_builder(return_expr.accept(self)).rvalue() - # TODO: compare pytypes instead - if returning.wtype != self._return_type.wtype: + returning_builder = require_expression_builder(return_expr.accept(self)) + if returning_builder.pytype != self._return_type: self._error( - f"invalid return type of {returning.wtype}, expected {self._return_type.wtype}", + f"invalid return type of {returning_builder.pytype}, expected {self._return_type}", loc, ) - return ReturnStatement(source_location=loc, value=returning) + return ReturnStatement(source_location=loc, value=returning_builder.rvalue()) def visit_match_stmt(self, stmt: mypy.nodes.MatchStmt) -> Switch | None: loc = self._location(stmt) + subject_eb = require_expression_builder(stmt.subject.accept(self)) # TODO: PyType from EB - subject = require_expression_builder( - temporary_assignment_if_required(stmt.subject.accept(self)) - ).rvalue() + subject_typ = self.context.mypy_expr_node_type(stmt.subject) + subject = temporary_assignment_if_required(subject_typ, subject_eb).rvalue() case_block_map = dict[Expression, Block]() default_block: Block | None = None for pattern, guard, block in zip(stmt.patterns, stmt.guards, stmt.bodies, strict=True): @@ -669,11 +624,15 @@ def _visit_ref_expr( if func_builder := type_registry.FUNC_NAME_TO_BUILDER.get(fullname): return func_builder(expr_loc) match expr: - case mypy.nodes.RefExpr(node=mypy.nodes.TypeInfo() as typ): - if typ.has_base(constants.CONTRACT_BASE): - return ContractTypeExpressionBuilder(self.context, typ.defn.info, expr_loc) - if typ.has_base(constants.CLS_ARC4_CLIENT): # provides type info only - return ARC4ClientClassExpressionBuilder(self.context, expr_loc, typ.defn.info) + case mypy.nodes.RefExpr(node=mypy.nodes.TypeInfo() as typ) if py_typ: + if pytypes.ContractBaseType in py_typ.mro: + return ContractTypeExpressionBuilder( + self.context, py_typ, typ.defn.info, expr_loc + ) + if pytypes.ARC4ClientBaseType in py_typ.bases: # provides type info only + return ARC4ClientClassExpressionBuilder( + self.context, py_typ, expr_loc, typ.defn.info + ) case mypy.nodes.NameExpr(node=mypy.nodes.Var(is_self=True) as self_var): if self.contract_method_info is None: raise InternalError( @@ -1011,7 +970,7 @@ def _visit_bool_op_expr( source_location=location, left=lhs_expr, op=op, right=rhs_expr ) else: - lhs_builder = temporary_assignment_if_required2(target_pytyp, lhs_expr) + lhs_builder = temporary_assignment_if_required(target_pytyp, lhs_expr) # (lhs:uint64 and rhs:uint64) => lhs_tmp_var if not bool(lhs_tmp_var := lhs) else rhs # (lhs:uint64 or rhs:uint64) => lhs_tmp_var if bool(lhs_tmp_var := lhs) else rhs # TODO: this is a bit convoluted in terms of ExpressionBuilder <-> Expression @@ -1029,12 +988,15 @@ def _visit_bool_op_expr( def visit_index_expr(self, expr: mypy.nodes.IndexExpr) -> ExpressionBuilder | Literal: expr_location = self._location(expr) + if isinstance(expr.method_type, mypy.types.CallableType): + result_pytyp = self.context.type_to_pytype( + expr.method_type.ret_type, source_location=expr_location + ) + if isinstance(result_pytyp, pytypes.PseudoGenericFunctionType): + return builder_for_type(result_pytyp, expr_location) match expr.analyzed: case None: - with contextlib.suppress(PuyaError): - result_pytyp = self.context.mypy_expr_node_type(expr) - if isinstance(result_pytyp, pytypes.PseudoGenericFunctionType): - return builder_for_type(result_pytyp, expr_location) + pass case mypy.nodes.TypeAliasExpr(): raise CodeError("type aliases are not supported inside subroutines", expr_location) case mypy.nodes.TypeApplication(): @@ -1046,6 +1008,8 @@ def visit_index_expr(self, expr: mypy.nodes.IndexExpr) -> ExpressionBuilder | Li expr_location, ) return builder_for_type(type_type.typ, expr_location) + case _: + typing.assert_never(expr.analyzed) base_expr = expr.base.accept(self) if isinstance(base_expr, Literal): @@ -1072,6 +1036,7 @@ def visit_index_expr(self, expr: mypy.nodes.IndexExpr) -> ExpressionBuilder | Li return base_expr.index(index=index_expr_or_literal, location=expr_location) def visit_conditional_expr(self, expr: mypy.nodes.ConditionalExpr) -> ExpressionBuilder: + # TODO: conditional literals as literal builders condition = self._eval_condition(expr.cond) true_expr = require_expression_builder(expr.if_expr.accept(self)).rvalue() # TODO: pytypes false_expr = require_expression_builder(expr.else_expr.accept(self)).rvalue() # TODO: ^ @@ -1114,7 +1079,11 @@ def visit_comparison_expr(self, expr: mypy.nodes.ComparisonExpr) -> ExpressionBu operands = [o.accept(self) for o in expr.operands] # TODO: operands are Literal or EB, so can get PyType - operands[1:-1] = [temporary_assignment_if_required(operand) for operand in operands[1:-1]] + operand_types = [self.context.mypy_expr_node_type(o) for o in expr.operands] # TODO: YUCK + operands[1:-1] = [ + temporary_assignment_if_required(op_typ, operand) + for operand, op_typ in list(zip(operands, operand_types, strict=True))[1:-1] + ] comparisons = [ self._build_compare(operator=operator, lhs=lhs, rhs=rhs) @@ -1183,21 +1152,23 @@ def visit_tuple_expr(self, mypy_expr: mypy.nodes.TupleExpr) -> ExpressionBuilder require_expression_builder( mypy_item.accept(self), msg="Python literals (other than True/False) are not valid as tuple elements", - # TODO: grab item types from EB ).rvalue() for mypy_item in mypy_expr.items ] + # TODO: grab item types from EB items? + typ = self.context.mypy_expr_node_type(mypy_expr) location = self._location(mypy_expr) if not items: raise CodeError("Empty tuples are not supported", location) - wtype = wtypes.WTuple((i.wtype for i in items), location) + wtype = typ.wtype + assert isinstance(wtype, wtypes.WTuple) tuple_expr = TupleExpression( source_location=location, wtype=wtype, items=items, ) - return TupleExpressionBuilder(tuple_expr) + return TupleExpressionBuilder(tuple_expr, typ) def visit_assignment_expr(self, expr: mypy.nodes.AssignmentExpr) -> ExpressionBuilder: expr_loc = self._location(expr) @@ -1213,7 +1184,8 @@ def visit_assignment_expr(self, expr: mypy.nodes.AssignmentExpr) -> ExpressionBu target = self.resolve_lvalue(expr.target) result = AssignmentExpression(source_location=expr_loc, value=value, target=target) # TODO: take PyType from source ExpressionBuilder - return var_expression(result) + result_typ = self.context.mypy_expr_node_type(expr) + return builder_for_instance(result_typ, result) def visit_super_expr(self, super_expr: mypy.nodes.SuperExpr) -> ExpressionBuilder: super_loc = self._location(super_expr) @@ -1280,57 +1252,23 @@ def is_self_member( @typing.overload -def temporary_assignment_if_required(operand: Literal) -> Literal: ... - - -@typing.overload -def temporary_assignment_if_required(operand: Expression) -> ExpressionBuilder: ... +def temporary_assignment_if_required(typ: pytypes.PyType, operand: Literal) -> Literal: ... @typing.overload def temporary_assignment_if_required( - operand: ExpressionBuilder, -) -> ExpressionBuilder: ... - - -def temporary_assignment_if_required( - operand: ExpressionBuilder | Expression | Literal, -) -> ExpressionBuilder | Literal: - if isinstance(operand, Literal): - return operand - - if isinstance(operand, Expression): - expr = operand - else: - expr = operand.rvalue() - # TODO: optimise the below checks so we don't create unnecessary temporaries, - # ie when Expression has no side effects - if not isinstance(expr, VarExpression | CompileTimeConstantExpression): - return var_expression(SingleEvaluation(expr)) - if isinstance(operand, Expression): - return var_expression(operand) - else: - return operand - - -@typing.overload -def temporary_assignment_if_required2(typ: pytypes.PyType, operand: Literal) -> Literal: ... - - -@typing.overload -def temporary_assignment_if_required2( typ: pytypes.PyType, operand: Expression ) -> ExpressionBuilder: ... @typing.overload -def temporary_assignment_if_required2( +def temporary_assignment_if_required( typ: pytypes.PyType, operand: ExpressionBuilder, ) -> ExpressionBuilder: ... -def temporary_assignment_if_required2( +def temporary_assignment_if_required( typ: pytypes.PyType, operand: ExpressionBuilder | Expression | Literal, ) -> ExpressionBuilder | Literal: diff --git a/src/puya/awst_build/utils.py b/src/puya/awst_build/utils.py index 42b6d2bdf..ce34f9810 100644 --- a/src/puya/awst_build/utils.py +++ b/src/puya/awst_build/utils.py @@ -31,7 +31,7 @@ ) from puya.awst_build import constants, intrinsic_factory from puya.awst_build.context import ASTConversionModuleContext -from puya.awst_build.eb.base import ExpressionBuilder, TypeClassExpressionBuilder +from puya.awst_build.eb.base import ExpressionBuilder from puya.errors import CodeError, InternalError from puya.parse import SourceLocation @@ -162,7 +162,6 @@ def require_expression_builder( match builder_or_literal: case Literal(value=bool(value), source_location=literal_location): - # TODO: PyType known as bool return BoolExpressionBuilder( BoolConstant(value=value, source_location=literal_location) ) @@ -174,18 +173,6 @@ def require_expression_builder( typing.assert_never(builder_or_literal) -def require_type_class_eb( - builder_or_literal: ExpressionBuilder | Literal, - *, - msg: str = "A Python type is required at this location", -) -> TypeClassExpressionBuilder: - match builder_or_literal: - case TypeClassExpressionBuilder() as type_eb: - return type_eb - case _: - raise CodeError(msg, builder_or_literal.source_location) - - def expect_operand_wtype( literal_or_expr: Literal | Expression | ExpressionBuilder, target_wtype: wtypes.WType ) -> Expression: diff --git a/src/puya/awst_build/validation/arc4_copy.py b/src/puya/awst_build/validation/arc4_copy.py index bbb29e880..bb949abef 100644 --- a/src/puya/awst_build/validation/arc4_copy.py +++ b/src/puya/awst_build/validation/arc4_copy.py @@ -99,20 +99,19 @@ def _is_referable_expression(expr: awst_nodes.Expression) -> bool: def _check_assignment(target: awst_nodes.Expression, value: awst_nodes.Expression) -> None: if not isinstance(target, awst_nodes.TupleExpression): _check_for_arc4_copy(value, "being assigned to another variable") - elif _is_referable_expression(value): - problem_type = next((i for i in target.wtype.types if _is_arc4_mutable(i)), None) - if problem_type: - logger.error( - f"Tuple cannot be destructured as it contains an item of type" - f" {problem_type} which requires copying. Use index access instead", - location=value.source_location, - ) + elif _is_referable_expression(value) and any(_is_arc4_mutable(i) for i in target.wtype.types): + logger.error( + "tuples containing a mutable reference to an ARC4-encoded value cannot be unpacked," + " use index access instead", + location=value.source_location, + ) def _check_for_arc4_copy(expr: awst_nodes.Expression, context_desc: str) -> None: if _is_arc4_mutable(expr.wtype) and _is_referable_expression(expr): logger.error( - f"{expr.wtype} must be copied using .copy() when {context_desc}", + "mutable reference to ARC4-encoded value" + f" must be copied using .copy() when {context_desc}", location=expr.source_location, ) diff --git a/src/puya/ir/builder/box.py b/src/puya/ir/builder/box.py index e5b9ffbb1..b268a1aa2 100644 --- a/src/puya/ir/builder/box.py +++ b/src/puya/ir/builder/box.py @@ -1,15 +1,13 @@ from collections.abc import Sequence from puya.arc4_util import get_arc4_fixed_bit_size +from puya.avm_type import AVMType from puya.awst import ( nodes as awst_nodes, wtypes, ) -from puya.errors import CodeError, InternalError -from puya.ir import ( - intrinsic_factory, - models as ops, -) +from puya.errors import CodeError +from puya.ir import models as ops from puya.ir.avm_ops import AVMOp from puya.ir.builder._utils import assert_value, assign, assign_intrinsic_op from puya.ir.context import IRFunctionBuildContext @@ -17,44 +15,12 @@ from puya.parse import SourceLocation -def _get_box_key(context: IRFunctionBuildContext, box: awst_nodes.Expression) -> ops.Value: - if not isinstance(box, awst_nodes.BoxKeyExpression | awst_nodes.BoxValueExpression): - raise InternalError( - "param box must be an expression of type BoxKeyExpression or BoxValueExpression" - ) - base_key = context.visitor.visit_and_materialise_single(box.proxy) - if box.item_key: - item_key = context.visitor.visit_and_materialise_single(box.item_key) - (compound_key,) = assign( - context=context, - temp_description=["compound_key"], - source_location=box.source_location, - source=ops.Intrinsic( - op=AVMOp.concat, args=[base_key, item_key], source_location=box.source_location - ), - ) - return compound_key - return base_key - - -def _get_box_content_wtype(box: awst_nodes.Expression) -> wtypes.WType: - match box: - case awst_nodes.BoxValueExpression(proxy=proxy): - return _get_box_content_wtype(proxy) - case awst_nodes.BoxKeyExpression(proxy=proxy): - return _get_box_content_wtype(proxy) - case awst_nodes.Expression(wtype=wtypes.WBoxProxy(content_wtype=content_wtype)): - return content_wtype - case _: - return wtypes.bytes_wtype - - -def _get_box( +def _box_get( context: IRFunctionBuildContext, - box: awst_nodes.Expression, + box: awst_nodes.BoxValueExpression, source_location: SourceLocation, ) -> tuple[ops.Register, ops.Register]: - box_key = _get_box_key(context, box) + box_key = context.visitor.visit_and_materialise_single(box.key) (box_value, box_exists) = assign( context=context, temp_description=["box_value", "box_exists"], @@ -65,7 +31,7 @@ def _get_box( source_location=source_location, ), ) - if wtypes.is_uint64_on_stack(_get_box_content_wtype(box)): + if wtype_to_ir_type(box).avm_type == AVMType.uint64: (box_value,) = assign_intrinsic_op( op=AVMOp.btoi, target="box_value_uint64", @@ -76,68 +42,10 @@ def _get_box( return box_value, box_exists -def visit_box_state_get( - context: IRFunctionBuildContext, expr: awst_nodes.StateGet -) -> ops.ValueProvider: - (box_value, box_exists) = _get_box(context, expr.field, expr.source_location) - default_value = context.visitor.visit_and_materialise_single(expr.default) - return intrinsic_factory.select( - condition=box_exists, - true=box_value, - false=default_value, - type_=wtype_to_ir_type(expr.wtype), - source_location=expr.source_location, - ) - - -def visit_box_state_get_ex( - context: IRFunctionBuildContext, expr: awst_nodes.StateGetEx -) -> ops.ValueProvider: - (box_value, box_exists) = _get_box(context, expr.field, expr.source_location) - return ops.ValueTuple(values=[box_value, box_exists], source_location=expr.source_location) - - -def visit_box_state_delete(context: IRFunctionBuildContext, expr: awst_nodes.StateDelete) -> None: - box_key = context.visitor.visit_and_materialise_single(expr.field) - assign( - temp_description="box_del_res", - source_location=expr.source_location, - source=ops.Intrinsic( - op=AVMOp.box_del, - args=[box_key], - source_location=expr.source_location, - ), - context=context, - ) - - -def visit_box_length( - context: IRFunctionBuildContext, expr: awst_nodes.BoxLength -) -> ops.ValueProvider: - box_key = _get_box_key(context, expr.box_key) - (box_len, box_exists) = assign( - temp_description=["box_len", "box_exists"], - source_location=expr.source_location, - source=ops.Intrinsic( - op=AVMOp.box_len, - args=[box_key], - source_location=expr.source_location, - ), - context=context, - ) - assert_value( - context, - box_exists, - comment="Box must exist", - source_location=expr.source_location, - ) - return box_len - - def visit_box_state_exists( context: IRFunctionBuildContext, expr: awst_nodes.StateExists ) -> ops.ValueProvider: - box_key = _get_box_key(context, expr.field) + box_key = context.visitor.visit_and_materialise_single(expr.field.key) (box_len, box_exists) = assign( temp_description=["box_len", "box_exists"], source_location=expr.source_location, @@ -154,7 +62,7 @@ def visit_box_state_exists( def visit_box_value( context: IRFunctionBuildContext, expr: awst_nodes.BoxValueExpression ) -> ops.ValueProvider: - (box_value, box_exists) = _get_box(context, expr, expr.source_location) + (box_value, box_exists) = _box_get(context, expr, expr.source_location) assert_value( context, @@ -172,7 +80,7 @@ def handle_box_assign( value: ops.ValueProvider, assignment_location: SourceLocation, ) -> Sequence[ops.Value]: - box_key = _get_box_key(context, box) + box_key = context.visitor.visit_and_materialise_single(box.key) source = context.visitor.materialise_value_provider(value, description="new_box_value") if len(source) != 1: raise CodeError( @@ -219,22 +127,3 @@ def _is_fixed_byte_size(wtype: wtypes.WType) -> bool: if isinstance(wtype, wtypes.ARC4Type): return get_arc4_fixed_bit_size(wtype) is not None return False - - -def visit_field_box( - context: IRFunctionBuildContext, field_box: awst_nodes.BoxProxyField -) -> ops.Value: - state_def = context.resolve_state(field_box.field_name, field_box.source_location) - return context.visitor.visit_bytes_constant(state_def.key) - - -def visit_box_proxy_expression( - context: IRFunctionBuildContext, box_proxy: awst_nodes.BoxProxyExpression -) -> ops.Value: - return context.visitor.visit_and_materialise_single(box_proxy.key) - - -def visit_box_key_expression( - context: IRFunctionBuildContext, box_key: awst_nodes.BoxKeyExpression -) -> ops.Value: - return _get_box_key(context, box_key) diff --git a/src/puya/ir/builder/main.py b/src/puya/ir/builder/main.py index 384a1fd9c..8a756d58c 100644 --- a/src/puya/ir/builder/main.py +++ b/src/puya/ir/builder/main.py @@ -972,21 +972,9 @@ def materialise_value_provider( source_location=provider.source_location, ) - def visit_box_length(self, expr: puya.awst.nodes.BoxLength) -> TExpression: - return box.visit_box_length(self.context, expr) - def visit_box_value_expression(self, expr: awst_nodes.BoxValueExpression) -> TExpression: return box.visit_box_value(self.context, expr) - def visit_box_proxy_field(self, expr: awst_nodes.BoxProxyField) -> TExpression: - return box.visit_field_box(self.context, expr) - - def visit_box_proxy_expression(self, expr: awst_nodes.BoxProxyExpression) -> TExpression: - return box.visit_box_proxy_expression(self.context, expr) - - def visit_box_key_expression(self, expr: puya.awst.nodes.BoxKeyExpression) -> TExpression: - return box.visit_box_key_expression(self.context, expr) - def visit_bytes_raw(self, expr: puya.awst.nodes.BytesRaw) -> TExpression: value = self.visit_and_materialise_single(expr.expr) backing = value.ir_type.maybe_avm_type diff --git a/src/puya/ir/builder/state.py b/src/puya/ir/builder/state.py index cae9c6200..5ea76e744 100644 --- a/src/puya/ir/builder/state.py +++ b/src/puya/ir/builder/state.py @@ -15,7 +15,7 @@ def visit_app_state_expression( context: IRFunctionBuildContext, expr: awst_nodes.AppStateExpression ) -> ValueProvider: # TODO: add specific (unsafe) optimisation flag to allow skipping this check - return _checked_state_access(context, expr, assert_comment=f"check {expr.field_name} exists") + return _checked_state_access(context, expr, assert_comment=f"check {expr.member_name} exists") def visit_app_account_state_expression( @@ -23,23 +23,21 @@ def visit_app_account_state_expression( ) -> ValueProvider: # TODO: add specific (unsafe) optimisation flag to allow skipping this check return _checked_state_access( - context, expr, assert_comment=f"check {expr.field_name} exists for account" + context, expr, assert_comment=f"check {expr.member_name} exists for account" ) def visit_state_get_ex( context: IRFunctionBuildContext, expr: awst_nodes.StateGetEx ) -> ValueProvider: - match expr.field: - case awst_nodes.BoxKeyExpression(): - return box.visit_box_state_get_ex(context, expr) return _build_state_get_ex(context, expr.field, expr.source_location) def visit_state_delete(context: IRFunctionBuildContext, statement: awst_nodes.StateDelete) -> None: match statement.field: - case awst_nodes.BoxKeyExpression(): - return box.visit_box_state_delete(context, statement) + case awst_nodes.BoxValueExpression(key=awst_key): + op = AVMOp.box_del + awst_account = None case awst_nodes.AppStateExpression(key=awst_key): op = AVMOp.app_global_del awst_account = None @@ -61,13 +59,10 @@ def visit_state_delete(context: IRFunctionBuildContext, statement: awst_nodes.St def visit_state_get(context: IRFunctionBuildContext, expr: awst_nodes.StateGet) -> ValueProvider: - match expr.field: - case awst_nodes.BoxKeyExpression(): - return box.visit_box_state_get(context, expr) default = context.visitor.visit_and_materialise_single(expr.default) get_ex = _build_state_get_ex(context, expr.field, expr.source_location) maybe_value, exists = context.visitor.materialise_value_provider( - get_ex, description=f"{expr.field.field_name}_get_ex" + get_ex, description=f"{expr.field.member_name}_get_ex" ) return intrinsic_factory.select( condition=exists, @@ -82,11 +77,11 @@ def visit_state_exists( context: IRFunctionBuildContext, expr: awst_nodes.StateExists ) -> ValueProvider: match expr.field: - case awst_nodes.BoxKeyExpression(): + case awst_nodes.BoxValueExpression(): return box.visit_box_state_exists(context, expr) get_ex = _build_state_get_ex(context, expr.field, expr.source_location) _, exists = context.visitor.materialise_value_provider( - get_ex, description=f"{expr.field.field_name}_exists" + get_ex, description=f"{expr.field.member_name}_exists" ) return exists @@ -97,19 +92,19 @@ def _checked_state_access( assert_comment: str, ) -> ValueProvider: get = _build_state_get_ex(context, expr, expr.source_location) - # note: we manually construct temporary targets here since ir_type is any, + # note: we manually construct temporary targets here since AVMType can be any, # but we "know" the type from the expression value_ir_type = wtype_to_ir_type(expr.wtype) value_tmp = mktemp( context, ir_type=value_ir_type, - description=f"{expr.field_name}_value", + description=f"{expr.member_name}_value", source_location=expr.source_location, ) did_exist_tmp = mktemp( context, ir_type=IRType.bool, - description=f"{expr.field_name}_exists", + description=f"{expr.member_name}_exists", source_location=expr.source_location, ) assign_targets( @@ -129,18 +124,27 @@ def _checked_state_access( def _build_state_get_ex( context: IRFunctionBuildContext, - expr: awst_nodes.AppAccountStateExpression | awst_nodes.AppStateExpression, + expr: ( + awst_nodes.AppAccountStateExpression + | awst_nodes.AppStateExpression + | awst_nodes.BoxValueExpression + ), source_location: SourceLocation, ) -> Intrinsic: - current_app_offset = UInt64Constant(value=0, source_location=expr.source_location) key = context.visitor.visit_and_materialise_single(expr.key) - args: list[Value] = [current_app_offset, key] + args: list[Value] if isinstance(expr, awst_nodes.AppStateExpression): + current_app_offset = UInt64Constant(value=0, source_location=expr.source_location) + args = [current_app_offset, key] op = AVMOp.app_global_get_ex - else: + elif isinstance(expr, awst_nodes.AppAccountStateExpression): + current_app_offset = UInt64Constant(value=0, source_location=expr.source_location) op = AVMOp.app_local_get_ex account = context.visitor.visit_and_materialise_single(expr.account) - args.insert(0, account) + args = [account, current_app_offset, key] + else: + op = AVMOp.box_get + args = [key] return Intrinsic( op=op, args=args, diff --git a/src/puya/ir/types_.py b/src/puya/ir/types_.py index 8e7cde62d..f6aff93fe 100644 --- a/src/puya/ir/types_.py +++ b/src/puya/ir/types_.py @@ -83,14 +83,7 @@ def wtype_to_ir_type( return IRType.itxn_field_set case wtypes.biguint_wtype: return IRType.biguint - case ( - wtypes.bytes_wtype - | wtypes.account_wtype - | wtypes.string_wtype - | wtypes.ARC4Type() - | wtypes.box_ref_proxy_type - | wtypes.WBoxProxy() - ): + case wtypes.bytes_wtype | wtypes.account_wtype | wtypes.string_wtype | wtypes.ARC4Type(): return IRType.bytes case wtypes.void_wtype: raise InternalError("Can't translate void WType to IRType", source_location) @@ -144,8 +137,6 @@ def wtype_to_avm_type( | wtypes.account_wtype | wtypes.ARC4Type() | wtypes.string_wtype - | wtypes.box_ref_proxy_type - | wtypes.WBoxProxy() ): return AVMType.bytes case wtypes.void_wtype: diff --git a/stubs/algopy-stubs/_box.pyi b/stubs/algopy-stubs/_box.pyi index 588370c64..f2ea249c0 100644 --- a/stubs/algopy-stubs/_box.pyi +++ b/stubs/algopy-stubs/_box.pyi @@ -1,19 +1,21 @@ import typing -from algopy import Bytes, UInt64 +from algopy import Bytes, UInt64, String -_TContent = typing.TypeVar("_TContent") _TKey = typing.TypeVar("_TKey") +_TValue = typing.TypeVar("_TValue") -class Box(typing.Generic[_TContent]): +class Box(typing.Generic[_TValue]): """ Box abstracts the reading and writing of a single value to a single box. The box size will be reconfigured dynamically to fit the size of the value being assigned to it. """ - # TODO: support String | str for key, ensure default key works - def __init__(self, type_: type[_TContent], /, *, key: Bytes | bytes = ...) -> None: ... + # TODO: ensure default key works, ensure str/String work + def __init__( + self, type_: type[_TValue], /, *, key: bytes | str | Bytes | String = ... + ) -> None: ... def __bool__(self) -> bool: """ Returns True if the box exists, regardless of the truthiness of the contents @@ -21,25 +23,25 @@ class Box(typing.Generic[_TContent]): """ @property - def value(self) -> _TContent: + def value(self) -> _TValue: """Retrieve the contents of the box. Fails if the box has not been created.""" @value.setter - def value(self, value: _TContent) -> None: + def value(self, value: _TValue) -> None: """Write _value_ to the box. Creates the box if it does not exist.""" @value.deleter def value(self) -> None: """Delete the box""" - def get(self, *, default: _TContent) -> _TContent: + def get(self, *, default: _TValue) -> _TValue: """ Retrieve the contents of the box, or return the default value if the box has not been created. @param default: The default value to return if the box has not been created """ - def maybe(self) -> tuple[_TContent, bool]: + def maybe(self) -> tuple[_TValue, bool]: """ Retrieve the contents of the box if it exists, and return a boolean indicating if the box exists. @@ -59,8 +61,8 @@ class BoxRef: value. """ - # TODO: support String | str for key, ensure default key works - def __init__(self, /, *, key: Bytes | bytes = ...) -> None: ... + # TODO: ensure default key works, ensure str/String work + def __init__(self, /, *, key: bytes | str | Bytes | String = ...) -> None: ... def __bool__(self) -> bool: """Returns True if the box has a value set, regardless of the truthiness of that value""" @@ -144,23 +146,28 @@ class BoxRef: Get the length of this Box. Fails if the box does not exist """ -class BoxMap(typing.Generic[_TKey, _TContent]): +class BoxMap(typing.Generic[_TKey, _TValue]): """ BoxMap abstracts the reading and writing of a set of boxes using a common key and content type. Each composite key (prefix + key) still needs to be made available to the application via the `boxes` property of the Transaction. """ - # TODO: support String | str for key_prefix, ensure default key_prefix works + # TODO: ensure default key_prefix works, ensure str/String work def __init__( - self, key_type: type[_TKey], type_: type[_TContent], /, *, key_prefix: Bytes | bytes = ... + self, + key_type: type[_TKey], + value_type: type[_TValue], + /, + *, + key_prefix: bytes | str | Bytes | String = ..., ) -> None: ... - def __getitem__(self, key: _TKey) -> _TContent: + def __getitem__(self, key: _TKey) -> _TValue: """ Retrieve the contents of a keyed box. Fails if the box for the key has not been created. """ - def __setitem__(self, key: _TKey, value: _TContent) -> None: + def __setitem__(self, key: _TKey, value: _TValue) -> None: """Write _value_ to a keyed box. Creates the box if it does not exist""" def __delitem__(self, key: _TKey) -> None: @@ -172,7 +179,7 @@ class BoxMap(typing.Generic[_TKey, _TContent]): truthiness of the contents of the box """ - def get(self, key: _TKey, *, default: _TContent) -> _TContent: + def get(self, key: _TKey, *, default: _TValue) -> _TValue: """ Retrieve the contents of a keyed box, or return the default value if the box has not been created. @@ -180,7 +187,7 @@ class BoxMap(typing.Generic[_TKey, _TContent]): @param default: The default value to return if the box has not been created. """ - def maybe(self, key: _TKey) -> tuple[_TContent, bool]: + def maybe(self, key: _TKey) -> tuple[_TValue, bool]: """ Retrieve the contents of a keyed box if it exists, and return a boolean indicating if the box exists. diff --git a/test_cases/abi_routing/out/client_Reference.py b/test_cases/abi_routing/out/client_Reference.py index 2c4d34ccc..6365af00a 100644 --- a/test_cases/abi_routing/out/client_Reference.py +++ b/test_cases/abi_routing/out/client_Reference.py @@ -10,20 +10,20 @@ class Reference(algopy.arc4.ARC4Client, typing.Protocol): @algopy.arc4.abimethod def noop_with_uint64( self, - a: algopy.arc4.UInt64, - ) -> algopy.arc4.UInt8: ... + a: algopy.arc4.UIntN[typing.Literal[64]], + ) -> algopy.arc4.UIntN[typing.Literal[8]]: ... @algopy.arc4.abimethod(name='all_the_things', readonly=True, allow_actions=['NoOp', 'OptIn', 'CloseOut', 'UpdateApplication', 'DeleteApplication'], create='allow') def full_abi_config( self, - a: algopy.arc4.UInt64, - ) -> algopy.arc4.UInt8: ... + a: algopy.arc4.UIntN[typing.Literal[64]], + ) -> algopy.arc4.UIntN[typing.Literal[8]]: ... @algopy.arc4.abimethod(readonly=True, allow_actions=['NoOp', 'CloseOut', 'DeleteApplication']) def mixed_oca( self, - a: algopy.arc4.UInt64, - ) -> algopy.arc4.UInt8: ... + a: algopy.arc4.UIntN[typing.Literal[64]], + ) -> algopy.arc4.UIntN[typing.Literal[8]]: ... @algopy.arc4.abimethod def opt_into_asset( @@ -35,9 +35,9 @@ def opt_into_asset( def with_transactions( self, asset: algopy.Asset, - an_int: algopy.arc4.UInt64, + an_int: algopy.arc4.UIntN[typing.Literal[64]], pay: algopy.gtxn.PaymentTransaction, - another_int: algopy.arc4.UInt64, + another_int: algopy.arc4.UIntN[typing.Literal[64]], ) -> None: ... @algopy.arc4.abimethod @@ -55,17 +55,17 @@ def get_address( @algopy.arc4.abimethod(readonly=True) def get_asset( self, - ) -> algopy.arc4.UInt64: ... + ) -> algopy.arc4.UIntN[typing.Literal[64]]: ... @algopy.arc4.abimethod(name='get_application', readonly=True) def get_app( self, - ) -> algopy.arc4.UInt64: ... + ) -> algopy.arc4.UIntN[typing.Literal[64]]: ... @algopy.arc4.abimethod(name='get_an_int', readonly=True) def get_a_int( self, - ) -> algopy.arc4.UInt64: ... + ) -> algopy.arc4.UIntN[typing.Literal[64]]: ... @algopy.arc4.abimethod(default_args={'asset_from_storage': 'asa', 'asset_from_function': 'get_asset', 'account_from_storage': 'creator', 'account_from_function': 'get_address', 'application_from_storage': 'app', 'application_from_function': 'get_app', 'bytes_from_storage': 'some_bytes', 'int_from_storage': 'an_int', 'int_from_function': 'get_a_int'}) def method_with_default_args( @@ -77,40 +77,40 @@ def method_with_default_args( application_from_storage: algopy.Application, application_from_function: algopy.Application, bytes_from_storage: algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[3]], - int_from_storage: algopy.arc4.UInt64, - int_from_function: algopy.arc4.UInt64, + int_from_storage: algopy.arc4.UIntN[typing.Literal[64]], + int_from_function: algopy.arc4.UIntN[typing.Literal[64]], ) -> None: ... @algopy.arc4.abimethod def method_with_more_than_15_args( self, - a: algopy.arc4.UInt64, - b: algopy.arc4.UInt64, - c: algopy.arc4.UInt64, - d: algopy.arc4.UInt64, + a: algopy.arc4.UIntN[typing.Literal[64]], + b: algopy.arc4.UIntN[typing.Literal[64]], + c: algopy.arc4.UIntN[typing.Literal[64]], + d: algopy.arc4.UIntN[typing.Literal[64]], asset: algopy.Asset, - e: algopy.arc4.UInt64, - f: algopy.arc4.UInt64, + e: algopy.arc4.UIntN[typing.Literal[64]], + f: algopy.arc4.UIntN[typing.Literal[64]], pay: algopy.gtxn.PaymentTransaction, - g: algopy.arc4.UInt64, - h: algopy.arc4.UInt64, - i: algopy.arc4.UInt64, - j: algopy.arc4.UInt64, - k: algopy.arc4.UInt64, - l: algopy.arc4.UInt64, - m: algopy.arc4.UInt64, - n: algopy.arc4.UInt64, - o: algopy.arc4.UInt64, - p: algopy.arc4.UInt64, - q: algopy.arc4.UInt64, - r: algopy.arc4.UInt64, + g: algopy.arc4.UIntN[typing.Literal[64]], + h: algopy.arc4.UIntN[typing.Literal[64]], + i: algopy.arc4.UIntN[typing.Literal[64]], + j: algopy.arc4.UIntN[typing.Literal[64]], + k: algopy.arc4.UIntN[typing.Literal[64]], + l: algopy.arc4.UIntN[typing.Literal[64]], + m: algopy.arc4.UIntN[typing.Literal[64]], + n: algopy.arc4.UIntN[typing.Literal[64]], + o: algopy.arc4.UIntN[typing.Literal[64]], + p: algopy.arc4.UIntN[typing.Literal[64]], + q: algopy.arc4.UIntN[typing.Literal[64]], + r: algopy.arc4.UIntN[typing.Literal[64]], s: algopy.arc4.DynamicBytes, t: algopy.arc4.DynamicBytes, asset2: algopy.Asset, pay2: algopy.gtxn.PaymentTransaction, - u: algopy.arc4.UInt64, - v: algopy.arc4.UInt64, - ) -> algopy.arc4.UInt64: ... + u: algopy.arc4.UIntN[typing.Literal[64]], + v: algopy.arc4.UIntN[typing.Literal[64]], + ) -> algopy.arc4.UIntN[typing.Literal[64]]: ... @algopy.arc4.abimethod def hello_with_algopy_string( diff --git a/test_cases/abi_routing/out/contract.awst b/test_cases/abi_routing/out/contract.awst index 08763acd0..06461ac9a 100644 --- a/test_cases/abi_routing/out/contract.awst +++ b/test_cases/abi_routing/out/contract.awst @@ -1,51 +1,51 @@ contract Reference { globals { - ['asa']: algopy.Asset - ['an_int']: algopy.UInt64 - ['some_bytes']: algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[3]] - ['creator']: algopy.Account - ['app']: algopy.Application + ['asa']: asset + ['an_int']: uint64 + ['some_bytes']: arc4.static_array + ['creator']: account + ['app']: application } constructor() { - this.asa: algopy.Asset = reinterpret_cast(123u) - this.an_int: algopy.UInt64 = 2u - this.some_bytes: algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[3]] = new algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[3]](7arc4u8, 8arc4u8, 9arc4u8) - this.creator: algopy.Account = txn() - this.app: algopy.Application = reinterpret_cast(123u) + this.asa: asset = reinterpret_cast(123u) + this.an_int: uint64 = 2u + this.some_bytes: arc4.static_array = new arc4.static_array(7arc4u8, 8arc4u8, 9arc4u8) + this.creator: account = txn() + this.app: application = reinterpret_cast(123u) assert(reinterpret_cast(len(Method("get(uint64,byte[])byte[]"))), comment="has method selector") } - abimethod noop_with_uint64(a: algopy.arc4.UInt64): algopy.arc4.UInt8 + abimethod noop_with_uint64(a: arc4.uint64): arc4.uint8 { - result: algopy.UInt64 = 1u + arc4_decode(a, algopy.UInt64) - return arc4_encode(result, algopy.arc4.UInt8) + result: uint64 = 1u + arc4_decode(a, uint64) + return arc4_encode(result, arc4.uint8) } - abimethod[name_override=all_the_things] full_abi_config(a: algopy.arc4.UInt64): algopy.arc4.UInt8 + abimethod[name_override=all_the_things] full_abi_config(a: arc4.uint64): arc4.uint8 { - result: algopy.UInt64 = 1u + arc4_decode(a, algopy.UInt64) - return arc4_encode(result, algopy.arc4.UInt8) + result: uint64 = 1u + arc4_decode(a, uint64) + return arc4_encode(result, arc4.uint8) } - abimethod mixed_oca(a: algopy.arc4.UInt64): algopy.arc4.UInt8 + abimethod mixed_oca(a: arc4.uint64): arc4.uint8 { - result: algopy.UInt64 = 1u + arc4_decode(a, algopy.UInt64) - return arc4_encode(result, algopy.arc4.UInt8) + result: uint64 = 1u + arc4_decode(a, uint64) + return arc4_encode(result, arc4.uint8) } - abimethod bare_abi_config(): None + abimethod bare_abi_config(): void { log('Hello World') } - abimethod opt_into_asset(asset: algopy.Asset): None + abimethod opt_into_asset(asset: asset): void { assert(txn() == global(), comment="Only creator can opt in to ASA") assert(!(reinterpret_cast(this.asa)), comment="ASA already opted in") - this.asa: algopy.Asset = asset + this.asa: asset = asset itxn_begin() itxn_field(axfer) itxn_field(0u) @@ -54,66 +54,66 @@ contract Reference itxn_submit() } - abimethod with_transactions(asset: algopy.Asset, an_int: algopy.arc4.UInt64, pay: algopy.gtxn.PaymentTransaction, another_int: algopy.arc4.UInt64): None + abimethod with_transactions(asset: asset, an_int: arc4.uint64, pay: group_transaction_pay, another_int: arc4.uint64): void { assert(this.asa == asset, comment="is correct asset") - assert(arc4_decode(an_int, algopy.UInt64) == 1u, comment="is correct int") + assert(arc4_decode(an_int, uint64) == 1u, comment="is correct int") assert(gtxns(pay) == global(), comment="is payment to app") - assert(arc4_decode(another_int, algopy.UInt64) == 2u, comment="is correct int") + assert(arc4_decode(another_int, uint64) == 2u, comment="is correct int") } - abimethod compare_assets(asset_a: algopy.Asset, asset_b: algopy.Asset): None + abimethod compare_assets(asset_a: asset, asset_b: asset): void { assert(asset_a == asset_b, comment="asset a == b") } - abimethod get_address(): algopy.arc4.Address + abimethod get_address(): arc4.address { return global() } - abimethod get_asset(): algopy.arc4.UInt64 + abimethod get_asset(): arc4.uint64 { return 456arc4u64 } - abimethod[name_override=get_application] get_app(): algopy.arc4.UInt64 + abimethod[name_override=get_application] get_app(): arc4.uint64 { return 456arc4u64 } - abimethod[name_override=get_an_int] get_a_int(): algopy.arc4.UInt64 + abimethod[name_override=get_an_int] get_a_int(): arc4.uint64 { return 3arc4u64 } - abimethod method_with_default_args(asset_from_storage: algopy.Asset, asset_from_function: algopy.Asset, account_from_storage: algopy.Account, account_from_function: algopy.Account, application_from_storage: algopy.Application, application_from_function: algopy.Application, bytes_from_storage: algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[3]], int_from_storage: algopy.arc4.UInt64, int_from_function: algopy.arc4.UInt64): None + abimethod method_with_default_args(asset_from_storage: asset, asset_from_function: asset, account_from_storage: account, account_from_function: account, application_from_storage: application, application_from_function: application, bytes_from_storage: arc4.static_array, int_from_storage: arc4.uint64, int_from_function: arc4.uint64): void { - assert(asset_from_storage == reinterpret_cast(123u), comment="wrong asset from storage") - assert(asset_from_function == reinterpret_cast(456u), comment="wrong asset from function") + assert(asset_from_storage == reinterpret_cast(123u), comment="wrong asset from storage") + assert(asset_from_function == reinterpret_cast(456u), comment="wrong asset from function") assert(account_from_storage == global(), comment="wrong account from storage") assert(account_from_function == global(), comment="wrong account from function") - assert(application_from_storage == reinterpret_cast(123u), comment="wrong application from storage") - assert(application_from_function == reinterpret_cast(456u), comment="wrong application from function") - assert(reinterpret_cast(bytes_from_storage[0u]) == reinterpret_cast(7arc4u8), comment="wrong 0th byte from storage") - assert(reinterpret_cast(bytes_from_storage[1u]) == reinterpret_cast(8arc4u8), comment="wrong 1st byte from storage") - assert(reinterpret_cast(bytes_from_storage[2u]) == reinterpret_cast(9arc4u8), comment="wrong 2nd byte from storage") - assert(arc4_decode(int_from_storage, algopy.UInt64) == 2u, comment="wrong int from storage") - assert(arc4_decode(int_from_function, algopy.UInt64) == 3u, comment="wrong int from function") + assert(application_from_storage == reinterpret_cast(123u), comment="wrong application from storage") + assert(application_from_function == reinterpret_cast(456u), comment="wrong application from function") + assert(reinterpret_cast(bytes_from_storage[0u]) == reinterpret_cast(7arc4u8), comment="wrong 0th byte from storage") + assert(reinterpret_cast(bytes_from_storage[1u]) == reinterpret_cast(8arc4u8), comment="wrong 1st byte from storage") + assert(reinterpret_cast(bytes_from_storage[2u]) == reinterpret_cast(9arc4u8), comment="wrong 2nd byte from storage") + assert(arc4_decode(int_from_storage, uint64) == 2u, comment="wrong int from storage") + assert(arc4_decode(int_from_function, uint64) == 3u, comment="wrong int from function") } - abimethod method_with_more_than_15_args(a: algopy.arc4.UInt64, b: algopy.arc4.UInt64, c: algopy.arc4.UInt64, d: algopy.UInt64, asset: algopy.Asset, e: algopy.arc4.UInt64, f: algopy.arc4.UInt64, pay: algopy.gtxn.PaymentTransaction, g: algopy.arc4.UInt64, h: algopy.arc4.UInt64, i: algopy.arc4.UInt64, j: algopy.arc4.UInt64, k: algopy.arc4.UInt64, l: algopy.arc4.UInt64, m: algopy.arc4.UInt64, n: algopy.arc4.UInt64, o: algopy.arc4.UInt64, p: algopy.UInt64, q: algopy.arc4.UInt64, r: algopy.arc4.UInt64, s: algopy.Bytes, t: algopy.Bytes, asset2: algopy.Asset, pay2: algopy.gtxn.PaymentTransaction, u: algopy.arc4.UInt64, v: algopy.arc4.UInt64): algopy.arc4.UInt64 + abimethod method_with_more_than_15_args(a: arc4.uint64, b: arc4.uint64, c: arc4.uint64, d: uint64, asset: asset, e: arc4.uint64, f: arc4.uint64, pay: group_transaction_pay, g: arc4.uint64, h: arc4.uint64, i: arc4.uint64, j: arc4.uint64, k: arc4.uint64, l: arc4.uint64, m: arc4.uint64, n: arc4.uint64, o: arc4.uint64, p: uint64, q: arc4.uint64, r: arc4.uint64, s: bytes, t: bytes, asset2: asset, pay2: group_transaction_pay, u: arc4.uint64, v: arc4.uint64): arc4.uint64 { assert(txn() == 16u) assert(gtxns(pay) == 100000u) assert(gtxns(pay2) == 200000u) - assert(reinterpret_cast(reinterpret_cast(asset))) - assert(reinterpret_cast(reinterpret_cast(asset2))) + assert(reinterpret_cast(reinterpret_cast(asset))) + assert(reinterpret_cast(reinterpret_cast(asset2))) log(s + t) - return arc4_encode(arc4_decode(a, algopy.UInt64) + arc4_decode(b, algopy.UInt64) + arc4_decode(c, algopy.UInt64) + d + arc4_decode(e, algopy.UInt64) + arc4_decode(f, algopy.UInt64) + arc4_decode(g, algopy.UInt64) + arc4_decode(h, algopy.UInt64) + arc4_decode(i, algopy.UInt64) + arc4_decode(j, algopy.UInt64) + arc4_decode(k, algopy.UInt64) + arc4_decode(l, algopy.UInt64) + arc4_decode(m, algopy.UInt64) + arc4_decode(n, algopy.UInt64) + arc4_decode(o, algopy.UInt64) + p + arc4_decode(q, algopy.UInt64) + arc4_decode(r, algopy.UInt64) + arc4_decode(u, algopy.UInt64) + arc4_decode(v, algopy.UInt64), algopy.arc4.UInt64) + return arc4_encode(arc4_decode(a, uint64) + arc4_decode(b, uint64) + arc4_decode(c, uint64) + d + arc4_decode(e, uint64) + arc4_decode(f, uint64) + arc4_decode(g, uint64) + arc4_decode(h, uint64) + arc4_decode(i, uint64) + arc4_decode(j, uint64) + arc4_decode(k, uint64) + arc4_decode(l, uint64) + arc4_decode(m, uint64) + arc4_decode(n, uint64) + arc4_decode(o, uint64) + p + arc4_decode(q, uint64) + arc4_decode(r, uint64) + arc4_decode(u, uint64) + arc4_decode(v, uint64), arc4.uint64) } - abimethod hello_with_algopy_string(name: algopy.String): algopy.String + abimethod hello_with_algopy_string(name: string): string { return 'Hello ' + name + '!' } diff --git a/test_cases/abi_routing/out/minimal.awst b/test_cases/abi_routing/out/minimal.awst index 6b8b5f73e..1903f828d 100644 --- a/test_cases/abi_routing/out/minimal.awst +++ b/test_cases/abi_routing/out/minimal.awst @@ -1,11 +1,11 @@ contract MinimumARC4 { globals { - ['gvalue']: algopy.UInt64 + ['gvalue']: uint64 } constructor() { - this.gvalue: algopy.UInt64 = 4u + this.gvalue: uint64 = 4u } } \ No newline at end of file diff --git a/test_cases/application/out/contract.awst b/test_cases/application/out/contract.awst index 23d484a2c..46d0e14c6 100644 --- a/test_cases/application/out/contract.awst +++ b/test_cases/application/out/contract.awst @@ -1,25 +1,25 @@ contract Reference { globals { - ['int_1']: algopy.UInt64 - ['bytes_1']: algopy.Bytes - ['bytes_2']: algopy.Bytes + ['int_1']: uint64 + ['bytes_1']: bytes + ['bytes_2']: bytes } locals { - ['int_l1']: algopy.UInt64 - ['int_l2']: algopy.UInt64 - ['int_l3']: algopy.UInt64 - ['bytes_l1']: algopy.Bytes - ['bytes_l2']: algopy.Bytes - ['bytes_l3']: algopy.Bytes - ['bytes_l4']: algopy.Bytes + ['int_l1']: uint64 + ['int_l2']: uint64 + ['int_l3']: uint64 + ['bytes_l1']: bytes + ['bytes_l2']: bytes + ['bytes_l3']: bytes + ['bytes_l4']: bytes } constructor() { - this.int_1: algopy.UInt64 = 0u - this.bytes_1: algopy.Bytes = '' - this.bytes_2: algopy.Bytes = '' + this.int_1: uint64 = 0u + this.bytes_1: bytes = '' + this.bytes_2: bytes = '' } approval_program(): bool @@ -39,7 +39,7 @@ contract Reference return true } - subroutine validate_asset(app: algopy.Application): None + subroutine validate_asset(app: application): void { assert(!(app_opted_in(txn(), app)), comment="app opted in") assert(checked_maybe(app_params_get(app)) == global(), comment="expected creator") diff --git a/test_cases/arc4_numeric_comparisons/out/uint_n.awst b/test_cases/arc4_numeric_comparisons/out/uint_n.awst index aff050514..4bd004938 100644 --- a/test_cases/arc4_numeric_comparisons/out/uint_n.awst +++ b/test_cases/arc4_numeric_comparisons/out/uint_n.awst @@ -14,188 +14,188 @@ contract UIntNOrdering } } -subroutine check_both_uint_n(one: algopy.arc4.Byte, two: algopy.arc4.UInt64): None +subroutine check_both_uint_n(one: arc4.byte, two: arc4.uint64): void { - one_uint64: algopy.UInt64 = 1u - one_biguint: algopy.BigUInt = 1n - two_uint64: algopy.UInt64 = 2u - two_biguint: algopy.BigUInt = 2n - assert(reinterpret_cast(one) == reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) == reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) == reinterpret_cast(one)) - assert(reinterpret_cast(one) == itob(one_uint64)) - assert(reinterpret_cast(one) == one_biguint) - assert(!(reinterpret_cast(one) == reinterpret_cast(2arc4u8))) - assert(!(reinterpret_cast(one) == reinterpret_cast(two))) - assert(!(reinterpret_cast(one) == itob(two_uint64))) - assert(!(reinterpret_cast(one) == two_biguint)) - assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) != reinterpret_cast(one))) - assert(!(reinterpret_cast(one) != itob(one_uint64))) - assert(!(reinterpret_cast(one) != one_biguint)) - assert(reinterpret_cast(one) != reinterpret_cast(2arc4u8)) - assert(reinterpret_cast(one) != reinterpret_cast(two)) - assert(reinterpret_cast(one) != itob(two_uint64)) - assert(reinterpret_cast(one) != two_biguint) - assert(reinterpret_cast(one) <= reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) >= reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) <= reinterpret_cast(one)) - assert(reinterpret_cast(one) <= itob(one_uint64)) - assert(reinterpret_cast(one) <= one_biguint) - assert(reinterpret_cast(one) <= reinterpret_cast(2arc4u8)) - assert(reinterpret_cast(one) <= reinterpret_cast(two)) - assert(reinterpret_cast(one) <= itob(two_uint64)) - assert(reinterpret_cast(one) <= two_biguint) - assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) < reinterpret_cast(one))) - assert(!(reinterpret_cast(one) < itob(one_uint64))) - assert(!(reinterpret_cast(one) < one_biguint)) - assert(reinterpret_cast(one) < reinterpret_cast(2arc4u8)) - assert(reinterpret_cast(one) < reinterpret_cast(two)) - assert(reinterpret_cast(one) < itob(two_uint64)) - assert(reinterpret_cast(one) < two_biguint) - assert(reinterpret_cast(one) >= reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) <= reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) >= reinterpret_cast(one)) - assert(reinterpret_cast(one) >= itob(one_uint64)) - assert(reinterpret_cast(one) >= one_biguint) - assert(!(reinterpret_cast(one) >= reinterpret_cast(2arc4u8))) - assert(!(reinterpret_cast(one) >= reinterpret_cast(two))) - assert(!(reinterpret_cast(one) >= itob(two_uint64))) - assert(!(reinterpret_cast(one) >= two_biguint)) - assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) > reinterpret_cast(one))) - assert(!(reinterpret_cast(one) > itob(one_uint64))) - assert(!(reinterpret_cast(one) > one_biguint)) - assert(!(reinterpret_cast(one) > reinterpret_cast(2arc4u8))) - assert(!(reinterpret_cast(one) > reinterpret_cast(two))) - assert(!(reinterpret_cast(one) > itob(two_uint64))) - assert(!(reinterpret_cast(one) > two_biguint)) + one_uint64: uint64 = 1u + one_biguint: biguint = 1n + two_uint64: uint64 = 2u + two_biguint: biguint = 2n + assert(reinterpret_cast(one) == reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) == reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) == reinterpret_cast(one)) + assert(reinterpret_cast(one) == itob(one_uint64)) + assert(reinterpret_cast(one) == one_biguint) + assert(!(reinterpret_cast(one) == reinterpret_cast(2arc4u8))) + assert(!(reinterpret_cast(one) == reinterpret_cast(two))) + assert(!(reinterpret_cast(one) == itob(two_uint64))) + assert(!(reinterpret_cast(one) == two_biguint)) + assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) != reinterpret_cast(one))) + assert(!(reinterpret_cast(one) != itob(one_uint64))) + assert(!(reinterpret_cast(one) != one_biguint)) + assert(reinterpret_cast(one) != reinterpret_cast(2arc4u8)) + assert(reinterpret_cast(one) != reinterpret_cast(two)) + assert(reinterpret_cast(one) != itob(two_uint64)) + assert(reinterpret_cast(one) != two_biguint) + assert(reinterpret_cast(one) <= reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) >= reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) <= reinterpret_cast(one)) + assert(reinterpret_cast(one) <= itob(one_uint64)) + assert(reinterpret_cast(one) <= one_biguint) + assert(reinterpret_cast(one) <= reinterpret_cast(2arc4u8)) + assert(reinterpret_cast(one) <= reinterpret_cast(two)) + assert(reinterpret_cast(one) <= itob(two_uint64)) + assert(reinterpret_cast(one) <= two_biguint) + assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) < reinterpret_cast(one))) + assert(!(reinterpret_cast(one) < itob(one_uint64))) + assert(!(reinterpret_cast(one) < one_biguint)) + assert(reinterpret_cast(one) < reinterpret_cast(2arc4u8)) + assert(reinterpret_cast(one) < reinterpret_cast(two)) + assert(reinterpret_cast(one) < itob(two_uint64)) + assert(reinterpret_cast(one) < two_biguint) + assert(reinterpret_cast(one) >= reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) <= reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) >= reinterpret_cast(one)) + assert(reinterpret_cast(one) >= itob(one_uint64)) + assert(reinterpret_cast(one) >= one_biguint) + assert(!(reinterpret_cast(one) >= reinterpret_cast(2arc4u8))) + assert(!(reinterpret_cast(one) >= reinterpret_cast(two))) + assert(!(reinterpret_cast(one) >= itob(two_uint64))) + assert(!(reinterpret_cast(one) >= two_biguint)) + assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) > reinterpret_cast(one))) + assert(!(reinterpret_cast(one) > itob(one_uint64))) + assert(!(reinterpret_cast(one) > one_biguint)) + assert(!(reinterpret_cast(one) > reinterpret_cast(2arc4u8))) + assert(!(reinterpret_cast(one) > reinterpret_cast(two))) + assert(!(reinterpret_cast(one) > itob(two_uint64))) + assert(!(reinterpret_cast(one) > two_biguint)) } -subroutine check_mixed(one: algopy.arc4.Byte, two: algopy.arc4.BigUIntN[typing.Literal[264]]): None +subroutine check_mixed(one: arc4.byte, two: arc4.uint264): void { - one_uint64: algopy.UInt64 = 1u - one_biguint: algopy.BigUInt = 1n - two_uint64: algopy.UInt64 = 2u - two_biguint: algopy.BigUInt = 2n - assert(reinterpret_cast(one) == reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) == reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) == reinterpret_cast(one)) - assert(reinterpret_cast(one) == itob(one_uint64)) - assert(reinterpret_cast(one) == one_biguint) - assert(!(reinterpret_cast(one) == reinterpret_cast(2arc4u8))) - assert(!(reinterpret_cast(one) == reinterpret_cast(two))) - assert(!(reinterpret_cast(one) == itob(two_uint64))) - assert(!(reinterpret_cast(one) == two_biguint)) - assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) != reinterpret_cast(one))) - assert(!(reinterpret_cast(one) != itob(one_uint64))) - assert(!(reinterpret_cast(one) != one_biguint)) - assert(reinterpret_cast(one) != reinterpret_cast(2arc4u8)) - assert(reinterpret_cast(one) != reinterpret_cast(two)) - assert(reinterpret_cast(one) != itob(two_uint64)) - assert(reinterpret_cast(one) != two_biguint) - assert(reinterpret_cast(one) <= reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) >= reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) <= reinterpret_cast(one)) - assert(reinterpret_cast(one) <= itob(one_uint64)) - assert(reinterpret_cast(one) <= one_biguint) - assert(reinterpret_cast(one) <= reinterpret_cast(2arc4u8)) - assert(reinterpret_cast(one) <= reinterpret_cast(two)) - assert(reinterpret_cast(one) <= itob(two_uint64)) - assert(reinterpret_cast(one) <= two_biguint) - assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) < reinterpret_cast(one))) - assert(!(reinterpret_cast(one) < itob(one_uint64))) - assert(!(reinterpret_cast(one) < one_biguint)) - assert(reinterpret_cast(one) < reinterpret_cast(2arc4u8)) - assert(reinterpret_cast(one) < reinterpret_cast(two)) - assert(reinterpret_cast(one) < itob(two_uint64)) - assert(reinterpret_cast(one) < two_biguint) - assert(reinterpret_cast(one) >= reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) <= reinterpret_cast(1arc4u8)) - assert(reinterpret_cast(one) >= reinterpret_cast(one)) - assert(reinterpret_cast(one) >= itob(one_uint64)) - assert(reinterpret_cast(one) >= one_biguint) - assert(!(reinterpret_cast(one) >= reinterpret_cast(2arc4u8))) - assert(!(reinterpret_cast(one) >= reinterpret_cast(two))) - assert(!(reinterpret_cast(one) >= itob(two_uint64))) - assert(!(reinterpret_cast(one) >= two_biguint)) - assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4u8))) - assert(!(reinterpret_cast(one) > reinterpret_cast(one))) - assert(!(reinterpret_cast(one) > itob(one_uint64))) - assert(!(reinterpret_cast(one) > one_biguint)) - assert(!(reinterpret_cast(one) > reinterpret_cast(2arc4u8))) - assert(!(reinterpret_cast(one) > reinterpret_cast(two))) - assert(!(reinterpret_cast(one) > itob(two_uint64))) - assert(!(reinterpret_cast(one) > two_biguint)) + one_uint64: uint64 = 1u + one_biguint: biguint = 1n + two_uint64: uint64 = 2u + two_biguint: biguint = 2n + assert(reinterpret_cast(one) == reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) == reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) == reinterpret_cast(one)) + assert(reinterpret_cast(one) == itob(one_uint64)) + assert(reinterpret_cast(one) == one_biguint) + assert(!(reinterpret_cast(one) == reinterpret_cast(2arc4u8))) + assert(!(reinterpret_cast(one) == reinterpret_cast(two))) + assert(!(reinterpret_cast(one) == itob(two_uint64))) + assert(!(reinterpret_cast(one) == two_biguint)) + assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) != reinterpret_cast(one))) + assert(!(reinterpret_cast(one) != itob(one_uint64))) + assert(!(reinterpret_cast(one) != one_biguint)) + assert(reinterpret_cast(one) != reinterpret_cast(2arc4u8)) + assert(reinterpret_cast(one) != reinterpret_cast(two)) + assert(reinterpret_cast(one) != itob(two_uint64)) + assert(reinterpret_cast(one) != two_biguint) + assert(reinterpret_cast(one) <= reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) >= reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) <= reinterpret_cast(one)) + assert(reinterpret_cast(one) <= itob(one_uint64)) + assert(reinterpret_cast(one) <= one_biguint) + assert(reinterpret_cast(one) <= reinterpret_cast(2arc4u8)) + assert(reinterpret_cast(one) <= reinterpret_cast(two)) + assert(reinterpret_cast(one) <= itob(two_uint64)) + assert(reinterpret_cast(one) <= two_biguint) + assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) < reinterpret_cast(one))) + assert(!(reinterpret_cast(one) < itob(one_uint64))) + assert(!(reinterpret_cast(one) < one_biguint)) + assert(reinterpret_cast(one) < reinterpret_cast(2arc4u8)) + assert(reinterpret_cast(one) < reinterpret_cast(two)) + assert(reinterpret_cast(one) < itob(two_uint64)) + assert(reinterpret_cast(one) < two_biguint) + assert(reinterpret_cast(one) >= reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) <= reinterpret_cast(1arc4u8)) + assert(reinterpret_cast(one) >= reinterpret_cast(one)) + assert(reinterpret_cast(one) >= itob(one_uint64)) + assert(reinterpret_cast(one) >= one_biguint) + assert(!(reinterpret_cast(one) >= reinterpret_cast(2arc4u8))) + assert(!(reinterpret_cast(one) >= reinterpret_cast(two))) + assert(!(reinterpret_cast(one) >= itob(two_uint64))) + assert(!(reinterpret_cast(one) >= two_biguint)) + assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4u8))) + assert(!(reinterpret_cast(one) > reinterpret_cast(one))) + assert(!(reinterpret_cast(one) > itob(one_uint64))) + assert(!(reinterpret_cast(one) > one_biguint)) + assert(!(reinterpret_cast(one) > reinterpret_cast(2arc4u8))) + assert(!(reinterpret_cast(one) > reinterpret_cast(two))) + assert(!(reinterpret_cast(one) > itob(two_uint64))) + assert(!(reinterpret_cast(one) > two_biguint)) } -subroutine check_both_big_uint_n(one: algopy.arc4.UInt256, two: algopy.arc4.BigUIntN[typing.Literal[264]]): None +subroutine check_both_big_uint_n(one: arc4.uint256, two: arc4.uint264): void { - one_uint64: algopy.UInt64 = 1u - one_biguint: algopy.BigUInt = 1n - two_uint64: algopy.UInt64 = 2u - two_biguint: algopy.BigUInt = 2n - assert(reinterpret_cast(one) == reinterpret_cast(1arc4n256)) - assert(reinterpret_cast(one) == reinterpret_cast(1arc4n256)) - assert(reinterpret_cast(one) == reinterpret_cast(one)) - assert(reinterpret_cast(one) == itob(one_uint64)) - assert(reinterpret_cast(one) == one_biguint) - assert(!(reinterpret_cast(one) == reinterpret_cast(2arc4n256))) - assert(!(reinterpret_cast(one) == reinterpret_cast(two))) - assert(!(reinterpret_cast(one) == itob(two_uint64))) - assert(!(reinterpret_cast(one) == two_biguint)) - assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4n256))) - assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4n256))) - assert(!(reinterpret_cast(one) != reinterpret_cast(one))) - assert(!(reinterpret_cast(one) != itob(one_uint64))) - assert(!(reinterpret_cast(one) != one_biguint)) - assert(reinterpret_cast(one) != reinterpret_cast(2arc4n256)) - assert(reinterpret_cast(one) != reinterpret_cast(two)) - assert(reinterpret_cast(one) != itob(two_uint64)) - assert(reinterpret_cast(one) != two_biguint) - assert(reinterpret_cast(one) <= reinterpret_cast(1arc4n256)) - assert(reinterpret_cast(one) >= reinterpret_cast(1arc4n256)) - assert(reinterpret_cast(one) <= reinterpret_cast(one)) - assert(reinterpret_cast(one) <= itob(one_uint64)) - assert(reinterpret_cast(one) <= one_biguint) - assert(reinterpret_cast(one) <= reinterpret_cast(2arc4n256)) - assert(reinterpret_cast(one) <= reinterpret_cast(two)) - assert(reinterpret_cast(one) <= itob(two_uint64)) - assert(reinterpret_cast(one) <= two_biguint) - assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4n256))) - assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4n256))) - assert(!(reinterpret_cast(one) < reinterpret_cast(one))) - assert(!(reinterpret_cast(one) < itob(one_uint64))) - assert(!(reinterpret_cast(one) < one_biguint)) - assert(reinterpret_cast(one) < reinterpret_cast(2arc4n256)) - assert(reinterpret_cast(one) < reinterpret_cast(two)) - assert(reinterpret_cast(one) < itob(two_uint64)) - assert(reinterpret_cast(one) < two_biguint) - assert(reinterpret_cast(one) >= reinterpret_cast(1arc4n256)) - assert(reinterpret_cast(one) <= reinterpret_cast(1arc4n256)) - assert(reinterpret_cast(one) >= reinterpret_cast(one)) - assert(reinterpret_cast(one) >= itob(one_uint64)) - assert(reinterpret_cast(one) >= one_biguint) - assert(!(reinterpret_cast(one) >= reinterpret_cast(2arc4n256))) - assert(!(reinterpret_cast(one) >= reinterpret_cast(two))) - assert(!(reinterpret_cast(one) >= itob(two_uint64))) - assert(!(reinterpret_cast(one) >= two_biguint)) - assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4n256))) - assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4n256))) - assert(!(reinterpret_cast(one) > reinterpret_cast(one))) - assert(!(reinterpret_cast(one) > itob(one_uint64))) - assert(!(reinterpret_cast(one) > one_biguint)) - assert(!(reinterpret_cast(one) > reinterpret_cast(2arc4n256))) - assert(!(reinterpret_cast(one) > reinterpret_cast(two))) - assert(!(reinterpret_cast(one) > itob(two_uint64))) - assert(!(reinterpret_cast(one) > two_biguint)) + one_uint64: uint64 = 1u + one_biguint: biguint = 1n + two_uint64: uint64 = 2u + two_biguint: biguint = 2n + assert(reinterpret_cast(one) == reinterpret_cast(1arc4n256)) + assert(reinterpret_cast(one) == reinterpret_cast(1arc4n256)) + assert(reinterpret_cast(one) == reinterpret_cast(one)) + assert(reinterpret_cast(one) == itob(one_uint64)) + assert(reinterpret_cast(one) == one_biguint) + assert(!(reinterpret_cast(one) == reinterpret_cast(2arc4n256))) + assert(!(reinterpret_cast(one) == reinterpret_cast(two))) + assert(!(reinterpret_cast(one) == itob(two_uint64))) + assert(!(reinterpret_cast(one) == two_biguint)) + assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4n256))) + assert(!(reinterpret_cast(one) != reinterpret_cast(1arc4n256))) + assert(!(reinterpret_cast(one) != reinterpret_cast(one))) + assert(!(reinterpret_cast(one) != itob(one_uint64))) + assert(!(reinterpret_cast(one) != one_biguint)) + assert(reinterpret_cast(one) != reinterpret_cast(2arc4n256)) + assert(reinterpret_cast(one) != reinterpret_cast(two)) + assert(reinterpret_cast(one) != itob(two_uint64)) + assert(reinterpret_cast(one) != two_biguint) + assert(reinterpret_cast(one) <= reinterpret_cast(1arc4n256)) + assert(reinterpret_cast(one) >= reinterpret_cast(1arc4n256)) + assert(reinterpret_cast(one) <= reinterpret_cast(one)) + assert(reinterpret_cast(one) <= itob(one_uint64)) + assert(reinterpret_cast(one) <= one_biguint) + assert(reinterpret_cast(one) <= reinterpret_cast(2arc4n256)) + assert(reinterpret_cast(one) <= reinterpret_cast(two)) + assert(reinterpret_cast(one) <= itob(two_uint64)) + assert(reinterpret_cast(one) <= two_biguint) + assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4n256))) + assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4n256))) + assert(!(reinterpret_cast(one) < reinterpret_cast(one))) + assert(!(reinterpret_cast(one) < itob(one_uint64))) + assert(!(reinterpret_cast(one) < one_biguint)) + assert(reinterpret_cast(one) < reinterpret_cast(2arc4n256)) + assert(reinterpret_cast(one) < reinterpret_cast(two)) + assert(reinterpret_cast(one) < itob(two_uint64)) + assert(reinterpret_cast(one) < two_biguint) + assert(reinterpret_cast(one) >= reinterpret_cast(1arc4n256)) + assert(reinterpret_cast(one) <= reinterpret_cast(1arc4n256)) + assert(reinterpret_cast(one) >= reinterpret_cast(one)) + assert(reinterpret_cast(one) >= itob(one_uint64)) + assert(reinterpret_cast(one) >= one_biguint) + assert(!(reinterpret_cast(one) >= reinterpret_cast(2arc4n256))) + assert(!(reinterpret_cast(one) >= reinterpret_cast(two))) + assert(!(reinterpret_cast(one) >= itob(two_uint64))) + assert(!(reinterpret_cast(one) >= two_biguint)) + assert(!(reinterpret_cast(one) > reinterpret_cast(1arc4n256))) + assert(!(reinterpret_cast(one) < reinterpret_cast(1arc4n256))) + assert(!(reinterpret_cast(one) > reinterpret_cast(one))) + assert(!(reinterpret_cast(one) > itob(one_uint64))) + assert(!(reinterpret_cast(one) > one_biguint)) + assert(!(reinterpret_cast(one) > reinterpret_cast(2arc4n256))) + assert(!(reinterpret_cast(one) > reinterpret_cast(two))) + assert(!(reinterpret_cast(one) > itob(two_uint64))) + assert(!(reinterpret_cast(one) > two_biguint)) } \ No newline at end of file diff --git a/test_cases/arc4_types/out/address.awst b/test_cases/arc4_types/out/address.awst index c5960d7a7..23692a323 100644 --- a/test_cases/arc4_types/out/address.awst +++ b/test_cases/arc4_types/out/address.awst @@ -4,16 +4,16 @@ contract Arc4AddressContract { approval_program(): bool { - address: algopy.arc4.Address = reinterpret_cast(reinterpret_cast(txn())) - assert(reinterpret_cast(address) == reinterpret_cast(txn())) + address: arc4.address = reinterpret_cast(reinterpret_cast(txn())) + assert(reinterpret_cast(address) == reinterpret_cast(txn())) assert(32u == 32u) - assert(reinterpret_cast(address) == txn()) - zero_address: algopy.arc4.Address = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=0, source=reinterpret_cast(global())), 32u == len(SINGLE_EVAL(id=0, source=reinterpret_cast(global())))))) - assert(reinterpret_cast(zero_address) == reinterpret_cast(global())) - some_address: algopy.arc4.Address = reinterpret_cast(Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA")) - assert(reinterpret_cast(some_address) == reinterpret_cast(Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA"))) - some_address[0u]: algopy.arc4.Byte = 123arc4u8 - assert(reinterpret_cast(some_address) != reinterpret_cast(Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA"))) + assert(reinterpret_cast(address) == txn()) + zero_address: arc4.address = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=0, source=reinterpret_cast(global())), 32u == len(SINGLE_EVAL(id=0, source=reinterpret_cast(global())))))) + assert(reinterpret_cast(zero_address) == reinterpret_cast(global())) + some_address: arc4.address = reinterpret_cast(Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA")) + assert(reinterpret_cast(some_address) == reinterpret_cast(Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA"))) + some_address[0u]: arc4.byte = 123arc4u8 + assert(reinterpret_cast(some_address) != reinterpret_cast(Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA"))) return true } diff --git a/test_cases/arc4_types/out/array.awst b/test_cases/arc4_types/out/array.awst index 64b6b0b03..aba23924c 100644 --- a/test_cases/arc4_types/out/array.awst +++ b/test_cases/arc4_types/out/array.awst @@ -2,44 +2,44 @@ contract Arc4ArraysContract { approval_program(): bool { - dynamic_uint8_array: algopy.arc4.DynamicArray[algopy.arc4.UInt8] = new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8) - total: algopy.UInt64 = 0u + dynamic_uint8_array: arc4.dynamic_array = new arc4.dynamic_array(1arc4u8, 2arc4u8) + total: uint64 = 0u for uint8_item in dynamic_uint8_array { - total += arc4_decode(uint8_item, algopy.UInt64) + total += arc4_decode(uint8_item, uint64) } assert(total == 3u, comment="Total should be sum of dynamic_uint8_array items") - aliased_dynamic: algopy.arc4.DynamicArray[algopy.arc4.UInt16] = new algopy.arc4.DynamicArray[algopy.arc4.UInt16](1arc4u16) + aliased_dynamic: arc4.dynamic_array = new arc4.dynamic_array(1arc4u16) for uint16_item in aliased_dynamic { - total += arc4_decode(uint16_item, algopy.UInt64) + total += arc4_decode(uint16_item, uint64) } assert(total == 4u, comment="Total should now include sum of aliased_dynamic items") - dynamic_string_array: algopy.arc4.DynamicArray[algopy.arc4.String] = new algopy.arc4.DynamicArray[algopy.arc4.String](arc4_encode('Hello', algopy.arc4.String), arc4_encode('World', algopy.arc4.String)) + dynamic_string_array: arc4.dynamic_array = new arc4.dynamic_array(arc4_encode('Hello', arc4.string), arc4_encode('World', arc4.string)) assert(extract_uint16(dynamic_string_array, 0u) == 2u) - assert(reinterpret_cast(dynamic_string_array[0u]) == reinterpret_cast(arc4_encode('Hello', algopy.arc4.String))) - result: algopy.String = '' + assert(reinterpret_cast(dynamic_string_array[0u]) == reinterpret_cast(arc4_encode('Hello', arc4.string))) + result: string = '' for (index, string_item) in enumerate(dynamic_string_array) { if (index == 0u) { - result: algopy.String = arc4_decode(string_item, algopy.String) + result: string = arc4_decode(string_item, string) } else { - result += ' ' + arc4_decode(string_item, algopy.String) + result += ' ' + arc4_decode(string_item, string) } } assert(result == 'Hello World') - static_uint32_array: algopy.arc4.StaticArray[algopy.arc4.UInt32, typing.Literal[4]] = new algopy.arc4.StaticArray[algopy.arc4.UInt32, typing.Literal[4]](1arc4u32, 10arc4u32, 255arc4u32, 128arc4u32) + static_uint32_array: arc4.static_array = new arc4.static_array(1arc4u32, 10arc4u32, 255arc4u32, 128arc4u32) for uint32_item in static_uint32_array { - total += arc4_decode(uint32_item, algopy.UInt64) + total += arc4_decode(uint32_item, uint64) } assert(total == 398u) - aliased_static: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[1]] = new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[1]](101arc4u8) - index: algopy.UInt64 = 0u - assert(arc4_decode(aliased_static[0u], algopy.UInt64) + arc4_decode(aliased_static[index], algopy.UInt64) == 202u) - static_string_array: algopy.arc4.StaticArray[algopy.arc4.String, typing.Literal[2]] = new algopy.arc4.StaticArray[algopy.arc4.String, typing.Literal[2]](arc4_encode('Ping', algopy.arc4.String), arc4_encode('Pong', algopy.arc4.String)) - result: algopy.String = '' + aliased_static: arc4.static_array = new arc4.static_array(101arc4u8) + index: uint64 = 0u + assert(arc4_decode(aliased_static[0u], uint64) + arc4_decode(aliased_static[index], uint64) == 202u) + static_string_array: arc4.static_array = new arc4.static_array(arc4_encode('Ping', arc4.string), arc4_encode('Pong', arc4.string)) + result: string = '' for (index, string_item) in enumerate(static_string_array) { if (index == 0u) { - result: algopy.String = arc4_decode(string_item, algopy.String) + result: string = arc4_decode(string_item, string) } else { - result += ' ' + arc4_decode(string_item, algopy.String) + result += ' ' + arc4_decode(string_item, string) } } assert(result == 'Ping Pong') @@ -52,8 +52,8 @@ contract Arc4ArraysContract return true } - subroutine hash_as_array(commitment_args_concat: algopy.Bytes): algopy.arc4.StaticArray[algopy.arc4.Byte, typing.Literal[32]] + subroutine hash_as_array(commitment_args_concat: bytes): arc4.static_array { - return reinterpret_cast(sha3_256(commitment_args_concat)) + return reinterpret_cast>(sha3_256(commitment_args_concat)) } } \ No newline at end of file diff --git a/test_cases/arc4_types/out/bool.awst b/test_cases/arc4_types/out/bool.awst index 97ff3b3a8..ebae4be27 100644 --- a/test_cases/arc4_types/out/bool.awst +++ b/test_cases/arc4_types/out/bool.awst @@ -2,13 +2,13 @@ contract Arc4BoolTypeContract { approval_program(): bool { - this::test_stuff(arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool)) - static_boolean_array: algopy.arc4.StaticArray[algopy.arc4.Bool, typing.Literal[12]] = new algopy.arc4.StaticArray[algopy.arc4.Bool, typing.Literal[12]](arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool)) - assert(reinterpret_cast(static_boolean_array) == hex<"FFF0">) - assert(reinterpret_cast(static_boolean_array[0u]) == reinterpret_cast(arc4_encode(true, algopy.arc4.Bool)), comment="Single boolean can be unpacked") - assert(reinterpret_cast(static_boolean_array[12u - 1u]) == reinterpret_cast(arc4_encode(true, algopy.arc4.Bool)), comment="Single boolean can be unpacked") - dynamic_boolean_array: algopy.arc4.DynamicArray[algopy.arc4.Bool] = new algopy.arc4.DynamicArray[algopy.arc4.Bool](arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool)) - assert(reinterpret_cast(dynamic_boolean_array) == hex<"0003A0">) + this::test_stuff(arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool)) + static_boolean_array: arc4.static_array = new arc4.static_array(arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool)) + assert(reinterpret_cast(static_boolean_array) == hex<"FFF0">) + assert(reinterpret_cast(static_boolean_array[0u]) == reinterpret_cast(arc4_encode(true, arc4.bool)), comment="Single boolean can be unpacked") + assert(reinterpret_cast(static_boolean_array[12u - 1u]) == reinterpret_cast(arc4_encode(true, arc4.bool)), comment="Single boolean can be unpacked") + dynamic_boolean_array: arc4.dynamic_array = new arc4.dynamic_array(arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool)) + assert(reinterpret_cast(dynamic_boolean_array) == hex<"0003A0">) return true } @@ -17,12 +17,11 @@ contract Arc4BoolTypeContract return true } - subroutine test_stuff(true: algopy.arc4.Bool, false: algopy.arc4.Bool): bool + subroutine test_stuff(true: arc4.bool, false: arc4.bool): void { assert(arc4_decode(true, bool)) assert(!(arc4_decode(false, bool))) - assert(reinterpret_cast(true) == reinterpret_cast(arc4_encode(arc4_decode(true, bool), algopy.arc4.Bool))) - assert(reinterpret_cast(false) == reinterpret_cast(arc4_encode(arc4_decode(false, bool), algopy.arc4.Bool))) - return arc4_decode(true, bool) + assert(reinterpret_cast(true) == reinterpret_cast(arc4_encode(arc4_decode(true, bool), arc4.bool))) + assert(reinterpret_cast(false) == reinterpret_cast(arc4_encode(arc4_decode(false, bool), arc4.bool))) } } \ No newline at end of file diff --git a/test_cases/arc4_types/out/bool_eval.awst b/test_cases/arc4_types/out/bool_eval.awst index 1fe01c0ee..497184a71 100644 --- a/test_cases/arc4_types/out/bool_eval.awst +++ b/test_cases/arc4_types/out/bool_eval.awst @@ -1,50 +1,50 @@ struct MyStruct { - x: algopy.arc4.UInt512 + x: arc4.uint512 } contract Arc4BoolEvalContract { approval_program(): bool { - assert(reinterpret_cast(arc4_encode(false, algopy.arc4.Bool)) == hex<"00">) - assert(reinterpret_cast(arc4_encode(true, algopy.arc4.Bool)) != hex<"00">) - assert(reinterpret_cast(arc4_encode('', algopy.arc4.String)) == hex<"0000">) - assert(reinterpret_cast(arc4_encode('.', algopy.arc4.String)) != hex<"0000">) - assert(reinterpret_cast(global()) == global()) - assert(reinterpret_cast(reinterpret_cast(reinterpret_cast(txn()))) != global()) - assert(reinterpret_cast(0arc4u8) == hex<"00">) - assert(reinterpret_cast(1arc4u8) != hex<"00">) - assert(reinterpret_cast(0arc4u16) == hex<"0000">) - assert(reinterpret_cast(1arc4u16) != hex<"0000">) - assert(reinterpret_cast(0arc4u32) == hex<"00000000">) - assert(reinterpret_cast(1arc4u32) != hex<"00000000">) - assert(reinterpret_cast(0arc4u64) == hex<"0000000000000000">) - assert(reinterpret_cast(1arc4u64) != hex<"0000000000000000">) - assert(reinterpret_cast(0arc4n128) == hex<"00000000000000000000000000000000">) - assert(reinterpret_cast(1arc4n128) != hex<"00000000000000000000000000000000">) - assert(reinterpret_cast(0arc4n256) == hex<"0000000000000000000000000000000000000000000000000000000000000000">) - assert(reinterpret_cast(1arc4n256) != hex<"0000000000000000000000000000000000000000000000000000000000000000">) - assert(reinterpret_cast(0arc4n512) == hex<"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) - assert(reinterpret_cast(1arc4n512) != hex<"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) - assert(reinterpret_cast(0arc4u24) == hex<"000000">) - assert(reinterpret_cast(1arc4u24) != hex<"000000">) - assert(reinterpret_cast(0arc4n504) == hex<"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) - assert(reinterpret_cast(1arc4n504) != hex<"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) - assert(reinterpret_cast(0E-10arc4u48x10) == hex<"000000000000">) - assert(reinterpret_cast(1.0000000000arc4u48x10) != hex<"000000000000">) - assert(reinterpret_cast(0E-10arc4n496x10) == hex<"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) - assert(reinterpret_cast(0.0100000000arc4n496x10) != hex<"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) + assert(reinterpret_cast(arc4_encode(false, arc4.bool)) == hex<"00">) + assert(reinterpret_cast(arc4_encode(true, arc4.bool)) != hex<"00">) + assert(reinterpret_cast(arc4_encode('', arc4.string)) == hex<"0000">) + assert(reinterpret_cast(arc4_encode('.', arc4.string)) != hex<"0000">) + assert(reinterpret_cast(global()) == global()) + assert(reinterpret_cast(reinterpret_cast(reinterpret_cast(txn()))) != global()) + assert(reinterpret_cast(0arc4u8) == hex<"00">) + assert(reinterpret_cast(1arc4u8) != hex<"00">) + assert(reinterpret_cast(0arc4u16) == hex<"0000">) + assert(reinterpret_cast(1arc4u16) != hex<"0000">) + assert(reinterpret_cast(0arc4u32) == hex<"00000000">) + assert(reinterpret_cast(1arc4u32) != hex<"00000000">) + assert(reinterpret_cast(0arc4u64) == hex<"0000000000000000">) + assert(reinterpret_cast(1arc4u64) != hex<"0000000000000000">) + assert(reinterpret_cast(0arc4n128) == hex<"00000000000000000000000000000000">) + assert(reinterpret_cast(1arc4n128) != hex<"00000000000000000000000000000000">) + assert(reinterpret_cast(0arc4n256) == hex<"0000000000000000000000000000000000000000000000000000000000000000">) + assert(reinterpret_cast(1arc4n256) != hex<"0000000000000000000000000000000000000000000000000000000000000000">) + assert(reinterpret_cast(0arc4n512) == hex<"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) + assert(reinterpret_cast(1arc4n512) != hex<"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) + assert(reinterpret_cast(0arc4u24) == hex<"000000">) + assert(reinterpret_cast(1arc4u24) != hex<"000000">) + assert(reinterpret_cast(0arc4n504) == hex<"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) + assert(reinterpret_cast(1arc4n504) != hex<"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) + assert(reinterpret_cast(0E-10arc4u48x10) == hex<"000000000000">) + assert(reinterpret_cast(1.0000000000arc4u48x10) != hex<"000000000000">) + assert(reinterpret_cast(0E-10arc4n496x10) == hex<"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) + assert(reinterpret_cast(0.0100000000arc4n496x10) != hex<"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">) assert(true) assert(true) assert(true) assert(true) - dynamic_arr: algopy.arc4.DynamicArray[algopy.arc4.UInt64] = new algopy.arc4.DynamicArray[algopy.arc4.UInt64]() - assert(reinterpret_cast(dynamic_arr) == hex<"0000">) + dynamic_arr: arc4.dynamic_array = new arc4.dynamic_array() + assert(reinterpret_cast(dynamic_arr) == hex<"0000">) dynamic_arr.extend((0arc4u64)) - assert(reinterpret_cast(dynamic_arr) != hex<"0000">) + assert(reinterpret_cast(dynamic_arr) != hex<"0000">) assert(true) assert(true) - assert(reinterpret_cast(arc4_encode(false, algopy.arc4.Bool)) == reinterpret_cast(arc4_encode(false, algopy.arc4.Bool))) + assert(reinterpret_cast(arc4_encode(false, arc4.bool)) == reinterpret_cast(arc4_encode(false, arc4.bool))) return true } diff --git a/test_cases/arc4_types/out/dynamic_bytes.awst b/test_cases/arc4_types/out/dynamic_bytes.awst index b74ff2241..31902052e 100644 --- a/test_cases/arc4_types/out/dynamic_bytes.awst +++ b/test_cases/arc4_types/out/dynamic_bytes.awst @@ -2,30 +2,30 @@ contract Arc4DynamicBytesContract { approval_program(): bool { - total: algopy.UInt64 = 0u - dynamic_bytes: algopy.arc4.DynamicBytes = new algopy.arc4.DynamicBytes(2arc4u8, reinterpret_cast(3arc4u8), 1arc4u8) - assert(arc4_decode(dynamic_bytes, algopy.Bytes) == '\x02\x03\x01') - assert(reinterpret_cast(dynamic_bytes) == '\x00\x03\x02\x03\x01') + total: uint64 = 0u + dynamic_bytes: arc4.dynamic_bytes = new arc4.dynamic_bytes(2arc4u8, reinterpret_cast(3arc4u8), 1arc4u8) + assert(extract<2, 0>(reinterpret_cast(dynamic_bytes)) == '\x02\x03\x01') + assert(reinterpret_cast(dynamic_bytes) == '\x00\x03\x02\x03\x01') for uint8_item in dynamic_bytes { - total += arc4_decode(uint8_item, algopy.UInt64) + total += arc4_decode(uint8_item, uint64) } assert(total == 6u, comment="Total should be of dynamic_bytes items") - dynamic_bytes2: algopy.arc4.DynamicBytes = arc4_encode(hex<"0304">, algopy.arc4.DynamicBytes) - assert(arc4_decode(dynamic_bytes2, algopy.Bytes) == '\x03\x04') - assert(reinterpret_cast(dynamic_bytes2) == '\x00\x02\x03\x04') + dynamic_bytes2: arc4.dynamic_bytes = arc4_encode(hex<"0304">, arc4.dynamic_bytes) + assert(extract<2, 0>(reinterpret_cast(dynamic_bytes2)) == '\x03\x04') + assert(reinterpret_cast(dynamic_bytes2) == '\x00\x02\x03\x04') for uint8_item in dynamic_bytes2 { - total += arc4_decode(uint8_item, algopy.UInt64) + total += arc4_decode(uint8_item, uint64) } - dynamic_bytes3: algopy.arc4.DynamicBytes = arc4_encode(arc4_decode(dynamic_bytes2, algopy.Bytes), algopy.arc4.DynamicBytes) - assert(arc4_decode(dynamic_bytes3, algopy.Bytes) == '\x03\x04') - assert(reinterpret_cast(dynamic_bytes3) == '\x00\x02\x03\x04') + dynamic_bytes3: arc4.dynamic_bytes = arc4_encode(extract<2, 0>(reinterpret_cast(dynamic_bytes2)), arc4.dynamic_bytes) + assert(extract<2, 0>(reinterpret_cast(dynamic_bytes3)) == '\x03\x04') + assert(reinterpret_cast(dynamic_bytes3) == '\x00\x02\x03\x04') for uint8_item in dynamic_bytes3 { - total += arc4_decode(uint8_item, algopy.UInt64) + total += arc4_decode(uint8_item, uint64) } assert(total == 20u, comment="Total should now include sum of dynamic_bytes3 items") - dynamic_bytes3.extend(arc4_encode(hex<"616263">, algopy.arc4.DynamicBytes)) - assert(reinterpret_cast(dynamic_bytes3) == '\x00\x05\x03\x04abc') - assert(arc4_decode(dynamic_bytes3, algopy.Bytes) == '\x03\x04abc') + dynamic_bytes3.extend(arc4_encode(hex<"616263">, arc4.dynamic_bytes)) + assert(reinterpret_cast(dynamic_bytes3) == '\x00\x05\x03\x04abc') + assert(extract<2, 0>(reinterpret_cast(dynamic_bytes3)) == '\x03\x04abc') return true } diff --git a/test_cases/arc4_types/out/dynamic_string_array.awst b/test_cases/arc4_types/out/dynamic_string_array.awst index 09c2224ac..db96b0386 100644 --- a/test_cases/arc4_types/out/dynamic_string_array.awst +++ b/test_cases/arc4_types/out/dynamic_string_array.awst @@ -1,13 +1,13 @@ contract Arc4DynamicStringArrayContract { - abimethod xyz(): algopy.arc4.DynamicArray[algopy.arc4.String] + abimethod xyz(): arc4.dynamic_array { - return new algopy.arc4.DynamicArray[algopy.arc4.String](arc4_encode('X', algopy.arc4.String), arc4_encode('Y', algopy.arc4.String), arc4_encode('Z', algopy.arc4.String)) + return new arc4.dynamic_array(arc4_encode('X', arc4.string), arc4_encode('Y', arc4.string), arc4_encode('Z', arc4.string)) } - abimethod xyz_raw(): algopy.arc4.DynamicArray[algopy.arc4.String] + abimethod xyz_raw(): arc4.dynamic_array { - raw: algopy.arc4.DynamicArray[algopy.arc4.DynamicArray[algopy.arc4.Byte]] = new algopy.arc4.DynamicArray[algopy.arc4.DynamicArray[algopy.arc4.Byte]](new algopy.arc4.DynamicArray[algopy.arc4.Byte](88arc4u8), new algopy.arc4.DynamicArray[algopy.arc4.Byte](89arc4u8), new algopy.arc4.DynamicArray[algopy.arc4.Byte](90arc4u8)) - return reinterpret_cast(reinterpret_cast(raw)) + raw: arc4.dynamic_array> = new arc4.dynamic_array>(new arc4.dynamic_array(88arc4u8), new arc4.dynamic_array(89arc4u8), new arc4.dynamic_array(90arc4u8)) + return reinterpret_cast>(reinterpret_cast(raw)) } } \ No newline at end of file diff --git a/test_cases/arc4_types/out/mutable_params.awst b/test_cases/arc4_types/out/mutable_params.awst index e6643b0df..9de1dd1b7 100644 --- a/test_cases/arc4_types/out/mutable_params.awst +++ b/test_cases/arc4_types/out/mutable_params.awst @@ -1,12 +1,12 @@ struct TestStruct { - b_val: algopy.arc4.Bool - u_val: algopy.arc4.UInt8 - s_val_1: algopy.arc4.String - s_val_2: algopy.arc4.String + b_val: arc4.bool + u_val: arc4.uint8 + s_val_1: arc4.string + s_val_2: arc4.string } struct StructWithArray { - test_array: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] + test_array: arc4.static_array } contract Arc4MutableParamsContract @@ -22,53 +22,53 @@ contract Arc4MutableParamsContract return true } - subroutine mutating_copies(): None + subroutine mutating_copies(): void { - my_array: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] = new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]](1arc4u8, 2arc4u8, 3arc4u8, 4arc4u8) - my_struct: test_cases.arc4_types.mutable_params.TestStruct = new test_cases.arc4_types.mutable_params.TestStruct(b_val=arc4_encode(true, algopy.arc4.Bool), u_val=50arc4u8, s_val_1=arc4_encode('Happy', algopy.arc4.String), s_val_2=arc4_encode('Days', algopy.arc4.String)) - my_array_copy: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] = my_array.copy() - my_struct_copy: test_cases.arc4_types.mutable_params.TestStruct = my_struct.copy() - my_array[2u]: algopy.arc4.UInt8 = 5arc4u8 - assert(reinterpret_cast(my_array_copy[2u]) == reinterpret_cast(3arc4u8), comment="my_array_copy should be unchanged") - assert(reinterpret_cast(my_array[2u]) == reinterpret_cast(5arc4u8), comment="my_array should be mutated") - (t, f): tuple[bool, bool] = this::other_routine(my_array, my_struct) + my_array: arc4.static_array = new arc4.static_array(1arc4u8, 2arc4u8, 3arc4u8, 4arc4u8) + my_struct: arc4.struct = new arc4.struct(b_val=arc4_encode(true, arc4.bool), u_val=50arc4u8, s_val_1=arc4_encode('Happy', arc4.string), s_val_2=arc4_encode('Days', arc4.string)) + my_array_copy: arc4.static_array = my_array.copy() + my_struct_copy: arc4.struct = my_struct.copy() + my_array[2u]: arc4.uint8 = 5arc4u8 + assert(reinterpret_cast(my_array_copy[2u]) == reinterpret_cast(3arc4u8), comment="my_array_copy should be unchanged") + assert(reinterpret_cast(my_array[2u]) == reinterpret_cast(5arc4u8), comment="my_array should be mutated") + (t, f): tuple = this::other_routine(my_array, my_struct) assert(t) assert(!(f)) - assert(reinterpret_cast(my_array[1u]) == reinterpret_cast(5arc4u8), comment="my_array has been mutated by the subroutine") - assert(reinterpret_cast(my_struct.s_val_1) == reinterpret_cast(arc4_encode('AARRGH!', algopy.arc4.String)), comment="my_struct has been mutated by the subroutine") + assert(reinterpret_cast(my_array[1u]) == reinterpret_cast(5arc4u8), comment="my_array has been mutated by the subroutine") + assert(reinterpret_cast(my_struct.s_val_1) == reinterpret_cast(arc4_encode('AARRGH!', arc4.string)), comment="my_struct has been mutated by the subroutine") this::other_routine(my_array_copy.copy(), my_struct_copy.copy()) - assert(reinterpret_cast(my_array_copy[1u]) == reinterpret_cast(2arc4u8), comment="my_array_copy should not be mutated by the subroutine") - assert(reinterpret_cast(my_struct_copy.s_val_1) == reinterpret_cast(arc4_encode('Happy', algopy.arc4.String)), comment="my_struct_copy should not be mutated by the subroutine") - my_array_copy_2: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] = my_array_copy.copy() - my_array_copy_2: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] = this::other_routine_2(my_array_copy_2) - assert(reinterpret_cast(my_array_copy_2[0u]) == reinterpret_cast(1arc4u8), comment="my_array_copy_2 should have original value") + assert(reinterpret_cast(my_array_copy[1u]) == reinterpret_cast(2arc4u8), comment="my_array_copy should not be mutated by the subroutine") + assert(reinterpret_cast(my_struct_copy.s_val_1) == reinterpret_cast(arc4_encode('Happy', arc4.string)), comment="my_struct_copy should not be mutated by the subroutine") + my_array_copy_2: arc4.static_array = my_array_copy.copy() + my_array_copy_2: arc4.static_array = this::other_routine_2(my_array_copy_2) + assert(reinterpret_cast(my_array_copy_2[0u]) == reinterpret_cast(1arc4u8), comment="my_array_copy_2 should have original value") this::other_routine_2(my_array_copy_2) - assert(reinterpret_cast(my_array_copy_2[0u]) == reinterpret_cast(10arc4u8), comment="my_array_copy_2 should have mutated value") - nested: test_cases.arc4_types.mutable_params.StructWithArray = new test_cases.arc4_types.mutable_params.StructWithArray(test_array=my_array.copy()) + assert(reinterpret_cast(my_array_copy_2[0u]) == reinterpret_cast(10arc4u8), comment="my_array_copy_2 should have mutated value") + nested: arc4.struct> = new arc4.struct>(test_array=my_array.copy()) this::other_routine_2(nested.test_array.copy()) } - subroutine other_routine(array: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]], struct: test_cases.arc4_types.mutable_params.TestStruct): tuple[bool, bool] + subroutine other_routine(array: arc4.static_array, struct: arc4.struct): tuple { - array[1u]: algopy.arc4.UInt8 = 5arc4u8 - struct.s_val_1: algopy.arc4.String = arc4_encode('AARRGH!', algopy.arc4.String) + array[1u]: arc4.uint8 = 5arc4u8 + struct.s_val_1: arc4.string = arc4_encode('AARRGH!', arc4.string) return (true, false) } - subroutine other_routine_2(array: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]]): algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] + subroutine other_routine_2(array: arc4.static_array): arc4.static_array { - copy: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] = array.copy() - array[0u]: algopy.arc4.UInt8 = 10arc4u8 + copy: arc4.static_array = array.copy() + array[0u]: arc4.uint8 = 10arc4u8 return copy } - subroutine other_routine_3(arrays: tuple[algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]], algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]], algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]]]): None + subroutine other_routine_3(arrays: tuple,arc4.static_array,arc4.static_array>): void { for array in arrays { - array[0u]: algopy.arc4.UInt8 = 99arc4u8 + array[0u]: arc4.uint8 = 99arc4u8 } - arrays[0][0u]: algopy.arc4.UInt8 = 99arc4u8 - arrays[1][0u]: algopy.arc4.UInt8 = 99arc4u8 - arrays[2][0u]: algopy.arc4.UInt8 = 99arc4u8 + arrays[0][0u]: arc4.uint8 = 99arc4u8 + arrays[1][0u]: arc4.uint8 = 99arc4u8 + arrays[2][0u]: arc4.uint8 = 99arc4u8 } } \ No newline at end of file diff --git a/test_cases/arc4_types/out/mutation.awst b/test_cases/arc4_types/out/mutation.awst index 2d0edfc77..f8be1825c 100644 --- a/test_cases/arc4_types/out/mutation.awst +++ b/test_cases/arc4_types/out/mutation.awst @@ -1,12 +1,12 @@ struct TestStruct { - b_val: algopy.arc4.Bool - u_val: algopy.arc4.UInt8 - s_val_1: algopy.arc4.String - s_val_2: algopy.arc4.String + b_val: arc4.bool + u_val: arc4.uint8 + s_val_1: arc4.string + s_val_2: arc4.string } struct StructWithArray { - d_array: algopy.arc4.DynamicArray[algopy.arc4.String] + d_array: arc4.dynamic_array } contract Arc4MutationContract @@ -29,125 +29,125 @@ contract Arc4MutationContract return true } - subroutine check_copy_required(): None + subroutine check_copy_required(): void { - d_array: algopy.arc4.DynamicArray[algopy.arc4.String] = new algopy.arc4.DynamicArray[algopy.arc4.String](arc4_encode('Test', algopy.arc4.String)) - nested_in_array: algopy.arc4.DynamicArray[algopy.arc4.DynamicArray[algopy.arc4.String]] = new algopy.arc4.DynamicArray[algopy.arc4.DynamicArray[algopy.arc4.String]](d_array.copy()) - nested_in_struct: test_cases.arc4_types.mutation.StructWithArray = new test_cases.arc4_types.mutation.StructWithArray(d_array=nested_in_array[0u].copy()) - assert(reinterpret_cast(d_array) == reinterpret_cast(nested_in_struct.d_array)) + d_array: arc4.dynamic_array = new arc4.dynamic_array(arc4_encode('Test', arc4.string)) + nested_in_array: arc4.dynamic_array> = new arc4.dynamic_array>(d_array.copy()) + nested_in_struct: arc4.struct> = new arc4.struct>(d_array=nested_in_array[0u].copy()) + assert(reinterpret_cast(d_array) == reinterpret_cast(nested_in_struct.d_array)) } - subroutine array_concat(): None + subroutine array_concat(): void { - uint8_array: algopy.arc4.DynamicArray[algopy.arc4.UInt8] = new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8) - array_concat_tuple: algopy.arc4.DynamicArray[algopy.arc4.UInt8] = uint8_array + (3arc4u8, 4arc4u8) - assert(reinterpret_cast(array_concat_tuple) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8, 3arc4u8, 4arc4u8))) + uint8_array: arc4.dynamic_array = new arc4.dynamic_array(1arc4u8, 2arc4u8) + array_concat_tuple: arc4.dynamic_array = uint8_array + (3arc4u8, 4arc4u8) + assert(reinterpret_cast(array_concat_tuple) == reinterpret_cast(new arc4.dynamic_array(1arc4u8, 2arc4u8, 3arc4u8, 4arc4u8))) array_concat_tuple.extend((5arc4u8)) - assert(reinterpret_cast(array_concat_tuple) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8, 3arc4u8, 4arc4u8, 5arc4u8))) - hello_world: algopy.arc4.DynamicArray[algopy.arc4.String] = new algopy.arc4.DynamicArray[algopy.arc4.String](arc4_encode('Hello', algopy.arc4.String), arc4_encode('World', algopy.arc4.String)) - hello_world_concat: algopy.arc4.DynamicArray[algopy.arc4.String] = new algopy.arc4.DynamicArray[algopy.arc4.String](arc4_encode('Hello', algopy.arc4.String)) + new algopy.arc4.DynamicArray[algopy.arc4.String](arc4_encode('World', algopy.arc4.String)) - assert(reinterpret_cast(hello_world) == reinterpret_cast(hello_world_concat)) + assert(reinterpret_cast(array_concat_tuple) == reinterpret_cast(new arc4.dynamic_array(1arc4u8, 2arc4u8, 3arc4u8, 4arc4u8, 5arc4u8))) + hello_world: arc4.dynamic_array = new arc4.dynamic_array(arc4_encode('Hello', arc4.string), arc4_encode('World', arc4.string)) + hello_world_concat: arc4.dynamic_array = new arc4.dynamic_array(arc4_encode('Hello', arc4.string)) + new arc4.dynamic_array(arc4_encode('World', arc4.string)) + assert(reinterpret_cast(hello_world) == reinterpret_cast(hello_world_concat)) } - subroutine array_of_array_dynamic(): None + subroutine array_of_array_dynamic(): void { - array_of_array: algopy.arc4.DynamicArray[algopy.arc4.DynamicArray[algopy.arc4.UInt8]] = new algopy.arc4.DynamicArray[algopy.arc4.DynamicArray[algopy.arc4.UInt8]]() - assert(reinterpret_cast(array_of_array) == hex<"0000">) - array_of_array.extend((new algopy.arc4.DynamicArray[algopy.arc4.UInt8](10arc4u8))) - assert(reinterpret_cast(array_of_array) == hex<"0001000200010A">) - array_of_array.extend((new algopy.arc4.DynamicArray[algopy.arc4.UInt8](16arc4u8))) - assert(reinterpret_cast(array_of_array) == hex<"00020004000700010A000110">) + array_of_array: arc4.dynamic_array> = new arc4.dynamic_array>() + assert(reinterpret_cast(array_of_array) == hex<"0000">) + array_of_array.extend((new arc4.dynamic_array(10arc4u8))) + assert(reinterpret_cast(array_of_array) == hex<"0001000200010A">) + array_of_array.extend((new arc4.dynamic_array(16arc4u8))) + assert(reinterpret_cast(array_of_array) == hex<"00020004000700010A000110">) array_of_array[0u].extend((255arc4u8)) - assert(reinterpret_cast(array_of_array) == hex<"00020004000800020AFF000110">) - array_of_array[0u][1u]: algopy.arc4.UInt8 = 0arc4u8 - assert(reinterpret_cast(array_of_array) == hex<"00020004000800020A00000110">) + assert(reinterpret_cast(array_of_array) == hex<"00020004000800020AFF000110">) + array_of_array[0u][1u]: arc4.uint8 = 0arc4u8 + assert(reinterpret_cast(array_of_array) == hex<"00020004000800020A00000110">) } - subroutine array_of_array_static(): None + subroutine array_of_array_static(): void { - array_of_array: algopy.arc4.StaticArray[algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[2]], typing.Literal[2]] = new algopy.arc4.StaticArray[algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[2]], typing.Literal[2]](new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[2]](10arc4u8, 9arc4u8), new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[2]](64arc4u8, 128arc4u8)) - assert(reinterpret_cast(array_of_array) == hex<"0A094080">) - array_of_array[0u]: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[2]] = new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[2]](255arc4u8, 254arc4u8) - assert(reinterpret_cast(array_of_array) == hex<"FFFE4080">) - array_of_array[1u][0u]: algopy.arc4.UInt8 = 1arc4u8 - assert(reinterpret_cast(array_of_array) == hex<"FFFE0180">) + array_of_array: arc4.static_array, 2> = new arc4.static_array, 2>(new arc4.static_array(10arc4u8, 9arc4u8), new arc4.static_array(64arc4u8, 128arc4u8)) + assert(reinterpret_cast(array_of_array) == hex<"0A094080">) + array_of_array[0u]: arc4.static_array = new arc4.static_array(255arc4u8, 254arc4u8) + assert(reinterpret_cast(array_of_array) == hex<"FFFE4080">) + array_of_array[1u][0u]: arc4.uint8 = 1arc4u8 + assert(reinterpret_cast(array_of_array) == hex<"FFFE0180">) } - subroutine index_assign(): None + subroutine index_assign(): void { - dynamic_uint8_array: algopy.arc4.DynamicArray[algopy.arc4.UInt8] = new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8) - dynamic_uint8_array[0u]: algopy.arc4.UInt8 = 255arc4u8 - assert(reinterpret_cast(dynamic_uint8_array) == hex<"0002FF02">) - static_uint8_array: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[2]] = new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[2]](1arc4u8, 2arc4u8) - static_uint8_array[1u]: algopy.arc4.UInt8 = 255arc4u8 - assert(reinterpret_cast(static_uint8_array) == hex<"01FF">) - dynamic_bool_array: algopy.arc4.DynamicArray[algopy.arc4.Bool] = new algopy.arc4.DynamicArray[algopy.arc4.Bool](arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool)) - dynamic_bool_array[0u]: algopy.arc4.Bool = arc4_encode(false, algopy.arc4.Bool) - assert(reinterpret_cast(dynamic_bool_array) == hex<"000200">) - static_bool_array: algopy.arc4.StaticArray[algopy.arc4.Bool, typing.Literal[2]] = new algopy.arc4.StaticArray[algopy.arc4.Bool, typing.Literal[2]](arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool)) - static_bool_array[1u]: algopy.arc4.Bool = arc4_encode(false, algopy.arc4.Bool) - assert(reinterpret_cast(static_bool_array) == hex<"80">) + dynamic_uint8_array: arc4.dynamic_array = new arc4.dynamic_array(1arc4u8, 2arc4u8) + dynamic_uint8_array[0u]: arc4.uint8 = 255arc4u8 + assert(reinterpret_cast(dynamic_uint8_array) == hex<"0002FF02">) + static_uint8_array: arc4.static_array = new arc4.static_array(1arc4u8, 2arc4u8) + static_uint8_array[1u]: arc4.uint8 = 255arc4u8 + assert(reinterpret_cast(static_uint8_array) == hex<"01FF">) + dynamic_bool_array: arc4.dynamic_array = new arc4.dynamic_array(arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool)) + dynamic_bool_array[0u]: arc4.bool = arc4_encode(false, arc4.bool) + assert(reinterpret_cast(dynamic_bool_array) == hex<"000200">) + static_bool_array: arc4.static_array = new arc4.static_array(arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool)) + static_bool_array[1u]: arc4.bool = arc4_encode(false, arc4.bool) + assert(reinterpret_cast(static_bool_array) == hex<"80">) } - subroutine struct_assign(): None + subroutine struct_assign(): void { - test_struct: test_cases.arc4_types.mutation.TestStruct = new test_cases.arc4_types.mutation.TestStruct(b_val=arc4_encode(true, algopy.arc4.Bool), u_val=50arc4u8, s_val_1=arc4_encode('Happy', algopy.arc4.String), s_val_2=arc4_encode('Days', algopy.arc4.String)) - test_struct.b_val: algopy.arc4.Bool = arc4_encode(false, algopy.arc4.Bool) - test_struct.u_val: algopy.arc4.UInt8 = 12arc4u8 - assert(reinterpret_cast(test_struct) == reinterpret_cast(new test_cases.arc4_types.mutation.TestStruct(b_val=arc4_encode(false, algopy.arc4.Bool), u_val=12arc4u8, s_val_1=arc4_encode('Happy', algopy.arc4.String), s_val_2=arc4_encode('Days', algopy.arc4.String)))) - test_struct.s_val_1: algopy.arc4.String = arc4_encode('Hmmmm', algopy.arc4.String) - test_struct.s_val_2: algopy.arc4.String = arc4_encode('Oh well', algopy.arc4.String) - assert(reinterpret_cast(test_struct) == reinterpret_cast(new test_cases.arc4_types.mutation.TestStruct(b_val=arc4_encode(false, algopy.arc4.Bool), u_val=12arc4u8, s_val_1=arc4_encode('Hmmmm', algopy.arc4.String), s_val_2=arc4_encode('Oh well', algopy.arc4.String)))) + test_struct: arc4.struct = new arc4.struct(b_val=arc4_encode(true, arc4.bool), u_val=50arc4u8, s_val_1=arc4_encode('Happy', arc4.string), s_val_2=arc4_encode('Days', arc4.string)) + test_struct.b_val: arc4.bool = arc4_encode(false, arc4.bool) + test_struct.u_val: arc4.uint8 = 12arc4u8 + assert(reinterpret_cast(test_struct) == reinterpret_cast(new arc4.struct(b_val=arc4_encode(false, arc4.bool), u_val=12arc4u8, s_val_1=arc4_encode('Happy', arc4.string), s_val_2=arc4_encode('Days', arc4.string)))) + test_struct.s_val_1: arc4.string = arc4_encode('Hmmmm', arc4.string) + test_struct.s_val_2: arc4.string = arc4_encode('Oh well', arc4.string) + assert(reinterpret_cast(test_struct) == reinterpret_cast(new arc4.struct(b_val=arc4_encode(false, arc4.bool), u_val=12arc4u8, s_val_1=arc4_encode('Hmmmm', arc4.string), s_val_2=arc4_encode('Oh well', arc4.string)))) } - subroutine dynamic_array_fixed_size(): None + subroutine dynamic_array_fixed_size(): void { - dynamic_uint8_array: algopy.arc4.DynamicArray[algopy.arc4.UInt8] = new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8) + dynamic_uint8_array: arc4.dynamic_array = new arc4.dynamic_array(1arc4u8, 2arc4u8) dynamic_uint8_array.extend((50arc4u8)) - assert(reinterpret_cast(dynamic_uint8_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8, 50arc4u8))) + assert(reinterpret_cast(dynamic_uint8_array) == reinterpret_cast(new arc4.dynamic_array(1arc4u8, 2arc4u8, 50arc4u8))) dynamic_uint8_array.extend(dynamic_uint8_array) - assert(reinterpret_cast(dynamic_uint8_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8, 50arc4u8, 1arc4u8, 2arc4u8, 50arc4u8))) + assert(reinterpret_cast(dynamic_uint8_array) == reinterpret_cast(new arc4.dynamic_array(1arc4u8, 2arc4u8, 50arc4u8, 1arc4u8, 2arc4u8, 50arc4u8))) dynamic_uint8_array.extend((4arc4u8, 90arc4u8)) - assert(reinterpret_cast(dynamic_uint8_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8, 50arc4u8, 1arc4u8, 2arc4u8, 50arc4u8, 4arc4u8, 90arc4u8))) - popped: algopy.arc4.UInt8 = dynamic_uint8_array.pop() - assert(reinterpret_cast(popped) == reinterpret_cast(90arc4u8)) - assert(reinterpret_cast(dynamic_uint8_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.UInt8](1arc4u8, 2arc4u8, 50arc4u8, 1arc4u8, 2arc4u8, 50arc4u8, 4arc4u8))) + assert(reinterpret_cast(dynamic_uint8_array) == reinterpret_cast(new arc4.dynamic_array(1arc4u8, 2arc4u8, 50arc4u8, 1arc4u8, 2arc4u8, 50arc4u8, 4arc4u8, 90arc4u8))) + popped: arc4.uint8 = dynamic_uint8_array.pop() + assert(reinterpret_cast(popped) == reinterpret_cast(90arc4u8)) + assert(reinterpret_cast(dynamic_uint8_array) == reinterpret_cast(new arc4.dynamic_array(1arc4u8, 2arc4u8, 50arc4u8, 1arc4u8, 2arc4u8, 50arc4u8, 4arc4u8))) } - subroutine dynamic_array_bool(): None + subroutine dynamic_array_bool(): void { - dynamic_bool_array: algopy.arc4.DynamicArray[algopy.arc4.Bool] = new algopy.arc4.DynamicArray[algopy.arc4.Bool](arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool)) - assert(reinterpret_cast(dynamic_bool_array) == hex<"000280">) - dynamic_bool_array.extend((arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool))) - assert(reinterpret_cast(dynamic_bool_array) == hex<"0004A0">) - assert(reinterpret_cast(dynamic_bool_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.Bool](arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool)))) + dynamic_bool_array: arc4.dynamic_array = new arc4.dynamic_array(arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool)) + assert(reinterpret_cast(dynamic_bool_array) == hex<"000280">) + dynamic_bool_array.extend((arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool))) + assert(reinterpret_cast(dynamic_bool_array) == hex<"0004A0">) + assert(reinterpret_cast(dynamic_bool_array) == reinterpret_cast(new arc4.dynamic_array(arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool)))) dynamic_bool_array.extend(dynamic_bool_array) - assert(reinterpret_cast(dynamic_bool_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.Bool](arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool)))) - dynamic_bool_array.extend((arc4_encode(true, algopy.arc4.Bool))) - assert(reinterpret_cast(dynamic_bool_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.Bool](arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool)))) - assert(reinterpret_cast(dynamic_bool_array.pop()) == reinterpret_cast(arc4_encode(true, algopy.arc4.Bool))) - assert(reinterpret_cast(dynamic_bool_array.pop()) == reinterpret_cast(arc4_encode(false, algopy.arc4.Bool))) - assert(reinterpret_cast(dynamic_bool_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.Bool](arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool)))) + assert(reinterpret_cast(dynamic_bool_array) == reinterpret_cast(new arc4.dynamic_array(arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool)))) + dynamic_bool_array.extend((arc4_encode(true, arc4.bool))) + assert(reinterpret_cast(dynamic_bool_array) == reinterpret_cast(new arc4.dynamic_array(arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool)))) + assert(reinterpret_cast(dynamic_bool_array.pop()) == reinterpret_cast(arc4_encode(true, arc4.bool))) + assert(reinterpret_cast(dynamic_bool_array.pop()) == reinterpret_cast(arc4_encode(false, arc4.bool))) + assert(reinterpret_cast(dynamic_bool_array) == reinterpret_cast(new arc4.dynamic_array(arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool)))) } - subroutine dynamic_array_string(): None + subroutine dynamic_array_string(): void { - hello: algopy.arc4.String = arc4_encode('Hello', algopy.arc4.String) - world: algopy.arc4.String = arc4_encode('World', algopy.arc4.String) - foo: algopy.arc4.String = arc4_encode('Foo', algopy.arc4.String) - bar: algopy.arc4.String = arc4_encode('Bar', algopy.arc4.String) - dynamic_string_array: algopy.arc4.DynamicArray[algopy.arc4.String] = new algopy.arc4.DynamicArray[algopy.arc4.String](hello, world) - assert(reinterpret_cast(dynamic_string_array) == '\x00\x02\x00\x04\x00\x0b\x00\x05Hello\x00\x05World') + hello: arc4.string = arc4_encode('Hello', arc4.string) + world: arc4.string = arc4_encode('World', arc4.string) + foo: arc4.string = arc4_encode('Foo', arc4.string) + bar: arc4.string = arc4_encode('Bar', arc4.string) + dynamic_string_array: arc4.dynamic_array = new arc4.dynamic_array(hello, world) + assert(reinterpret_cast(dynamic_string_array) == '\x00\x02\x00\x04\x00\x0b\x00\x05Hello\x00\x05World') dynamic_string_array.extend((foo, bar)) - assert(reinterpret_cast(dynamic_string_array) == '\x00\x04\x00\x08\x00\x0f\x00\x16\x00\x1b\x00\x05Hello\x00\x05World\x00\x03Foo\x00\x03Bar') + assert(reinterpret_cast(dynamic_string_array) == '\x00\x04\x00\x08\x00\x0f\x00\x16\x00\x1b\x00\x05Hello\x00\x05World\x00\x03Foo\x00\x03Bar') dynamic_string_array.extend(dynamic_string_array) - assert(reinterpret_cast(dynamic_string_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.String](hello, world, foo, bar, hello, world, foo, bar))) - dynamic_string_array: algopy.arc4.DynamicArray[algopy.arc4.String] = new algopy.arc4.DynamicArray[algopy.arc4.String](hello, world, foo, bar, hello, world, foo, bar) - dynamic_string_array[3u]: algopy.arc4.String = hello - dynamic_string_array[5u]: algopy.arc4.String = hello - assert(reinterpret_cast(dynamic_string_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.String](hello, world, foo, hello, hello, hello, foo, bar))) - assert(reinterpret_cast(dynamic_string_array.pop()) == reinterpret_cast(bar)) - assert(reinterpret_cast(dynamic_string_array.pop()) == reinterpret_cast(foo)) - assert(reinterpret_cast(dynamic_string_array) == reinterpret_cast(new algopy.arc4.DynamicArray[algopy.arc4.String](hello, world, foo, hello, hello, hello))) + assert(reinterpret_cast(dynamic_string_array) == reinterpret_cast(new arc4.dynamic_array(hello, world, foo, bar, hello, world, foo, bar))) + dynamic_string_array: arc4.dynamic_array = new arc4.dynamic_array(hello, world, foo, bar, hello, world, foo, bar) + dynamic_string_array[3u]: arc4.string = hello + dynamic_string_array[5u]: arc4.string = hello + assert(reinterpret_cast(dynamic_string_array) == reinterpret_cast(new arc4.dynamic_array(hello, world, foo, hello, hello, hello, foo, bar))) + assert(reinterpret_cast(dynamic_string_array.pop()) == reinterpret_cast(bar)) + assert(reinterpret_cast(dynamic_string_array.pop()) == reinterpret_cast(foo)) + assert(reinterpret_cast(dynamic_string_array) == reinterpret_cast(new arc4.dynamic_array(hello, world, foo, hello, hello, hello))) } } \ No newline at end of file diff --git a/test_cases/arc4_types/out/numeric.awst b/test_cases/arc4_types/out/numeric.awst index 9793bbcd3..2d12589f5 100644 --- a/test_cases/arc4_types/out/numeric.awst +++ b/test_cases/arc4_types/out/numeric.awst @@ -4,54 +4,54 @@ contract Arc4NumericTypesContract { approval_program(): bool { - uint8: algopy.UInt64 = 255u - int8_encoded: algopy.arc4.UInt8 = arc4_encode(uint8, algopy.arc4.UInt8) - int8_decoded: algopy.UInt64 = arc4_decode(int8_encoded, algopy.UInt64) + uint8: uint64 = 255u + int8_encoded: arc4.uint8 = arc4_encode(uint8, arc4.uint8) + int8_decoded: uint64 = arc4_decode(int8_encoded, uint64) assert(uint8 == int8_decoded) - test_bytes: algopy.Bytes = hex<"7FFFFFFFFFFFFFFF00"> - assert(arc4_decode(reinterpret_cast(test_bytes[:1]), algopy.UInt64) == 127u) - assert(arc4_decode(reinterpret_cast(test_bytes[:3]), algopy.UInt64) == 8388607u) - assert(arc4_decode(reinterpret_cast(test_bytes[:2]), algopy.UInt64) == 32767u) - assert(arc4_decode(reinterpret_cast(test_bytes[:4]), algopy.UInt64) == 2147483647u) - assert(arc4_decode(reinterpret_cast(test_bytes[:8]), algopy.UInt64) == 9223372036854775807u) - decimals: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 145.6853943940arc4u64x10 - assert(reinterpret_cast(decimals) == itob(1456853943940u)) - decimals_from_truncated_str: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 145.0000000000arc4u64x10 - assert(reinterpret_cast(decimals_from_truncated_str) == itob(1450000000000u)) - thousand: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 1000.0000000000arc4u64x10 - assert(len(reinterpret_cast(thousand)) == 8u) - assert(reinterpret_cast(thousand) == itob(10000000000000u)) - one_decimal: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 1.0000000000arc4u64x10 - assert(reinterpret_cast(one_decimal) == itob(10000000000u)) - zero_decimal: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 0E-10arc4u64x10 - assert(reinterpret_cast(zero_decimal) == itob(0u)) - small_decimal: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 1.00E-8arc4u64x10 - assert(reinterpret_cast(small_decimal) == itob(100u)) - smaller_decimal: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 1.0E-9arc4u64x10 - assert(reinterpret_cast(smaller_decimal) == itob(10u)) - smallest_decimal: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 1E-10arc4u64x10 - assert(reinterpret_cast(smallest_decimal) == itob(1u)) - sixty_four_decimal: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[10]] = 1844674407.3709551615arc4u64x10 - assert(reinterpret_cast(sixty_four_decimal) == itob(18446744073709551615u)) - really_big_int: algopy.arc4.UInt512 = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095arc4n512 - assert(reinterpret_cast(really_big_int) == reinterpret_cast(reinterpret_cast(reinterpret_cast(really_big_int)))) - really_big_decimal: algopy.arc4.BigUFixedNxM[typing.Literal[512], typing.Literal[2]] = reinterpret_cast(reinterpret_cast(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095n)) - biguint: algopy.BigUInt = 1n - arc4_biguint_const: algopy.arc4.UInt128 = 1arc4n128 - arc4_biguint_dynamic: algopy.arc4.UInt128 = arc4_encode(biguint b+ 1n, algopy.arc4.UInt128) - assert(biguint == arc4_decode(arc4_biguint_const, algopy.BigUInt)) - assert(len(reinterpret_cast(arc4_biguint_dynamic)) == 16u) - assert(len(reinterpret_cast(really_big_decimal)) == 64u) + test_bytes: bytes = hex<"7FFFFFFFFFFFFFFF00"> + assert(arc4_decode(reinterpret_cast(test_bytes[:1]), uint64) == 127u) + assert(arc4_decode(reinterpret_cast(test_bytes[:3]), uint64) == 8388607u) + assert(arc4_decode(reinterpret_cast(test_bytes[:2]), uint64) == 32767u) + assert(arc4_decode(reinterpret_cast(test_bytes[:4]), uint64) == 2147483647u) + assert(arc4_decode(reinterpret_cast(test_bytes[:8]), uint64) == 9223372036854775807u) + decimals: arc4.ufixed64x10 = 145.6853943940arc4u64x10 + assert(reinterpret_cast(decimals) == itob(1456853943940u)) + decimals_from_truncated_str: arc4.ufixed64x10 = 145.0000000000arc4u64x10 + assert(reinterpret_cast(decimals_from_truncated_str) == itob(1450000000000u)) + thousand: arc4.ufixed64x10 = 1000.0000000000arc4u64x10 + assert(len(reinterpret_cast(thousand)) == 8u) + assert(reinterpret_cast(thousand) == itob(10000000000000u)) + one_decimal: arc4.ufixed64x10 = 1.0000000000arc4u64x10 + assert(reinterpret_cast(one_decimal) == itob(10000000000u)) + zero_decimal: arc4.ufixed64x10 = 0E-10arc4u64x10 + assert(reinterpret_cast(zero_decimal) == itob(0u)) + small_decimal: arc4.ufixed64x10 = 1.00E-8arc4u64x10 + assert(reinterpret_cast(small_decimal) == itob(100u)) + smaller_decimal: arc4.ufixed64x10 = 1.0E-9arc4u64x10 + assert(reinterpret_cast(smaller_decimal) == itob(10u)) + smallest_decimal: arc4.ufixed64x10 = 1E-10arc4u64x10 + assert(reinterpret_cast(smallest_decimal) == itob(1u)) + sixty_four_decimal: arc4.ufixed64x10 = 1844674407.3709551615arc4u64x10 + assert(reinterpret_cast(sixty_four_decimal) == itob(18446744073709551615u)) + really_big_int: arc4.uint512 = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095arc4n512 + assert(reinterpret_cast(really_big_int) == reinterpret_cast(reinterpret_cast(reinterpret_cast(really_big_int)))) + really_big_decimal: arc4.ufixed512x2 = reinterpret_cast(reinterpret_cast(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095n)) + biguint: biguint = 1n + arc4_biguint_const: arc4.uint128 = 1arc4n128 + arc4_biguint_dynamic: arc4.uint128 = arc4_encode(biguint b+ 1n, arc4.uint128) + assert(biguint == arc4_decode(arc4_biguint_const, biguint)) + assert(len(reinterpret_cast(arc4_biguint_dynamic)) == 16u) + assert(len(reinterpret_cast(really_big_decimal)) == 64u) return true } clear_state_program(): bool { - assert(reinterpret_cast(reinterpret_cast(0E-10arc4u64x10)) == 0n) - assert(reinterpret_cast(reinterpret_cast(0.00000arc4n512x5)) == 0n) - assert(reinterpret_cast(0arc4u8) == reinterpret_cast(0arc4u8)) - assert(reinterpret_cast(0arc4u64) == reinterpret_cast(0arc4u64)) - assert(reinterpret_cast(0arc4n512) == reinterpret_cast(0arc4n512)) + assert(reinterpret_cast(reinterpret_cast(0E-10arc4u64x10)) == 0n) + assert(reinterpret_cast(reinterpret_cast(0.00000arc4n512x5)) == 0n) + assert(reinterpret_cast(0arc4u8) == reinterpret_cast(0arc4u8)) + assert(reinterpret_cast(0arc4u64) == reinterpret_cast(0arc4u64)) + assert(reinterpret_cast(0arc4n512) == reinterpret_cast(0arc4n512)) return true } } \ No newline at end of file diff --git a/test_cases/arc4_types/out/reference_types.awst b/test_cases/arc4_types/out/reference_types.awst index f198b07c9..570bb5696 100644 --- a/test_cases/arc4_types/out/reference_types.awst +++ b/test_cases/arc4_types/out/reference_types.awst @@ -2,12 +2,12 @@ contract Arc4RefTypesContract { approval_program(): bool { - sender_address: algopy.arc4.Address = reinterpret_cast(reinterpret_cast(txn())) - assert(reinterpret_cast(sender_address) == reinterpret_cast(txn())) - checked_address: algopy.arc4.Address = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=0, source=reinterpret_cast(txn())), 32u == len(SINGLE_EVAL(id=0, source=reinterpret_cast(txn())))))) - unchecked_address: algopy.arc4.Address = reinterpret_cast(reinterpret_cast(txn())) - assert(reinterpret_cast(sender_address) == reinterpret_cast(checked_address) and reinterpret_cast(checked_address) == reinterpret_cast(unchecked_address)) - assert(reinterpret_cast(global()) == reinterpret_cast(Address("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ"))) + sender_address: arc4.address = reinterpret_cast(reinterpret_cast(txn())) + assert(reinterpret_cast(sender_address) == reinterpret_cast(txn())) + checked_address: arc4.address = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=0, source=reinterpret_cast(txn())), 32u == len(SINGLE_EVAL(id=0, source=reinterpret_cast(txn())))))) + unchecked_address: arc4.address = reinterpret_cast(reinterpret_cast(txn())) + assert(reinterpret_cast(sender_address) == reinterpret_cast(checked_address) and reinterpret_cast(checked_address) == reinterpret_cast(unchecked_address)) + assert(reinterpret_cast(global()) == reinterpret_cast(Address("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ"))) return true } diff --git a/test_cases/arc4_types/out/string.awst b/test_cases/arc4_types/out/string.awst index 40bd7ebad..5f78049c7 100644 --- a/test_cases/arc4_types/out/string.awst +++ b/test_cases/arc4_types/out/string.awst @@ -4,24 +4,24 @@ contract Arc4StringTypesContract { approval_program(): bool { - some_bytes_as_string: algopy.arc4.String = arc4_encode(reinterpret_cast(hex<"48656C6C6F20576F726C6421">), algopy.arc4.String) - some_bytes_as_bytes_again: algopy.Bytes = reinterpret_cast(arc4_decode(some_bytes_as_string, algopy.String)) - assert(reinterpret_cast(some_bytes_as_string) != 'Hello World!', comment="Original bytes should not match encoded bytes") - assert(reinterpret_cast(some_bytes_as_string)[2:] == 'Hello World!', comment="Original bytes should match encoded if we strip the length header") + some_bytes_as_string: arc4.string = arc4_encode(reinterpret_cast(hex<"48656C6C6F20576F726C6421">), arc4.string) + some_bytes_as_bytes_again: bytes = reinterpret_cast(arc4_decode(some_bytes_as_string, string)) + assert(reinterpret_cast(some_bytes_as_string) != 'Hello World!', comment="Original bytes should not match encoded bytes") + assert(reinterpret_cast(some_bytes_as_string)[2:] == 'Hello World!', comment="Original bytes should match encoded if we strip the length header") assert(some_bytes_as_bytes_again == 'Hello World!') - hello: algopy.arc4.String = arc4_encode('Hello', algopy.arc4.String) - space: algopy.arc4.String = arc4_encode(' ', algopy.arc4.String) - world: algopy.arc4.String = arc4_encode('World!', algopy.arc4.String) - assert(reinterpret_cast(arc4_encode('Hello World!', algopy.arc4.String)) == reinterpret_cast(hello + space + world)) - thing: algopy.arc4.String = arc4_encode('hi', algopy.arc4.String) + hello: arc4.string = arc4_encode('Hello', arc4.string) + space: arc4.string = arc4_encode(' ', arc4.string) + world: arc4.string = arc4_encode('World!', arc4.string) + assert(reinterpret_cast(arc4_encode('Hello World!', arc4.string)) == reinterpret_cast(hello + space + world)) + thing: arc4.string = arc4_encode('hi', arc4.string) thing.extend(thing) - assert(reinterpret_cast(thing) == reinterpret_cast(arc4_encode('hihi', algopy.arc4.String))) - value: algopy.arc4.String = arc4_encode('a', algopy.arc4.String) + arc4_encode('b', algopy.arc4.String) + arc4_encode('cd', algopy.arc4.String) - value.extend(arc4_encode('e', algopy.arc4.String)) - value.extend(arc4_encode('f', algopy.arc4.String)) - value.extend(arc4_encode('g', algopy.arc4.String)) - assert(reinterpret_cast(arc4_encode('abcdefg', algopy.arc4.String)) == reinterpret_cast(value)) - assert(arc4_decode(arc4_encode('', algopy.arc4.String), algopy.String) == '') + assert(reinterpret_cast(thing) == reinterpret_cast(arc4_encode('hihi', arc4.string))) + value: arc4.string = arc4_encode('a', arc4.string) + arc4_encode('b', arc4.string) + arc4_encode('cd', arc4.string) + value.extend(arc4_encode('e', arc4.string)) + value.extend(arc4_encode('f', arc4.string)) + value.extend(arc4_encode('g', arc4.string)) + assert(reinterpret_cast(arc4_encode('abcdefg', arc4.string)) == reinterpret_cast(value)) + assert(arc4_decode(arc4_encode('', arc4.string), string) == '') return true } diff --git a/test_cases/arc4_types/out/structs.awst b/test_cases/arc4_types/out/structs.awst index 87ec5fd3a..11a6780e3 100644 --- a/test_cases/arc4_types/out/structs.awst +++ b/test_cases/arc4_types/out/structs.awst @@ -1,35 +1,35 @@ struct Vector { - x: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[9]] - y: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[9]] + x: arc4.ufixed64x9 + y: arc4.ufixed64x9 } struct Flags { - a: algopy.arc4.Bool - b: algopy.arc4.Bool - c: algopy.arc4.Bool - d: algopy.arc4.Bool + a: arc4.bool + b: arc4.bool + c: arc4.bool + d: arc4.bool } struct VectorFlags { - vector: test_cases.arc4_types.structs.Vector - flags: test_cases.arc4_types.structs.Flags + vector: arc4.struct + flags: arc4.struct } contract Arc4StructsTypeContract { approval_program(): bool { - coord_1: test_cases.arc4_types.structs.Vector = new test_cases.arc4_types.structs.Vector(x=35.382882839arc4u64x9, y=150.382884930arc4u64x9) - coord_2: test_cases.arc4_types.structs.Vector = new test_cases.arc4_types.structs.Vector(x=35.382882839arc4u64x9, y=150.382884930arc4u64x9) - coord_3: test_cases.arc4_types.structs.Vector = test_cases.arc4_types.structs::add(coord_1.copy(), coord_2.copy()) + coord_1: arc4.struct = new arc4.struct(x=35.382882839arc4u64x9, y=150.382884930arc4u64x9) + coord_2: arc4.struct = new arc4.struct(x=35.382882839arc4u64x9, y=150.382884930arc4u64x9) + coord_3: arc4.struct = test_cases.arc4_types.structs::add(coord_1.copy(), coord_2.copy()) for val in (coord_3.x, coord_3.y) { - log(reinterpret_cast(val)) + log(reinterpret_cast(val)) } - flags: test_cases.arc4_types.structs.Flags = new test_cases.arc4_types.structs.Flags(a=arc4_encode(true, algopy.arc4.Bool), b=arc4_encode(false, algopy.arc4.Bool), c=arc4_encode(true, algopy.arc4.Bool), d=arc4_encode(false, algopy.arc4.Bool)) + flags: arc4.struct = new arc4.struct(a=arc4_encode(true, arc4.bool), b=arc4_encode(false, arc4.bool), c=arc4_encode(true, arc4.bool), d=arc4_encode(false, arc4.bool)) test_cases.arc4_types.structs::check(flags.copy()) - log(reinterpret_cast(flags)) - assert(reinterpret_cast(reinterpret_cast(reinterpret_cast(coord_1))) == reinterpret_cast(coord_1)) - test_cases.arc4_types.structs::nested_decode(new test_cases.arc4_types.structs.VectorFlags(vector=coord_1.copy(), flags=flags.copy())) + log(reinterpret_cast(flags)) + assert(reinterpret_cast(reinterpret_cast>(reinterpret_cast(coord_1))) == reinterpret_cast(coord_1)) + test_cases.arc4_types.structs::nested_decode(new arc4.struct,flags:arc4.struct>(vector=coord_1.copy(), flags=flags.copy())) return true } @@ -39,12 +39,12 @@ contract Arc4StructsTypeContract } } -subroutine add(v1: test_cases.arc4_types.structs.Vector, v2: test_cases.arc4_types.structs.Vector): test_cases.arc4_types.structs.Vector +subroutine add(v1: arc4.struct, v2: arc4.struct): arc4.struct { - return new test_cases.arc4_types.structs.Vector(x=test_cases.arc4_types.structs::add_decimal(v1.x, v2.x), y=test_cases.arc4_types.structs::add_decimal(v1.y, v2.y)) + return new arc4.struct(x=test_cases.arc4_types.structs::add_decimal(v1.x, v2.x), y=test_cases.arc4_types.structs::add_decimal(v1.y, v2.y)) } -subroutine check(flags: test_cases.arc4_types.structs.Flags): None +subroutine check(flags: arc4.struct): void { assert(arc4_decode(flags.a, bool)) assert(!(arc4_decode(flags.b, bool))) @@ -52,13 +52,13 @@ subroutine check(flags: test_cases.arc4_types.structs.Flags): None assert(!(arc4_decode(flags.d, bool))) } -subroutine nested_decode(vector_flags: test_cases.arc4_types.structs.VectorFlags): None +subroutine nested_decode(vector_flags: arc4.struct,flags:arc4.struct>): void { - assert(reinterpret_cast(vector_flags.vector.x) == itob(35382882839u)) + assert(reinterpret_cast(vector_flags.vector.x) == itob(35382882839u)) assert(arc4_decode(vector_flags.flags.c, bool)) } -subroutine add_decimal(x: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[9]], y: algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[9]]): algopy.arc4.UFixedNxM[typing.Literal[64], typing.Literal[9]] +subroutine add_decimal(x: arc4.ufixed64x9, y: arc4.ufixed64x9): arc4.ufixed64x9 { - return reinterpret_cast(itob(btoi(reinterpret_cast(x)) + btoi(reinterpret_cast(y)))) + return reinterpret_cast(itob(btoi(reinterpret_cast(x)) + btoi(reinterpret_cast(y)))) } \ No newline at end of file diff --git a/test_cases/arc4_types/out/structs2.awst b/test_cases/arc4_types/out/structs2.awst index ee8ed5f69..61089b9ce 100644 --- a/test_cases/arc4_types/out/structs2.awst +++ b/test_cases/arc4_types/out/structs2.awst @@ -2,8 +2,8 @@ contract Arc4StructsFromAnotherModule { approval_program(): bool { - flags: test_cases.arc4_types.structs.Flags = new test_cases.arc4_types.structs.Flags(a=arc4_encode(true, algopy.arc4.Bool), b=arc4_encode(false, algopy.arc4.Bool), c=arc4_encode(true, algopy.arc4.Bool), d=arc4_encode(false, algopy.arc4.Bool)) - log(reinterpret_cast(flags)) + flags: arc4.struct = new arc4.struct(a=arc4_encode(true, arc4.bool), b=arc4_encode(false, arc4.bool), c=arc4_encode(true, arc4.bool), d=arc4_encode(false, arc4.bool)) + log(reinterpret_cast(flags)) return true } diff --git a/test_cases/arc4_types/out/tuples.awst b/test_cases/arc4_types/out/tuples.awst index 564c736c1..cd08cee77 100644 --- a/test_cases/arc4_types/out/tuples.awst +++ b/test_cases/arc4_types/out/tuples.awst @@ -2,19 +2,19 @@ contract Arc4TuplesTypeContract { approval_program(): bool { - my_tuple: algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.String, algopy.arc4.String, algopy.arc4.UInt8] = arc4_encode((1arc4u8, 2arc4u8, arc4_encode('hello', algopy.arc4.String), arc4_encode('world', algopy.arc4.String), 255arc4u8), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.String, algopy.arc4.String, algopy.arc4.UInt8]) - assert(reinterpret_cast(my_tuple) == reinterpret_cast(reinterpret_cast(hex<"01020007000EFF000568656C6C6F0005776F726C64">))) - boolean_packing: algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.UInt8] = arc4_encode((4arc4u8, arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(false, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), arc4_encode(true, algopy.arc4.Bool), 16arc4u8), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.UInt8]) - assert(reinterpret_cast(boolean_packing) == hex<"04BD8010">) - (a, b, c, d, e, f, g, h, i, j, k): tuple[algopy.arc4.UInt8, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.UInt8] = arc4_decode(boolean_packing, tuple[algopy.arc4.UInt8, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.UInt8]) - assert(reinterpret_cast(boolean_packing[10]) == reinterpret_cast(k)) - assert(arc4_decode(a, algopy.UInt64) == 4u, comment="a is 4") - assert(reinterpret_cast((reinterpret_cast(b) == hex<"00">) ? (b) : ((reinterpret_cast(d) == hex<"00">) ? (d) : ((reinterpret_cast(e) == hex<"00">) ? (e) : ((reinterpret_cast(f) == hex<"00">) ? (f) : ((reinterpret_cast(g) == hex<"00">) ? (g) : ((reinterpret_cast(i) == hex<"00">) ? (i) : (j))))))) != hex<"00">, comment="b,d,e,f,g,i,j are true") - assert(reinterpret_cast((reinterpret_cast(c) != hex<"00">) ? (c) : (h)) == hex<"00">, comment="c and h are false") - assert(arc4_decode(k, algopy.UInt64) == 16u, comment="k is 16") - assert(reinterpret_cast(boolean_packing) == reinterpret_cast(arc4_encode(arc4_decode(boolean_packing, tuple[algopy.arc4.UInt8, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.UInt8]), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.Bool, algopy.arc4.UInt8]))) - (total, concat): tuple[algopy.UInt64, algopy.arc4.String] = this::test_stuff(my_tuple) - assert(arc4_decode(concat, algopy.String) == 'hello world') + my_tuple: arc4.tuple = arc4_encode((1arc4u8, 2arc4u8, arc4_encode('hello', arc4.string), arc4_encode('world', arc4.string), 255arc4u8), arc4.tuple) + assert(reinterpret_cast(my_tuple) == reinterpret_cast(reinterpret_cast>(hex<"01020007000EFF000568656C6C6F0005776F726C64">))) + boolean_packing: arc4.tuple = arc4_encode((4arc4u8, arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(false, arc4.bool), arc4_encode(true, arc4.bool), arc4_encode(true, arc4.bool), 16arc4u8), arc4.tuple) + assert(reinterpret_cast(boolean_packing) == hex<"04BD8010">) + (a, b, c, d, e, f, g, h, i, j, k): tuple = arc4_decode(boolean_packing, tuple) + assert(reinterpret_cast(boolean_packing[10]) == reinterpret_cast(k)) + assert(arc4_decode(a, uint64) == 4u, comment="a is 4") + assert(reinterpret_cast((reinterpret_cast(b) == hex<"00">) ? (b) : ((reinterpret_cast(d) == hex<"00">) ? (d) : ((reinterpret_cast(e) == hex<"00">) ? (e) : ((reinterpret_cast(f) == hex<"00">) ? (f) : ((reinterpret_cast(g) == hex<"00">) ? (g) : ((reinterpret_cast(i) == hex<"00">) ? (i) : (j))))))) != hex<"00">, comment="b,d,e,f,g,i,j are true") + assert(reinterpret_cast((reinterpret_cast(c) != hex<"00">) ? (c) : (h)) == hex<"00">, comment="c and h are false") + assert(arc4_decode(k, uint64) == 16u, comment="k is 16") + assert(reinterpret_cast(boolean_packing) == reinterpret_cast(arc4_encode(arc4_decode(boolean_packing, tuple), arc4.tuple))) + (total, concat): tuple = this::test_stuff(my_tuple) + assert(arc4_decode(concat, string) == 'hello world') assert(total == 258u) return true } @@ -24,14 +24,14 @@ contract Arc4TuplesTypeContract return true } - subroutine test_stuff(test_tuple: algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.String, algopy.arc4.String, algopy.arc4.UInt8]): tuple[algopy.UInt64, algopy.arc4.String] + subroutine test_stuff(test_tuple: arc4.tuple): tuple { - (a, b, c, d, e): tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.String, algopy.arc4.String, algopy.arc4.UInt8] = arc4_decode(test_tuple, tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.String, algopy.arc4.String, algopy.arc4.UInt8]) - assert(reinterpret_cast(test_tuple[0]) == reinterpret_cast(a)) - assert(reinterpret_cast(test_tuple[-1]) == reinterpret_cast(e)) - assert(reinterpret_cast(test_tuple[-2]) == reinterpret_cast(d)) - total: algopy.UInt64 = arc4_decode(a, algopy.UInt64) + arc4_decode(b, algopy.UInt64) + arc4_decode(e, algopy.UInt64) - text: algopy.String = arc4_decode(c, algopy.String) + ' ' + arc4_decode(d, algopy.String) - return (total, arc4_encode(text, algopy.arc4.String)) + (a, b, c, d, e): tuple = arc4_decode(test_tuple, tuple) + assert(reinterpret_cast(test_tuple[0]) == reinterpret_cast(a)) + assert(reinterpret_cast(test_tuple[-1]) == reinterpret_cast(e)) + assert(reinterpret_cast(test_tuple[-2]) == reinterpret_cast(d)) + total: uint64 = arc4_decode(a, uint64) + arc4_decode(b, uint64) + arc4_decode(e, uint64) + text: string = arc4_decode(c, string) + ' ' + arc4_decode(d, string) + return (total, arc4_encode(text, arc4.string)) } } \ No newline at end of file diff --git a/test_cases/asset/out/contract.awst b/test_cases/asset/out/contract.awst index 3dbf77207..02a37d050 100644 --- a/test_cases/asset/out/contract.awst +++ b/test_cases/asset/out/contract.awst @@ -1,23 +1,23 @@ contract Reference { globals { - ['asa']: algopy.Asset + ['asa']: asset } constructor() { - this.asa: algopy.Asset = reinterpret_cast(0u) + this.asa: asset = reinterpret_cast(0u) } approval_program(): bool { if (txn() == 1u) { if (txna() == 'opt_in') { - asset: algopy.Asset = txna() + asset: asset = txna() this::opt_into_asset(asset) } else { if (txna() == 'is_opted_in') { - asset: algopy.Asset = txna() + asset: asset = txna() this::is_opted_asset(asset) } else { assert(false, comment="Expected opt_in or is_opted_in") @@ -32,11 +32,11 @@ contract Reference return true } - subroutine opt_into_asset(asset: algopy.Asset): None + subroutine opt_into_asset(asset: asset): void { assert(txn() == global(), comment="Only creator can opt in to ASA") assert(!(reinterpret_cast(this.asa)), comment="ASA already opted in") - this.asa: algopy.Asset = asset + this.asa: asset = asset itxn_begin() itxn_field(axfer) itxn_field(0u) @@ -45,7 +45,7 @@ contract Reference itxn_submit() } - subroutine is_opted_asset(asset: algopy.Asset): None + subroutine is_opted_asset(asset: asset): void { assert(this.asa == asset, comment="asset self.asa == asset") assert(checked_maybe(asset_params_get(asset)) == 10000000u, comment="total") diff --git a/test_cases/augmented_assignment/out/contract.awst b/test_cases/augmented_assignment/out/contract.awst index f06f96574..707958edd 100644 --- a/test_cases/augmented_assignment/out/contract.awst +++ b/test_cases/augmented_assignment/out/contract.awst @@ -1,30 +1,30 @@ contract Augmented { globals { - ['global_uint']: algopy.UInt64 - ['global_bytes']: algopy.Bytes + ['global_uint']: uint64 + ['global_bytes']: bytes } locals { - ['my_uint']: algopy.UInt64 - ['my_bytes']: algopy.Bytes + ['my_uint']: uint64 + ['my_bytes']: bytes } constructor() { - this.global_uint: algopy.UInt64 = 0u - this.global_bytes: algopy.Bytes = '' + this.global_uint: uint64 = 0u + this.global_bytes: bytes = '' } approval_program(): bool { - me: algopy.Account = txn() + me: account = txn() if (txn() == OptIn) { - this.my_uint[me]: algopy.UInt64 = 0u - this.my_bytes[me]: algopy.Bytes = '' + this.my_uint[me]: uint64 = 0u + this.my_bytes[me]: bytes = '' } if (reinterpret_cast(txn())) { - n: algopy.UInt64 = txn() - bytes_to_add: algopy.Bytes = reinterpret_cast(itob(n)) + n: uint64 = txn() + bytes_to_add: bytes = reinterpret_cast(itob(n)) this.my_uint[me] += n this.my_bytes[me] += bytes_to_add this.global_uint += n diff --git a/test_cases/avm_types_in_abi/out/client_TestContract.py b/test_cases/avm_types_in_abi/out/client_TestContract.py index 212801d1e..64fe18d6e 100644 --- a/test_cases/avm_types_in_abi/out/client_TestContract.py +++ b/test_cases/avm_types_in_abi/out/client_TestContract.py @@ -11,15 +11,15 @@ class TestContract(algopy.arc4.ARC4Client, typing.Protocol): def create( self, bool_param: algopy.arc4.Bool, - uint64_param: algopy.arc4.UInt64, + uint64_param: algopy.arc4.UIntN[typing.Literal[64]], bytes_param: algopy.arc4.DynamicBytes, - biguint_param: algopy.arc4.UInt512, + biguint_param: algopy.arc4.BigUIntN[typing.Literal[512]], string_param: algopy.arc4.String, - tuple_param: algopy.arc4.Tuple[algopy.arc4.Bool, algopy.arc4.UInt64, algopy.arc4.DynamicBytes, algopy.arc4.UInt512, algopy.arc4.String], - ) -> algopy.arc4.Tuple[algopy.arc4.Bool, algopy.arc4.UInt64, algopy.arc4.DynamicBytes, algopy.arc4.UInt512, algopy.arc4.String]: ... + tuple_param: algopy.arc4.Tuple[algopy.arc4.Bool, algopy.arc4.UIntN[typing.Literal[64]], algopy.arc4.DynamicBytes, algopy.arc4.BigUIntN[typing.Literal[512]], algopy.arc4.String], + ) -> algopy.arc4.Tuple[algopy.arc4.Bool, algopy.arc4.UIntN[typing.Literal[64]], algopy.arc4.DynamicBytes, algopy.arc4.BigUIntN[typing.Literal[512]], algopy.arc4.String]: ... @algopy.arc4.abimethod def tuple_of_arc4( self, - args: algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.Address], - ) -> algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.Address]: ... + args: algopy.arc4.Tuple[algopy.arc4.UIntN[typing.Literal[8]], algopy.arc4.Address], + ) -> algopy.arc4.Tuple[algopy.arc4.UIntN[typing.Literal[8]], algopy.arc4.Address]: ... diff --git a/test_cases/avm_types_in_abi/out/contract.awst b/test_cases/avm_types_in_abi/out/contract.awst index 2147412b6..3e08f2f64 100644 --- a/test_cases/avm_types_in_abi/out/contract.awst +++ b/test_cases/avm_types_in_abi/out/contract.awst @@ -1,16 +1,16 @@ contract TestContract { - abimethod create(bool_param: bool, uint64_param: algopy.UInt64, bytes_param: algopy.Bytes, biguint_param: algopy.BigUInt, string_param: algopy.String, tuple_param: tuple[bool, algopy.UInt64, algopy.Bytes, algopy.BigUInt, algopy.String]): tuple[bool, algopy.UInt64, algopy.Bytes, algopy.BigUInt, algopy.String] + abimethod create(bool_param: bool, uint64_param: uint64, bytes_param: bytes, biguint_param: biguint, string_param: string, tuple_param: tuple): tuple { - result: tuple[bool, algopy.UInt64, algopy.Bytes, algopy.BigUInt, algopy.String] = (bool_param, uint64_param, bytes_param, biguint_param, string_param) + result: tuple = (bool_param, uint64_param, bytes_param, biguint_param, string_param) assert(result[0] == tuple_param[0] and result[1] == tuple_param[1] and result[2] == tuple_param[2] and result[3] == tuple_param[3] and result[4] == tuple_param[4]) return result } - abimethod tuple_of_arc4(args: tuple[algopy.arc4.UInt8, algopy.arc4.Address]): tuple[algopy.arc4.UInt8, algopy.arc4.Address] + abimethod tuple_of_arc4(args: tuple): tuple { - assert(len(reinterpret_cast(args[0])) == 1u) - assert(len(reinterpret_cast(args[1])) == 32u) + assert(len(reinterpret_cast(args[0])) == 1u) + assert(len(reinterpret_cast(args[1])) == 32u) return args } } \ No newline at end of file diff --git a/test_cases/biguint_binary_ops/out/contract.awst b/test_cases/biguint_binary_ops/out/contract.awst index 94ad85d56..a64f3806c 100644 --- a/test_cases/biguint_binary_ops/out/contract.awst +++ b/test_cases/biguint_binary_ops/out/contract.awst @@ -2,8 +2,8 @@ contract BiguintBinaryOps { approval_program(): bool { - left: algopy.BigUInt = 58446744073709552000n - right: algopy.BigUInt = 18446744073709552000n + left: biguint = 58446744073709552000n + right: biguint = 18446744073709552000n assert(left b+ right == 76893488147419104000n) assert(left b- right == 40000000000000000000n) assert(left b* right == 1078152129869320557630474056040704000000n) diff --git a/test_cases/boolean_binary_ops/out/contract.awst b/test_cases/boolean_binary_ops/out/contract.awst index 8fad65b1f..e5d2188dc 100644 --- a/test_cases/boolean_binary_ops/out/contract.awst +++ b/test_cases/boolean_binary_ops/out/contract.awst @@ -14,7 +14,7 @@ contract BooleanBinaryOps } } -subroutine test_boolean_binary_ops(true: bool, false: bool): None +subroutine test_boolean_binary_ops(true: bool, false: bool): void { assert(!(true and false)) assert(!(false and true)) @@ -26,26 +26,26 @@ subroutine test_boolean_binary_ops(true: bool, false: bool): None assert(!(false or false)) } -subroutine bool_to_bytes(x: bool): algopy.Bytes +subroutine bool_to_bytes(x: bool): bytes { return (x) ? ('true') : ('false') } -subroutine test_boolean_shortcircuit_binary_ops(): None +subroutine test_boolean_shortcircuit_binary_ops(): void { for lhs in (true, false) { for rhs in (true, false) { - and_msg: algopy.Bytes = '_' + test_cases.boolean_binary_ops.contract::bool_to_bytes(lhs) + '_and_' + test_cases.boolean_binary_ops.contract::bool_to_bytes(rhs) + and_msg: bytes = '_' + test_cases.boolean_binary_ops.contract::bool_to_bytes(lhs) + '_and_' + test_cases.boolean_binary_ops.contract::bool_to_bytes(rhs) and_result: bool = test_cases.boolean_binary_ops.contract::log_and_return(lhs, 'lhs' + and_msg) and test_cases.boolean_binary_ops.contract::log_and_return(rhs, 'rhs' + and_msg) assert(and_result == lhs and rhs) - or_msg: algopy.Bytes = '_' + test_cases.boolean_binary_ops.contract::bool_to_bytes(lhs) + '_or_' + test_cases.boolean_binary_ops.contract::bool_to_bytes(rhs) + or_msg: bytes = '_' + test_cases.boolean_binary_ops.contract::bool_to_bytes(lhs) + '_or_' + test_cases.boolean_binary_ops.contract::bool_to_bytes(rhs) or_result: bool = test_cases.boolean_binary_ops.contract::log_and_return(lhs, 'lhs' + or_msg) or test_cases.boolean_binary_ops.contract::log_and_return(rhs, 'rhs' + or_msg) assert(or_result == lhs or rhs) } } } -subroutine log_and_return(x: bool, msg: algopy.Bytes): bool +subroutine log_and_return(x: bool, msg: bytes): bool { log(msg) return x diff --git a/test_cases/bytes_ops/out/contract.awst b/test_cases/bytes_ops/out/contract.awst index 433d7abd9..2de98a3d5 100644 --- a/test_cases/bytes_ops/out/contract.awst +++ b/test_cases/bytes_ops/out/contract.awst @@ -13,26 +13,26 @@ contract BiguintBinaryOps } } -subroutine do_some_ops(left: algopy.Bytes, right: algopy.Bytes, concat: algopy.Bytes, bitwise_or: algopy.Bytes, bitwise_xor: algopy.Bytes, bitwise_and: algopy.Bytes): None +subroutine do_some_ops(left: bytes, right: bytes, concat: bytes, bitwise_or: bytes, bitwise_xor: bytes, bitwise_and: bytes): void { - result: algopy.Bytes = left + right + result: bytes = left + right assert(result == concat) - result: algopy.Bytes = left | right + result: bytes = left | right assert(result == bitwise_or) - result: algopy.Bytes = left ^ right + result: bytes = left ^ right assert(result == bitwise_xor) - result: algopy.Bytes = left & right + result: bytes = left & right assert(result == bitwise_and) } -subroutine do_augmented_assignment_ops(seed: algopy.Bytes): None +subroutine do_augmented_assignment_ops(seed: bytes): void { seed &= hex<"00"> assert(seed == hex<"00">) - five: algopy.Bytes = hex<"05"> + five: bytes = hex<"05"> seed |= five assert(seed == five) - sixteen: algopy.Bytes = hex<"10"> + sixteen: bytes = hex<"10"> seed ^= sixteen assert(seed == hex<"15">) seed ^= five diff --git a/test_cases/callsub/out/contract.awst b/test_cases/callsub/out/contract.awst index 88ce5f77d..e4dd5a24c 100644 --- a/test_cases/callsub/out/contract.awst +++ b/test_cases/callsub/out/contract.awst @@ -1,18 +1,18 @@ contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { log(itob(42u)) this::echo(1u, 2u) return 1u } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { return 1u } - subroutine echo(a: algopy.UInt64, b: algopy.UInt64): None + subroutine echo(a: uint64, b: uint64): void { log(itob(a)) log(itob(b)) diff --git a/test_cases/chained_assignment/out/contract.awst b/test_cases/chained_assignment/out/contract.awst index a42ee76c1..68eec3b33 100644 --- a/test_cases/chained_assignment/out/contract.awst +++ b/test_cases/chained_assignment/out/contract.awst @@ -3,14 +3,14 @@ WAVE = b'\xf0\x9f\x91\x8b' abstract contract BaseContract { globals { - ['state1']: algopy.Bytes - ['state2']: algopy.Bytes + ['state1']: bytes + ['state2']: bytes } constructor() { - this.state2: algopy.Bytes = SINGLE_EVAL(id=0, source=test_cases.chained_assignment.contract::join_log_and_return(right='\xf0\x9f\x91\x8b', left='Hello, world!')) - this.state1: algopy.Bytes = SINGLE_EVAL(id=0, source=test_cases.chained_assignment.contract::join_log_and_return(right='\xf0\x9f\x91\x8b', left='Hello, world!')) + this.state2: bytes = SINGLE_EVAL(id=0, source=test_cases.chained_assignment.contract::join_log_and_return(right='\xf0\x9f\x91\x8b', left='Hello, world!')) + this.state1: bytes = SINGLE_EVAL(id=0, source=test_cases.chained_assignment.contract::join_log_and_return(right='\xf0\x9f\x91\x8b', left='Hello, world!')) } } @@ -32,9 +32,9 @@ contract ChainedAssignment extends (test_cases.chained_assignment.contract::Base } } -subroutine join_log_and_return(left: algopy.Bytes, right: algopy.Bytes): algopy.Bytes +subroutine join_log_and_return(left: bytes, right: bytes): bytes { - result: algopy.Bytes = left + ' ' + right + result: bytes = left + ' ' + right log(result) return result } \ No newline at end of file diff --git a/test_cases/conditional_execution/out/contract.awst b/test_cases/conditional_execution/out/contract.awst index 0e1fa636f..54421b527 100644 --- a/test_cases/conditional_execution/out/contract.awst +++ b/test_cases/conditional_execution/out/contract.awst @@ -35,7 +35,7 @@ contract ConditionalExecutionContract return true } - subroutine assert_and_reset(condition: bool): None + subroutine assert_and_reset(condition: bool): void { assert(condition) this.did_execute_b: bool = false diff --git a/test_cases/conditional_expressions/out/contract.awst b/test_cases/conditional_expressions/out/contract.awst index 3d7d15114..5107a91db 100644 --- a/test_cases/conditional_expressions/out/contract.awst +++ b/test_cases/conditional_expressions/out/contract.awst @@ -1,34 +1,34 @@ contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - a: algopy.UInt64 = 1u - b: algopy.UInt64 = 2u - c: algopy.UInt64 = (reinterpret_cast(a)) ? (a) : (b) - d: algopy.UInt64 = (!(reinterpret_cast(b))) ? (b) : (a) - e: algopy.UInt64 = (reinterpret_cast(SINGLE_EVAL(id=0, source=this::expensive_op(0u)))) ? (SINGLE_EVAL(id=0, source=this::expensive_op(0u))) : (this::side_effecting_op(1u)) - f: algopy.UInt64 = (reinterpret_cast(SINGLE_EVAL(id=1, source=this::expensive_op(3u)))) ? (SINGLE_EVAL(id=1, source=this::expensive_op(3u))) : (this::side_effecting_op(42u)) - g: algopy.UInt64 = (!(reinterpret_cast(SINGLE_EVAL(id=2, source=this::side_effecting_op(0u))))) ? (SINGLE_EVAL(id=2, source=this::side_effecting_op(0u))) : (this::expensive_op(42u)) - h: algopy.UInt64 = (!(reinterpret_cast(SINGLE_EVAL(id=3, source=this::side_effecting_op(2u))))) ? (SINGLE_EVAL(id=3, source=this::side_effecting_op(2u))) : (this::expensive_op(3u)) - i: algopy.UInt64 = (b < c) ? (a) : (d + e) - result: algopy.UInt64 = a * b * c * d * f * h - e - g + i + a: uint64 = 1u + b: uint64 = 2u + c: uint64 = (reinterpret_cast(a)) ? (a) : (b) + d: uint64 = (!(reinterpret_cast(b))) ? (b) : (a) + e: uint64 = (reinterpret_cast(SINGLE_EVAL(id=0, source=this::expensive_op(0u)))) ? (SINGLE_EVAL(id=0, source=this::expensive_op(0u))) : (this::side_effecting_op(1u)) + f: uint64 = (reinterpret_cast(SINGLE_EVAL(id=1, source=this::expensive_op(3u)))) ? (SINGLE_EVAL(id=1, source=this::expensive_op(3u))) : (this::side_effecting_op(42u)) + g: uint64 = (!(reinterpret_cast(SINGLE_EVAL(id=2, source=this::side_effecting_op(0u))))) ? (SINGLE_EVAL(id=2, source=this::side_effecting_op(0u))) : (this::expensive_op(42u)) + h: uint64 = (!(reinterpret_cast(SINGLE_EVAL(id=3, source=this::side_effecting_op(2u))))) ? (SINGLE_EVAL(id=3, source=this::side_effecting_op(2u))) : (this::expensive_op(3u)) + i: uint64 = (b < c) ? (a) : (d + e) + result: uint64 = a * b * c * d * f * h - e - g + i log(itob(result)) return result } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { return 0u } - subroutine expensive_op(val: algopy.UInt64): algopy.UInt64 + subroutine expensive_op(val: uint64): uint64 { assert(val != 42u, comment="Can't be 42") log('expensive_op') return val } - subroutine side_effecting_op(val: algopy.UInt64): algopy.UInt64 + subroutine side_effecting_op(val: uint64): uint64 { assert(val != 42u, comment="Can't be 42") log('side_effecting_op') diff --git a/test_cases/constants/out/address_constant.awst b/test_cases/constants/out/address_constant.awst index 41b84ffc5..98aeb5fe1 100644 --- a/test_cases/constants/out/address_constant.awst +++ b/test_cases/constants/out/address_constant.awst @@ -2,14 +2,14 @@ contract AddressConstantContract { approval_program(): bool { - some_address: algopy.Account = global() + some_address: account = global() assert(some_address == global()) - some_address: algopy.Account = Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA") + some_address: account = Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA") assert(some_address != global()) - some_address: algopy.Account = reinterpret_cast(reinterpret_cast(some_address)) - some_address: algopy.Account = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=0, source=reinterpret_cast(some_address)), 32u == len(SINGLE_EVAL(id=0, source=reinterpret_cast(some_address)))))) - sender: algopy.Account = txn() - sender_bytes: algopy.Bytes = reinterpret_cast(sender) + some_address: account = reinterpret_cast(reinterpret_cast(some_address)) + some_address: account = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=0, source=reinterpret_cast(some_address)), 32u == len(SINGLE_EVAL(id=0, source=reinterpret_cast(some_address)))))) + sender: account = txn() + sender_bytes: bytes = reinterpret_cast(sender) log(sender_bytes) is_some_address: bool = txn() == some_address return !(is_some_address) diff --git a/test_cases/constants/out/byte_constants.awst b/test_cases/constants/out/byte_constants.awst index 093824104..cef359120 100644 --- a/test_cases/constants/out/byte_constants.awst +++ b/test_cases/constants/out/byte_constants.awst @@ -1,12 +1,12 @@ contract ByteConstantsContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - base_64: algopy.Bytes = b64<"QmFzZSA2NCBlbmNvZGVk"> - base_32: algopy.Bytes = b32<"IJQXGZJAGMZCAZLOMNXWIZLE"> - base_16: algopy.Bytes = hex<"4261736520313620656E636F646564"> - utf8: algopy.Bytes = 'UTF-8 Encoded' - result: algopy.Bytes = base_16 + '|' + base_64 + '|' + base_32 + '|' + utf8 + base_64: bytes = b64<"QmFzZSA2NCBlbmNvZGVk"> + base_32: bytes = b32<"IJQXGZJAGMZCAZLOMNXWIZLE"> + base_16: bytes = hex<"4261736520313620656E636F646564"> + utf8: bytes = 'UTF-8 Encoded' + result: bytes = base_16 + '|' + base_64 + '|' + base_32 + '|' + utf8 log(result) log(itob(len(result))) return 1u diff --git a/test_cases/contains/out/contract.awst b/test_cases/contains/out/contract.awst index 90ee55c3b..50ffbe61d 100644 --- a/test_cases/contains/out/contract.awst +++ b/test_cases/contains/out/contract.awst @@ -1,8 +1,8 @@ contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - not_ten: algopy.UInt64 = 15u + not_ten: uint64 = 15u one_true: bool = this::is_in_tuple_1(10u, (10u, not_ten, 'five')) one_false: bool = this::is_in_tuple_1(5u, (10u, not_ten, 'five')) assert(one_true, comment="Should be true") @@ -18,22 +18,22 @@ contract MyContract return 1u } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { return 1u } - subroutine is_in_tuple_1(x: algopy.UInt64, y: tuple[algopy.UInt64, algopy.UInt64, algopy.Bytes]): bool + subroutine is_in_tuple_1(x: uint64, y: tuple): bool { return x IS IN y } - subroutine is_in_tuple_2(x: algopy.Bytes, y: tuple[algopy.Bytes, algopy.UInt64, algopy.Bytes]): bool + subroutine is_in_tuple_2(x: bytes, y: tuple): bool { return x IS IN y } - subroutine is_in_tuple_3(x: algopy.BigUInt, y: tuple[algopy.BigUInt, algopy.BigUInt]): bool + subroutine is_in_tuple_3(x: biguint, y: tuple): bool { return x IS IN y } diff --git a/test_cases/dup2_optimization_bug/out/crash.awst b/test_cases/dup2_optimization_bug/out/crash.awst index b0d0e3030..9073be145 100644 --- a/test_cases/dup2_optimization_bug/out/crash.awst +++ b/test_cases/dup2_optimization_bug/out/crash.awst @@ -2,8 +2,8 @@ contract MyContract { approval_program(): bool { - a: algopy.Bytes = txna() - b: algopy.Bytes = txna() + a: bytes = txna() + b: bytes = txna() assert(reinterpret_cast(len(a + b))) return len(b + a) > 0u } diff --git a/test_cases/enumeration/out/contract.awst b/test_cases/enumeration/out/contract.awst index 38681bc60..48c92a265 100644 --- a/test_cases/enumeration/out/contract.awst +++ b/test_cases/enumeration/out/contract.awst @@ -2,15 +2,15 @@ contract EnumerationContract { approval_program(): bool { - (iteration_count, item_sum, index_sum): tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64] = test_cases.enumeration.contract::enumerate_urange(10u, 21u, 5u) + (iteration_count, item_sum, index_sum): tuple = test_cases.enumeration.contract::enumerate_urange(10u, 21u, 5u) assert(iteration_count == 6u) assert(item_sum == 90u) assert(index_sum == 3u) - (iteration_count, item_concat, index_sum): tuple[algopy.UInt64, algopy.Bytes, algopy.UInt64] = test_cases.enumeration.contract::enumerate_tuple(('How', 'Now', 'Brown', 'Cow')) + (iteration_count, item_concat, index_sum): tuple = test_cases.enumeration.contract::enumerate_tuple(('How', 'Now', 'Brown', 'Cow')) assert(iteration_count == 8u) assert(item_concat == 'HowNowBrownCowHowNowBrownCow') assert(index_sum == 6u) - (iteration_count, item_concat, index_sum): tuple[algopy.UInt64, algopy.Bytes, algopy.UInt64] = test_cases.enumeration.contract::enumerate_bytes('abcdefg') + (iteration_count, item_concat, index_sum): tuple = test_cases.enumeration.contract::enumerate_bytes('abcdefg') assert(iteration_count == 14u) assert(item_concat == 'abcdefgabcdefg') assert(index_sum == 21u) @@ -23,11 +23,11 @@ contract EnumerationContract } } -subroutine enumerate_urange(start: algopy.UInt64, stop: algopy.UInt64, step: algopy.UInt64): tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64] +subroutine enumerate_urange(start: uint64, stop: uint64, step: uint64): tuple { - iteration_count: algopy.UInt64 = 0u - item_sum: algopy.UInt64 = 0u - index_sum: algopy.UInt64 = 0u + iteration_count: uint64 = 0u + item_sum: uint64 = 0u + index_sum: uint64 = 0u for item in range(start, stop, step) { iteration_count += 1u item_sum += item @@ -40,11 +40,11 @@ subroutine enumerate_urange(start: algopy.UInt64, stop: algopy.UInt64, step: alg return (iteration_count, item_sum, index_sum) } -subroutine enumerate_tuple(tup: tuple[algopy.Bytes, algopy.Bytes, algopy.Bytes, algopy.Bytes]): tuple[algopy.UInt64, algopy.Bytes, algopy.UInt64] +subroutine enumerate_tuple(tup: tuple): tuple { - iteration_count: algopy.UInt64 = 0u - item_concat: algopy.Bytes = '' - index_sum: algopy.UInt64 = 0u + iteration_count: uint64 = 0u + item_concat: bytes = '' + index_sum: uint64 = 0u for item in tup { iteration_count += 1u item_concat += item @@ -57,11 +57,11 @@ subroutine enumerate_tuple(tup: tuple[algopy.Bytes, algopy.Bytes, algopy.Bytes, return (iteration_count, item_concat, index_sum) } -subroutine enumerate_bytes(bytes_: algopy.Bytes): tuple[algopy.UInt64, algopy.Bytes, algopy.UInt64] +subroutine enumerate_bytes(bytes_: bytes): tuple { - iteration_count: algopy.UInt64 = 0u - item_concat: algopy.Bytes = '' - index_sum: algopy.UInt64 = 0u + iteration_count: uint64 = 0u + item_concat: bytes = '' + index_sum: uint64 = 0u for item in bytes_ { iteration_count += 1u item_concat += item diff --git a/test_cases/everything/out/client_MyContract.py b/test_cases/everything/out/client_MyContract.py index 3437c2daa..cd382e393 100644 --- a/test_cases/everything/out/client_MyContract.py +++ b/test_cases/everything/out/client_MyContract.py @@ -26,9 +26,9 @@ def say_hello( @algopy.arc4.abimethod def calculate( self, - a: algopy.arc4.UInt64, - b: algopy.arc4.UInt64, - ) -> algopy.arc4.UInt64: ... + a: algopy.arc4.UIntN[typing.Literal[64]], + b: algopy.arc4.UIntN[typing.Literal[64]], + ) -> algopy.arc4.UIntN[typing.Literal[64]]: ... @algopy.arc4.abimethod(allow_actions=['CloseOut']) def close_out( diff --git a/test_cases/everything/out/contract.awst b/test_cases/everything/out/contract.awst index d6cabc55f..471b57828 100644 --- a/test_cases/everything/out/contract.awst +++ b/test_cases/everything/out/contract.awst @@ -2,16 +2,16 @@ ZERO = 0 ZER0 = 0 ONE = 1 -subroutine get_banned(): algopy.Account +subroutine get_banned(): account { - addr: algopy.Account = Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA") + addr: account = Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA") return addr } -subroutine add_one(x: algopy.UInt64): algopy.UInt64 +subroutine add_one(x: uint64): uint64 { - new_value: algopy.UInt64 = x - one: algopy.UInt64 = 1u + new_value: uint64 = x + one: uint64 = 1u new_value += one return new_value } @@ -19,10 +19,10 @@ subroutine add_one(x: algopy.UInt64): algopy.UInt64 contract Everything extends (test_cases.everything.my_base::MyMiddleBase, test_cases.everything.my_base::MyBase) { globals { - ['counter']: algopy.UInt64 + ['counter']: uint64 } locals { - ['name']: algopy.arc4.String + ['name']: arc4.string } constructor() @@ -35,58 +35,58 @@ contract Everything extends (test_cases.everything.my_base::MyMiddleBase, test_c return true } - abimethod create(): None + abimethod create(): void { this::_check_ban_list() this::remember_creator() - this.counter: algopy.UInt64 = 0u + this.counter: uint64 = 0u } - abimethod register(name: algopy.arc4.String): None + abimethod register(name: arc4.string): void { this::_check_ban_list() if (txn() == OptIn) { - (sender_name, sender_name_existed): tuple[algopy.arc4.String, bool] = STATE_GET_EX(this.name[0u]) + (sender_name, sender_name_existed): tuple = STATE_GET_EX(this.name[0u]) if (!(sender_name_existed)) { this.counter += test_cases.everything.my_base::multiplicative_identity() } } - this.name[0u]: algopy.arc4.String = name + this.name[0u]: arc4.string = name } - abimethod say_hello(): algopy.arc4.String + abimethod say_hello(): arc4.string { this::_check_ban_list() - (name, exists): tuple[algopy.arc4.String, bool] = STATE_GET_EX(this.name[0u]) + (name, exists): tuple = STATE_GET_EX(this.name[0u]) if (!(exists)) { - return arc4_encode('Howdy stranger!', algopy.arc4.String) + return arc4_encode('Howdy stranger!', arc4.string) } - return arc4_encode('Hello, ', algopy.arc4.String) + name + arc4_encode('!', algopy.arc4.String) + return arc4_encode('Hello, ', arc4.string) + name + arc4_encode('!', arc4.string) } - abimethod calculate(a: algopy.arc4.UInt64, b: algopy.arc4.UInt64): algopy.arc4.UInt64 + abimethod calculate(a: arc4.uint64, b: arc4.uint64): arc4.uint64 { - c: algopy.arc4.UInt64 = test_cases.everything.my_base::MyMiddleBase::calculate(a, b) - return arc4_encode(arc4_decode(c, algopy.UInt64) * arc4_decode(b, algopy.UInt64), algopy.arc4.UInt64) + c: arc4.uint64 = test_cases.everything.my_base::MyMiddleBase::calculate(a, b) + return arc4_encode(arc4_decode(c, uint64) * arc4_decode(b, uint64), arc4.uint64) } - abimethod close_out(): None + abimethod close_out(): void { this::_remove_sender() } - subroutine _check_ban_list(): None + subroutine _check_ban_list(): void { assert(txn() != test_cases.everything.contract::get_banned(), comment="You are banned, goodbye") } - subroutine _remove_sender(): None + subroutine _remove_sender(): void { this.counter -= test_cases.everything.contract::positive_one() } } -subroutine positive_one(): algopy.UInt64 +subroutine positive_one(): uint64 { return 1u } \ No newline at end of file diff --git a/test_cases/everything/out/my_base.awst b/test_cases/everything/out/my_base.awst index 43d312824..172f2324b 100644 --- a/test_cases/everything/out/my_base.awst +++ b/test_cases/everything/out/my_base.awst @@ -1,24 +1,24 @@ abstract contract MyBase { globals { - ['creator']: algopy.Account + ['creator']: account } - subroutine remember_creator(): None + subroutine remember_creator(): void { - this.creator: algopy.Account = txn() + this.creator: account = txn() } } abstract contract MyMiddleBase extends (test_cases.everything.my_base::MyBase) { - subroutine calculate(a: algopy.arc4.UInt64, b: algopy.arc4.UInt64): algopy.arc4.UInt64 + subroutine calculate(a: arc4.uint64, b: arc4.uint64): arc4.uint64 { - return arc4_encode(arc4_decode(a, algopy.UInt64) + arc4_decode(b, algopy.UInt64), algopy.arc4.UInt64) + return arc4_encode(arc4_decode(a, uint64) + arc4_decode(b, uint64), arc4.uint64) } } -subroutine multiplicative_identity(): algopy.UInt64 +subroutine multiplicative_identity(): uint64 { return 1u } \ No newline at end of file diff --git a/test_cases/inner_transactions/out/array_access.awst b/test_cases/inner_transactions/out/array_access.awst index 4584dfe22..743496891 100644 --- a/test_cases/inner_transactions/out/array_access.awst +++ b/test_cases/inner_transactions/out/array_access.awst @@ -3,14 +3,14 @@ ALWAYS_APPROVE = b'\t\x81\x01' contract ArrayAccessContract { - abimethod test_branching_array_call(maybe: algopy.arc4.Bool): None + abimethod test_branching_array_call(maybe: arc4.bool): void { - if (reinterpret_cast(maybe) != hex<"00">) { - create_app_txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, ApplicationArgs=('1', '2'))) + if (reinterpret_cast(maybe) != hex<"00">) { + create_app_txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, ApplicationArgs=('1', '2'))) } else { - create_app_txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, ApplicationArgs=('3', '4', '5'), Note='different param set')) + create_app_txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, ApplicationArgs=('3', '4', '5'), Note='different param set')) } - if (reinterpret_cast(maybe) != hex<"00">) { + if (reinterpret_cast(maybe) != hex<"00">) { assert(create_app_txn.ApplicationArgs[0u] == '1', comment="correct args used 1") assert(create_app_txn.ApplicationArgs[1u] == '2', comment="correct args used 2") } else { diff --git a/test_cases/inner_transactions/out/asset_transfer.awst b/test_cases/inner_transactions/out/asset_transfer.awst index 33b28e06a..051a57f7d 100644 --- a/test_cases/inner_transactions/out/asset_transfer.awst +++ b/test_cases/inner_transactions/out/asset_transfer.awst @@ -1,8 +1,8 @@ contract CreateAndTransferContract { - abimethod create_and_transfer(): None + abimethod create_and_transfer(): void { - new_asset: algopy.Asset = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=acfg, ConfigAssetTotal=1000u, ConfigAssetName='test', ConfigAssetUnitName='TST', ConfigAssetDecimals=0u, ConfigAssetManager=global(), ConfigAssetClawback=global())).CreatedAssetID + new_asset: asset = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=acfg, ConfigAssetTotal=1000u, ConfigAssetName='test', ConfigAssetUnitName='TST', ConfigAssetDecimals=0u, ConfigAssetManager=global(), ConfigAssetClawback=global())).CreatedAssetID submit_txn(create_inner_transaction(Fee=0u, TypeEnum=axfer, AssetSender=checked_maybe(asset_params_get(new_asset)), AssetReceiver=global(), AssetAmount=1000u, XferAsset=new_asset)) } } \ No newline at end of file diff --git a/test_cases/inner_transactions/out/c2c.awst b/test_cases/inner_transactions/out/c2c.awst index 490331382..9a04c8b29 100644 --- a/test_cases/inner_transactions/out/c2c.awst +++ b/test_cases/inner_transactions/out/c2c.awst @@ -1,25 +1,25 @@ contract Greeter { globals { - ['hello_app']: algopy.Application + ['hello_app']: application } constructor() { - this.hello_app: algopy.Application = reinterpret_cast(0u) + this.hello_app: application = reinterpret_cast(0u) } - abimethod bootstrap(): algopy.UInt64 + abimethod bootstrap(): uint64 { assert(!(reinterpret_cast(this.hello_app)), comment="already bootstrapped") - this.hello_app: algopy.Application = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"0A200101311B410026800402BECE11361A008E0100010031191444311844361A018800158004151F7C754C50B02243311914443118144422438A01018BFF570200800748656C6C6F2C204C504915165706004C5089">, ClearStateProgramPages=hex<"0A8101">)).CreatedApplicationID - return reinterpret_cast(this.hello_app) + this.hello_app: application = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"0A200101311B410026800402BECE11361A008E0100010031191444311844361A018800158004151F7C754C50B02243311914443118144422438A01018BFF570200800748656C6C6F2C204C504915165706004C5089">, ClearStateProgramPages=hex<"0A8101">)).CreatedApplicationID + return reinterpret_cast(this.hello_app) } - abimethod log_greetings(name: algopy.arc4.String): None + abimethod log_greetings(name: arc4.string): void { - hello_call: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationID=this.hello_app, ApplicationArgs=(Method("hello(string)string"), name))) - greeting: algopy.arc4.String = reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=0, source=hello_call.LastLog)), extract<0, 4>(SINGLE_EVAL(id=0, source=hello_call.LastLog)) == hex<"151F7C75">))) - log(concat(concat('HelloWorld returned: ', ''), arc4_decode(greeting, algopy.String))) + hello_call: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationID=this.hello_app, ApplicationArgs=(Method("hello(string)string"), name))) + greeting: arc4.string = reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=0, source=hello_call.LastLog)), extract<0, 4>(SINGLE_EVAL(id=0, source=hello_call.LastLog)) == hex<"151F7C75">))) + log(concat(concat('HelloWorld returned: ', ''), arc4_decode(greeting, string))) } } \ No newline at end of file diff --git a/test_cases/inner_transactions/out/client_Greeter.py b/test_cases/inner_transactions/out/client_Greeter.py index eda3e7f8c..23b821d04 100644 --- a/test_cases/inner_transactions/out/client_Greeter.py +++ b/test_cases/inner_transactions/out/client_Greeter.py @@ -10,7 +10,7 @@ class Greeter(algopy.arc4.ARC4Client, typing.Protocol): @algopy.arc4.abimethod def bootstrap( self, - ) -> algopy.arc4.UInt64: ... + ) -> algopy.arc4.UIntN[typing.Literal[64]]: ... @algopy.arc4.abimethod def log_greetings( diff --git a/test_cases/inner_transactions/out/contract.awst b/test_cases/inner_transactions/out/contract.awst index 3913c3467..491dbe943 100644 --- a/test_cases/inner_transactions/out/contract.awst +++ b/test_cases/inner_transactions/out/contract.awst @@ -4,12 +4,12 @@ ALWAYS_APPROVE = b'\t\x81\x01' contract MyContract { globals { - ['name']: algopy.Bytes + ['name']: bytes } constructor() { - this.name: algopy.Bytes = '' + this.name: bytes = '' } approval_program(): bool @@ -38,21 +38,21 @@ contract MyContract return true } - subroutine test1(): None + subroutine test1(): void { - this.name: algopy.Bytes = 'AST1' - asset_params: algopy.itxn.AssetConfig = create_inner_transaction(Fee=0u, TypeEnum=acfg, ConfigAssetTotal=1000u, ConfigAssetName=this.name, ConfigAssetUnitName='unit', ConfigAssetDecimals=3u, ConfigAssetManager=global(), ConfigAssetReserve=global()) - this.name: algopy.Bytes = 'AST2' - asset1_txn: algopy.itxn.AssetConfigInnerTransaction = submit_txn(asset_params) + this.name: bytes = 'AST1' + asset_params: inner_transaction_fields_acfg = create_inner_transaction(Fee=0u, TypeEnum=acfg, ConfigAssetTotal=1000u, ConfigAssetName=this.name, ConfigAssetUnitName='unit', ConfigAssetDecimals=3u, ConfigAssetManager=global(), ConfigAssetReserve=global()) + this.name: bytes = 'AST2' + asset1_txn: inner_transaction_acfg = submit_txn(asset_params) update_inner_transaction(asset_params,ConfigAssetName=this.name) - asset2_txn: algopy.itxn.AssetConfigInnerTransaction = submit_txn(asset_params) + asset2_txn: inner_transaction_acfg = submit_txn(asset_params) assert(asset1_txn.ConfigAssetName == 'AST1', comment="asset1_txn is correct") assert(asset2_txn.ConfigAssetName == 'AST2', comment="asset2_txn is correct") assert(checked_maybe(asset_params_get(asset1_txn.CreatedAssetID)) == 'AST1', comment="created asset 1 is correct") assert(checked_maybe(asset_params_get(asset2_txn.CreatedAssetID)) == 'AST2', comment="created asset 2 is correct") - app_create_params: algopy.itxn.ApplicationCall = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">) + app_create_params: inner_transaction_fields_appl = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">) update_inner_transaction(asset_params,ConfigAssetName='AST3') - (app_create_txn, asset3_txn): tuple[algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.AssetConfigInnerTransaction] = submit_txn(app_create_params, asset_params) + (app_create_txn, asset3_txn): tuple = submit_txn(app_create_params, asset_params) assert(reinterpret_cast(app_create_txn.CreatedApplicationID), comment="created app") assert(asset3_txn.ConfigAssetName == 'AST3', comment="asset3_txn is correct") update_inner_transaction(app_create_params,Note='3rd') @@ -60,58 +60,58 @@ contract MyContract submit_txn(app_create_params, asset_params) } - subroutine test2(): None + subroutine test2(): void { if (reinterpret_cast(txn())) { - args: tuple[algopy.Bytes, algopy.Bytes] = ('1', '2') - create_app_params: algopy.itxn.ApplicationCall = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, ApplicationArgs=args, OnCompletion=NoOp, Note='with args param set') + args: tuple = ('1', '2') + create_app_params: inner_transaction_fields_appl = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, ApplicationArgs=args, OnCompletion=NoOp, Note='with args param set') } else { - create_app_params: algopy.itxn.ApplicationCall = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, ApplicationArgs=('3', '4', '5'), Note='no args param set') + create_app_params: inner_transaction_fields_appl = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, ApplicationArgs=('3', '4', '5'), Note='no args param set') } - create_app_txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_app_params) + create_app_txn: inner_transaction_appl = submit_txn(create_app_params) assert(create_app_txn.ApplicationArgs[0u] == '1', comment="correct args used 1") assert(create_app_txn.ApplicationArgs[1u] == '2', comment="correct args used 2") if (txn() > 1u) { - create_app_txn2: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('42'))) + create_app_txn2: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('42'))) assert(create_app_txn2.ApplicationArgs[0u] == '42', comment="correct args used 2") assert(create_app_txn.Note == 'with args param set') } } - subroutine test3(): None + subroutine test3(): void { - app_p_1: algopy.itxn.ApplicationCall = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"09361A00B08101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('1')) - app_p_2: algopy.itxn.ApplicationCall = app_p_1.copy().copy() + app_p_1: inner_transaction_fields_appl = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"09361A00B08101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('1')) + app_p_2: inner_transaction_fields_appl = app_p_1.copy().copy() update_inner_transaction(app_p_2,ApplicationArgs=('2')) - app_p_3: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_3: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_3,ApplicationArgs=('3')) - app_p_4: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_4: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_4,ApplicationArgs=('4')) - app_p_5: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_5: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_5,ApplicationArgs=('5')) - app_p_6: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_6: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_6,ApplicationArgs=('6')) - app_p_7: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_7: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_7,ApplicationArgs=('7')) - app_p_8: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_8: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_8,ApplicationArgs=('8')) - app_p_9: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_9: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_9,ApplicationArgs=('9')) - app_p_10: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_10: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_10,ApplicationArgs=('10')) - app_p_11: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_11: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_11,ApplicationArgs=('11')) - app_p_12: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_12: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_12,ApplicationArgs=('12')) - app_p_13: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_13: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_13,ApplicationArgs=('13')) - app_p_14: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_14: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_14,ApplicationArgs=('14')) - app_p_15: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_15: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_15,ApplicationArgs=('15')) - app_p_16: algopy.itxn.ApplicationCall = app_p_1.copy() + app_p_16: inner_transaction_fields_appl = app_p_1.copy() update_inner_transaction(app_p_16,ApplicationArgs=('16')) - (app1, app2, app3, app4, app5, app6, app7, app8, app9, app10, app11, app12, app13, app14, app15, app16): tuple[algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction] = submit_txn(app_p_1, app_p_2, app_p_3, app_p_4, app_p_5, app_p_6, app_p_7, app_p_8, app_p_9, app_p_10, app_p_11, app_p_12, app_p_13, app_p_14, app_p_15, app_p_16) + (app1, app2, app3, app4, app5, app6, app7, app8, app9, app10, app11, app12, app13, app14, app15, app16): tuple = submit_txn(app_p_1, app_p_2, app_p_3, app_p_4, app_p_5, app_p_6, app_p_7, app_p_8, app_p_9, app_p_10, app_p_11, app_p_12, app_p_13, app_p_14, app_p_15, app_p_16) assert(app1.Logs[0u] == '1') assert(app2.Logs[0u] == '2') assert(app3.Logs[0u] == '3') @@ -130,13 +130,13 @@ contract MyContract assert(app16.Logs[0u] == '16') } - subroutine test4(): None + subroutine test4(): void { - lots_of_bytes: algopy.Bytes = bzero(2044u) - approval_1: algopy.Bytes = hex<"098101"> - approval_2: algopy.Bytes = hex<"80FC0F"> + lots_of_bytes + 'H' - app_p_1: algopy.itxn.ApplicationCall = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=(approval_1, approval_2, approval_2, approval_2), ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('1'), ExtraProgramPages=3u) - app_1: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(app_p_1) + lots_of_bytes: bytes = bzero(2044u) + approval_1: bytes = hex<"098101"> + approval_2: bytes = hex<"80FC0F"> + lots_of_bytes + 'H' + app_p_1: inner_transaction_fields_appl = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=(approval_1, approval_2, approval_2, approval_2), ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('1'), ExtraProgramPages=3u) + app_1: inner_transaction_appl = submit_txn(app_p_1) assert(app_1.ExtraProgramPages == 3u, comment="extra_pages == 3") assert(app_1.NumApprovalProgramPages == 2u, comment="approval_pages == 2") assert(app_1.ApprovalProgramPages[0u] == approval_1 + approval_2 + approval_2[:-3], comment="expected approval page 0") @@ -146,7 +146,7 @@ contract MyContract } } -subroutine echo(v: algopy.Bytes): algopy.Bytes +subroutine echo(v: bytes): bytes { return v } \ No newline at end of file diff --git a/test_cases/inner_transactions/out/field_tuple_assignment.awst b/test_cases/inner_transactions/out/field_tuple_assignment.awst index 8ea89d6c1..1ba5e17b7 100644 --- a/test_cases/inner_transactions/out/field_tuple_assignment.awst +++ b/test_cases/inner_transactions/out/field_tuple_assignment.awst @@ -3,10 +3,10 @@ ALWAYS_APPROVE = b'\t\x81\x01' contract FieldTupleContract { - abimethod test_assign_tuple(): None + abimethod test_assign_tuple(): void { - create_txns: tuple[algopy.itxn.ApplicationCall, algopy.itxn.ApplicationCall] = (create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('1a', '2a')), create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('3a', '4a', '5a'), Note='different param set')) - (txn_1, txn_2): tuple[algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction] = submit_txn(create_txns[0], create_txns[1]) + create_txns: tuple = (create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('1a', '2a')), create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('3a', '4a', '5a'), Note='different param set')) + (txn_1, txn_2): tuple = submit_txn(create_txns[0], create_txns[1]) assert(txn_1.ApplicationArgs[0u] == '1a') assert(txn_1.ApplicationArgs[1u] == '2a') assert(txn_2.ApplicationArgs[0u] == '3a') @@ -14,7 +14,7 @@ contract FieldTupleContract assert(txn_2.ApplicationArgs[2u] == '5a') update_inner_transaction(create_txns[0],ApplicationArgs=('1b', '2b')) update_inner_transaction(create_txns[1],ApplicationArgs=('3b', '4b', '5b')) - (txn_1, txn_2): tuple[algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction] = submit_txn(create_txns[1], create_txns[0]) + (txn_1, txn_2): tuple = submit_txn(create_txns[1], create_txns[0]) assert(txn_2.ApplicationArgs[0u] == '1b') assert(txn_2.ApplicationArgs[1u] == '2b') assert(txn_1.ApplicationArgs[0u] == '3b') @@ -22,7 +22,7 @@ contract FieldTupleContract assert(txn_1.ApplicationArgs[2u] == '5b') update_inner_transaction(create_txns[0],ApplicationArgs=('1c', '2c')) update_inner_transaction(create_txns[1],ApplicationArgs=('3c', '4c', '5c')) - txn_tuple: tuple[algopy.itxn.ApplicationCallInnerTransaction, algopy.itxn.ApplicationCallInnerTransaction] = submit_txn(create_txns[0], create_txns[1]) + txn_tuple: tuple = submit_txn(create_txns[0], create_txns[1]) assert(txn_tuple[0].ApplicationArgs[0u] == '1c') assert(txn_tuple[0].ApplicationArgs[1u] == '2c') assert(txn_tuple[1].ApplicationArgs[0u] == '3c') @@ -30,10 +30,10 @@ contract FieldTupleContract assert(txn_tuple[1].ApplicationArgs[2u] == '5c') } - abimethod test_assign_tuple_mixed(): None + abimethod test_assign_tuple_mixed(): void { - tuple_with_txn_fields: tuple[algopy.itxn.ApplicationCall, algopy.Bytes] = (create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('1a', '2a')), 'some other value') - result_with_txn: tuple[algopy.itxn.ApplicationCallInnerTransaction, algopy.Bytes] = (submit_txn(tuple_with_txn_fields[0]), tuple_with_txn_fields[1]) + tuple_with_txn_fields: tuple = (create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"098101">, ClearStateProgramPages=hex<"098101">, OnCompletion=DeleteApplication, ApplicationArgs=('1a', '2a')), 'some other value') + result_with_txn: tuple = (submit_txn(tuple_with_txn_fields[0]), tuple_with_txn_fields[1]) assert(result_with_txn[0].ApplicationArgs[0u] == '1a') assert(result_with_txn[0].ApplicationArgs[1u] == '2a') assert(result_with_txn[1] == 'some other value') diff --git a/test_cases/inner_transactions/out/itxn_loop.awst b/test_cases/inner_transactions/out/itxn_loop.awst index 776e6d960..c7c21c8eb 100644 --- a/test_cases/inner_transactions/out/itxn_loop.awst +++ b/test_cases/inner_transactions/out/itxn_loop.awst @@ -2,10 +2,10 @@ contract MyContract { approval_program(): bool { - note: algopy.Bytes = 'ABCDE' - app_params: algopy.itxn.ApplicationCall = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"0A8101">, ClearStateProgramPages=hex<"0A8101">, OnCompletion=DeleteApplication, Note='') + note: bytes = 'ABCDE' + app_params: inner_transaction_fields_appl = create_inner_transaction(Fee=0u, TypeEnum=appl, ApprovalProgramPages=hex<"0A8101">, ClearStateProgramPages=hex<"0A8101">, OnCompletion=DeleteApplication, Note='') for i in range(0u, 4u, 1u) { - i_note: algopy.Bytes = extract3(note, 0u, i) + i_note: bytes = extract3(note, 0u, i) switch (i) { case 1u: { update_inner_transaction(app_params,Note=i_note, ApplicationArgs=('1')) @@ -17,7 +17,7 @@ contract MyContract update_inner_transaction(app_params,Note=i_note, ApplicationArgs=('3', '2', '1')) } } - app_txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(app_params) + app_txn: inner_transaction_appl = submit_txn(app_params) log(app_txn.Note) log(itob(app_txn.NumAppArgs)) } diff --git a/test_cases/intrinsics/out/Overloaded.approval.mir b/test_cases/intrinsics/out/Overloaded.approval.mir index 14bc0c368..f7a918ab1 100644 --- a/test_cases/intrinsics/out/Overloaded.approval.mir +++ b/test_cases/intrinsics/out/Overloaded.approval.mir @@ -27,12 +27,12 @@ main_entrypoint@2: // virtual: store tmp%2#0 to l-stack (no copy) tmp%2#0 op.AppGlobal.get_uint64(b"key") == op.AppGlobal.get_uint64(b"key") intrinsics/overloaded.py:9 // virtual: load tmp%2#0 from l-stack (no copy) tmp%2#0 assert op.AppGlobal.get_uint64(b"key") == op.AppGlobal.get_uint64(b"key") intrinsics/overloaded.py:9 assert // assert op.AppGlobal.get_uint64(b"key") == op.AppGlobal.get_uint64(b"key") intrinsics/overloaded.py:9 - int 0 // 0 self.key intrinsics/overloaded.py:10 + int 0 // 0 self.key.maybe intrinsics/overloaded.py:10 byte "key" // 0,"key" self.key intrinsics/overloaded.py:6 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.key.maybe() intrinsics/overloaded.py:10 pop // {app_global_get_ex}.0 self.key.maybe() intrinsics/overloaded.py:10 // virtual: store tmp%3#0 to l-stack (no copy) tmp%3#0 self.key.maybe() intrinsics/overloaded.py:10 - int 0 // tmp%3#0,0 self.key intrinsics/overloaded.py:10 + int 0 // tmp%3#0,0 self.key.maybe intrinsics/overloaded.py:10 byte "key" // tmp%3#0,0,"key" self.key intrinsics/overloaded.py:6 app_global_get_ex // tmp%3#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.key.maybe() intrinsics/overloaded.py:10 pop // tmp%3#0,{app_global_get_ex}.0 self.key.maybe() intrinsics/overloaded.py:10 diff --git a/test_cases/intrinsics/out/immediate_variants.awst b/test_cases/intrinsics/out/immediate_variants.awst index 006583e69..d9364e981 100644 --- a/test_cases/intrinsics/out/immediate_variants.awst +++ b/test_cases/intrinsics/out/immediate_variants.awst @@ -2,10 +2,10 @@ contract ImmediateVariants { approval_program(): bool { - num_app_args: algopy.UInt64 = txn() + num_app_args: uint64 = txn() assert(gtxn<0, NumAppArgs>() == num_app_args) assert(gtxns(0u) == num_app_args) - first_arg: algopy.Bytes = txna() + first_arg: bytes = txna() assert(txnas(0u) == first_arg) assert(gtxna<0, ApplicationArgs, 0>() == first_arg) assert(gtxnas<0, ApplicationArgs>(0u) == first_arg) @@ -19,7 +19,7 @@ contract ImmediateVariants itxn_field(0u) itxn_field(0u) itxn_field(first_arg) - second_arg: algopy.Bytes = first_arg + '2' + second_arg: bytes = first_arg + '2' itxn_field(second_arg) itxn_submit() assert(itxn() == 2u) diff --git a/test_cases/intrinsics/out/overloaded.awst b/test_cases/intrinsics/out/overloaded.awst index e4d6066fc..4ac5e4ab0 100644 --- a/test_cases/intrinsics/out/overloaded.awst +++ b/test_cases/intrinsics/out/overloaded.awst @@ -1,12 +1,12 @@ contract Overloaded { globals { - ['key']: algopy.UInt64 + ['key']: uint64 } constructor() { - this.key: algopy.UInt64 = 0u + this.key: uint64 = 0u } approval_program(): bool diff --git a/test_cases/koopman/out/contract.awst b/test_cases/koopman/out/contract.awst index 80677e0e5..b021910f3 100644 --- a/test_cases/koopman/out/contract.awst +++ b/test_cases/koopman/out/contract.awst @@ -1,16 +1,16 @@ contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - a: algopy.UInt64 = 75u - c: algopy.UInt64 = 77u - b: algopy.UInt64 = a + c - a: algopy.UInt64 = b + 5u - c: algopy.UInt64 = b + a + a: uint64 = 75u + c: uint64 = 77u + b: uint64 = a + c + a: uint64 = b + 5u + c: uint64 = b + a return c } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { return 1u } diff --git a/test_cases/less_simple/out/contract.awst b/test_cases/less_simple/out/contract.awst index 09ac343bb..2a0628b00 100644 --- a/test_cases/less_simple/out/contract.awst +++ b/test_cases/less_simple/out/contract.awst @@ -1,10 +1,10 @@ contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - a: algopy.UInt64 = 1u - sum_of_evens: algopy.UInt64 = 0u - product_of_odds: algopy.UInt64 = 0u + a: uint64 = 1u + sum_of_evens: uint64 = 0u + product_of_odds: uint64 = 0u while (a < 100u) { if (a % 5u == 0u) { continue @@ -16,7 +16,7 @@ contract MyContract sum_of_evens += a } else { if (product_of_odds == 0u) { - product_of_odds: algopy.UInt64 = a + product_of_odds: uint64 = a } else { product_of_odds *= a } @@ -26,11 +26,11 @@ contract MyContract return product_of_odds - sum_of_evens } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { - sum_of_squares: algopy.UInt64 = 0u + sum_of_squares: uint64 = 0u for i in range(1u, 100u, 1u) { - square_root: algopy.UInt64 = sqrt(i) + square_root: uint64 = sqrt(i) if (square_root * square_root == i) { sum_of_squares += i } diff --git a/test_cases/logic_signature/out/signature.awst b/test_cases/logic_signature/out/signature.awst index 6cbf217dd..e6827a74a 100644 --- a/test_cases/logic_signature/out/signature.awst +++ b/test_cases/logic_signature/out/signature.awst @@ -1,7 +1,7 @@ logicsig pre_approved_sale { - pay_txn: algopy.gtxn.PaymentTransaction = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=0, source=0u), gtxns(SINGLE_EVAL(id=0, source=0u)) == pay))) - asset_txn: algopy.gtxn.AssetTransferTransaction = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=1, source=1u), gtxns(SINGLE_EVAL(id=1, source=1u)) == axfer))) + pay_txn: group_transaction_pay = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=0, source=0u), gtxns(SINGLE_EVAL(id=0, source=0u)) == pay))) + asset_txn: group_transaction_axfer = reinterpret_cast(checked_maybe((SINGLE_EVAL(id=1, source=1u), gtxns(SINGLE_EVAL(id=1, source=1u)) == axfer))) test_cases.logic_signature.signature::assert_correct_payment(pay_txn) test_cases.logic_signature.signature::assert_correct_asset(asset_txn) assert(gtxns(pay_txn) == gtxns(asset_txn)) @@ -14,12 +14,12 @@ logicsig always_allow return true } -subroutine assert_correct_payment(txn: algopy.gtxn.PaymentTransaction): None +subroutine assert_correct_payment(txn: group_transaction_pay): void { - assert(gtxns(txn) == TemplateVar[algopy.Account](TMPL_SELLER) and gtxns(txn) == TemplateVar[algopy.UInt64](TMPL_PRICE)) + assert(gtxns(txn) == TemplateVar[account](TMPL_SELLER) and gtxns(txn) == TemplateVar[uint64](TMPL_PRICE)) } -subroutine assert_correct_asset(txn: algopy.gtxn.AssetTransferTransaction): None +subroutine assert_correct_asset(txn: group_transaction_axfer): void { - assert(gtxns(txn) == 1u and gtxns(txn) == TemplateVar[algopy.Account](TMPL_SELLER) and gtxns(txn) == TemplateVar[algopy.Asset](TMPL_ASSET_ID) and gtxns(txn) == global() and gtxns(txn) == global()) + assert(gtxns(txn) == 1u and gtxns(txn) == TemplateVar[account](TMPL_SELLER) and gtxns(txn) == TemplateVar[asset](TMPL_ASSET_ID) and gtxns(txn) == global() and gtxns(txn) == global()) } \ No newline at end of file diff --git a/test_cases/match/out/contract.awst b/test_cases/match/out/contract.awst index 1045b340d..838783278 100644 --- a/test_cases/match/out/contract.awst +++ b/test_cases/match/out/contract.awst @@ -1,14 +1,14 @@ contract MyContract { globals { - ['case_one']: algopy.UInt64 - ['case_two']: algopy.UInt64 + ['case_one']: uint64 + ['case_two']: uint64 } approval_program(): bool { - this.case_one: algopy.UInt64 = 1u - this.case_two: algopy.UInt64 = 2u + this.case_one: uint64 = 1u + this.case_two: uint64 = 2u this::match_uint64() this::match_biguint() this::match_bytes() @@ -23,95 +23,95 @@ contract MyContract return true } - subroutine match_uint64(): None + subroutine match_uint64(): void { - n: algopy.UInt64 = txn() + n: uint64 = txn() switch (n) { case 0u: { - hello: algopy.Bytes = 'Hello' + hello: bytes = 'Hello' log(hello) } case 10u: { - hello: algopy.Bytes = 'Hello There' + hello: bytes = 'Hello There' log(hello) } } } - subroutine match_bytes(): None + subroutine match_bytes(): void { - n: algopy.Bytes = txna() + n: bytes = txna() switch (n) { case '': { - hello: algopy.Bytes = 'Hello bytes' + hello: bytes = 'Hello bytes' log(hello) } case '10': { - hello: algopy.Bytes = 'Hello There bytes' + hello: bytes = 'Hello There bytes' log(hello) } } } - subroutine match_biguint(): None + subroutine match_biguint(): void { - n: algopy.BigUInt = itob(txn()) b* 10n + n: biguint = itob(txn()) b* 10n switch (n) { case 0n: { - hello: algopy.Bytes = 'Hello biguint' + hello: bytes = 'Hello biguint' log(hello) } case 10n: { - hello: algopy.Bytes = 'Hello There biguint' + hello: bytes = 'Hello There biguint' log(hello) } } } - subroutine match_address(): None + subroutine match_address(): void { - n: algopy.Account = txn() + n: account = txn() switch (n) { case Address("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ"): { - hello: algopy.Bytes = 'Hello address' + hello: bytes = 'Hello address' log(hello) } case Address("VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA"): { - hello: algopy.Bytes = 'Hello There address' + hello: bytes = 'Hello There address' log(hello) } } } - subroutine match_attributes(): None + subroutine match_attributes(): void { - n: algopy.UInt64 = txn() + n: uint64 = txn() switch (n) { case this.case_one: { - hello: algopy.Bytes = 'Hello one' + hello: bytes = 'Hello one' log(hello) } case this.case_two: { - hello: algopy.Bytes = 'Hello two' + hello: bytes = 'Hello two' log(hello) } case _: { - hello: algopy.Bytes = 'Hello default' + hello: bytes = 'Hello default' log(hello) } } } - subroutine match_bools(): None + subroutine match_bools(): void { n: bool = txn() > 0u switch (n) { case true: { - hello: algopy.Bytes = 'Hello True' + hello: bytes = 'Hello True' log(hello) } case false: { - hello: algopy.Bytes = 'Hello False' + hello: bytes = 'Hello False' log(hello) } } diff --git a/test_cases/mylib/out/simple_functions.awst b/test_cases/mylib/out/simple_functions.awst index a5e5875b5..8e8701cd7 100644 --- a/test_cases/mylib/out/simple_functions.awst +++ b/test_cases/mylib/out/simple_functions.awst @@ -1,75 +1,75 @@ ONE = 1 HELLO = b'\xf0\x9f\x91\x8b' -subroutine three(): algopy.UInt64 +subroutine three(): uint64 { - a: algopy.UInt64 = 1u + 1u - b: algopy.UInt64 = a + 1u + a: uint64 = 1u + 1u + b: uint64 = a + 1u return b } -subroutine hello_world(): algopy.Bytes +subroutine hello_world(): bytes { - hello: algopy.Bytes = '\xf0\x9f\x91\x8b' - comma: algopy.Bytes = b64<"4aCI"> - world: algopy.Bytes = ' world' + hello: bytes = '\xf0\x9f\x91\x8b' + comma: bytes = b64<"4aCI"> + world: bytes = ' world' return hello + comma + world } -subroutine safe_add(x: algopy.UInt64, y: algopy.UInt64): tuple[algopy.UInt64, bool] +subroutine safe_add(x: uint64, y: uint64): tuple { - (hi, lo): tuple[algopy.UInt64, algopy.UInt64] = addw(x, y) + (hi, lo): tuple = addw(x, y) did_overflow: bool = hi > 0u return (lo, did_overflow) } -subroutine safe_six(): tuple[algopy.UInt64, bool] +subroutine safe_six(): tuple { return test_cases.mylib.simple_functions::safe_add(test_cases.mylib.simple_functions::three(), test_cases.mylib.simple_functions::three()) } -subroutine itoa(i: algopy.UInt64): algopy.Bytes +subroutine itoa(i: uint64): bytes { - digits: algopy.Bytes = '0123456789' - radix: algopy.UInt64 = len(digits) + digits: bytes = '0123456789' + radix: uint64 = len(digits) if (i < radix) { return digits[i] } return test_cases.mylib.simple_functions::itoa(i // radix) + digits[i % radix] } -subroutine itoa_loop(num: algopy.UInt64): algopy.Bytes +subroutine itoa_loop(num: uint64): bytes { - digits: algopy.Bytes = '0123456789' - result: algopy.Bytes = '' + digits: bytes = '0123456789' + result: bytes = '' while (num >= 10u) { - result: algopy.Bytes = digits[num % 10u] + result + result: bytes = digits[num % 10u] + result num //= 10u } - result: algopy.Bytes = digits[num] + result + result: bytes = digits[num] + result return result } -subroutine inefficient_multiply(a: algopy.UInt64, b: algopy.UInt64): algopy.UInt64 +subroutine inefficient_multiply(a: uint64, b: uint64): uint64 { if (a == 0u or b == 0u) { return a } if (a < b) { - smaller: algopy.UInt64 = a - bigger: algopy.UInt64 = b + smaller: uint64 = a + bigger: uint64 = b } else { - smaller: algopy.UInt64 = b - bigger: algopy.UInt64 = a + smaller: uint64 = b + bigger: uint64 = a } - result: algopy.UInt64 = 0u + result: uint64 = 0u for _i in range(0u, smaller, 1u) { result += bigger } return result } -subroutine test_and_uint64(): algopy.UInt64 +subroutine test_and_uint64(): uint64 { return (!(reinterpret_cast(1u))) ? (1u) : (2u) } \ No newline at end of file diff --git a/test_cases/nested_loops/out/contract.awst b/test_cases/nested_loops/out/contract.awst index 49913e686..eda327e1b 100644 --- a/test_cases/nested_loops/out/contract.awst +++ b/test_cases/nested_loops/out/contract.awst @@ -2,10 +2,10 @@ LOOP_ITERATIONS = 2 contract Nested { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - n: algopy.UInt64 = 2u - x: algopy.UInt64 = 0u + n: uint64 = 2u + x: uint64 = 0u for a in range(0u, n, 1u) { for b in range(0u, n, 1u) { for c in range(0u, n, 1u) { @@ -21,7 +21,7 @@ contract Nested a += n } log(itob(x)) - y: algopy.UInt64 = 0u + y: uint64 = 0u for (index, item) in enumerate(range(0u, 10u, 1u)) { y += item * index } @@ -29,7 +29,7 @@ contract Nested return x } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { return 1u } diff --git a/test_cases/regression_118/out/client_Contract.py b/test_cases/regression_118/out/client_Contract.py index cbfb63c74..2617c4024 100644 --- a/test_cases/regression_118/out/client_Contract.py +++ b/test_cases/regression_118/out/client_Contract.py @@ -10,5 +10,5 @@ class Contract(algopy.arc4.ARC4Client, typing.Protocol): @algopy.arc4.abimethod def verify( self, - values: algopy.arc4.DynamicArray[algopy.arc4.UInt256], + values: algopy.arc4.DynamicArray[algopy.arc4.BigUIntN[typing.Literal[256]]], ) -> algopy.arc4.Tuple[algopy.arc4.Bool, algopy.arc4.String]: ... diff --git a/test_cases/regression_118/out/contract.awst b/test_cases/regression_118/out/contract.awst index 501c860a7..a2c269a71 100644 --- a/test_cases/regression_118/out/contract.awst +++ b/test_cases/regression_118/out/contract.awst @@ -1,11 +1,11 @@ contract Contract { - abimethod verify(values: algopy.arc4.DynamicArray[algopy.arc4.UInt256]): algopy.arc4.Tuple[algopy.arc4.Bool, algopy.arc4.String] + abimethod verify(values: arc4.dynamic_array): arc4.tuple { - val1: algopy.arc4.Bool = arc4_encode(reinterpret_cast(txn()), algopy.arc4.Bool) + val1: arc4.bool = arc4_encode(reinterpret_cast(txn()), arc4.bool) if (extract_uint16(values, 0u) != 2u) { - return arc4_encode((val1, arc4_encode('', algopy.arc4.String)), algopy.arc4.Tuple[algopy.arc4.Bool, algopy.arc4.String]) + return arc4_encode((val1, arc4_encode('', arc4.string)), arc4.tuple) } - return arc4_encode((val1, arc4_encode('', algopy.arc4.String)), algopy.arc4.Tuple[algopy.arc4.Bool, algopy.arc4.String]) + return arc4_encode((val1, arc4_encode('', arc4.string)), arc4.tuple) } } \ No newline at end of file diff --git a/test_cases/reinterpret_cast/out/contract.awst b/test_cases/reinterpret_cast/out/contract.awst index 526b67778..1e2322240 100644 --- a/test_cases/reinterpret_cast/out/contract.awst +++ b/test_cases/reinterpret_cast/out/contract.awst @@ -5,13 +5,13 @@ contract Contract return reinterpret_cast(len('')) } - abimethod test_bytes_to_biguint(): None + abimethod test_bytes_to_biguint(): void { assert(test_cases.reinterpret_cast.contract::bytes_to_biguint() != 0n) } } -subroutine bytes_to_biguint(): algopy.BigUInt +subroutine bytes_to_biguint(): biguint { - return reinterpret_cast('') + return reinterpret_cast('') } \ No newline at end of file diff --git a/test_cases/reversed_iteration/out/contract.awst b/test_cases/reversed_iteration/out/contract.awst index c2bb4cb94..d802f01f7 100644 --- a/test_cases/reversed_iteration/out/contract.awst +++ b/test_cases/reversed_iteration/out/contract.awst @@ -5,28 +5,28 @@ contract MyContract for i in reversed(range(0u, 0u, 1u)) { log(itob(i)) } - for x in reversed(new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[0]]()) { - log(reinterpret_cast(x)) + for x in reversed(new arc4.static_array()) { + log(reinterpret_cast(x)) } - test_array: algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]] = new algopy.arc4.StaticArray[algopy.arc4.UInt8, typing.Literal[4]](0arc4u8, 0arc4u8, 0arc4u8, 0arc4u8) + test_array: arc4.static_array = new arc4.static_array(0arc4u8, 0arc4u8, 0arc4u8, 0arc4u8) for (index, item) in enumerate(reversed(range(0u, 4u, 1u))) { - test_array[index]: algopy.arc4.UInt8 = arc4_encode(item, algopy.arc4.UInt8) + test_array[index]: arc4.uint8 = arc4_encode(item, arc4.uint8) } - assert(reinterpret_cast(test_array) == hex<"03020100">) + assert(reinterpret_cast(test_array) == hex<"03020100">) for (index, item) in reversed(enumerate(reversed(range(4u, 8u, 1u)))) { - test_array[index]: algopy.arc4.UInt8 = arc4_encode(item, algopy.arc4.UInt8) + test_array[index]: arc4.uint8 = arc4_encode(item, arc4.uint8) if (index == 2u) { break } } - assert(reinterpret_cast(test_array) == hex<"03020504">) - some_strings: algopy.arc4.StaticArray[algopy.arc4.String, typing.Literal[3]] = new algopy.arc4.StaticArray[algopy.arc4.String, typing.Literal[3]](arc4_encode('a', algopy.arc4.String), arc4_encode('b', algopy.arc4.String), arc4_encode('c', algopy.arc4.String)) - some_string_reversed: algopy.arc4.String = arc4_encode('', algopy.arc4.String) + assert(reinterpret_cast(test_array) == hex<"03020504">) + some_strings: arc4.static_array = new arc4.static_array(arc4_encode('a', arc4.string), arc4_encode('b', arc4.string), arc4_encode('c', arc4.string)) + some_string_reversed: arc4.string = arc4_encode('', arc4.string) for str_item in reversed(some_strings) { some_string_reversed.extend(str_item) } - assert(reinterpret_cast(some_string_reversed) == reinterpret_cast(arc4_encode('cba', algopy.arc4.String))) - bytes_reversed_with_index: algopy.Bytes = '' + assert(reinterpret_cast(some_string_reversed) == reinterpret_cast(arc4_encode('cba', arc4.string))) + bytes_reversed_with_index: bytes = '' for (index, bytes_item) in reversed(enumerate('HELLO')) { bytes_reversed_with_index += itob(index)[-1:] + bytes_item } @@ -34,14 +34,14 @@ contract MyContract for (index, tuple_item) in enumerate(reversed((0u, 1u, 2u, 3u))) { assert(index + tuple_item == 3u) } - prev_item: algopy.UInt64 = 0u - prev_index: algopy.UInt64 = 99u + prev_item: uint64 = 0u + prev_index: uint64 = 99u for (index, tuple_item) in reversed(enumerate(reversed((5u, 6u, 7u, 8u)))) { assert(prev_item < tuple_item) assert(prev_index > index) assert(index + tuple_item == 8u) - prev_item: algopy.UInt64 = tuple_item - prev_index: algopy.UInt64 = index + prev_item: uint64 = tuple_item + prev_index: uint64 = index } return true } diff --git a/test_cases/scratch_slots/out/contract2.awst b/test_cases/scratch_slots/out/contract2.awst index b11213538..0a4b7165c 100644 --- a/test_cases/scratch_slots/out/contract2.awst +++ b/test_cases/scratch_slots/out/contract2.awst @@ -4,7 +4,7 @@ contract MyContract2 extends (test_cases.scratch_slots.contract::MyContract) 1..19, 25, 50, 52, 100..104, 110..114 } - subroutine my_sub(): None + subroutine my_sub(): void { stores(1u, 'abc') stores(52u, '52') diff --git a/test_cases/simple/out/contract.awst b/test_cases/simple/out/contract.awst index 556a0ea59..2ca87c2d3 100644 --- a/test_cases/simple/out/contract.awst +++ b/test_cases/simple/out/contract.awst @@ -1,15 +1,15 @@ contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - a: algopy.UInt64 = 1u + 2u - b: algopy.UInt64 = 4u * 5u + a: uint64 = 1u + 2u + b: uint64 = 4u * 5u if (a == 3u) { if (b < 2u) { - b: algopy.UInt64 = 3u + 2u + b: uint64 = 3u + 2u return a + b } else { - b: algopy.UInt64 = 2u * a + b: uint64 = 2u * a if (reinterpret_cast(14u * b)) { return 2u } else { @@ -21,7 +21,7 @@ contract MyContract } } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { assert(txn() == 0u) return test_cases.simple.subs::zero() * test_cases.simple.pkg_a.pkg_1.subs::one() diff --git a/test_cases/simple/out/pkg_a/pkg_1/subs.awst b/test_cases/simple/out/pkg_a/pkg_1/subs.awst index 0d557b298..6d015f4be 100644 --- a/test_cases/simple/out/pkg_a/pkg_1/subs.awst +++ b/test_cases/simple/out/pkg_a/pkg_1/subs.awst @@ -1,4 +1,4 @@ -subroutine one(): algopy.UInt64 +subroutine one(): uint64 { return 1u } \ No newline at end of file diff --git a/test_cases/simple/out/subs.awst b/test_cases/simple/out/subs.awst index a4655ea31..7eca2e2cb 100644 --- a/test_cases/simple/out/subs.awst +++ b/test_cases/simple/out/subs.awst @@ -1,4 +1,4 @@ -subroutine zero(): algopy.UInt64 +subroutine zero(): uint64 { return 0u } \ No newline at end of file diff --git a/test_cases/simplish/out/base_class.awst b/test_cases/simplish/out/base_class.awst index 799e0d101..4e2b2768e 100644 --- a/test_cases/simplish/out/base_class.awst +++ b/test_cases/simplish/out/base_class.awst @@ -1,24 +1,24 @@ abstract contract CallCounter { globals { - ['counter']: algopy.UInt64 + ['counter']: uint64 } locals { - ['name']: algopy.Bytes + ['name']: bytes } constructor() { - this.counter: algopy.UInt64 = 0u + this.counter: uint64 = 0u } - subroutine increment_counter(): None + subroutine increment_counter(): void { this.counter += 1u } - subroutine set_sender_nickname(nickname: algopy.Bytes): None + subroutine set_sender_nickname(nickname: bytes): void { - this.name[0u]: algopy.Bytes = nickname + this.name[0u]: bytes = nickname } } \ No newline at end of file diff --git a/test_cases/simplish/out/contract.awst b/test_cases/simplish/out/contract.awst index 5c50af86b..0f96d9aff 100644 --- a/test_cases/simplish/out/contract.awst +++ b/test_cases/simplish/out/contract.awst @@ -5,11 +5,11 @@ contract Simplish extends (test_cases.simplish.base_class::CallCounter) { approval_program(): bool { - if (txn() == reinterpret_cast(0u)) { + if (txn() == reinterpret_cast(0u)) { return true } - oca: algopy.UInt64 = txn() - sender: algopy.Account = txn() + oca: uint64 = txn() + sender: account = txn() if (oca IS IN (UpdateApplication, DeleteApplication)) { if (oca == DeleteApplication) { log('I was used ' + test_cases.simplish.contract::itoa(this.counter) + ' time(s) before I died') @@ -25,20 +25,20 @@ contract Simplish extends (test_cases.simplish.base_class::CallCounter) if (oca != NoOp) { return false } - if (num_app_args: algopy.UInt64 := txn() > 0u) { - method_name: algopy.Bytes = txna() - (msg, result): tuple[algopy.Bytes, bool] = this::call(method_name, num_app_args) + if (num_app_args: uint64 := txn() > 0u) { + method_name: bytes = txna() + (msg, result): tuple = this::call(method_name, num_app_args) } else { if (txn() == 1u) { - (asset_balance, asset_exists): tuple[algopy.UInt64, bool] = asset_holding_get(sender, reinterpret_cast(0u)) + (asset_balance, asset_exists): tuple = asset_holding_get(sender, reinterpret_cast(0u)) if (!(asset_exists)) { - msg: algopy.Bytes = 'You do not have any of the asset' + msg: bytes = 'You do not have any of the asset' } else { - msg: algopy.Bytes = 'You have asset balance: ' + test_cases.simplish.contract::itoa(asset_balance) + msg: bytes = 'You have asset balance: ' + test_cases.simplish.contract::itoa(asset_balance) } result: bool = true } else { - msg: algopy.Bytes = 'not enough app args or foreign assets' + msg: bytes = 'not enough app args or foreign assets' result: bool = false } } @@ -52,74 +52,74 @@ contract Simplish extends (test_cases.simplish.base_class::CallCounter) return true } - subroutine call(method_name: algopy.Bytes, num_app_args: algopy.UInt64): tuple[algopy.Bytes, bool] + subroutine call(method_name: bytes, num_app_args: uint64): tuple { assert(num_app_args == 2u, comment="insufficient arguments") - radius: algopy.UInt64 = btoi(txna()) + radius: uint64 = btoi(txna()) status: bool = true if (method_name == 'circle_area') { - area: algopy.UInt64 = test_cases.simplish.contract::circle_area(radius) - result: algopy.Bytes = test_cases.simplish.contract::itoa(area) + area: uint64 = test_cases.simplish.contract::circle_area(radius) + result: bytes = test_cases.simplish.contract::itoa(area) } else { if (method_name == 'circle_circumference') { - circumference: algopy.UInt64 = test_cases.simplish.contract::circle_circumference(radius) - result: algopy.Bytes = test_cases.simplish.contract::itoa(circumference) + circumference: uint64 = test_cases.simplish.contract::circle_circumference(radius) + result: bytes = test_cases.simplish.contract::itoa(circumference) } else { if (method_name == 'circle_report') { - (area, circumference): tuple[algopy.UInt64, algopy.UInt64] = (test_cases.simplish.contract::circle_area(radius), test_cases.simplish.contract::circle_circumference(radius)) - result: algopy.Bytes = 'Approximate area and circumference of circle with radius ' + test_cases.simplish.contract::itoa(radius) + ' = ' + test_cases.simplish.contract::itoa(area) + ', ' + test_cases.simplish.contract::itoa(circumference) + (area, circumference): tuple = (test_cases.simplish.contract::circle_area(radius), test_cases.simplish.contract::circle_circumference(radius)) + result: bytes = 'Approximate area and circumference of circle with radius ' + test_cases.simplish.contract::itoa(radius) + ' = ' + test_cases.simplish.contract::itoa(area) + ', ' + test_cases.simplish.contract::itoa(circumference) } else { status: bool = false - result: algopy.Bytes = 'unknown method name' + result: bytes = 'unknown method name' } } } return (result, status) } - subroutine increment_counter(): None + subroutine increment_counter(): void { log('Incrementing counter!') test_cases.simplish.base_class::CallCounter::increment_counter() } } -subroutine circle_circumference(radius: algopy.UInt64): algopy.UInt64 +subroutine circle_circumference(radius: uint64): uint64 { - two_pi: algopy.UInt64 = 2u * 314159u + two_pi: uint64 = 2u * 314159u return radius * two_pi // 100000u } -subroutine circle_area(radius: algopy.UInt64): algopy.UInt64 +subroutine circle_area(radius: uint64): uint64 { - result: algopy.UInt64 = radius ** 2u * 314159u // 100000u + result: uint64 = radius ** 2u * 314159u // 100000u return result } -subroutine itoa(i: algopy.UInt64): algopy.Bytes +subroutine itoa(i: uint64): bytes { - digits: algopy.Bytes = '0123456789' - radix: algopy.UInt64 = len(digits) + digits: bytes = '0123456789' + radix: uint64 = len(digits) if (i < radix) { return digits[i] } return test_cases.simplish.contract::itoa(i // radix) + digits[i % radix] } -subroutine test_intrinsics(): algopy.UInt64 +subroutine test_intrinsics(): uint64 { - _ii: algopy.Bytes = gload<1, 1>() - _si: algopy.Bytes = gloads<2>(2u) - _ss: algopy.Bytes = gloadss(3u, 3u) - _is: algopy.Bytes = gloadss(4u, 4u) - _foo_uint: algopy.UInt64 = setbit(32u, 0u, 3u) - _foo_int: algopy.UInt64 = setbit(32u, 0u, 3u) - _foo_bytes: algopy.Bytes = setbit('32', 0u, 3u) - test: algopy.Bytes = app_global_get('foo') + _ii: bytes = gload<1, 1>() + _si: bytes = gloads<2>(2u) + _ss: bytes = gloadss(3u, 3u) + _is: bytes = gloadss(4u, 4u) + _foo_uint: uint64 = setbit(32u, 0u, 3u) + _foo_int: uint64 = setbit(32u, 0u, 3u) + _foo_bytes: bytes = setbit('32', 0u, 3u) + test: bytes = app_global_get('foo') app_global_put('b', 'yeah') app_global_del('foo') - _expect_bytes: algopy.Bytes = test - _abcd: tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64] = divmodw(1u, 2u, 3u, 4u) - _hello_str: algopy.Bytes = base64_decode('SGVsbG8=') + _expect_bytes: bytes = test + _abcd: tuple = divmodw(1u, 2u, 3u, 4u) + _hello_str: bytes = base64_decode('SGVsbG8=') return 0u } \ No newline at end of file diff --git a/test_cases/ssa/out/contract.awst b/test_cases/ssa/out/contract.awst index 650266ec9..aeba5841d 100644 --- a/test_cases/ssa/out/contract.awst +++ b/test_cases/ssa/out/contract.awst @@ -1,72 +1,72 @@ contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - a: algopy.UInt64 = 1u + 2u - b: algopy.UInt64 = 4u * 5u - a: algopy.UInt64 = a * b - b: algopy.UInt64 = a + b + a: uint64 = 1u + 2u + b: uint64 = 4u * 5u + a: uint64 = a * b + b: uint64 = a + b while (a < 5u) { - b: algopy.UInt64 = b + a - a: algopy.UInt64 = a + 1u + b: uint64 = b + a + a: uint64 = a + 1u } for i in range(0u, 5u, 1u) { - b: algopy.UInt64 = b + a - a: algopy.UInt64 = a + i + b: uint64 = b + a + a: uint64 = a + i } if (a < b) { if (b < 2u) { - b: algopy.UInt64 = 3u + 2u - c: algopy.UInt64 = a + b + b: uint64 = 3u + 2u + c: uint64 = a + b } else { - b: algopy.UInt64 = 2u * a + b: uint64 = 2u * a if (reinterpret_cast(14u * b)) { - c: algopy.UInt64 = 2u + c: uint64 = 2u } else { return 3u } } } else { if (b == a) { - c: algopy.UInt64 = a * b + c: uint64 = a * b } else { - c: algopy.UInt64 = a - b + c: uint64 = a - b } } - c: algopy.UInt64 = c + test_cases.ssa.contract::one_hundred(c) - c_bytes: algopy.Bytes = itob(c) + c: uint64 = c + test_cases.ssa.contract::one_hundred(c) + c_bytes: bytes = itob(c) log(c_bytes) assert(test_cases.ssa.contract::phi_in_equiv_class(3u, true) == 4u) assert(test_cases.ssa.contract::phi_in_equiv_class(3u, false) == 4u) return c } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { return test_cases.ssa.contract::one_hundred(40u) } } -subroutine one_hundred(c: algopy.UInt64): algopy.UInt64 +subroutine one_hundred(c: uint64): uint64 { - a: algopy.UInt64 = 25u - b: algopy.UInt64 = 2u + a: uint64 = 25u + b: uint64 = 2u if (a < c) { - b: algopy.UInt64 = 1u - a: algopy.UInt64 = 100u + b: uint64 = 1u + a: uint64 = 100u } b *= b return a * b } -subroutine phi_in_equiv_class(y: algopy.UInt64, b: bool): algopy.UInt64 +subroutine phi_in_equiv_class(y: uint64, b: bool): uint64 { if (b) { - tmp1: algopy.UInt64 = y - x: algopy.UInt64 = tmp1 + tmp1: uint64 = y + x: uint64 = tmp1 } else { - tmp2: algopy.UInt64 = y - x: algopy.UInt64 = tmp2 + tmp2: uint64 = y + x: uint64 = tmp2 } x += 1u return x diff --git a/test_cases/ssa2/out/contract.awst b/test_cases/ssa2/out/contract.awst index 74b10013d..23c280aa1 100644 --- a/test_cases/ssa2/out/contract.awst +++ b/test_cases/ssa2/out/contract.awst @@ -1,29 +1,29 @@ contract MyContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - a: algopy.UInt64 = 1u + 2u - b: algopy.UInt64 = 4u * 5u + a: uint64 = 1u + 2u + b: uint64 = 4u * 5u for i in range(0u, 5u, 1u) { - b: algopy.UInt64 = b + a - a: algopy.UInt64 = a + i + b: uint64 = b + a + a: uint64 = a + i } return a + b } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { return test_cases.ssa2.contract::one_hundred(40u) } } -subroutine one_hundred(c: algopy.UInt64): algopy.UInt64 +subroutine one_hundred(c: uint64): uint64 { - a: algopy.UInt64 = 25u - b: algopy.UInt64 = 2u + a: uint64 = 25u + b: uint64 = 2u if (a < c) { - b: algopy.UInt64 = 1u - a: algopy.UInt64 = 100u + b: uint64 = 1u + a: uint64 = 100u } b *= b return a * b diff --git a/test_cases/state_proxies/contract.py b/test_cases/state_proxies/contract.py index a6b9b8dd5..c2c82ab47 100644 --- a/test_cases/state_proxies/contract.py +++ b/test_cases/state_proxies/contract.py @@ -4,9 +4,9 @@ class StateProxyContract(ARC4Contract): def __init__(self) -> None: self.local1 = LocalState(UInt64, key="l1", description="l1 description") - self.local2 = LocalState(UInt64, key=b"l2", description="l2 description") + self.local2 = LocalState[UInt64](UInt64, key=b"l2", description="l2 description") self.global1 = GlobalState(UInt64, key="g1", description="g1 description") - self.global2 = GlobalState(UInt64(0), key=b"g2", description="g2 description") + self.global2 = GlobalState[UInt64](UInt64(0), key=b"g2", description="g2 description") @arc4.abimethod(allow_actions=["OptIn"], create="require") def create(self) -> None: diff --git a/test_cases/state_proxies/out/StateProxyContract.approval.mir b/test_cases/state_proxies/out/StateProxyContract.approval.mir index 41d16a45a..537f88786 100644 --- a/test_cases/state_proxies/out/StateProxyContract.approval.mir +++ b/test_cases/state_proxies/out/StateProxyContract.approval.mir @@ -1,4 +1,4 @@ -// Op // Op Description Stack (out) X stack Source code Source line +// Op // Op Description Stack (out) X stack Source code Source line #pragma version 10 @@ -15,64 +15,64 @@ main_on_create@1: // Implicit fall through to main_entrypoint@2 // main_entrypoint@2: - txna ApplicationArgs 0 // {txna} class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 + txna ApplicationArgs 0 // {txna} class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 - method "create()void" // tmp%0#0,method<"create()void"> class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 - uncover 1 // load tmp%0#0 from l-stack (no copy) method<"create()void">,tmp%0#0 class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 - match main_create_route@3 // class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 - err // reject transaction // class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 + method "create()void" // tmp%0#0,method<"create()void"> class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 + swap // load tmp%0#0 from l-stack (no copy) method<"create()void">,tmp%0#0 class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 + match main_create_route@3 // class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 + err // reject transaction // class StateProxyContract(ARC4Contract): state_proxies/contract.py:4 main_create_route@3: - txn OnCompletion // {txn} arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + txn OnCompletion // {txn} arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - int OptIn // tmp%1#0,OptIn arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - == // {==} arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + int OptIn // tmp%1#0,OptIn arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + == // {==} arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // virtual: store tmp%2#0 to l-stack (no copy) tmp%2#0 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // virtual: load tmp%2#0 from l-stack (no copy) tmp%2#0 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - assert // OnCompletion is OptIn // arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - txn ApplicationID // {txn} arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + assert // OnCompletion is OptIn // arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + txn ApplicationID // {txn} arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // virtual: store tmp%3#0 to l-stack (no copy) tmp%3#0 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // virtual: load tmp%3#0 from l-stack (no copy) tmp%3#0 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - ! // {!} arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + ! // {!} arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // virtual: store tmp%4#0 to l-stack (no copy) tmp%4#0 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // virtual: load tmp%4#0 from l-stack (no copy) tmp%4#0 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - assert // is creating // arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - callsub create // arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - int 1 // 1 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 - return // arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + assert // is creating // arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + callsub create // arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + int 1 // 1 arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 + return // arc4.abimethod(allow_actions=["OptIn"], create="require") state_proxies/contract.py:11 // test_cases.state_proxies.contract.StateProxyContract.create() -> void: create: - proto 0 0 // @arc4.abimethod(allow_actions=["OptIn"], create="require")\ndef create(self) -> None: state_proxies/contract.py:11-12 + proto 0 0 // @arc4.abimethod(allow_actions=["OptIn"], create="require")\ndef create(self) -> None: state_proxies/contract.py:11-12 create_block@0: - byte "g1" // "g1" "g1" state_proxies/contract.py:8 - int 1 // "g1",1 UInt64(1) state_proxies/contract.py:13 - app_global_put // self.global1.value = UInt64(1) state_proxies/contract.py:13 - txn Sender // {txn} Txn.sender state_proxies/contract.py:14 + byte "g1" // "g1" "g1" state_proxies/contract.py:8 + int 1 // "g1",1 UInt64(1) state_proxies/contract.py:13 + app_global_put // self.global1.value = UInt64(1) state_proxies/contract.py:13 + txn Sender // {txn} Txn.sender state_proxies/contract.py:14 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Txn.sender state_proxies/contract.py:14 // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 self.local1[Txn.sender] = UInt64(2) state_proxies/contract.py:14 - byte "l1" // tmp%0#0,"l1" "l1" state_proxies/contract.py:6 - int 2 // tmp%0#0,"l1",2 UInt64(2) state_proxies/contract.py:14 - app_local_put // self.local1[Txn.sender] = UInt64(2) state_proxies/contract.py:14 - txn Sender // {txn} Txn.sender state_proxies/contract.py:15 + byte "l1" // tmp%0#0,"l1" "l1" state_proxies/contract.py:6 + int 2 // tmp%0#0,"l1",2 UInt64(2) state_proxies/contract.py:14 + app_local_put // self.local1[Txn.sender] = UInt64(2) state_proxies/contract.py:14 + txn Sender // {txn} Txn.sender state_proxies/contract.py:15 // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 Txn.sender state_proxies/contract.py:15 // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 self.local2[Txn.sender] = UInt64(3) state_proxies/contract.py:15 - byte 0x6c32 // tmp%1#0,0x6c32 b"l2" state_proxies/contract.py:7 - int 3 // tmp%1#0,0x6c32,3 UInt64(3) state_proxies/contract.py:15 - app_local_put // self.local2[Txn.sender] = UInt64(3) state_proxies/contract.py:15 + byte 0x6c32 // tmp%1#0,0x6c32 b"l2" state_proxies/contract.py:7 + int 3 // tmp%1#0,0x6c32,3 UInt64(3) state_proxies/contract.py:15 + app_local_put // self.local2[Txn.sender] = UInt64(3) state_proxies/contract.py:15 retsub // // test_cases.state_proxies.contract.StateProxyContract.__init__() -> void: __init__: - proto 0 0 // def __init__(self) -> None: state_proxies/contract.py:5 + proto 0 0 // def __init__(self) -> None: state_proxies/contract.py:5 __init___block@0: - byte 0x6732 // 0x6732 b"g2" state_proxies/contract.py:9 - int 0 // 0x6732,0 UInt64(0) state_proxies/contract.py:9 - app_global_put // self.global2 = GlobalState(UInt64(0), key=b"g2", description="g2 description") state_proxies/contract.py:9 + byte 0x6732 // 0x6732 b"g2" state_proxies/contract.py:9 + int 0 // 0x6732,0 UInt64(0) state_proxies/contract.py:9 + app_global_put // self.global2 = GlobalState[UInt64](UInt64(0), key=b"g2", description="g2 description") state_proxies/contract.py:9 retsub // diff --git a/test_cases/state_proxies/out/StateProxyContract.approval.teal b/test_cases/state_proxies/out/StateProxyContract.approval.teal index 7ff4456bd..8dfa31bb4 100644 --- a/test_cases/state_proxies/out/StateProxyContract.approval.teal +++ b/test_cases/state_proxies/out/StateProxyContract.approval.teal @@ -55,7 +55,7 @@ create: // self.local2[Txn.sender] = UInt64(3) txn Sender // state_proxies/contract.py:7 - // self.local2 = LocalState(UInt64, key=b"l2", description="l2 description") + // self.local2 = LocalState[UInt64](UInt64, key=b"l2", description="l2 description") byte 0x6c32 // state_proxies/contract.py:15 // self.local2[Txn.sender] = UInt64(3) @@ -70,7 +70,7 @@ __init__: // def __init__(self) -> None: proto 0 0 // state_proxies/contract.py:9 - // self.global2 = GlobalState(UInt64(0), key=b"g2", description="g2 description") + // self.global2 = GlobalState[UInt64](UInt64(0), key=b"g2", description="g2 description") byte 0x6732 int 0 app_global_put diff --git a/test_cases/state_proxies/out/StateProxyContract.arc32.json b/test_cases/state_proxies/out/StateProxyContract.arc32.json index 9a8239941..f4a929422 100644 --- a/test_cases/state_proxies/out/StateProxyContract.arc32.json +++ b/test_cases/state_proxies/out/StateProxyContract.arc32.json @@ -7,7 +7,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX3Byb3hpZXMuY29udHJhY3QuU3RhdGVQcm94eUNvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVQcm94eUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBtZXRob2QgImNyZWF0ZSgpdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fY3JlYXRlX3JvdXRlQDMKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fY3JlYXRlX3JvdXRlQDM6CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIk9wdEluIl0sIGNyZWF0ZT0icmVxdWlyZSIpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBpbnQgT3B0SW4KICAgID09CiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE9wdEluCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBjYWxsc3ViIGNyZWF0ZQogICAgaW50IDEKICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfcHJveGllcy5jb250cmFjdC5TdGF0ZVByb3h5Q29udHJhY3QuY3JlYXRlKCkgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxMS0xMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdLCBjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjgKICAgIC8vIHNlbGYuZ2xvYmFsMSA9IEdsb2JhbFN0YXRlKFVJbnQ2NCwga2V5PSJnMSIsIGRlc2NyaXB0aW9uPSJnMSBkZXNjcmlwdGlvbiIpCiAgICBieXRlICJnMSIKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MTMKICAgIC8vIHNlbGYuZ2xvYmFsMS52YWx1ZSA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE0CiAgICAvLyBzZWxmLmxvY2FsMVtUeG4uc2VuZGVyXSA9IFVJbnQ2NCgyKQogICAgdHhuIFNlbmRlcgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weTo2CiAgICAvLyBzZWxmLmxvY2FsMSA9IExvY2FsU3RhdGUoVUludDY0LCBrZXk9ImwxIiwgZGVzY3JpcHRpb249ImwxIGRlc2NyaXB0aW9uIikKICAgIGJ5dGUgImwxIgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxNAogICAgLy8gc2VsZi5sb2NhbDFbVHhuLnNlbmRlcl0gPSBVSW50NjQoMikKICAgIGludCAyCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBzZWxmLmxvY2FsMltUeG4uc2VuZGVyXSA9IFVJbnQ2NCgzKQogICAgdHhuIFNlbmRlcgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weTo3CiAgICAvLyBzZWxmLmxvY2FsMiA9IExvY2FsU3RhdGUoVUludDY0LCBrZXk9YiJsMiIsIGRlc2NyaXB0aW9uPSJsMiBkZXNjcmlwdGlvbiIpCiAgICBieXRlIDB4NmMzMgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxNQogICAgLy8gc2VsZi5sb2NhbDJbVHhuLnNlbmRlcl0gPSBVSW50NjQoMykKICAgIGludCAzCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnN0YXRlX3Byb3hpZXMuY29udHJhY3QuU3RhdGVQcm94eUNvbnRyYWN0Ll9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjUKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjkKICAgIC8vIHNlbGYuZ2xvYmFsMiA9IEdsb2JhbFN0YXRlKFVJbnQ2NCgwKSwga2V5PWIiZzIiLCBkZXNjcmlwdGlvbj0iZzIgZGVzY3JpcHRpb24iKQogICAgYnl0ZSAweDY3MzIKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX3Byb3hpZXMuY29udHJhY3QuU3RhdGVQcm94eUNvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgU3RhdGVQcm94eUNvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBtZXRob2QgImNyZWF0ZSgpdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fY3JlYXRlX3JvdXRlQDMKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fY3JlYXRlX3JvdXRlQDM6CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIk9wdEluIl0sIGNyZWF0ZT0icmVxdWlyZSIpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBpbnQgT3B0SW4KICAgID09CiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE9wdEluCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBjYWxsc3ViIGNyZWF0ZQogICAgaW50IDEKICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfcHJveGllcy5jb250cmFjdC5TdGF0ZVByb3h5Q29udHJhY3QuY3JlYXRlKCkgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxMS0xMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdLCBjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjgKICAgIC8vIHNlbGYuZ2xvYmFsMSA9IEdsb2JhbFN0YXRlKFVJbnQ2NCwga2V5PSJnMSIsIGRlc2NyaXB0aW9uPSJnMSBkZXNjcmlwdGlvbiIpCiAgICBieXRlICJnMSIKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MTMKICAgIC8vIHNlbGYuZ2xvYmFsMS52YWx1ZSA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE0CiAgICAvLyBzZWxmLmxvY2FsMVtUeG4uc2VuZGVyXSA9IFVJbnQ2NCgyKQogICAgdHhuIFNlbmRlcgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weTo2CiAgICAvLyBzZWxmLmxvY2FsMSA9IExvY2FsU3RhdGUoVUludDY0LCBrZXk9ImwxIiwgZGVzY3JpcHRpb249ImwxIGRlc2NyaXB0aW9uIikKICAgIGJ5dGUgImwxIgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxNAogICAgLy8gc2VsZi5sb2NhbDFbVHhuLnNlbmRlcl0gPSBVSW50NjQoMikKICAgIGludCAyCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBzZWxmLmxvY2FsMltUeG4uc2VuZGVyXSA9IFVJbnQ2NCgzKQogICAgdHhuIFNlbmRlcgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weTo3CiAgICAvLyBzZWxmLmxvY2FsMiA9IExvY2FsU3RhdGVbVUludDY0XShVSW50NjQsIGtleT1iImwyIiwgZGVzY3JpcHRpb249ImwyIGRlc2NyaXB0aW9uIikKICAgIGJ5dGUgMHg2YzMyCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBzZWxmLmxvY2FsMltUeG4uc2VuZGVyXSA9IFVJbnQ2NCgzKQogICAgaW50IDMKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfcHJveGllcy5jb250cmFjdC5TdGF0ZVByb3h5Q29udHJhY3QuX19pbml0X18oKSAtPiB2b2lkOgpfX2luaXRfXzoKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6NQogICAgLy8gZGVmIF9faW5pdF9fKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6OQogICAgLy8gc2VsZi5nbG9iYWwyID0gR2xvYmFsU3RhdGVbVUludDY0XShVSW50NjQoMCksIGtleT1iImcyIiwgZGVzY3JpcHRpb249ImcyIGRlc2NyaXB0aW9uIikKICAgIGJ5dGUgMHg2NzMyCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX3Byb3hpZXMuY29udHJhY3QuU3RhdGVQcm94eUNvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIFN0YXRlUHJveHlDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/test_cases/state_proxies/out/contract.awst b/test_cases/state_proxies/out/contract.awst index fb83abf9b..1a85e12a9 100644 --- a/test_cases/state_proxies/out/contract.awst +++ b/test_cases/state_proxies/out/contract.awst @@ -1,23 +1,23 @@ contract StateProxyContract { globals { - ['g1']: algopy.UInt64 - [hex<"6732">]: algopy.UInt64 + ['g1']: uint64 + [hex<"6732">]: uint64 } locals { - ['l1']: algopy.UInt64 - [hex<"6C32">]: algopy.UInt64 + ['l1']: uint64 + [hex<"6C32">]: uint64 } constructor() { - this.global2: algopy.UInt64 = 0u + this.global2: uint64 = 0u } - abimethod create(): None + abimethod create(): void { - this.global1: algopy.UInt64 = 1u - this.local1[txn()]: algopy.UInt64 = 2u - this.local2[txn()]: algopy.UInt64 = 3u + this.global1: uint64 = 1u + this.local1[txn()]: uint64 = 2u + this.local2[txn()]: uint64 = 3u } } \ No newline at end of file diff --git a/test_cases/state_proxies/out_unoptimized/StateProxyContract.approval.teal b/test_cases/state_proxies/out_unoptimized/StateProxyContract.approval.teal index 878aa0911..ad7d20a9b 100644 --- a/test_cases/state_proxies/out_unoptimized/StateProxyContract.approval.teal +++ b/test_cases/state_proxies/out_unoptimized/StateProxyContract.approval.teal @@ -61,7 +61,7 @@ create: // self.local2[Txn.sender] = UInt64(3) txn Sender // state_proxies/contract.py:7 - // self.local2 = LocalState(UInt64, key=b"l2", description="l2 description") + // self.local2 = LocalState[UInt64](UInt64, key=b"l2", description="l2 description") byte 0x6c32 // state_proxies/contract.py:15 // self.local2[Txn.sender] = UInt64(3) @@ -76,7 +76,7 @@ __init__: // def __init__(self) -> None: proto 0 0 // state_proxies/contract.py:9 - // self.global2 = GlobalState(UInt64(0), key=b"g2", description="g2 description") + // self.global2 = GlobalState[UInt64](UInt64(0), key=b"g2", description="g2 description") byte 0x6732 int 0 app_global_put diff --git a/test_cases/state_totals/out/contract.awst b/test_cases/state_totals/out/contract.awst index ee5bd8140..f2d0ade6b 100644 --- a/test_cases/state_totals/out/contract.awst +++ b/test_cases/state_totals/out/contract.awst @@ -3,17 +3,17 @@ GLOBAL_UINTS = 3 contract Contract { globals { - ['global_one']: algopy.Bytes + ['global_one']: bytes } locals { - ['local_one']: algopy.UInt64 + ['local_one']: uint64 } constructor() { } - abimethod create(): None + abimethod create(): void { } } \ No newline at end of file diff --git a/test_cases/stress_tests/out/brute_force_rotation_search.awst b/test_cases/stress_tests/out/brute_force_rotation_search.awst index 054f21e1b..72db64cd8 100644 --- a/test_cases/stress_tests/out/brute_force_rotation_search.awst +++ b/test_cases/stress_tests/out/brute_force_rotation_search.awst @@ -2,7 +2,7 @@ contract BruteForceRotationSearch { approval_program(): bool { - (a, b, c, d, e, f, g, h, i, j, k, l, m, n): tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64] = test_cases.stress_tests.brute_force_rotation_search::do_some_ops(0u, 0u) + (a, b, c, d, e, f, g, h, i, j, k, l, m, n): tuple = test_cases.stress_tests.brute_force_rotation_search::do_some_ops(0u, 0u) assert(a == 0u) assert(b == 1u) assert(c == 2u) @@ -26,8 +26,8 @@ contract BruteForceRotationSearch } } -subroutine do_some_ops(a: algopy.UInt64, b: algopy.UInt64): tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64] +subroutine do_some_ops(a: uint64, b: uint64): tuple { - c: algopy.UInt64 = a + b + c: uint64 = a + b return (c, c + 1u, c + 2u, c + 3u, c + 4u, c + 5u, c + 6u, c + 7u, c + 8u, c + 9u, c + 10u, c + 11u, c + 12u, c + 13u) } \ No newline at end of file diff --git a/test_cases/string_ops/out/contract.awst b/test_cases/string_ops/out/contract.awst index f1c202d4d..77e051e75 100644 --- a/test_cases/string_ops/out/contract.awst +++ b/test_cases/string_ops/out/contract.awst @@ -13,7 +13,7 @@ contract MyContract } } -subroutine is_in_str(a: algopy.Bytes, b: algopy.Bytes): bool +subroutine is_in_str(a: bytes, b: bytes): bool { return algopy_lib_bytes::is_substring(a, b) } \ No newline at end of file diff --git a/test_cases/stubs/out/biguint.awst b/test_cases/stubs/out/biguint.awst index 24d36f372..0830466b4 100644 --- a/test_cases/stubs/out/biguint.awst +++ b/test_cases/stubs/out/biguint.awst @@ -2,7 +2,7 @@ contract BigUIntContract { approval_program(): bool { - one: algopy.BigUInt = 1n + one: biguint = 1n test_cases.stubs.biguint::compare_biguints(one, 2n) test_cases.stubs.biguint::compare_biguint_vs_uint64(one, 2u) test_cases.stubs.biguint::compare_uint64_vs_biguint(1u, 2n) @@ -18,7 +18,7 @@ contract BigUIntContract } } -subroutine compare_biguints(one: algopy.BigUInt, two: algopy.BigUInt): None +subroutine compare_biguints(one: biguint, two: biguint): void { assert(one < two) assert(one <= two) @@ -28,7 +28,7 @@ subroutine compare_biguints(one: algopy.BigUInt, two: algopy.BigUInt): None assert(one != two) } -subroutine compare_biguint_vs_uint64(one: algopy.BigUInt, two: algopy.UInt64): None +subroutine compare_biguint_vs_uint64(one: biguint, two: uint64): void { assert(one < itob(two)) assert(one <= itob(two)) @@ -38,7 +38,7 @@ subroutine compare_biguint_vs_uint64(one: algopy.BigUInt, two: algopy.UInt64): N assert(one != itob(two)) } -subroutine compare_uint64_vs_biguint(one: algopy.UInt64, two: algopy.BigUInt): None +subroutine compare_uint64_vs_biguint(one: uint64, two: biguint): void { assert(two > itob(one)) assert(two >= itob(one)) diff --git a/test_cases/stubs/out/bytes.awst b/test_cases/stubs/out/bytes.awst index 6926e1827..d2f25f4c1 100644 --- a/test_cases/stubs/out/bytes.awst +++ b/test_cases/stubs/out/bytes.awst @@ -1,21 +1,21 @@ contract BytesContract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - base_64: algopy.Bytes = b64<"QmFzZSA2NCBlbmNvZGVk"> + base_64: bytes = b64<"QmFzZSA2NCBlbmNvZGVk"> assert(base_64 == 'Base 64 encoded') - base_32: algopy.Bytes = b32<"IJQXGZJAGMZCAZLOMNXWIZLE"> + base_32: bytes = b32<"IJQXGZJAGMZCAZLOMNXWIZLE"> assert(base_32 == 'Base 32 encoded') - base_16: algopy.Bytes = hex<"4261736520313620656E636F646564"> + base_16: bytes = hex<"4261736520313620656E636F646564"> assert(base_16 == 'Base 16 encoded') - empty: algopy.Bytes = '' + empty: bytes = '' assert(reinterpret_cast(len(base_64)), comment="Non empty bytes should be Truthy") assert(!(reinterpret_cast(len(empty))), comment="Empty bytes should be Falsy") assert('a' + 'b' == 'ab') - c: algopy.Bytes = 'c' + c: bytes = 'c' c += 'd' assert(c == 'cd') - abc: algopy.Bytes = 'abc' + abc: bytes = 'abc' assert(abc[0u] == 'a') assert(abc[1:] == 'bc') assert(abc[1:1] == '') @@ -25,8 +25,8 @@ contract BytesContract assert(abc[-2:-1] == 'b') assert('1234567'[1:-1] == '23456') assert(abc[-10:10] == 'abc') - true: algopy.Bytes = '1' - false: algopy.Bytes = '' + true: bytes = '1' + false: bytes = '' x: bool = (!(reinterpret_cast(len(true)))) ? (true) : (true) == true assert(x) assert((!(reinterpret_cast(len(true)))) ? (true) : (true) == true) @@ -37,11 +37,11 @@ contract BytesContract assert((reinterpret_cast(len(true))) ? (true) : (false) == true) assert((reinterpret_cast(len(false))) ? (false) : (true) == true) assert((reinterpret_cast(len(false))) ? (false) : (false) == false) - (a, b, c, d): tuple[algopy.Bytes, algopy.Bytes, algopy.Bytes, algopy.Bytes] = (hex<"00">, hex<"0F">, hex<"F0">, hex<"FF">) + (a, b, c, d): tuple = (hex<"00">, hex<"0F">, hex<"F0">, hex<"FF">) assert(a & b == a) assert(b | c == d) assert(b ^ d == c) - y: algopy.Bytes = a + y: bytes = a y &= d assert(y == a) y |= d @@ -59,10 +59,10 @@ contract BytesContract } } -subroutine check_slicing_with_uint64(abc: algopy.Bytes): None +subroutine check_slicing_with_uint64(abc: bytes): void { - one: algopy.UInt64 = 1u - ten: algopy.UInt64 = 10u + one: uint64 = 1u + ten: uint64 = 10u assert(abc[one:] == 'bc') assert(abc[one:one] == '') assert(abc[:one] == 'a') @@ -70,16 +70,16 @@ subroutine check_slicing_with_uint64(abc: algopy.Bytes): None assert(abc[0u:ten] == 'abc') } -subroutine check_end_before_start_slicing(abc: algopy.Bytes): None +subroutine check_end_before_start_slicing(abc: bytes): void { assert(abc[10:1] == '') assert(abc[-10:-12] == '') - one: algopy.UInt64 = 1u - ten: algopy.UInt64 = 10u + one: uint64 = 1u + ten: uint64 = 10u assert(abc[ten:one] == '') } -subroutine one_to_seven(): algopy.Bytes +subroutine one_to_seven(): bytes { log('one_to_seven called') return '1234567' diff --git a/test_cases/stubs/out/string.awst b/test_cases/stubs/out/string.awst index f229b57ed..2acd360b8 100644 --- a/test_cases/stubs/out/string.awst +++ b/test_cases/stubs/out/string.awst @@ -2,38 +2,38 @@ contract StringContract { approval_program(): bool { - empty: algopy.String = '' - assert(!(reinterpret_cast(len(reinterpret_cast(empty)))), comment="Empty bytes should be False") - non_empty: algopy.String = ' ' - assert(reinterpret_cast(len(reinterpret_cast(non_empty))), comment="Non-empty bytes should be True") + empty: string = '' + assert(!(reinterpret_cast(len(reinterpret_cast(empty)))), comment="Empty bytes should be False") + non_empty: string = ' ' + assert(reinterpret_cast(len(reinterpret_cast(non_empty))), comment="Non-empty bytes should be True") assert('a' + 'b' == 'ab') assert('a' + 'b' == 'ab') assert('a' + 'b' == 'ab') assert(empty != non_empty) - c: algopy.String = 'c' + c: string = 'c' c += 'd' c += 'e' assert(c == 'cde') - assert(algopy_lib_bytes::is_substring(item=reinterpret_cast('brown fox'), sequence=reinterpret_cast('The quick brown fox jumped over the lazy dog'))) - assert(!(algopy_lib_bytes::is_substring(item=reinterpret_cast('red fox'), sequence=reinterpret_cast('The quick brown fox jumped over the lazy dog')))) - alpha: algopy.String = 'abcdefg' - assert((len(reinterpret_cast(SINGLE_EVAL(id=0, source=''))) > len(reinterpret_cast(SINGLE_EVAL(id=1, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=1, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=0, source='')))) == reinterpret_cast(SINGLE_EVAL(id=0, source='')))) - assert((len(reinterpret_cast(SINGLE_EVAL(id=2, source='a'))) > len(reinterpret_cast(SINGLE_EVAL(id=3, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=3, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=2, source='a')))) == reinterpret_cast(SINGLE_EVAL(id=2, source='a')))) - assert((len(reinterpret_cast(SINGLE_EVAL(id=4, source='ab'))) > len(reinterpret_cast(SINGLE_EVAL(id=5, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=5, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=4, source='ab')))) == reinterpret_cast(SINGLE_EVAL(id=4, source='ab')))) - assert(!((len(reinterpret_cast(SINGLE_EVAL(id=6, source='b'))) > len(reinterpret_cast(SINGLE_EVAL(id=7, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=7, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=6, source='b')))) == reinterpret_cast(SINGLE_EVAL(id=6, source='b'))))) - assert((len(reinterpret_cast(SINGLE_EVAL(id=8, source=alpha))) > len(reinterpret_cast(SINGLE_EVAL(id=9, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=9, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=8, source=alpha)))) == reinterpret_cast(SINGLE_EVAL(id=8, source=alpha)))) - assert(!((len(reinterpret_cast(SINGLE_EVAL(id=10, source=alpha + '!'))) > len(reinterpret_cast(SINGLE_EVAL(id=11, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=11, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=10, source=alpha + '!')))) == reinterpret_cast(SINGLE_EVAL(id=10, source=alpha + '!'))))) - assert((len(reinterpret_cast(SINGLE_EVAL(id=12, source=''))) > len(reinterpret_cast(SINGLE_EVAL(id=13, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=13, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=13, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=12, source=''))), len(reinterpret_cast(SINGLE_EVAL(id=12, source='')))) == reinterpret_cast(SINGLE_EVAL(id=12, source='')))) - assert((len(reinterpret_cast(SINGLE_EVAL(id=14, source='g'))) > len(reinterpret_cast(SINGLE_EVAL(id=15, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=15, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=15, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=14, source='g'))), len(reinterpret_cast(SINGLE_EVAL(id=14, source='g')))) == reinterpret_cast(SINGLE_EVAL(id=14, source='g')))) - assert((len(reinterpret_cast(SINGLE_EVAL(id=16, source='fg'))) > len(reinterpret_cast(SINGLE_EVAL(id=17, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=17, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=17, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=16, source='fg'))), len(reinterpret_cast(SINGLE_EVAL(id=16, source='fg')))) == reinterpret_cast(SINGLE_EVAL(id=16, source='fg')))) - assert(!((len(reinterpret_cast(SINGLE_EVAL(id=18, source='f'))) > len(reinterpret_cast(SINGLE_EVAL(id=19, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=19, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=19, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=18, source='f'))), len(reinterpret_cast(SINGLE_EVAL(id=18, source='f')))) == reinterpret_cast(SINGLE_EVAL(id=18, source='f'))))) - assert((len(reinterpret_cast(SINGLE_EVAL(id=20, source=alpha))) > len(reinterpret_cast(SINGLE_EVAL(id=21, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=21, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=21, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=20, source=alpha))), len(reinterpret_cast(SINGLE_EVAL(id=20, source=alpha)))) == reinterpret_cast(SINGLE_EVAL(id=20, source=alpha)))) - assert(!((len(reinterpret_cast(SINGLE_EVAL(id=22, source='!' + alpha))) > len(reinterpret_cast(SINGLE_EVAL(id=23, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=23, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=23, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=22, source='!' + alpha))), len(reinterpret_cast(SINGLE_EVAL(id=22, source='!' + alpha)))) == reinterpret_cast(SINGLE_EVAL(id=22, source='!' + alpha))))) - (d, e, f): tuple[algopy.String, algopy.String, algopy.String] = ('d', 'e', 'f') - assert(reinterpret_cast(concat(concat(concat(concat(reinterpret_cast(SINGLE_EVAL(id=24, source=(d, e, f))[0]), reinterpret_cast(SINGLE_EVAL(id=25, source='.'))), reinterpret_cast(SINGLE_EVAL(id=24, source=(d, e, f))[1])), reinterpret_cast(SINGLE_EVAL(id=25, source='.'))), reinterpret_cast(SINGLE_EVAL(id=24, source=(d, e, f))[2]))) == 'd.e.f') - assert(reinterpret_cast(concat(concat(concat(concat(reinterpret_cast(SINGLE_EVAL(id=26, source=(d, e, f))[0]), reinterpret_cast(SINGLE_EVAL(id=27, source=''))), reinterpret_cast(SINGLE_EVAL(id=26, source=(d, e, f))[1])), reinterpret_cast(SINGLE_EVAL(id=27, source=''))), reinterpret_cast(SINGLE_EVAL(id=26, source=(d, e, f))[2]))) == 'def') - assert(reinterpret_cast(reinterpret_cast(SINGLE_EVAL(id=28, source=(d))[0])) == 'd') - assert(reinterpret_cast(reinterpret_cast(SINGLE_EVAL(id=29, source=(d))[0])) == 'd') + assert(algopy_lib_bytes::is_substring(item=reinterpret_cast('brown fox'), sequence=reinterpret_cast('The quick brown fox jumped over the lazy dog'))) + assert(!(algopy_lib_bytes::is_substring(item=reinterpret_cast('red fox'), sequence=reinterpret_cast('The quick brown fox jumped over the lazy dog')))) + alpha: string = 'abcdefg' + assert((len(reinterpret_cast(SINGLE_EVAL(id=0, source=''))) > len(reinterpret_cast(SINGLE_EVAL(id=1, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=1, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=0, source='')))) == reinterpret_cast(SINGLE_EVAL(id=0, source='')))) + assert((len(reinterpret_cast(SINGLE_EVAL(id=2, source='a'))) > len(reinterpret_cast(SINGLE_EVAL(id=3, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=3, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=2, source='a')))) == reinterpret_cast(SINGLE_EVAL(id=2, source='a')))) + assert((len(reinterpret_cast(SINGLE_EVAL(id=4, source='ab'))) > len(reinterpret_cast(SINGLE_EVAL(id=5, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=5, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=4, source='ab')))) == reinterpret_cast(SINGLE_EVAL(id=4, source='ab')))) + assert(!((len(reinterpret_cast(SINGLE_EVAL(id=6, source='b'))) > len(reinterpret_cast(SINGLE_EVAL(id=7, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=7, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=6, source='b')))) == reinterpret_cast(SINGLE_EVAL(id=6, source='b'))))) + assert((len(reinterpret_cast(SINGLE_EVAL(id=8, source=alpha))) > len(reinterpret_cast(SINGLE_EVAL(id=9, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=9, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=8, source=alpha)))) == reinterpret_cast(SINGLE_EVAL(id=8, source=alpha)))) + assert(!((len(reinterpret_cast(SINGLE_EVAL(id=10, source=alpha + '!'))) > len(reinterpret_cast(SINGLE_EVAL(id=11, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=11, source=alpha)), 0u, len(reinterpret_cast(SINGLE_EVAL(id=10, source=alpha + '!')))) == reinterpret_cast(SINGLE_EVAL(id=10, source=alpha + '!'))))) + assert((len(reinterpret_cast(SINGLE_EVAL(id=12, source=''))) > len(reinterpret_cast(SINGLE_EVAL(id=13, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=13, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=13, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=12, source=''))), len(reinterpret_cast(SINGLE_EVAL(id=12, source='')))) == reinterpret_cast(SINGLE_EVAL(id=12, source='')))) + assert((len(reinterpret_cast(SINGLE_EVAL(id=14, source='g'))) > len(reinterpret_cast(SINGLE_EVAL(id=15, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=15, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=15, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=14, source='g'))), len(reinterpret_cast(SINGLE_EVAL(id=14, source='g')))) == reinterpret_cast(SINGLE_EVAL(id=14, source='g')))) + assert((len(reinterpret_cast(SINGLE_EVAL(id=16, source='fg'))) > len(reinterpret_cast(SINGLE_EVAL(id=17, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=17, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=17, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=16, source='fg'))), len(reinterpret_cast(SINGLE_EVAL(id=16, source='fg')))) == reinterpret_cast(SINGLE_EVAL(id=16, source='fg')))) + assert(!((len(reinterpret_cast(SINGLE_EVAL(id=18, source='f'))) > len(reinterpret_cast(SINGLE_EVAL(id=19, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=19, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=19, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=18, source='f'))), len(reinterpret_cast(SINGLE_EVAL(id=18, source='f')))) == reinterpret_cast(SINGLE_EVAL(id=18, source='f'))))) + assert((len(reinterpret_cast(SINGLE_EVAL(id=20, source=alpha))) > len(reinterpret_cast(SINGLE_EVAL(id=21, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=21, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=21, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=20, source=alpha))), len(reinterpret_cast(SINGLE_EVAL(id=20, source=alpha)))) == reinterpret_cast(SINGLE_EVAL(id=20, source=alpha)))) + assert(!((len(reinterpret_cast(SINGLE_EVAL(id=22, source='!' + alpha))) > len(reinterpret_cast(SINGLE_EVAL(id=23, source=alpha)))) ? (false) : (extract3(reinterpret_cast(SINGLE_EVAL(id=23, source=alpha)), len(reinterpret_cast(SINGLE_EVAL(id=23, source=alpha))) - len(reinterpret_cast(SINGLE_EVAL(id=22, source='!' + alpha))), len(reinterpret_cast(SINGLE_EVAL(id=22, source='!' + alpha)))) == reinterpret_cast(SINGLE_EVAL(id=22, source='!' + alpha))))) + (d, e, f): tuple = ('d', 'e', 'f') + assert(reinterpret_cast(concat(concat(concat(concat(reinterpret_cast(SINGLE_EVAL(id=24, source=(d, e, f))[0]), reinterpret_cast(SINGLE_EVAL(id=25, source='.'))), reinterpret_cast(SINGLE_EVAL(id=24, source=(d, e, f))[1])), reinterpret_cast(SINGLE_EVAL(id=25, source='.'))), reinterpret_cast(SINGLE_EVAL(id=24, source=(d, e, f))[2]))) == 'd.e.f') + assert(reinterpret_cast(concat(concat(concat(concat(reinterpret_cast(SINGLE_EVAL(id=26, source=(d, e, f))[0]), reinterpret_cast(SINGLE_EVAL(id=27, source=''))), reinterpret_cast(SINGLE_EVAL(id=26, source=(d, e, f))[1])), reinterpret_cast(SINGLE_EVAL(id=27, source=''))), reinterpret_cast(SINGLE_EVAL(id=26, source=(d, e, f))[2]))) == 'def') + assert(reinterpret_cast(reinterpret_cast(SINGLE_EVAL(id=28, source=(d))[0])) == 'd') + assert(reinterpret_cast(reinterpret_cast(SINGLE_EVAL(id=29, source=(d))[0])) == 'd') return true } diff --git a/test_cases/stubs/out/uint64.awst b/test_cases/stubs/out/uint64.awst index 9a8d2bef2..d10831518 100644 --- a/test_cases/stubs/out/uint64.awst +++ b/test_cases/stubs/out/uint64.awst @@ -1,13 +1,13 @@ contract Uint64Contract { - approval_program(): algopy.UInt64 + approval_program(): uint64 { - zero: algopy.UInt64 = 0u - one: algopy.UInt64 = 1u - two: algopy.UInt64 = 2u - five: algopy.UInt64 = 5u - three: algopy.UInt64 = 3u - sixty: algopy.UInt64 = 60u + zero: uint64 = 0u + one: uint64 = 1u + two: uint64 = 2u + five: uint64 = 5u + three: uint64 = 3u + sixty: uint64 = 60u assert(reinterpret_cast(one), comment="Any non-zero number should be Truthy") assert(!(reinterpret_cast(zero)), comment="Zero should beFalsy") assert(one < five) @@ -15,7 +15,7 @@ contract Uint64Contract assert(one <= one) assert(five >= five) assert(one + five == 6u) - c: algopy.UInt64 = five + c: uint64 = five c += sixty assert(c == 65u) assert(sixty - five == 55u) @@ -35,8 +35,8 @@ contract Uint64Contract assert(c == 128u) assert(five >> three == 0u) assert(~(one) == 18446744073709551614u) - true: algopy.UInt64 = 1u - false: algopy.UInt64 = 0u + true: uint64 = 1u + false: uint64 = 0u assert((!(reinterpret_cast(true))) ? (true) : (true) == true) assert((!(reinterpret_cast(true))) ? (true) : (false) == false) assert((!(reinterpret_cast(false))) ? (false) : (true) == false) @@ -48,7 +48,7 @@ contract Uint64Contract assert(one & five == one) assert(sixty | five == 61u) assert(sixty ^ five == 57u) - y: algopy.UInt64 = 254u + y: uint64 = 254u y &= 31u assert(y == 30u) y |= 54u diff --git a/test_cases/template_variables/out/client_TemplateVariablesContract.py b/test_cases/template_variables/out/client_TemplateVariablesContract.py index 58f8ba139..3756915f0 100644 --- a/test_cases/template_variables/out/client_TemplateVariablesContract.py +++ b/test_cases/template_variables/out/client_TemplateVariablesContract.py @@ -15,4 +15,4 @@ def get_bytes( @algopy.arc4.abimethod def get_big_uint( self, - ) -> algopy.arc4.UInt512: ... + ) -> algopy.arc4.BigUIntN[typing.Literal[512]]: ... diff --git a/test_cases/template_variables/out/contract.awst b/test_cases/template_variables/out/contract.awst index 77d65c65f..6dc6ac7e2 100644 --- a/test_cases/template_variables/out/contract.awst +++ b/test_cases/template_variables/out/contract.awst @@ -1,23 +1,23 @@ contract TemplateVariablesContract { - abimethod get_bytes(): algopy.Bytes + abimethod get_bytes(): bytes { - return TemplateVar[algopy.Bytes](TMPL_SOME_BYTES) + return TemplateVar[bytes](TMPL_SOME_BYTES) } - abimethod get_big_uint(): algopy.arc4.UInt512 + abimethod get_big_uint(): arc4.uint512 { - x: algopy.BigUInt = TemplateVar[algopy.BigUInt](TMPL_SOME_BIG_UINT) - return arc4_encode(x, algopy.arc4.UInt512) + x: biguint = TemplateVar[biguint](TMPL_SOME_BIG_UINT) + return arc4_encode(x, arc4.uint512) } - abimethod on_update(): None + abimethod on_update(): void { assert(TemplateVar[bool](TMPL_UPDATABLE)) } - abimethod on_delete(): None + abimethod on_delete(): void { - assert(reinterpret_cast(TemplateVar[algopy.UInt64](TMPL_DELETABLE))) + assert(reinterpret_cast(TemplateVar[uint64](TMPL_DELETABLE))) } } \ No newline at end of file diff --git a/test_cases/too_many_permutations/out/contract.awst b/test_cases/too_many_permutations/out/contract.awst index b4f28c696..e368fca2f 100644 --- a/test_cases/too_many_permutations/out/contract.awst +++ b/test_cases/too_many_permutations/out/contract.awst @@ -2,10 +2,10 @@ contract MyContract { approval_program(): bool { - a: algopy.Bytes = txna() - b: algopy.Bytes = txna() - c: algopy.Bytes = txna() - d: algopy.Bytes = txna() + a: bytes = txna() + b: bytes = txna() + c: bytes = txna() + d: bytes = txna() assert(a != c or b != d) assert(test_cases.too_many_permutations.contract::four_args(a, b, c, d)) test_cases.too_many_permutations.contract::two_args(a, b) @@ -19,12 +19,12 @@ contract MyContract } } -subroutine four_args(a: algopy.Bytes, b: algopy.Bytes, c: algopy.Bytes, d: algopy.Bytes): bool +subroutine four_args(a: bytes, b: bytes, c: bytes, d: bytes): bool { return len(a + b + c + d) > 0u } -subroutine two_args(a: algopy.Bytes, b: algopy.Bytes): None +subroutine two_args(a: bytes, b: bytes): void { assert(reinterpret_cast(len(a + b))) } \ No newline at end of file diff --git a/test_cases/transaction/out/contract.awst b/test_cases/transaction/out/contract.awst index 79bc76267..f2446972e 100644 --- a/test_cases/transaction/out/contract.awst +++ b/test_cases/transaction/out/contract.awst @@ -1,10 +1,10 @@ contract TransactionContract { - abimethod create(): None + abimethod create(): void { } - subroutine _common_checks(txn: algopy.gtxn.TransactionBase): None + subroutine _common_checks(txn: group_transaction_base): void { assert(reinterpret_cast(len(gtxns(txn))), comment="txn_id") assert(gtxns(txn) == global(), comment="sender") @@ -19,7 +19,7 @@ contract TransactionContract assert(gtxns(txn) == global(), comment="rekey_to") } - abimethod pay(txn: algopy.gtxn.PaymentTransaction): None + abimethod pay(txn: group_transaction_pay): void { this::_common_checks(txn) assert(gtxns(txn) == global(), comment="Payment should be for this app") @@ -27,7 +27,7 @@ contract TransactionContract assert(gtxns(txn) == global(), comment="close_remainder_to") } - abimethod key(txn: algopy.gtxn.KeyRegistrationTransaction): None + abimethod key(txn: group_transaction_keyreg): void { this::_common_checks(txn) assert(reinterpret_cast(len(gtxns(txn))), comment="vote_key") @@ -39,7 +39,7 @@ contract TransactionContract assert(reinterpret_cast(len(gtxns(txn))), comment="state_proof_key") } - abimethod asset_config(txn: algopy.gtxn.AssetConfigTransaction): None + abimethod asset_config(txn: group_transaction_acfg): void { this::_common_checks(txn) assert(reinterpret_cast(gtxns(txn)), comment="config_asset") @@ -56,7 +56,7 @@ contract TransactionContract assert(gtxns(txn) != global(), comment="clawback") } - abimethod asset_transfer(txn: algopy.gtxn.AssetTransferTransaction): None + abimethod asset_transfer(txn: group_transaction_axfer): void { this::_common_checks(txn) assert(reinterpret_cast(gtxns(txn)), comment="xfer_asset") @@ -66,7 +66,7 @@ contract TransactionContract assert(gtxns(txn) != global(), comment="asset_close_to") } - abimethod asset_freeze(txn: algopy.gtxn.AssetFreezeTransaction): None + abimethod asset_freeze(txn: group_transaction_afrz): void { this::_common_checks(txn) assert(reinterpret_cast(gtxns(txn)), comment="freeze_asset") @@ -74,7 +74,7 @@ contract TransactionContract assert(gtxns(txn), comment="frozen") } - abimethod application_call(txn: algopy.gtxn.ApplicationCallTransaction): None + abimethod application_call(txn: group_transaction_appl): void { this::_common_checks(txn) assert(reinterpret_cast(gtxns(txn)), comment="app_id") @@ -101,26 +101,26 @@ contract TransactionContract assert(reinterpret_cast(len(gtxnsas(txn, 0u))), comment="clear_state_program_pages(0)") } - abimethod multiple_txns(txn1: algopy.gtxn.ApplicationCallTransaction, txn2: algopy.gtxn.ApplicationCallTransaction, txn3: algopy.gtxn.ApplicationCallTransaction): None + abimethod multiple_txns(txn1: group_transaction_appl, txn2: group_transaction_appl, txn3: group_transaction_appl): void { for (index, app) in enumerate((txn1, txn2, txn3)) { assert(gtxns(app) == index) } } - abimethod any_txn(txn1: algopy.gtxn.Transaction, txn2: algopy.gtxn.Transaction, txn3: algopy.gtxn.Transaction): None + abimethod any_txn(txn1: group_transaction, txn2: group_transaction, txn3: group_transaction): void { for (index, txn) in enumerate((txn1, txn2, txn3)) { assert(gtxns(txn) == index) } } - abimethod group_init(txn1: algopy.gtxn.Transaction, txn2: algopy.gtxn.Transaction, txn3: algopy.gtxn.Transaction): None + abimethod group_init(txn1: group_transaction, txn2: group_transaction, txn3: group_transaction): void { for txn in (txn1, txn2, txn3) { - txn_from_index: algopy.gtxn.Transaction = reinterpret_cast(gtxns(txn)) + txn_from_index: group_transaction = reinterpret_cast(gtxns(txn)) assert(gtxns(txn) == gtxns(txn_from_index)) } - assert(gtxns(txn1) == gtxns(reinterpret_cast(0u))) + assert(gtxns(txn1) == gtxns(reinterpret_cast(0u))) } } \ No newline at end of file diff --git a/test_cases/tuple_support/out/tuple_support.awst b/test_cases/tuple_support/out/tuple_support.awst index e4761f784..3037cf582 100644 --- a/test_cases/tuple_support/out/tuple_support.awst +++ b/test_cases/tuple_support/out/tuple_support.awst @@ -1,42 +1,42 @@ contract TupleSupport { globals { - ['state']: algopy.UInt64 + ['state']: uint64 } constructor() { - this.state: algopy.UInt64 = 0u + this.state: uint64 = 0u } - approval_program(): algopy.UInt64 + approval_program(): uint64 { - total: algopy.UInt64 = test_cases.tuple_support.tuple_support::add_three_values((101u, 102u, 103u)) + total: uint64 = test_cases.tuple_support.tuple_support::add_three_values((101u, 102u, 103u)) log(itob(total)) - (a, b): tuple[algopy.UInt64, algopy.UInt64] = (1u, 2u) - (did_overflow, this.state): tuple[algopy.UInt64, algopy.UInt64] = addw(a, b) + (a, b): tuple = (1u, 2u) + (did_overflow, this.state): tuple = addw(a, b) assert(!(reinterpret_cast(did_overflow)), comment="overflow!") - ab: tuple[algopy.UInt64, algopy.UInt64] = (a, b) + ab: tuple = (a, b) assert(ab[-1] == ab[1]) - result: tuple[algopy.UInt64, algopy.UInt64] = addw(a, b) + result: tuple = addw(a, b) assert(!(reinterpret_cast(result[0])), comment="overflow!") - d: algopy.UInt64 = 3u - c: algopy.UInt64 = 3u - (a2, b2): tuple[algopy.UInt64, algopy.UInt64] = ab - cd: tuple[algopy.UInt64, algopy.UInt64] = (c, d) - ab2: tuple[algopy.UInt64, algopy.UInt64] = ab + d: uint64 = 3u + c: uint64 = 3u + (a2, b2): tuple = ab + cd: tuple = (c, d) + ab2: tuple = ab if (a == b) { - tup: tuple[algopy.UInt64, algopy.UInt64] = ab2 + tup: tuple = ab2 } else { - tup: tuple[algopy.UInt64, algopy.UInt64] = cd + tup: tuple = cd } assert(a2 == a) assert(b2 == b) assert(cd[0] == tup[0]) assert(cd[1] == tup[1]) log(test_cases.tuple_support.tuple_support::bytes_combine(('Hello, ', 'world!'))) - max_uint64: algopy.UInt64 = 18446744073709551615u - (hi, mid, lo): tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64] = test_cases.tuple_support.tuple_support::addw2(addw(max_uint64, max_uint64), addw(a, b)) + max_uint64: uint64 = 18446744073709551615u + (hi, mid, lo): tuple = test_cases.tuple_support.tuple_support::addw2(addw(max_uint64, max_uint64), addw(a, b)) log(itob(hi)) log(itob(mid)) log(itob(lo)) @@ -46,62 +46,62 @@ contract TupleSupport return a + b } - clear_state_program(): algopy.UInt64 + clear_state_program(): uint64 { return 0u } } -subroutine bytes_combine(arg: tuple[algopy.Bytes, algopy.Bytes]): algopy.Bytes +subroutine bytes_combine(arg: tuple): bytes { - (a, b): tuple[algopy.Bytes, algopy.Bytes] = arg - result: algopy.Bytes = a + b + (a, b): tuple = arg + result: bytes = a + b return result } -subroutine bytes_multiply(arg: tuple[algopy.Bytes, algopy.UInt64]): algopy.Bytes +subroutine bytes_multiply(arg: tuple): bytes { - (b, count): tuple[algopy.Bytes, algopy.UInt64] = arg - result: algopy.Bytes = '' + (b, count): tuple = arg + result: bytes = '' for _i in range(0u, count, 1u) { result += b } return result } -subroutine add_three_values(values: tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64]): algopy.UInt64 +subroutine add_three_values(values: tuple): uint64 { - total: algopy.UInt64 = 0u + total: uint64 = 0u for value in values { total += value } return total } -subroutine addw2(a: tuple[algopy.UInt64, algopy.UInt64], b: tuple[algopy.UInt64, algopy.UInt64]): tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64] +subroutine addw2(a: tuple, b: tuple): tuple { - (a_hi, a_lo): tuple[algopy.UInt64, algopy.UInt64] = a - (b_hi, b_lo): tuple[algopy.UInt64, algopy.UInt64] = b - (lo_carry, c_lo): tuple[algopy.UInt64, algopy.UInt64] = addw(a_lo, b_lo) - (hi_carry1, c_mid): tuple[algopy.UInt64, algopy.UInt64] = addw(a_hi, b_hi) - (hi_carry2, c_mid): tuple[algopy.UInt64, algopy.UInt64] = addw(c_mid, lo_carry) - (did_overflow, c_hi): tuple[algopy.UInt64, algopy.UInt64] = addw(hi_carry1, hi_carry2) + (a_hi, a_lo): tuple = a + (b_hi, b_lo): tuple = b + (lo_carry, c_lo): tuple = addw(a_lo, b_lo) + (hi_carry1, c_mid): tuple = addw(a_hi, b_hi) + (hi_carry2, c_mid): tuple = addw(c_mid, lo_carry) + (did_overflow, c_hi): tuple = addw(hi_carry1, hi_carry2) assert(!(reinterpret_cast(did_overflow)), comment="is such a thing even possible? 👽") return (c_hi, c_mid, c_lo) } -subroutine test_tuple_swap(zero: algopy.UInt64): None +subroutine test_tuple_swap(zero: uint64): void { - a: algopy.UInt64 = zero + 1u - b: algopy.UInt64 = zero + 2u - (a, b): tuple[algopy.UInt64, algopy.UInt64] = (b, a) + a: uint64 = zero + 1u + b: uint64 = zero + 2u + (a, b): tuple = (b, a) assert(a == 2u, comment="a should be two") assert(b == 1u, comment="b should be one") } -subroutine slicing(values: tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64, algopy.UInt64]): None +subroutine slicing(values: tuple): void { - one_to_three: tuple[algopy.UInt64, algopy.UInt64, algopy.UInt64] = values[0u:3u] + one_to_three: tuple = values[0u:3u] assert(test_cases.tuple_support.tuple_support::add_three_values(one_to_three) == values[0] + values[1] + values[2]) assert(one_to_three[1u:2u][0] == one_to_three[1]) } \ No newline at end of file diff --git a/test_cases/typed_abi_call/out/client_Logger.py b/test_cases/typed_abi_call/out/client_Logger.py index d951e0053..60a7fd2a2 100644 --- a/test_cases/typed_abi_call/out/client_Logger.py +++ b/test_cases/typed_abi_call/out/client_Logger.py @@ -16,13 +16,13 @@ def echo( @algopy.arc4.abimethod(name='log') def log_uint64( self, - value: algopy.arc4.UInt64, + value: algopy.arc4.UIntN[typing.Literal[64]], ) -> None: ... @algopy.arc4.abimethod(name='log') def log_uint512( self, - value: algopy.arc4.UInt512, + value: algopy.arc4.BigUIntN[typing.Literal[512]], ) -> None: ... @algopy.arc4.abimethod(name='log') @@ -66,45 +66,45 @@ def echo_native_bytes( @algopy.arc4.abimethod def echo_native_uint64( self, - value: algopy.arc4.UInt64, - ) -> algopy.arc4.UInt64: ... + value: algopy.arc4.UIntN[typing.Literal[64]], + ) -> algopy.arc4.UIntN[typing.Literal[64]]: ... @algopy.arc4.abimethod def echo_native_biguint( self, - value: algopy.arc4.UInt512, - ) -> algopy.arc4.UInt512: ... + value: algopy.arc4.BigUIntN[typing.Literal[512]], + ) -> algopy.arc4.BigUIntN[typing.Literal[512]]: ... @algopy.arc4.abimethod def echo_native_tuple( self, s: algopy.arc4.String, b: algopy.arc4.DynamicBytes, - u: algopy.arc4.UInt64, - bu: algopy.arc4.UInt512, - ) -> algopy.arc4.Tuple[algopy.arc4.String, algopy.arc4.DynamicBytes, algopy.arc4.UInt64, algopy.arc4.UInt512]: ... + u: algopy.arc4.UIntN[typing.Literal[64]], + bu: algopy.arc4.BigUIntN[typing.Literal[512]], + ) -> algopy.arc4.Tuple[algopy.arc4.String, algopy.arc4.DynamicBytes, algopy.arc4.UIntN[typing.Literal[64]], algopy.arc4.BigUIntN[typing.Literal[512]]]: ... @algopy.arc4.abimethod def return_args_after_14th( self, - _a1: algopy.arc4.UInt64, - _a2: algopy.arc4.UInt64, - _a3: algopy.arc4.UInt64, - _a4: algopy.arc4.UInt64, - _a5: algopy.arc4.UInt64, - _a6: algopy.arc4.UInt64, - _a7: algopy.arc4.UInt64, - _a8: algopy.arc4.UInt64, - _a9: algopy.arc4.UInt64, - _a10: algopy.arc4.UInt64, - _a11: algopy.arc4.UInt64, - _a12: algopy.arc4.UInt64, - _a13: algopy.arc4.UInt64, - _a14: algopy.arc4.UInt64, - a15: algopy.arc4.UInt8, - a16: algopy.arc4.UInt8, - a17: algopy.arc4.UInt8, - a18: algopy.arc4.UInt8, - a19: algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8], - a20: algopy.arc4.UInt8, + _a1: algopy.arc4.UIntN[typing.Literal[64]], + _a2: algopy.arc4.UIntN[typing.Literal[64]], + _a3: algopy.arc4.UIntN[typing.Literal[64]], + _a4: algopy.arc4.UIntN[typing.Literal[64]], + _a5: algopy.arc4.UIntN[typing.Literal[64]], + _a6: algopy.arc4.UIntN[typing.Literal[64]], + _a7: algopy.arc4.UIntN[typing.Literal[64]], + _a8: algopy.arc4.UIntN[typing.Literal[64]], + _a9: algopy.arc4.UIntN[typing.Literal[64]], + _a10: algopy.arc4.UIntN[typing.Literal[64]], + _a11: algopy.arc4.UIntN[typing.Literal[64]], + _a12: algopy.arc4.UIntN[typing.Literal[64]], + _a13: algopy.arc4.UIntN[typing.Literal[64]], + _a14: algopy.arc4.UIntN[typing.Literal[64]], + a15: algopy.arc4.UIntN[typing.Literal[8]], + a16: algopy.arc4.UIntN[typing.Literal[8]], + a17: algopy.arc4.UIntN[typing.Literal[8]], + a18: algopy.arc4.UIntN[typing.Literal[8]], + a19: algopy.arc4.Tuple[algopy.arc4.UIntN[typing.Literal[8]], algopy.arc4.UIntN[typing.Literal[8]], algopy.arc4.UIntN[typing.Literal[8]], algopy.arc4.UIntN[typing.Literal[8]]], + a20: algopy.arc4.UIntN[typing.Literal[8]], ) -> algopy.arc4.DynamicBytes: ... diff --git a/test_cases/typed_abi_call/out/logger.awst b/test_cases/typed_abi_call/out/logger.awst index a2149a5e0..3b2ede905 100644 --- a/test_cases/typed_abi_call/out/logger.awst +++ b/test_cases/typed_abi_call/out/logger.awst @@ -2,70 +2,70 @@ LOG_METHOD_NAME = 'log' contract Logger { - abimethod echo(value: algopy.arc4.String): algopy.arc4.String + abimethod echo(value: arc4.string): arc4.string { - return arc4_encode('echo: ', algopy.arc4.String) + value + return arc4_encode('echo: ', arc4.string) + value } - abimethod[name_override=log] log_uint64(value: algopy.arc4.UInt64): None + abimethod[name_override=log] log_uint64(value: arc4.uint64): void { log(value) } - abimethod[name_override=log] log_uint512(value: algopy.arc4.UInt512): None + abimethod[name_override=log] log_uint512(value: arc4.uint512): void { log(value) } - abimethod[name_override=log] log_string(value: algopy.arc4.String): None + abimethod[name_override=log] log_string(value: arc4.string): void { - log(arc4_decode(value, algopy.String)) + log(arc4_decode(value, string)) } - abimethod[name_override=log] log_bool(value: algopy.arc4.Bool): None + abimethod[name_override=log] log_bool(value: arc4.bool): void { log((arc4_decode(value, bool)) ? ('True') : ('False')) } - abimethod[name_override=log] log_bytes(value: algopy.arc4.DynamicBytes): None + abimethod[name_override=log] log_bytes(value: arc4.dynamic_bytes): void { - log(arc4_decode(value, algopy.Bytes)) + log(extract<2, 0>(reinterpret_cast(value))) } - abimethod[name_override=log] log_asset_account_app(asset: algopy.Asset, account: algopy.Account, app: algopy.Application): None + abimethod[name_override=log] log_asset_account_app(asset: asset, account: account, app: application): void { - log(concat(concat(concat(concat(checked_maybe(asset_params_get(asset)), ''), reinterpret_cast(account)), ''), checked_maybe(app_params_get(app)))) + log(concat(concat(concat(concat(checked_maybe(asset_params_get(asset)), ''), reinterpret_cast(account)), ''), checked_maybe(app_params_get(app)))) } - abimethod echo_native_string(value: algopy.String): algopy.String + abimethod echo_native_string(value: string): string { return 'echo: ' + value } - abimethod echo_native_bytes(value: algopy.Bytes): algopy.Bytes + abimethod echo_native_bytes(value: bytes): bytes { return 'echo: ' + value } - abimethod echo_native_uint64(value: algopy.UInt64): algopy.UInt64 + abimethod echo_native_uint64(value: uint64): uint64 { return value + 1u } - abimethod echo_native_biguint(value: algopy.BigUInt): algopy.BigUInt + abimethod echo_native_biguint(value: biguint): biguint { return value b+ 1n } - abimethod echo_native_tuple(s: algopy.String, b: algopy.Bytes, u: algopy.UInt64, bu: algopy.BigUInt): tuple[algopy.String, algopy.Bytes, algopy.UInt64, algopy.BigUInt] + abimethod echo_native_tuple(s: string, b: bytes, u: uint64, bu: biguint): tuple { return ('echo: ' + s, 'echo: ' + b, u + 1u, bu b+ 1n) } - abimethod return_args_after_14th(_a1: algopy.arc4.UInt64, _a2: algopy.arc4.UInt64, _a3: algopy.arc4.UInt64, _a4: algopy.arc4.UInt64, _a5: algopy.arc4.UInt64, _a6: algopy.arc4.UInt64, _a7: algopy.arc4.UInt64, _a8: algopy.arc4.UInt64, _a9: algopy.arc4.UInt64, _a10: algopy.arc4.UInt64, _a11: algopy.arc4.UInt64, _a12: algopy.arc4.UInt64, _a13: algopy.arc4.UInt64, _a14: algopy.arc4.UInt64, a15: algopy.arc4.UInt8, a16: algopy.arc4.UInt8, a17: algopy.arc4.UInt8, a18: algopy.arc4.UInt8, a19: algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8], a20: algopy.arc4.UInt8): algopy.arc4.DynamicBytes + abimethod return_args_after_14th(_a1: arc4.uint64, _a2: arc4.uint64, _a3: arc4.uint64, _a4: arc4.uint64, _a5: arc4.uint64, _a6: arc4.uint64, _a7: arc4.uint64, _a8: arc4.uint64, _a9: arc4.uint64, _a10: arc4.uint64, _a11: arc4.uint64, _a12: arc4.uint64, _a13: arc4.uint64, _a14: arc4.uint64, a15: arc4.uint8, a16: arc4.uint8, a17: arc4.uint8, a18: arc4.uint8, a19: arc4.tuple, a20: arc4.uint8): arc4.dynamic_bytes { - last_arg: algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8], algopy.arc4.UInt8] = arc4_encode((a15, a16, a17, a18, a19, a20), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8], algopy.arc4.UInt8]) - assert(txna() == reinterpret_cast(last_arg)) - return arc4_encode(reinterpret_cast(last_arg), algopy.arc4.DynamicBytes) + last_arg: arc4.tuple,arc4.uint8> = arc4_encode((a15, a16, a17, a18, a19, a20), arc4.tuple,arc4.uint8>) + assert(txna() == reinterpret_cast(last_arg)) + return arc4_encode(reinterpret_cast(last_arg), arc4.dynamic_bytes) } } \ No newline at end of file diff --git a/test_cases/typed_abi_call/out/typed_c2c.awst b/test_cases/typed_abi_call/out/typed_c2c.awst index d5ceb9e9a..197bc0071 100644 --- a/test_cases/typed_abi_call/out/typed_c2c.awst +++ b/test_cases/typed_abi_call/out/typed_c2c.awst @@ -1,124 +1,124 @@ contract Greeter { - abimethod test_method_selector_kinds(app: algopy.Application): None + abimethod test_method_selector_kinds(app: application): void { - (result, _txn): tuple[algopy.arc4.String, algopy.itxn.ApplicationCallInnerTransaction] = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=0, source=SINGLE_EVAL(id=1, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test1', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=0, source=SINGLE_EVAL(id=1, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test1', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=1, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test1', algopy.arc4.String)), ApplicationID=app)))) - assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test1', algopy.arc4.String))) - (result, _txn): tuple[algopy.arc4.String, algopy.itxn.ApplicationCallInnerTransaction] = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=2, source=SINGLE_EVAL(id=3, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test2', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=2, source=SINGLE_EVAL(id=3, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test2', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=3, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test2', algopy.arc4.String)), ApplicationID=app)))) - assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test2', algopy.arc4.String))) - (result, _txn): tuple[algopy.arc4.String, algopy.itxn.ApplicationCallInnerTransaction] = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=4, source=SINGLE_EVAL(id=5, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test3', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=4, source=SINGLE_EVAL(id=5, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test3', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=5, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test3', algopy.arc4.String)), ApplicationID=app)))) - assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test3', algopy.arc4.String))) - (result, _txn): tuple[algopy.arc4.String, algopy.itxn.ApplicationCallInnerTransaction] = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=6, source=SINGLE_EVAL(id=7, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test4', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=6, source=SINGLE_EVAL(id=7, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test4', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=7, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test4', algopy.arc4.String)), ApplicationID=app)))) - assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test4', algopy.arc4.String))) - (result, _txn): tuple[algopy.arc4.String, algopy.itxn.ApplicationCallInnerTransaction] = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=8, source=SINGLE_EVAL(id=9, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test5', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=8, source=SINGLE_EVAL(id=9, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test5', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=9, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test5', algopy.arc4.String)), ApplicationID=app)))) - assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test5', algopy.arc4.String))) + (result, _txn): tuple = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=0, source=SINGLE_EVAL(id=1, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test1', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=0, source=SINGLE_EVAL(id=1, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test1', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=1, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test1', arc4.string)), ApplicationID=app)))) + assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test1', arc4.string))) + (result, _txn): tuple = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=2, source=SINGLE_EVAL(id=3, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test2', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=2, source=SINGLE_EVAL(id=3, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test2', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=3, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test2', arc4.string)), ApplicationID=app)))) + assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test2', arc4.string))) + (result, _txn): tuple = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=4, source=SINGLE_EVAL(id=5, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test3', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=4, source=SINGLE_EVAL(id=5, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test3', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=5, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test3', arc4.string)), ApplicationID=app)))) + assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test3', arc4.string))) + (result, _txn): tuple = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=6, source=SINGLE_EVAL(id=7, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test4', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=6, source=SINGLE_EVAL(id=7, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test4', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=7, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test4', arc4.string)), ApplicationID=app)))) + assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test4', arc4.string))) + (result, _txn): tuple = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=8, source=SINGLE_EVAL(id=9, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test5', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=8, source=SINGLE_EVAL(id=9, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test5', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=9, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('test5', arc4.string)), ApplicationID=app)))) + assert(reinterpret_cast(result) == reinterpret_cast(arc4_encode('echo: test5', arc4.string))) } - abimethod test_method_overload(app: algopy.Application): None + abimethod test_method_overload(app: application): void { - (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=10, source=SINGLE_EVAL(id=11, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('typed + ignore', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=10, source=SINGLE_EVAL(id=11, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('typed + ignore', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=11, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('typed + ignore', algopy.arc4.String)), ApplicationID=app)))) - assert(reinterpret_cast(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=12, source=itxn())), extract<0, 4>(SINGLE_EVAL(id=12, source=itxn())) == hex<"151F7C75">)))) == reinterpret_cast(arc4_encode('echo: typed + ignore', algopy.arc4.String))) - submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('untyped + ignore', algopy.arc4.String)), ApplicationID=app)) - assert(reinterpret_cast(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=13, source=itxn())), extract<0, 4>(SINGLE_EVAL(id=13, source=itxn())) == hex<"151F7C75">)))) == reinterpret_cast(arc4_encode('echo: untyped + ignore', algopy.arc4.String))) - result: tuple[algopy.arc4.String, algopy.itxn.ApplicationCallInnerTransaction] = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=14, source=SINGLE_EVAL(id=15, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('tuple', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=14, source=SINGLE_EVAL(id=15, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('tuple', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=15, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('tuple', algopy.arc4.String)), ApplicationID=app)))) - assert(reinterpret_cast(result[0]) == reinterpret_cast(arc4_encode('echo: tuple', algopy.arc4.String))) - assert(reinterpret_cast(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=16, source=result[1].LastLog)), extract<0, 4>(SINGLE_EVAL(id=16, source=result[1].LastLog)) == hex<"151F7C75">)))) == reinterpret_cast(arc4_encode('echo: tuple', algopy.arc4.String))) - txn_result: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('untyped', algopy.arc4.String)), ApplicationID=app)) - assert(reinterpret_cast(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=17, source=txn_result.LastLog)), extract<0, 4>(SINGLE_EVAL(id=17, source=txn_result.LastLog)) == hex<"151F7C75">)))) == reinterpret_cast(arc4_encode('echo: untyped', algopy.arc4.String))) + (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=10, source=SINGLE_EVAL(id=11, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('typed + ignore', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=10, source=SINGLE_EVAL(id=11, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('typed + ignore', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=11, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('typed + ignore', arc4.string)), ApplicationID=app)))) + assert(reinterpret_cast(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=12, source=itxn())), extract<0, 4>(SINGLE_EVAL(id=12, source=itxn())) == hex<"151F7C75">)))) == reinterpret_cast(arc4_encode('echo: typed + ignore', arc4.string))) + submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('untyped + ignore', arc4.string)), ApplicationID=app)) + assert(reinterpret_cast(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=13, source=itxn())), extract<0, 4>(SINGLE_EVAL(id=13, source=itxn())) == hex<"151F7C75">)))) == reinterpret_cast(arc4_encode('echo: untyped + ignore', arc4.string))) + result: tuple = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=14, source=SINGLE_EVAL(id=15, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('tuple', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=14, source=SINGLE_EVAL(id=15, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('tuple', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=15, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('tuple', arc4.string)), ApplicationID=app)))) + assert(reinterpret_cast(result[0]) == reinterpret_cast(arc4_encode('echo: tuple', arc4.string))) + assert(reinterpret_cast(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=16, source=result[1].LastLog)), extract<0, 4>(SINGLE_EVAL(id=16, source=result[1].LastLog)) == hex<"151F7C75">)))) == reinterpret_cast(arc4_encode('echo: tuple', arc4.string))) + txn_result: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo(string)string"), arc4_encode('untyped', arc4.string)), ApplicationID=app)) + assert(reinterpret_cast(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=17, source=txn_result.LastLog)), extract<0, 4>(SINGLE_EVAL(id=17, source=txn_result.LastLog)) == hex<"151F7C75">)))) == reinterpret_cast(arc4_encode('echo: untyped', arc4.string))) } - abimethod test_arg_conversion(app: algopy.Application): None + abimethod test_arg_conversion(app: application): void { - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('converted1', algopy.arc4.String)), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('converted1', arc4.string)), ApplicationID=app)) assert(txn.LastLog == 'converted1') - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(uint64)void"), 2arc4u64), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(uint64)void"), 2arc4u64), ApplicationID=app)) assert(txn.LastLog == itob(2u)) - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(uint512)void"), 3arc4n512), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(uint512)void"), 3arc4n512), ApplicationID=app)) assert(txn.LastLog == bzero(56u) + itob(3u)) - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(byte[])void"), arc4_encode(hex<"34">, algopy.arc4.DynamicBytes)), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(byte[])void"), arc4_encode(hex<"34">, arc4.dynamic_bytes)), ApplicationID=app)) assert(txn.LastLog == '4') - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(bool)void"), arc4_encode(true, algopy.arc4.Bool)), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(bool)void"), arc4_encode(true, arc4.bool)), ApplicationID=app)) assert(txn.LastLog == 'True') } - abimethod test_15plus_args(app: algopy.Application): None + abimethod test_15plus_args(app: application): void { - (result, txn): tuple[algopy.arc4.DynamicBytes, algopy.itxn.ApplicationCallInnerTransaction] = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=18, source=SINGLE_EVAL(id=19, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("return_args_after_14th(uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint8,uint8,uint8,uint8,(uint8,uint8,uint8,uint8),uint8)byte[]"), 1arc4u64, 2arc4u64, 3arc4u64, 4arc4u64, 5arc4u64, 6arc4u64, 7arc4u64, 8arc4u64, 9arc4u64, 10arc4u64, 11arc4u64, 12arc4u64, 13arc4u64, 14arc4u64, arc4_encode((15arc4u8, 16arc4u8, 17arc4u8, 18arc4u8, arc4_encode((222arc4u8, 173arc4u8, 190arc4u8, 239arc4u8), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8]), 20arc4u8), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8], algopy.arc4.UInt8])), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=18, source=SINGLE_EVAL(id=19, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("return_args_after_14th(uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint8,uint8,uint8,uint8,(uint8,uint8,uint8,uint8),uint8)byte[]"), 1arc4u64, 2arc4u64, 3arc4u64, 4arc4u64, 5arc4u64, 6arc4u64, 7arc4u64, 8arc4u64, 9arc4u64, 10arc4u64, 11arc4u64, 12arc4u64, 13arc4u64, 14arc4u64, arc4_encode((15arc4u8, 16arc4u8, 17arc4u8, 18arc4u8, arc4_encode((222arc4u8, 173arc4u8, 190arc4u8, 239arc4u8), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8]), 20arc4u8), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8], algopy.arc4.UInt8])), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=19, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("return_args_after_14th(uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint8,uint8,uint8,uint8,(uint8,uint8,uint8,uint8),uint8)byte[]"), 1arc4u64, 2arc4u64, 3arc4u64, 4arc4u64, 5arc4u64, 6arc4u64, 7arc4u64, 8arc4u64, 9arc4u64, 10arc4u64, 11arc4u64, 12arc4u64, 13arc4u64, 14arc4u64, arc4_encode((15arc4u8, 16arc4u8, 17arc4u8, 18arc4u8, arc4_encode((222arc4u8, 173arc4u8, 190arc4u8, 239arc4u8), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8]), 20arc4u8), algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.Tuple[algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8, algopy.arc4.UInt8], algopy.arc4.UInt8])), ApplicationID=app)))) - assert(arc4_decode(result, algopy.Bytes) == hex<"0F101112DEADBEEF14">) + (result, txn): tuple = (reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=18, source=SINGLE_EVAL(id=19, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("return_args_after_14th(uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint8,uint8,uint8,uint8,(uint8,uint8,uint8,uint8),uint8)byte[]"), 1arc4u64, 2arc4u64, 3arc4u64, 4arc4u64, 5arc4u64, 6arc4u64, 7arc4u64, 8arc4u64, 9arc4u64, 10arc4u64, 11arc4u64, 12arc4u64, 13arc4u64, 14arc4u64, arc4_encode((15arc4u8, 16arc4u8, 17arc4u8, 18arc4u8, arc4_encode((222arc4u8, 173arc4u8, 190arc4u8, 239arc4u8), arc4.tuple), 20arc4u8), arc4.tuple,arc4.uint8>)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=18, source=SINGLE_EVAL(id=19, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("return_args_after_14th(uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint8,uint8,uint8,uint8,(uint8,uint8,uint8,uint8),uint8)byte[]"), 1arc4u64, 2arc4u64, 3arc4u64, 4arc4u64, 5arc4u64, 6arc4u64, 7arc4u64, 8arc4u64, 9arc4u64, 10arc4u64, 11arc4u64, 12arc4u64, 13arc4u64, 14arc4u64, arc4_encode((15arc4u8, 16arc4u8, 17arc4u8, 18arc4u8, arc4_encode((222arc4u8, 173arc4u8, 190arc4u8, 239arc4u8), arc4.tuple), 20arc4u8), arc4.tuple,arc4.uint8>)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), SINGLE_EVAL(id=19, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("return_args_after_14th(uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint8,uint8,uint8,uint8,(uint8,uint8,uint8,uint8),uint8)byte[]"), 1arc4u64, 2arc4u64, 3arc4u64, 4arc4u64, 5arc4u64, 6arc4u64, 7arc4u64, 8arc4u64, 9arc4u64, 10arc4u64, 11arc4u64, 12arc4u64, 13arc4u64, 14arc4u64, arc4_encode((15arc4u8, 16arc4u8, 17arc4u8, 18arc4u8, arc4_encode((222arc4u8, 173arc4u8, 190arc4u8, 239arc4u8), arc4.tuple), 20arc4u8), arc4.tuple,arc4.uint8>)), ApplicationID=app)))) + assert(extract<2, 0>(reinterpret_cast(result)) == hex<"0F101112DEADBEEF14">) } - abimethod test_void(app: algopy.Application): None + abimethod test_void(app: application): void { - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('World1', algopy.arc4.String)), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('World1', arc4.string)), ApplicationID=app)) assert(txn.LastLog == 'World1') - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('World2', algopy.arc4.String)), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('World2', arc4.string)), ApplicationID=app)) assert(txn.LastLog == 'World2') - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('World3', algopy.arc4.String)), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('World3', arc4.string)), ApplicationID=app)) assert(txn.LastLog == 'World3') - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('World4', algopy.arc4.String)), ApplicationID=app)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(string)void"), arc4_encode('World4', arc4.string)), ApplicationID=app)) assert(txn.LastLog == 'World4') } - abimethod test_ref_types(app: algopy.Application, asset: algopy.Asset): None + abimethod test_ref_types(app: application, asset: asset): void { - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(asset,account,application)void"), hex<"00">, hex<"01">, hex<"01">), Accounts=(global()), Applications=(app), Assets=(asset), ApplicationID=app)) - assert(txn.LastLog == checked_maybe(asset_params_get(asset)) + reinterpret_cast(global()) + reinterpret_cast(checked_maybe(app_params_get(app)))) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("log(asset,account,application)void"), hex<"00">, hex<"01">, hex<"01">), Accounts=(global()), Applications=(app), Assets=(asset), ApplicationID=app)) + assert(txn.LastLog == checked_maybe(asset_params_get(asset)) + reinterpret_cast(global()) + reinterpret_cast(checked_maybe(app_params_get(app)))) } - abimethod test_native_string(app: algopy.Application): None + abimethod test_native_string(app: application): void { - (result1, _txn): tuple[algopy.String, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=20, source=SINGLE_EVAL(id=21, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=20, source=SINGLE_EVAL(id=21, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.String), SINGLE_EVAL(id=21, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app)))) + (result1, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=20, source=SINGLE_EVAL(id=21, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=20, source=SINGLE_EVAL(id=21, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), string), SINGLE_EVAL(id=21, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app)))) assert(result1 == 'echo: s') - (result2, _txn): tuple[algopy.String, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=22, source=SINGLE_EVAL(id=23, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=22, source=SINGLE_EVAL(id=23, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.String), SINGLE_EVAL(id=23, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app)))) + (result2, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=22, source=SINGLE_EVAL(id=23, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=22, source=SINGLE_EVAL(id=23, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), string), SINGLE_EVAL(id=23, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app)))) assert(result2 == result1) - (result3, _txn): tuple[algopy.String, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=24, source=SINGLE_EVAL(id=25, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=24, source=SINGLE_EVAL(id=25, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.String), SINGLE_EVAL(id=25, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', algopy.arc4.String)), ApplicationID=app)))) + (result3, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=24, source=SINGLE_EVAL(id=25, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=24, source=SINGLE_EVAL(id=25, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), string), SINGLE_EVAL(id=25, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_string(string)string"), arc4_encode('s', arc4.string)), ApplicationID=app)))) assert(result3 == result1) } - abimethod test_native_bytes(app: algopy.Application): None + abimethod test_native_bytes(app: application): void { - (result1, _txn): tuple[algopy.Bytes, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=26, source=SINGLE_EVAL(id=27, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, algopy.arc4.DynamicBytes)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=26, source=SINGLE_EVAL(id=27, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, algopy.arc4.DynamicBytes)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.Bytes), SINGLE_EVAL(id=27, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, algopy.arc4.DynamicBytes)), ApplicationID=app)))) + (result1, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=26, source=SINGLE_EVAL(id=27, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, arc4.dynamic_bytes)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=26, source=SINGLE_EVAL(id=27, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, arc4.dynamic_bytes)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), bytes), SINGLE_EVAL(id=27, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, arc4.dynamic_bytes)), ApplicationID=app)))) assert(result1 == 'echo: b') - (result2, _txn): tuple[algopy.Bytes, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=28, source=SINGLE_EVAL(id=29, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), reinterpret_cast(concat(substring<6, 8>(itob(len(SINGLE_EVAL(id=30, source='b')))), SINGLE_EVAL(id=30, source='b')))), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=28, source=SINGLE_EVAL(id=29, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), reinterpret_cast(concat(substring<6, 8>(itob(len(SINGLE_EVAL(id=30, source='b')))), SINGLE_EVAL(id=30, source='b')))), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.Bytes), SINGLE_EVAL(id=29, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), reinterpret_cast(concat(substring<6, 8>(itob(len(SINGLE_EVAL(id=30, source='b')))), SINGLE_EVAL(id=30, source='b')))), ApplicationID=app)))) + (result2, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=28, source=SINGLE_EVAL(id=29, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), reinterpret_cast(concat(substring<6, 8>(itob(len(SINGLE_EVAL(id=30, source='b')))), SINGLE_EVAL(id=30, source='b')))), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=28, source=SINGLE_EVAL(id=29, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), reinterpret_cast(concat(substring<6, 8>(itob(len(SINGLE_EVAL(id=30, source='b')))), SINGLE_EVAL(id=30, source='b')))), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), bytes), SINGLE_EVAL(id=29, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), reinterpret_cast(concat(substring<6, 8>(itob(len(SINGLE_EVAL(id=30, source='b')))), SINGLE_EVAL(id=30, source='b')))), ApplicationID=app)))) assert(result2 == result1) - (result3, _txn): tuple[algopy.Bytes, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=31, source=SINGLE_EVAL(id=32, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, algopy.arc4.DynamicBytes)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=31, source=SINGLE_EVAL(id=32, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, algopy.arc4.DynamicBytes)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.Bytes), SINGLE_EVAL(id=32, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, algopy.arc4.DynamicBytes)), ApplicationID=app)))) + (result3, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=31, source=SINGLE_EVAL(id=32, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, arc4.dynamic_bytes)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=31, source=SINGLE_EVAL(id=32, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, arc4.dynamic_bytes)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), bytes), SINGLE_EVAL(id=32, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_bytes(byte[])byte[]"), arc4_encode(hex<"62">, arc4.dynamic_bytes)), ApplicationID=app)))) assert(result3 == result1) } - abimethod test_native_uint64(app: algopy.Application): None + abimethod test_native_uint64(app: application): void { - (result1, _txn): tuple[algopy.UInt64, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=33, source=SINGLE_EVAL(id=34, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=33, source=SINGLE_EVAL(id=34, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.UInt64), SINGLE_EVAL(id=34, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app)))) + (result1, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=33, source=SINGLE_EVAL(id=34, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=33, source=SINGLE_EVAL(id=34, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), uint64), SINGLE_EVAL(id=34, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app)))) assert(result1 == 2u) - (result2, _txn): tuple[algopy.UInt64, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=35, source=SINGLE_EVAL(id=36, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), arc4_encode(1u, algopy.arc4.UInt64)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=35, source=SINGLE_EVAL(id=36, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), arc4_encode(1u, algopy.arc4.UInt64)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.UInt64), SINGLE_EVAL(id=36, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), arc4_encode(1u, algopy.arc4.UInt64)), ApplicationID=app)))) + (result2, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=35, source=SINGLE_EVAL(id=36, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), arc4_encode(1u, arc4.uint64)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=35, source=SINGLE_EVAL(id=36, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), arc4_encode(1u, arc4.uint64)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), uint64), SINGLE_EVAL(id=36, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), arc4_encode(1u, arc4.uint64)), ApplicationID=app)))) assert(result2 == result1) - (result3, _txn): tuple[algopy.UInt64, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=37, source=SINGLE_EVAL(id=38, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=37, source=SINGLE_EVAL(id=38, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.UInt64), SINGLE_EVAL(id=38, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app)))) + (result3, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=37, source=SINGLE_EVAL(id=38, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=37, source=SINGLE_EVAL(id=38, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), uint64), SINGLE_EVAL(id=38, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_uint64(uint64)uint64"), 1arc4u64), ApplicationID=app)))) assert(result3 == result1) } - abimethod test_native_biguint(app: algopy.Application): None + abimethod test_native_biguint(app: application): void { - (result1, _txn): tuple[algopy.BigUInt, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=39, source=SINGLE_EVAL(id=40, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=39, source=SINGLE_EVAL(id=40, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.BigUInt), SINGLE_EVAL(id=40, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app)))) + (result1, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=39, source=SINGLE_EVAL(id=40, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=39, source=SINGLE_EVAL(id=40, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), biguint), SINGLE_EVAL(id=40, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app)))) assert(result1 == 3n) - (result2, _txn): tuple[algopy.BigUInt, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=41, source=SINGLE_EVAL(id=42, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), arc4_encode(2n, algopy.arc4.UInt512)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=41, source=SINGLE_EVAL(id=42, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), arc4_encode(2n, algopy.arc4.UInt512)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.BigUInt), SINGLE_EVAL(id=42, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), arc4_encode(2n, algopy.arc4.UInt512)), ApplicationID=app)))) + (result2, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=41, source=SINGLE_EVAL(id=42, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), arc4_encode(2n, arc4.uint512)), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=41, source=SINGLE_EVAL(id=42, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), arc4_encode(2n, arc4.uint512)), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), biguint), SINGLE_EVAL(id=42, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), arc4_encode(2n, arc4.uint512)), ApplicationID=app)))) assert(result2 == result1) - (result3, _txn): tuple[algopy.BigUInt, algopy.itxn.ApplicationCallInnerTransaction] = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=43, source=SINGLE_EVAL(id=44, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=43, source=SINGLE_EVAL(id=44, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), algopy.BigUInt), SINGLE_EVAL(id=44, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app)))) + (result3, _txn): tuple = (arc4_decode(reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=43, source=SINGLE_EVAL(id=44, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app))).LastLog)), extract<0, 4>(SINGLE_EVAL(id=43, source=SINGLE_EVAL(id=44, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app))).LastLog)) == hex<"151F7C75">))), biguint), SINGLE_EVAL(id=44, source=submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_biguint(uint512)uint512"), 2arc4n512), ApplicationID=app)))) assert(result3 == result1) } - abimethod test_native_tuple(app: algopy.Application): None + abimethod test_native_tuple(app: application): void { - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_tuple(string,byte[],uint64,uint512)(string,byte[],uint64,uint512)"), arc4_encode('s1', algopy.arc4.String), arc4_encode(hex<"6231">, algopy.arc4.DynamicBytes), 1arc4u64, 2arc4n512), ApplicationID=app)) - result1: algopy.arc4.Tuple[algopy.arc4.String, algopy.arc4.DynamicBytes, algopy.arc4.UInt64, algopy.arc4.UInt512] = reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=45, source=txn.LastLog)), extract<0, 4>(SINGLE_EVAL(id=45, source=txn.LastLog)) == hex<"151F7C75">))) - (s, b, u, bu): tuple[algopy.arc4.String, algopy.arc4.DynamicBytes, algopy.arc4.UInt64, algopy.arc4.UInt512] = arc4_decode(result1, tuple[algopy.arc4.String, algopy.arc4.DynamicBytes, algopy.arc4.UInt64, algopy.arc4.UInt512]) - assert(arc4_decode(s, algopy.String) == 'echo: s1') - assert(arc4_decode(b, algopy.Bytes) == 'echo: b1') - assert(arc4_decode(u, algopy.UInt64) == 2u) - assert(arc4_decode(bu, algopy.BigUInt) == 3n) - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_tuple(string,byte[],uint64,uint512)(string,byte[],uint64,uint512)"), arc4_encode('s1', algopy.arc4.String), reinterpret_cast(concat(substring<6, 8>(itob(len(SINGLE_EVAL(id=46, source='b1')))), SINGLE_EVAL(id=46, source='b1'))), arc4_encode(1u, algopy.arc4.UInt64), arc4_encode(2n, algopy.arc4.UInt512)), ApplicationID=app)) - result2: algopy.arc4.Tuple[algopy.arc4.String, algopy.arc4.DynamicBytes, algopy.arc4.UInt64, algopy.arc4.UInt512] = reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=47, source=txn.LastLog)), extract<0, 4>(SINGLE_EVAL(id=47, source=txn.LastLog)) == hex<"151F7C75">))) - assert(reinterpret_cast(result1) == reinterpret_cast(result2)) - txn: algopy.itxn.ApplicationCallInnerTransaction = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_tuple(string,byte[],uint64,uint512)(string,byte[],uint64,uint512)"), arc4_encode('s1', algopy.arc4.String), arc4_encode(hex<"6231">, algopy.arc4.DynamicBytes), 1arc4u64, 2arc4n512), ApplicationID=app)) - result3: algopy.arc4.Tuple[algopy.arc4.String, algopy.arc4.DynamicBytes, algopy.arc4.UInt64, algopy.arc4.UInt512] = reinterpret_cast(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=48, source=txn.LastLog)), extract<0, 4>(SINGLE_EVAL(id=48, source=txn.LastLog)) == hex<"151F7C75">))) - assert(reinterpret_cast(result1) == reinterpret_cast(result3)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_tuple(string,byte[],uint64,uint512)(string,byte[],uint64,uint512)"), arc4_encode('s1', arc4.string), arc4_encode(hex<"6231">, arc4.dynamic_bytes), 1arc4u64, 2arc4n512), ApplicationID=app)) + result1: arc4.tuple = reinterpret_cast>(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=45, source=txn.LastLog)), extract<0, 4>(SINGLE_EVAL(id=45, source=txn.LastLog)) == hex<"151F7C75">))) + (s, b, u, bu): tuple = arc4_decode(result1, tuple) + assert(arc4_decode(s, string) == 'echo: s1') + assert(extract<2, 0>(reinterpret_cast(b)) == 'echo: b1') + assert(arc4_decode(u, uint64) == 2u) + assert(arc4_decode(bu, biguint) == 3n) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_tuple(string,byte[],uint64,uint512)(string,byte[],uint64,uint512)"), arc4_encode('s1', arc4.string), reinterpret_cast(concat(substring<6, 8>(itob(len(SINGLE_EVAL(id=46, source='b1')))), SINGLE_EVAL(id=46, source='b1'))), arc4_encode(1u, arc4.uint64), arc4_encode(2n, arc4.uint512)), ApplicationID=app)) + result2: arc4.tuple = reinterpret_cast>(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=47, source=txn.LastLog)), extract<0, 4>(SINGLE_EVAL(id=47, source=txn.LastLog)) == hex<"151F7C75">))) + assert(reinterpret_cast(result1) == reinterpret_cast(result2)) + txn: inner_transaction_appl = submit_txn(create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("echo_native_tuple(string,byte[],uint64,uint512)(string,byte[],uint64,uint512)"), arc4_encode('s1', arc4.string), arc4_encode(hex<"6231">, arc4.dynamic_bytes), 1arc4u64, 2arc4n512), ApplicationID=app)) + result3: arc4.tuple = reinterpret_cast>(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=48, source=txn.LastLog)), extract<0, 4>(SINGLE_EVAL(id=48, source=txn.LastLog)) == hex<"151F7C75">))) + assert(reinterpret_cast(result1) == reinterpret_cast(result3)) } } \ No newline at end of file diff --git a/test_cases/unary/out/contract.awst b/test_cases/unary/out/contract.awst index 4ada44a44..4cb5c1383 100644 --- a/test_cases/unary/out/contract.awst +++ b/test_cases/unary/out/contract.awst @@ -17,7 +17,7 @@ contract UnaryContract } } -subroutine uint_unary(): None +subroutine uint_unary(): void { assert(!(reinterpret_cast(0u)), comment="not uint") for i in (1u, 2u, 150u, 18446744073709551615u) { @@ -25,12 +25,12 @@ subroutine uint_unary(): None } } -subroutine biguint_unary(): None +subroutine biguint_unary(): void { assert(0n == 0n, comment="not biguint") } -subroutine bytes_unary(): None +subroutine bytes_unary(): void { assert(!(reinterpret_cast(len(''))), comment="not bytes") assert(b~(hex<"FF">) == hex<"00">, comment="~ bytes") diff --git a/test_cases/unassigned_expression/out/contract.awst b/test_cases/unassigned_expression/out/contract.awst index b5ebc1dae..ef81eab2e 100644 --- a/test_cases/unassigned_expression/out/contract.awst +++ b/test_cases/unassigned_expression/out/contract.awst @@ -1,16 +1,16 @@ contract Unassigned { - abimethod discard_op(): None + abimethod discard_op(): void { bzero(10u) } - abimethod discard_subroutine(): None + abimethod discard_subroutine(): void { test_cases.unassigned_expression.contract::get_a_value() } - abimethod discard_constants(): None + abimethod discard_constants(): void { '' 0u @@ -18,7 +18,7 @@ contract Unassigned } } -subroutine get_a_value(): algopy.UInt64 +subroutine get_a_value(): uint64 { return 42u } \ No newline at end of file diff --git a/test_cases/undefined_phi_args/out/baddie.awst b/test_cases/undefined_phi_args/out/baddie.awst index 35467f8ca..1276454ab 100644 --- a/test_cases/undefined_phi_args/out/baddie.awst +++ b/test_cases/undefined_phi_args/out/baddie.awst @@ -2,7 +2,7 @@ contract Baddie { approval_program(): bool { - test_case: algopy.Bytes = txna() + test_case: bytes = txna() invert_second_condition: bool = txn() > 1u and btoi(txna()) > 0u if (invert_second_condition) { if (test_case == 'uint') { @@ -40,56 +40,56 @@ contract Baddie } } -subroutine test_uint_undefined(x: bool, y: bool): algopy.UInt64 +subroutine test_uint_undefined(x: bool, y: bool): uint64 { if (x) { - a: algopy.UInt64 = 7u + a: uint64 = 7u } if (x) { - b: algopy.UInt64 = 11u + b: uint64 = 11u } else { - b: algopy.UInt64 = 11u + b: uint64 = 11u } if (y) { - c: algopy.UInt64 = a + 1u + c: uint64 = a + 1u } else { - c: algopy.UInt64 = b - 1u + c: uint64 = b - 1u } return c } -subroutine test_bytes_undefined(x: bool, y: bool): algopy.BigUInt +subroutine test_bytes_undefined(x: bool, y: bool): biguint { if (x) { - a: algopy.BigUInt = 7n + a: biguint = 7n } if (x) { - b: algopy.BigUInt = 11n + b: biguint = 11n } else { - b: algopy.BigUInt = 11n + b: biguint = 11n } if (y) { - c: algopy.BigUInt = a b+ 1n + c: biguint = a b+ 1n } else { - c: algopy.BigUInt = b b- 1n + c: biguint = b b- 1n } return c } -subroutine test_mixed_undefined(x: bool, y: bool): algopy.BigUInt +subroutine test_mixed_undefined(x: bool, y: bool): biguint { if (x) { - a: algopy.UInt64 = 7u + a: uint64 = 7u } if (x) { - b: algopy.BigUInt = 11n + b: biguint = 11n } else { - b: algopy.BigUInt = 11n + b: biguint = 11n } if (y) { - c: algopy.BigUInt = itob(a) b+ 1n + c: biguint = itob(a) b+ 1n } else { - c: algopy.BigUInt = b b- 1n + c: biguint = b b- 1n } return c } \ No newline at end of file diff --git a/test_cases/unssa/out/contract.awst b/test_cases/unssa/out/contract.awst index 1f9345bb1..d3d33bbb4 100644 --- a/test_cases/unssa/out/contract.awst +++ b/test_cases/unssa/out/contract.awst @@ -3,10 +3,10 @@ contract UnSSAContract approval_program(): bool { test_cases.unssa.contract::test_self_ref_phi() - result1: algopy.UInt64 = test_cases.unssa.contract::test_swap(1u) + result1: uint64 = test_cases.unssa.contract::test_swap(1u) log(itob(result1)) assert(result1 >= 1u and result1 <= 2u) - result2: algopy.UInt64 = test_cases.unssa.contract::test_swap(2u) + result2: uint64 = test_cases.unssa.contract::test_swap(2u) log(itob(result2)) assert(result2 >= 1u and result2 <= 2u) test_cases.unssa.contract::test_swap_loop(7u, 11u) @@ -14,10 +14,10 @@ contract UnSSAContract test_cases.unssa.contract::test_param_update_with_reentrant_entry_block_v2(0u) test_cases.unssa.contract::test_param_update_with_reentrant_entry_block_v3() test_cases.unssa.contract::test_swap_args() - (a, b): tuple[algopy.UInt64, algopy.UInt64] = test_cases.unssa.contract::test_tuple_swap(100u, 200u, 0u) + (a, b): tuple = test_cases.unssa.contract::test_tuple_swap(100u, 200u, 0u) assert(a == 100u) assert(b == 200u) - (a, b): tuple[algopy.UInt64, algopy.UInt64] = test_cases.unssa.contract::test_tuple_swap(100u, 200u, 1u) + (a, b): tuple = test_cases.unssa.contract::test_tuple_swap(100u, 200u, 1u) assert(a == 200u) assert(b == 100u) return true @@ -29,9 +29,9 @@ contract UnSSAContract } } -subroutine test_self_ref_phi(): algopy.UInt64 +subroutine test_self_ref_phi(): uint64 { - a: algopy.UInt64 = 1u + a: uint64 = 1u while (a < 100u) { if (a % 105u == 0u) { continue @@ -44,47 +44,47 @@ subroutine test_self_ref_phi(): algopy.UInt64 return a } -subroutine test_swap(i: algopy.UInt64): algopy.UInt64 +subroutine test_swap(i: uint64): uint64 { - x: algopy.UInt64 = 1u - y: algopy.UInt64 = 2u + x: uint64 = 1u + y: uint64 = 2u while (i > 0u) { - tmp: algopy.UInt64 = x - x: algopy.UInt64 = y - y: algopy.UInt64 = tmp - i: algopy.UInt64 = i - 1u + tmp: uint64 = x + x: uint64 = y + y: uint64 = tmp + i: uint64 = i - 1u } return x } -subroutine test_swap_loop(i: algopy.UInt64, j: algopy.UInt64): algopy.UInt64 +subroutine test_swap_loop(i: uint64, j: uint64): uint64 { - x: algopy.UInt64 = 1u - y: algopy.UInt64 = 2u + x: uint64 = 1u + y: uint64 = 2u while (i > 0u) { while (j > 0u) { - tmp: algopy.UInt64 = x - x: algopy.UInt64 = y - y: algopy.UInt64 = tmp - j: algopy.UInt64 = j - 1u + tmp: uint64 = x + x: uint64 = y + y: uint64 = tmp + j: uint64 = j - 1u } - i: algopy.UInt64 = i - 1u + i: uint64 = i - 1u } return x } -subroutine test_tuple_swap(a: algopy.UInt64, b: algopy.UInt64, i: algopy.UInt64): tuple[algopy.UInt64, algopy.UInt64] +subroutine test_tuple_swap(a: uint64, b: uint64, i: uint64): tuple { for _item in range(0u, i, 1u) { - (a, b): tuple[algopy.UInt64, algopy.UInt64] = (b, a) + (a, b): tuple = (b, a) } return (a, b) } -subroutine test_param_update_with_reentrant_entry_block(x: algopy.UInt64): algopy.UInt64 +subroutine test_param_update_with_reentrant_entry_block(x: uint64): uint64 { while (true) { - x: algopy.UInt64 = x + 1u + x: uint64 = x + 1u if (x >= 10u) { break } @@ -92,9 +92,9 @@ subroutine test_param_update_with_reentrant_entry_block(x: algopy.UInt64): algop return x } -subroutine test_param_update_with_reentrant_entry_block_v2(x: algopy.UInt64): algopy.UInt64 +subroutine test_param_update_with_reentrant_entry_block_v2(x: uint64): uint64 { - x: algopy.UInt64 = x + 1u + x: uint64 = x + 1u while (true) { if (x >= 1u) { break @@ -103,7 +103,7 @@ subroutine test_param_update_with_reentrant_entry_block_v2(x: algopy.UInt64): al return x } -subroutine test_param_update_with_reentrant_entry_block_v3(): None +subroutine test_param_update_with_reentrant_entry_block_v3(): void { while (true) { if (reinterpret_cast(test_cases.unssa.contract::one())) { @@ -112,21 +112,21 @@ subroutine test_param_update_with_reentrant_entry_block_v3(): None } } -subroutine one(): algopy.UInt64 +subroutine one(): uint64 { return 1u } -subroutine swap_args(a: algopy.UInt64, b: algopy.UInt64): tuple[algopy.UInt64, algopy.UInt64] +subroutine swap_args(a: uint64, b: uint64): tuple { return (b, a) } -subroutine test_swap_args(): None +subroutine test_swap_args(): void { - a: algopy.UInt64 = test_cases.unssa.contract::one() + 123u - b: algopy.UInt64 = test_cases.unssa.contract::one() + 234u - (a, b): tuple[algopy.UInt64, algopy.UInt64] = test_cases.unssa.contract::swap_args(a, b) + a: uint64 = test_cases.unssa.contract::one() + 123u + b: uint64 = test_cases.unssa.contract::one() + 234u + (a, b): tuple = test_cases.unssa.contract::swap_args(a, b) assert(a == 235u, comment="a == 235") assert(b == 124u, comment="b = 124") } \ No newline at end of file diff --git a/test_cases/with_reentrancy/out/contract.awst b/test_cases/with_reentrancy/out/contract.awst index aa760d4e1..1f2848a5a 100644 --- a/test_cases/with_reentrancy/out/contract.awst +++ b/test_cases/with_reentrancy/out/contract.awst @@ -13,17 +13,17 @@ contract WithReentrancy } } -subroutine itoa(i: algopy.UInt64): algopy.Bytes +subroutine itoa(i: uint64): bytes { - digits: algopy.Bytes = '0123456789' - radix: algopy.UInt64 = len(digits) + digits: bytes = '0123456789' + radix: uint64 = len(digits) if (i < radix) { return digits[i] } return test_cases.with_reentrancy.contract::itoa(i // radix) + digits[i % radix] } -subroutine fibonacci(n: algopy.UInt64): algopy.UInt64 +subroutine fibonacci(n: uint64): uint64 { if (n <= 1u) { return n @@ -31,34 +31,34 @@ subroutine fibonacci(n: algopy.UInt64): algopy.UInt64 return test_cases.with_reentrancy.contract::fibonacci(n - 1u) + test_cases.with_reentrancy.contract::fibonacci(n - 2u) } -subroutine silly(x: algopy.UInt64): algopy.UInt64 +subroutine silly(x: uint64): uint64 { - x: algopy.UInt64 = x + 1u - result: algopy.UInt64 = test_cases.with_reentrancy.contract::silly2(x) + x: uint64 = x + 1u + result: uint64 = test_cases.with_reentrancy.contract::silly2(x) log('silly = ' + test_cases.with_reentrancy.contract::itoa(x)) return result } -subroutine silly2(x: algopy.UInt64): algopy.UInt64 +subroutine silly2(x: uint64): uint64 { - x: algopy.UInt64 = x + 2u - result: algopy.UInt64 = test_cases.with_reentrancy.contract::silly3(x) + x: uint64 = x + 2u + result: uint64 = test_cases.with_reentrancy.contract::silly3(x) log('silly2 = ' + test_cases.with_reentrancy.contract::itoa(x)) return result } -subroutine silly3(x: algopy.UInt64): algopy.UInt64 +subroutine silly3(x: uint64): uint64 { is_even: bool = x % 2u == 0u - a: algopy.UInt64 = x + 2u + a: uint64 = x + 2u if (is_even) { - result: algopy.UInt64 = a * 2u - a: algopy.UInt64 = result // 2u - 2u + result: uint64 = a * 2u + a: uint64 = result // 2u - 2u } else { - result: algopy.UInt64 = test_cases.with_reentrancy.contract::silly(x) + result: uint64 = test_cases.with_reentrancy.contract::silly(x) } if (is_even) { - result: algopy.UInt64 = a + result: uint64 = a } log('silly3 = ' + test_cases.with_reentrancy.contract::itoa(x)) return result diff --git a/tests/test_arc32.py b/tests/test_arc32.py index 54c3e65ac..ac54f65fb 100644 --- a/tests/test_arc32.py +++ b/tests/test_arc32.py @@ -1310,7 +1310,7 @@ def test_box_contract(algod_client: AlgodClient, account: algokit_utils.Account) ), ) transaction_parameters = algokit_utils.OnCompleteCallParameters( - boxes=[(0, b"BOX_A"), (0, b"b"), (0, b"BOX_C"), (0, b"0"), (0, b"d")] + boxes=[(0, "box_a"), (0, "b"), (0, b"BOX_C"), (0, b"0"), (0, b"d")] ) (a_exist, b_exist, c_exist) = client.call( diff --git a/tests/test_expected_output/arc4.test b/tests/test_expected_output/arc4.test index 8d6e5728f..b8745b7fc 100644 --- a/tests/test_expected_output/arc4.test +++ b/tests/test_expected_output/arc4.test @@ -173,35 +173,35 @@ class Arc4CopyContract(arc4.ARC4Contract): # Require copy when reassigning - copy1 = local_array ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being assigned to another variable - assert (copy2 := local_array).length, "this isn't ok" ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being assigned to another variable + copy1 = local_array ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + assert (copy2 := local_array).length, "this isn't ok" ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable valid_tuple = (local_array.copy(),) - copy3 = valid_tuple[0] ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being assigned to another variable - copy4 = self.global_a ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being assigned to another variable - copy5 = self.global_b.value ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being assigned to another variable + copy3 = valid_tuple[0] ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + copy4 = self.global_a ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + copy5 = self.global_b.value ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable # Require copy when building a collection - my_tuple = (local_array, local_array) ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being passed to a tuple expression - copy_in_tuple = arc4.Tuple(valid_tuple) ## E: tuple[algopy.arc4.DynamicArray[algopy.arc4.UInt64]] must be copied using .copy() when being passed to a constructor - copy_in_array1 = arc4.DynamicArray(local_array) ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being passed to an array constructor - copy_in_array2 = arc4.StaticArray(local_array) ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being passed to an array constructor + my_tuple = (local_array, local_array) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a tuple expression + copy_in_tuple = arc4.Tuple(valid_tuple) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a constructor + copy_in_array1 = arc4.DynamicArray(local_array) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to an array constructor + copy_in_array2 = arc4.StaticArray(local_array) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to an array constructor # State vars should require copy - self.method_a(self.global_a) ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being passed to a subroutine from state - self.method_a(self.global_b.value) ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being passed to a subroutine from state - self.method_a(self.local[Txn.sender]) ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being passed to a subroutine from state + self.method_a(self.global_a) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine from state + self.method_a(self.global_b.value) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine from state + self.method_a(self.local[Txn.sender]) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine from state # Tuple items require a copy when passing - self.method_a(valid_tuple[0]) ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being passed to a subroutine + self.method_a(valid_tuple[0]) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine # Require copy when reassigning tuple elements - destructured_a, destructured_b = my_tuple ## E: Tuple cannot be destructured as it contains an item of type algopy.arc4.DynamicArray[algopy.arc4.UInt64] which requires copying. Use index access instead - destructured_a = my_tuple[0] ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being assigned to another variable - destructured_b = my_tuple[1] ## E: algopy.arc4.DynamicArray[algopy.arc4.UInt64] must be copied using .copy() when being assigned to another variable + destructured_a, destructured_b = my_tuple ## E: tuples containing a mutable reference to an ARC4-encoded value cannot be unpacked, use index access instead + destructured_a = my_tuple[0] ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + destructured_b = my_tuple[1] ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable # Can't create copies by iterating valid_array_of_arrays = arc4.DynamicArray(local_array.copy()) @@ -271,9 +271,9 @@ class Arc4StructCopyTests(arc4.ARC4Contract): # **FUNCTION LOCALS** - bad_inner = var_inner ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being assigned to another variable + bad_inner = var_inner ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable inner_copy = var_inner.copy() - var_outer.inner = var_inner ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being assigned to another variable + var_outer.inner = var_inner ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable var_outer.inner = var_inner.copy() # **METHOD ARGS** @@ -286,53 +286,53 @@ class Arc4StructCopyTests(arc4.ARC4Contract): method_num(var_outer.number) method_num(var_outer.inner.number) - method_inner(var_outer.inner) ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a subroutine + method_inner(var_outer.inner) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_inner(var_outer.inner.copy()) method_inner(new_inner()) method_outer(new_outer()) method_inner(new_outer().inner) - method_inner(self.global_inner)## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a subroutine from state ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a subroutine from state + method_inner(self.global_inner)## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a subroutine from state ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine from state method_inner(self.global_inner.copy()) - method_inner(self.global_outer.inner) ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a subroutine + method_inner(self.global_outer.inner) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_inner(self.global_outer.inner.copy()) method_num(self.global_outer.number) method_num(self.global_outer.inner.number) - method_outer(self.global_proxy.value) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being passed to a subroutine from state + method_outer(self.global_proxy.value) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine from state method_outer(self.global_proxy.value.copy()) - method_inner(self.global_proxy.value.inner) ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a subroutine + method_inner(self.global_proxy.value.inner) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_inner(self.global_proxy.value.inner.copy()) - method_outer(self.global_proxy.maybe()[0]) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being passed to a subroutine + method_outer(self.global_proxy.maybe()[0]) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_bool(self.global_proxy.maybe()[1]) - method_outer(self.global_proxy.get(new_outer())) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being passed to a subroutine + method_outer(self.global_proxy.get(new_outer())) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_outer(self.global_proxy.get(new_outer()).copy()) method_num(self.global_proxy.value.number) method_num(self.global_proxy.value.inner.number) - bad_inner = self.global_proxy.value.inner ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being assigned to another variable + bad_inner = self.global_proxy.value.inner ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable bad_inner = self.global_proxy.value.inner.copy() - maybe_outer = self.global_proxy.maybe() ## E: tuple[copy_arc4_struct.OuterStruct, bool] must be copied using .copy() when being assigned to another variable - bad_outer, bol = self.global_proxy.maybe() ## E: Tuple cannot be destructured as it contains an item of type copy_arc4_struct.OuterStruct which requires copying. Use index access instead + maybe_outer = self.global_proxy.maybe() ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + bad_outer, bol = self.global_proxy.maybe() ## E: tuples containing a mutable reference to an ARC4-encoded value cannot be unpacked, use index access instead bol = self.global_proxy.maybe()[1] - bad_outer = self.global_proxy.get(new_outer()) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being assigned to another variable + bad_outer = self.global_proxy.get(new_outer()) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable var_outer = self.global_proxy.get(new_outer()).copy() - method_outer(self.local[Txn.sender]) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being passed to a subroutine from state + method_outer(self.local[Txn.sender]) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine from state method_outer(self.local[Txn.sender].copy()) - method_inner(self.local[Txn.sender].inner) ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a subroutine + method_inner(self.local[Txn.sender].inner) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_inner(self.local[Txn.sender].inner.copy()) - method_outer(self.local.maybe(0)[0]) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being passed to a subroutine + method_outer(self.local.maybe(0)[0]) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_bool(self.local.maybe(0)[1]) - method_outer(self.local.get(0, new_outer())) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being passed to a subroutine + method_outer(self.local.get(0, new_outer())) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_outer(self.local.get(0, new_outer()).copy()) method_num(self.local[Txn.sender].number) method_num(self.local[Txn.sender].inner.number) - bad_inner = self.local[Txn.sender].inner ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being assigned to another variable - maybe_outer = self.local.maybe(0) ## E: tuple[copy_arc4_struct.OuterStruct, bool] must be copied using .copy() when being assigned to another variable - bad_outer, bol = self.local.maybe(0) ## E: Tuple cannot be destructured as it contains an item of type copy_arc4_struct.OuterStruct which requires copying. Use index access instead + bad_inner = self.local[Txn.sender].inner ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + maybe_outer = self.local.maybe(0) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + bad_outer, bol = self.local.maybe(0) ## E: tuples containing a mutable reference to an ARC4-encoded value cannot be unpacked, use index access instead bol = self.local.maybe(0)[1] - bad_outer = self.local.get(0, new_outer()) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being assigned to another variable + bad_outer = self.local.get(0, new_outer()) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable var_outer = self.local.get(0, new_outer()).copy() method_tup(new_inner_in_tup()) @@ -347,34 +347,32 @@ class Arc4StructCopyTests(arc4.ARC4Contract): # (...) = t # (...) = (...) - tup = (var_inner, var_outer) ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being passed to a tuple expression \ - ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a tuple expression + tup = (var_inner, var_outer) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a tuple expression tup = (var_inner.copy(), var_outer.copy()) tup = (new_inner(), new_outer()) - tup2 = tup ## E: tuple[copy_arc4_struct.InnerStruct, copy_arc4_struct.OuterStruct] must be copied using .copy() when being assigned to another variable - (a, b) = tup ## E: Tuple cannot be destructured as it contains an item of type copy_arc4_struct.InnerStruct which requires copying. Use index access instead - (a, b) = (var_inner, var_outer) ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a tuple expression \ - ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being passed to a tuple expression + tup2 = tup ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + (a, b) = tup ## E: tuples containing a mutable reference to an ARC4-encoded value cannot be unpacked, use index access instead + (a, b) = (var_inner, var_outer) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a tuple expression (a, b) = (new_inner(), new_outer()) # **TUPLE INDEXING** - a = tup[0] ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being assigned to another variable - a = tup[1].inner ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being assigned to another variable + a = tup[0] ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable + a = tup[1].inner ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable a = tup[0].copy() a = tup[1].inner.copy() - method_inner(tup[0]) ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a subroutine + method_inner(tup[0]) ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a subroutine method_inner(tup[0].copy()) - self.global_inner = tup[0] ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being assigned to another variable + self.global_inner = tup[0] ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable self.global_inner = tup[0].copy() - self.global_proxy.value = tup[1] ## E: copy_arc4_struct.OuterStruct must be copied using .copy() when being assigned to another variable + self.global_proxy.value = tup[1] ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable self.global_proxy.value = tup[1].copy() - self.global_outer.inner = tup[0] ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being assigned to another variable + self.global_outer.inner = tup[0] ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being assigned to another variable self.global_outer.inner = tup[0].copy() # **ITERATION** - for s in (var_inner, var_outer.inner): ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a tuple expression + for s in (var_inner, var_outer.inner): ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a tuple expression assert s.number for s in (new_inner(), new_outer().inner): @@ -383,7 +381,7 @@ class Arc4StructCopyTests(arc4.ARC4Contract): for s in (var_inner.copy(), var_outer.inner.copy()): assert s.number - for idx, s in uenumerate((var_inner, var_outer.inner)): ## E: copy_arc4_struct.InnerStruct must be copied using .copy() when being passed to a tuple expression + for idx, s in uenumerate((var_inner, var_outer.inner)): ## E: mutable reference to ARC4-encoded value must be copied using .copy() when being passed to a tuple expression assert idx >= 0 assert s.number diff --git a/tests/test_expected_output/awst.test b/tests/test_expected_output/awst.test index 1073a1970..11bb9508b 100644 --- a/tests/test_expected_output/awst.test +++ b/tests/test_expected_output/awst.test @@ -15,18 +15,18 @@ def test() -> bool: return a in (one(), two()) ## expected: awst -subroutine one(): algopy.UInt64 +subroutine one(): uint64 { return 1u } -subroutine two(): algopy.UInt64 +subroutine two(): uint64 { return 2u } subroutine test(): bool { - a: algopy.UInt64 = 42u + a: uint64 = 42u return a IS IN (contains_expression::one(), contains_expression::two()) } diff --git a/tests/test_expected_output/expected_errors.test b/tests/test_expected_output/expected_errors.test index f628b3b7f..0a040e9c6 100644 --- a/tests/test_expected_output/expected_errors.test +++ b/tests/test_expected_output/expected_errors.test @@ -289,7 +289,7 @@ class Derived1(Base): class Derived2(Base): def __init__(self) -> None: super().__init__() - self.bar = Bytes(b"bbb") # type: ignore[assignment] ## E: Assignment target type algopy.UInt64 differs from expression value type algopy.Bytes + self.bar = Bytes(b"bbb") # type: ignore[assignment] ## E: assignment target type differs from expression value type class Derived3(Base): def __init__(self) -> None: @@ -299,9 +299,7 @@ class Derived3(Base): class Derived4(Base): def __init__(self) -> None: super().__init__() - self.bar_p = GlobalState(Bytes(b"bbb")) # type: ignore[arg-type] ## E: Redefinition of bar_p \ - ## E: Assignment target type algopy.UInt64 differs from expression value type algopy.Bytes - + self.bar_p = GlobalState(Bytes(b"bbb")) # type: ignore[arg-type] ## E: Redefinition of bar_p class Base2(ARC4Contract): def __init__(self) -> None: @@ -325,4 +323,4 @@ class Con(Contract): def clear_state_program(self) -> bool: assert self.x ## E: None does not support boolean evaluation - return True \ No newline at end of file + return True diff --git a/tests/test_expected_output/subroutine.test b/tests/test_expected_output/subroutine.test index c3cbfd56b..2d7d0eaa7 100644 --- a/tests/test_expected_output/subroutine.test +++ b/tests/test_expected_output/subroutine.test @@ -100,7 +100,7 @@ from algopy import Bytes, UInt64, subroutine @subroutine def test() -> None: b = Bytes(b"123") - b = UInt64(1) # type: ignore[assignment] ## E: Assignment target type algopy.Bytes differs from expression value type algopy.UInt64 + b = UInt64(1) # type: ignore[assignment] ## E: assignment target type differs from expression value type ## case: while_ok from algopy import UInt64, subroutine @@ -376,7 +376,7 @@ from algopy import Bytes, UInt64, subroutine def test() -> None: one = UInt64(1) two = Bytes(b"2") - one = two = Bytes(b"3") # type: ignore[assignment] ## E: Assignment target type algopy.UInt64 differs from expression value type algopy.Bytes + one = two = Bytes(b"3") # type: ignore[assignment] ## E: assignment target type differs from expression value type ## case: can_reference_intrinsic_with_enum from algopy import UInt64, op, subroutine @@ -498,4 +498,4 @@ from algopy import * @subroutine def naughty(foo: None) -> None: ## E: void type arguments are not supported - return foo + return foo \ No newline at end of file diff --git a/tests/test_transaction_fields.py b/tests/test_transaction_fields.py index 4b3083767..ef085de25 100644 --- a/tests/test_transaction_fields.py +++ b/tests/test_transaction_fields.py @@ -44,7 +44,7 @@ def is_compatible(self, other: FieldType) -> bool: def __str__(self) -> str: types = " | ".join( - t.stub_name if isinstance(t, wtypes.WType) else t.__name__ for t in self.field_types + t.name if isinstance(t, wtypes.WType) else t.__name__ for t in self.field_types ) if self.is_array: return f"tuple[{types}, ...]"