From 36cbce7c78b56dd68359084a5d8b03f84efed8fb Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Thu, 14 Nov 2024 20:34:12 +0200 Subject: [PATCH] feat(forge): allow `--verifier custom` option (#9311) * feat(forge): allow `--verifier custom` option * Changes after review: add description of custom verifier, reorg err message, add custom verifier api key * Fix descriptions * Update crates/verify/src/provider.rs Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> --- crates/common/src/retry.rs | 2 +- crates/verify/src/bytecode.rs | 5 +++++ crates/verify/src/provider.rs | 7 +++++++ crates/verify/src/verify.rs | 17 +++++++++++++++-- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/crates/common/src/retry.rs b/crates/common/src/retry.rs index 7f649c7ed35a..59ba2055f8a3 100644 --- a/crates/common/src/retry.rs +++ b/crates/common/src/retry.rs @@ -83,6 +83,6 @@ impl Retry { fn handle_err(&mut self, err: Error) { self.retries -= 1; - warn!("erroneous attempt ({} tries remaining): {}", self.retries, err.root_cause()); + let _ = sh_warn!("{} ({} tries remaining)", err.root_cause(), self.retries); } } diff --git a/crates/verify/src/bytecode.rs b/crates/verify/src/bytecode.rs index a8fc1ace7066..0c3f9e5b0a91 100644 --- a/crates/verify/src/bytecode.rs +++ b/crates/verify/src/bytecode.rs @@ -96,6 +96,11 @@ impl figment::Provider for VerifyBytecodeArgs { &self, ) -> Result, figment::Error> { let mut dict = self.etherscan.dict(); + + if let Some(api_key) = &self.verifier.verifier_api_key { + dict.insert("etherscan_api_key".into(), api_key.as_str().into()); + } + if let Some(block) = &self.block { dict.insert("block".into(), figment::value::Value::serialize(block)?); } diff --git a/crates/verify/src/provider.rs b/crates/verify/src/provider.rs index 6e5b29d5e34c..bc01bd9e304d 100644 --- a/crates/verify/src/provider.rs +++ b/crates/verify/src/provider.rs @@ -124,6 +124,7 @@ impl FromStr for VerificationProviderType { "s" | "sourcify" => Ok(Self::Sourcify), "b" | "blockscout" => Ok(Self::Blockscout), "o" | "oklink" => Ok(Self::Oklink), + "c" | "custom" => Ok(Self::Custom), _ => Err(format!("Unknown provider: {s}")), } } @@ -144,6 +145,9 @@ impl fmt::Display for VerificationProviderType { Self::Oklink => { write!(f, "oklink")?; } + Self::Custom => { + write!(f, "custom")?; + } }; Ok(()) } @@ -156,6 +160,8 @@ pub enum VerificationProviderType { Sourcify, Blockscout, Oklink, + /// Custom verification provider, requires compatibility with the Etherscan API. + Custom, } impl VerificationProviderType { @@ -171,6 +177,7 @@ impl VerificationProviderType { Self::Sourcify => Ok(Box::::default()), Self::Blockscout => Ok(Box::::default()), Self::Oklink => Ok(Box::::default()), + Self::Custom => Ok(Box::::default()), } } } diff --git a/crates/verify/src/verify.rs b/crates/verify/src/verify.rs index 5f3e55329d88..89cfd99aa676 100644 --- a/crates/verify/src/verify.rs +++ b/crates/verify/src/verify.rs @@ -31,14 +31,22 @@ pub struct VerifierArgs { #[arg(long, help_heading = "Verifier options", default_value = "etherscan", value_enum)] pub verifier: VerificationProviderType, - /// The verifier URL, if using a custom provider + /// The verifier API KEY, if using a custom provider. + #[arg(long, help_heading = "Verifier options", env = "VERIFIER_API_KEY")] + pub verifier_api_key: Option, + + /// The verifier URL, if using a custom provider. #[arg(long, help_heading = "Verifier options", env = "VERIFIER_URL")] pub verifier_url: Option, } impl Default for VerifierArgs { fn default() -> Self { - Self { verifier: VerificationProviderType::Etherscan, verifier_url: None } + Self { + verifier: VerificationProviderType::Etherscan, + verifier_api_key: None, + verifier_url: None, + } } } @@ -162,6 +170,11 @@ impl figment::Provider for VerifyArgs { if self.via_ir { dict.insert("via_ir".to_string(), figment::value::Value::serialize(self.via_ir)?); } + + if let Some(api_key) = &self.verifier.verifier_api_key { + dict.insert("etherscan_api_key".into(), api_key.as_str().into()); + } + Ok(figment::value::Map::from([(Config::selected_profile(), dict)])) } }