dfinity / vscode-motoko

Motoko language support for VS Code.
Apache License 2.0
42 stars 15 forks source link

Error while importing a canister #282

Open icpShiller opened 1 month ago

icpShiller commented 1 month ago

Issue:

Canister import is shown as an error whereas it shouldn't:

image

How to reproduce:

I'm trying to use the ICP ledger from my backend canister. For that I'm doing 2 things:

N.B: the VSCode extension error message says:

canister alias "icp_ledger_canister" not defined. This is usually fixed by running dfx deploy or adding dependencies in your dfx.json fileMotoko(M0011)

..however dfx deploy runs successfully while the file still complains about an error on the import.

Related forum issue: https://forum.dfinity.org/t/canister-dependency-not-working/31377

rvanasa commented 1 month ago

Hi, thanks for reaching out! I am trying to reproduce the issue, but everything seems to work as expected on my end. Would you be able to send the relevant part of your dfx.json file, ledger canister init args, and anything else I could use to recreate the error?

icpShiller commented 1 month ago

@rvanasa Here's my dfx.json file:

{
  "canisters": {
    "internet_identity": {
      "candid": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity.did",
      "frontend": {},
      "remote": {
        "id": {
          "ic": "rdmx6-jaaaa-aaaaa-aaadq-cai"
        }
      },
      "type": "custom",
      "wasm": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity_dev.wasm.gz"
    },
    "icp_ledger_canister": {
      "type": "custom",
      "candid": "https://raw.githubusercontent.com/dfinity/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/rs/rosetta-api/icp_ledger/ledger.did",
      "wasm": "https://download.dfinity.systems/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/canisters/ledger-canister.wasm.gz",
      "remote": {
        "id": {
          "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
        }
      }
    },
    "myapp_backend": {
      "main": "src/myapp_backend/main.mo",
      "type": "motoko",
      "dependencies": [
          "icp_ledger_canister"
      ]
    },
    "myapp_frontend": {
      "dependencies": [
        "myapp_backend"
      ],
      "source": [
        "src/myapp_frontend/dist"
      ],
      "type": "assets",
      "workspace": "myapp_frontend"
    }
  },
  "defaults": {
    "build": {
      "args": "",
      "packtool": ""
    }
  },
  "output_env_file": ".env",
  "version": 1
}
rvanasa commented 1 month ago

Which OS are you using? I tested on both macOS M1 and Ubuntu, and everything seems to work for me. Are you also using the latest version of dfx (0.20.1)?

It might be possible to temporarily work around this using the specified_id field in the dfx.json configuration:

    "icp_ledger_canister": {
      "type": "custom",
      "candid": "https://raw.githubusercontent.com/dfinity/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/rs/rosetta-api/icp_ledger/ledger.did",
      "wasm": "https://download.dfinity.systems/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/canisters/ledger-canister.wasm.gz",
      "specified_id": "ryjl3-tyaaa-aaaaa-aaaba-cai",
      "remote": {
        "id": {
          "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
        }
      }
    }

Then, you could potentially use the approach described in this forum reply.

icpShiller commented 1 month ago

@rvanasa thanks I'm on Mac (Sonama 14.5). I was on dfx version 0.19 but after upgrading, same issue..

I realized that I had dfx startrunning in the background for quite some time. After running dfx start --clean, it made me remember that I had created my ICP canister using the command provided on this page:

dfx deploy --specified-id ryjl3-tyaaa-aaaaa-aaaba-cai icp_ledger_canister --argument "
  (variant {
    Init = record {
      minting_account = \"$MINTER_ACCOUNT_ID\";
      initial_values = vec {
        record {
          \"$DEFAULT_ACCOUNT_ID\";
          record {
            e8s = 10_000_000_000 : nat64;
          };
        };
      };
      send_whitelist = vec {};
      transfer_fee = opt record {
        e8s = 10_000 : nat64;
      };
      token_symbol = opt \"LICP\";
      token_name = opt \"Local ICP\";
    }
  })
"

seems pretty normal to me, but maybe this could be causing the issue ?

So I first ran the above command, then later only used dfx deploy to update my canisters.

rvanasa commented 1 month ago

I've followed the same steps on both of my testing environments and still haven't managed to reproduce the issue. Does anything look unusual in the "Motoko Language Server" extension logs? For reference, here is where to find it:

image

Do you encounter the same issue when opening the project on an online IDE such as Gitpod? This might help narrow down the possibilities.

Starter project which you can replace with your own files: https://gitpod.io/new/#https://github.com/rvanasa/vite-react-motoko

Alternatively, do you have a public Git repository for your project?

icpShiller commented 1 month ago

