From b69e71342ec966b6fcdbb11b4b79438328c517f5 Mon Sep 17 00:00:00 2001 From: Dakota Brink <779390+codabrink@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:27:49 -0400 Subject: [PATCH] Upgrade default urls to paid/private if appropriate env vars are present (#1128) * Upgrade default urls to paid/private if appropriate env vars are present * still take the json file from a provided path * better description * log when default --- mls_validation_service/src/config.rs | 4 ++ mls_validation_service/src/main.rs | 5 +- .../src/scw_verifier/chain_urls_default.json | 6 +- xmtp_id/src/scw_verifier/mod.rs | 63 +++++++++++-------- xmtp_mls/src/utils/test.rs | 4 +- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/mls_validation_service/src/config.rs b/mls_validation_service/src/config.rs index 2fefae233..8de6da78d 100644 --- a/mls_validation_service/src/config.rs +++ b/mls_validation_service/src/config.rs @@ -10,4 +10,8 @@ pub(crate) struct Args { #[arg(long, default_value_t = 50052)] pub(crate) health_check_port: u32, + + // A path to a json file in the same format as chain_urls_default.json in the codebase. + #[arg(long)] + pub(crate) chain_urls: Option, } diff --git a/mls_validation_service/src/main.rs b/mls_validation_service/src/main.rs index dedcbc540..f3b5a0673 100644 --- a/mls_validation_service/src/main.rs +++ b/mls_validation_service/src/main.rs @@ -30,7 +30,10 @@ async fn main() -> Result<(), Box> { let health_server = health_check_server(args.health_check_port as u16); - let scw_verifier = MultiSmartContractSignatureVerifier::new_from_file("chain_urls.json"); + let scw_verifier = match args.chain_urls { + Some(path) => MultiSmartContractSignatureVerifier::new_from_file(path)?, + None => MultiSmartContractSignatureVerifier::default(), + }; let grpc_server = Server::builder() .add_service(ValidationApiServer::new(ValidationService::new( diff --git a/xmtp_id/src/scw_verifier/chain_urls_default.json b/xmtp_id/src/scw_verifier/chain_urls_default.json index a079c84b5..47f07c32b 100644 --- a/xmtp_id/src/scw_verifier/chain_urls_default.json +++ b/xmtp_id/src/scw_verifier/chain_urls_default.json @@ -1,5 +1,9 @@ { "1": "https://eth.llamarpc.com", + "10": "https://rpc.ankr.com/optimism", + "137": "https://polygon.llamarpc.com", + "324": "https://mainnet.era.zksync.io", "8453": "https://base.llamarpc.com", - "42161": "https://arbitrum.llamarpc.com" + "42161": "https://arbitrum.llamarpc.com", + "59144": "https://linea-rpc.publicnode.com" } diff --git a/xmtp_id/src/scw_verifier/mod.rs b/xmtp_id/src/scw_verifier/mod.rs index 9d69eb84d..002491151 100644 --- a/xmtp_id/src/scw_verifier/mod.rs +++ b/xmtp_id/src/scw_verifier/mod.rs @@ -8,8 +8,15 @@ use ethers::{ providers::{Http, Provider, ProviderError}, types::{BlockNumber, Bytes}, }; -use std::{collections::HashMap, fs, path::Path, str::FromStr}; +use std::{ + collections::HashMap, + env, + fs::{self}, + io, + path::Path, +}; use thiserror::Error; +use tracing::info; use url::Url; pub use chain_rpc_verifier::*; @@ -71,9 +78,17 @@ pub struct MultiSmartContractSignatureVerifier { verifiers: HashMap>, } +impl Default for MultiSmartContractSignatureVerifier { + fn default() -> Self { + let urls: HashMap = + serde_json::from_str(DEFAULT_CHAIN_URLS).expect("DEFAULT_CHAIN_URLS is malformatted"); + Self::new(urls).upgrade() + } +} + impl MultiSmartContractSignatureVerifier { pub fn new(urls: HashMap) -> Self { - let verifiers: HashMap> = urls + let verifiers = urls .into_iter() .map(|(chain_id, url)| { ( @@ -87,32 +102,28 @@ impl MultiSmartContractSignatureVerifier { Self { verifiers } } - pub fn new_from_file(path: impl AsRef) -> Self { - let path = path.as_ref(); - - let file_str; - let json = if path.exists() { - file_str = fs::read_to_string(path).unwrap_or_else(|_| panic!("{path:?} is missing")); - &file_str - } else { - DEFAULT_CHAIN_URLS - }; - - let json: HashMap = - serde_json::from_str(json).unwrap_or_else(|_| panic!("{path:?} is malformatted")); + pub fn new_from_file(path: impl AsRef) -> Result { + let json = fs::read_to_string(path.as_ref())?; + let urls: HashMap = serde_json::from_str(&json).map_err(|err| { + io::Error::new( + io::ErrorKind::InvalidData, + format!("Unable to deserialize json: {err:?}"), + ) + })?; - let urls = json - .into_iter() - .map(|(id, url)| { - ( - id, - Url::from_str(&url) - .unwrap_or_else(|_| panic!("unable to parse url in {path:?} ({url})")), - ) - }) - .collect(); + Ok(Self::new(urls)) + } - Self::new(urls) + /// Upgrade the default urls to paid/private/alternative urls if the env vars are present. + pub fn upgrade(mut self) -> Self { + self.verifiers.iter_mut().for_each(|(id, verif)| { + if let Ok(url) = env::var(format!("CHAIN_RPC_{id}")) { + *verif = Box::new(RpcSmartContractWalletVerifier::new(url)); + } else { + info!("No upgraded chain url for chain {id}, using default."); + }; + }); + self } } diff --git a/xmtp_mls/src/utils/test.rs b/xmtp_mls/src/utils/test.rs index 9f183ed49..fad72951e 100755 --- a/xmtp_mls/src/utils/test.rs +++ b/xmtp_mls/src/utils/test.rs @@ -109,9 +109,7 @@ impl ClientBuilder { pub async fn local_client(self) -> Self { self.api_client(::create_local().await) - .scw_signature_verifier(MultiSmartContractSignatureVerifier::new_from_file( - "chain_urls.json", - )) + .scw_signature_verifier(MultiSmartContractSignatureVerifier::default()) } pub async fn new_test_client(owner: &impl InboxOwner) -> Client {