diff --git a/examples/sizes.txt b/examples/sizes.txt index 20036ad680..f8312d59ee 100644 --- a/examples/sizes.txt +++ b/examples/sizes.txt @@ -119,7 +119,7 @@ tuple_support/TupleSupport 696 409 - | 381 180 - typed_abi_call/Greeter 3147 2685 - | 1488 1171 - typed_abi_call/Logger 1014 838 - | 549 435 - - typed_abi_call_txn/Caller 326 283 - | 160 138 - + typed_abi_call_txn/Caller 336 290 - | 167 143 - typed_abi_call_txn/Txn 241 188 - | 128 100 - unary/Unary 130 67 - | 62 27 - unassigned_expression/Unassigned 158 119 - | 80 58 - diff --git a/src/puya/awst/validation/inner_transactions.py b/src/puya/awst/validation/inner_transactions.py index 79db49885c..1352c8a137 100644 --- a/src/puya/awst/validation/inner_transactions.py +++ b/src/puya/awst/validation/inner_transactions.py @@ -202,6 +202,10 @@ def _is_assignable_itxn_expr(expr: awst_nodes.Expression) -> bool: items=items ): # tuple expressions composed of assignable expressions are assignable return all(map(_is_assignable_itxn_expr, items)) + case awst_nodes.TupleItemExpression( + base=base + ): # tuple items are assignable if their base is assignable + return _is_assignable_itxn_expr(base) case awst_nodes.SingleEvaluation(source=source): return _is_assignable_itxn_expr(source) # anything else is not considered assignable diff --git a/test_cases/typed_abi_call_txn/caller.py b/test_cases/typed_abi_call_txn/caller.py index 6054be0814..4454bfe495 100644 --- a/test_cases/typed_abi_call_txn/caller.py +++ b/test_cases/typed_abi_call_txn/caller.py @@ -17,13 +17,14 @@ def test_call_with_txn(self, a: Bytes, b: Bytes, app: Application) -> None: asset_name="TEST", total=1, ) - arc4.abi_call( + asset_id, _txn = arc4.abi_call( TxnContract.call_with_txn, a, txn, b, app_id=app, ) + assert asset_id, "expected asset id" @arc4.abimethod def test_call_with_acfg(self, a: Bytes, b: Bytes, app: Application) -> None: diff --git a/test_cases/typed_abi_call_txn/out/Caller.approval.mir b/test_cases/typed_abi_call_txn/out/Caller.approval.mir index a4619b00a5..6413adc3a9 100644 --- a/test_cases/typed_abi_call_txn/out/Caller.approval.mir +++ b/test_cases/typed_abi_call_txn/out/Caller.approval.mir @@ -69,17 +69,17 @@ __puya_arc4_router___test_call_with_txn_route@2: retsub // 1 arc4.abimethod typed_abi_call_txn/caller.py:13 __puya_arc4_router___test_call_with_acfg_route@3: - txn OnCompletion // {txn} arc4.abimethod typed_abi_call_txn/caller.py:28 - // virtual: store tmp%14#0 to l-stack (no copy) tmp%14#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - // virtual: load tmp%14#0 from l-stack (no copy) tmp%14#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - ! // {!} arc4.abimethod typed_abi_call_txn/caller.py:28 - // virtual: store tmp%15#0 to l-stack (no copy) tmp%15#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - // virtual: load tmp%15#0 from l-stack (no copy) tmp%15#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - assert // OnCompletion is NoOp // arc4.abimethod typed_abi_call_txn/caller.py:28 - txn ApplicationID // {txn} arc4.abimethod typed_abi_call_txn/caller.py:28 - // virtual: store tmp%16#0 to l-stack (no copy) tmp%16#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - // virtual: load tmp%16#0 from l-stack (no copy) tmp%16#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - assert // is not creating // arc4.abimethod typed_abi_call_txn/caller.py:28 + txn OnCompletion // {txn} arc4.abimethod typed_abi_call_txn/caller.py:29 + // virtual: store tmp%14#0 to l-stack (no copy) tmp%14#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + // virtual: load tmp%14#0 from l-stack (no copy) tmp%14#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + ! // {!} arc4.abimethod typed_abi_call_txn/caller.py:29 + // virtual: store tmp%15#0 to l-stack (no copy) tmp%15#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + // virtual: load tmp%15#0 from l-stack (no copy) tmp%15#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + assert // OnCompletion is NoOp // arc4.abimethod typed_abi_call_txn/caller.py:29 + txn ApplicationID // {txn} arc4.abimethod typed_abi_call_txn/caller.py:29 + // virtual: store tmp%16#0 to l-stack (no copy) tmp%16#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + // virtual: load tmp%16#0 from l-stack (no copy) tmp%16#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + assert // is not creating // arc4.abimethod typed_abi_call_txn/caller.py:29 txna ApplicationArgs 1 // {txna} class Caller(ARC4Contract): typed_abi_call_txn/caller.py:12 // virtual: store tmp%18#0 to l-stack (no copy) tmp%18#0 class Caller(ARC4Contract): typed_abi_call_txn/caller.py:12 // virtual: load tmp%18#0 from l-stack (no copy) tmp%18#0 class Caller(ARC4Contract): typed_abi_call_txn/caller.py:12 @@ -98,12 +98,12 @@ __puya_arc4_router___test_call_with_acfg_route@3: // virtual: load tmp%23#0 from l-stack (no copy) tmp%19#0,tmp%21#0,tmp%23#0 class Caller(ARC4Contract): typed_abi_call_txn/caller.py:12 txnas Applications // tmp%19#0,tmp%21#0,{txnas} class Caller(ARC4Contract): typed_abi_call_txn/caller.py:12 // virtual: store tmp%24#0 to l-stack (no copy) tmp%19#0,tmp%21#0,tmp%24#0 class Caller(ARC4Contract): typed_abi_call_txn/caller.py:12 - uncover 2 // load tmp%19#0 from l-stack (no copy) tmp%21#0,tmp%24#0,tmp%19#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - uncover 2 // load tmp%21#0 from l-stack (no copy) tmp%24#0,tmp%19#0,tmp%21#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - uncover 2 // load tmp%24#0 from l-stack (no copy) tmp%19#0,tmp%21#0,tmp%24#0 arc4.abimethod typed_abi_call_txn/caller.py:28 - callsub test_call_with_acfg // arc4.abimethod typed_abi_call_txn/caller.py:28 - int 1 // 1 arc4.abimethod typed_abi_call_txn/caller.py:28 - retsub // 1 arc4.abimethod typed_abi_call_txn/caller.py:28 + uncover 2 // load tmp%19#0 from l-stack (no copy) tmp%21#0,tmp%24#0,tmp%19#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + uncover 2 // load tmp%21#0 from l-stack (no copy) tmp%24#0,tmp%19#0,tmp%21#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + uncover 2 // load tmp%24#0 from l-stack (no copy) tmp%19#0,tmp%21#0,tmp%24#0 arc4.abimethod typed_abi_call_txn/caller.py:29 + callsub test_call_with_acfg // arc4.abimethod typed_abi_call_txn/caller.py:29 + int 1 // 1 arc4.abimethod typed_abi_call_txn/caller.py:29 + retsub // 1 arc4.abimethod typed_abi_call_txn/caller.py:29 __puya_arc4_router___bare_routing@6: txn OnCompletion // {txn} class Caller(ARC4Contract): typed_abi_call_txn/caller.py:12 @@ -186,84 +186,92 @@ test_call_with_txn_block@0: itxn_submit // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 gitxn 1 LastLog // (𝕡) a#0,b#0,app#0 | {gitxn} arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 // virtual: store awst_tmp%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - // virtual: load awst_tmp%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - extract 0 4 // (𝕡) a#0,b#0,app#0 | {extract} arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%1#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - // virtual: load tmp%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%1#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - byte 0x151f7c75 // (𝕡) a#0,b#0,app#0 | tmp%1#0,0x151f7c75 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - == // (𝕡) a#0,b#0,app#0 | {==} arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - // virtual: store tmp%2#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%2#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%2#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 - assert // ARC4 prefix is valid // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + dup // load awst_tmp%0#0 from l-stack (copy) (𝕡) a#0,b#0,app#0 | awst_tmp%0#0,awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + extract 4 0 // (𝕡) a#0,b#0,app#0 | awst_tmp%0#0,{extract} arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + cover 1 // store tmp%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%0#0,awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + // virtual: load awst_tmp%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%0#0,awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + extract 0 4 // (𝕡) a#0,b#0,app#0 | tmp%0#0,{extract} arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%0#0,tmp%1#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + // virtual: load tmp%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%0#0,tmp%1#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + byte 0x151f7c75 // (𝕡) a#0,b#0,app#0 | tmp%0#0,tmp%1#0,0x151f7c75 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + == // (𝕡) a#0,b#0,app#0 | tmp%0#0,{==} arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + // virtual: store tmp%2#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%0#0,tmp%2#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%0#0,tmp%2#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + assert // ARC4 prefix is valid // (𝕡) a#0,b#0,app#0 | tmp%0#0 arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%0#0 asset_id, _txn = arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + btoi // (𝕡) a#0,b#0,app#0 | {btoi} arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + // virtual: store asset_id#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | asset_id#0 asset_id, _txn = arc4.abi_call(\nTxnContract.call_with_txn,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:20-26 + // virtual: load asset_id#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | asset_id#0 assert asset_id, "expected asset id" typed_abi_call_txn/caller.py:27 + assert // expected asset id // (𝕡) a#0,b#0,app#0 | assert asset_id, "expected asset id" typed_abi_call_txn/caller.py:27 retsub // // test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: test_call_with_acfg: - proto 3 0 // (𝕡) a#0,b#0,app#0 | @arc4.abimethod\ndef test_call_with_acfg(self, a: Bytes, b: Bytes, app: Application) -> None: typed_abi_call_txn/caller.py:28-29 + proto 3 0 // (𝕡) a#0,b#0,app#0 | @arc4.abimethod\ndef test_call_with_acfg(self, a: Bytes, b: Bytes, app: Application) -> None: typed_abi_call_txn/caller.py:29-30 test_call_with_acfg_block@0: - itxn_begin // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - int 1 // (𝕡) a#0,b#0,app#0 | 1 1 typed_abi_call_txn/caller.py:33 + itxn_begin // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + int 1 // (𝕡) a#0,b#0,app#0 | 1 1 typed_abi_call_txn/caller.py:34 itxn_field ConfigAssetTotal // (𝕡) a#0,b#0,app#0 | - byte "TEST" // (𝕡) a#0,b#0,app#0 | "TEST" "TEST" typed_abi_call_txn/caller.py:32 + byte "TEST" // (𝕡) a#0,b#0,app#0 | "TEST" "TEST" typed_abi_call_txn/caller.py:33 itxn_field ConfigAssetName // (𝕡) a#0,b#0,app#0 | - byte "TST" // (𝕡) a#0,b#0,app#0 | "TST" "TST" typed_abi_call_txn/caller.py:31 + byte "TST" // (𝕡) a#0,b#0,app#0 | "TST" "TST" typed_abi_call_txn/caller.py:32 itxn_field ConfigAssetUnitName // (𝕡) a#0,b#0,app#0 | - int acfg // (𝕡) a#0,b#0,app#0 | acfg itxn.AssetConfig typed_abi_call_txn/caller.py:30 + int acfg // (𝕡) a#0,b#0,app#0 | acfg itxn.AssetConfig typed_abi_call_txn/caller.py:31 itxn_field TypeEnum // (𝕡) a#0,b#0,app#0 | - int 0 // (𝕡) a#0,b#0,app#0 | 0 itxn.AssetConfig typed_abi_call_txn/caller.py:30 + int 0 // (𝕡) a#0,b#0,app#0 | 0 itxn.AssetConfig typed_abi_call_txn/caller.py:31 itxn_field Fee // (𝕡) a#0,b#0,app#0 | - itxn_next // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - frame_dig -3 // load a#0 from parameters (𝕡) a#0,b#0,app#0 | a#0 a typed_abi_call_txn/caller.py:37 - len // (𝕡) a#0,b#0,app#0 | {len} a typed_abi_call_txn/caller.py:37 - // virtual: store length%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | length%0#0 a typed_abi_call_txn/caller.py:37 - // virtual: load length%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | length%0#0 a typed_abi_call_txn/caller.py:37 - itob // (𝕡) a#0,b#0,app#0 | {itob} a typed_abi_call_txn/caller.py:37 - // virtual: store as_bytes%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | as_bytes%0#0 a typed_abi_call_txn/caller.py:37 - // virtual: load as_bytes%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | as_bytes%0#0 a typed_abi_call_txn/caller.py:37 - extract 6 2 // (𝕡) a#0,b#0,app#0 | {extract} a typed_abi_call_txn/caller.py:37 - // virtual: store length_uint16%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | length_uint16%0#0 a typed_abi_call_txn/caller.py:37 - // virtual: load length_uint16%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | length_uint16%0#0 a typed_abi_call_txn/caller.py:37 - frame_dig -3 // load a#0 from parameters (𝕡) a#0,b#0,app#0 | length_uint16%0#0,a#0 a typed_abi_call_txn/caller.py:37 - concat // (𝕡) a#0,b#0,app#0 | {concat} a typed_abi_call_txn/caller.py:37 - // virtual: store encoded_value%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0 a typed_abi_call_txn/caller.py:37 - frame_dig -2 // load b#0 from parameters (𝕡) a#0,b#0,app#0 | encoded_value%0#0,b#0 b typed_abi_call_txn/caller.py:39 - len // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,{len} b typed_abi_call_txn/caller.py:39 - // virtual: store length%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length%1#0 b typed_abi_call_txn/caller.py:39 - // virtual: load length%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length%1#0 b typed_abi_call_txn/caller.py:39 - itob // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,{itob} b typed_abi_call_txn/caller.py:39 - // virtual: store as_bytes%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,as_bytes%1#0 b typed_abi_call_txn/caller.py:39 - // virtual: load as_bytes%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,as_bytes%1#0 b typed_abi_call_txn/caller.py:39 - extract 6 2 // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,{extract} b typed_abi_call_txn/caller.py:39 - // virtual: store length_uint16%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length_uint16%1#0 b typed_abi_call_txn/caller.py:39 - // virtual: load length_uint16%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length_uint16%1#0 b typed_abi_call_txn/caller.py:39 - frame_dig -2 // load b#0 from parameters (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length_uint16%1#0,b#0 b typed_abi_call_txn/caller.py:39 - concat // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,{concat} b typed_abi_call_txn/caller.py:39 - // virtual: store encoded_value%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,encoded_value%1#0 b typed_abi_call_txn/caller.py:39 + itxn_next // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + frame_dig -3 // load a#0 from parameters (𝕡) a#0,b#0,app#0 | a#0 a typed_abi_call_txn/caller.py:38 + len // (𝕡) a#0,b#0,app#0 | {len} a typed_abi_call_txn/caller.py:38 + // virtual: store length%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | length%0#0 a typed_abi_call_txn/caller.py:38 + // virtual: load length%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | length%0#0 a typed_abi_call_txn/caller.py:38 + itob // (𝕡) a#0,b#0,app#0 | {itob} a typed_abi_call_txn/caller.py:38 + // virtual: store as_bytes%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | as_bytes%0#0 a typed_abi_call_txn/caller.py:38 + // virtual: load as_bytes%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | as_bytes%0#0 a typed_abi_call_txn/caller.py:38 + extract 6 2 // (𝕡) a#0,b#0,app#0 | {extract} a typed_abi_call_txn/caller.py:38 + // virtual: store length_uint16%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | length_uint16%0#0 a typed_abi_call_txn/caller.py:38 + // virtual: load length_uint16%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | length_uint16%0#0 a typed_abi_call_txn/caller.py:38 + frame_dig -3 // load a#0 from parameters (𝕡) a#0,b#0,app#0 | length_uint16%0#0,a#0 a typed_abi_call_txn/caller.py:38 + concat // (𝕡) a#0,b#0,app#0 | {concat} a typed_abi_call_txn/caller.py:38 + // virtual: store encoded_value%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0 a typed_abi_call_txn/caller.py:38 + frame_dig -2 // load b#0 from parameters (𝕡) a#0,b#0,app#0 | encoded_value%0#0,b#0 b typed_abi_call_txn/caller.py:40 + len // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,{len} b typed_abi_call_txn/caller.py:40 + // virtual: store length%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length%1#0 b typed_abi_call_txn/caller.py:40 + // virtual: load length%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length%1#0 b typed_abi_call_txn/caller.py:40 + itob // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,{itob} b typed_abi_call_txn/caller.py:40 + // virtual: store as_bytes%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,as_bytes%1#0 b typed_abi_call_txn/caller.py:40 + // virtual: load as_bytes%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,as_bytes%1#0 b typed_abi_call_txn/caller.py:40 + extract 6 2 // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,{extract} b typed_abi_call_txn/caller.py:40 + // virtual: store length_uint16%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length_uint16%1#0 b typed_abi_call_txn/caller.py:40 + // virtual: load length_uint16%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length_uint16%1#0 b typed_abi_call_txn/caller.py:40 + frame_dig -2 // load b#0 from parameters (𝕡) a#0,b#0,app#0 | encoded_value%0#0,length_uint16%1#0,b#0 b typed_abi_call_txn/caller.py:40 + concat // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,{concat} b typed_abi_call_txn/caller.py:40 + // virtual: store encoded_value%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%0#0,encoded_value%1#0 b typed_abi_call_txn/caller.py:40 frame_dig -1 // load app#0 from parameters (𝕡) a#0,b#0,app#0 | encoded_value%0#0,encoded_value%1#0,app#0 itxn_field ApplicationID // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,encoded_value%1#0 - method "call_with_acfg(byte[],acfg,byte[])uint64" // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,encoded_value%1#0,method<"call_with_acfg(byte[],acfg,byte[])uint64"> arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 + method "call_with_acfg(byte[],acfg,byte[])uint64" // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,encoded_value%1#0,method<"call_with_acfg(byte[],acfg,byte[])uint64"> arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 itxn_field ApplicationArgs // (𝕡) a#0,b#0,app#0 | encoded_value%0#0,encoded_value%1#0 uncover 1 // load encoded_value%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%1#0,encoded_value%0#0 itxn_field ApplicationArgs // (𝕡) a#0,b#0,app#0 | encoded_value%1#0 // virtual: load encoded_value%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | encoded_value%1#0 itxn_field ApplicationArgs // (𝕡) a#0,b#0,app#0 | - int appl // (𝕡) a#0,b#0,app#0 | appl arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 + int appl // (𝕡) a#0,b#0,app#0 | appl arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 itxn_field TypeEnum // (𝕡) a#0,b#0,app#0 | - int 0 // (𝕡) a#0,b#0,app#0 | 0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 + int 0 // (𝕡) a#0,b#0,app#0 | 0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 itxn_field Fee // (𝕡) a#0,b#0,app#0 | - itxn_submit // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - gitxn 1 LastLog // (𝕡) a#0,b#0,app#0 | {gitxn} arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - // virtual: store awst_tmp%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - // virtual: load awst_tmp%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - extract 0 4 // (𝕡) a#0,b#0,app#0 | {extract} arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%1#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - // virtual: load tmp%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%1#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - byte 0x151f7c75 // (𝕡) a#0,b#0,app#0 | tmp%1#0,0x151f7c75 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - == // (𝕡) a#0,b#0,app#0 | {==} arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - // virtual: store tmp%2#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%2#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%2#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 - assert // ARC4 prefix is valid // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:35-41 + itxn_submit // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + gitxn 1 LastLog // (𝕡) a#0,b#0,app#0 | {gitxn} arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + // virtual: store awst_tmp%0#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + // virtual: load awst_tmp%0#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | awst_tmp%0#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + extract 0 4 // (𝕡) a#0,b#0,app#0 | {extract} arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%1#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + // virtual: load tmp%1#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%1#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + byte 0x151f7c75 // (𝕡) a#0,b#0,app#0 | tmp%1#0,0x151f7c75 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + == // (𝕡) a#0,b#0,app#0 | {==} arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + // virtual: store tmp%2#0 to l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%2#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) a#0,b#0,app#0 | tmp%2#0 arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 + assert // ARC4 prefix is valid // (𝕡) a#0,b#0,app#0 | arc4.abi_call(\nTxnContract.call_with_acfg,\na,\ntxn,\nb,\napp_id=app,\n) typed_abi_call_txn/caller.py:36-42 retsub // diff --git a/test_cases/typed_abi_call_txn/out/Caller.approval.teal b/test_cases/typed_abi_call_txn/out/Caller.approval.teal index e1e01abce4..3ed879b043 100644 --- a/test_cases/typed_abi_call_txn/out/Caller.approval.teal +++ b/test_cases/typed_abi_call_txn/out/Caller.approval.teal @@ -43,7 +43,7 @@ __puya_arc4_router___test_call_with_txn_route@2: retsub __puya_arc4_router___test_call_with_acfg_route@3: - // typed_abi_call_txn/caller.py:28 + // typed_abi_call_txn/caller.py:29 // @arc4.abimethod txn OnCompletion ! @@ -59,7 +59,7 @@ __puya_arc4_router___test_call_with_acfg_route@3: txna ApplicationArgs 3 btoi txnas Applications - // typed_abi_call_txn/caller.py:28 + // typed_abi_call_txn/caller.py:29 // @arc4.abimethod callsub test_call_with_acfg int 1 @@ -90,7 +90,7 @@ test_call_with_txn: // def test_call_with_txn(self, a: Bytes, b: Bytes, app: Application) -> None: proto 3 0 // typed_abi_call_txn/caller.py:20-26 - // arc4.abi_call( + // asset_id, _txn = arc4.abi_call( // TxnContract.call_with_txn, // a, // txn, @@ -117,7 +117,7 @@ test_call_with_txn: int 0 itxn_field Fee // typed_abi_call_txn/caller.py:20-26 - // arc4.abi_call( + // asset_id, _txn = arc4.abi_call( // TxnContract.call_with_txn, // a, // txn, @@ -144,7 +144,7 @@ test_call_with_txn: frame_dig -1 itxn_field ApplicationID // typed_abi_call_txn/caller.py:20-26 - // arc4.abi_call( + // asset_id, _txn = arc4.abi_call( // TxnContract.call_with_txn, // a, // txn, @@ -162,20 +162,27 @@ test_call_with_txn: itxn_field Fee itxn_submit gitxn 1 LastLog + dup + extract 4 0 + swap extract 0 4 byte 0x151f7c75 == assert // ARC4 prefix is valid + btoi + // typed_abi_call_txn/caller.py:27 + // assert asset_id, "expected asset id" + assert // expected asset id retsub // test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: test_call_with_acfg: - // typed_abi_call_txn/caller.py:28-29 + // typed_abi_call_txn/caller.py:29-30 // @arc4.abimethod // def test_call_with_acfg(self, a: Bytes, b: Bytes, app: Application) -> None: proto 3 0 - // typed_abi_call_txn/caller.py:35-41 + // typed_abi_call_txn/caller.py:36-42 // arc4.abi_call( // TxnContract.call_with_acfg, // a, @@ -184,25 +191,25 @@ test_call_with_acfg: // app_id=app, // ) itxn_begin - // typed_abi_call_txn/caller.py:33 + // typed_abi_call_txn/caller.py:34 // total=1, int 1 itxn_field ConfigAssetTotal - // typed_abi_call_txn/caller.py:32 + // typed_abi_call_txn/caller.py:33 // asset_name="TEST", byte "TEST" itxn_field ConfigAssetName - // typed_abi_call_txn/caller.py:31 + // typed_abi_call_txn/caller.py:32 // unit_name="TST", byte "TST" itxn_field ConfigAssetUnitName - // typed_abi_call_txn/caller.py:30 + // typed_abi_call_txn/caller.py:31 // txn = itxn.AssetConfig( int acfg itxn_field TypeEnum int 0 itxn_field Fee - // typed_abi_call_txn/caller.py:35-41 + // typed_abi_call_txn/caller.py:36-42 // arc4.abi_call( // TxnContract.call_with_acfg, // a, @@ -211,7 +218,7 @@ test_call_with_acfg: // app_id=app, // ) itxn_next - // typed_abi_call_txn/caller.py:37 + // typed_abi_call_txn/caller.py:38 // a, frame_dig -3 len @@ -219,7 +226,7 @@ test_call_with_acfg: extract 6 2 frame_dig -3 concat - // typed_abi_call_txn/caller.py:39 + // typed_abi_call_txn/caller.py:40 // b, frame_dig -2 len @@ -229,7 +236,7 @@ test_call_with_acfg: concat frame_dig -1 itxn_field ApplicationID - // typed_abi_call_txn/caller.py:35-41 + // typed_abi_call_txn/caller.py:36-42 // arc4.abi_call( // TxnContract.call_with_acfg, // a, diff --git a/test_cases/typed_abi_call_txn/out/Caller.arc32.json b/test_cases/typed_abi_call_txn/out/Caller.arc32.json index b1789a7a80..090f46b028 100644 --- a/test_cases/typed_abi_call_txn/out/Caller.arc32.json +++ b/test_cases/typed_abi_call_txn/out/Caller.arc32.json @@ -12,7 +12,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnR5cGVkX2FiaV9jYWxsX3R4bi5jYWxsZXIuQ2FsbGVyLmFwcHJvdmFsX3Byb2dyYW06CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0X2Nhc2VzLnR5cGVkX2FiaV9jYWxsX3R4bi5jYWxsZXIuQ2FsbGVyLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTIKICAgIC8vIGNsYXNzIENhbGxlcihBUkM0Q29udHJhY3QpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDYKICAgIG1ldGhvZCAidGVzdF9jYWxsX3dpdGhfdHhuKGJ5dGVbXSxieXRlW10sYXBwbGljYXRpb24pdm9pZCIKICAgIG1ldGhvZCAidGVzdF9jYWxsX3dpdGhfYWNmZyhieXRlW10sYnl0ZVtdLGFwcGxpY2F0aW9uKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX190ZXN0X2NhbGxfd2l0aF90eG5fcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX190ZXN0X2NhbGxfd2l0aF9hY2ZnX3JvdXRlQDMKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3Rlc3RfY2FsbF93aXRoX3R4bl9yb3V0ZUAyOgogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjEyCiAgICAvLyBjbGFzcyBDYWxsZXIoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgdGVzdF9jYWxsX3dpdGhfdHhuCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX190ZXN0X2NhbGxfd2l0aF9hY2ZnX3JvdXRlQDM6CiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTIKICAgIC8vIGNsYXNzIENhbGxlcihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB0ZXN0X2NhbGxfd2l0aF9hY2ZnCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTIKICAgIC8vIGNsYXNzIENhbGxlcihBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTAKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjEyCiAgICAvLyBjbGFzcyBDYWxsZXIoQVJDNENvbnRyYWN0KToKICAgIGludCAwCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR5cGVkX2FiaV9jYWxsX3R4bi5jYWxsZXIuQ2FsbGVyLnRlc3RfY2FsbF93aXRoX3R4bihhOiBieXRlcywgYjogYnl0ZXMsIGFwcDogdWludDY0KSAtPiB2b2lkOgp0ZXN0X2NhbGxfd2l0aF90eG46CiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjEzLTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB0ZXN0X2NhbGxfd2l0aF90eG4oc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzLCBhcHA6IEFwcGxpY2F0aW9uKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjIwLTI2CiAgICAvLyBhcmM0LmFiaV9jYWxsKAogICAgLy8gICAgIFR4bkNvbnRyYWN0LmNhbGxfd2l0aF90eG4sCiAgICAvLyAgICAgYSwKICAgIC8vICAgICB0eG4sCiAgICAvLyAgICAgYiwKICAgIC8vICAgICBhcHBfaWQ9YXBwLAogICAgLy8gKQogICAgaXR4bl9iZWdpbgogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToxOAogICAgLy8gdG90YWw9MSwKICAgIGludCAxCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VG90YWwKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTcKICAgIC8vIGFzc2V0X25hbWU9IlRFU1QiLAogICAgYnl0ZSAiVEVTVCIKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXROYW1lCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjE2CiAgICAvLyB1bml0X25hbWU9IlRTVCIsCiAgICBieXRlICJUU1QiCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VW5pdE5hbWUKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTUKICAgIC8vIHR4biA9IGl0eG4uQXNzZXRDb25maWcoCiAgICBpbnQgYWNmZwogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjIwLTI2CiAgICAvLyBhcmM0LmFiaV9jYWxsKAogICAgLy8gICAgIFR4bkNvbnRyYWN0LmNhbGxfd2l0aF90eG4sCiAgICAvLyAgICAgYSwKICAgIC8vICAgICB0eG4sCiAgICAvLyAgICAgYiwKICAgIC8vICAgICBhcHBfaWQ9YXBwLAogICAgLy8gKQogICAgaXR4bl9uZXh0CiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjIyCiAgICAvLyBhLAogICAgZnJhbWVfZGlnIC0zCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgLTMKICAgIGNvbmNhdAogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToyNAogICAgLy8gYiwKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMQogICAgaXR4bl9maWVsZCBBcHBsaWNhdGlvbklECiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjIwLTI2CiAgICAvLyBhcmM0LmFiaV9jYWxsKAogICAgLy8gICAgIFR4bkNvbnRyYWN0LmNhbGxfd2l0aF90eG4sCiAgICAvLyAgICAgYSwKICAgIC8vICAgICB0eG4sCiAgICAvLyAgICAgYiwKICAgIC8vICAgICBhcHBfaWQ9YXBwLAogICAgLy8gKQogICAgbWV0aG9kICJjYWxsX3dpdGhfdHhuKGJ5dGVbXSx0eG4sYnl0ZVtdKXVpbnQ2NCIKICAgIGl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCiAgICBzd2FwCiAgICBpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwogICAgaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKICAgIGludCBhcHBsCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIGl0eG5fc3VibWl0CiAgICBnaXR4biAxIExhc3RMb2cKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudHlwZWRfYWJpX2NhbGxfdHhuLmNhbGxlci5DYWxsZXIudGVzdF9jYWxsX3dpdGhfYWNmZyhhOiBieXRlcywgYjogYnl0ZXMsIGFwcDogdWludDY0KSAtPiB2b2lkOgp0ZXN0X2NhbGxfd2l0aF9hY2ZnOgogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToyOC0yOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgdGVzdF9jYWxsX3dpdGhfYWNmZyhzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMsIGFwcDogQXBwbGljYXRpb24pIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MzUtNDEKICAgIC8vIGFyYzQuYWJpX2NhbGwoCiAgICAvLyAgICAgVHhuQ29udHJhY3QuY2FsbF93aXRoX2FjZmcsCiAgICAvLyAgICAgYSwKICAgIC8vICAgICB0eG4sCiAgICAvLyAgICAgYiwKICAgIC8vICAgICBhcHBfaWQ9YXBwLAogICAgLy8gKQogICAgaXR4bl9iZWdpbgogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weTozMwogICAgLy8gdG90YWw9MSwKICAgIGludCAxCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VG90YWwKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MzIKICAgIC8vIGFzc2V0X25hbWU9IlRFU1QiLAogICAgYnl0ZSAiVEVTVCIKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXROYW1lCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjMxCiAgICAvLyB1bml0X25hbWU9IlRTVCIsCiAgICBieXRlICJUU1QiCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VW5pdE5hbWUKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MzAKICAgIC8vIHR4biA9IGl0eG4uQXNzZXRDb25maWcoCiAgICBpbnQgYWNmZwogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjM1LTQxCiAgICAvLyBhcmM0LmFiaV9jYWxsKAogICAgLy8gICAgIFR4bkNvbnRyYWN0LmNhbGxfd2l0aF9hY2ZnLAogICAgLy8gICAgIGEsCiAgICAvLyAgICAgdHhuLAogICAgLy8gICAgIGIsCiAgICAvLyAgICAgYXBwX2lkPWFwcCwKICAgIC8vICkKICAgIGl0eG5fbmV4dAogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weTozNwogICAgLy8gYSwKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MzkKICAgIC8vIGIsCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGl0eG5fZmllbGQgQXBwbGljYXRpb25JRAogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weTozNS00MQogICAgLy8gYXJjNC5hYmlfY2FsbCgKICAgIC8vICAgICBUeG5Db250cmFjdC5jYWxsX3dpdGhfYWNmZywKICAgIC8vICAgICBhLAogICAgLy8gICAgIHR4biwKICAgIC8vICAgICBiLAogICAgLy8gICAgIGFwcF9pZD1hcHAsCiAgICAvLyApCiAgICBtZXRob2QgImNhbGxfd2l0aF9hY2ZnKGJ5dGVbXSxhY2ZnLGJ5dGVbXSl1aW50NjQiCiAgICBpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwogICAgc3dhcAogICAgaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKICAgIGl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCiAgICBpbnQgYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICBpdHhuX3N1Ym1pdAogICAgZ2l0eG4gMSBMYXN0TG9nCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnR5cGVkX2FiaV9jYWxsX3R4bi5jYWxsZXIuQ2FsbGVyLmFwcHJvdmFsX3Byb2dyYW06CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0X2Nhc2VzLnR5cGVkX2FiaV9jYWxsX3R4bi5jYWxsZXIuQ2FsbGVyLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTIKICAgIC8vIGNsYXNzIENhbGxlcihBUkM0Q29udHJhY3QpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDYKICAgIG1ldGhvZCAidGVzdF9jYWxsX3dpdGhfdHhuKGJ5dGVbXSxieXRlW10sYXBwbGljYXRpb24pdm9pZCIKICAgIG1ldGhvZCAidGVzdF9jYWxsX3dpdGhfYWNmZyhieXRlW10sYnl0ZVtdLGFwcGxpY2F0aW9uKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX190ZXN0X2NhbGxfd2l0aF90eG5fcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX190ZXN0X2NhbGxfd2l0aF9hY2ZnX3JvdXRlQDMKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3Rlc3RfY2FsbF93aXRoX3R4bl9yb3V0ZUAyOgogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjEyCiAgICAvLyBjbGFzcyBDYWxsZXIoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgdGVzdF9jYWxsX3dpdGhfdHhuCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX190ZXN0X2NhbGxfd2l0aF9hY2ZnX3JvdXRlQDM6CiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTIKICAgIC8vIGNsYXNzIENhbGxlcihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB0ZXN0X2NhbGxfd2l0aF9hY2ZnCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTIKICAgIC8vIGNsYXNzIENhbGxlcihBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTAKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjEyCiAgICAvLyBjbGFzcyBDYWxsZXIoQVJDNENvbnRyYWN0KToKICAgIGludCAwCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR5cGVkX2FiaV9jYWxsX3R4bi5jYWxsZXIuQ2FsbGVyLnRlc3RfY2FsbF93aXRoX3R4bihhOiBieXRlcywgYjogYnl0ZXMsIGFwcDogdWludDY0KSAtPiB2b2lkOgp0ZXN0X2NhbGxfd2l0aF90eG46CiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjEzLTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB0ZXN0X2NhbGxfd2l0aF90eG4oc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzLCBhcHA6IEFwcGxpY2F0aW9uKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjIwLTI2CiAgICAvLyBhc3NldF9pZCwgX3R4biA9IGFyYzQuYWJpX2NhbGwoCiAgICAvLyAgICAgVHhuQ29udHJhY3QuY2FsbF93aXRoX3R4biwKICAgIC8vICAgICBhLAogICAgLy8gICAgIHR4biwKICAgIC8vICAgICBiLAogICAgLy8gICAgIGFwcF9pZD1hcHAsCiAgICAvLyApCiAgICBpdHhuX2JlZ2luCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjE4CiAgICAvLyB0b3RhbD0xLAogICAgaW50IDEKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRUb3RhbAogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToxNwogICAgLy8gYXNzZXRfbmFtZT0iVEVTVCIsCiAgICBieXRlICJURVNUIgogICAgaXR4bl9maWVsZCBDb25maWdBc3NldE5hbWUKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MTYKICAgIC8vIHVuaXRfbmFtZT0iVFNUIiwKICAgIGJ5dGUgIlRTVCIKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRVbml0TmFtZQogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToxNQogICAgLy8gdHhuID0gaXR4bi5Bc3NldENvbmZpZygKICAgIGludCBhY2ZnCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MjAtMjYKICAgIC8vIGFzc2V0X2lkLCBfdHhuID0gYXJjNC5hYmlfY2FsbCgKICAgIC8vICAgICBUeG5Db250cmFjdC5jYWxsX3dpdGhfdHhuLAogICAgLy8gICAgIGEsCiAgICAvLyAgICAgdHhuLAogICAgLy8gICAgIGIsCiAgICAvLyAgICAgYXBwX2lkPWFwcCwKICAgIC8vICkKICAgIGl0eG5fbmV4dAogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToyMgogICAgLy8gYSwKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MjQKICAgIC8vIGIsCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGl0eG5fZmllbGQgQXBwbGljYXRpb25JRAogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weToyMC0yNgogICAgLy8gYXNzZXRfaWQsIF90eG4gPSBhcmM0LmFiaV9jYWxsKAogICAgLy8gICAgIFR4bkNvbnRyYWN0LmNhbGxfd2l0aF90eG4sCiAgICAvLyAgICAgYSwKICAgIC8vICAgICB0eG4sCiAgICAvLyAgICAgYiwKICAgIC8vICAgICBhcHBfaWQ9YXBwLAogICAgLy8gKQogICAgbWV0aG9kICJjYWxsX3dpdGhfdHhuKGJ5dGVbXSx0eG4sYnl0ZVtdKXVpbnQ2NCIKICAgIGl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCiAgICBzd2FwCiAgICBpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwogICAgaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKICAgIGludCBhcHBsCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIGl0eG5fc3VibWl0CiAgICBnaXR4biAxIExhc3RMb2cKICAgIGR1cAogICAgZXh0cmFjdCA0IDAKICAgIHN3YXAKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIGJ0b2kKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MjcKICAgIC8vIGFzc2VydCBhc3NldF9pZCwgImV4cGVjdGVkIGFzc2V0IGlkIgogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGFzc2V0IGlkCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR5cGVkX2FiaV9jYWxsX3R4bi5jYWxsZXIuQ2FsbGVyLnRlc3RfY2FsbF93aXRoX2FjZmcoYTogYnl0ZXMsIGI6IGJ5dGVzLCBhcHA6IHVpbnQ2NCkgLT4gdm9pZDoKdGVzdF9jYWxsX3dpdGhfYWNmZzoKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MjktMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHRlc3RfY2FsbF93aXRoX2FjZmcoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzLCBhcHA6IEFwcGxpY2F0aW9uKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjM2LTQyCiAgICAvLyBhcmM0LmFiaV9jYWxsKAogICAgLy8gICAgIFR4bkNvbnRyYWN0LmNhbGxfd2l0aF9hY2ZnLAogICAgLy8gICAgIGEsCiAgICAvLyAgICAgdHhuLAogICAgLy8gICAgIGIsCiAgICAvLyAgICAgYXBwX2lkPWFwcCwKICAgIC8vICkKICAgIGl0eG5fYmVnaW4KICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MzQKICAgIC8vIHRvdGFsPTEsCiAgICBpbnQgMQogICAgaXR4bl9maWVsZCBDb25maWdBc3NldFRvdGFsCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjMzCiAgICAvLyBhc3NldF9uYW1lPSJURVNUIiwKICAgIGJ5dGUgIlRFU1QiCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0TmFtZQogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weTozMgogICAgLy8gdW5pdF9uYW1lPSJUU1QiLAogICAgYnl0ZSAiVFNUIgogICAgaXR4bl9maWVsZCBDb25maWdBc3NldFVuaXROYW1lCiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjMxCiAgICAvLyB0eG4gPSBpdHhuLkFzc2V0Q29uZmlnKAogICAgaW50IGFjZmcKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgLy8gdHlwZWRfYWJpX2NhbGxfdHhuL2NhbGxlci5weTozNi00MgogICAgLy8gYXJjNC5hYmlfY2FsbCgKICAgIC8vICAgICBUeG5Db250cmFjdC5jYWxsX3dpdGhfYWNmZywKICAgIC8vICAgICBhLAogICAgLy8gICAgIHR4biwKICAgIC8vICAgICBiLAogICAgLy8gICAgIGFwcF9pZD1hcHAsCiAgICAvLyApCiAgICBpdHhuX25leHQKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MzgKICAgIC8vIGEsCiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICAvLyB0eXBlZF9hYmlfY2FsbF90eG4vY2FsbGVyLnB5OjQwCiAgICAvLyBiLAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uSUQKICAgIC8vIHR5cGVkX2FiaV9jYWxsX3R4bi9jYWxsZXIucHk6MzYtNDIKICAgIC8vIGFyYzQuYWJpX2NhbGwoCiAgICAvLyAgICAgVHhuQ29udHJhY3QuY2FsbF93aXRoX2FjZmcsCiAgICAvLyAgICAgYSwKICAgIC8vICAgICB0eG4sCiAgICAvLyAgICAgYiwKICAgIC8vICAgICBhcHBfaWQ9YXBwLAogICAgLy8gKQogICAgbWV0aG9kICJjYWxsX3dpdGhfYWNmZyhieXRlW10sYWNmZyxieXRlW10pdWludDY0IgogICAgaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKICAgIHN3YXAKICAgIGl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCiAgICBpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwogICAgaW50IGFwcGwKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgaXR4bl9zdWJtaXQKICAgIGdpdHhuIDEgTGFzdExvZwogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBBUkM0IHByZWZpeCBpcyB2YWxpZAogICAgcmV0c3ViCg==", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnR5cGVkX2FiaV9jYWxsX3R4bi5jYWxsZXIuQ2FsbGVyLmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICBpbnQgMQogICAgcmV0dXJuCg==" }, "state": { diff --git a/test_cases/typed_abi_call_txn/out/Caller.destructured.ir b/test_cases/typed_abi_call_txn/out/Caller.destructured.ir index a5d977b176..2f1fa890db 100644 --- a/test_cases/typed_abi_call_txn/out/Caller.destructured.ir +++ b/test_cases/typed_abi_call_txn/out/Caller.destructured.ir @@ -27,7 +27,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: let tmp%13#0: uint64 = ((txnas Applications) tmp%12#0) test_cases.typed_abi_call_txn.caller.Caller.test_call_with_txn(tmp%8#0, tmp%10#0, tmp%13#0) return 1u - block@3: // test_call_with_acfg_route_L28 + block@3: // test_call_with_acfg_route_L29 let tmp%14#0: uint64 = (txn OnCompletion) let tmp%15#0: bool = (! tmp%14#0) (assert tmp%15#0) // OnCompletion is NoOp @@ -78,13 +78,16 @@ contract test_cases.typed_abi_call_txn.caller.Caller: ((itxn_field Fee) 0u) itxn_submit let awst_tmp%0#0: bytes = (gitxn 1 LastLog) + let tmp%0#0: bytes = ((extract 4 0) awst_tmp%0#0) let tmp%1#0: bytes = ((extract 0 4) awst_tmp%0#0) let tmp%2#0: bool = (== tmp%1#0 0x151f7c75) (assert tmp%2#0) // ARC4 prefix is valid + let asset_id#0: uint64 = (btoi tmp%0#0) + (assert asset_id#0) // expected asset id return subroutine test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: - block@0: // L28 + block@0: // L29 itxn_begin ((itxn_field ConfigAssetTotal) 1u) ((itxn_field ConfigAssetName) "TEST") diff --git a/test_cases/typed_abi_call_txn/out/Caller.ssa.ir b/test_cases/typed_abi_call_txn/out/Caller.ssa.ir index 8c9e6b9136..0a25605457 100644 --- a/test_cases/typed_abi_call_txn/out/Caller.ssa.ir +++ b/test_cases/typed_abi_call_txn/out/Caller.ssa.ir @@ -29,7 +29,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: let tmp%13#0: uint64 = ((txnas Applications) tmp%12#0) test_cases.typed_abi_call_txn.caller.Caller.test_call_with_txn(tmp%8#0, tmp%10#0, tmp%13#0) return 1u - block@3: // test_call_with_acfg_route_L28 + block@3: // test_call_with_acfg_route_L29 let tmp%14#0: uint64 = (txn OnCompletion) let tmp%15#0: bool = (== tmp%14#0 NoOp) (assert tmp%15#0) // OnCompletion is NoOp @@ -213,11 +213,76 @@ contract test_cases.typed_abi_call_txn.caller.Caller: let tmp%1#0: bytes = ((extract 0 4) awst_tmp%0#0) let tmp%2#0: bool = (== tmp%1#0 0x151f7c75) (assert tmp%2#0) // ARC4 prefix is valid - let tmp%3#0: uint64 = (btoi tmp%0#0) + let asset_id#0: uint64 = (btoi tmp%0#0) + let _txn#0: itxn_group_idx = itxn_group_idx(1) + let _txn._is_last#0: bool = 1u + let _txn.Sender#0: bytes = itxn[_txn#0].Sender + let _txn.Fee#0: uint64 = itxn[_txn#0].Fee + let _txn.FirstValid#0: uint64 = itxn[_txn#0].FirstValid + let _txn.FirstValidTime#0: uint64 = itxn[_txn#0].FirstValidTime + let _txn.LastValid#0: uint64 = itxn[_txn#0].LastValid + let _txn.Note#0: bytes = itxn[_txn#0].Note + let _txn.Lease#0: bytes = itxn[_txn#0].Lease + let _txn.Receiver#0: bytes = itxn[_txn#0].Receiver + let _txn.Amount#0: uint64 = itxn[_txn#0].Amount + let _txn.CloseRemainderTo#0: bytes = itxn[_txn#0].CloseRemainderTo + let _txn.VotePK#0: bytes = itxn[_txn#0].VotePK + let _txn.SelectionPK#0: bytes = itxn[_txn#0].SelectionPK + let _txn.VoteFirst#0: uint64 = itxn[_txn#0].VoteFirst + let _txn.VoteLast#0: uint64 = itxn[_txn#0].VoteLast + let _txn.VoteKeyDilution#0: uint64 = itxn[_txn#0].VoteKeyDilution + let _txn.Type#0: bytes = itxn[_txn#0].Type + let _txn.TypeEnum#0: uint64 = itxn[_txn#0].TypeEnum + let _txn.XferAsset#0: uint64 = itxn[_txn#0].XferAsset + let _txn.AssetAmount#0: uint64 = itxn[_txn#0].AssetAmount + let _txn.AssetSender#0: bytes = itxn[_txn#0].AssetSender + let _txn.AssetReceiver#0: bytes = itxn[_txn#0].AssetReceiver + let _txn.AssetCloseTo#0: bytes = itxn[_txn#0].AssetCloseTo + let _txn.GroupIndex#0: uint64 = itxn[_txn#0].GroupIndex + let _txn.TxID#0: bytes = itxn[_txn#0].TxID + let _txn.ApplicationID#0: uint64 = itxn[_txn#0].ApplicationID + let _txn.OnCompletion#0: uint64 = itxn[_txn#0].OnCompletion + let _txn.NumAppArgs#0: uint64 = itxn[_txn#0].NumAppArgs + let _txn.NumAccounts#0: uint64 = itxn[_txn#0].NumAccounts + let _txn.ApprovalProgram#0: bytes = itxn[_txn#0].ApprovalProgram + let _txn.ClearStateProgram#0: bytes = itxn[_txn#0].ClearStateProgram + let _txn.RekeyTo#0: bytes = itxn[_txn#0].RekeyTo + let _txn.ConfigAsset#0: uint64 = itxn[_txn#0].ConfigAsset + let _txn.ConfigAssetTotal#0: uint64 = itxn[_txn#0].ConfigAssetTotal + let _txn.ConfigAssetDecimals#0: uint64 = itxn[_txn#0].ConfigAssetDecimals + let _txn.ConfigAssetDefaultFrozen#0: bool = itxn[_txn#0].ConfigAssetDefaultFrozen + let _txn.ConfigAssetUnitName#0: bytes = itxn[_txn#0].ConfigAssetUnitName + let _txn.ConfigAssetName#0: bytes = itxn[_txn#0].ConfigAssetName + let _txn.ConfigAssetURL#0: bytes = itxn[_txn#0].ConfigAssetURL + let _txn.ConfigAssetMetadataHash#0: bytes = itxn[_txn#0].ConfigAssetMetadataHash + let _txn.ConfigAssetManager#0: bytes = itxn[_txn#0].ConfigAssetManager + let _txn.ConfigAssetReserve#0: bytes = itxn[_txn#0].ConfigAssetReserve + let _txn.ConfigAssetFreeze#0: bytes = itxn[_txn#0].ConfigAssetFreeze + let _txn.ConfigAssetClawback#0: bytes = itxn[_txn#0].ConfigAssetClawback + let _txn.FreezeAsset#0: uint64 = itxn[_txn#0].FreezeAsset + let _txn.FreezeAssetAccount#0: bytes = itxn[_txn#0].FreezeAssetAccount + let _txn.FreezeAssetFrozen#0: bool = itxn[_txn#0].FreezeAssetFrozen + let _txn.NumAssets#0: uint64 = itxn[_txn#0].NumAssets + let _txn.NumApplications#0: uint64 = itxn[_txn#0].NumApplications + let _txn.GlobalNumUint#0: uint64 = itxn[_txn#0].GlobalNumUint + let _txn.GlobalNumByteSlice#0: uint64 = itxn[_txn#0].GlobalNumByteSlice + let _txn.LocalNumUint#0: uint64 = itxn[_txn#0].LocalNumUint + let _txn.LocalNumByteSlice#0: uint64 = itxn[_txn#0].LocalNumByteSlice + let _txn.ExtraProgramPages#0: uint64 = itxn[_txn#0].ExtraProgramPages + let _txn.Nonparticipation#0: bool = itxn[_txn#0].Nonparticipation + let _txn.NumLogs#0: uint64 = itxn[_txn#0].NumLogs + let _txn.CreatedAssetID#0: uint64 = itxn[_txn#0].CreatedAssetID + let _txn.CreatedApplicationID#0: uint64 = itxn[_txn#0].CreatedApplicationID + let _txn.LastLog#0: bytes = itxn[_txn#0].LastLog + let _txn.StateProofPK#0: bytes = itxn[_txn#0].StateProofPK + let _txn.NumApprovalProgramPages#0: uint64 = itxn[_txn#0].NumApprovalProgramPages + let _txn.NumClearStateProgramPages#0: uint64 = itxn[_txn#0].NumClearStateProgramPages + let tmp%3#0: bool = (!= asset_id#0 0u) + (assert tmp%3#0) // expected asset id return subroutine test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: - block@0: // L28 + block@0: // L29 let txn#0: itxn_field_set = itxn_field_set(0) let txn%%param_Fee_idx_0#0: uint64 = 0u let txn%%Fee_length#0: uint64 = 1u @@ -282,7 +347,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: ((itxn_field TypeEnum) txn%%param_TypeEnum_idx_0#0) ((itxn_field Fee) txn%%param_Fee_idx_0#0) goto block@1 - block@1: // next_txn_L38 + block@1: // next_txn_L39 itxn_next let inner_txn_params%0#0: itxn_field_set = itxn_field_set(1) let inner_txn_params%0%%param_Fee_idx_0#0: uint64 = 0u @@ -357,7 +422,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: ((itxn_field TypeEnum) inner_txn_params%0%%param_TypeEnum_idx_0#0) ((itxn_field Fee) inner_txn_params%0%%param_Fee_idx_0#0) goto block@2 - block@2: // next_txn_L35 + block@2: // next_txn_L36 itxn_submit let awst_tmp%0#0: bytes = itxn[itxn_group_idx(1)].LastLog let tmp%0#0: bytes = ((extract 4 0) awst_tmp%0#0) diff --git a/test_cases/typed_abi_call_txn/out/Caller.ssa.opt_pass_1.ir b/test_cases/typed_abi_call_txn/out/Caller.ssa.opt_pass_1.ir index 4965675a9a..11c72bdfbb 100644 --- a/test_cases/typed_abi_call_txn/out/Caller.ssa.opt_pass_1.ir +++ b/test_cases/typed_abi_call_txn/out/Caller.ssa.opt_pass_1.ir @@ -27,7 +27,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: let tmp%13#0: uint64 = ((txnas Applications) tmp%12#0) test_cases.typed_abi_call_txn.caller.Caller.test_call_with_txn(tmp%8#0, tmp%10#0, tmp%13#0) return 1u - block@3: // test_call_with_acfg_route_L28 + block@3: // test_call_with_acfg_route_L29 let tmp%14#0: uint64 = (txn OnCompletion) let tmp%15#0: bool = (! tmp%14#0) (assert tmp%15#0) // OnCompletion is NoOp @@ -82,10 +82,12 @@ contract test_cases.typed_abi_call_txn.caller.Caller: let tmp%1#0: bytes = ((extract 0 4) awst_tmp%0#0) let tmp%2#0: bool = (== tmp%1#0 0x151f7c75) (assert tmp%2#0) // ARC4 prefix is valid + let asset_id#0: uint64 = (btoi tmp%0#0) + (assert asset_id#0) // expected asset id return subroutine test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: - block@0: // L28 + block@0: // L29 itxn_begin ((itxn_field ConfigAssetTotal) 1u) ((itxn_field ConfigAssetName) "TEST") diff --git a/test_cases/typed_abi_call_txn/out/Caller.ssa.opt_pass_2.ir b/test_cases/typed_abi_call_txn/out/Caller.ssa.opt_pass_2.ir index a5d977b176..2f1fa890db 100644 --- a/test_cases/typed_abi_call_txn/out/Caller.ssa.opt_pass_2.ir +++ b/test_cases/typed_abi_call_txn/out/Caller.ssa.opt_pass_2.ir @@ -27,7 +27,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: let tmp%13#0: uint64 = ((txnas Applications) tmp%12#0) test_cases.typed_abi_call_txn.caller.Caller.test_call_with_txn(tmp%8#0, tmp%10#0, tmp%13#0) return 1u - block@3: // test_call_with_acfg_route_L28 + block@3: // test_call_with_acfg_route_L29 let tmp%14#0: uint64 = (txn OnCompletion) let tmp%15#0: bool = (! tmp%14#0) (assert tmp%15#0) // OnCompletion is NoOp @@ -78,13 +78,16 @@ contract test_cases.typed_abi_call_txn.caller.Caller: ((itxn_field Fee) 0u) itxn_submit let awst_tmp%0#0: bytes = (gitxn 1 LastLog) + let tmp%0#0: bytes = ((extract 4 0) awst_tmp%0#0) let tmp%1#0: bytes = ((extract 0 4) awst_tmp%0#0) let tmp%2#0: bool = (== tmp%1#0 0x151f7c75) (assert tmp%2#0) // ARC4 prefix is valid + let asset_id#0: uint64 = (btoi tmp%0#0) + (assert asset_id#0) // expected asset id return subroutine test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: - block@0: // L28 + block@0: // L29 itxn_begin ((itxn_field ConfigAssetTotal) 1u) ((itxn_field ConfigAssetName) "TEST") diff --git a/test_cases/typed_abi_call_txn/out/module.awst b/test_cases/typed_abi_call_txn/out/module.awst index 48bd5cef7d..1d33b1491b 100644 --- a/test_cases/typed_abi_call_txn/out/module.awst +++ b/test_cases/typed_abi_call_txn/out/module.awst @@ -31,7 +31,8 @@ contract Caller extends (algopy.arc4.ARC4Contract) abimethod test_call_with_txn(a: bytes, b: bytes, app: application): void { txn: inner_transaction_fields_acfg = create_inner_transaction(Fee=0u, TypeEnum=acfg, ConfigAssetUnitName='TST', ConfigAssetName='TEST', ConfigAssetTotal=1u) - (arc4_decode(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=2, source=SINGLE_EVAL(id=1, source=SINGLE_EVAL(id=0, source=submit_txn(txn, create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("call_with_txn(byte[],txn,byte[])uint64"), arc4_encode(a, arc4.dynamic_array), arc4_encode(b, arc4.dynamic_array)), ApplicationID=app)))[-1]).LastLog)), extract<0, 4>(SINGLE_EVAL(id=2)) == hex<"151F7C75">)), uint64), SINGLE_EVAL(id=1)) + (asset_id, _txn): tuple = (arc4_decode(checked_maybe((extract<4, 0>(SINGLE_EVAL(id=2, source=SINGLE_EVAL(id=1, source=SINGLE_EVAL(id=0, source=submit_txn(txn, create_inner_transaction(Fee=0u, TypeEnum=appl, ApplicationArgs=(Method("call_with_txn(byte[],txn,byte[])uint64"), arc4_encode(a, arc4.dynamic_array), arc4_encode(b, arc4.dynamic_array)), ApplicationID=app)))[-1]).LastLog)), extract<0, 4>(SINGLE_EVAL(id=2)) == hex<"151F7C75">)), uint64), SINGLE_EVAL(id=1)) + assert(asset_id != 0u, comment="expected asset id") } abimethod test_call_with_acfg(a: bytes, b: bytes, app: application): void diff --git a/test_cases/typed_abi_call_txn/out_O2/Caller.approval.teal b/test_cases/typed_abi_call_txn/out_O2/Caller.approval.teal index 7c6db62079..83a6bb98a5 100644 --- a/test_cases/typed_abi_call_txn/out_O2/Caller.approval.teal +++ b/test_cases/typed_abi_call_txn/out_O2/Caller.approval.teal @@ -105,10 +105,15 @@ test_call_with_txn: itxn_field Fee itxn_submit gitxn 1 LastLog + dup + extract 4 0 + swap extract 0 4 byte 0x151f7c75 == assert // ARC4 prefix is valid + btoi + assert // expected asset id retsub diff --git a/test_cases/typed_abi_call_txn/out_O2/Caller.destructured.ir b/test_cases/typed_abi_call_txn/out_O2/Caller.destructured.ir index a5d977b176..2f1fa890db 100644 --- a/test_cases/typed_abi_call_txn/out_O2/Caller.destructured.ir +++ b/test_cases/typed_abi_call_txn/out_O2/Caller.destructured.ir @@ -27,7 +27,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: let tmp%13#0: uint64 = ((txnas Applications) tmp%12#0) test_cases.typed_abi_call_txn.caller.Caller.test_call_with_txn(tmp%8#0, tmp%10#0, tmp%13#0) return 1u - block@3: // test_call_with_acfg_route_L28 + block@3: // test_call_with_acfg_route_L29 let tmp%14#0: uint64 = (txn OnCompletion) let tmp%15#0: bool = (! tmp%14#0) (assert tmp%15#0) // OnCompletion is NoOp @@ -78,13 +78,16 @@ contract test_cases.typed_abi_call_txn.caller.Caller: ((itxn_field Fee) 0u) itxn_submit let awst_tmp%0#0: bytes = (gitxn 1 LastLog) + let tmp%0#0: bytes = ((extract 4 0) awst_tmp%0#0) let tmp%1#0: bytes = ((extract 0 4) awst_tmp%0#0) let tmp%2#0: bool = (== tmp%1#0 0x151f7c75) (assert tmp%2#0) // ARC4 prefix is valid + let asset_id#0: uint64 = (btoi tmp%0#0) + (assert asset_id#0) // expected asset id return subroutine test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: - block@0: // L28 + block@0: // L29 itxn_begin ((itxn_field ConfigAssetTotal) 1u) ((itxn_field ConfigAssetName) "TEST") diff --git a/test_cases/typed_abi_call_txn/out_unoptimized/Caller.approval.teal b/test_cases/typed_abi_call_txn/out_unoptimized/Caller.approval.teal index a8ee496008..4bf76cea1f 100644 --- a/test_cases/typed_abi_call_txn/out_unoptimized/Caller.approval.teal +++ b/test_cases/typed_abi_call_txn/out_unoptimized/Caller.approval.teal @@ -51,7 +51,7 @@ __puya_arc4_router___test_call_with_txn_route@2: retsub __puya_arc4_router___test_call_with_acfg_route@3: - // typed_abi_call_txn/caller.py:28 + // typed_abi_call_txn/caller.py:29 // @arc4.abimethod txn OnCompletion int NoOp @@ -70,7 +70,7 @@ __puya_arc4_router___test_call_with_acfg_route@3: txna ApplicationArgs 3 btoi txnas Applications - // typed_abi_call_txn/caller.py:28 + // typed_abi_call_txn/caller.py:29 // @arc4.abimethod uncover 2 uncover 2 @@ -118,7 +118,7 @@ test_call_with_txn: // def test_call_with_txn(self, a: Bytes, b: Bytes, app: Application) -> None: proto 3 0 // typed_abi_call_txn/caller.py:20-26 - // arc4.abi_call( + // asset_id, _txn = arc4.abi_call( // TxnContract.call_with_txn, // a, // txn, @@ -145,7 +145,7 @@ test_call_with_txn: int 0 itxn_field Fee // typed_abi_call_txn/caller.py:20-26 - // arc4.abi_call( + // asset_id, _txn = arc4.abi_call( // TxnContract.call_with_txn, // a, // txn, @@ -175,7 +175,7 @@ test_call_with_txn: frame_dig -1 itxn_field ApplicationID // typed_abi_call_txn/caller.py:20-26 - // arc4.abi_call( + // asset_id, _txn = arc4.abi_call( // TxnContract.call_with_txn, // a, // txn, @@ -192,20 +192,29 @@ test_call_with_txn: itxn_field Fee itxn_submit gitxn 1 LastLog + dup + extract 4 0 + cover 1 extract 0 4 byte 0x151f7c75 == assert // ARC4 prefix is valid + btoi + // typed_abi_call_txn/caller.py:27 + // assert asset_id, "expected asset id" + int 0 + != + assert // expected asset id retsub // test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: test_call_with_acfg: - // typed_abi_call_txn/caller.py:28-29 + // typed_abi_call_txn/caller.py:29-30 // @arc4.abimethod // def test_call_with_acfg(self, a: Bytes, b: Bytes, app: Application) -> None: proto 3 0 - // typed_abi_call_txn/caller.py:35-41 + // typed_abi_call_txn/caller.py:36-42 // arc4.abi_call( // TxnContract.call_with_acfg, // a, @@ -214,25 +223,25 @@ test_call_with_acfg: // app_id=app, // ) itxn_begin - // typed_abi_call_txn/caller.py:33 + // typed_abi_call_txn/caller.py:34 // total=1, int 1 itxn_field ConfigAssetTotal - // typed_abi_call_txn/caller.py:32 + // typed_abi_call_txn/caller.py:33 // asset_name="TEST", byte "TEST" itxn_field ConfigAssetName - // typed_abi_call_txn/caller.py:31 + // typed_abi_call_txn/caller.py:32 // unit_name="TST", byte "TST" itxn_field ConfigAssetUnitName - // typed_abi_call_txn/caller.py:30 + // typed_abi_call_txn/caller.py:31 // txn = itxn.AssetConfig( int acfg itxn_field TypeEnum int 0 itxn_field Fee - // typed_abi_call_txn/caller.py:35-41 + // typed_abi_call_txn/caller.py:36-42 // arc4.abi_call( // TxnContract.call_with_acfg, // a, @@ -241,7 +250,7 @@ test_call_with_acfg: // app_id=app, // ) itxn_next - // typed_abi_call_txn/caller.py:37 + // typed_abi_call_txn/caller.py:38 // a, frame_dig -3 len @@ -249,7 +258,7 @@ test_call_with_acfg: extract 6 2 frame_dig -3 concat - // typed_abi_call_txn/caller.py:39 + // typed_abi_call_txn/caller.py:40 // b, frame_dig -2 len @@ -258,11 +267,11 @@ test_call_with_acfg: frame_dig -2 concat cover 1 - // typed_abi_call_txn/caller.py:29 + // typed_abi_call_txn/caller.py:30 // def test_call_with_acfg(self, a: Bytes, b: Bytes, app: Application) -> None: frame_dig -1 itxn_field ApplicationID - // typed_abi_call_txn/caller.py:35-41 + // typed_abi_call_txn/caller.py:36-42 // arc4.abi_call( // TxnContract.call_with_acfg, // a, diff --git a/test_cases/typed_abi_call_txn/out_unoptimized/Caller.destructured.ir b/test_cases/typed_abi_call_txn/out_unoptimized/Caller.destructured.ir index 1eafeaa14b..320432fa72 100644 --- a/test_cases/typed_abi_call_txn/out_unoptimized/Caller.destructured.ir +++ b/test_cases/typed_abi_call_txn/out_unoptimized/Caller.destructured.ir @@ -29,7 +29,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: let tmp%13#0: uint64 = ((txnas Applications) tmp%12#0) test_cases.typed_abi_call_txn.caller.Caller.test_call_with_txn(tmp%8#0, tmp%10#0, tmp%13#0) return 1u - block@3: // test_call_with_acfg_route_L28 + block@3: // test_call_with_acfg_route_L29 let tmp%14#0: uint64 = (txn OnCompletion) let tmp%15#0: bool = (== tmp%14#0 NoOp) (assert tmp%15#0) // OnCompletion is NoOp @@ -97,13 +97,17 @@ contract test_cases.typed_abi_call_txn.caller.Caller: block@2: // next_txn_L20 itxn_submit let awst_tmp%0#0: bytes = (gitxn 1 LastLog) + let tmp%0#0: bytes = ((extract 4 0) awst_tmp%0#0) let tmp%1#0: bytes = ((extract 0 4) awst_tmp%0#0) let tmp%2#0: bool = (== tmp%1#0 0x151f7c75) (assert tmp%2#0) // ARC4 prefix is valid + let asset_id#0: uint64 = (btoi tmp%0#0) + let tmp%3#0: bool = (!= asset_id#0 0u) + (assert tmp%3#0) // expected asset id return subroutine test_cases.typed_abi_call_txn.caller.Caller.test_call_with_acfg(a: bytes, b: bytes, app: uint64) -> void: - block@0: // L28 + block@0: // L29 itxn_begin ((itxn_field ConfigAssetTotal) 1u) ((itxn_field ConfigAssetName) "TEST") @@ -111,7 +115,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: ((itxn_field TypeEnum) acfg) ((itxn_field Fee) 0u) goto block@1 - block@1: // next_txn_L38 + block@1: // next_txn_L39 itxn_next let length%0#0: uint64 = (len a#0) let as_bytes%0#0: bytes = (itob length%0#0) @@ -131,7 +135,7 @@ contract test_cases.typed_abi_call_txn.caller.Caller: ((itxn_field TypeEnum) appl) ((itxn_field Fee) 0u) goto block@2 - block@2: // next_txn_L35 + block@2: // next_txn_L36 itxn_submit let awst_tmp%0#0: bytes = (gitxn 1 LastLog) let tmp%1#0: bytes = ((extract 0 4) awst_tmp%0#0) diff --git a/test_cases/typed_abi_call_txn/puya.log b/test_cases/typed_abi_call_txn/puya.log index b141969cfe..44abbf0c06 100644 --- a/test_cases/typed_abi_call_txn/puya.log +++ b/test_cases/typed_abi_call_txn/puya.log @@ -388,8 +388,8 @@ debug: Sealing block@1: // abi_routing_L12 debug: Terminated block@1: // abi_routing_L12 debug: Sealing block@2: // test_call_with_txn_route_L13 debug: Terminated block@2: // test_call_with_txn_route_L13 -debug: Sealing block@3: // test_call_with_acfg_route_L28 -debug: Terminated block@3: // test_call_with_acfg_route_L28 +debug: Sealing block@3: // test_call_with_acfg_route_L29 +debug: Terminated block@3: // test_call_with_acfg_route_L29 debug: Sealing block@4: // switch_case_default_L12 debug: Terminated block@4: // switch_case_default_L12 debug: Sealing block@5: // switch_case_next_L12 @@ -410,12 +410,12 @@ debug: Sealing block@1: // next_txn_L23 debug: Terminated block@1: // next_txn_L23 debug: Sealing block@2: // next_txn_L20 debug: Terminated block@2: // next_txn_L20 -debug: Sealing block@0: // L28 -debug: Terminated block@0: // L28 -debug: Sealing block@1: // next_txn_L38 -debug: Terminated block@1: // next_txn_L38 -debug: Sealing block@2: // next_txn_L35 -debug: Terminated block@2: // next_txn_L35 +debug: Sealing block@0: // L29 +debug: Terminated block@0: // L29 +debug: Sealing block@1: // next_txn_L39 +debug: Terminated block@1: // next_txn_L39 +debug: Sealing block@2: // next_txn_L36 +debug: Terminated block@2: // next_txn_L36 debug: Sealing block@0: // L12 debug: Terminated block@0: // L12 debug: Sealing block@0: // L1 @@ -897,6 +897,69 @@ debug: Removing unused variable inner_txn_params%0%%Assets_length#0 debug: Removing unused variable inner_txn_params%0%%Applications_length#0 debug: Removing unused variable inner_txn_params%0%%ApprovalProgramPages_length#0 debug: Removing unused variable inner_txn_params%0%%ClearStateProgramPages_length#0 +debug: Removing unused variable _txn#0 +debug: Removing unused variable _txn._is_last#0 +debug: Removing unused variable _txn.Sender#0 +debug: Removing unused variable _txn.Fee#0 +debug: Removing unused variable _txn.FirstValid#0 +debug: Removing unused variable _txn.FirstValidTime#0 +debug: Removing unused variable _txn.LastValid#0 +debug: Removing unused variable _txn.Note#0 +debug: Removing unused variable _txn.Lease#0 +debug: Removing unused variable _txn.Receiver#0 +debug: Removing unused variable _txn.Amount#0 +debug: Removing unused variable _txn.CloseRemainderTo#0 +debug: Removing unused variable _txn.VotePK#0 +debug: Removing unused variable _txn.SelectionPK#0 +debug: Removing unused variable _txn.VoteFirst#0 +debug: Removing unused variable _txn.VoteLast#0 +debug: Removing unused variable _txn.VoteKeyDilution#0 +debug: Removing unused variable _txn.Type#0 +debug: Removing unused variable _txn.TypeEnum#0 +debug: Removing unused variable _txn.XferAsset#0 +debug: Removing unused variable _txn.AssetAmount#0 +debug: Removing unused variable _txn.AssetSender#0 +debug: Removing unused variable _txn.AssetReceiver#0 +debug: Removing unused variable _txn.AssetCloseTo#0 +debug: Removing unused variable _txn.GroupIndex#0 +debug: Removing unused variable _txn.TxID#0 +debug: Removing unused variable _txn.ApplicationID#0 +debug: Removing unused variable _txn.OnCompletion#0 +debug: Removing unused variable _txn.NumAppArgs#0 +debug: Removing unused variable _txn.NumAccounts#0 +debug: Removing unused variable _txn.ApprovalProgram#0 +debug: Removing unused variable _txn.ClearStateProgram#0 +debug: Removing unused variable _txn.RekeyTo#0 +debug: Removing unused variable _txn.ConfigAsset#0 +debug: Removing unused variable _txn.ConfigAssetTotal#0 +debug: Removing unused variable _txn.ConfigAssetDecimals#0 +debug: Removing unused variable _txn.ConfigAssetDefaultFrozen#0 +debug: Removing unused variable _txn.ConfigAssetUnitName#0 +debug: Removing unused variable _txn.ConfigAssetName#0 +debug: Removing unused variable _txn.ConfigAssetURL#0 +debug: Removing unused variable _txn.ConfigAssetMetadataHash#0 +debug: Removing unused variable _txn.ConfigAssetManager#0 +debug: Removing unused variable _txn.ConfigAssetReserve#0 +debug: Removing unused variable _txn.ConfigAssetFreeze#0 +debug: Removing unused variable _txn.ConfigAssetClawback#0 +debug: Removing unused variable _txn.FreezeAsset#0 +debug: Removing unused variable _txn.FreezeAssetAccount#0 +debug: Removing unused variable _txn.FreezeAssetFrozen#0 +debug: Removing unused variable _txn.NumAssets#0 +debug: Removing unused variable _txn.NumApplications#0 +debug: Removing unused variable _txn.GlobalNumUint#0 +debug: Removing unused variable _txn.GlobalNumByteSlice#0 +debug: Removing unused variable _txn.LocalNumUint#0 +debug: Removing unused variable _txn.LocalNumByteSlice#0 +debug: Removing unused variable _txn.ExtraProgramPages#0 +debug: Removing unused variable _txn.Nonparticipation#0 +debug: Removing unused variable _txn.NumLogs#0 +debug: Removing unused variable _txn.CreatedAssetID#0 +debug: Removing unused variable _txn.CreatedApplicationID#0 +debug: Removing unused variable _txn.LastLog#0 +debug: Removing unused variable _txn.StateProofPK#0 +debug: Removing unused variable _txn.NumApprovalProgramPages#0 +debug: Removing unused variable _txn.NumClearStateProgramPages#0 debug: Removing unused variable tmp%3#0 debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Replace Compiled References @@ -1038,9 +1101,9 @@ debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Replace Compiled References debug: Optimizer: Simplify Control Ops debug: Optimizer: Remove Linear Jump -debug: Replaced predecessor block@1: // next_txn_L38 with block@0: // L28 in block@2: // next_txn_L35 -debug: Merged linear block@1: // next_txn_L38 into block@0: // L28 -debug: Merged linear block@2: // next_txn_L35 into block@0: // L28 +debug: Replaced predecessor block@1: // next_txn_L39 with block@0: // L29 in block@2: // next_txn_L36 +debug: Merged linear block@1: // next_txn_L39 into block@0: // L29 +debug: Merged linear block@2: // next_txn_L36 into block@0: // L29 debug: Optimizer: Remove Empty Blocks debug: Optimizer: Remove Unreachable Blocks debug: Optimizer: Repeated Expression Elimination @@ -1106,7 +1169,6 @@ debug: Optimizer: Constant Replacer debug: Optimizer: Copy Propagation debug: Optimizer: Intrinsic Simplifier debug: Optimizer: Remove Unused Variables -debug: Removing unused variable tmp%0#0 debug: Optimizer: Inner Txn Field Replacer debug: Optimizer: Replace Compiled References debug: Optimizer: Simplify Control Ops @@ -1299,12 +1361,18 @@ debug: Inserted test_call_with_txn_block@0.ops[38]: 'store length_uint16%1#0 to debug: Replaced test_call_with_txn_block@0.ops[40]: 'load length_uint16%1#0' with 'load length_uint16%1#0 from l-stack (no copy)' debug: Inserted test_call_with_txn_block@0.ops[58]: 'store awst_tmp%0#0 to l-stack (copy)' debug: Replaced test_call_with_txn_block@0.ops[60]: 'load awst_tmp%0#0' with 'load awst_tmp%0#0 from l-stack (no copy)' -debug: Inserted test_call_with_txn_block@0.ops[62]: 'store tmp%1#0 to l-stack (copy)' -debug: Replaced test_call_with_txn_block@0.ops[64]: 'load tmp%1#0' with 'load tmp%1#0 from l-stack (no copy)' -debug: Inserted test_call_with_txn_block@0.ops[67]: 'store tmp%2#0 to l-stack (copy)' -debug: Replaced test_call_with_txn_block@0.ops[69]: 'load tmp%2#0' with 'load tmp%2#0 from l-stack (no copy)' +debug: Inserted test_call_with_txn_block@0.ops[65]: 'store tmp%1#0 to l-stack (copy)' +debug: Replaced test_call_with_txn_block@0.ops[67]: 'load tmp%1#0' with 'load tmp%1#0 from l-stack (no copy)' +debug: Inserted test_call_with_txn_block@0.ops[70]: 'store tmp%2#0 to l-stack (copy)' +debug: Replaced test_call_with_txn_block@0.ops[72]: 'load tmp%2#0' with 'load tmp%2#0 from l-stack (no copy)' +debug: Inserted test_call_with_txn_block@0.ops[76]: 'store asset_id#0 to l-stack (copy)' +debug: Replaced test_call_with_txn_block@0.ops[78]: 'load asset_id#0' with 'load asset_id#0 from l-stack (no copy)' +debug: Inserted test_call_with_txn_block@0.ops[61]: 'store awst_tmp%0#0 to l-stack (copy)' +debug: Replaced test_call_with_txn_block@0.ops[64]: 'load awst_tmp%0#0' with 'load awst_tmp%0#0 from l-stack (no copy)' debug: Inserted test_call_with_txn_block@0.ops[43]: 'store encoded_value%1#0 to l-stack (copy)' debug: Replaced test_call_with_txn_block@0.ops[51]: 'load encoded_value%1#0' with 'load encoded_value%1#0 from l-stack (no copy)' +debug: Inserted test_call_with_txn_block@0.ops[64]: 'store tmp%0#0 to l-stack (copy)' +debug: Replaced test_call_with_txn_block@0.ops[77]: 'load tmp%0#0' with 'load tmp%0#0 from l-stack (no copy)' debug: Inserted test_call_with_txn_block@0.ops[27]: 'store encoded_value%0#0 to l-stack (copy)' debug: Replaced test_call_with_txn_block@0.ops[50]: 'load encoded_value%0#0' with 'load encoded_value%0#0 from l-stack (no copy)' debug: Inserted test_call_with_acfg_block@0.ops[14]: 'store length%0#0 to l-stack (copy)'