I have no errors displayed in my VSCode "Output" tab (Motoko Language Server selected). I have just tried in Gitpod and I have the same error 😲

image

The repository is private but I just added you @rvanasa.

rvanasa commented 1 month ago

Thanks for adding me to the repository! I was able to reproduce the issue by running the following commands in a Gitpod environment:

sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)"
source "$HOME/.local/share/dfx/env"

dfx start --background

export MINTER_ACCOUNT_ID=$(dfx ledger account-id)
export DEFAULT_ACCOUNT_ID=$(dfx ledger account-id)

dfx deploy --specified-id ryjl3-tyaaa-aaaaa-aaaba-cai icp_ledger_canister --argument "
  (variant {
    Init = record {
      minting_account = \"$MINTER_ACCOUNT_ID\";
      initial_values = vec {
        record {
          \"$DEFAULT_ACCOUNT_ID\";
          record {
            e8s = 10_000_000_000 : nat64;
          };
        };
      };
      send_whitelist = vec {};
      transfer_fee = opt record {
        e8s = 10_000 : nat64;
      };
      token_symbol = opt \"LICP\";
      token_name = opt \"Local ICP\";
    }
  })
"

Instead of canister alias "icp_ledger_canister" not defined, I'm getting file "/workspace/pitreon/.dfx/local/lsp/bkyz2-fmaaa-aaaaa-qaaaq-cai.did" does not exist.

Is this the same for you? If so, you can fix the issue by resetting your local dfx environment (dfx stop; dfx start --clean --background) and then removing the --specified-id flag.

This appears to be some sort of platform-specific bug, since it doesn't happen on my local dev environment for some reason. I will see if there is a way to fix this in the extension. Hopefully removing the --specified-id flag works for the time being; otherwise, let me know and I'll continue looking into this.

icpShiller commented 1 month ago

@rvanasa actually no, I'm still getting the same isssue in Gitpod as I was locally:

image
icpShiller commented 1 month ago

That being said, I don't really know how Gitpod works: I basically just authorized access to my repo and it initialized itself. I didn't run any commands.

rvanasa commented 1 month ago

Got it; this error message will always show up until all canisters are deployed. Does everything work if you run the commands that I listed above?

icpShiller commented 1 month ago

@rvanasa Ok, so after running your command, I see no more error! Now how can I reproduce this locally? 😋

rvanasa commented 1 month ago

Since this seems to narrow down the issue to something that's specific to your local dev environment, here are a few more debugging questions:

  1. Is dfx available on your path from the terminal which you launched VS Code?
  2. Have you tried fully resetting the local replica (dfx stop; dfx start --clean --background), redeploying without the --specified-id flag, and then restarting VS Code?
  3. Do you have an M1/M2/M3 chip on your Mac, and if so, are you using Rosetta? Sometimes this can cause subtle platform-specific issues in general.
icpShiller commented 1 month ago

@rvanasa So you mean this command:

dfx deploy icp_ledger_canister --argument "
  (variant {
    Init = record {
      minting_account = \"$MINTER_ACCOUNT_ID\";
      initial_values = vec {
        record {
          \"$DEFAULT_ACCOUNT_ID\";
          record {
            e8s = 10_000_000_000 : nat64;
          };
        };
      };
      send_whitelist = vec {};
      transfer_fee = opt record {
        e8s = 10_000 : nat64;
      };
      token_symbol = opt \"LICP\";
      token_name = opt \"Local ICP\";
    }
  })
"

then dfx deploy ?

By the way, my Mac has an M2. However I'm not using Rosetta (at least not to my knowledge!)

rvanasa commented 1 month ago

Yep! As a side note, if you want to simplify the setup process, you can add the init_arg_file field to your dfx.json file:

    "icp_ledger_canister": {
      "type": "custom",
      "candid": "https://raw.githubusercontent.com/dfinity/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/rs/rosetta-api/icp_ledger/ledger.did",
      "wasm": "https://download.dfinity.systems/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/canisters/ledger-canister.wasm.gz",
      "remote": {
        "id": {
          "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
        }
      },
      "init_arg_file": "candid/icp_ledger_init.did"
    },

Then, create a new candid/icp_ledger_init.did file:

(variant {
  Init = record {
    minting_account = \"$MINTER_ACCOUNT_ID\";
    initial_values = vec {
      record {
        \"$DEFAULT_ACCOUNT_ID\";
        record {
          e8s = 10_000_000_000 : nat64;
        };
      };
    };
    send_whitelist = vec {};
    transfer_fee = opt record {
      e8s = 10_000 : nat64;
    };
    token_symbol = opt \"LICP\";
    token_name = opt \"Local ICP\";
  }
})

It might be worth debugging this VS Code issue first, but I just wanted to mention this since it's a nice quality-of-life improvement that was recently added to dfx.

