-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add prim call_raw : (Principal, Text, Blob) -> async Blob (#3086)
Fixes #2703 (by lowering ourselves to the level of Rust). Adds a prim to dynamically invoke a method by name with an already serialized blob and get the raw (undeserialized) blob back asynchronously: ``` Motoko call_raw : (canister : Principal, function_name : Text, arg : Blob) -> async Blob ```` The function can only be called in an asynchronous context and this is enforced by the type system. There is no assumption that the contents of either blob is Candid, so this could also be used to talk to non-Candid endpoints. This should be sufficient to implement the call-forwarding functionality of the Rust cycles wallet. - [x] Determine whether the method name must be (rope)-normalized before use. Currently it is not. @nomeata, what's the representation invariant for ordinary shared functions - I see they are (Principal,Text) pairs, but is the Text normalized? - [ ] Any ideas for better name: `request`, `send`, `call`, `invoke`, `call_dynamic` spring to mind
- Loading branch information
Showing
13 changed files
with
242 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import P "mo:⛔"; | ||
|
||
actor self { | ||
|
||
public shared func sint() : async Int { | ||
return 2; | ||
}; | ||
|
||
public shared func snat() : async Nat { | ||
return 2; | ||
}; | ||
|
||
public shared func stext() : async Text { | ||
return "hello"; | ||
}; | ||
|
||
public shared func stuple() : async (Nat, Bool, Char) { | ||
return (1, true, 'a'); | ||
}; | ||
|
||
public shared func unit() : async () { | ||
P.debugPrint("unit!"); | ||
}; | ||
|
||
public shared func int(n : Int) : async Int { | ||
P.debugPrint(debug_show("int",n)); | ||
return n; | ||
}; | ||
|
||
public shared func text(t : Text) : async Text { | ||
P.debugPrint(debug_show("text", t)); | ||
return t; | ||
}; | ||
|
||
public shared func tuple(n: Nat, b: Bool, c: Char) : async (Nat, Bool, Char) { | ||
P.debugPrint(debug_show("text", (n, b, c))); | ||
return (n, b, c); | ||
}; | ||
|
||
public shared func trapInt(n : Int) : async Int { | ||
P.trap("ohoh"); | ||
}; | ||
|
||
public shared func supercalifragilisticexpialidocious() : async () { | ||
P.debugPrint("supercalifragilisticexpialidocious"); | ||
}; | ||
|
||
public shared func go() : async () { | ||
let p = P.principalOfActor(self); | ||
|
||
do { | ||
let arg : Blob = "DIDL\00\00"; | ||
let res = await P.call_raw(p,"unit", arg); | ||
assert (res == arg); | ||
}; | ||
|
||
do { | ||
let arg : Blob = "DIDL\00\01\7c\01"; | ||
let res = await P.call_raw(p,"int", arg); | ||
assert (res == arg); | ||
}; | ||
|
||
do { | ||
let arg : Blob = "DIDL\00\01\7c\02"; | ||
let res = await P.call_raw(p,"int", arg); | ||
assert (res == arg); | ||
}; | ||
|
||
do { | ||
let arg : Blob = "DIDL\00\01\71\05\68\65\6c\6c\6f"; | ||
let res = await P.call_raw(p,"text", arg); | ||
assert (res == arg); | ||
}; | ||
|
||
do { | ||
let arg : Blob = "DIDL\00\03\7d\7e\79\01\01\61\00\00\00"; | ||
let res = await P.call_raw(p,"tuple", arg); | ||
assert (res == arg); | ||
}; | ||
|
||
do { | ||
let arg : Blob = "DIDL\00\01\7c\01"; | ||
try { | ||
let res = await P.call_raw(p,"trapInt", arg); | ||
assert false; | ||
} | ||
catch e { | ||
P.debugPrint(P.errorMessage(e)); | ||
} | ||
}; | ||
|
||
do { | ||
let m = "super"#"cali"#"fragilisticexpialidocious"; | ||
let arg : Blob = "DIDL\00\00"; | ||
let res = await P.call_raw(p, m, arg); | ||
assert (res == arg); | ||
}; | ||
|
||
} | ||
}; | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
//CALL ingress sint 0x4449444C0000 | ||
//CALL ingress snat 0x4449444C0000 | ||
//CALL ingress stext 0x4449444C0000 | ||
//CALL ingress stuple 0x4449444C0000 | ||
//CALL ingress go 0x4449444C0000 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 | ||
ingress Completed: Reply: 0x4449444c0000 | ||
ingress Completed: Reply: 0x4449444c00017c02 | ||
ingress Completed: Reply: 0x4449444c00017d02 | ||
ingress Completed: Reply: 0x4449444c0001710568656c6c6f | ||
ingress Completed: Reply: 0x4449444c00037d7e79010161000000 | ||
debug.print: unit! | ||
debug.print: ("int", +1) | ||
debug.print: ("int", +2) | ||
debug.print: ("text", "hello") | ||
debug.print: ("text", (1, true, 'a')) | ||
debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: ohoh | ||
debug.print: supercalifragilisticexpialidocious | ||
ingress Completed: Reply: 0x4449444c0000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
→ update create_canister(record {settings = null}) | ||
← replied: (record {hymijyo = principal "cvccv-qqaaq-aaaaa-aaaaa-c"}) | ||
→ update install_code(record {arg = blob ""; kca_xin = blob "\00asm\01\00\00\00\0… | ||
← replied: () | ||
→ update sint() | ||
← replied: (+2) | ||
→ update snat() | ||
← replied: (2) | ||
→ update stext() | ||
← replied: ("hello") | ||
→ update stuple() | ||
← replied: (1, true, (97 : nat32)) | ||
→ update go() | ||
debug.print: unit! | ||
debug.print: ("int", +1) | ||
debug.print: ("int", +2) | ||
debug.print: ("text", "hello") | ||
debug.print: ("text", (1, true, 'a')) | ||
debug.print: canister trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: ohoh" | ||
debug.print: supercalifragilisticexpialidocious | ||
← replied: () |