Skip to content

Commit

Permalink
feat: allow controllers to call __motoko_stable_var_info query endp…
Browse files Browse the repository at this point in the history
…oint (#4103)

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.)
  • Loading branch information
ggreif authored Jul 6, 2023
1 parent 5334f9b commit 1a7fdce
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 9 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -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`)
Expand Down
7 changes: 4 additions & 3 deletions src/ir_def/construct.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions src/lowering/desugar.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions test/run-drun/ok/query-footprint.drun-run.ok
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions test/run-drun/ok/query-footprint.ic-ref-run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 1a7fdce

Please sign in to comment.