icpShiller commented 1 month ago

@rvanasa I successfully restarted everything (I even restarted my laptop, as I don't do it often enough and sometimes get cache issues.. :P ), then started VSCode from a terminal where dfx 0.20.1 is available, then:

Everything works, but I still get the error "canister alias icp_ledger_canister is not defined..." 🤯

Sorry, I feel like I'm taking too much of your time! Any other idea? How are the aliases defined (in the dfx.json file, right? then why..) ? And why am I not seeing the error in Gitpod.. 😟

I noticed in the forum 2 guys having the same issue 2 years ago. Just like him, I really wouldn't want to have to create a class just to use the icp ledger canister.

rvanasa commented 1 month ago

No worries; it would be good to figure out what's happening so that we can fix this for anyone else encountering the same issue. This is bizarre though. I'll ask around internally to see if we can further narrow down the root cause.

rvanasa commented 3 weeks ago

As a quick update, I included a bugfix in version 0.16.4 of the extension which might be possible to use as a workaround for this issue.

You could try the new logic by adjusting your dfx.json file to use the following definition, and then fresh-redeploying the canister:

"icp_ledger_canister": {
      "type": "custom",
      "candid": "https://raw.githubusercontent.com/dfinity/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/rs/rosetta-api/icp_ledger/ledger.did",
      "wasm": "https://download.dfinity.systems/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/canisters/ledger-canister.wasm.gz",
      "remote": {
        "id": {
          "local": "ryjl3-tyaaa-aaaaa-aaaba-cai",
          "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
        }
      }
    },

I also added some additional debugging info in the output panel (specifically the "Actor alias" output) which could be useful if the extension still isn't working as expected on your local machine.

icpShiller commented 3 weeks ago

Hey @rvanasa, thanks! I just saw your message.

So, after upgrading to 0.16.4, I added the local line so that my dfx.json looks like this:

...

"icp_ledger": {
  "type": "custom",
  "candid": "https://raw.githubusercontent.com/dfinity/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/rs/rosetta-api/icp_ledger/ledger.did",
  "wasm": "https://download.dfinity.systems/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/canisters/ledger-canister.wasm.gz",
  "remote": {
    "id": {
      "local": "ryjl3-tyaaa-aaaaa-aaaba-cai",
      "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
    }
  }
},
"pitreon_backend": {
  "main": "src/pitreon_backend/main.mo",
  "type": "motoko",
  "dependencies": [
      "icp_ledger"
  ]
},

...

I'm still getting the exact same error.. sigh Here are the logs of my dfx deploy. Maybe you'll notice something wrong..

Deploying all canisters.
All canisters have already been created.
Building canisters...
WARN: ryjl3-tyaaa-aaaaa-aaaba-cai.did:484.10-538.2: warning [M0185], importing Candid service constructor as instantiated service
ryjl3-tyaaa-aaaaa-aaaba-cai.did:484.10-538.2: warning [M0185], importing Candid service constructor as instantiated service
/Users/me/.cache/dfinity/versions/0.20.1/base/Principal.mo:80.20-80.32: warning [M0154], field append is deprecated:
`Array.append` copies its arguments and has linear complexity;
/Users/me/Code/pitreon/src/pitreon_backend/main.mo:76.21-76.23: warning [M0194], unused identifier id (delete or rename to wildcard `_` or `_id`)

Building frontend...
WARN: Building canisters before generate for Motoko
WARN: ryjl3-tyaaa-aaaaa-aaaba-cai.did:484.10-538.2: warning [M0185], importing Candid service constructor as instantiated service
ryjl3-tyaaa-aaaaa-aaaba-cai.did:484.10-538.2: warning [M0185], importing Candid service constructor as instantiated service
/Users/me/.cache/dfinity/versions/0.20.1/base/Principal.mo:80.20-80.32: warning [M0154], field append is deprecated:
`Array.append` copies its arguments and has linear complexity;
/Users/me/Code/pitreon/src/pitreon_backend/main.mo:76.21-76.23: warning [M0194], unused identifier id (delete or rename to wildcard `_` or `_id`)

Generating type declarations for canister pitreon_frontend:
  /Users/me/Code/pitreon/src/declarations/pitreon_frontend/pitreon_frontend.did.d.ts
  /Users/me/Code/pitreon/src/declarations/pitreon_frontend/pitreon_frontend.did.js
  /Users/me/Code/pitreon/src/declarations/pitreon_frontend/pitreon_frontend.did
Generating type declarations for canister pitreon_backend:
  /Users/me/Code/pitreon/src/declarations/pitreon_backend/pitreon_backend.did.d.ts
  /Users/me/Code/pitreon/src/declarations/pitreon_backend/pitreon_backend.did.js
  /Users/me/Code/pitreon/src/declarations/pitreon_backend/pitreon_backend.did
Generating type declarations for canister internet_identity:
  /Users/me/Code/pitreon/src/declarations/internet_identity/internet_identity.did.d.ts
  /Users/me/Code/pitreon/src/declarations/internet_identity/internet_identity.did.js
  /Users/me/Code/pitreon/src/declarations/internet_identity/internet_identity.did
Generating type declarations for canister icp_ledger:
  /Users/me/Code/pitreon/src/declarations/icp_ledger/icp_ledger.did.d.ts
  /Users/me/Code/pitreon/src/declarations/icp_ledger/icp_ledger.did.js
  /Users/me/Code/pitreon/src/declarations/icp_ledger/icp_ledger.did

(!) Some chunks are larger than 500 kBs after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.

Installing canisters...
Upgrading code for canister internet_identity, with canister ID be2us-64aaa-aaaaa-qaabq-cai
Module hash 01797eac7db02126e7cb507e2f3134e2d7b5154289808fdc2c8c03d1fc2dc60e is already installed.
Upgrading code for canister pitreon_backend, with canister ID br5f7-7uaaa-aaaaa-qaaca-cai
Upgrading code for canister pitreon_frontend, with canister ID bw4dl-smaaa-aaaaa-qaacq-cai
Module hash 32e92f1190d8321e97f8d8f3e793019e4fd2812bfc595345d46d2c23f74c1ab5 is already installed.
Uploading assets to asset canister...
Fetching properties for all assets in the canister.
Starting batch.
Staging contents of new and changed assets in batch 12:
  /defaultpfp.png (98357 bytes) sha a143849cc6a8f1383021fb6edad6ff6092dcf5163990a0a6fec9cc3384ae0830 is already installed
  /defaultbgp.png (325441 bytes) sha 750521805bac653cd695da1268299097751500875385de288b1eaee0b6b00a96 is already installed
  /favicon.ico (15406 bytes) sha 4e8d31b50ffb59695389d94e393d299c5693405a12f6ccd08c31bcf9b58db2d4 is already installed
  /logo2.svg (15139 bytes) sha 037eb7ae523403daa588cf4f47a34c56a3f5de08a5a2dd2364839e45f14f4b8b is already installed
  /logo.svg (16067 bytes) sha d4d32da5343d9b4949d572c30e737adb776c386c1716c1bd20be56bf6c994406 is already installed
  /assets/index-80bd07c8.js 1/1 (887777 bytes) sha 3f5626b652dc084826e7de3fde41227c157a27f6f368c444481a48cd1e98f4e1 (with 7 headers)
  /index.html (gzip) 1/1 (260 bytes) sha fbbf1dd58030d85a09be6616d45b44b06ced86a7de08f791f08d03360ae4add9 (with 7 headers)
  /index.html 1/1 (371 bytes) sha 0f31898cd1e9b97d59237e504328b529509cadf86a51c3c2ae5112273d96174f (with 7 headers)
  /assets/index-80bd07c8.js (gzip) 1/1 (291518 bytes) sha 80b432ed685d632e35d1870fc4cf165d5f023eab9c30499cb0101655317e0e67 (with 7 headers)
Committing batch.
Committing batch with 6 operations.
Deployed canisters.
URLs:
  Frontend canister via browser
    internet_identity:
      - http://127.0.0.1:4943/?canisterId=be2us-64aaa-aaaaa-qaabq-cai
      - http://be2us-64aaa-aaaaa-qaabq-cai.localhost:4943/
    pitreon_frontend:
      - http://127.0.0.1:4943/?canisterId=bw4dl-smaaa-aaaaa-qaacq-cai
      - http://bw4dl-smaaa-aaaaa-qaacq-cai.localhost:4943/
  Backend canister via Candid interface:
    internet_identity: http://127.0.0.1:4943/?canisterId=bd3sg-teaaa-aaaaa-qaaba-cai&id=be2us-64aaa-aaaaa-qaabq-cai
    pitreon_backend: http://127.0.0.1:4943/?canisterId=bd3sg-teaaa-aaaaa-qaaba-cai&id=br5f7-7uaaa-aaaaa-qaaca-cai

Also, note that I don't see anything in the "Output" tab.

Thanks again for sticking with me :)

rvanasa commented 2 weeks ago

Thanks for the debugging info. Since this only seems to happen on your machine (given that everything works on Gitpod and #284 fixed the error for Severin internally), I'm not sure if there's much else I can do to figure out what's causing this.

If anyone else comes across this page with a similar issue, please be sure to leave a comment so we can more effectively triangulate what's happening.