Ic-cdk wasi feature

How does the new Wasi feature work for ic-cdk? I don’t really see any documentation. I’m trying to get Azle updated to wasi, which is a prerequisite to swapping out the current engine for QuickJS. I’d also like to take advantage of the new Candid generation capabilities.

So far I’m getting a bunch of weird errors with ic-cdk 0.10.0 when I turn on the wasi feature. Do I need to use the ic-wasi-polyfill? Do I need to use wasi2ic?

Errors:

error: duplicate init method
     --> src/src/lib.rs:13438:4
      |
13438 | fn init() {
      |    ^^^^

error: duplicate method name getRandomnessDirectly
     --> src/src/lib.rs:13515:10
      |
13515 | async fn _cdk_user_defined_getRandomnessDirectly() -> (ic_cdk::api::call::ManualReply<
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: duplicate method name getRandomnessIndirectly
     --> src/src/lib.rs:13567:10
      |
13567 | async fn _cdk_user_defined_getRandomnessIndirectly() -> (ic_cdk::api::call::ManualReply<
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: duplicate method name getRandomnessSuperIndirectly
     --> src/src/lib.rs:13619:10
      |
13619 | async fn _cdk_user_defined_getRandomnessSuperIndirectly() -> (ic_cdk::api::call::ManualReply<
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: duplicate method name returnPromiseVoid
     --> src/src/lib.rs:13671:10
      |
13671 | async fn _cdk_user_defined_returnPromiseVoid() -> (ic_cdk::api::call::ManualReply<()>) {
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0425]: cannot find function `init` in this scope
     --> src/src/lib.rs:13438:4
      |
13438 | fn init() {
      |    ^^^^ not found in this scope

error[E0425]: cannot find function `_cdk_user_defined_getRandomnessDirectly` in this scope
     --> src/src/lib.rs:13515:10
      |
13513 | #[ic_cdk_macros::update(name = "getRandomnessDirectly", manual_reply = true)]
      | ----------------------------------------------------------------------------- similarly named function `_cdk_user_defined_getRandomnessDirectly_3_` defined here
13514 | #[candid::candid_method(update, rename = "getRandomnessDirectly")]
13515 | async fn _cdk_user_defined_getRandomnessDirectly() -> (ic_cdk::api::call::ManualReply<
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `_cdk_user_defined_getRandomnessDirectly_3_`

error[E0425]: cannot find function `_cdk_user_defined_getRandomnessIndirectly` in this scope
     --> src/src/lib.rs:13567:10
      |
13565 | #[ic_cdk_macros::update(name = "getRandomnessIndirectly", manual_reply = true)]
      | ------------------------------------------------------------------------------- similarly named function `_cdk_user_defined_getRandomnessIndirectly_4_` defined here
13566 | #[candid::candid_method(update, rename = "getRandomnessIndirectly")]
13567 | async fn _cdk_user_defined_getRandomnessIndirectly() -> (ic_cdk::api::call::ManualReply<
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `_cdk_user_defined_getRandomnessIndirectly_4_`

error[E0425]: cannot find function `_cdk_user_defined_getRandomnessSuperIndirectly` in this scope
     --> src/src/lib.rs:13619:10
      |
13617 | #[ic_cdk_macros::update(name = "getRandomnessSuperIndirectly", manual_reply = true)]
      | ------------------------------------------------------------------------------------ similarly named function `_cdk_user_defined_getRandomnessSuperIndirectly_5_` defined here
13618 | #[candid::candid_method(update, rename = "getRandomnessSuperIndirectly")]
13619 | async fn _cdk_user_defined_getRandomnessSuperIndirectly() -> (ic_cdk::api::call::ManualReply<
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `_cdk_user_defined_getRandomnessSuperIndirectly_5_`

error[E0425]: cannot find function `_cdk_user_defined_returnPromiseVoid` in this scope
     --> src/src/lib.rs:13671:10
      |
13669 | #[ic_cdk_macros::update(name = "returnPromiseVoid", manual_reply = true)]
      | ------------------------------------------------------------------------- similarly named function `_cdk_user_defined_returnPromiseVoid_6_` defined here
13670 | #[candid::candid_method(update, rename = "returnPromiseVoid")]
13671 | async fn _cdk_user_defined_returnPromiseVoid() -> (ic_cdk::api::call::ManualReply<()>) {
      |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `_cdk_user_defined_returnPromiseVoid_6_`

So I’ve overcome the above errors, I had to remove all instances of candid::candid_method that I was using to help with Candid generation.

Everything compiles now but on deploy I get the following:

Error: Failed while trying to deploy canisters.
Caused by: Failed while trying to deploy canisters.
  Failed while trying to install all canisters.
    Failed to install wasm module to canister 'async_await'.
      Failed during wasm installation call: The replica returned a replica error: Replica Error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped: unreachable, error code None

The wasi feature simply allow to generate a wasi binary that outputs the did file. To use this feature, the Rust shouldn’t have the candid_method attributes, you only need to add export_service! at the end.

1 Like

Right, that wasi binary cannot be deployed to the IC. It only generates the did file when you run it through wasmtime. To get the real wasm binary, you need to compile the binary without the wasi feature.

1 Like

Oh I see, thank you.

So I have to compile the binary twice then? Have we reached the point where dfx will do all of this automatically yet?

Right. We are still working on the dfx integration, so that dfx will compile the binary twice for Rust canisters. For custom canisters, you need to include this script into your build process: https://github.com/dfinity/cdk-rs/blob/main/examples/build.sh

2 Likes