diff --git a/Cargo.lock b/Cargo.lock index ad744d021e..5f2975a8b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,13 +279,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.58" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.11", ] [[package]] @@ -323,10 +323,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] -name = "base32" -version = "0.4.0" +name = "base16ct" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -383,7 +383,7 @@ checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", "hmac 0.12.1", - "k256", + "k256 0.11.6", "once_cell", "pbkdf2", "rand_core", @@ -464,8 +464,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62250ece575fa9b22068b3a8d59586f01d426dd7785522efd97632959e71c986" dependencies = [ "digest 0.9.0", - "ff", - "group", + "ff 0.12.1", + "group 0.12.1", "pairing", "rand_core", "subtle", @@ -931,6 +931,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -1033,7 +1045,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", - "pem-rfc7468", + "pem-rfc7468 0.6.0", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" +dependencies = [ + "const-oid", + "pem-rfc7468 0.7.0", "zeroize", ] @@ -1096,7 +1119,7 @@ dependencies = [ "net2", "num-traits", "os_str_bytes", - "pem", + "pem 1.1.1", "petgraph", "proptest", "rand", @@ -1106,7 +1129,7 @@ dependencies = [ "rust_decimal", "rustls", "schemars", - "sec1", + "sec1 0.3.0", "semver", "serde", "serde_bytes", @@ -1150,13 +1173,13 @@ dependencies = [ "ic-agent", "ic-identity-hsm", "ic-utils", - "k256", + "k256 0.11.6", "keyring", "lazy_static", "proptest", "ring", "schemars", - "sec1", + "sec1 0.3.0", "semver", "serde", "serde_json", @@ -1238,6 +1261,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] @@ -1291,10 +1315,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +dependencies = [ + "der 0.7.6", + "digest 0.10.6", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -1309,17 +1347,37 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", "digest 0.10.6", - "ff", + "ff 0.12.1", "generic-array", - "group", - "pem-rfc7468", - "pkcs8", + "group 0.12.1", + "pem-rfc7468 0.6.0", + "pkcs8 0.9.0", "rand_core", - "sec1", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.2", + "digest 0.10.6", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", + "rand_core", + "sec1 0.7.2", "subtle", "zeroize", ] @@ -1440,6 +1498,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "filetime" version = "0.2.18" @@ -1627,12 +1695,13 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1675,7 +1744,18 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "ff", + "ff 0.12.1", + "rand_core", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", "rand_core", "subtle", ] @@ -1919,35 +1999,30 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.23.2" -source = "git+https://github.com/dfinity/agent-rs.git?rev=862ddb2871db426d0e42e816a2f792d224d7bdf5#862ddb2871db426d0e42e816a2f792d224d7bdf5" +version = "0.24.1" +source = "git+https://github.com/dfinity/agent-rs.git?rev=b9c57f8bab23cc9936dca4560293ffe485471c6d#b9c57f8bab23cc9936dca4560293ffe485471c6d" dependencies = [ - "async-trait", "backoff", - "base32", - "base64 0.13.1", - "byteorder", "candid 0.8.4", "futures-util", "hex", "http", "http-body", - "hyper-rustls", - "ic-certification 0.23.2 (git+https://github.com/dfinity/agent-rs.git?rev=862ddb2871db426d0e42e816a2f792d224d7bdf5)", + "ic-certification 0.24.1", "ic-verify-bls-signature", - "k256", + "k256 0.13.1", "leb128", - "mime", - "pem", - "pkcs8", + "pem 2.0.1", + "pkcs8 0.10.2", "rand", "reqwest", "ring", "rustls", - "sec1", + "sec1 0.7.2", "serde", "serde_bytes", "serde_cbor", + "serde_repr", "sha2 0.10.6", "simple_asn1", "thiserror", @@ -2026,8 +2101,8 @@ dependencies = [ [[package]] name = "ic-certification" -version = "0.23.2" -source = "git+https://github.com/dfinity/agent-rs.git?rev=862ddb2871db426d0e42e816a2f792d224d7bdf5#862ddb2871db426d0e42e816a2f792d224d7bdf5" +version = "0.24.1" +source = "git+https://github.com/dfinity/agent-rs.git?rev=b9c57f8bab23cc9936dca4560293ffe485471c6d#b9c57f8bab23cc9936dca4560293ffe485471c6d" dependencies = [ "hex", "serde", @@ -2076,12 +2151,11 @@ dependencies = [ [[package]] name = "ic-identity-hsm" -version = "0.23.2" -source = "git+https://github.com/dfinity/agent-rs.git?rev=862ddb2871db426d0e42e816a2f792d224d7bdf5#862ddb2871db426d0e42e816a2f792d224d7bdf5" +version = "0.24.1" +source = "git+https://github.com/dfinity/agent-rs.git?rev=b9c57f8bab23cc9936dca4560293ffe485471c6d#b9c57f8bab23cc9936dca4560293ffe485471c6d" dependencies = [ "hex", "ic-agent", - "num-bigint 0.4.3", "pkcs11", "sha2 0.10.6", "simple_asn1", @@ -2098,7 +2172,7 @@ dependencies = [ "candid 0.8.4", "flate2", "http", - "ic-certification 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ic-certification 0.23.2", "leb128", "log", "miracl_core_bls12381", @@ -2109,16 +2183,13 @@ dependencies = [ [[package]] name = "ic-utils" -version = "0.23.2" -source = "git+https://github.com/dfinity/agent-rs.git?rev=862ddb2871db426d0e42e816a2f792d224d7bdf5#862ddb2871db426d0e42e816a2f792d224d7bdf5" +version = "0.24.1" +source = "git+https://github.com/dfinity/agent-rs.git?rev=b9c57f8bab23cc9936dca4560293ffe485471c6d#b9c57f8bab23cc9936dca4560293ffe485471c6d" dependencies = [ "async-trait", "candid 0.8.4", "ic-agent", - "leb128", - "num-bigint 0.4.3", "once_cell", - "paste", "semver", "serde", "serde_bytes", @@ -2176,7 +2247,7 @@ dependencies = [ "ic-utils", "libflate", "num-traits", - "pem", + "pem 1.1.1", "serde", "serde_bytes", "serde_json", @@ -2341,12 +2412,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if 1.0.0", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2 0.10.6", "sha3", ] +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa 0.16.7", + "elliptic-curve 0.13.5", + "once_cell", + "sha2 0.10.6", + "signature 2.1.0", +] + [[package]] name = "keccak" version = "0.1.3" @@ -2917,7 +3002,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" dependencies = [ - "group", + "group 0.12.1", ] [[package]] @@ -3009,6 +3094,16 @@ dependencies = [ "base64 0.13.1", ] +[[package]] +name = "pem" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" +dependencies = [ + "base64 0.21.0", + "serde", +] + [[package]] name = "pem-rfc7468" version = "0.6.0" @@ -3018,6 +3113,15 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.2.0" @@ -3143,8 +3247,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.6", + "spki 0.7.2", ] [[package]] @@ -3470,11 +3584,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac 0.12.1", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + [[package]] name = "ring" version = "0.16.20" @@ -3714,10 +3838,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.1", "generic-array", - "pkcs8", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.6", + "generic-array", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -3776,9 +3914,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.159" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] @@ -3804,9 +3942,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", @@ -3850,13 +3988,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.11", ] [[package]] @@ -3961,6 +4099,16 @@ dependencies = [ "rand_core", ] +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.6", + "rand_core", +] + [[package]] name = "simdutf8" version = "0.1.4" @@ -4060,7 +4208,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.6", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 466e5de75a..7bfd6ceec3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,12 +18,12 @@ license = "Apache-2.0" [workspace.dependencies] candid = "0.8.4" -ic-agent = "0.23.1" +ic-agent = "0.24.1" ic-asset = { path = "src/canisters/frontend/ic-asset" } ic-cdk = "0.8.0" ic-cdk-macros = "0.6.7" -ic-identity-hsm = "0.23.1" -ic-utils = "0.23.1" +ic-identity-hsm = "0.24.1" +ic-utils = "0.24.1" aes-gcm = "0.9.4" anyhow = "1.0.56" @@ -68,19 +68,19 @@ url = "2.1.0" walkdir = "2.3.2" [patch.crates-io.ic-agent] -version = "0.23.2" +version = "0.24.1" git = "https://github.com/dfinity/agent-rs.git" -rev = "862ddb2871db426d0e42e816a2f792d224d7bdf5" +rev = "b9c57f8bab23cc9936dca4560293ffe485471c6d" [patch.crates-io.ic-identity-hsm] -version = "0.23.2" +version = "0.24.1" git = "https://github.com/dfinity/agent-rs.git" -rev = "862ddb2871db426d0e42e816a2f792d224d7bdf5" +rev = "b9c57f8bab23cc9936dca4560293ffe485471c6d" [patch.crates-io.ic-utils] -version = "0.23.2" +version = "0.24.1" git = "https://github.com/dfinity/agent-rs.git" -rev = "862ddb2871db426d0e42e816a2f792d224d7bdf5" +rev = "b9c57f8bab23cc9936dca4560293ffe485471c6d" [profile.release] panic = 'abort' diff --git a/src/canisters/frontend/ic-asset/src/asset/config.rs b/src/canisters/frontend/ic-asset/src/asset/config.rs index 85721981dc..8068d0928c 100644 --- a/src/canisters/frontend/ic-asset/src/asset/config.rs +++ b/src/canisters/frontend/ic-asset/src/asset/config.rs @@ -1,7 +1,7 @@ -use crate::error::get_asset_config::GetAssetConfigError; -use crate::error::get_asset_config::GetAssetConfigError::{AssetConfigNotFound, InvalidPath}; -use crate::error::load_config::AssetLoadConfigError; -use crate::error::load_config::AssetLoadConfigError::{LoadRuleFailed, MalformedAssetConfigFile}; +use crate::error::AssetLoadConfigError; +use crate::error::AssetLoadConfigError::{LoadRuleFailed, MalformedAssetConfigFile}; +use crate::error::GetAssetConfigError; +use crate::error::GetAssetConfigError::{AssetConfigNotFound, InvalidPath}; use derivative::Derivative; use globset::GlobMatcher; @@ -269,7 +269,7 @@ impl AssetConfig { /// and pretty-printing of the `AssetConfigRule` data structure. mod rule_utils { use super::{AssetConfig, AssetConfigRule, CacheConfig, HeadersConfig, Maybe}; - use crate::error::load_rule::LoadRuleError; + use crate::error::LoadRuleError; use globset::{Glob, GlobMatcher}; use serde::{Deserialize, Serializer}; use serde_json::Value; diff --git a/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs b/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs index f33eb645d5..6e2e5c5bb2 100644 --- a/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs +++ b/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs @@ -4,10 +4,10 @@ use crate::asset::content_encoder::ContentEncoder; use crate::batch_upload::semaphores::Semaphores; use crate::canister_api::methods::chunk::create_chunk; use crate::canister_api::types::asset::AssetDetails; -use crate::error::create_chunk::CreateChunkError; -use crate::error::create_encoding::CreateEncodingError; -use crate::error::create_encoding::CreateEncodingError::EncodeContentFailed; -use crate::error::create_project_asset::CreateProjectAssetError; +use crate::error::CreateChunkError; +use crate::error::CreateEncodingError; +use crate::error::CreateEncodingError::EncodeContentFailed; +use crate::error::CreateProjectAssetError; use candid::Nat; use futures::future::try_join_all; diff --git a/src/canisters/frontend/ic-asset/src/canister_api/methods/asset_properties.rs b/src/canisters/frontend/ic-asset/src/canister_api/methods/asset_properties.rs index 0ba8d40417..c2ae9fb664 100644 --- a/src/canisters/frontend/ic-asset/src/canister_api/methods/asset_properties.rs +++ b/src/canisters/frontend/ic-asset/src/canister_api/methods/asset_properties.rs @@ -1,6 +1,9 @@ use std::collections::HashMap; -use ic_agent::AgentError; +use ic_agent::{ + agent::{RejectCode, RejectResponse}, + AgentError, +}; use ic_utils::call::SyncCall; use ic_utils::Canister; @@ -8,8 +11,8 @@ use crate::canister_api::{ methods::method_names::GET_ASSET_PROPERTIES, types::asset::{AssetDetails, AssetProperties, GetAssetPropertiesArgument}, }; -use crate::error::get_asset_properties::GetAssetPropertiesError; -use crate::error::get_asset_properties::GetAssetPropertiesError::GetAssetPropertiesFailed; +use crate::error::GetAssetPropertiesError; +use crate::error::GetAssetPropertiesError::GetAssetPropertiesFailed; pub(crate) async fn get_assets_properties( canister: &Canister<'_>, @@ -23,10 +26,11 @@ pub(crate) async fn get_assets_properties( } // older canisters don't have get_assets_properties method // therefore we can break the loop - Err(AgentError::ReplicaError { + Err(AgentError::ReplicaError(RejectResponse { reject_code, reject_message, - }) if reject_code == 3 + .. + })) if reject_code == RejectCode::DestinationInvalid && (reject_message .contains(&format!("has no query method '{GET_ASSET_PROPERTIES}'")) || reject_message.contains("query method does not exist")) => diff --git a/src/canisters/frontend/ic-asset/src/canister_api/methods/chunk.rs b/src/canisters/frontend/ic-asset/src/canister_api/methods/chunk.rs index 71787b2fb7..77736b8009 100644 --- a/src/canisters/frontend/ic-asset/src/canister_api/methods/chunk.rs +++ b/src/canisters/frontend/ic-asset/src/canister_api/methods/chunk.rs @@ -4,7 +4,7 @@ use crate::batch_upload::retryable::retryable; use crate::batch_upload::semaphores::Semaphores; use crate::canister_api::methods::method_names::CREATE_CHUNK; use crate::canister_api::types::batch_upload::common::{CreateChunkRequest, CreateChunkResponse}; -use crate::error::create_chunk::CreateChunkError; +use crate::error::CreateChunkError; use backoff::backoff::Backoff; use backoff::ExponentialBackoffBuilder; @@ -51,15 +51,15 @@ pub(crate) async fn create_chunk( Ok(response) => { // failure to decode the response is not retryable let response = Decode!(&response, CreateChunkResponse) - .map_err(CreateChunkError::DecodeCreateChunkResponseFailed)?; + .map_err(CreateChunkError::DecodeCreateChunkResponse)?; return Ok(response.chunk_id); } Err(agent_err) if !retryable(&agent_err) => { - return Err(CreateChunkError::Agent(agent_err)); + return Err(CreateChunkError::CreateChunk(agent_err)); } Err(agent_err) => match retry_policy.next_backoff() { Some(duration) => tokio::time::sleep(duration).await, - None => return Err(CreateChunkError::Agent(agent_err)), + None => return Err(CreateChunkError::CreateChunk(agent_err)), }, } } diff --git a/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/v0.rs b/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/v0.rs index 6b0b56a6f0..5078a1012b 100644 --- a/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/v0.rs +++ b/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/v0.rs @@ -1,6 +1,6 @@ use super::common::*; -use crate::error::downgrade_commit_batch_arguments::DowngradeCommitBatchArgumentsV1ToV0Error; -use crate::error::downgrade_commit_batch_arguments::DowngradeCommitBatchArgumentsV1ToV0Error::V0SetAssetPropertiesNotSupported; +use crate::error::DowngradeCommitBatchArgumentsV1ToV0Error; +use crate::error::DowngradeCommitBatchArgumentsV1ToV0Error::V0SetAssetPropertiesNotSupported; use candid::{CandidType, Nat}; diff --git a/src/canisters/frontend/ic-asset/src/error/compatibility.rs b/src/canisters/frontend/ic-asset/src/error/compatibility.rs index 94cd92f151..352f8df410 100644 --- a/src/canisters/frontend/ic-asset/src/error/compatibility.rs +++ b/src/canisters/frontend/ic-asset/src/error/compatibility.rs @@ -2,8 +2,10 @@ use crate::error::downgrade_commit_batch_arguments::DowngradeCommitBatchArgument use thiserror::Error; +/// Errors that occur when trying to deploy to an older version of the asset canister. #[derive(Error, Debug)] pub enum CompatibilityError { + /// Failed to downgrade from v1::CommitBatchArguments to v0::CommitBatchArguments. #[error("Failed to downgrade from v1::CommitBatchArguments to v0::CommitBatchArguments: {0}. Please upgrade your asset canister, or use older tooling (dfx<=v-0.13.1 or icx-asset<=0.20.0)")] DowngradeV1TOV0Failed(DowngradeCommitBatchArgumentsV1ToV0Error), } diff --git a/src/canisters/frontend/ic-asset/src/error/compute_evidence.rs b/src/canisters/frontend/ic-asset/src/error/compute_evidence.rs index 8a81e26000..acb4f9831b 100644 --- a/src/canisters/frontend/ic-asset/src/error/compute_evidence.rs +++ b/src/canisters/frontend/ic-asset/src/error/compute_evidence.rs @@ -6,20 +6,26 @@ use crate::error::hash_content::HashContentError; use ic_agent::AgentError; use thiserror::Error; +/// Errors related to computing evidence for a proposed update. #[derive(Error, Debug)] pub enum ComputeEvidenceError { + /// Failed when inspecting assets to be updated. #[error(transparent)] ProcessProjectAsset(#[from] CreateProjectAssetError), + /// Failed when determining which assets and encodings changed. #[error(transparent)] GatherAssetDescriptors(#[from] GatherAssetDescriptorsError), + /// Failed when reading assets properties from the asset canister. #[error(transparent)] GetAssetProperties(#[from] GetAssetPropertiesError), + /// Failed when computing hashes of asset content. #[error(transparent)] HashContent(#[from] HashContentError), + /// Failed to list assets in the asset canister. #[error("Failed to list assets: {0}")] ListAssets(AgentError), } diff --git a/src/canisters/frontend/ic-asset/src/error/create_chunk.rs b/src/canisters/frontend/ic-asset/src/error/create_chunk.rs index 080c923c85..d982c0e453 100644 --- a/src/canisters/frontend/ic-asset/src/error/create_chunk.rs +++ b/src/canisters/frontend/ic-asset/src/error/create_chunk.rs @@ -1,11 +1,14 @@ use ic_agent::AgentError; use thiserror::Error; +/// Errors related to creating a chunk. #[derive(Error, Debug)] pub enum CreateChunkError { - #[error(transparent)] - Agent(#[from] AgentError), + /// Failed in call to create_chunk, or in waiting for response. + #[error("Failed to create chunk: {0}")] + CreateChunk(AgentError), + /// Failed to decode the create chunk response. #[error("Failed to decode create chunk response: {0}")] - DecodeCreateChunkResponseFailed(candid::Error), + DecodeCreateChunkResponse(candid::Error), } diff --git a/src/canisters/frontend/ic-asset/src/error/create_encoding.rs b/src/canisters/frontend/ic-asset/src/error/create_encoding.rs index a2ca623450..83d228d5bc 100644 --- a/src/canisters/frontend/ic-asset/src/error/create_encoding.rs +++ b/src/canisters/frontend/ic-asset/src/error/create_encoding.rs @@ -3,11 +3,14 @@ use crate::error::create_chunk::CreateChunkError; use thiserror::Error; +/// Errors related to creating/uploading an asset content encoding to the asset canister #[derive(Error, Debug)] pub enum CreateEncodingError { + /// Failed when creating a chunk. #[error("Failed to create chunk: {0}")] CreateChunkFailed(CreateChunkError), + /// Failed when encoding asset content. #[error("Failed to encode content of '{0}' with {1} encoding: {2}")] EncodeContentFailed(String, ContentEncoder, std::io::Error), } diff --git a/src/canisters/frontend/ic-asset/src/error/create_project_asset.rs b/src/canisters/frontend/ic-asset/src/error/create_project_asset.rs index d091e72618..bd2bb3a6f9 100644 --- a/src/canisters/frontend/ic-asset/src/error/create_project_asset.rs +++ b/src/canisters/frontend/ic-asset/src/error/create_project_asset.rs @@ -3,14 +3,18 @@ use dfx_core::error::fs::FsError; use thiserror::Error; +/// Errors related to creating an asset found in the project in the asset canister. #[derive(Error, Debug)] pub enum CreateProjectAssetError { + /// Failed to create an asset encoding in the asset canister. #[error("Failed to create encoding: {0}")] CreateEncodingError(#[from] CreateEncodingError), + /// Failed to find out the file size of an asset. #[error("Failed to determine asset size: {0}")] DetermineAssetSizeFailed(FsError), + /// Failed to load asset content from the filesystem. #[error("Failed to load asset content: {0}")] LoadContentFailed(FsError), } diff --git a/src/canisters/frontend/ic-asset/src/error/downgrade_commit_batch_arguments.rs b/src/canisters/frontend/ic-asset/src/error/downgrade_commit_batch_arguments.rs index 16989fa9e8..219847950e 100644 --- a/src/canisters/frontend/ic-asset/src/error/downgrade_commit_batch_arguments.rs +++ b/src/canisters/frontend/ic-asset/src/error/downgrade_commit_batch_arguments.rs @@ -1,7 +1,9 @@ use thiserror::Error; +/// Errors related to downgrading CommitBatchArguments for use with a v0 asset canister. #[derive(Error, Debug)] pub enum DowngradeCommitBatchArgumentsV1ToV0Error { + /// Asset canister v0 does not support SetAssetProperties. #[error("SetAssetProperties is not supported")] V0SetAssetPropertiesNotSupported, } diff --git a/src/canisters/frontend/ic-asset/src/error/gather_asset_descriptors.rs b/src/canisters/frontend/ic-asset/src/error/gather_asset_descriptors.rs index 1f634d7be1..890ec4ea3d 100644 --- a/src/canisters/frontend/ic-asset/src/error/gather_asset_descriptors.rs +++ b/src/canisters/frontend/ic-asset/src/error/gather_asset_descriptors.rs @@ -5,20 +5,26 @@ use dfx_core::error::fs::FsError; use std::path::PathBuf; use thiserror::Error; +/// Errors related to building asset list and reading asset configurations. #[derive(Error, Debug)] pub enum GatherAssetDescriptorsError { + /// An asset with a given key exists in more than one source directory. #[error("Asset with key '{0}' defined at {1} and {2}")] DuplicateAssetKey(String, Box, Box), + /// Failed to get asset configuration. #[error("Failed to get asset configuration: {0}")] GetAssetConfigFailed(#[from] GetAssetConfigError), + /// Failed to canonicalize a directory entry. #[error("Invalid directory entry: {0}")] InvalidDirectoryEntry(FsError), + /// Failed to canonicalize a source directory. #[error("Invalid source directory: {0}")] InvalidSourceDirectory(FsError), + /// Failed to load the asset configuration for a directory. #[error("Failed to load asset configuration: {0}")] LoadConfigFailed(AssetLoadConfigError), } diff --git a/src/canisters/frontend/ic-asset/src/error/get_asset_config.rs b/src/canisters/frontend/ic-asset/src/error/get_asset_config.rs index 255ee06a33..d56d884240 100644 --- a/src/canisters/frontend/ic-asset/src/error/get_asset_config.rs +++ b/src/canisters/frontend/ic-asset/src/error/get_asset_config.rs @@ -2,11 +2,14 @@ use dfx_core::error::fs::FsError; use std::path::PathBuf; use thiserror::Error; +/// Errors related to getting asset configuration. #[derive(Error, Debug)] pub enum GetAssetConfigError { + /// An asset exists, but it does not have a configuration. #[error("No configuration found for asset '{0}'")] AssetConfigNotFound(PathBuf), + /// The path to an asset was invalid. #[error("Invalid asset path: {0}")] InvalidPath(FsError), } diff --git a/src/canisters/frontend/ic-asset/src/error/get_asset_properties.rs b/src/canisters/frontend/ic-asset/src/error/get_asset_properties.rs index 10342c839a..243b0528e5 100644 --- a/src/canisters/frontend/ic-asset/src/error/get_asset_properties.rs +++ b/src/canisters/frontend/ic-asset/src/error/get_asset_properties.rs @@ -1,8 +1,10 @@ use ic_agent::AgentError; use thiserror::Error; +/// Errors related to getting asset properties. #[derive(Error, Debug)] pub enum GetAssetPropertiesError { + /// The call to get_asset_properties failed. #[error("Failed to get asset properties for {0}: {1}")] GetAssetPropertiesFailed(String, AgentError), } diff --git a/src/canisters/frontend/ic-asset/src/error/hash_content.rs b/src/canisters/frontend/ic-asset/src/error/hash_content.rs index 0c37171233..8b70c1f8a9 100644 --- a/src/canisters/frontend/ic-asset/src/error/hash_content.rs +++ b/src/canisters/frontend/ic-asset/src/error/hash_content.rs @@ -3,11 +3,14 @@ use crate::asset::content_encoder::ContentEncoder; use dfx_core::error::fs::FsError; use thiserror::Error; +/// Errors related to hashing asset content. #[derive(Error, Debug)] pub enum HashContentError { + /// Failed to encode the content in order to compute the hash. #[error("Failed to encode content of '{0}' with {1} encoding: {2}")] EncodeContentFailed(String, ContentEncoder, std::io::Error), + /// Failed to load asset content from the filesystem. #[error("Failed to load content: {0}")] LoadContentFailed(FsError), } diff --git a/src/canisters/frontend/ic-asset/src/error/load_config.rs b/src/canisters/frontend/ic-asset/src/error/load_config.rs index e88b70c37f..a5b62f825c 100644 --- a/src/canisters/frontend/ic-asset/src/error/load_config.rs +++ b/src/canisters/frontend/ic-asset/src/error/load_config.rs @@ -4,20 +4,26 @@ use dfx_core::error::fs::FsError; use std::path::PathBuf; use thiserror::Error; +/// Errors related to loading asset configuration. #[derive(Error, Debug)] pub enum AssetLoadConfigError { + /// Failed a filesystem operation; the inner error contains the details. #[error(transparent)] FsError(#[from] FsError), + /// Failed to canonicalize the root directory. #[error("root_dir '{0}' is expected to be a canonical path")] InvalidRootDir(PathBuf), + /// Failed to load a rule from the asset configuration file. #[error("Failed to load rule in {0}: {1}")] LoadRuleFailed(PathBuf, LoadRuleError), + /// An asset configuration file was not valid JSON5. #[error("Malformed JSON asset config file '{0}': {1}")] MalformedAssetConfigFile(PathBuf, json5::Error), + /// both `assets.json` and `assets.json5` files exist in the same directory. #[error("both {} and {} files exist in the same directory (dir = {:?})", crate::asset::config::ASSETS_CONFIG_FILENAME_JSON, crate::asset::config::ASSETS_CONFIG_FILENAME_JSON5, diff --git a/src/canisters/frontend/ic-asset/src/error/load_rule.rs b/src/canisters/frontend/ic-asset/src/error/load_rule.rs index 6c031f410f..2e99294f2f 100644 --- a/src/canisters/frontend/ic-asset/src/error/load_rule.rs +++ b/src/canisters/frontend/ic-asset/src/error/load_rule.rs @@ -1,11 +1,14 @@ use std::path::PathBuf; use thiserror::Error; +/// Errors related to loading an asset configuration rule. #[derive(Error, Debug)] pub enum LoadRuleError { + /// The match string could not be combined with the root directory to form a valid string. #[error("Failed to combine {0} and {1} into a string (to be later used as a glob pattern)")] FormGlobPatternFailed(PathBuf, String), + /// The glob pattern was not valid. #[error("{0} is not a valid glob pattern: {1}")] InvalidGlobPattern(String, globset::Error), } diff --git a/src/canisters/frontend/ic-asset/src/error/mod.rs b/src/canisters/frontend/ic-asset/src/error/mod.rs index 55c230e1cc..6162a8e0d1 100644 --- a/src/canisters/frontend/ic-asset/src/error/mod.rs +++ b/src/canisters/frontend/ic-asset/src/error/mod.rs @@ -1,16 +1,35 @@ -pub mod compatibility; -pub mod compute_evidence; -pub mod create_chunk; -pub mod create_encoding; -pub mod create_project_asset; -pub mod downgrade_commit_batch_arguments; -pub mod gather_asset_descriptors; -pub mod get_asset_config; -pub mod get_asset_properties; -pub mod hash_content; -pub mod load_config; -pub mod load_rule; -pub mod prepare_sync_for_proposal; -pub mod sync; -pub mod upload; -pub mod upload_content; +//! Error types + +mod compatibility; +mod compute_evidence; +mod create_chunk; +mod create_encoding; +mod create_project_asset; +mod downgrade_commit_batch_arguments; +mod gather_asset_descriptors; +mod get_asset_config; +mod get_asset_properties; +mod hash_content; +mod load_config; +mod load_rule; +mod prepare_sync_for_proposal; +mod sync; +mod upload; +mod upload_content; + +pub use compatibility::CompatibilityError; +pub use compute_evidence::ComputeEvidenceError; +pub use create_chunk::CreateChunkError; +pub use create_encoding::CreateEncodingError; +pub use create_project_asset::CreateProjectAssetError; +pub use downgrade_commit_batch_arguments::DowngradeCommitBatchArgumentsV1ToV0Error; +pub use gather_asset_descriptors::GatherAssetDescriptorsError; +pub use get_asset_config::GetAssetConfigError; +pub use get_asset_properties::GetAssetPropertiesError; +pub use hash_content::HashContentError; +pub use load_config::AssetLoadConfigError; +pub use load_rule::LoadRuleError; +pub use prepare_sync_for_proposal::PrepareSyncForProposalError; +pub use sync::SyncError; +pub use upload::UploadError; +pub use upload_content::UploadContentError; diff --git a/src/canisters/frontend/ic-asset/src/error/prepare_sync_for_proposal.rs b/src/canisters/frontend/ic-asset/src/error/prepare_sync_for_proposal.rs index e489b57d78..1c7d4cbd9a 100644 --- a/src/canisters/frontend/ic-asset/src/error/prepare_sync_for_proposal.rs +++ b/src/canisters/frontend/ic-asset/src/error/prepare_sync_for_proposal.rs @@ -3,14 +3,18 @@ use crate::error::upload_content::UploadContentError; use ic_agent::AgentError; use thiserror::Error; +/// Errors related to preparing synchronization operations for a proposal. #[derive(Error, Debug)] pub enum PrepareSyncForProposalError { + /// Failed while requesting that the asset canister compute evidence. #[error("Failed to compute evidence: {0}")] ComputeEvidence(AgentError), + /// Failed while calling propose_commit_batch. #[error("Failed to propose batch to commit: {0}")] ProposeCommitBatch(AgentError), + /// Failed while uploading content for synchronization. #[error(transparent)] UploadContent(#[from] UploadContentError), } diff --git a/src/canisters/frontend/ic-asset/src/error/sync.rs b/src/canisters/frontend/ic-asset/src/error/sync.rs index c1fb75559e..b2b4828395 100644 --- a/src/canisters/frontend/ic-asset/src/error/sync.rs +++ b/src/canisters/frontend/ic-asset/src/error/sync.rs @@ -4,14 +4,18 @@ use crate::error::upload_content::UploadContentError; use ic_agent::AgentError; use thiserror::Error; +/// Errors related to the sync process. #[derive(Error, Debug)] pub enum SyncError { + /// Failed when calling commit_batch #[error("Failed to commit batch: {0}")] CommitBatchFailed(AgentError), + /// Failed when trying to work with an older asset canister. #[error(transparent)] Compatibility(#[from] CompatibilityError), + /// Failed when uploading content for synchronization. #[error(transparent)] UploadContentFailed(#[from] UploadContentError), } diff --git a/src/canisters/frontend/ic-asset/src/error/upload.rs b/src/canisters/frontend/ic-asset/src/error/upload.rs index aededdff3f..04ed5b14b9 100644 --- a/src/canisters/frontend/ic-asset/src/error/upload.rs +++ b/src/canisters/frontend/ic-asset/src/error/upload.rs @@ -4,20 +4,26 @@ use crate::error::create_project_asset::CreateProjectAssetError; use ic_agent::AgentError; use thiserror::Error; +/// Errors encountered during the upload process. #[derive(Error, Debug)] pub enum UploadError { + /// Failed when calling commit_batch. #[error("Commit batch failed: {0}")] CommitBatchFailed(AgentError), + /// Failure when trying to work with an older asset canister. #[error(transparent)] Compatibility(#[from] CompatibilityError), + /// Failed when calling create_batch. #[error("Create batch failed: {0}")] CreateBatchFailed(AgentError), + /// Failed when creating project assets. #[error("Failed to create project asset: {0}")] CreateProjectAssetFailed(#[from] CreateProjectAssetError), + /// Failed when calling the list method. #[error("List assets failed: {0}")] ListAssetsFailed(AgentError), } diff --git a/src/canisters/frontend/ic-asset/src/error/upload_content.rs b/src/canisters/frontend/ic-asset/src/error/upload_content.rs index dd174f8c21..001f14e0ee 100644 --- a/src/canisters/frontend/ic-asset/src/error/upload_content.rs +++ b/src/canisters/frontend/ic-asset/src/error/upload_content.rs @@ -5,20 +5,26 @@ use crate::error::get_asset_properties::GetAssetPropertiesError; use ic_agent::AgentError; use thiserror::Error; +/// Errors related to uploading content to the asset canister. #[derive(Error, Debug)] pub enum UploadContentError { + /// Failed when calling create_batch. #[error("Failed to create batch: {0}")] CreateBatchFailed(AgentError), + /// Failed when creating project assets. #[error("Failed to create project asset: {0}")] CreateProjectAssetError(#[from] CreateProjectAssetError), + /// Failed when building list of assets to synchronize. #[error("Failed to gather asset descriptors: {0}")] GatherAssetDescriptorsFailed(#[from] GatherAssetDescriptorsError), + /// Failed when getting asset properties. #[error(transparent)] GetAssetPropertiesFailed(#[from] GetAssetPropertiesError), + /// Failed when calling the list method. #[error("Failed to list assets: {0}")] ListAssetsFailed(AgentError), } diff --git a/src/canisters/frontend/ic-asset/src/evidence/mod.rs b/src/canisters/frontend/ic-asset/src/evidence/mod.rs index 5764a6f4e5..e6f12cd792 100644 --- a/src/canisters/frontend/ic-asset/src/evidence/mod.rs +++ b/src/canisters/frontend/ic-asset/src/evidence/mod.rs @@ -11,9 +11,9 @@ use crate::canister_api::types::batch_upload::common::{ UnsetAssetContentArguments, }; use crate::canister_api::types::batch_upload::v1::BatchOperationKind; -use crate::error::compute_evidence::ComputeEvidenceError; -use crate::error::hash_content::HashContentError; -use crate::error::hash_content::HashContentError::{EncodeContentFailed, LoadContentFailed}; +use crate::error::ComputeEvidenceError; +use crate::error::HashContentError; +use crate::error::HashContentError::{EncodeContentFailed, LoadContentFailed}; use crate::sync::gather_asset_descriptors; use ic_utils::Canister; use sha2::{Digest, Sha256}; diff --git a/src/canisters/frontend/ic-asset/src/lib.rs b/src/canisters/frontend/ic-asset/src/lib.rs index 595d27f4d8..8059916760 100644 --- a/src/canisters/frontend/ic-asset/src/lib.rs +++ b/src/canisters/frontend/ic-asset/src/lib.rs @@ -34,7 +34,7 @@ mod asset; mod batch_upload; mod canister_api; -mod error; +pub mod error; mod evidence; mod sync; mod upload; diff --git a/src/canisters/frontend/ic-asset/src/sync.rs b/src/canisters/frontend/ic-asset/src/sync.rs index b74b639e09..d9fedb4eff 100644 --- a/src/canisters/frontend/ic-asset/src/sync.rs +++ b/src/canisters/frontend/ic-asset/src/sync.rs @@ -20,16 +20,16 @@ use crate::canister_api::types::batch_upload::v1::BatchOperationKind; use crate::canister_api::types::batch_upload::{ common::ComputeEvidenceArguments, v1::CommitBatchArguments, }; -use crate::error::compatibility::CompatibilityError::DowngradeV1TOV0Failed; -use crate::error::gather_asset_descriptors::GatherAssetDescriptorsError; -use crate::error::gather_asset_descriptors::GatherAssetDescriptorsError::{ +use crate::error::CompatibilityError::DowngradeV1TOV0Failed; +use crate::error::GatherAssetDescriptorsError; +use crate::error::GatherAssetDescriptorsError::{ DuplicateAssetKey, InvalidDirectoryEntry, InvalidSourceDirectory, LoadConfigFailed, }; -use crate::error::prepare_sync_for_proposal::PrepareSyncForProposalError; -use crate::error::sync::SyncError; -use crate::error::sync::SyncError::CommitBatchFailed; -use crate::error::upload_content::UploadContentError; -use crate::error::upload_content::UploadContentError::{CreateBatchFailed, ListAssetsFailed}; +use crate::error::PrepareSyncForProposalError; +use crate::error::SyncError; +use crate::error::SyncError::CommitBatchFailed; +use crate::error::UploadContentError; +use crate::error::UploadContentError::{CreateBatchFailed, ListAssetsFailed}; use candid::Nat; use ic_agent::AgentError; diff --git a/src/canisters/frontend/ic-asset/src/upload.rs b/src/canisters/frontend/ic-asset/src/upload.rs index a329200515..b6221f4263 100644 --- a/src/canisters/frontend/ic-asset/src/upload.rs +++ b/src/canisters/frontend/ic-asset/src/upload.rs @@ -11,9 +11,9 @@ use crate::canister_api::methods::{ list::list_assets, }; use crate::canister_api::types::batch_upload::v0; -use crate::error::compatibility::CompatibilityError::DowngradeV1TOV0Failed; -use crate::error::upload::UploadError; -use crate::error::upload::UploadError::{CommitBatchFailed, CreateBatchFailed, ListAssetsFailed}; +use crate::error::CompatibilityError::DowngradeV1TOV0Failed; +use crate::error::UploadError; +use crate::error::UploadError::{CommitBatchFailed, CreateBatchFailed, ListAssetsFailed}; use ic_utils::Canister; use slog::{info, Logger}; diff --git a/src/dfx-core/src/identity/mod.rs b/src/dfx-core/src/identity/mod.rs index ee9c293c05..04d540ace7 100644 --- a/src/dfx-core/src/identity/mod.rs +++ b/src/dfx-core/src/identity/mod.rs @@ -14,6 +14,7 @@ use crate::error::wallet_config::WalletConfigError::{ }; use crate::identity::identity_file_locations::IdentityFileLocations; use crate::json::{load_json_file, save_json_file}; +use ic_agent::agent::EnvelopeContent; pub use identity_manager::{ HardwareIdentityConfiguration, IdentityConfiguration, IdentityCreationParameters, IdentityManager, @@ -249,8 +250,8 @@ impl ic_agent::Identity for Identity { self.inner.sender() } - fn sign(&self, blob: &[u8]) -> Result { - self.inner.sign(blob) + fn sign(&self, content: &EnvelopeContent) -> Result { + self.inner.sign(content) } } diff --git a/src/dfx/src/commands/canister/call.rs b/src/dfx/src/commands/canister/call.rs index a64a5a75b8..a1512e6c4f 100644 --- a/src/dfx/src/commands/canister/call.rs +++ b/src/dfx/src/commands/canister/call.rs @@ -291,7 +291,7 @@ pub async fn exec( agent .query(&canister_id, method_name) .with_effective_canister_id(effective_canister_id) - .with_arg(&arg_value) + .with_arg(arg_value) .call() .await .context("Failed query call.")? @@ -324,7 +324,7 @@ pub async fn exec( agent .update(&canister_id, method_name) .with_effective_canister_id(effective_canister_id) - .with_arg(&arg_value) + .with_arg(arg_value) .call() .await .context("Failed update call.")? @@ -353,7 +353,7 @@ pub async fn exec( agent .update(&canister_id, method_name) .with_effective_canister_id(effective_canister_id) - .with_arg(&arg_value) + .with_arg(arg_value) .call_and_wait() .await .context("Failed update call.")? diff --git a/src/dfx/src/commands/canister/request_status.rs b/src/dfx/src/commands/canister/request_status.rs index d71f15e36d..f451016ee8 100644 --- a/src/dfx/src/commands/canister/request_status.rs +++ b/src/dfx/src/commands/canister/request_status.rs @@ -59,14 +59,8 @@ pub async fn exec(env: &dyn Environment, opts: RequestStatusOpts) -> DfxResult { .context("Failed to fetch request status.")? { RequestStatusResponse::Replied { reply } => return Ok(reply), - RequestStatusResponse::Rejected { - reject_code, - reject_message, - } => { - return Err(DfxError::new(AgentError::ReplicaError { - reject_code, - reject_message, - })) + RequestStatusResponse::Rejected(response) => { + return Err(DfxError::new(AgentError::ReplicaError(response))) } RequestStatusResponse::Unknown => (), RequestStatusResponse::Received | RequestStatusResponse::Processing => { diff --git a/src/dfx/src/commands/canister/send.rs b/src/dfx/src/commands/canister/send.rs index c8319d526b..cf29086b5f 100644 --- a/src/dfx/src/commands/canister/send.rs +++ b/src/dfx/src/commands/canister/send.rs @@ -3,7 +3,7 @@ use crate::lib::error::DfxResult; use crate::lib::sign::signed_message::SignedMessageV1; use dfx_core::identity::CallSender; -use ic_agent::agent::ReplicaV2Transport; +use ic_agent::agent::Transport; use ic_agent::{agent::http_transport::ReqwestHttpReplicaV2Transport, RequestId}; use anyhow::{anyhow, bail, Context}; diff --git a/src/dfx/src/commands/canister/sign.rs b/src/dfx/src/commands/canister/sign.rs index bc91df8fc7..33f06b9657 100644 --- a/src/dfx/src/commands/canister/sign.rs +++ b/src/dfx/src/commands/canister/sign.rs @@ -2,7 +2,7 @@ use crate::commands::canister::call::get_effective_canister_id; use crate::lib::environment::Environment; use crate::lib::error::DfxResult; use crate::lib::operations::canister::get_local_cid_and_candid_path; -use crate::lib::sign::sign_transport::SignReplicaV2Transport; +use crate::lib::sign::sign_transport::SignTransport; use crate::lib::sign::signed_message::SignedMessageV1; use dfx_core::identity::CallSender; @@ -174,10 +174,7 @@ pub async fn exec( } let mut sign_agent = agent.clone(); - sign_agent.set_transport(SignReplicaV2Transport::new( - file_name.clone(), - message_template, - )); + sign_agent.set_transport(SignTransport::new(file_name.clone(), message_template)); let is_management_canister = canister_id == Principal::management_canister(); let effective_canister_id = @@ -187,7 +184,7 @@ pub async fn exec( let res = sign_agent .query(&canister_id, method_name) .with_effective_canister_id(effective_canister_id) - .with_arg(&arg_value) + .with_arg(arg_value) .expire_at(expiration_system_time) .call() .await; @@ -203,7 +200,7 @@ pub async fn exec( let res = sign_agent .update(&canister_id, method_name) .with_effective_canister_id(effective_canister_id) - .with_arg(&arg_value) + .with_arg(arg_value) .expire_at(expiration_system_time) .call() .await; diff --git a/src/dfx/src/commands/ledger/mod.rs b/src/dfx/src/commands/ledger/mod.rs index b06914598b..9fb292fa08 100644 --- a/src/dfx/src/commands/ledger/mod.rs +++ b/src/dfx/src/commands/ledger/mod.rs @@ -17,6 +17,7 @@ use candid::Principal; use candid::{Decode, Encode}; use clap::Parser; use fn_error_context::context; +use ic_agent::agent::{RejectCode, RejectResponse}; use ic_agent::agent_error::HttpErrorPayload; use ic_agent::{Agent, AgentError}; use std::time::{SystemTime, UNIX_EPOCH}; @@ -238,10 +239,11 @@ pub async fn notify_top_up( fn retryable(agent_error: &AgentError) -> bool { match agent_error { - AgentError::ReplicaError { - reject_code, + AgentError::ReplicaError(RejectResponse { + reject_code: RejectCode::CanisterError, reject_message, - } if *reject_code == 5 && reject_message.contains("is out of cycles") => false, + .. + }) if reject_message.contains("is out of cycles") => false, AgentError::HttpError(HttpErrorPayload { status, content_type: _, diff --git a/src/dfx/src/lib/environment.rs b/src/dfx/src/lib/environment.rs index e1b332b873..6fabaf3cfe 100644 --- a/src/dfx/src/lib/environment.rs +++ b/src/dfx/src/lib/environment.rs @@ -4,7 +4,6 @@ use crate::lib::error::extension::ExtensionError; use crate::lib::error::DfxResult; use crate::lib::extension::manager::ExtensionManager; use crate::lib::progress_bar::ProgressBar; -use dfx_core::config::cache::get_cache_root; use dfx_core::config::cache::Cache; use dfx_core::config::model::canister_id_store::CanisterIdStore; use dfx_core::config::model::dfinity::{Config, NetworksConfig}; @@ -20,10 +19,9 @@ use ic_agent::{Agent, Identity}; use semver::Version; use slog::{warn, Logger, Record}; use std::borrow::Cow; -use std::collections::BTreeMap; use std::fs::create_dir_all; use std::path::PathBuf; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::time::Duration; pub trait Environment { @@ -373,208 +371,19 @@ impl<'a> Environment for AgentEnvironment<'a> { } } -pub struct AgentClient { - logger: Logger, - url: reqwest::Url, - - // The auth `(username, password)`. - auth: Arc>>, -} - -impl AgentClient { - pub fn new(logger: Logger, url: String) -> DfxResult { - let url = reqwest::Url::parse(&url).with_context(|| format!("Invalid URL: {}", url))?; - - let result = Self { - logger, - url, - auth: Arc::new(Mutex::new(None)), - }; - - if let Ok(Some(auth)) = result.read_http_auth() { - result.auth.lock().unwrap().replace(auth); - } - - Ok(result) - } - - #[context("Failed to determine http auth path.")] - fn http_auth_path() -> DfxResult { - Ok(get_cache_root()?.join("http_auth")) - } - - // A connection is considered secure if it goes to an HTTPs scheme or if it's the - // localhost (which cannot be spoofed). - fn is_secure(&self) -> bool { - self.url.scheme() == "https" || self.url.host_str().unwrap_or("") == "localhost" - } - - #[context("Failed to read http auth map.")] - fn read_http_auth_map(&self) -> DfxResult> { - let p = &Self::http_auth_path()?; - let content = std::fs::read_to_string(p) - .with_context(|| format!("Failed to read {}.", p.to_string_lossy()))?; - - // If there's an error parsing, simply use an empty map. - Ok( - serde_json::from_slice::>(content.as_bytes()) - .unwrap_or_else(|_| BTreeMap::new()), - ) - } - - fn read_http_auth(&self) -> DfxResult> { - match self.url.host() { - None => Ok(None), - Some(h) => { - let map = self.read_http_auth_map()?; - if let Some(token) = map.get(&h.to_string()) { - if !self.is_secure() { - slog::warn!( - self.logger, - "HTTP Auth was found, but protocol is not secure. Refusing to use the token." - ); - Ok(None) - } else { - // For backward compatibility with previous versions of DFX, we still - // store the base64 encoding of `username:password`, but we decode it - // since the Agent requires username and password as separate fields. - let pair = base64::decode(token).unwrap(); - let pair = String::from_utf8_lossy(pair.as_slice()); - let colon_pos = pair - .find(':') - .ok_or_else(|| anyhow!("Incorrectly formatted auth string (no `:`)"))?; - Ok(Some(( - pair[..colon_pos].to_owned(), - pair[colon_pos + 1..].to_owned(), - ))) - } - } else { - Ok(None) - } - } - } - } - - fn save_http_auth(&self, host: &str, auth: &str) -> DfxResult { - let mut map = self - .read_http_auth_map() - .unwrap_or_else(|_| BTreeMap::new()); - map.insert(host.to_string(), auth.to_string()); - - let p = Self::http_auth_path()?; - std::fs::write( - &p, - serde_json::to_string(&map) - .context("Failed to serialize http auth map.")? - .as_bytes(), - ) - .with_context(|| format!("Failed to write to {}.", p.to_string_lossy()))?; - - Ok(p) - } -} - -impl ic_agent::agent::http_transport::PasswordManager for AgentClient { - fn cached(&self, _url: &str) -> Result, String> { - // Support for HTTP Auth if necessary (tries to contact first, then do the HTTP Auth - // flow). - if let Some(auth) = self.auth.lock().unwrap().as_ref() { - Ok(Some(auth.clone())) - } else { - Ok(None) - } - } - - fn required(&self, _url: &str) -> Result<(String, String), String> { - eprintln!("Unauthorized HTTP Access... Please enter credentials:"); - let mut username; - while { - username = dialoguer::Input::::new() - .with_prompt("Username") - .interact() - .unwrap(); - username.contains(':') - } { - eprintln!("Invalid username (unexpected `:`)") - } - let password = dialoguer::Password::new() - .with_prompt("Password") - .interact() - .unwrap(); - - let auth = format!("{}:{}", username, password); - let auth = base64::encode(&auth); - - self.auth - .lock() - .unwrap() - .replace((username.clone(), password.clone())); - - if let Some(h) = &self.url.host() { - if let Ok(p) = self.save_http_auth(&h.to_string(), &auth) { - slog::info!( - self.logger, - "Saved HTTP credentials to {}.", - p.to_string_lossy() - ); - } - } - - Ok((username, password)) - } -} - #[context("Failed to create agent with url {}.", url)] pub fn create_agent( - logger: Logger, + _logger: Logger, url: &str, identity: Box, timeout: Duration, ) -> DfxResult { - let executor = AgentClient::new(logger, url.to_string())?; let agent = Agent::builder() - .with_transport( - ic_agent::agent::http_transport::ReqwestHttpReplicaV2Transport::create(url)? - .with_password_manager(executor), - ) + .with_transport(ic_agent::agent::http_transport::ReqwestTransport::create( + url, + )?) .with_boxed_identity(identity) .with_ingress_expiry(Some(timeout)) .build()?; Ok(agent) } - -#[cfg(test)] -mod tests { - use std::{env, io}; - - use slog::{o, Drain, Logger}; - use slog_term::{FullFormat, PlainSyncDecorator}; - use tempfile::TempDir; - - use super::AgentClient; - - #[test] - fn test_passwords() { - let cache_root = TempDir::new().unwrap(); - let old_var = env::var_os("DFX_CACHE_ROOT"); - env::set_var("DFX_CACHE_ROOT", cache_root.path()); - let log = Logger::root( - FullFormat::new(PlainSyncDecorator::new(io::stderr())) - .build() - .fuse(), - o!(), - ); - let client = AgentClient::new(log, "https://localhost".to_owned()).unwrap(); - client - .save_http_auth("localhost", &base64::encode("default:hunter2:")) - .unwrap(); - let (user, pass) = client.read_http_auth().unwrap().unwrap(); - assert_eq!(user, "default"); - assert_eq!(pass, "hunter2:"); - if let Some(old_var) = old_var { - env::set_var("DFX_CACHE_ROOT", old_var); - } else { - env::remove_var("DFX_CACHE_ROOT"); - } - } -} diff --git a/src/dfx/src/lib/identity/wallet.rs b/src/dfx/src/lib/identity/wallet.rs index 9179c3dd08..92382017fb 100644 --- a/src/dfx/src/lib/identity/wallet.rs +++ b/src/dfx/src/lib/identity/wallet.rs @@ -16,6 +16,7 @@ use dfx_core::json::save_json_file; use anyhow::{anyhow, bail, Context}; use candid::Principal; use fn_error_context::context; +use ic_agent::agent::{RejectCode, RejectResponse}; use ic_agent::AgentError; use ic_utils::call::AsyncCall; use ic_utils::interfaces::management_canister::builders::InstallMode; @@ -113,10 +114,11 @@ pub async fn create_wallet( .call_and_wait() .await { - Err(AgentError::ReplicaError { - reject_code: 5, + Err(AgentError::ReplicaError(RejectResponse { + reject_code: RejectCode::CanisterError, reject_message, - }) if reject_message.contains("not empty") => { + .. + })) if reject_message.contains("not empty") => { bail!( r#"The wallet canister "{canister_id}" already exists for user "{name}" on "{}" network."#, network.name diff --git a/src/dfx/src/lib/operations/canister/create_canister.rs b/src/dfx/src/lib/operations/canister/create_canister.rs index 4456093866..165a80e4eb 100644 --- a/src/dfx/src/lib/operations/canister/create_canister.rs +++ b/src/dfx/src/lib/operations/canister/create_canister.rs @@ -8,6 +8,7 @@ use dfx_core::network::provider::get_network_context; use anyhow::{anyhow, bail, Context}; use candid::Principal; use fn_error_context::context; +use ic_agent::agent::{RejectCode, RejectResponse}; use ic_agent::agent_error::HttpErrorPayload; use ic_agent::AgentError; use ic_utils::interfaces::ManagementCanister; @@ -93,14 +94,25 @@ pub async fn create_canister( .with_optional_freezing_threshold(settings.freezing_threshold) .call_and_wait() .await; - if let Err(AgentError::HttpError(HttpErrorPayload { status, .. })) = &res { - if *status >= 400 && *status < 500 { - bail!("In order to create a canister on this network, you must use a wallet in order to allocate cycles to the new canister. \ - To do this, remove the --no-wallet argument and try again. It is also possible to create a canister on this network \ - using `dfx ledger create-canister`, but doing so will not associate the created canister with any of the canisters in your project.") + const NEEDS_WALLET: &str = "In order to create a canister on this network, you must use a wallet in order to allocate cycles to the new canister. \ + To do this, remove the --no-wallet argument and try again. It is also possible to create a canister on this network \ + using `dfx ledger create-canister`, but doing so will not associate the created canister with any of the canisters in your project."; + match res { + Ok((o,)) => o, + Err(AgentError::HttpError(HttpErrorPayload { status, .. })) + if (400..500).contains(&status) => + { + bail!(NEEDS_WALLET) } + Err(AgentError::ReplicaError(RejectResponse { + reject_code: RejectCode::CanisterReject, + reject_message, + .. + })) if reject_message.contains("is not allowed to call ic00 method") => { + bail!(NEEDS_WALLET) + } + Err(e) => return Err(e).context("Canister creation call failed."), } - res.context("Canister creation call failed.")?.0 } CallSender::Wallet(wallet_id) => { let wallet = build_wallet_canister(*wallet_id, agent).await?; diff --git a/src/dfx/src/lib/operations/ledger.rs b/src/dfx/src/lib/operations/ledger.rs index 1fcfecbe69..c1159ca055 100644 --- a/src/dfx/src/lib/operations/ledger.rs +++ b/src/dfx/src/lib/operations/ledger.rs @@ -60,19 +60,19 @@ pub async fn xdr_permyriad_per_icp(agent: &Agent) -> DfxResult { let witness = lookup_value( &cert, [ - "canister".into(), - MAINNET_CYCLE_MINTER_CANISTER_ID.into(), - "certified_data".into(), + b"canister", + MAINNET_CYCLE_MINTER_CANISTER_ID.as_slice(), + b"certified_data", ], ) .context("The IC's certificate for the XDR <> ICP exchange rate could not be verified")?; - let tree = serde_cbor::from_slice::(&certified_rate.hash_tree)?; + let tree = serde_cbor::from_slice::>>(&certified_rate.hash_tree)?; ensure!( tree.digest() == witness, "The CMC's certificate for the XDR <> ICP exchange rate did not match the IC's certificate" ); // we can trust the hash tree - let lookup = tree.lookup_path([&"ICP_XDR_CONVERSION_RATE".into()]); + let lookup = tree.lookup_path([b"ICP_XDR_CONVERSION_RATE"]); let certified_data = if let LookupResult::Found(content) = lookup { content } else { diff --git a/src/dfx/src/lib/sign/sign_transport.rs b/src/dfx/src/lib/sign/sign_transport.rs index d8078fb65b..701110c62c 100644 --- a/src/dfx/src/lib/sign/sign_transport.rs +++ b/src/dfx/src/lib/sign/sign_transport.rs @@ -1,7 +1,7 @@ use super::signed_message::SignedMessageV1; use candid::Principal; -use ic_agent::agent::ReplicaV2Transport; +use ic_agent::agent::Transport; use ic_agent::{AgentError, RequestId}; use std::fs::{File, OpenOptions}; @@ -17,12 +17,12 @@ enum SerializeStatus { Success(String), } -pub(crate) struct SignReplicaV2Transport { +pub(crate) struct SignTransport { file_name: PathBuf, message_template: SignedMessageV1, } -impl SignReplicaV2Transport { +impl SignTransport { pub fn new>(file_name: U, message_template: SignedMessageV1) -> Self { Self { file_name: file_name.into(), @@ -31,13 +31,13 @@ impl SignReplicaV2Transport { } } -impl ReplicaV2Transport for SignReplicaV2Transport { +impl Transport for SignTransport { fn read_state<'a>( &'a self, _effective_canister_id: Principal, envelope: Vec, ) -> Pin, AgentError>> + Send + 'a>> { - async fn run(s: &SignReplicaV2Transport, envelope: Vec) -> Result, AgentError> { + async fn run(s: &SignTransport, envelope: Vec) -> Result, AgentError> { let path = &s.file_name; let mut file = File::open(path).map_err(|x| AgentError::MessageError(x.to_string()))?; let mut json = String::new(); @@ -74,7 +74,7 @@ impl ReplicaV2Transport for SignReplicaV2Transport { request_id: RequestId, ) -> Pin> + Send + 'a>> { async fn run( - s: &SignReplicaV2Transport, + s: &SignTransport, envelope: Vec, request_id: RequestId, ) -> Result<(), AgentError> { @@ -108,7 +108,7 @@ impl ReplicaV2Transport for SignReplicaV2Transport { _effective_canister_id: Principal, envelope: Vec, ) -> Pin, AgentError>> + Send + 'a>> { - async fn run(s: &SignReplicaV2Transport, envelope: Vec) -> Result, AgentError> { + async fn run(s: &SignTransport, envelope: Vec) -> Result, AgentError> { let message = s .message_template .clone() @@ -136,7 +136,7 @@ impl ReplicaV2Transport for SignReplicaV2Transport { fn status<'a>( &'a self, ) -> Pin, AgentError>> + Send + 'a>> { - async fn run(_: &SignReplicaV2Transport) -> Result, AgentError> { + async fn run(_: &SignTransport) -> Result, AgentError> { Err(AgentError::MessageError( "status calls not supported".to_string(), ))