diff --git a/Cargo.lock b/Cargo.lock index bc449421..69df6e96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -336,9 +336,8 @@ dependencies = [ [[package]] name = "candid" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088c2e3d22a0fb1ada78b968946b0f7b96027ac8669973fe7c0815a98e8d13ef" +version = "0.10.8" +source = "git+https://github.com/nathanosdev/candid#01b46057a543da477d34391d860c296bc49d4674" dependencies = [ "anyhow", "binread", @@ -360,8 +359,7 @@ dependencies = [ [[package]] name = "candid_derive" version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3de398570c386726e7a59d9887b68763c481477f9a043fb998a2e09d428df1a9" +source = "git+https://github.com/nathanosdev/candid#01b46057a543da477d34391d860c296bc49d4674" dependencies = [ "lazy_static", "proc-macro2", @@ -371,21 +369,23 @@ dependencies = [ [[package]] name = "candid_parser" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4756982955984c41f4652a265091725c88ff4ccf4e390d0a36edd08387b28f" +version = "0.2.0-beta.1" +source = "git+https://github.com/nathanosdev/candid#01b46057a543da477d34391d860c296bc49d4674" dependencies = [ "anyhow", "candid", "codespan-reporting", "convert_case", + "handlebars", "hex", "lalrpop", "lalrpop-util", "logos", "num-bigint 0.4.3", "pretty", + "serde", "thiserror", + "toml", ] [[package]] @@ -1003,6 +1003,20 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "handlebars" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "hashbrown" version = "0.14.0" @@ -1351,16 +1365,13 @@ dependencies = [ [[package]] name = "ic_principal" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899a4e8ddada85b91a2fe32b4dc6c0d475ef7bfef3f51cf2aecb26ee4ac4724f" +version = "0.1.1" +source = "git+https://github.com/nathanosdev/candid#01b46057a543da477d34391d860c296bc49d4674" dependencies = [ "arbitrary", "crc32fast", "data-encoding", - "hex", "serde", - "serde_bytes", "sha2 0.10.7", "thiserror", ] @@ -1572,32 +1583,33 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "logos" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +checksum = "161971eb88a0da7ae0c333e1063467c5b5727e7fb6b710b8db4814eade3a42e8" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +checksum = "8e31badd9de5131fdf4921f6473d457e3dd85b11b7f091ceb50e4df7c3eeb12a" dependencies = [ "beef", "fnv", + "lazy_static", "proc-macro2", "quote", - "regex-syntax 0.6.29", + "regex-syntax 0.8.3", "syn 2.0.32", ] [[package]] name = "logos-derive" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +checksum = "1c2a69b3eb68d5bd595107c9ee58d7e07fe2bb5e360cc85b0f084dedac80de0a" dependencies = [ "logos-codegen", ] @@ -1820,6 +1832,51 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +[[package]] +name = "pest" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "pest_meta" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.7", +] + [[package]] name = "petgraph" version = "0.6.4" @@ -2062,15 +2119,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" @@ -2433,6 +2490,15 @@ dependencies = [ "syn 2.0.32", ] +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2833,6 +2899,40 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -2900,6 +3000,12 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -3274,6 +3380,15 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winnow" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/Cargo.toml b/Cargo.toml index c9b7b194..011c6b7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,8 +27,8 @@ ic-utils = { path = "ic-utils", version = "0.35.0" } ic-transport-types = { path = "ic-transport-types", version = "0.35.0" } ic-certification = "2.2" -candid = "0.10.1" -candid_parser = "0.1.1" +candid = { git = "https://github.com/nathanosdev/candid" } +candid_parser = { git = "https://github.com/nathanosdev/candid" } clap = "4.4.3" futures-util = "0.3.21" hex = "0.4.3" diff --git a/ic-agent/src/agent/agent_error.rs b/ic-agent/src/agent/agent_error.rs index 08cf77a1..7f24f226 100644 --- a/ic-agent/src/agent/agent_error.rs +++ b/ic-agent/src/agent/agent_error.rs @@ -12,7 +12,7 @@ use std::{ use thiserror::Error; /// An error that occurred when using the agent. -#[derive(Error, Debug)] +#[derive(Error, Debug, Clone)] pub enum AgentError { /// The replica URL was invalid. #[error(r#"Invalid Replica URL: "{0}""#)] @@ -28,7 +28,7 @@ pub enum AgentError { /// The data fetched was invalid CBOR. #[error("Invalid CBOR data, could not deserialize: {0}")] - InvalidCborData(#[from] serde_cbor::Error), + InvalidCborData(String), /// There was an error calculating a request ID. #[error("Cannot calculate a RequestID: {0}")] @@ -36,7 +36,7 @@ pub enum AgentError { /// There was an error when de/serializing with Candid. #[error("Candid returned an error: {0}")] - CandidError(Box), + CandidError(#[from] candid::Error), /// There was an error parsing a URL. #[error(r#"Cannot parse url: "{0}""#)] @@ -44,7 +44,7 @@ pub enum AgentError { /// The HTTP method was invalid. #[error(r#"Invalid method: "{0}""#)] - InvalidMethodError(#[from] http::method::InvalidMethod), + InvalidMethodError(String), /// The principal string was not a valid principal. #[error("Cannot parse Principal: {0}")] @@ -76,7 +76,7 @@ pub enum AgentError { /// There was an error reading a LEB128 value. #[error("Error reading LEB128 value: {0}")] - Leb128ReadError(#[from] read::Error), + Leb128ReadError(String), /// A string was invalid UTF-8. #[error("Error in UTF-8 string: {0}")] @@ -185,7 +185,7 @@ pub enum AgentError { /// An unknown error occurred during communication with the replica. #[error("An error happened during communication with the replica: {0}")] - TransportError(Box), + TransportError(String), /// There was a mismatch between the expected and actual CBOR data during inspection. #[error("There is a mismatch between the CBOR encoded call and the arguments: field {field}, value in argument is {value_arg}, value in CBOR is {value_cbor}")] @@ -215,12 +215,32 @@ impl PartialEq for AgentError { } } -impl From for AgentError { - fn from(e: candid::Error) -> AgentError { - AgentError::CandidError(e.into()) +impl From for AgentError { + fn from(e: serde_cbor::Error) -> AgentError { + AgentError::InvalidCborData(e.to_string()) } } +impl From for AgentError { + fn from(e: http::method::InvalidMethod) -> AgentError { + AgentError::InvalidMethodError(e.to_string()) + } +} + +impl From for AgentError { + fn from(e: read::Error) -> AgentError { + AgentError::Leb128ReadError(e.to_string()) + } +} + +#[cfg(feature = "reqwest")] +impl From for AgentError { + fn from(e: reqwest::Error) -> AgentError { + AgentError::TransportError(e.to_string()) + } +} + +#[derive(Clone)] /// A HTTP error from the replica. pub struct HttpErrorPayload { /// The HTTP status code. diff --git a/ic-agent/src/agent/http_transport/reqwest_transport.rs b/ic-agent/src/agent/http_transport/reqwest_transport.rs index e519eeea..38286072 100644 --- a/ic-agent/src/agent/http_transport/reqwest_transport.rs +++ b/ic-agent/src/agent/http_transport/reqwest_transport.rs @@ -83,11 +83,7 @@ impl ReqwestTransport { &self, http_request: Request, ) -> Result<(StatusCode, HeaderMap, Vec), AgentError> { - let response = self - .client - .execute(http_request) - .await - .map_err(|x| AgentError::TransportError(Box::new(x)))?; + let response = self.client.execute(http_request).await?; let http_status = response.status(); let response_headers = response.headers().clone(); @@ -107,7 +103,7 @@ impl ReqwestTransport { let mut stream = response.bytes_stream(); while let Some(chunk) = stream.next().await { - let chunk = chunk.map_err(|x| AgentError::TransportError(Box::new(x)))?; + let chunk = chunk?; // Size Check (Body Size) if matches!(self @@ -155,7 +151,7 @@ impl ReqwestTransport { let agent_error = match cbor_decoded_body { Ok(replica_error) => AgentError::UncertifiedReject(replica_error), - Err(cbor_error) => AgentError::InvalidCborData(cbor_error), + Err(cbor_error) => cbor_error.into(), }; Err(agent_error) diff --git a/ic-agent/src/agent/mod.rs b/ic-agent/src/agent/mod.rs index 2ab74185..1fe4c74c 100644 --- a/ic-agent/src/agent/mod.rs +++ b/ic-agent/src/agent/mod.rs @@ -379,7 +379,7 @@ impl Agent { .transport .query(effective_canister_id, serialized_bytes) .await?; - serde_cbor::from_slice(&bytes).map_err(AgentError::InvalidCborData) + serde_cbor::from_slice(&bytes).map_err(Into::into) } async fn read_state_endpoint( @@ -395,7 +395,7 @@ impl Agent { .transport .read_state(effective_canister_id, serialized_bytes) .await?; - serde_cbor::from_slice(&bytes).map_err(AgentError::InvalidCborData) + serde_cbor::from_slice(&bytes).map_err(Into::into) } async fn read_subnet_state_endpoint( @@ -411,7 +411,7 @@ impl Agent { .transport .read_subnet_state(subnet_id, serialized_bytes) .await?; - serde_cbor::from_slice(&bytes).map_err(AgentError::InvalidCborData) + serde_cbor::from_slice(&bytes).map_err(Into::into) } async fn call_endpoint( @@ -465,8 +465,7 @@ impl Agent { effective_canister_id: Principal, signed_query: Vec, ) -> Result, AgentError> { - let envelope: Envelope = - serde_cbor::from_slice(&signed_query).map_err(AgentError::InvalidCborData)?; + let envelope: Envelope = serde_cbor::from_slice(&signed_query)?; self.query_inner( effective_canister_id, signed_query, @@ -616,8 +615,7 @@ impl Agent { effective_canister_id: Principal, signed_update: Vec, ) -> Result { - let envelope: Envelope = - serde_cbor::from_slice(&signed_update).map_err(AgentError::InvalidCborData)?; + let envelope: Envelope = serde_cbor::from_slice(&signed_update)?; let request_id = to_request_id(&envelope.content)?; self.call_endpoint(effective_canister_id, request_id, signed_update) .await @@ -776,8 +774,7 @@ impl Agent { let read_state_response: ReadStateResponse = self .read_state_endpoint(effective_canister_id, serialized_bytes) .await?; - let cert: Certificate = serde_cbor::from_slice(&read_state_response.certificate) - .map_err(AgentError::InvalidCborData)?; + let cert: Certificate = serde_cbor::from_slice(&read_state_response.certificate)?; self.verify(&cert, effective_canister_id)?; Ok(cert) } @@ -795,8 +792,7 @@ impl Agent { let read_state_response: ReadStateResponse = self .read_subnet_state_endpoint(subnet_id, serialized_bytes) .await?; - let cert: Certificate = serde_cbor::from_slice(&read_state_response.certificate) - .map_err(AgentError::InvalidCborData)?; + let cert: Certificate = serde_cbor::from_slice(&read_state_response.certificate)?; self.verify_for_subnet(&cert, subnet_id)?; Ok(cert) } @@ -894,8 +890,7 @@ impl Agent { match delegation { None => Ok(self.read_root_key()), Some(delegation) => { - let cert: Certificate = serde_cbor::from_slice(&delegation.certificate) - .map_err(AgentError::InvalidCborData)?; + let cert: Certificate = serde_cbor::from_slice(&delegation.certificate)?; if cert.delegation.is_some() { return Err(AgentError::CertificateHasTooManyDelegations); } @@ -906,8 +901,7 @@ impl Agent { "canister_ranges".as_bytes(), ]; let canister_range = lookup_value(&cert.tree, canister_range_lookup)?; - let ranges: Vec<(Principal, Principal)> = - serde_cbor::from_slice(canister_range).map_err(AgentError::InvalidCborData)?; + let ranges: Vec<(Principal, Principal)> = serde_cbor::from_slice(canister_range)?; if !principal_is_within_ranges(&effective_canister_id, &ranges[..]) { // the certificate is not authorized to answer calls for this canister return Err(AgentError::CertificateNotAuthorized()); @@ -931,8 +925,7 @@ impl Agent { match delegation { None => Ok(self.read_root_key()), Some(delegation) => { - let cert: Certificate = serde_cbor::from_slice(&delegation.certificate) - .map_err(AgentError::InvalidCborData)?; + let cert: Certificate = serde_cbor::from_slice(&delegation.certificate)?; if cert.delegation.is_some() { return Err(AgentError::CertificateHasTooManyDelegations); } @@ -1023,14 +1016,12 @@ impl Agent { effective_canister_id: Principal, signed_request_status: Vec, ) -> Result { - let _envelope: Envelope = - serde_cbor::from_slice(&signed_request_status).map_err(AgentError::InvalidCborData)?; + let _envelope: Envelope = serde_cbor::from_slice(&signed_request_status)?; let read_state_response: ReadStateResponse = self .read_state_endpoint(effective_canister_id, signed_request_status) .await?; - let cert: Certificate = serde_cbor::from_slice(&read_state_response.certificate) - .map_err(AgentError::InvalidCborData)?; + let cert: Certificate = serde_cbor::from_slice(&read_state_response.certificate)?; self.verify(&cert, effective_canister_id)?; lookup_request_status(cert, request_id) } @@ -1049,8 +1040,7 @@ impl Agent { pub async fn status(&self) -> Result { let bytes = self.transport.status().await?; - let cbor: serde_cbor::Value = - serde_cbor::from_slice(&bytes).map_err(AgentError::InvalidCborData)?; + let cbor: serde_cbor::Value = serde_cbor::from_slice(&bytes)?; Status::try_from(&cbor).map_err(|_| AgentError::InvalidReplicaStatus) } @@ -1180,8 +1170,7 @@ pub fn signed_query_inspect( ingress_expiry: u64, signed_query: Vec, ) -> Result<(), AgentError> { - let envelope: Envelope = - serde_cbor::from_slice(&signed_query).map_err(AgentError::InvalidCborData)?; + let envelope: Envelope = serde_cbor::from_slice(&signed_query)?; match envelope.content.as_ref() { EnvelopeContent::Query { ingress_expiry: ingress_expiry_cbor, @@ -1255,8 +1244,7 @@ pub fn signed_update_inspect( ingress_expiry: u64, signed_update: Vec, ) -> Result<(), AgentError> { - let envelope: Envelope = - serde_cbor::from_slice(&signed_update).map_err(AgentError::InvalidCborData)?; + let envelope: Envelope = serde_cbor::from_slice(&signed_update)?; match envelope.content.as_ref() { EnvelopeContent::Call { nonce: _nonce, @@ -1329,8 +1317,7 @@ pub fn signed_request_status_inspect( signed_request_status: Vec, ) -> Result<(), AgentError> { let paths: Vec> = vec![vec!["request_status".into(), request_id.to_vec().into()]]; - let envelope: Envelope = - serde_cbor::from_slice(&signed_request_status).map_err(AgentError::InvalidCborData)?; + let envelope: Envelope = serde_cbor::from_slice(&signed_request_status)?; match envelope.content.as_ref() { EnvelopeContent::ReadState { ingress_expiry: ingress_expiry_cbor, diff --git a/ic-agent/src/agent/status.rs b/ic-agent/src/agent/status.rs index 60f78203..c8201ba0 100644 --- a/ic-agent/src/agent/status.rs +++ b/ic-agent/src/agent/status.rs @@ -40,7 +40,7 @@ impl std::fmt::Display for Value { /// The structure returned by [`super::Agent::status`], containing the information returned /// by the status endpoint of a replica. -#[derive(Debug, Ord, PartialOrd, PartialEq, Eq)] +#[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq)] pub struct Status { /// Optional. The precise git revision of the Internet Computer Protocol implementation. pub impl_version: Option, diff --git a/ic-transport-types/src/lib.rs b/ic-transport-types/src/lib.rs index 65fc6524..00d2f023 100644 --- a/ic-transport-types/src/lib.rs +++ b/ic-transport-types/src/lib.rs @@ -239,7 +239,7 @@ impl TryFrom for RejectCode { } /// Error returned from `RejectCode::try_from`. -#[derive(Debug, Error)] +#[derive(Debug, Clone, Error)] #[error("Invalid reject code {0}")] pub struct InvalidRejectCodeError(pub u64); diff --git a/ic-utils/src/call.rs b/ic-utils/src/call.rs index cccf69eb..d32a6044 100644 --- a/ic-utils/src/call.rs +++ b/ic-utils/src/call.rs @@ -207,7 +207,7 @@ where async fn call(self) -> Result { let result = self.call_raw().await?; - decode_args(&result).map_err(|e| AgentError::CandidError(Box::new(e))) + decode_args(&result).map_err(Into::into) } } @@ -263,7 +263,7 @@ where self.build_call()? .call_and_wait() .await - .and_then(|r| decode_args(&r).map_err(|e| AgentError::CandidError(Box::new(e)))) + .and_then(|r| decode_args(&r).map_err(Into::into)) } /// Equivalent to calling [`AsyncCall::call_and_wait`] with the expected return type `(T,)`. @@ -274,7 +274,7 @@ where self.build_call()? .call_and_wait() .await - .and_then(|r| decode_one(&r).map_err(|e| AgentError::CandidError(Box::new(e)))) + .and_then(|r| decode_one(&r).map_err(Into::into)) } /// See [`AsyncCall::map`]. diff --git a/ic-utils/src/interfaces/wallet.rs b/ic-utils/src/interfaces/wallet.rs index 514b2637..bbcf3242 100644 --- a/ic-utils/src/interfaces/wallet.rs +++ b/ic-utils/src/interfaces/wallet.rs @@ -113,8 +113,7 @@ where .build() .and_then(|(result,): (Result,)| async move { let result = result.map_err(AgentError::WalletCallFailed)?; - decode_args::(result.r#return.as_slice()) - .map_err(|e| AgentError::CandidError(Box::new(e))) + decode_args::(result.r#return.as_slice()).map_err(Into::into) })) } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index cca9dd55..07fca9a7 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -2,6 +2,6 @@ # MSRV # Avoid updating this field unless we use new Rust features # Sync rust-version in workspace Cargo.toml -channel = "1.70.0" +channel = "1.72.0" components = ["rustfmt", "clippy"] targets = ["wasm32-unknown-unknown"]