From 1f75ec92fb623e83be3cf733b5b32cb1e85350e4 Mon Sep 17 00:00:00 2001 From: acheron Date: Fri, 13 Dec 2024 14:52:47 +0100 Subject: [PATCH 1/3] cli: Fix custom `provider.cluster` --- cli/src/config.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/cli/src/config.rs b/cli/src/config.rs index c8a579f3a2..27ff2e52d0 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -7,7 +7,8 @@ use dirs::home_dir; use heck::ToSnakeCase; use reqwest::Url; use serde::de::{self, MapAccess, Visitor}; -use serde::{Deserialize, Deserializer, Serialize}; +use serde::ser::SerializeMap; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use solana_cli_config::{Config as SolanaConfig, CONFIG_FILE}; use solana_sdk::clock::Slot; use solana_sdk::pubkey::Pubkey; @@ -590,11 +591,29 @@ struct _Config { #[derive(Debug, Serialize, Deserialize)] struct Provider { - #[serde(deserialize_with = "des_cluster")] + #[serde(serialize_with = "ser_cluster", deserialize_with = "des_cluster")] cluster: Cluster, wallet: String, } +fn ser_cluster(cluster: &Cluster, s: S) -> Result { + match cluster { + Cluster::Custom(http, ws) => { + match (Url::parse(http), Url::parse(ws)) { + // If `ws` was derived from `http`, serialize `http` as string + (Ok(h), Ok(w)) if h.domain() == w.domain() => s.serialize_str(http), + _ => { + let mut map = s.serialize_map(Some(2))?; + map.serialize_entry("http", http)?; + map.serialize_entry("ws", ws)?; + map.end() + } + } + } + _ => s.serialize_str(&cluster.to_string()), + } +} + fn des_cluster<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, From b50dd425ca86c142cb3bcfd5d84dce76e049d865 Mon Sep 17 00:00:00 2001 From: acheron Date: Sat, 14 Dec 2024 19:01:39 +0100 Subject: [PATCH 2/3] cli: Add tests --- cli/src/config.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/cli/src/config.rs b/cli/src/config.rs index 27ff2e52d0..f38100aba5 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -1484,15 +1484,34 @@ mod tests { wallet = \"id.json\" "; - const CUSTOM_CONFIG: &str = " + #[test] + fn parse_custom_cluster_str() { + let config = Config::from_str( + " [provider] - cluster = { http = \"http://my-url.com\", ws = \"ws://my-url.com\" } + cluster = \"http://my-url.com\" wallet = \"id.json\" - "; + ", + ) + .unwrap(); + assert!(!config.features.skip_lint); + + // Make sure the layout of `provider.cluster` stays the same after serialization + assert!(config + .to_string() + .contains(r#"cluster = "http://my-url.com""#)); + } #[test] - fn parse_custom_cluster() { - let config = Config::from_str(CUSTOM_CONFIG).unwrap(); + fn parse_custom_cluster_map() { + let config = Config::from_str( + " + [provider] + cluster = { http = \"http://my-url.com\", ws = \"ws://my-url.com\" } + wallet = \"id.json\" + ", + ) + .unwrap(); assert!(!config.features.skip_lint); } From 6cf2638ccf654c5a7cef0cd9c4928f897b30de14 Mon Sep 17 00:00:00 2001 From: acheron Date: Sat, 14 Dec 2024 19:02:32 +0100 Subject: [PATCH 3/3] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e15cb1432d..ad4184eb8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,6 +102,7 @@ The minor version will be incremented upon a breaking change and the patch versi - cli: Avoid extra IDL generation during `verify` ([#3398](https://github.com/coral-xyz/anchor/pull/3398)). - lang: Require `zero` accounts to be unique ([#3409](https://github.com/coral-xyz/anchor/pull/3409)). - lang: Deduplicate `zero` accounts against `init` accounts ([#3422](https://github.com/coral-xyz/anchor/pull/3422)). +- cli: Fix custom `provider.cluster` ([#3428](https://github.com/coral-xyz/anchor/pull/3428)). ### Breaking