Ledger Wasm Too Big

This version of the ledger seems too big. It will only work if you install it on a system subnet as described earlier in this thread.

Itā€™s not intended to be in the dependencies. dfx automatically calls ic-cdk-optimizer to reduce wasm size AFTER compilation if itā€™s installed.

Thank you both for assisting me. I got it downloaded, and its unzipped and seems to run at least a bit before an internal error stops the canister build. At least I have overcome my initial error with a too large wasm, and learned some things, now I get a different error ā†’ progress I guess. FYI I put the error here as its internal in .rs and you might know where this is happening ā†’

Installing code for canister fileupload, with canister ID rrkah-fqaaa-aaaaa-aaaaq-cai
Installing code for canister ledger, with canister ID ryjl3-tyaaa-aaaaa-aaaba-cai
[Canister ryjl3-tyaaa-aaaaa-aaaba-cai] Panicked at 'Deserialization Failed: "Cannot parse header "', /ic/rs/rust_canisters/dfn_core/src/endpoint.rs:50:41
Error: Failed to install wasm module to canister 'ledger'.
Caused by: Failed to install wasm module to canister 'ledger'.
  Failed to install wasm in canister 'ryjl3-tyaaa-aaaaa-aaaba-cai'.
    Failed to install wasm.
      The Replica returned an error: code 5, message: "Canister ryjl3-tyaaa-aaaaa-aaaba-cai trapped explicitly: Panicked at 'Deserialization Failed: "Cannot parse header "', /ic/rs/rust_canisters/dfn_core/src/endpoint.rs:50:41"

This happens regardless of the new dfx.json remote settings being present in the .json as follows - >

      "remote": {
        "candid": "src/ledger/ledger.public.did",
        "id": {
          "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
        }
      }

I will keep hacking at it and see how far I can get with this new error.

thanks for clarifying, I was silly, and thought that since its on crate.io, it should be added to dependancies.

I canā€™t seem to get dfx to do this for me automatically, Iā€™m using dfx 0.11.0. Is it supposed to just happen during the dfx deploy command?

We are bad at communicating, thatā€™s all. This entry in the release notes means that ic-cdk-optimizer is no longer needed. The same optimization is now done through ic-wasm. And ic-wasm is included in dfx now, so you donā€™t need an external installation of ic-cdk-optimizer anymore.

This only applies to canisters with "type": "rust", so custom canisters still would need manual calls to some optimizer.

Let me see if I can get that line in the changelog clarified. (And maybe even our communication improved?) EDIT: does this help? PR here and here

2 Likes

Thanks! So Iā€™m using type: custom canisters (building Azle, the TypeScript CDK). Iā€™d like to remove the need for the user to install ic-cdk-optimizer and have it run for them on dfx deploy. Even if I have to run it for them, Iā€™d love to use the new library that doesnā€™t require installing ic-cdk-optimizer. Iā€™ll look at those links and hopefully I can figure it out.

I doubt this is possible with dfx as-is. It doesnā€™t expose anything that will only optimize the wasm.

1 Like

Iā€™d love to be able to turn this feature on somehow for canisters of type custom, perhaps the dfx.json could have a configuration for this.

1 Like

Iā€™m AFK but Iā€™m curious if ic-wasm gets put in the cache directory by dfx (like moc, etc)

Either way, it looks simple enough to call manually:

@lastmjs not sure if this lends itself well to your use case though.

1 Like

@Severin, in Post-build step for asset canister fails because directory is considered to be outside the workspace root Ā· Issue #2199 Ā· dfinity/sdk Ā· GitHub you were open to examples for reworking the custom build command.

Iā€™m not sure if this topic qualifies but it at least seems related.

1 Like

No, we use ic-wasm as a crate in dfx because bundling an executable in the cache is more annoying. (Code here if youā€™re interested)

In case you want to look at the cache you can do so with ls "$(dfx cache show)"

I think having a way to run ic-wasm on the produced wasm is a very reasonable ask since this problem will not only happen with Rust but other languages as well. Added to our backlog.

2 Likes

I just started using ic-wasm and it cut the file size in half.

1 Like

How are you using ic-wasm? As in during the build process, how are you setting that up?

Iā€™m using nix flakes, so I have this entry in my flake.nix file which sets up the binary:

          packages.ic-wasm = naersk-lib.buildPackage rec {
            pname = "ic-wasm";
            root = pkgs.stdenv.mkDerivation {
              name = "ic-wasm-src";
              src = pkgs.fetchFromGitHub {
                owner = "dfinity";
                repo = "ic-wasm";
                rev = "2e876e84953e24e6a1820aa524f228c8edea4307";
                sha256 = "sha256-0E7Qa0tOtFwV6pkZsjvkGE2TGaj/30+JSlNGtiU0xYo=";
              };
              installPhase = ''
                cp -R --preserve=mode,timestamps . $out
              '';
            };
            cargoBuildOptions = x: x ++ [
              "--package" pname
            ];
            cargoTestOptions = x: x ++ [
              "--package" pname
            ];
          };

Then I call ic-wasm as a post-install step when building my backend canister:

          packages.backend = naersk-lib.buildPackage rec {
            pname = "my-project";
            root = ./backend;
            nativeBuildInputs = [] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
              pkgs.libiconv
            ];
            cargoBuildOptions = x: x ++ [
              "--package" pname
              "--target" "wasm32-unknown-unknown"
            ];
            cargoTestOptions = x: x ++ [
              "--package" pname
              "--target" "wasm32-unknown-unknown"
            ];
            compressTarget = false;
            copyBins = false;
            copyTarget = true;
            postInstall = ''
              MY_PROJECT_WASM=$out/target/wasm32-unknown-unknown/release/my_project.wasm
              ${packages.ic-wasm}/bin/ic-wasm -o $MY_PROJECT_WASM $MY_PROJECT_WASM shrink
            '';
          };
1 Like

Actually, I am curious why adding ciborium reduced the wasm size. serde_cbor is not removed from the lockfile in that PR. Does serde_cbor generate a mass of code using macros? At the moment it looks like a case of: ā€œI made it bigger so that it would become smallerā€, which usually only works when the original is about to implode anyway.

serde_cbor is not removed from the lockfile in that PR.

We had to continue using serde_cbor for transaction deduplication reasons. Luckily, there we needed only the encoding logic.

Does serde_cbor generate a mass of code using macros?

The bloat seems to come from serde_cborā€™s decoding logic (most likely, from generic function instantiations), which we replaced with ciborium in the referenced commit.

1 Like

As an update on the optimizers, ic-wasm now wraps wasm-opt similarly to how ic-cdk-optimizer use to work.

2 Likes