From 1a7fdce4ad1858d6660fd43ff916a3c5f7c51865 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Thu, 6 Jul 2023 13:55:36 +0200 Subject: [PATCH] feat: allow controllers to call `__motoko_stable_var_info` query endpoint (#4103) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was originally spec-ed, but there was no possibility to implement it (a canister couldn't get its own controller list). In the meantime canisters can get their controller list (via query), but a query cannot call another query 🫤. So we had to wait until the `ic0.is_controller` syscall became available. Now it is there and the implementation is easy. (It was technically possible to call it before, but it invariably trapped.) --- Changelog.md | 3 +++ src/ir_def/construct.ml | 7 ++++--- src/lowering/desugar.ml | 5 +++-- test/run-drun/ok/query-footprint.drun-run.ok | 4 ++-- test/run-drun/ok/query-footprint.ic-ref-run.ok | 4 ++-- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Changelog.md b/Changelog.md index 400f3ee2fa8..91cd41ffd0a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,8 @@ # Motoko compiler changelog + * Allow canister controllers to call the `__motoko_stable_var_info` query endpoint (#4103). + (Previously only self-queries were permitted.) + ## 0.9.5 (2023-07-05) * motoko (`moc`) diff --git a/src/ir_def/construct.ml b/src/ir_def/construct.ml index d7ae54f5638..597fa7a81f3 100644 --- a/src/ir_def/construct.ml +++ b/src/ir_def/construct.ml @@ -95,8 +95,8 @@ let primE prim es = | ICStableSize _ -> T.nat64 | IdxPrim | DerefArrayOffset -> T.(as_immut (as_array_sub (List.hd es).note.Note.typ)) - | NextArrayOffset _ -> T.nat | ValidArrayOffset -> T.bool + | NextArrayOffset _ | GetPastArrayOffset _ -> T.nat | IcUrlOfBlob -> T.text | ActorOfIdBlob t -> t @@ -111,9 +111,10 @@ let primE prim es = | OtherPrim "trap" -> T.Non | OtherPrim "call_perform_status" -> T.(Prim Nat32) | OtherPrim "call_perform_message" -> T.text - | OtherPrim "array_len" -> T.nat - | OtherPrim "blob_size" -> T.nat + | OtherPrim "array_len" + | OtherPrim "blob_size" | OtherPrim "text_len" -> T.nat + | OtherPrim "is_controller" -> T.bool | _ -> assert false (* implement more as needed *) in let effs = List.map eff es in diff --git a/src/lowering/desugar.ml b/src/lowering/desugar.ml index 17b12cf6351..fdbc5b44c4b 100644 --- a/src/lowering/desugar.ml +++ b/src/lowering/desugar.ml @@ -438,8 +438,9 @@ and export_footprint self_id expr = ([ letD (var v typ) ( funcE v (Shared Query) Promises [bind1] [] [ret_typ] ( (asyncE T.Fut bind2 - (blockE [expD (assertE (primE (I.RelPrim (caller, Operator.EqOp)) - [primE I.ICCallerPrim []; selfRefE caller])); + (blockE [expD (assertE (orE (primE (I.RelPrim (caller, Operator.EqOp)) + [primE I.ICCallerPrim []; selfRefE caller]) + (primE (I.OtherPrim "is_controller") [primE I.ICCallerPrim []]))); letD size (primE (I.ICStableSize expr.note.Note.typ) [expr]) ] (newObjE T.Object diff --git a/test/run-drun/ok/query-footprint.drun-run.ok b/test/run-drun/ok/query-footprint.drun-run.ok index 016f7247968..67a8afe9e37 100644 --- a/test/run-drun/ok/query-footprint.drun-run.ok +++ b/test/run-drun/ok/query-footprint.drun-run.ok @@ -1,7 +1,7 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 ingress Completed: Reply: 0x4449444c0000 -ingress Err: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: assertion failed at .:0.1 -Err: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: assertion failed at .:0.1 +ingress Completed: Reply: 0x4449444c016c01c1c1cee2047801005118000000000000 +Ok: Reply: 0x4449444c016c01c1c1cee2047801005118000000000000 ingress Completed: Reply: 0x4449444c0001785118000000000000 ingress Completed: Reply: 0x4449444c0001785118000000000000 Ok: Reply: 0x4449444c0001712973657276696365203a207b0a202064656c65676174653a202829202d3e20286e61743634293b0a7d0a diff --git a/test/run-drun/ok/query-footprint.ic-ref-run.ok b/test/run-drun/ok/query-footprint.ic-ref-run.ok index 2b939ba7635..468b5363bd0 100644 --- a/test/run-drun/ok/query-footprint.ic-ref-run.ok +++ b/test/run-drun/ok/query-footprint.ic-ref-run.ok @@ -3,9 +3,9 @@ => update install_code(record {arg = blob ""; kca_xin = blob "\00asm\01\00\00\00\0... <= replied: () => update __motoko_stable_var_info() -<= rejected (RC_CANISTER_ERROR): canister trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: assertion failed at .:0.1" +<= replied: (record {size = (6225 : nat64)}) => query __motoko_stable_var_info() -<= rejected (RC_CANISTER_ERROR): canister trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: assertion failed at .:0.1" +<= replied: (record {size = (6225 : nat64)}) => update delegate() <= replied: ((6225 : nat64)) => update delegate()