cdk-rs icon indicating copy to clipboard operation
cdk-rs copied to clipboard

feat: export candid

Open chenyan-dfinity opened this issue 3 years ago • 14 comments

The main implementation is in https://github.com/dfinity/candid/pull/119. cdk-rs is a simple wrapper around the candid derive. We have two ways to get the did file:

  • Install the canister then call __get_candid_interface_tmp_hack
  • Compile the canister code in WASI mode, and run wasmtime to output the did file

chenyan-dfinity avatar Oct 09 '20 21:10 chenyan-dfinity

Netlify deployed rust-cdk as draft

Link: https://5f80d746b8a91f13322a57df--cdk-rust.netlify.app

github-actions[bot] avatar Oct 09 '20 21:10 github-actions[bot]

Netlify deployed rust-cdk as draft

Link: https://5f814c1bf2fb3ef98bd42fc6--cdk-rust.netlify.app

github-actions[bot] avatar Oct 10 '20 05:10 github-actions[bot]

Netlify deployed rust-cdk as draft

Link: https://5f82223017be70745d406386--cdk-rust.netlify.app

github-actions[bot] avatar Oct 10 '20 21:10 github-actions[bot]

Netlify deployed rust-cdk as draft

Link: https://5f874c81ee6a7953cc35d301--cdk-rust.netlify.app

github-actions[bot] avatar Oct 14 '20 19:10 github-actions[bot]

Netlify deployed rust-cdk as draft

Link: https://5f878b1fd6ee6200ca76c9a1--cdk-rust.netlify.app

github-actions[bot] avatar Oct 14 '20 23:10 github-actions[bot]

Is it possible to make this work gradually? Each procedural macros like: init, query or update could write to some file when they are invoked.

I mean... for example:

  • the program meets #[init] proc macro
  • since this macros has access to function's signature, it should be able to generate a portion of candid like
type A = ...;

service : (A) -> {
}
  • then the program meets some #[update] proc macro and updates this file once again
type A = ...;
type B = ...;
type C = ...;

service : (A) -> {
  "some_update_function" : (B) -> (C);
}
  • program continues till the end populating this file in one compilation

What do you think?

UPD: nevermind, I figured out rust macroses would not allow this. UPD2: hmmm, but maybe... since you also have all the info about all possible CandidTypes it should be possible

seniorjoinu avatar Jul 16 '21 21:07 seniorjoinu

The candid type is generated at runtime via T::ty(), so at the proc macro phase, the compiler doesn't know anything about candid type. That's why we need to compile to a WASI target to generate the did file.

chenyan-dfinity avatar Jul 16 '21 22:07 chenyan-dfinity

Hello @chenyan-dfinity, do you have updates on this feature?

neokree avatar Dec 13 '22 21:12 neokree

Yes any update on being able to generate the did file without having to compile once and execute code at runtime? Shouldn't static analysis of the Rust code be enough to generate a did file without any compilation?

This is a considerable headache for Azle and Kybra the TypeScript and Python CDKs

lastmjs avatar Mar 08 '23 21:03 lastmjs

any update on being able to generate the did file without having to compile once and execute code at runtime?

No plans for this. Would it help if dfx build bundles the two compilation in one command?

Shouldn't static analysis of the Rust code be enough to generate a did file without any compilation?

Theoretically yes. But you have to patch a static analyzer like rust-analyzer to achieve this. And you don't really gain anything. You still need to compile the code twice, one for generating the did file, one for the real wasm module.

chenyan-dfinity avatar Mar 08 '23 22:03 chenyan-dfinity

Theoretically yes. But you have to patch a static analyzer like rust-analyzer to achieve this. And you don't really gain anything. You still need to compile the code twice, one for generating the did file, one for the real wasm module.

Can't you just use a Rust parser and use that to compile down to Candid? Or am I missing something?

lastmjs avatar Mar 09 '23 00:03 lastmjs

My real goal is for dfx to completely abstract away the need for a Candid file when writing a Rust or custom canister.

Actually today I figured out a way to do this for Azle that is pretty nice, but it would be great to avoid doing it. We take the Wasm module and stub out all of the ic0 imports, and then call a couple functions to return a pointer and the length of the pointer to the string stored on the heap after calling __export_service. This has made the flow a lot simpler, but still unfortunate to have to do this.

Basically compile to Wasm -> Run module with ic0 stubs in Node.js Wasm engine -> save the Candid to a .did file.

Ideally dfx build would do everything for us, generating the candid, storing it in the metadata section, and only optionally writing it to disk. IMO we shouldn't have to specify a Candid file in the dfx.json, it should be entirely optional.

This would provide an excellent developer experience like Motoko, especially for those just getting started.

lastmjs avatar Mar 09 '23 00:03 lastmjs

Can't you just use a Rust parser and use that to compile down to Candid?

No. You need at least the def-use info, which requires non-trivial understanding of the Rust module system. See this discussion: https://github.com/dfinity/cdk-rs/pull/35#discussion_r516420072

Ideally dfx build would do everything for us, generating the candid, storing it in the metadata section, and only optionally writing it to disk. IMO we shouldn't have to specify a Candid file in the dfx.json, it should be entirely optional.

Okay, our goal is the same. You are not really oppose to getting the metadata by running an executable, which will be done in dfx build automatically.

chenyan-dfinity avatar Mar 09 '23 00:03 chenyan-dfinity

Okay, our goal is the same. You are not really oppose to getting the metadata by running an executable, which will be done in dfx build automatically.

Fantastic! We just have to do it ourselves for now using Node.js V8 Wasm engine for Azle and wasmer or wasmtime in Kybra, it will be awesome once we can remove that code once dfx build can do this automatically!

I imagine it will be relatively simple for dfx build to do this automatically, it's been pretty easy to just run the bare module through a wasm runtime with stubbed imports.

lastmjs avatar Mar 09 '23 17:03 lastmjs