From 5790124de4e8f032d56c929e7c0de1cb0b1fd95c Mon Sep 17 00:00:00 2001 From: evan-schott <53463459+evan-schott@users.noreply.github.com> Date: Mon, 8 Apr 2024 11:18:45 -0700 Subject: [PATCH] test parity with snarkVM --- .../futures/future_not_all_awaited_fail.out | 5 + ...ture_not_all_passed_to_async_call_fail.out | 5 + .../expectations/compiler/futures/nested.out | 57 ++++++++++++ .../expectations/compiler/futures/simple.out | 31 +++++++ .../futures/future_not_all_awaited_fail.leo | 46 +++++++++ ...ture_not_all_passed_to_async_call_fail.leo | 53 +++++++++++ tests/tests/compiler/futures/nested.leo | 93 +++++++++++++++++++ tests/tests/compiler/futures/simple.leo | 33 +++++++ 8 files changed, 323 insertions(+) create mode 100644 tests/expectations/compiler/futures/future_not_all_awaited_fail.out create mode 100644 tests/expectations/compiler/futures/future_not_all_passed_to_async_call_fail.out create mode 100644 tests/expectations/compiler/futures/nested.out create mode 100644 tests/expectations/compiler/futures/simple.out create mode 100644 tests/tests/compiler/futures/future_not_all_awaited_fail.leo create mode 100644 tests/tests/compiler/futures/future_not_all_passed_to_async_call_fail.leo create mode 100644 tests/tests/compiler/futures/nested.leo create mode 100644 tests/tests/compiler/futures/simple.leo diff --git a/tests/expectations/compiler/futures/future_not_all_awaited_fail.out b/tests/expectations/compiler/futures/future_not_all_awaited_fail.out new file mode 100644 index 0000000000..2b466ac26d --- /dev/null +++ b/tests/expectations/compiler/futures/future_not_all_awaited_fail.out @@ -0,0 +1,5 @@ +--- +namespace: Compile +expectation: Fail +outputs: + - "Error [ETYC0372104]: The following futures were never awaited: f4\n --> compiler-test:12:5\n |\n 12 | async function finalize_foo(f0: Future, f1: Future, f2: Future, f3: Future, f4: Future, f5: Future) {\n 13 | f1.await();\n 14 | f2.await();\n 15 | f3.await();\n 16 | f0.await();\n 17 | f5.await();\n 18 | }\n | ^\n |\n = Ex: for `f: Future` call `f.await()` to await a future.\n" diff --git a/tests/expectations/compiler/futures/future_not_all_passed_to_async_call_fail.out b/tests/expectations/compiler/futures/future_not_all_passed_to_async_call_fail.out new file mode 100644 index 0000000000..8b81384e7d --- /dev/null +++ b/tests/expectations/compiler/futures/future_not_all_passed_to_async_call_fail.out @@ -0,0 +1,5 @@ +--- +namespace: Compile +expectation: Fail +outputs: + - "Error [ETYC0372115]: Not all futures were consumed: f1\n --> compiler-test:16:16\n |\n 16 | return finalize_foo(f0, f3, f2, f5, f4);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n |\n = Make sure all futures are consumed exactly once. Consume by passing to an async function call.\n" diff --git a/tests/expectations/compiler/futures/nested.out b/tests/expectations/compiler/futures/nested.out new file mode 100644 index 0000000000..d819aa6031 --- /dev/null +++ b/tests/expectations/compiler/futures/nested.out @@ -0,0 +1,57 @@ +--- +namespace: Compile +expectation: Pass +outputs: + - - compile: + - initial_symbol_table: dae357041d36da1120cf105172587da66def60fa8b3e628ed5fff17b982a659c + type_checked_symbol_table: f3b647588241ff6b01e59cf177b86171f7f2a592dcf72e52a72896296c697300 + unrolled_symbol_table: f3b647588241ff6b01e59cf177b86171f7f2a592dcf72e52a72896296c697300 + initial_ast: 39133a103f2f3b642b71ab3d3cff63208dbdf4046d9e11f24ef2db36643ea6ad + unrolled_ast: 39133a103f2f3b642b71ab3d3cff63208dbdf4046d9e11f24ef2db36643ea6ad + ssa_ast: 7bb68239eae8b54a9d05ccda3d2d233d2bbd64ea3279dc17d88c385cc03f53f7 + flattened_ast: 56743a5fdf067555159476aaa7ec14e3d4d1a411d87a9e8cdc63412e9e5458a6 + destructured_ast: ef747062ccb6ce25f3c12c454f2962a452edadce34f39fa658e022ee22d84806 + inlined_ast: b0d5479dfb26351bcbfec2a0efca41bc8bbb9420723d1e6c91ee769a48a6b619 + dce_ast: 2fdb23928efb46e9f91af70dbc9c7f6082c1998778c8b3b412ef06d9cf96eec0 + bytecode: 833525edcc02927d3c52ea36f01ee8b6100738cb8d8c2d26fedec7365c622169 + errors: "" + warnings: "" + - initial_symbol_table: ed7c9d3e814ddcc7686a6585e0e823cfd8400eba7458ed011db1b1abde398fdc + type_checked_symbol_table: 7832db804a9257b494d0e6222c4ed676b4e59b919f218050c69c8bb792f84366 + unrolled_symbol_table: 7832db804a9257b494d0e6222c4ed676b4e59b919f218050c69c8bb792f84366 + initial_ast: dcefb152cf26b6ebbcc97687efe1c5a3c0dbba0b8ed613d03dd700e3f85df9d4 + unrolled_ast: 2d0c1760e413a88abd05d24bb350b44f51ab26815dde02ee00fcf228d45f3326 + ssa_ast: 8467d96a1185b59e3c11dc8a9ee309b6c3b93e02f2891e7faf675a45c71b4078 + flattened_ast: ede5cc1d50b2fbc89cf2aed9cb4e48ab65401210ba97e498bd317f08f38492b8 + destructured_ast: e53fb17e29e433005d0c89178e442be9869dd653f33253648ac1cb44313767a9 + inlined_ast: 67902a89b1770e7b732851086c0922e0af1fde9794d081875e301fee6c10354b + dce_ast: 50604dc814424d9fd0fc2f70923b56a44a626297befc47561c5a41af21c40e5f + bytecode: 54b6bc6aa92b27fa7a8266c76f58173d50890d94cc46e3c9edc023e22d48c4c8 + errors: "" + warnings: "Warning [WTYC0372000]: Not all paths through the function await all futures. 2/4 paths contain at least one future that is never awaited.\n --> compiler-test:17:5\n |\n 17 | async function finalize_main(f: Future, f2: Future, a: u32) {\n 18 | // f.await();\n 19 | if a == 1u32 {\n 20 | Future::await(f);\n 21 | f2.await();\n 22 | }\n 23 | \n 24 | if a == 2u32 {\n 25 | //f2.await();\n 26 | Mapping::set(ayo, 1u32, 1u32);\n 27 | }\n 28 | \n 29 | let total: u32 = f.0 + f2.0;\n 30 | Mapping::set(ayo, 1u32, total);\n 31 | }\n | ^\n |\n = Ex: `f.await()` to await a future. Remove this warning by including the `--disable-conditional-branch-type-checking` flag." + - initial_symbol_table: 2e1f799adc7efd3ce3222975fe05ce5622a9c0945dbca930c38160d9ffc31725 + type_checked_symbol_table: a0bfeeb827a70464a88e80174ffdc64e3194b46bff56acf8b8cbc34cc56867d0 + unrolled_symbol_table: a0bfeeb827a70464a88e80174ffdc64e3194b46bff56acf8b8cbc34cc56867d0 + initial_ast: a308ff9a4303940219e622a8b569f15fca293a71e350fec3576662ea8934c611 + unrolled_ast: a992e9c9dc248e6408023ccc4a9379b2d4c7b65f7fab77d9c771bd2b6c866a75 + ssa_ast: 250e34750c759e2b403e2e82789dacab853b93fc2f4470f3ff3f3b1fb389e1a4 + flattened_ast: e0c564a41adae220a2f5ce02494608a8bba441489da1916a315f3d22b4002db1 + destructured_ast: c01f8593421d8017a233fb035800f08548c28ccf36f90c9b7b544d0404d6b442 + inlined_ast: 500774c030257c087cdf0a73757e87e738cb62623a7147d9b9449c8f742c36b7 + dce_ast: 2dc009cf8733679b787f89a794520ac4ebae5f27c7833103e0f9c536c05ef34e + bytecode: 7a2fd5581e13d3b66f1fad269ba868cf6d272929b84cea2dc1cb6a0af22867c2 + errors: "" + warnings: "" + - initial_symbol_table: 8ad69be0fd89bb76b691de96b7487cf22a375c4260cc31d8a40c9f304ce86729 + type_checked_symbol_table: efe6c4280d124277c6715e6adc84ffe43ede395fb860dca38f7ed2f9cbd20c11 + unrolled_symbol_table: efe6c4280d124277c6715e6adc84ffe43ede395fb860dca38f7ed2f9cbd20c11 + initial_ast: 79784e9bead4fdd8dc8d7adebd70bc9f8801a2194ad36739873582c2a9cc196b + unrolled_ast: b907ea2c254bb2666c0477f55be028715062ca8ecca51367e4855b3c47c589fb + ssa_ast: cb480d9cb77149d16a57a355122a42fc97bf83989f0b32858ee9a5222b5ccc23 + flattened_ast: 3a17c65ffd73f4ac47247498dd39e8b578251b541436395604663d5192730741 + destructured_ast: a4db377f1867ccafda01ddfedd854a7b698c40d52f09e1299a3abe0e71437e5c + inlined_ast: ef9b47b8c55c86273360209ec9650a41426b3c9bc625e79e7f68892be58baebb + dce_ast: be196ed1333097cdfd6eacfe0f645308b28ba31c08ba730c7483318e4060a7be + bytecode: 388c60022d4ad4fac382a685cc997c84d142f4e1357eb7c00e3efb545f5f70e5 + errors: "" + warnings: "" diff --git a/tests/expectations/compiler/futures/simple.out b/tests/expectations/compiler/futures/simple.out new file mode 100644 index 0000000000..c5a74054bc --- /dev/null +++ b/tests/expectations/compiler/futures/simple.out @@ -0,0 +1,31 @@ +--- +namespace: Compile +expectation: Pass +outputs: + - - compile: + - initial_symbol_table: 47a51901c66d5f1114b2a8b9e310d9e94496bd96b6d0ace33c113dfa0ca98e74 + type_checked_symbol_table: 296592ba1e77d8b2a425173f16667acc101401c4f2d5e2bef89bb9bd1600ed79 + unrolled_symbol_table: 296592ba1e77d8b2a425173f16667acc101401c4f2d5e2bef89bb9bd1600ed79 + initial_ast: e1b2a0140500be55ae83251c9b425dd92419952de27be605b3369145ef5f74da + unrolled_ast: e1b2a0140500be55ae83251c9b425dd92419952de27be605b3369145ef5f74da + ssa_ast: 472918a255a170f0ca8fd8995f0455337e3ecc3584cb791ff1a4a90b39043a62 + flattened_ast: d878cae6b698cf3a17b3452865f7bf9b4226da1f8c576259686d6b9734bac61f + destructured_ast: 70463f7122bd326523125de9fe7080780416b2047075637825909711a18a0ca3 + inlined_ast: b51bf5dc9f96f68c665ef4312c1fe772b89cc007eb7f5394ba81ac32ed0a325b + dce_ast: b51bf5dc9f96f68c665ef4312c1fe772b89cc007eb7f5394ba81ac32ed0a325b + bytecode: 7e95d1c0ff9c0edfb2081fe98cc11fb567b41a1c5c586688a2586aed8629b3be + errors: "" + warnings: "" + - initial_symbol_table: 6d89772d0f9458fbfd1cfd35c65c8b3cc741e7daa78694c21eeb6f7e61b16d0b + type_checked_symbol_table: a8e3ac4ebf716186f9703d4602ee4cbfaec34667e0e7d63f5922778082790288 + unrolled_symbol_table: a8e3ac4ebf716186f9703d4602ee4cbfaec34667e0e7d63f5922778082790288 + initial_ast: 659a8a8861752028a0ffed9c7124583d6a9f179756502dfcdb1e79beb946b3a6 + unrolled_ast: df30b083de57cc108a6ebfbd2fc9f5a702d79630ffe85774c02b354f55fc6b59 + ssa_ast: c81f1f0d01164205cca84bab44810993dc2be7f9c60916a1f4e5f46c304a35fe + flattened_ast: 46a48c999be2a01042e2a79e24ae916ba541c4079fd5cdd01747c37764d3bdb1 + destructured_ast: 55242cf20e7ad4b04a6063c8267ee4d700551ff6a34a05f0d0494712094358db + inlined_ast: 491228a25b5c7f2d4699431ba67624d3a5c95315e1cfd59b8adf44bebdffe9b3 + dce_ast: 9a3e86584fe577c5ff45d22070067a86f10a862ce1ba3bb5c53033aaaefebba7 + bytecode: 7a91652b8a95d6a25f0ad68011d37481570f9c7b5e79d05c0ae8476c6754f7a8 + errors: "" + warnings: "" diff --git a/tests/tests/compiler/futures/future_not_all_awaited_fail.leo b/tests/tests/compiler/futures/future_not_all_awaited_fail.leo new file mode 100644 index 0000000000..4361e02e82 --- /dev/null +++ b/tests/tests/compiler/futures/future_not_all_awaited_fail.leo @@ -0,0 +1,46 @@ +/* +namespace: Compile +expectation: Fail +*/ + +program child.aleo { + mapping count: address => field; + + async transition foo() -> Future { + return finalize_foo(self.caller); + } + + async function finalize_foo(addr: address) { + let val: field = Mapping::get_or_use(count, addr, 0field); + Mapping::set(count, addr, val + 1field); + } + + async transition boo() -> Future { + return finalize_boo(self.caller); + } + + async function finalize_boo(addr: address) { + let val: field = Mapping::get_or_use(count, addr, 0field); + Mapping::set(count, addr, val + 1field); + } + } + + // --- Next Program --- // + +import child.aleo; + +program parent.aleo { + + async transition foo() -> Future { + return finalize_foo(child.aleo/foo(), child.aleo/foo(), child.aleo/foo(), child.aleo/boo(), child.aleo/boo(), child.aleo/boo()); + } + + // Doesn't await f4. + async function finalize_foo(f0: Future, f1: Future, f2: Future, f3: Future, f4: Future, f5: Future) { + f1.await(); + f2.await(); + f3.await(); + f0.await(); + f5.await(); + } +} \ No newline at end of file diff --git a/tests/tests/compiler/futures/future_not_all_passed_to_async_call_fail.leo b/tests/tests/compiler/futures/future_not_all_passed_to_async_call_fail.leo new file mode 100644 index 0000000000..a4aefffd24 --- /dev/null +++ b/tests/tests/compiler/futures/future_not_all_passed_to_async_call_fail.leo @@ -0,0 +1,53 @@ +/* +namespace: Compile +expectation: Fail +*/ + +program child.aleo { + mapping count: address => field; + + async transition foo() -> Future { + return finalize_foo(self.caller); + } + + async function finalize_foo(addr: address) { + let val: field = Mapping::get_or_use(count, addr, 0field); + Mapping::set(count, addr, val + 1field); + } + + async transition boo() -> Future { + return finalize_boo(self.caller); + } + + async function finalize_boo(addr: address) { + let val: field = Mapping::get_or_use(count, addr, 0field); + Mapping::set(count, addr, val + 1field); + } + } + +// --- Next Program --- // + +import child.aleo; + +program parent.aleo { + + async transition foo() -> Future { + let f0: Future = child.aleo/foo(); + let f1: Future = child.aleo/foo(); + let f2: Future = child.aleo/foo(); + let f3: Future = child.aleo/boo(); + let f4: Future = child.aleo/boo(); + let f5: Future = child.aleo/boo(); + + // Doesn't pass f1. + return finalize_foo(f0, f3, f2, f5, f4); + } + + async function finalize_foo(f0: Future, f1: Future, f2: Future, f3: Future, f4: Future) { + f1.await(); + f4.await(); + f2.await(); + f3.await(); + f0.await(); + } +} \ No newline at end of file diff --git a/tests/tests/compiler/futures/nested.leo b/tests/tests/compiler/futures/nested.leo new file mode 100644 index 0000000000..6466ef8dc9 --- /dev/null +++ b/tests/tests/compiler/futures/nested.leo @@ -0,0 +1,93 @@ +/* +namespace: Compile +expectation: Pass +*/ + +// The 'test_dep' program. +program test_dep.aleo { + mapping Yo: u32 => u32; + record yeets { + owner: address, + val: u32, + } + + async transition main_dep(a:u32) -> (yeets, Future) { + let f: Future = finalize_main_dep(a, 1u32); + let l: yeets = yeets {owner: self.caller, val: 1u32}; + return (l, f); + } + + async function finalize_main_dep(a:u32, b:u32) { + Mapping::set(Yo, a, b); + let c:u32 = a + b; + } +} + +// --- Next Program --- // + +// The 'test' program. +import test_dep.aleo; +program test.aleo { + mapping ayo: u32 => u32; + + async transition main(a:u32)-> (u32, Future) { + let (y,f): (test_dep.aleo/yeets, Future) = test_dep.aleo/main_dep(10u32); + let (y2,f2): (test_dep.aleo/yeets, Future) = test_dep.aleo/main_dep(1u32); + let val:u32 = f.0; + let f3: Future = finalize_main(f, f2, 1u32); + let total: u32 = f.0 + f2.0; + return (total + val + f.0*2u32, f3); + } + + async function finalize_main(f: Future, f2: Future, a: u32) { + // f.await(); + if a == 1u32 { + Future::await(f); + f2.await(); + } + + if a == 2u32 { + //f2.await(); + Mapping::set(ayo, 1u32, 1u32); + } + + let total: u32 = f.0 + f2.0; + Mapping::set(ayo, 1u32, total); + } +} + +// --- Next Program --- // + +// The 'wrapper' program. +import test.aleo; +program wrapper.aleo { + async transition main(public a: u32, b: u32) -> (u32, Future){ + let (val, f): (u32, Future) = test.aleo/main(1u32); + let (val2, f2): (u32, Future) = test.aleo/main(1u32); + let (val3, f3): (u32, Future) = test.aleo/main(1u32); + let f4: Future = finalize_main(f,f2,f3); + return (val, f4); + } + + async function finalize_main(f: Future, f2: Future, f3: Future) { + f.await(); + f2.await(); + f3.await(); + } +} + +// --- Next Program --- // + +import wrapper.aleo; +import test_dep.aleo; +program big_wrapper.aleo { + async transition main(public a: u32, b: u32) -> (u32, Future){ + let (val, f): (u32, Future) = wrapper.aleo/main(10u32, 10u32); + let f2:Future = finalize_main(f); + return (f2.0.0.0.0, f2); + } + + async function finalize_main(f: Future) { + f.await(); + } +} \ No newline at end of file diff --git a/tests/tests/compiler/futures/simple.leo b/tests/tests/compiler/futures/simple.leo new file mode 100644 index 0000000000..b6632fd927 --- /dev/null +++ b/tests/tests/compiler/futures/simple.leo @@ -0,0 +1,33 @@ +/* +namespace: Compile +expectation: Pass +*/ +program test.aleo { + mapping foo: u32 => u32; + async transition main_inner(public a: u32, b: u32) -> (u32, Future) { + let c: u32 = a + b; + let f: Future = finalize(); + return (c, f); + } + + async function finalize() { + Mapping::set(foo, 1u32, 1u32); + } +} + +// --- Next Program --- // + +import test.aleo; +program basic.aleo { + async transition main(public a: u32, b: u32) -> (u32, Future) { + let c: u32 = a + b; + let (d, f1): (u32, Future) = test.aleo/main_inner(1u32, 1u32); + let f:Future = finalize(c, f1); + return (c,f); + } + + async function finalize(input: u32, f: Future) { + f.await(); + assert_eq(input, 1u32); + } +} \ No newline at end of file