diff --git a/CHANGELOG.md b/CHANGELOG.md index a2dceab4ea..8fbc9e1e30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The `dfx cycles` command no longer needs nor accepts the `--cycles-ledger-canister-id ` parameter. +### chore: removed the dfx start --emulator mode + +This was deprecated in dfx 0.15.1. + ### chore: removed ic-ref from the binary cache ### chore: updated dependencies for new rust projects @@ -23,6 +27,10 @@ Now they are stored with nanosecond precision on Windows too. Updated Motoko to [0.10.4](https://github.com/dfinity/motoko/releases/tag/0.10.4) +### Frontend canister + +Module hash: b625e04115725038808dcd6db1e398def28e981f8d6de464bb8438b2656864c8 + # 0.15.3 ### fix: allow `http://localhost:*` as `connect-src` in the asset canister's CSP @@ -1352,7 +1360,7 @@ Additionally, after build step, the `.wasm` file is archived with `gzip`. ### chore: Move all `frontend canister`-related code into the SDK repo | from (`repository` `path`) | to (path in `dfinity/sdk` repository) | summary | -| :------------------------------------------ | :--------------------------------------------- | :------------------------------------------------------------------------------------------ | +|:--------------------------------------------|:-----------------------------------------------|:--------------------------------------------------------------------------------------------| | `dfinity/cdk-rs` `/src/ic-certified-assets` | `/src/canisters/frontend/ic-certified-asset` | the core of the frontend canister | | `dfinity/certified-assets` `/` | `/src/canisters/frontend/ic-frontend-canister` | wraps `ic-certified-assets` to build the canister wasm | | `dfinity/agent-rs` `/ic-asset` | `/src/canisters/frontend/ic-asset` | library facilitating interactions with frontend canister (e.g. uploading or listing assets) | diff --git a/Cargo.lock b/Cargo.lock index 697148c70e..f57c19b0d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,10 +112,11 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "aead" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ + "crypto-common", "generic-array", ] @@ -126,20 +127,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ "cfg-if 1.0.0", - "cipher", + "cipher 0.3.0", "cpufeatures", "opaque-debug", ] +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if 1.0.0", + "cipher 0.4.4", + "cpufeatures", +] + [[package]] name = "aes-gcm" -version = "0.9.4" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", - "aes", - "cipher", + "aes 0.8.3", + "cipher 0.4.4", "ctr", "ghash", "subtle", @@ -574,7 +586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" dependencies = [ "block-padding", - "cipher", + "cipher 0.3.0", ] [[package]] @@ -599,47 +611,26 @@ dependencies = [ [[package]] name = "borsh" -version = "0.10.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" dependencies = [ "borsh-derive", - "hashbrown 0.13.2", + "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" -dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", - "proc-macro-crate 0.1.5", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "borsh-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "borsh-schema-derive-internal" -version = "0.10.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" dependencies = [ + "once_cell", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", + "syn_derive", ] [[package]] @@ -762,7 +753,7 @@ dependencies = [ "logos 0.12.1", "num-bigint 0.4.4", "num-traits", - "num_enum 0.5.11", + "num_enum", "paste", "pretty 0.10.0", "serde", @@ -773,35 +764,23 @@ dependencies = [ [[package]] name = "candid" -version = "0.9.11" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465c1ce01d8089ee5b49ba20d3a9da15a28bba64c35cdff2aa256d37e319625d" +checksum = "39be580be172631a35cac2fc6c765f365709de459edb88121b3e7a80cce6c1ec" dependencies = [ "anyhow", - "arbitrary", "binread", "byteorder", - "candid_derive 0.6.4", - "codespan-reporting", - "convert_case 0.6.0", - "crc32fast", - "data-encoding", - "fake", + "candid_derive 0.6.5", "hex", - "lalrpop 0.20.0", - "lalrpop-util 0.20.0", + "ic_principal", "leb128", - "logos 0.13.0", "num-bigint 0.4.4", "num-traits", - "num_enum 0.6.1", "paste", "pretty 0.12.3", - "rand", "serde", "serde_bytes", - "serde_dhall", - "sha2 0.10.8", "stacker", "thiserror", ] @@ -820,9 +799,9 @@ dependencies = [ [[package]] name = "candid_derive" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201ea498d901add0822653ac94cb0f8a92f9b1758a5273f4dafbb6673c9a5020" +checksum = "970c220da8aa2fa6f7ef5dbbf3ea5b620a59eb3ac107cfb95ae8c6eebdfb7a08" dependencies = [ "lazy_static", "proc-macro2", @@ -830,6 +809,31 @@ dependencies = [ "syn 2.0.38", ] +[[package]] +name = "candid_parser" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36381de3ba8a312deb028552c0d63f7c7fe6e204f44bae4c58a3643308cfa9d5" +dependencies = [ + "anyhow", + "arbitrary", + "candid 0.10.2", + "codespan-reporting", + "convert_case 0.6.0", + "fake", + "hex", + "lalrpop 0.20.0", + "lalrpop-util 0.20.0", + "logos 0.13.0", + "num-bigint 0.4.4", + "num-traits", + "pretty 0.12.3", + "rand", + "serde", + "serde_dhall", + "thiserror", +] + [[package]] name = "cc" version = "1.0.83" @@ -852,6 +856,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.31" @@ -884,6 +894,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.4.7" @@ -1178,6 +1198,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] @@ -1193,11 +1214,11 @@ dependencies = [ [[package]] name = "ctr" -version = "0.8.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher", + "cipher 0.4.4", ] [[package]] @@ -1392,12 +1413,12 @@ dependencies = [ "anyhow", "apply-patch", "argon2", - "atty", "backoff", "base64 0.13.1", "byte-unit", "bytes", - "candid 0.9.11", + "candid 0.10.2", + "candid_parser", "ci_info", "clap", "console", @@ -1420,7 +1441,7 @@ dependencies = [ "ic-asset", "ic-cdk", "ic-identity-hsm", - "ic-utils 0.30.2", + "ic-utils 0.31.0", "ic-wasm", "icrc-ledger-types", "indicatif", @@ -1481,7 +1502,8 @@ dependencies = [ "bip32", "byte-unit", "bytes", - "candid 0.9.11", + "candid 0.10.2", + "candid_parser", "clap", "dialoguer", "directories-next", @@ -1491,7 +1513,7 @@ dependencies = [ "humantime-serde", "ic-agent", "ic-identity-hsm", - "ic-utils 0.30.2", + "ic-utils 0.31.0", "k256 0.11.6", "keyring", "lazy_static", @@ -2127,9 +2149,9 @@ dependencies = [ [[package]] name = "ghash" -version = "0.4.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" dependencies = [ "opaque-debug", "polyval", @@ -2235,15 +2257,6 @@ dependencies = [ "ahash 0.7.7", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash 0.8.6", -] - [[package]] name = "hashbrown" version = "0.14.2" @@ -2460,18 +2473,18 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.30.2" -source = "git+https://github.com/dfinity/agent-rs.git?rev=ed0862a45d5973ff123cbabc4ac40a89821b18c6#ed0862a45d5973ff123cbabc4ac40a89821b18c6" +version = "0.31.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=a7f44ad05e77fc89b8447dd65b345e7a62fd1042#a7f44ad05e77fc89b8447dd65b345e7a62fd1042" dependencies = [ "backoff", "cached 0.46.1", - "candid 0.9.11", + "candid 0.10.2", "ed25519-consensus", "futures-util", "hex", "http", "http-body", - "ic-certification 1.3.0", + "ic-certification 2.3.0", "ic-transport-types", "ic-verify-bls-signature", "k256 0.13.1", @@ -2501,7 +2514,7 @@ name = "ic-asset" version = "0.20.0" dependencies = [ "backoff", - "candid 0.9.11", + "candid 0.10.2", "derivative", "dfx-core", "flate2", @@ -2510,7 +2523,7 @@ dependencies = [ "globset", "hex", "ic-agent", - "ic-utils 0.30.2", + "ic-utils 0.31.0", "itertools 0.10.5", "json5", "mime", @@ -2572,11 +2585,11 @@ dependencies = [ [[package]] name = "ic-cdk" -version = "0.10.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d4c0b932bf454d5d60e61e13c3c944972fcfd74dc82b9ed5c8b0a75979cf50" +checksum = "9f3d204af0b11c45715169c997858edb58fa8407d08f4fae78a6b415dd39a362" dependencies = [ - "candid 0.9.11", + "candid 0.10.2", "ic-cdk-macros", "ic0", "serde", @@ -2585,11 +2598,11 @@ dependencies = [ [[package]] name = "ic-cdk-macros" -version = "0.7.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411c0dd4c149132b68e679274d397053332ee29996c6a541075895881916333b" +checksum = "a5a618e4020cea88e933d8d2f8c7f86d570ec06213506a80d4f2c520a9bba512" dependencies = [ - "candid 0.9.11", + "candid 0.10.2", "proc-macro2", "quote", "serde", @@ -2619,12 +2632,25 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "ic-certification" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79fd38f674173bd0af3c80b9dab6fedd3391b81a2fc0f87a2e393fb723fe13b" +dependencies = [ + "hex", + "serde", + "serde_bytes", + "sha2 0.10.8", +] + [[package]] name = "ic-certified-assets" version = "0.2.5" dependencies = [ "base64 0.13.1", - "candid 0.9.11", + "candid 0.10.2", + "candid_parser", "hex", "ic-cdk", "ic-certification 1.3.0", @@ -2803,6 +2829,7 @@ dependencies = [ name = "ic-frontend-canister" version = "0.2.5" dependencies = [ + "candid 0.10.2", "ic-cdk", "ic-certified-assets", ] @@ -2829,8 +2856,8 @@ dependencies = [ [[package]] name = "ic-identity-hsm" -version = "0.30.2" -source = "git+https://github.com/dfinity/agent-rs.git?rev=ed0862a45d5973ff123cbabc4ac40a89821b18c6#ed0862a45d5973ff123cbabc4ac40a89821b18c6" +version = "0.31.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=a7f44ad05e77fc89b8447dd65b345e7a62fd1042#a7f44ad05e77fc89b8447dd65b345e7a62fd1042" dependencies = [ "hex", "ic-agent", @@ -2925,12 +2952,12 @@ dependencies = [ [[package]] name = "ic-transport-types" -version = "0.30.2" -source = "git+https://github.com/dfinity/agent-rs.git?rev=ed0862a45d5973ff123cbabc4ac40a89821b18c6#ed0862a45d5973ff123cbabc4ac40a89821b18c6" +version = "0.31.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=a7f44ad05e77fc89b8447dd65b345e7a62fd1042#a7f44ad05e77fc89b8447dd65b345e7a62fd1042" dependencies = [ - "candid 0.9.11", + "candid 0.10.2", "hex", - "ic-certification 1.3.0", + "ic-certification 2.3.0", "leb128", "serde", "serde_bytes", @@ -3000,11 +3027,11 @@ dependencies = [ [[package]] name = "ic-utils" -version = "0.30.2" -source = "git+https://github.com/dfinity/agent-rs.git?rev=ed0862a45d5973ff123cbabc4ac40a89821b18c6#ed0862a45d5973ff123cbabc4ac40a89821b18c6" +version = "0.31.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=a7f44ad05e77fc89b8447dd65b345e7a62fd1042#a7f44ad05e77fc89b8447dd65b345e7a62fd1042" dependencies = [ "async-trait", - "candid 0.9.11", + "candid 0.10.2", "ic-agent", "once_cell", "semver", @@ -3030,14 +3057,16 @@ dependencies = [ [[package]] name = "ic-wasm" -version = "0.4.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e360e45c2bf406a867c35ec5daee433f2c3bbbaf013469e6a386a322a9713885" +checksum = "9d2aa0d7deeb38f18fcec6e4c25c5004422e2e9f8c3fbad15bb795ebac37aca6" dependencies = [ "anyhow", - "candid 0.9.11", + "candid 0.10.2", "clap", "rustc-demangle", + "serde", + "serde_json", "tempfile", "thiserror", "walrus", @@ -3046,9 +3075,9 @@ dependencies = [ [[package]] name = "ic0" -version = "0.18.11" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576c539151d4769fb4d1a0c25c4108dd18facd04c5695b02cf2d226ab4e43aa5" +checksum = "a54b5297861c651551676e8c43df805dad175cc33bc97dbd992edbbb85dcbcdf" [[package]] name = "ic_bls12_381" @@ -3065,14 +3094,28 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ic_principal" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1762deb6f7c8d8c2bdee4b6c5a47b60195b74e9b5280faa5ba29692f8e17429c" +dependencies = [ + "arbitrary", + "crc32fast", + "data-encoding", + "serde", + "sha2 0.10.8", + "thiserror", +] + [[package]] name = "icrc-ledger-types" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ad46da2124f4d7bf5c079eca568786b87bd60fc962bef404ff44207077961c" +checksum = "804c892bf95652101660a25cea10f059f73eb8973f6b04e0349758fda1190447" dependencies = [ "base32", - "candid 0.9.11", + "candid 0.10.2", "crc32fast", "hex", "num-bigint 0.4.4", @@ -3088,13 +3131,13 @@ version = "0.20.0" dependencies = [ "anstyle", "anyhow", - "candid 0.9.11", + "candid 0.10.2", "clap", "delay", "humantime", "ic-agent", "ic-asset", - "ic-utils 0.30.2", + "ic-utils 0.31.0", "libflate", "num-traits", "pem 1.1.1", @@ -3164,6 +3207,15 @@ dependencies = [ "regex", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.12" @@ -3862,16 +3914,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ - "num_enum_derive 0.5.11", -] - -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive", ] [[package]] @@ -3886,18 +3929,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "num_threads" version = "0.1.6" @@ -4308,9 +4339,9 @@ dependencies = [ [[package]] name = "polyval" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -4395,7 +4426,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" +dependencies = [ + "toml_edit 0.21.0", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", ] [[package]] @@ -4793,9 +4856,9 @@ checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" [[package]] name = "rust_decimal" -version = "1.32.0" +version = "1.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd" +checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" dependencies = [ "arrayvec 0.7.4", "borsh", @@ -5029,7 +5092,7 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1da5c423b8783185fd3fecd1c8796c267d2c089d894ce5a93c280a5d3f780a2" dependencies = [ - "aes", + "aes 0.7.5", "block-modes", "hkdf", "lazy_static", @@ -5077,9 +5140,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.190" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] @@ -5105,9 +5168,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -5523,11 +5586,11 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "supports-color" -version = "1.3.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba6faf2ca7ee42fdd458f4347ae0a9bd6bcc445ad7cb57ad82b383f18870d6f" +checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89" dependencies = [ - "atty", + "is-terminal", "is_ci", ] @@ -5553,6 +5616,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "sysinfo" version = "0.28.4" @@ -5767,9 +5842,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -5786,9 +5861,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", @@ -5847,7 +5922,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.19.15", ] [[package]] @@ -5872,6 +5947,17 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -5986,11 +6072,11 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "universal-hash" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "generic-array", + "crypto-common", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index 8a42a64df0..b3a9ad6814 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,14 +18,15 @@ rust-version = "1.71.1" license = "Apache-2.0" [workspace.dependencies] -candid = { version = "0.9.0", features = ["parser"] } -ic-agent = "0.30.2" +candid = "0.10.0" +candid_parser = "0.1.2" +ic-agent = { git = "https://github.com/dfinity/agent-rs.git", rev = "a7f44ad05e77fc89b8447dd65b345e7a62fd1042" } ic-asset = { path = "src/canisters/frontend/ic-asset" } -ic-cdk = "0.10.0" -ic-identity-hsm = "0.30.2" -ic-utils = "0.30.2" +ic-cdk = "0.12.0" +ic-identity-hsm = { git = "https://github.com/dfinity/agent-rs.git", rev = "a7f44ad05e77fc89b8447dd65b345e7a62fd1042" } +ic-utils = { git = "https://github.com/dfinity/agent-rs.git", rev = "a7f44ad05e77fc89b8447dd65b345e7a62fd1042" } -aes-gcm = "0.9.4" +aes-gcm = "0.10.3" anyhow = "1.0.56" anstyle = "1.0.0" argon2 = "0.4.0" @@ -68,21 +69,6 @@ tokio = "1.24.2" url = "2.1.0" walkdir = "2.3.2" -[patch.crates-io.ic-agent] -version = "0.30.2" -git = "https://github.com/dfinity/agent-rs.git" -rev = "ed0862a45d5973ff123cbabc4ac40a89821b18c6" - -[patch.crates-io.ic-identity-hsm] -version = "0.30.2" -git = "https://github.com/dfinity/agent-rs.git" -rev = "ed0862a45d5973ff123cbabc4ac40a89821b18c6" - -[patch.crates-io.ic-utils] -version = "0.30.2" -git = "https://github.com/dfinity/agent-rs.git" -rev = "ed0862a45d5973ff123cbabc4ac40a89821b18c6" - [profile.release] panic = 'abort' lto = true diff --git a/docs/cli-reference/dfx-start.md b/docs/cli-reference/dfx-start.md index 3621c67bc2..2ec382bf9d 100644 --- a/docs/cli-reference/dfx-start.md +++ b/docs/cli-reference/dfx-start.md @@ -18,7 +18,6 @@ You can use the following optional flags with the `dfx start` command. |-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `--background` | Starts the local canister execution environment and web server processes in the background and waits for a reply before returning to the shell. | | `--clean` | Starts the local canister execution environment and web server processes in a clean state by removing checkpoints from your project cache. You can use this flag to set your project cache to a new state when troubleshooting or debugging. | -| `--emulator` | Starts the [IC reference emulator](https://github.com/dfinity/ic-hs) rather than the replica. (deprecated: will be discontinued soon) | | `--enable-bitcoin` | Enables bitcoin integration. | | `--enable-canister-http` | Enables canister HTTP requests. (deprecated: now enabled by default) | | `--use-old-metering` | Enables the old metering in the local canister execution environment. Please see the forum thread for more details or to report any issues: [forum.dfinity.org/t/new-wasm-instrumentation/](https://forum.dfinity.org/t/new-wasm-instrumentation/22080) | diff --git a/e2e/tests-dfx/assetscanister.bash b/e2e/tests-dfx/assetscanister.bash index 2a5aaf6083..6656c6849b 100644 --- a/e2e/tests-dfx/assetscanister.bash +++ b/e2e/tests-dfx/assetscanister.bash @@ -884,13 +884,12 @@ check_permission_failure() { assert_command dfx canister call --query e2e_project_frontend get '(record{key="/text-with-newlines.txt";accept_encodings=vec{"identity"}})' - assert_command dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 243; 191; 114; 177; 83; 18; 144; 121; 131; 38; 109; 183; 89; 244; 120; 136; 53; 187; 14; 74; 8; 112; 86; 100; 115; 8; 179; 155; 69; 78; 95; 160; }})' + assert_command dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt blob "\f3\bf\72\b1\53\12\90\79\83\26\6d\b7\59\f4\78\88\35\bb\0e\4a\08\70\56\64\73\08\b3\9b\45\4e\5f\a0" })' assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0})' assert_match 'sha256 required' - assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 88; 87; 86; }})' + assert_command_fail dfx canister call --query e2e_project_frontend get_chunk '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt blob "XWV" })' assert_match 'sha256 mismatch' - assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 243; 191; 114; 177; 83; 18; 144; 121; 131; 38; 109; 183; 89; 244; 120; 136; 53; 187; 14; 74; 8; 112; 86; 100; 115; 8; 179; 155; 69; 78; 95; 160; }})' assert_command dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt blob "\f3\bf\72\b1\53\12\90\79\83\26\6d\b7\59\f4\78\88\35\bb\0e\4a\08\70\56\64\73\08\b3\9b\45\4e\5f\a0"})' assert_command_fail dfx canister call --query e2e_project_frontend http_request_streaming_callback '(record{key="/text-with-newlines.txt";content_encoding="identity";index=0;sha256=opt vec { 88; 87; 86; }})' assert_match 'sha256 mismatch' @@ -906,14 +905,14 @@ check_permission_failure() { dfx canister install e2e_project_frontend assert_command dfx canister call --query e2e_project_frontend retrieve '("/binary/noise.txt")' --output idl - assert_eq '(blob "\b8\01 \80\0aw12 \00xy\0aKL\0b\0ajk")' + assert_eq '(blob "\b8\01\20\80\0a\77\31\32\20\00\78\79\0a\4b\4c\0b\0a\6a\6b")' assert_command dfx canister call --query e2e_project_frontend retrieve '("/text-with-newlines.txt")' --output idl assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' assert_command dfx canister call --update e2e_project_frontend store '(record{key="AA"; content_type="text/plain"; content_encoding="identity"; content=blob "hello, world!"})' assert_eq '()' - assert_command dfx canister call --update e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' + assert_command dfx canister call --update e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=blob"XWV"})' assert_eq '()' assert_command dfx canister call --query e2e_project_frontend retrieve '("B")' --output idl diff --git a/e2e/tests-dfx/basic-project.bash b/e2e/tests-dfx/basic-project.bash index 6dd4ab76f8..8e77ee3ec9 100644 --- a/e2e/tests-dfx/basic-project.bash +++ b/e2e/tests-dfx/basic-project.bash @@ -47,7 +47,9 @@ teardown() { assert_eq \ '( variant { - 17_724 = record { 153_986_224 = blob "DIDL\00\01q\11Hello, Blueberry!" } + 17_724 = record { + 153_986_224 = blob "\44\49\44\4c\00\01\71\11\48\65\6c\6c\6f\2c\20\42\6c\75\65\62\65\72\72\79\21"; + } }, )' } @@ -100,7 +102,12 @@ teardown() { # Call using the wallet's call forwarding assert_command dfx canister call hello_backend read --async --wallet="$(dfx identity get-wallet)" assert_command dfx canister request-status "$stdout" "$(dfx identity get-wallet)" - assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01}\b9\0a" } })' + assert_eq \ +'( + variant { + 17_724 = record { 153_986_224 = blob "\44\49\44\4c\00\01\7d\b9\0a" } + }, +)' } diff --git a/e2e/tests-dfx/build_granular.bash b/e2e/tests-dfx/build_granular.bash index d60b824b53..3b50ec9d94 100644 --- a/e2e/tests-dfx/build_granular.bash +++ b/e2e/tests-dfx/build_granular.bash @@ -67,7 +67,7 @@ teardown() { dfx canister install e2e_project_frontend assert_command dfx canister call --query e2e_project_frontend retrieve '("/binary/noise.txt")' --output idl - assert_eq '(blob "\b8\01 \80\0aw12 \00xy\0aKL\0b\0ajk")' + assert_eq '(blob "\b8\01\20\80\0a\77\31\32\20\00\78\79\0a\4b\4c\0b\0a\6a\6b")' assert_command dfx canister call --query e2e_project_frontend retrieve '("/text-with-newlines.txt")' --output idl assert_eq '(blob "cherries\0ait\27s cherry season\0aCHERRIES")' diff --git a/e2e/tests-dfx/cycles-ledger.bash b/e2e/tests-dfx/cycles-ledger.bash index f015872900..0d12dd70a0 100644 --- a/e2e/tests-dfx/cycles-ledger.bash +++ b/e2e/tests-dfx/cycles-ledger.bash @@ -444,6 +444,7 @@ current_time_nanoseconds() { # using dfx canister create dfx identity use alice + # shellcheck disable=SC2030 export DFX_DISABLE_AUTO_WALLET=1 t=$(current_time_nanoseconds) assert_command dfx canister create e2e_project_backend --with-cycles 1T --created-at-time "$t" @@ -501,3 +502,46 @@ current_time_nanoseconds() { assert_command dfx cycles balance --precise assert_eq "9399600000000 cycles." } + +@test "canister deletion" { + skip "can't be properly tested with feature flag turned off (CYCLES_LEDGER_ENABLED). TODO(SDK-1331): re-enable this test" + dfx_new temporary + add_cycles_ledger_canisters_to_project + install_cycles_ledger_canisters + + ALICE=$(dfx identity get-principal --identity alice) + + assert_command deploy_cycles_ledger + CYCLES_LEDGER_ID=$(dfx canister id cycles-ledger) + echo "Cycles ledger deployed at id $CYCLES_LEDGER_ID" + assert_command dfx deploy cycles-depositor --argument "(record {ledger_id = principal \"$(dfx canister id cycles-ledger)\"})" + echo "Cycles depositor deployed at id $(dfx canister id cycles-depositor)" + assert_command dfx ledger fabricate-cycles --canister cycles-depositor --t 9999 + assert_command dfx deploy + assert_command dfx canister call cycles-depositor deposit "(record {to = record{owner = principal \"$ALICE\";};cycles = 22_400_000_000_000;})" --identity cycle-giver + + cd .. + dfx_new + # setup done + + dfx identity use alice + # shellcheck disable=SC2031 + export DFX_DISABLE_AUTO_WALLET=1 + assert_command dfx canister create --all --with-cycles 10T + assert_command dfx cycles balance --precise + assert_eq "2399800000000 cycles." + + # delete by name + assert_command dfx canister stop --all + assert_command dfx canister delete e2e_project_backend + assert_command dfx cycles balance + assert_eq "12.389 TC (trillion cycles)." + + # delete by id + FRONTEND_ID=$(dfx canister id e2e_project_frontend) + rm .dfx/local/canister_ids.json + assert_command dfx canister stop "${FRONTEND_ID}" + assert_command dfx canister delete "${FRONTEND_ID}" + assert_command dfx cycles balance + assert_eq "22.379 TC (trillion cycles)." +} \ No newline at end of file diff --git a/e2e/tests-dfx/deps.bash b/e2e/tests-dfx/deps.bash index 23083a3b5f..c0b319c48f 100644 --- a/e2e/tests-dfx/deps.bash +++ b/e2e/tests-dfx/deps.bash @@ -127,7 +127,7 @@ Failed to download from url: http://example.com/c.wasm." cd ../onchain dfx canister stop a - dfx canister delete a + dfx canister delete a --no-withdrawal cd ../app assert_command_fail dfx deps pull --network local @@ -332,11 +332,11 @@ candid:args => (nat)" # delete onchain canisters so that the replica has no canisters as a clean local replica cd ../onchain dfx canister stop a - dfx canister delete a + dfx canister delete a --no-withdrawal dfx canister stop b - dfx canister delete b + dfx canister delete b --no-withdrawal dfx canister stop c - dfx canister delete c + dfx canister delete c --no-withdrawal cd ../app assert_command dfx deps init # b is set here @@ -362,10 +362,10 @@ Installing canister: $CANISTER_ID_C (dep_c)" # deployed pull dependencies can be stopped and deleted assert_command dfx canister stop dep_b --identity anonymous - assert_command dfx canister delete dep_b --identity anonymous + assert_command dfx canister delete dep_b --identity anonymous --no-withdrawal assert_command dfx canister stop $CANISTER_ID_A --identity anonymous - assert_command dfx canister delete $CANISTER_ID_A --identity anonymous + assert_command dfx canister delete $CANISTER_ID_A --identity anonymous --no-withdrawal # error cases ## set wrong init argument @@ -404,11 +404,11 @@ Installing canister: $CANISTER_ID_C (dep_c)" # delete onchain canisters so that the replica has no canisters as a clean local replica cd ../onchain dfx canister stop a - dfx canister delete a + dfx canister delete a --no-withdrawal dfx canister stop b - dfx canister delete b + dfx canister delete b --no-withdrawal dfx canister stop c - dfx canister delete c + dfx canister delete c --no-withdrawal cd ../app assert_command_fail dfx canister create dep_b @@ -441,7 +441,7 @@ Installing canister: $CANISTER_ID_C (dep_c)" # start a clean local replica dfx canister stop app - dfx canister delete app + dfx canister delete app --no-withdrawal assert_command dfx deploy # only deploy app canister } @@ -450,8 +450,8 @@ Installing canister: $CANISTER_ID_C (dep_c)" # verify the help message assert_command dfx deps pull -h - assert_contains "Pull canisters upon which the project depends. This command connects to the \"ic\" mainnet by default. -You can still choose other network by setting \`--network\`" + assert_contains "Pull canisters upon which the project depends. This command connects to the \"ic\" mainnet by default." + assert_contains "You can still choose other network by setting \`--network\`" assert_command dfx deps pull assert_contains "There are no pull dependencies defined in dfx.json" diff --git a/e2e/tests-dfx/identity.bash b/e2e/tests-dfx/identity.bash index a39681152f..4550368a5a 100644 --- a/e2e/tests-dfx/identity.bash +++ b/e2e/tests-dfx/identity.bash @@ -146,13 +146,13 @@ teardown() { assert_eq '(false)' # these all fail (other identities are not initializer; cannot store assets): - assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity bob - assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity default - assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' + assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=blob"XWV"})' --identity bob + assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=blob"XWV"})' --identity default + assert_command_fail dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=blob"XWV"})' assert_command_fail dfx canister call e2e_project_frontend retrieve '("B")' # but alice, the initializer, can store assets: - assert_command dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=vec { 88; 87; 86; }})' --identity alice + assert_command dfx canister call e2e_project_frontend store '(record{key="B"; content_type="application/octet-stream"; content_encoding="identity"; content=blob"XWV"})' --identity alice assert_eq '()' assert_command dfx canister call --output idl e2e_project_frontend retrieve '("B")' assert_eq '(blob "XWV")' diff --git a/e2e/tests-dfx/wallet.bash b/e2e/tests-dfx/wallet.bash index b2c134f758..66bd979f98 100644 --- a/e2e/tests-dfx/wallet.bash +++ b/e2e/tests-dfx/wallet.bash @@ -131,7 +131,7 @@ teardown() { assert_command dfx canister call "$WALLET" wallet_call \ "(record { canister = principal \"$(dfx canister id e2e_project_backend)\"; method_name = \"amInitializer\"; args = blob \"DIDL\00\00\"; cycles = (0:nat64)})" - assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01~\01" } })' # True in DIDL. + assert_eq '(variant { 17_724 = record { 153_986_224 = blob "\44\49\44\4c\00\01\7e\01" } })' # True in DIDL. } @test "forward user call through wallet: deploy" { @@ -147,7 +147,7 @@ teardown() { assert_command dfx canister call e2e_project_backend amInitializer assert_command dfx canister call "$WALLET" wallet_call \ "(record { canister = principal \"$(dfx canister id e2e_project_backend)\"; method_name = \"amInitializer\"; args = blob \"DIDL\00\00\"; cycles = (0:nat64)})" - assert_eq '(variant { 17_724 = record { 153_986_224 = blob "DIDL\00\01~\01" } })' # True in DIDL. + assert_eq '(variant { 17_724 = record { 153_986_224 = blob "\44\49\44\4c\00\01\7e\01" } })' # True in DIDL. } @test "a 64-bit wallet can still be called in the 128-bit context" { diff --git a/src/canisters/frontend/ic-asset/src/sync.rs b/src/canisters/frontend/ic-asset/src/sync.rs index e892225c8a..b927d1513e 100644 --- a/src/canisters/frontend/ic-asset/src/sync.rs +++ b/src/canisters/frontend/ic-asset/src/sync.rs @@ -138,7 +138,7 @@ async fn commit_in_stages( commit_batch( canister, CommitBatchArguments { - batch_id: Nat::from(0), + batch_id: Nat::from(0_u8), operations: operations.into(), }, ) @@ -156,7 +156,7 @@ async fn commit_in_stages( commit_batch( canister, CommitBatchArguments { - batch_id: Nat::from(0), + batch_id: Nat::from(0_u8), operations: operations.into(), }, ) diff --git a/src/canisters/frontend/ic-certified-assets/Cargo.toml b/src/canisters/frontend/ic-certified-assets/Cargo.toml index 0aa6639bbc..4a96baca33 100644 --- a/src/canisters/frontend/ic-certified-assets/Cargo.toml +++ b/src/canisters/frontend/ic-certified-assets/Cargo.toml @@ -27,5 +27,6 @@ serde_cbor.workspace = true sha2.workspace = true [dev-dependencies] +candid_parser.workspace = true ic-response-verification-test-utils = { git = "https://github.com/dfinity/response-verification.git", rev = "4686895c6070ac36109a01f4bd642caf2369b97b" } ic-crypto-tree-hash = { git = "https://github.com/dfinity/ic.git", rev = "a533346f63f4091eb64692891de0d5b2ffd5b22a" } diff --git a/src/canisters/frontend/ic-certified-assets/src/lib.rs b/src/canisters/frontend/ic-certified-assets/src/lib.rs index 336a0106a9..087f81bc59 100644 --- a/src/canisters/frontend/ic-certified-assets/src/lib.rs +++ b/src/canisters/frontend/ic-certified-assets/src/lib.rs @@ -445,7 +445,7 @@ pub fn post_upgrade(stable_state: StableState, args: Option) #[test] fn candid_interface_compatibility() { - use candid::utils::{service_compatible, CandidSource}; + use candid_parser::utils::{service_compatible, CandidSource}; use std::path::PathBuf; candid::export_service!(); diff --git a/src/canisters/frontend/ic-certified-assets/src/state_machine.rs b/src/canisters/frontend/ic-certified-assets/src/state_machine.rs index 3a41f358a6..01d8d36e8e 100644 --- a/src/canisters/frontend/ic-certified-assets/src/state_machine.rs +++ b/src/canisters/frontend/ic-certified-assets/src/state_machine.rs @@ -472,8 +472,8 @@ impl State { self.assets.clear(); self.batches.clear(); self.chunks.clear(); - self.next_batch_id = Nat::from(1); - self.next_chunk_id = Nat::from(1); + self.next_batch_id = Nat::from(1_u8); + self.next_chunk_id = Nat::from(1_u8); } pub fn has_permission(&self, principal: &Principal, permission: &Permission) -> bool { @@ -566,7 +566,7 @@ impl State { } } let batch_id = self.next_batch_id.clone(); - self.next_batch_id += 1; + self.next_batch_id += 1_u8; self.batches.insert( batch_id.clone(), @@ -607,7 +607,7 @@ impl State { batch.expires_at = Int::from(now + BATCH_EXPIRY_NANOS); let chunk_id = self.next_chunk_id.clone(); - self.next_chunk_id += 1; + self.next_chunk_id += 1_u8; batch.chunk_content_total_size += arg.content.as_ref().len(); self.chunks.insert( @@ -1093,7 +1093,9 @@ impl From for State { prepare_principals, manage_permissions_principals, assets: stable_state.stable_assets, - next_batch_id: stable_state.next_batch_id.unwrap_or_else(|| Nat::from(1)), + next_batch_id: stable_state + .next_batch_id + .unwrap_or_else(|| Nat::from(1_u8)), configuration: stable_state.configuration.unwrap_or_default(), ..Self::default() }; diff --git a/src/canisters/frontend/ic-certified-assets/src/tests.rs b/src/canisters/frontend/ic-certified-assets/src/tests.rs index 88fb797277..7e77c6c9aa 100644 --- a/src/canisters/frontend/ic-certified-assets/src/tests.rs +++ b/src/canisters/frontend/ic-certified-assets/src/tests.rs @@ -962,7 +962,7 @@ fn uses_streaming_for_multichunk_assets() { .http_request_streaming_callback(StreamingCallbackToken { key: "/index.html".to_string(), content_encoding: "identity".to_string(), - index: Nat::from(1), + index: Nat::from(1_u8), sha256: None, }) .unwrap_err(), @@ -1005,7 +1005,7 @@ fn get_and_get_chunk_for_multichunk_assets() { .get_chunk(GetChunkArg { key: "/index.html".to_string(), content_encoding: "identity".to_string(), - index: Nat::from(1), + index: Nat::from(1_u8), sha256: chunk_0.sha256, }) .unwrap(); @@ -1017,7 +1017,7 @@ fn get_and_get_chunk_for_multichunk_assets() { .get_chunk(GetChunkArg { key: "/index.html".to_string(), content_encoding: "identity".to_string(), - index: Nat::from(1), + index: Nat::from(1_u8), sha256: None, }) .unwrap_err(), @@ -3347,7 +3347,7 @@ mod validate_commit_proposed_batch { let time_now = 100_000_000_000; match state.validate_commit_proposed_batch(CommitProposedBatchArguments { - batch_id: 1.into(), + batch_id: 1_u8.into(), evidence: Default::default(), }) { Err(err) if err.contains("batch not found") => (), @@ -3356,7 +3356,7 @@ mod validate_commit_proposed_batch { match state.commit_proposed_batch( CommitProposedBatchArguments { - batch_id: 1.into(), + batch_id: 1_u8.into(), evidence: Default::default(), }, time_now, diff --git a/src/canisters/frontend/ic-frontend-canister/Cargo.toml b/src/canisters/frontend/ic-frontend-canister/Cargo.toml index 5947ab793d..cc1119adac 100644 --- a/src/canisters/frontend/ic-frontend-canister/Cargo.toml +++ b/src/canisters/frontend/ic-frontend-canister/Cargo.toml @@ -16,3 +16,4 @@ crate-type = ["cdylib"] [dependencies] ic-certified-assets = { path = "../ic-certified-assets" } ic-cdk.workspace = true +candid.workspace = true diff --git a/src/dfx-core/Cargo.toml b/src/dfx-core/Cargo.toml index c55966067d..01b37aca02 100644 --- a/src/dfx-core/Cargo.toml +++ b/src/dfx-core/Cargo.toml @@ -13,7 +13,8 @@ argon2.workspace = true bip32 = "0.4.0" byte-unit = { workspace = true, features = ["serde"] } bytes.workspace = true -candid = { workspace = true, features = ["random"] } +candid = { workspace = true } +candid_parser = { workspace = true, features = ["random"] } clap = { workspace = true, features = ["string"] } dialoguer = "0.10.0" directories-next.workspace = true diff --git a/src/dfx-core/src/config/model/local_server_descriptor.rs b/src/dfx-core/src/config/model/local_server_descriptor.rs index 6d59829cfa..871da03dc7 100644 --- a/src/dfx-core/src/config/model/local_server_descriptor.rs +++ b/src/dfx-core/src/config/model/local_server_descriptor.rs @@ -98,11 +98,6 @@ impl LocalServerDescriptor { self.data_directory.join("icx-proxy-pid") } - /// This file contains the listening port of the ic-ref process - pub fn ic_ref_port_path(&self) -> PathBuf { - self.data_directory.join("ic-ref.port") - } - /// This file contains the pid of the ic-btc-adapter process pub fn btc_adapter_pid_path(&self) -> PathBuf { self.data_directory.join("ic-btc-adapter-pid") @@ -297,12 +292,11 @@ impl LocalServerDescriptor { /// Gets the port of a local replica. /// /// # Prerequisites - /// - A local replica or emulator needs to be running, e.g. with `dfx start`. + /// - A local replica needs to be running, e.g. with `dfx start`. pub fn get_running_replica_port( &self, logger: Option<&Logger>, ) -> Result, NetworkConfigError> { - let emulator_port_path = self.ic_ref_port_path(); let replica_port_path = self.replica_port_path(); match read_port_from(&replica_port_path)? { @@ -312,15 +306,7 @@ impl LocalServerDescriptor { } Ok(Some(port)) } - None => match read_port_from(&emulator_port_path)? { - Some(port) => { - if let Some(logger) = logger { - info!(logger, "Found local emulator running on port {}", port); - } - Ok(Some(port)) - } - None => Ok(self.replica.port), - }, + None => Ok(self.replica.port), } } } diff --git a/src/dfx-core/src/identity/pem_safekeeping.rs b/src/dfx-core/src/identity/pem_safekeeping.rs index ca520114a5..baa5f10b59 100644 --- a/src/dfx-core/src/identity/pem_safekeeping.rs +++ b/src/dfx-core/src/identity/pem_safekeeping.rs @@ -20,7 +20,7 @@ use crate::error::identity::write_pem_to_file::WritePemToFileError::{ use crate::identity::identity_file_locations::IdentityFileLocations; use crate::identity::keyring_mock; use crate::identity::pem_safekeeping::PromptMode::{DecryptingToUse, EncryptingToCreate}; -use aes_gcm::aead::{Aead, NewAead}; +use aes_gcm::aead::{Aead, KeyInit}; use aes_gcm::{Aes256Gcm, Key, Nonce}; use argon2::{password_hash::PasswordHasher, Argon2}; use slog::{debug, trace, Logger}; @@ -201,7 +201,7 @@ fn encrypt( let hash = argon2 .hash_password(password.as_bytes(), &config.pw_salt) .map_err(EncryptionError::HashPasswordFailed)?; - let key = Key::clone_from_slice(hash.hash.unwrap().as_ref()); + let key = Key::::clone_from_slice(hash.hash.unwrap().as_ref()); let cipher = Aes256Gcm::new(&key); let nonce = Nonce::from_slice(config.file_nonce.as_slice()); @@ -225,7 +225,7 @@ fn decrypt( let hash = argon2 .hash_password(password.as_bytes(), &config.pw_salt) .map_err(HashPasswordFailed)?; - let key = Key::clone_from_slice(hash.hash.unwrap().as_ref()); + let key = Key::::clone_from_slice(hash.hash.unwrap().as_ref()); let cipher = Aes256Gcm::new(&key); let nonce = Nonce::from_slice(config.file_nonce.as_slice()); diff --git a/src/dfx/Cargo.toml b/src/dfx/Cargo.toml index 9626792d0d..5927305ff4 100644 --- a/src/dfx/Cargo.toml +++ b/src/dfx/Cargo.toml @@ -34,12 +34,12 @@ anstyle.workspace = true anyhow.workspace = true apply-patch.path = "../lib/apply-patch" argon2.workspace = true -atty = "0.2.13" backoff.workspace = true base64.workspace = true byte-unit = { workspace = true, features = ["serde"] } bytes.workspace = true -candid = { workspace = true, features = ["random"] } +candid = { workspace = true } +candid_parser = { workspace = true, features = ["random"] } clap = { workspace = true, features = [ "derive", "env", @@ -66,8 +66,8 @@ ic-asset.workspace = true ic-cdk.workspace = true ic-identity-hsm = { workspace = true } ic-utils = { workspace = true } -ic-wasm = "0.4.0" -icrc-ledger-types = "0.1.1" +ic-wasm = "0.7.0" +icrc-ledger-types = "0.1.5" indicatif = "0.16.0" itertools.workspace = true json-patch = "1.0.0" @@ -104,7 +104,7 @@ shell-words = "1.1.0" slog = { workspace = true, features = ["max_level_trace"] } slog-async.workspace = true slog-term.workspace = true -supports-color = "1.3.0" +supports-color = "2.1.0" sysinfo = "0.28.4" tar.workspace = true tempfile.workspace = true diff --git a/src/dfx/src/actors/emulator.rs b/src/dfx/src/actors/emulator.rs deleted file mode 100644 index 241ad760d2..0000000000 --- a/src/dfx/src/actors/emulator.rs +++ /dev/null @@ -1,245 +0,0 @@ -use crate::actors::icx_proxy::signals::{PortReadySignal, PortReadySubscribe}; -use crate::actors::shutdown::{wait_for_child_or_receiver, ChildOrReceiver}; -use crate::actors::shutdown_controller::signals::outbound::Shutdown; -use crate::actors::shutdown_controller::signals::ShutdownSubscribe; -use crate::actors::shutdown_controller::ShutdownController; -use crate::lib::error::{DfxError, DfxResult}; -use actix::{ - Actor, ActorContext, ActorFutureExt, Addr, AsyncContext, Context, Handler, Recipient, - ResponseActFuture, Running, WrapFuture, -}; -use anyhow::bail; -use crossbeam::channel::{unbounded, Receiver, Sender}; -use slog::{debug, info, Logger}; -use std::path::{Path, PathBuf}; -use std::thread::JoinHandle; -use std::time::Duration; - -pub mod signals { - use actix::prelude::*; - - /// A message sent to the Emulator when the process is restarted. Since we're - /// restarting inside our own actor, this message should not be exposed. - #[derive(Message)] - #[rtype(result = "()")] - pub(super) struct EmulatorRestarted { - pub port: u16, - } -} - -/// The configuration for the emulator actor. -#[derive(Clone)] -pub struct Config { - pub ic_ref_path: PathBuf, - pub port: Option, - pub write_port_to: PathBuf, - pub shutdown_controller: Addr, - pub logger: Option, -} - -/// A emulator actor. Starts the emulator, can subscribe to a Ready signal and a -/// Killed signal. -/// This starts a thread that monitors the process and send signals to any subscriber -/// listening for restarts. The message contains the port the emulator is listening to. -/// -/// Signals -/// - PortReadySubscribe -/// Subscribe a recipient (address) to receive a EmulatorReadySignal message when -/// the emulator is ready to listen to a port. The message can be sent multiple -/// times (e.g. if the emulator crashes). -/// If a emulator is already started and another actor sends this message, a -/// EmulatorReadySignal will be sent free of charge in the same thread. -pub struct Emulator { - logger: Logger, - config: Config, - - // We keep the port to send to subscribers on subscription. - port: Option, - stop_sender: Option>, - thread_join: Option>, - - /// Ready Signal subscribers. - ready_subscribers: Vec>, -} - -impl Emulator { - pub fn new(config: Config) -> Self { - let logger = - (config.logger.clone()).unwrap_or_else(|| Logger::root(slog::Discard, slog::o!())); - Emulator { - config, - port: None, - stop_sender: None, - thread_join: None, - ready_subscribers: Vec::new(), - logger, - } - } - - fn wait_for_port_file(file_path: &Path) -> DfxResult { - let mut retries = 0; - loop { - if let Ok(content) = std::fs::read_to_string(file_path) { - if let Ok(port) = content.parse::() { - return Ok(port); - } - } - if retries >= 3000 { - bail!("Cannot start ic-ref: timed out"); - } - std::thread::sleep(Duration::from_millis(100)); - retries += 1; - } - } - - fn start_emulator(&mut self, addr: Addr) -> DfxResult { - let logger = self.logger.clone(); - - let (sender, receiver) = unbounded(); - - let handle = anyhow::Context::context( - emulator_start_thread(logger, self.config.clone(), addr, receiver), - "Failed to start emulator thread.", - )?; - - self.thread_join = Some(handle); - self.stop_sender = Some(sender); - Ok(()) - } - - fn send_ready_signal(&self, port: u16) { - for sub in &self.ready_subscribers { - sub.do_send(PortReadySignal { port }); - } - } -} - -impl Actor for Emulator { - type Context = Context; - - fn started(&mut self, ctx: &mut Self::Context) { - self.start_emulator(ctx.address()) - .expect("Could not start the emulator"); - - self.config - .shutdown_controller - .do_send(ShutdownSubscribe(ctx.address().recipient::())); - } - - fn stopping(&mut self, _ctx: &mut Self::Context) -> Running { - info!(self.logger, "Stopping ic-ref..."); - if let Some(sender) = self.stop_sender.take() { - let _ = sender.send(()); - } - - if let Some(join) = self.thread_join.take() { - let _ = join.join(); - } - - info!(self.logger, "Stopped."); - Running::Stop - } -} - -impl Handler for Emulator { - type Result = (); - - fn handle(&mut self, msg: PortReadySubscribe, _: &mut Self::Context) { - // If we have a port, send that we're already ready! Yeah! - if let Some(port) = self.port { - msg.0.do_send(PortReadySignal { port }); - } - - self.ready_subscribers.push(msg.0); - } -} - -impl Handler for Emulator { - type Result = (); - - fn handle( - &mut self, - msg: signals::EmulatorRestarted, - _ctx: &mut Self::Context, - ) -> Self::Result { - self.port = Some(msg.port); - self.send_ready_signal(msg.port); - } -} - -impl Handler for Emulator { - type Result = ResponseActFuture>; - - fn handle(&mut self, _msg: Shutdown, _ctx: &mut Self::Context) -> Self::Result { - // This is just the example for ResponseActFuture but stopping the context - Box::pin( - async {} - .into_actor(self) // converts future to ActorFuture - .map(|_, _act, ctx| { - ctx.stop(); - Ok(()) - }), - ) - } -} - -fn emulator_start_thread( - logger: Logger, - config: Config, - addr: Addr, - receiver: Receiver<()>, -) -> DfxResult> { - let thread_handler = move || { - // Start the process, then wait for the file. - let ic_ref_path = config.ic_ref_path.as_os_str(); - - // form the ic-start command here similar to emulator command - let mut cmd = std::process::Command::new(ic_ref_path); - match config.port { - Some(port) if port != 0 => cmd.args(["--listen-port", &port.to_string()]), - _ => cmd.args(["--pick-port"]), - }; - cmd.args(["--write-port-to", &config.write_port_to.to_string_lossy()]); - cmd.stdout(std::process::Stdio::inherit()); - cmd.stderr(std::process::Stdio::inherit()); - - loop { - let _ = std::fs::remove_file(&config.write_port_to); - let last_start = std::time::Instant::now(); - debug!(logger, "Starting emulator..."); - let mut child = cmd.spawn().expect("Could not start emulator."); - - let port = Emulator::wait_for_port_file(&config.write_port_to).unwrap(); - addr.do_send(signals::EmulatorRestarted { port }); - - // This waits for the child to stop, or the receiver to receive a message. - // We don't restart the emulator if done = true. - match wait_for_child_or_receiver(&mut child, &receiver) { - ChildOrReceiver::Receiver => { - debug!(logger, "Got signal to stop. Killing emulator process..."); - let _ = child.kill(); - let _ = child.wait(); - break; - } - ChildOrReceiver::Child => { - debug!(logger, "Emulator process failed."); - // If it took less than two seconds to exit, wait a bit before trying again. - if std::time::Instant::now().duration_since(last_start) < Duration::from_secs(2) - { - std::thread::sleep(Duration::from_secs(2)); - } else { - debug!( - logger, - "Last emulator seemed to have been healthy, not waiting..." - ); - } - } - } - } - }; - - std::thread::Builder::new() - .name("emulator-actor".to_owned()) - .spawn(thread_handler) - .map_err(DfxError::from) -} diff --git a/src/dfx/src/actors/mod.rs b/src/dfx/src/actors/mod.rs index ea3d5675c9..0d32bc0e55 100644 --- a/src/dfx/src/actors/mod.rs +++ b/src/dfx/src/actors/mod.rs @@ -1,9 +1,7 @@ -use crate::actors; use crate::actors::btc_adapter::signals::BtcAdapterReadySubscribe; use crate::actors::btc_adapter::BtcAdapter; use crate::actors::canister_http_adapter::signals::CanisterHttpAdapterReadySubscribe; use crate::actors::canister_http_adapter::CanisterHttpAdapter; -use crate::actors::emulator::Emulator; use crate::actors::icx_proxy::signals::PortReadySubscribe; use crate::actors::icx_proxy::{IcxProxy, IcxProxyConfig}; use crate::actors::replica::{BitcoinIntegrationConfig, Replica}; @@ -20,7 +18,6 @@ use std::path::PathBuf; pub mod btc_adapter; pub mod canister_http_adapter; -pub mod emulator; pub mod icx_proxy; pub mod replica; mod shutdown; @@ -82,36 +79,6 @@ pub fn start_canister_http_adapter_actor( Ok(CanisterHttpAdapter::new(actor_config).start().recipient()) } -#[context("Failed to start emulator actor.")] -pub fn start_emulator_actor( - env: &dyn Environment, - local_server_descriptor: &LocalServerDescriptor, - shutdown_controller: Addr, - emulator_port_path: PathBuf, -) -> DfxResult> { - let ic_ref_path = env.get_cache().get_binary_command_path("ic-ref")?; - - // Touch the port file. This ensures it is empty prior to - // handing it over to ic-ref. If we read the file and it has - // contents we shall assume it is due to our spawned ic-ref - // process. - std::fs::write(&emulator_port_path, "").with_context(|| { - format!( - "Failed to write/clear emulator port file {}.", - emulator_port_path.to_string_lossy() - ) - })?; - - let actor_config = actors::emulator::Config { - ic_ref_path, - port: local_server_descriptor.replica.port, - write_port_to: emulator_port_path, - shutdown_controller, - logger: Some(env.get_logger().clone()), - }; - Ok(actors::emulator::Emulator::new(actor_config).start()) -} - #[context("Failed to setup replica environment.")] fn setup_replica_env( local_server_descriptor: &LocalServerDescriptor, diff --git a/src/dfx/src/actors/shutdown.rs b/src/dfx/src/actors/shutdown.rs index 9610c36c83..b33668114d 100644 --- a/src/dfx/src/actors/shutdown.rs +++ b/src/dfx/src/actors/shutdown.rs @@ -17,7 +17,7 @@ pub fn wait_for_child_or_receiver( loop { // Check if either the child exited or a shutdown has been requested. // These can happen in either order in response to Ctrl-C, so increase the chance - // to notice a shutdown request even if the emulator exited quickly. + // to notice a shutdown request even if the replica exited quickly. let child_try_wait = child.try_wait(); let receiver_signalled = receiver.recv_timeout(std::time::Duration::from_millis(100)); diff --git a/src/dfx/src/commands/canister/delete.rs b/src/dfx/src/commands/canister/delete.rs index cb29aff404..af19f9937c 100644 --- a/src/dfx/src/commands/canister/delete.rs +++ b/src/dfx/src/commands/canister/delete.rs @@ -7,10 +7,14 @@ use crate::lib::operations::canister; use crate::lib::operations::canister::{ deposit_cycles, start_canister, stop_canister, update_settings, }; +use crate::lib::operations::cycles_ledger::{ + wallet_deposit_to_cycles_ledger, CYCLES_LEDGER_ENABLED, +}; use crate::lib::root_key::fetch_root_key_if_needed; use crate::util::assets::wallet_wasm; use crate::util::blob_from_arguments; -use anyhow::Context; +use crate::util::clap::parsers::icrc_subaccount_parser; +use anyhow::{bail, Context}; use candid::Principal; use clap::Parser; use dfx_core::canister::build_wallet_canister; @@ -23,6 +27,7 @@ use ic_utils::interfaces::management_canister::builders::InstallMode; use ic_utils::interfaces::management_canister::CanisterStatus; use ic_utils::interfaces::ManagementCanister; use ic_utils::Argument; +use icrc_ledger_types::icrc1::account::{Account, Subaccount}; use num_traits::cast::ToPrimitive; use slog::info; use std::convert::TryFrom; @@ -71,6 +76,11 @@ pub struct CanisterDeleteOpts { /// Auto-confirm deletion for a non-stopped canister. #[arg(long, short)] yes: bool, + + /// Subaccount of the selected identity to deposit cycles to. + //TODO(SDK-1331): unhide + #[arg(long, value_parser = icrc_subaccount_parser, hide = true)] + to_subaccount: Option, } #[context("Failed to delete canister '{}'.", canister)] @@ -83,6 +93,7 @@ async fn delete_canister( withdraw_cycles_to_canister: Option, withdraw_cycles_to_dank: bool, withdraw_cycles_to_dank_principal: Option, + to_cycles_ledger_subaccount: Option, ) -> DfxResult { let log = env.get_logger(); let mut canister_id_store = env.get_canister_id_store()?; @@ -99,19 +110,23 @@ async fn delete_canister( let to_dank = withdraw_cycles_to_dank || withdraw_cycles_to_dank_principal.is_some(); // Get the canister to transfer the cycles to. - let target_canister_id = if no_withdrawal { - None + let withdraw_target = if no_withdrawal { + WithdrawTarget::NoWithdrawal } else if to_dank { - Some(DANK_PRINCIPAL) + WithdrawTarget::Dank } else { match withdraw_cycles_to_canister { Some(ref target_canister_id) => { - Some(Principal::from_text(target_canister_id).with_context(|| { - format!("Failed to read canister id {:?}.", target_canister_id) - })?) + let canister_id = + Principal::from_text(target_canister_id).with_context(|| { + format!("Failed to read canister id {:?}.", target_canister_id) + })?; + WithdrawTarget::Canister { canister_id } } None => match call_sender { - CallSender::Wallet(wallet_id) => Some(*wallet_id), + CallSender::Wallet(wallet_id) => WithdrawTarget::Canister { + canister_id: *wallet_id, + }, CallSender::SelectedId => { let network = env.get_network_descriptor(); let agent_env = create_agent_environment(env, Some(network.name.clone()))?; @@ -120,7 +135,19 @@ async fn delete_canister( .expect("No selected identity.") .to_string(); // If there is no wallet, then do not attempt to withdraw the cycles. - wallet_canister_id(network, &identity_name)? + match wallet_canister_id(network, &identity_name)? { + Some(canister_id) => WithdrawTarget::Canister { canister_id }, + None if CYCLES_LEDGER_ENABLED => { + let Some(my_principal) = env.get_selected_identity_principal() else { bail!("Identity has no principal attached") }; + WithdrawTarget::CyclesLedger { + to: Account { + owner: my_principal, + subaccount: to_cycles_ledger_subaccount, + }, + } + } + _ => WithdrawTarget::NoWithdrawal, + } } }, } @@ -135,11 +162,10 @@ async fn delete_canister( }; fetch_root_key_if_needed(env).await?; - if let Some(target_canister_id) = target_canister_id { + if withdraw_target != WithdrawTarget::NoWithdrawal { info!( log, - "Beginning withdrawal of cycles to canister {}; on failure try --no-wallet --no-withdrawal.", - target_canister_id + "Beginning withdrawal of cycles; on failure try --no-wallet --no-withdrawal." ); // Determine how many cycles we can withdraw. @@ -197,40 +223,55 @@ async fn delete_canister( break; } let cycles_to_withdraw = cycles - margin; - let result = if !to_dank { - info!( - log, - "Attempting to transfer {} cycles to canister {}.", - cycles_to_withdraw, - target_canister_id - ); - // Transfer cycles from the source canister to the target canister using the temporary wallet. - deposit_cycles( - env, - target_canister_id, - &CallSender::Wallet(canister_id), - cycles_to_withdraw, - ) - .await - } else { - info!( - log, - "Attempting to transfer {} cycles to dank principal {}.", - cycles_to_withdraw, - dank_target_principal - ); - let wallet = build_wallet_canister(canister_id, agent).await?; - let opt_principal = Some(dank_target_principal); - wallet - .call( + let result = match withdraw_target { + WithdrawTarget::NoWithdrawal => Ok(()), + WithdrawTarget::Dank => { + info!( + log, + "Attempting to transfer {} cycles to dank principal {}.", + cycles_to_withdraw, + dank_target_principal + ); + let wallet = build_wallet_canister(canister_id, agent).await?; + let opt_principal = Some(dank_target_principal); + wallet + .call( + DANK_PRINCIPAL, + "mint", + Argument::from_candid((opt_principal,)), + cycles_to_withdraw, + ) + .call_and_wait() + .await + .context("Failed mint call.") + } + WithdrawTarget::Canister { + canister_id: target_canister_id, + } => { + info!( + log, + "Attempting to transfer {} cycles to canister {}.", + cycles_to_withdraw, + target_canister_id + ); + // Transfer cycles from the source canister to the target canister using the temporary wallet. + deposit_cycles( + env, target_canister_id, - "mint", - Argument::from_candid((opt_principal,)), + &CallSender::Wallet(canister_id), cycles_to_withdraw, ) - .call_and_wait() .await - .context("Failed mint call.") + } + WithdrawTarget::CyclesLedger { to } => { + wallet_deposit_to_cycles_ledger( + agent, + canister_id, + cycles_to_withdraw, + to, + ) + .await + } }; if result.is_ok() { info!(log, "Successfully withdrew {} cycles.", cycles_to_withdraw); @@ -239,7 +280,7 @@ async fn delete_canister( info!(log, "Not enough margin. Trying again with more margin."); attempts += 1; } else { - // Unforseen error. Report it back to user + // Unforeseen error. Report it back to user result?; } } @@ -293,6 +334,7 @@ pub async fn exec( opts.withdraw_cycles_to_canister, opts.withdraw_cycles_to_dank, opts.withdraw_cycles_to_dank_principal, + opts.to_subaccount, ) .await } else if opts.all { @@ -307,6 +349,7 @@ pub async fn exec( opts.withdraw_cycles_to_canister.clone(), opts.withdraw_cycles_to_dank, opts.withdraw_cycles_to_dank_principal.clone(), + opts.to_subaccount, ) .await?; } @@ -316,3 +359,11 @@ pub async fn exec( unreachable!() } } + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +enum WithdrawTarget { + NoWithdrawal, + Dank, + CyclesLedger { to: Account }, + Canister { canister_id: Principal }, +} diff --git a/src/dfx/src/commands/deps/init.rs b/src/dfx/src/commands/deps/init.rs index 0de294a203..05e0b81172 100644 --- a/src/dfx/src/commands/deps/init.rs +++ b/src/dfx/src/commands/deps/init.rs @@ -7,8 +7,8 @@ use crate::lib::environment::Environment; use crate::lib::error::DfxResult; use crate::util::{check_candid_file, fuzzy_parse_argument}; use anyhow::{anyhow, bail}; -use candid::parser::types::IDLTypes; use candid::Principal; +use candid_parser::{types::IDLTypes, typing::ast_to_type}; use clap::Parser; use slog::{info, warn, Logger}; @@ -73,7 +73,7 @@ fn set_init( let candid_args_idl_types: IDLTypes = candid_args.parse()?; let mut types = vec![]; for ty in candid_args_idl_types.args.iter() { - types.push(env.ast_to_type(ty)?); + types.push(ast_to_type(&env, ty)?); } let arguments = opts.argument.as_deref(); diff --git a/src/dfx/src/commands/language_service.rs b/src/dfx/src/commands/language_service.rs index ed927f5040..fe25382a55 100644 --- a/src/dfx/src/commands/language_service.rs +++ b/src/dfx/src/commands/language_service.rs @@ -12,6 +12,7 @@ use dfx_core::config::model::dfinity::{ }; use dfx_core::network::provider::{create_network_descriptor, LocalBindDetermination}; use fn_error_context::context; +use std::io::{stdout, IsTerminal}; use std::path::PathBuf; use std::process::Stdio; @@ -36,7 +37,7 @@ pub struct LanguageServiceOpts { pub fn exec(env: &dyn Environment, opts: LanguageServiceOpts) -> DfxResult { let force_tty = opts.force_tty; // Are we being run from a terminal? That's most likely not what we want - if atty::is(atty::Stream::Stdout) && !force_tty { + if stdout().is_terminal() && !force_tty { Err(anyhow!("The `_language-service` command is meant to be run by editors to start a language service. You probably don't want to run it from a terminal.\nIf you _really_ want to, you can pass the --force-tty flag.")) } else if let Some(config) = env.get_config() { let main_path = get_main_path(config.get_config(), opts.canister)?; diff --git a/src/dfx/src/commands/remote/generate_binding.rs b/src/dfx/src/commands/remote/generate_binding.rs index 6cc835c9a7..947b5b852a 100644 --- a/src/dfx/src/commands/remote/generate_binding.rs +++ b/src/dfx/src/commands/remote/generate_binding.rs @@ -73,16 +73,22 @@ pub fn exec(env: &dyn Environment, opts: GenerateBindingOpts) -> DfxResult { let (type_env, did_types) = check_candid_file(&candid)?; let extension = main.extension().unwrap_or_default(); let bindings = if extension == "mo" { - Some(candid::bindings::motoko::compile(&type_env, &did_types)) + Some(candid_parser::bindings::motoko::compile( + &type_env, &did_types, + )) } else if extension == "rs" { - let config = candid::bindings::rust::Config::new(); - Some(candid::bindings::rust::compile( + let config = candid_parser::bindings::rust::Config::new(); + Some(candid_parser::bindings::rust::compile( &config, &type_env, &did_types, )) } else if extension == "js" { - Some(candid::bindings::javascript::compile(&type_env, &did_types)) + Some(candid_parser::bindings::javascript::compile( + &type_env, &did_types, + )) } else if extension == "ts" { - Some(candid::bindings::typescript::compile(&type_env, &did_types)) + Some(candid_parser::bindings::typescript::compile( + &type_env, &did_types, + )) } else { info!( log, diff --git a/src/dfx/src/commands/start.rs b/src/dfx/src/commands/start.rs index 1fdcd36230..3f0fb5c907 100644 --- a/src/dfx/src/commands/start.rs +++ b/src/dfx/src/commands/start.rs @@ -1,8 +1,8 @@ use crate::actors::icx_proxy::signals::PortReadySubscribe; use crate::actors::icx_proxy::IcxProxyConfig; use crate::actors::{ - start_btc_adapter_actor, start_canister_http_adapter_actor, start_emulator_actor, - start_icx_proxy_actor, start_replica_actor, start_shutdown_controller, + start_btc_adapter_actor, start_canister_http_adapter_actor, start_icx_proxy_actor, + start_replica_actor, start_shutdown_controller, }; use crate::config::dfx_version_str; use crate::error_invalid_argument; @@ -53,24 +53,20 @@ pub struct StartOpts { #[arg(long)] clean: bool, - /// Runs a dedicated emulator instead of the replica - #[arg(long)] - emulator: bool, - /// Address of bitcoind node. Implies --enable-bitcoin. - #[arg(long, conflicts_with("emulator"), action = ArgAction::Append)] + #[arg(long, action = ArgAction::Append)] bitcoin_node: Vec, /// enable bitcoin integration - #[arg(long, conflicts_with("emulator"))] + #[arg(long)] enable_bitcoin: bool, /// enable canister http requests - #[arg(long, conflicts_with("emulator"))] + #[arg(long)] enable_canister_http: bool, /// The delay (in milliseconds) an update call should take. Lower values may be expedient in CI. - #[arg(long, conflicts_with("emulator"), default_value_t = 600)] + #[arg(long, default_value_t = 600)] artificial_delay: u32, /// Start even if the network config was modified. @@ -142,7 +138,6 @@ pub fn exec( StartOpts { host, background, - emulator, clean, force, bitcoin_node, @@ -183,7 +178,6 @@ pub fn exec( enable_bitcoin, bitcoin_node, enable_canister_http, - emulator, domain, )?; @@ -244,7 +238,6 @@ pub fn exec( })?; let replica_port_path = empty_writable_path(local_server_descriptor.replica_port_path())?; - let emulator_port_path = empty_writable_path(local_server_descriptor.ic_ref_port_path())?; if background { send_background()?; @@ -328,11 +321,8 @@ pub fn exec( replica_config }; - let effective_config = if emulator { - CachedConfig::emulator() - } else { - CachedConfig::replica(&replica_config) - }; + let effective_config = CachedConfig::replica(&replica_config); + if !clean && !force && previous_config_path.exists() { let previous_config = load_json_file(&previous_config_path) .context("Failed to read replica configuration. Rerun with `--clean`.")?; @@ -349,15 +339,7 @@ pub fn exec( let _proxy = system.block_on(async move { let shutdown_controller = start_shutdown_controller(env)?; - let port_ready_subscribe: Recipient = if emulator { - let emulator = start_emulator_actor( - env, - local_server_descriptor, - shutdown_controller.clone(), - emulator_port_path, - )?; - emulator.recipient() - } else { + let port_ready_subscribe: Recipient = { let btc_adapter_ready_subscribe = btc_adapter_config .map(|btc_adapter_config| { start_btc_adapter_actor( @@ -426,7 +408,6 @@ pub fn exec( #[allow(clippy::large_enum_variant)] pub enum CachedReplicaConfig<'a> { Replica { config: Cow<'a, ReplicaConfig> }, - Emulator, } #[derive(Serialize, Deserialize, PartialEq, Eq)] @@ -445,12 +426,6 @@ impl<'a> CachedConfig<'a> { }, } } - pub fn emulator() -> Self { - Self { - replica_rev: replica_rev().into(), - config: CachedReplicaConfig::Emulator, - } - } } pub fn apply_command_line_parameters( @@ -461,7 +436,6 @@ pub fn apply_command_line_parameters( enable_bitcoin: bool, bitcoin_nodes: Vec, enable_canister_http: bool, - emulator: bool, domain: Vec, ) -> DfxResult { if enable_canister_http { @@ -472,13 +446,6 @@ pub fn apply_command_line_parameters( warn!(logger, "Canister HTTP suppport is enabled by default. It can be disabled through dfx.json or networks.json."); } - if emulator { - warn!( - logger, - "The --emulator parameter is deprecated and will be discontinued soon." - ); - } - let _ = network_descriptor.local_server_descriptor()?; let mut local_server_descriptor = network_descriptor.local_server_descriptor.unwrap(); diff --git a/src/dfx/src/config/cache.rs b/src/dfx/src/config/cache.rs index 9ab80c47dd..7491d8e701 100644 --- a/src/dfx/src/config/cache.rs +++ b/src/dfx/src/config/cache.rs @@ -11,6 +11,7 @@ use indicatif::{ProgressBar, ProgressDrawTarget}; use rand::distributions::Alphanumeric; use rand::{thread_rng, Rng}; use semver::Version; +use std::io::{stderr, IsTerminal}; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; @@ -77,7 +78,7 @@ pub fn install_version(v: &str, force: bool) -> Result { // expensive step, and if this fails we can't continue anyway. let current_exe = dfx_core::foundation::get_current_exe()?; - let b: Option = if atty::is(atty::Stream::Stderr) { + let b: Option = if stderr().is_terminal() { let b = ProgressBar::new_spinner(); b.set_draw_target(ProgressDrawTarget::stderr()); b.set_message(format!("Installing version {} of dfx...", v)); diff --git a/src/dfx/src/lib/builders/mod.rs b/src/dfx/src/lib/builders/mod.rs index 1fe50f1cef..88b95e9abc 100644 --- a/src/dfx/src/lib/builders/mod.rs +++ b/src/dfx/src/lib/builders/mod.rs @@ -157,7 +157,8 @@ pub trait CanisterBuilder { let output_did_ts_path = generate_output_dir .join(info.get_name()) .with_extension("did.d.ts"); - let content = ensure_trailing_newline(candid::bindings::typescript::compile(&env, &ty)); + let content = + ensure_trailing_newline(candid_parser::bindings::typescript::compile(&env, &ty)); std::fs::write(&output_did_ts_path, content).with_context(|| { format!( "Failed to write to {}.", @@ -175,7 +176,8 @@ pub trait CanisterBuilder { let output_did_js_path = generate_output_dir .join(info.get_name()) .with_extension("did.js"); - let content = ensure_trailing_newline(candid::bindings::javascript::compile(&env, &ty)); + let content = + ensure_trailing_newline(candid_parser::bindings::javascript::compile(&env, &ty)); std::fs::write(&output_did_js_path, content).with_context(|| { format!( "Failed to write to {}.", @@ -192,7 +194,8 @@ pub trait CanisterBuilder { let output_mo_path = generate_output_dir .join(info.get_name()) .with_extension("mo"); - let content = ensure_trailing_newline(candid::bindings::motoko::compile(&env, &ty)); + let content = + ensure_trailing_newline(candid_parser::bindings::motoko::compile(&env, &ty)); std::fs::write(&output_mo_path, content).with_context(|| { format!("Failed to write to {}.", output_mo_path.to_string_lossy()) })?; diff --git a/src/dfx/src/lib/models/canister.rs b/src/dfx/src/lib/models/canister.rs index 3903adf513..5f435683d9 100644 --- a/src/dfx/src/lib/models/canister.rs +++ b/src/dfx/src/lib/models/canister.rs @@ -12,9 +12,12 @@ use crate::util::{assets, check_candid_file}; use anyhow::{anyhow, bail, Context}; use candid::Principal as CanisterId; use dfx_core::config::model::canister_id_store::CanisterIdStore; -use dfx_core::config::model::dfinity::{CanisterMetadataSection, Config, MetadataVisibility}; +use dfx_core::config::model::dfinity::{ + CanisterMetadataSection, Config, MetadataVisibility, WasmOptLevel, +}; use fn_error_context::context; use ic_wasm::metadata::{add_metadata, remove_metadata, Kind}; +use ic_wasm::optimize::OptLevel; use itertools::Itertools; use petgraph::graph::{DiGraph, NodeIndex}; use rand::{thread_rng, RngCore}; @@ -128,8 +131,14 @@ impl Canister { // optimize or shrink if let Some(level) = info.get_optimize() { trace!(logger, "Optimizing WASM at level {}", level); - ic_wasm::shrink::shrink_with_wasm_opt(&mut m, &level.to_string(), false) - .context("Failed to optimize the WASM module.")?; + ic_wasm::optimize::optimize( + &mut m, + &wasm_opt_level_convert(level), + false, + &None, + false, + ) + .context("Failed to optimize the WASM module.")?; modified = true; } else if info.get_shrink() == Some(true) || (info.get_shrink().is_none() && (info.is_rust() || info.is_motoko())) @@ -311,15 +320,32 @@ impl Canister { } } +fn wasm_opt_level_convert(opt_level: WasmOptLevel) -> OptLevel { + use WasmOptLevel::*; + match opt_level { + O0 => OptLevel::O0, + O1 => OptLevel::O1, + O2 => OptLevel::O2, + O3 => OptLevel::O3, + O4 => OptLevel::O4, + Os => OptLevel::Os, + Oz => OptLevel::Oz, + Size => OptLevel::Oz, + Cycles => OptLevel::O3, + } +} + fn separate_candid(path: &Path) -> DfxResult<(String, String)> { let (env, actor) = check_candid_file(path)?; let actor = actor.ok_or_else(|| anyhow!("provided candid file contains no main service"))?; if let candid::types::internal::TypeInner::Class(args, ty) = actor.as_ref() { - use candid::bindings::candid::pp_ty; - use candid::pretty::{concat, enclose}; + use candid_parser::pretty::{ + candid::{compile, pp_ty}, + utils::{concat, enclose}, + }; let actor = Some(ty.clone()); - let service_did = candid::bindings::candid::compile(&env, &actor); + let service_did = compile(&env, &actor); let doc = concat(args.iter().map(pp_ty), ","); let init_args = enclose("(", doc, ")").pretty(80).to_string(); Ok((service_did, init_args)) @@ -785,14 +811,14 @@ fn build_canister_js(canister_id: &CanisterId, canister_info: &CanisterInfo) -> .with_extension("did.d.ts"); let (env, ty) = check_candid_file(&canister_info.get_service_idl_path())?; - let content = ensure_trailing_newline(candid::bindings::javascript::compile(&env, &ty)); + let content = ensure_trailing_newline(candid_parser::bindings::javascript::compile(&env, &ty)); std::fs::write(&output_did_js_path, content).with_context(|| { format!( "Failed to write to {}.", output_did_js_path.to_string_lossy() ) })?; - let content = ensure_trailing_newline(candid::bindings::typescript::compile(&env, &ty)); + let content = ensure_trailing_newline(candid_parser::bindings::typescript::compile(&env, &ty)); std::fs::write(&output_did_ts_path, content).with_context(|| { format!( "Failed to write to {}.", diff --git a/src/dfx/src/lib/operations/canister/motoko_playground.rs b/src/dfx/src/lib/operations/canister/motoko_playground.rs index 8e8f9ea506..1d6d41db4a 100644 --- a/src/dfx/src/lib/operations/canister/motoko_playground.rs +++ b/src/dfx/src/lib/operations/canister/motoko_playground.rs @@ -193,7 +193,7 @@ fn create_nonce() -> (candid::Int, candid::Nat) { .as_nanos(); let timestamp = candid::Int::from(now); let mut rng = rand::thread_rng(); - let mut nonce = candid::Nat::from(rng.gen::()); + let mut nonce = candid::Nat::from(rng.gen::()); let prefix = format!("{}{}", POW_DOMAIN, timestamp); loop { let to_hash = format!("{}{}", prefix, nonce).replace('_', ""); @@ -201,7 +201,7 @@ fn create_nonce() -> (candid::Int, candid::Nat) { if (hash & 0xc0000000) == 0 { return (timestamp, nonce); } - nonce += 1; + nonce += 1_u8; } } diff --git a/src/dfx/src/lib/operations/cycles_ledger.rs b/src/dfx/src/lib/operations/cycles_ledger.rs index cc2cb45cce..265e476323 100644 --- a/src/dfx/src/lib/operations/cycles_ledger.rs +++ b/src/dfx/src/lib/operations/cycles_ledger.rs @@ -9,17 +9,18 @@ use crate::lib::operations::canister::create_canister::{ CANISTER_CREATE_FEE, CANISTER_INITIAL_CYCLE_BALANCE, }; use crate::lib::retryable::retryable; -use anyhow::{anyhow, bail}; +use anyhow::{anyhow, bail, Context}; use backoff::future::retry; use backoff::ExponentialBackoff; use candid::{CandidType, Decode, Encode, Nat, Principal}; +use dfx_core::canister::build_wallet_canister; use fn_error_context::context; use ic_agent::Agent; use ic_utils::call::SyncCall; use ic_utils::interfaces::management_canister::builders::CanisterSettings; -use ic_utils::Canister; +use ic_utils::{Argument, Canister}; use icrc_ledger_types::icrc1; -use icrc_ledger_types::icrc1::account::Subaccount; +use icrc_ledger_types::icrc1::account::{Account, Subaccount}; use icrc_ledger_types::icrc1::transfer::{BlockIndex, TransferError}; use serde::Deserialize; use slog::{info, Logger}; @@ -33,6 +34,7 @@ const ICRC1_BALANCE_OF_METHOD: &str = "icrc1_balance_of"; const ICRC1_TRANSFER_METHOD: &str = "icrc1_transfer"; const SEND_METHOD: &str = "send"; const CREATE_CANISTER_METHOD: &str = "create_canister"; +const CYCLES_LEDGER_DEPOSIT_METHOD: &str = "deposit"; const CYCLES_LEDGER_CANISTER_ID: Principal = Principal::from_slice(&[0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x02, 0x01, 0x01]); @@ -320,6 +322,32 @@ pub async fn create_with_cycles_ledger( } } +pub async fn wallet_deposit_to_cycles_ledger( + agent: &Agent, + wallet_id: Principal, + cycles_to_withdraw: u128, + to: Account, +) -> DfxResult { + // TODO(FI-1022): Import types from cycles ledger crate once available + #[derive(CandidType)] + pub struct DepositArg { + pub to: Account, + pub memo: Option>, + } + + build_wallet_canister(wallet_id, agent) + .await? + .call128( + CYCLES_LEDGER_CANISTER_ID, + CYCLES_LEDGER_DEPOSIT_METHOD, + Argument::from_candid((DepositArg { to, memo: None },)), + cycles_to_withdraw, + ) + .call_and_wait() + .await + .context("Failed deposit call.") +} + #[test] fn ledger_canister_id_text_representation() { assert_eq!( diff --git a/src/dfx/src/lib/replica/status.rs b/src/dfx/src/lib/replica/status.rs index 3efc7ee84f..9b896aa045 100644 --- a/src/dfx/src/lib/replica/status.rs +++ b/src/dfx/src/lib/replica/status.rs @@ -17,12 +17,7 @@ pub async fn ping_and_wait(url: &str) -> DfxResult { let status = agent.status().await; match status { Ok(status) => { - let healthy = match &status.replica_health_status { - Some(status) if status == "healthy" => true, - None => true, // emulator doesn't report replica_health_status - _ => false, - }; - if healthy { + if matches!(&status.replica_health_status, Some(status) if status == "healthy") { break; } } diff --git a/src/dfx/src/util/assets.rs b/src/dfx/src/util/assets.rs index d4a417368a..a5e87ba165 100644 --- a/src/dfx/src/util/assets.rs +++ b/src/dfx/src/util/assets.rs @@ -7,7 +7,7 @@ use std::io::Read; include!(concat!(env!("OUT_DIR"), "/load_assets.rs")); pub fn dfinity_logo() -> String { - let colors = supports_color::on(atty::Stream::Stdout); + let colors = supports_color::on(supports_color::Stream::Stdout); if let Some(colors) = colors { //Some terminals, notably MacOS's Terminal.app, do not support Truecolor (RGB-colored characters) properly. //Therefore we use xterm256 coloring when the program is running in such a terminal. diff --git a/src/dfx/src/util/mod.rs b/src/dfx/src/util/mod.rs index 98787ea76e..e0afdecea3 100644 --- a/src/dfx/src/util/mod.rs +++ b/src/dfx/src/util/mod.rs @@ -4,9 +4,10 @@ use anyhow::{bail, Context}; use backoff::backoff::Backoff; use backoff::ExponentialBackoff; use bytes::Bytes; -use candid::parser::typing::pretty_check_file; use candid::types::{value::IDLValue, Function, Type, TypeEnv, TypeInner}; use candid::IDLArgs; +use candid_parser::error::pretty_diagnose; +use candid_parser::typing::pretty_check_file; use dfx_core::fs::create_dir_all; use fn_error_context::context; #[cfg(unix)] @@ -178,7 +179,8 @@ pub fn blob_from_arguments( let typed_args = match method_type { None => { let arguments = arguments.unwrap_or("()"); - candid::pretty_parse::("Candid argument", arguments) + candid_parser::parse_idl_args(arguments) + .or_else(|e| pretty_wrap("Candid argument", arguments, e)) .map_err(|e| error_invalid_argument!("Invalid Candid values: {}", e))? .to_bytes() } @@ -208,9 +210,9 @@ pub fn blob_from_arguments( use rand::Rng; let mut rng = rand::thread_rng(); let seed: Vec = (0..2048).map(|_| rng.gen::()).collect(); - let config = candid::parser::configs::Configs::from_dhall(random) + let config = candid_parser::configs::Configs::from_dhall(random) .context("Failed to create candid parser config.")?; - let args = IDLArgs::any(&seed, &config, env, &func.args) + let args = candid_parser::random::any(&seed, &config, env, &func.args) .context("Failed to create idl args.")?; eprintln!("Sending the following random argument:\n{}\n", args); args.to_bytes_with_types(env, &func.args) @@ -235,17 +237,19 @@ pub fn fuzzy_parse_argument( let is_candid_format = first_char.map_or(false, |c| c == '('); // If parsing fails and method expects a single value, try parsing as IDLValue. // If it still fails, and method expects a text type, send arguments as text. - let args = arg_str.parse::().or_else(|_| { + let args = candid_parser::parse_idl_args(arg_str).or_else(|_| { if types.len() == 1 && !is_candid_format { let is_quote = first_char.map_or(false, |c| c == '"'); if &TypeInner::Text == types[0].as_ref() && !is_quote { Ok(IDLValue::Text(arg_str.to_string())) } else { - candid::pretty_parse::("Candid argument", arg_str) + candid_parser::parse_idl_value(arg_str) + .or_else(|e| pretty_wrap("Candid argument", arg_str, e)) } .map(|v| IDLArgs::new(&[v])) } else { - candid::pretty_parse::("Candid argument", arg_str) + candid_parser::parse_idl_args(arg_str) + .or_else(|e| pretty_wrap("Candid argument", arg_str, e)) } }); let bytes = args @@ -255,6 +259,15 @@ pub fn fuzzy_parse_argument( Ok(bytes) } +fn pretty_wrap( + file_name: &str, + source: &str, + e: candid_parser::Error, +) -> Result { + pretty_diagnose(file_name, source, &e)?; + Err(e) +} + pub fn format_as_trillions(amount: u128) -> String { const SCALE: u32 = 12; // trillion = 10^12 const FRACTIONAL_PRECISION: u32 = 3; diff --git a/src/distributed/assetstorage.wasm.gz b/src/distributed/assetstorage.wasm.gz index eb402f7605..08649715e2 100755 Binary files a/src/distributed/assetstorage.wasm.gz and b/src/distributed/assetstorage.wasm.gz differ