From b14bfbdba7ceb2673964298225b5a577071a9701 Mon Sep 17 00:00:00 2001 From: mikhailUshakoff Date: Thu, 16 Jul 2026 11:30:49 +0200 Subject: [PATCH 1/3] feat: use mtls for web3signer connection --- Cargo.lock | 13 +++- Cargo.toml | 1 + common/Cargo.toml | 2 + common/src/shared/transaction_monitor.rs | 2 +- common/src/signer/mod.rs | 12 ++-- common/src/signer/web3signer.rs | 35 +++++++--- common/src/utils/rpc_client.rs | 81 ++++++++++++++++++++++-- 7 files changed, 123 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9049f23f..ecbef21c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2360,6 +2360,8 @@ dependencies = [ "prometheus", "protocol", "reqwest", + "rustls", + "rustls-pemfile", "serde", "serde_json", "strum", @@ -2738,7 +2740,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] @@ -9778,6 +9780,15 @@ dependencies = [ "security-framework", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" version = "1.14.1" diff --git a/Cargo.toml b/Cargo.toml index b67abe9e..8264e25b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,6 +90,7 @@ rand_core = { version = "0.9", default-features = false } realtime = { path = "realtime" } reqwest = { version = "0.13", default-features = true, features = ["json"] } rustls = { version = "0.23", default-features = true } +rustls-pemfile = "2" secp256k1 = { version = "0.30", features = ["recovery", "rand"] } serde = { version = "1.0", default-features = false, features = ["derive"] } serde_json = { version = "1.0", default-features = false } diff --git a/common/Cargo.toml b/common/Cargo.toml index 9304add0..6a84d596 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -32,6 +32,8 @@ jsonwebtoken = { workspace = true } k256 = { workspace = true } prometheus = { workspace = true } reqwest = { workspace = true } +rustls = { workspace = true } +rustls-pemfile = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } strum = { workspace = true, features = ["derive"] } diff --git a/common/src/shared/transaction_monitor.rs b/common/src/shared/transaction_monitor.rs index 7f5a4b54..32acbc4b 100644 --- a/common/src/shared/transaction_monitor.rs +++ b/common/src/shared/transaction_monitor.rs @@ -42,7 +42,7 @@ pub struct TxMonitorHandles { pub tx_result_receiver: tokio::sync::oneshot::Receiver, } -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct TransactionMonitorConfig { min_priority_fee_per_gas_wei: u128, tx_fees_increase_percentage: u128, diff --git a/common/src/signer/mod.rs b/common/src/signer/mod.rs index ccc00334..33a5107d 100644 --- a/common/src/signer/mod.rs +++ b/common/src/signer/mod.rs @@ -6,9 +6,8 @@ use anyhow::Error; use std::str::FromStr; use std::sync::Arc; use tokio::time::Duration; -use web3signer::Web3Signer; +use web3signer::{Web3Signer, Web3SignerInfo}; -#[derive(Debug)] pub enum Signer { Web3signer(Arc, Address), PrivateKey(String, Address), @@ -17,15 +16,14 @@ pub enum Signer { const SIGNER_TIMEOUT: Duration = Duration::from_secs(10); pub async fn create_signer( - web3signer_url: Option, + web3signer_info: Option>, catalyst_node_ecdsa_private_key: Option, - preconfer_address: Option
, ) -> Result, Error> { - Ok(Arc::new(if let Some(web3signer_url) = web3signer_url { + Ok(Arc::new(if let Some(web3signer_info) = web3signer_info { let address = - preconfer_address.expect("preconfer address is required for web3signer usage"); + web3signer_info.signer_address.parse().expect("signer address is required for web3signer usage"); Signer::Web3signer( - Arc::new(Web3Signer::new(&web3signer_url, SIGNER_TIMEOUT, &address.to_string()).await?), + Arc::new(Web3Signer::new(web3signer_info).await?), address, ) } else if let Some(catalyst_node_ecdsa_private_key) = catalyst_node_ecdsa_private_key { diff --git a/common/src/signer/web3signer.rs b/common/src/signer/web3signer.rs index 7628954c..ec026491 100644 --- a/common/src/signer/web3signer.rs +++ b/common/src/signer/web3signer.rs @@ -1,4 +1,4 @@ -use crate::utils::rpc_client::JSONRPCClient; +use crate::utils::rpc_client::{JSONRPCClient, TlsConfig}; use alloy::{ consensus::{ Transaction, TxEnvelope, @@ -14,25 +14,40 @@ use hex; use serde_json::{Map, Value}; use std::sync::Arc; use std::time::Duration; +use std::path::PathBuf; use tracing::{debug, error, info}; -#[derive(Debug)] +pub struct Web3SignerInfo<'a> { + pub url: &'a str, + pub timeout: Duration, + pub signer_address: &'a str, + pub ca_cert: PathBuf, + pub client_cert: PathBuf, + pub client_key: PathBuf, +} + pub struct Web3Signer { client: JSONRPCClient, } impl Web3Signer { pub async fn new( - rpc_url: &str, - timeout: Duration, - signer_address: &str, + info: Web3SignerInfo<'_> ) -> Result { - info!("Web3Signer: Creating new Web3Signer with URL: {}", rpc_url); - let client = JSONRPCClient::new_with_timeout(rpc_url, timeout)?; - if !Self::is_signer_key_available(&client, signer_address).await? { + info!("Web3Signer: Creating new Web3Signer with URL: {}", info.url); + let client = JSONRPCClient::new_with_tls_and_timeout( + info.url, + info.timeout, + TlsConfig { + ca_cert: info.ca_cert, + client_cert: info.client_cert, + client_key: info.client_key, + }, + )?; + if !Self::is_signer_key_available(&client, info.signer_address).await? { return Err(anyhow::anyhow!( "Web3Signer: Signer key is not available for address {}", - signer_address + info.signer_address )); } Ok(Self { client }) @@ -137,7 +152,7 @@ impl Web3Signer { } } -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct Web3TxSigner { inner: Arc, address: Address, diff --git a/common/src/utils/rpc_client.rs b/common/src/utils/rpc_client.rs index cc64ed46..c22df784 100644 --- a/common/src/utils/rpc_client.rs +++ b/common/src/utils/rpc_client.rs @@ -3,11 +3,16 @@ use anyhow::Error; use http::{HeaderMap, HeaderValue}; use jsonrpsee::{ core::client::{ClientT, Error as JsonRpcError}, - http_client::{HttpClient, HttpClientBuilder}, + http_client::{CustomCertStore, HttpClient, HttpClientBuilder}, }; use jsonwebtoken::{Algorithm, EncodingKey, Header, encode}; +use rustls::RootCertStore; +use rustls::pki_types::{CertificateDer, PrivateKeyDer}; use serde::{Deserialize, Serialize}; use serde_json::Value; +use std::fs; +use std::io::BufReader; +use std::path::{Path, PathBuf}; use std::time::Duration; use tokio::sync::RwLock; @@ -33,12 +38,18 @@ fn create_jwt_token(secret: &[u8]) -> Result> )?) } -#[derive(Debug)] +pub struct TlsConfig { + pub ca_cert: PathBuf, + pub client_cert: PathBuf, + pub client_key: PathBuf, +} + pub struct JSONRPCClient { url: String, timeout: Duration, jwt_secret: Option<[u8; 32]>, client: RwLock, + tls_config: Option, } impl JSONRPCClient { @@ -62,6 +73,7 @@ impl JSONRPCClient { timeout, jwt_secret: Some(jwt_secret), client: RwLock::new(client), + tls_config: None, }) } @@ -97,6 +109,7 @@ impl JSONRPCClient { timeout, jwt_secret: None, client: RwLock::new(client), + tls_config: None, }) } @@ -108,6 +121,64 @@ impl JSONRPCClient { Ok(client) } + pub fn new_with_tls_and_timeout( + url: &str, + timeout: Duration, + tls_config: TlsConfig, + ) -> Result { + let client = Self::create_client_with_tls(url, timeout, &tls_config)?; + Ok(Self { + url: url.to_string(), + timeout, + jwt_secret: None, + client: RwLock::new(client), + tls_config: Some(tls_config), + }) + } + + fn load_certs(path: &Path) -> anyhow::Result>> { + let mut reader = BufReader::new(fs::File::open(path)?); + Ok(rustls_pemfile::certs(&mut reader).collect::, _>>()?) + } + + fn load_key(path: &Path) -> anyhow::Result> { + let mut reader = BufReader::new(fs::File::open(path)?); + rustls_pemfile::private_key(&mut reader)? + .ok_or_else(|| anyhow::anyhow!("no private key found in {}", path.display())) + } + + fn create_client_with_tls( + url: &str, + timeout: Duration, + tls_config: &TlsConfig, + ) -> Result { + // rustls 0.23 needs a process-wide default crypto provider installed once. + // jsonrpsee's own tls feature uses "ring", so match that here to avoid conflicts. + let _ = rustls::crypto::ring::default_provider().install_default(); + + // Trust anchor used to verify the *server's* certificate. + let mut roots = RootCertStore::empty(); + for cert in Self::load_certs(&tls_config.ca_cert)? { + roots.add(cert)?; + } + + // Our own identity, presented to the server for mTLS. + let client_certs = Self::load_certs(&tls_config.client_cert)?; + let client_key = Self::load_key(&tls_config.client_key)?; + + let tls_config: CustomCertStore = rustls::ClientConfig::builder() + .with_root_certificates(roots) + .with_client_auth_cert(client_certs, client_key)?; + + let client = HttpClientBuilder::new() + .request_timeout(timeout) + .with_custom_cert_store(tls_config) + .build(url) + .map_err(|e| anyhow::anyhow!("Failed to create HTTP client with TLS: {e}"))?; + + Ok(client) + } + pub async fn call_method(&self, method: &str, params: Vec) -> Result { let result = { let client_guard = self.client.read().await; @@ -153,8 +224,10 @@ impl JSONRPCClient { } async fn recreate_client(&self) -> Result<(), Error> { - let new_client = (if let Some(jwt_secret) = self.jwt_secret { - Self::create_client_with_jwt(&self.url, self.timeout, &jwt_secret) + let new_client = (if let Some(tls_config) = &self.tls_config { + Self::create_client_with_tls(&self.url, self.timeout, tls_config) + } else if let Some(jwt_secret) = &self.jwt_secret { + Self::create_client_with_jwt(&self.url, self.timeout, jwt_secret) } else { Self::create_client(&self.url, self.timeout) }) From 4f1d477073fdee6025d41763c9d67087fdab46e2 Mon Sep 17 00:00:00 2001 From: mikhailUshakoff Date: Fri, 17 Jul 2026 12:41:56 +0200 Subject: [PATCH 2/3] feat: read tls certificate from config --- common/src/config/mod.rs | 38 +++++++++++++++++++++-- common/src/l1/config.rs | 13 +++++--- common/src/shared/alloy_tools.rs | 6 ++-- common/src/signer/mod.rs | 23 +++++++------- common/src/signer/web3signer.rs | 26 ++++++---------- common/src/signer/web3signer_info.rs | 46 ++++++++++++++++++++++++++++ pacaya/src/l2/config.rs | 13 +++++--- 7 files changed, 120 insertions(+), 45 deletions(-) create mode 100644 common/src/signer/web3signer_info.rs diff --git a/common/src/config/mod.rs b/common/src/config/mod.rs index 2a0ab348..86b9d046 100644 --- a/common/src/config/mod.rs +++ b/common/src/config/mod.rs @@ -16,6 +16,9 @@ pub struct Config { pub preconfer_address: Option
, pub web3signer_l1_url: Option, pub web3signer_l2_url: Option, + pub web3signer_root_certificate_path: Option, + pub web3signer_client_certificate_path: Option, + pub web3signer_client_key_path: Option, pub catalyst_node_ecdsa_private_key: Option, // L1 pub l1_rpc_urls: Vec, @@ -141,22 +144,35 @@ impl Config { let web3signer_l1_url = std::env::var(WEB3SIGNER_L1_URL).ok(); const WEB3SIGNER_L2_URL: &str = "WEB3SIGNER_L2_URL"; let web3signer_l2_url = std::env::var(WEB3SIGNER_L2_URL).ok(); + const WEB3SIGNER_ROOT_CERTIFICATE_PATH: &str = "WEB3SIGNER_ROOT_CERTIFICATE_PATH"; + let web3signer_root_certificate_path = std::env::var(WEB3SIGNER_ROOT_CERTIFICATE_PATH).ok(); + const WEB3SIGNER_CLIENT_CERTIFICATE_PATH: &str = "WEB3SIGNER_CLIENT_CERTIFICATE_PATH"; + let web3signer_client_certificate_path = + std::env::var(WEB3SIGNER_CLIENT_CERTIFICATE_PATH).ok(); + const WEB3SIGNER_CLIENT_KEY_PATH: &str = "WEB3SIGNER_CLIENT_KEY_PATH"; + let web3signer_client_key_path = std::env::var(WEB3SIGNER_CLIENT_KEY_PATH).ok(); if catalyst_node_ecdsa_private_key.is_none() { if web3signer_l1_url.is_none() || web3signer_l2_url.is_none() || preconfer_address.is_none() + || web3signer_root_certificate_path.is_none() + || web3signer_client_certificate_path.is_none() + || web3signer_client_key_path.is_none() { return Err(anyhow::anyhow!( - "When {CATALYST_NODE_ECDSA_PRIVATE_KEY} is not set, {WEB3SIGNER_L1_URL}, {WEB3SIGNER_L2_URL} and {PRECONFER_ADDRESS} must be set" + "When {CATALYST_NODE_ECDSA_PRIVATE_KEY} is not set, {WEB3SIGNER_L1_URL}, {WEB3SIGNER_L2_URL}, {WEB3SIGNER_ROOT_CERTIFICATE_PATH}, {WEB3SIGNER_CLIENT_CERTIFICATE_PATH}, {WEB3SIGNER_CLIENT_KEY_PATH} and {PRECONFER_ADDRESS} must be set" )); } } else if web3signer_l1_url.is_some() || web3signer_l2_url.is_some() || preconfer_address.is_some() + || web3signer_root_certificate_path.is_some() + || web3signer_client_certificate_path.is_some() + || web3signer_client_key_path.is_some() { return Err(anyhow::anyhow!( - "When {CATALYST_NODE_ECDSA_PRIVATE_KEY} is set, {WEB3SIGNER_L1_URL}, {WEB3SIGNER_L2_URL} and {PRECONFER_ADDRESS} must not be set" + "When {CATALYST_NODE_ECDSA_PRIVATE_KEY} is set, {WEB3SIGNER_L1_URL}, {WEB3SIGNER_L2_URL}, {WEB3SIGNER_ROOT_CERTIFICATE_PATH}, {WEB3SIGNER_CLIENT_CERTIFICATE_PATH}, {WEB3SIGNER_CLIENT_KEY_PATH} and {PRECONFER_ADDRESS} must not be set" )); } @@ -531,6 +547,9 @@ impl Config { blob_indexer_url: std::env::var("BLOB_INDEXER_URL").ok(), web3signer_l1_url, web3signer_l2_url, + web3signer_root_certificate_path, + web3signer_client_certificate_path, + web3signer_client_key_path, l1_slot_duration_sec, l1_slots_per_epoch, preconf_heartbeat_ms, @@ -588,6 +607,9 @@ Consensus layer timeout: {}ms, Blob Indexer URL: {}, Web3signer L1 URL: {}, Web3signer L2 URL: {}, +Web3signer root certificate path: {}, +Web3signer client certificate path: {}, +Web3signer client key path: {}, L1 slot duration: {}s L1 slots per epoch: {} L2 slot duration (heart beat): {} @@ -651,6 +673,18 @@ internal server port: {} config.blob_indexer_url.as_deref().unwrap_or("not set"), config.web3signer_l1_url.as_deref().unwrap_or("not set"), config.web3signer_l2_url.as_deref().unwrap_or("not set"), + config + .web3signer_root_certificate_path + .as_deref() + .unwrap_or("not set"), + config + .web3signer_client_certificate_path + .as_deref() + .unwrap_or("not set"), + config + .web3signer_client_key_path + .as_deref() + .unwrap_or("not set"), config.l1_slot_duration_sec, config.l1_slots_per_epoch, config.preconf_heartbeat_ms, diff --git a/common/src/l1/config.rs b/common/src/l1/config.rs index 970de99c..c15032ed 100644 --- a/common/src/l1/config.rs +++ b/common/src/l1/config.rs @@ -1,5 +1,5 @@ use crate::config::Config; -use crate::signer::{Signer, create_signer}; +use crate::signer::{Signer, Web3SignerInfo, create_signer}; use alloy::primitives::Address; use anyhow::Error; use std::sync::Arc; @@ -26,12 +26,15 @@ pub struct EthereumL1Config { impl EthereumL1Config { pub async fn new(config: &Config) -> Result { - let signer = create_signer( + let w3s_info = Web3SignerInfo::new( config.web3signer_l1_url.clone(), - config.catalyst_node_ecdsa_private_key.clone(), + config.web3signer_root_certificate_path.clone(), + config.web3signer_client_certificate_path.clone(), + config.web3signer_client_key_path.clone(), config.preconfer_address, - ) - .await?; + )?; + let signer = + create_signer(w3s_info, config.catalyst_node_ecdsa_private_key.clone()).await?; Ok(Self { execution_rpc_urls: config.l1_rpc_urls.clone(), diff --git a/common/src/shared/alloy_tools.rs b/common/src/shared/alloy_tools.rs index 3bc8df9a..5a89a578 100644 --- a/common/src/shared/alloy_tools.rs +++ b/common/src/shared/alloy_tools.rs @@ -94,10 +94,8 @@ pub async fn construct_alloy_provider( ); let preconfer_address = *address; - let tx_signer = crate::signer::web3signer::Web3TxSigner::new( - web3signer.clone(), - preconfer_address, - )?; + let tx_signer = + crate::signer::Web3TxSigner::new(web3signer.clone(), preconfer_address)?; let wallet = EthereumWallet::new(tx_signer); Ok(create_alloy_provider_with_wallet(wallet, execution_ws_rpc_url).await?) diff --git a/common/src/signer/mod.rs b/common/src/signer/mod.rs index 33a5107d..05836b88 100644 --- a/common/src/signer/mod.rs +++ b/common/src/signer/mod.rs @@ -1,31 +1,30 @@ -pub mod web3signer; +mod web3signer; +mod web3signer_info; use alloy::primitives::Address; use alloy::signers::local::PrivateKeySigner; use anyhow::Error; use std::str::FromStr; use std::sync::Arc; -use tokio::time::Duration; -use web3signer::{Web3Signer, Web3SignerInfo}; +use web3signer::Web3Signer; +pub use web3signer::Web3TxSigner; +pub use web3signer_info::Web3SignerInfo; pub enum Signer { Web3signer(Arc, Address), PrivateKey(String, Address), } -const SIGNER_TIMEOUT: Duration = Duration::from_secs(10); - pub async fn create_signer( - web3signer_info: Option>, + web3signer_info: Option, catalyst_node_ecdsa_private_key: Option, ) -> Result, Error> { Ok(Arc::new(if let Some(web3signer_info) = web3signer_info { - let address = - web3signer_info.signer_address.parse().expect("signer address is required for web3signer usage"); - Signer::Web3signer( - Arc::new(Web3Signer::new(web3signer_info).await?), - address, - ) + let address = web3signer_info + .signer_address + .parse() + .expect("signer address is required for web3signer usage"); + Signer::Web3signer(Arc::new(Web3Signer::new(web3signer_info).await?), address) } else if let Some(catalyst_node_ecdsa_private_key) = catalyst_node_ecdsa_private_key { let signer = PrivateKeySigner::from_str(catalyst_node_ecdsa_private_key.as_str())?; Signer::PrivateKey(catalyst_node_ecdsa_private_key, signer.address()) diff --git a/common/src/signer/web3signer.rs b/common/src/signer/web3signer.rs index ec026491..d5b190b7 100644 --- a/common/src/signer/web3signer.rs +++ b/common/src/signer/web3signer.rs @@ -1,4 +1,7 @@ -use crate::utils::rpc_client::{JSONRPCClient, TlsConfig}; +use crate::{ + signer::web3signer_info::Web3SignerInfo, + utils::rpc_client::{JSONRPCClient, TlsConfig}, +}; use alloy::{ consensus::{ Transaction, TxEnvelope, @@ -13,30 +16,18 @@ use async_trait::async_trait; use hex; use serde_json::{Map, Value}; use std::sync::Arc; -use std::time::Duration; -use std::path::PathBuf; -use tracing::{debug, error, info}; -pub struct Web3SignerInfo<'a> { - pub url: &'a str, - pub timeout: Duration, - pub signer_address: &'a str, - pub ca_cert: PathBuf, - pub client_cert: PathBuf, - pub client_key: PathBuf, -} +use tracing::{debug, error, info}; pub struct Web3Signer { client: JSONRPCClient, } impl Web3Signer { - pub async fn new( - info: Web3SignerInfo<'_> - ) -> Result { + pub async fn new(info: Web3SignerInfo) -> Result { info!("Web3Signer: Creating new Web3Signer with URL: {}", info.url); let client = JSONRPCClient::new_with_tls_and_timeout( - info.url, + &info.url, info.timeout, TlsConfig { ca_cert: info.ca_cert, @@ -44,7 +35,7 @@ impl Web3Signer { client_key: info.client_key, }, )?; - if !Self::is_signer_key_available(&client, info.signer_address).await? { + if !Self::is_signer_key_available(&client, &info.signer_address).await? { return Err(anyhow::anyhow!( "Web3Signer: Signer key is not available for address {}", info.signer_address @@ -223,6 +214,7 @@ async fn check_signer_correctness(tx_envelope: &TxEnvelope, from: Address) -> bo #[cfg(test)] mod tests { use super::*; + use std::time::Duration; #[tokio::test] async fn test_is_signer_key_available() { diff --git a/common/src/signer/web3signer_info.rs b/common/src/signer/web3signer_info.rs new file mode 100644 index 00000000..b9d1da6f --- /dev/null +++ b/common/src/signer/web3signer_info.rs @@ -0,0 +1,46 @@ +use alloy::primitives::Address; +use anyhow::{Result, anyhow}; +use std::path::PathBuf; +use std::time::Duration; + +const SIGNER_TIMEOUT: Duration = Duration::from_secs(10); +pub struct Web3SignerInfo { + pub url: String, + pub timeout: Duration, + pub signer_address: String, + pub ca_cert: PathBuf, + pub client_cert: PathBuf, + pub client_key: PathBuf, +} + +impl Web3SignerInfo { + pub fn new( + web3signer_url: Option, + web3signer_root_certificate_path: Option, + web3signer_client_certificate_path: Option, + web3signer_client_key_path: Option, + preconfer_address: Option
, + ) -> Result> { + let Some(url) = web3signer_url else { + // Web3Signer is not configured. + return Ok(None); + }; + + Ok(Some(Self { + url, + timeout: SIGNER_TIMEOUT, + signer_address: preconfer_address + .ok_or_else(|| anyhow!("preconfer_address is required when using Web3Signer"))? + .to_string(), + ca_cert: PathBuf::from(web3signer_root_certificate_path.ok_or_else(|| { + anyhow!("web3signer_root_certificate_path is required when using Web3Signer") + })?), + client_cert: PathBuf::from(web3signer_client_certificate_path.ok_or_else(|| { + anyhow!("web3signer_client_certificate_path is required when using Web3Signer") + })?), + client_key: PathBuf::from(web3signer_client_key_path.ok_or_else(|| { + anyhow!("web3signer_client_key_path is required when using Web3Signer") + })?), + })) + } +} diff --git a/pacaya/src/l2/config.rs b/pacaya/src/l2/config.rs index 619485fb..7ce8a8d1 100644 --- a/pacaya/src/l2/config.rs +++ b/pacaya/src/l2/config.rs @@ -1,7 +1,7 @@ use alloy::primitives::Address; use anyhow::Error; use common::config::Config; -use common::signer::{Signer, create_signer}; +use common::signer::{Signer, Web3SignerInfo, create_signer}; use std::sync::Arc; use std::time::Duration; @@ -24,12 +24,15 @@ impl TaikoConfig { let jwt_secret_bytes = common::utils::file_operations::read_jwt_secret(&config.jwt_secret_file_path) .map_err(|e| anyhow::anyhow!("Failed to read JWT secret for Taiko: {}", e))?; - let signer = create_signer( + let w3s_info = Web3SignerInfo::new( config.web3signer_l2_url.clone(), - config.catalyst_node_ecdsa_private_key.clone(), + config.web3signer_root_certificate_path.clone(), + config.web3signer_client_certificate_path.clone(), + config.web3signer_client_key_path.clone(), config.preconfer_address, - ) - .await?; + )?; + let signer = + create_signer(w3s_info, config.catalyst_node_ecdsa_private_key.clone()).await?; Ok(Self { l2_rpc_url: config.l2_rpc_url.clone(), From 05f42dfe0047a7fc0a9f8f2121e6e88a4eca1c2b Mon Sep 17 00:00:00 2001 From: mikhailUshakoff Date: Fri, 17 Jul 2026 16:05:52 +0200 Subject: [PATCH 3/3] fix: remove redundant dependency --- Cargo.lock | 10 ---------- Cargo.toml | 1 - common/Cargo.toml | 1 - common/src/utils/rpc_client.rs | 11 +++-------- 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecbef21c..7db93510 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2361,7 +2361,6 @@ dependencies = [ "protocol", "reqwest", "rustls", - "rustls-pemfile", "serde", "serde_json", "strum", @@ -9780,15 +9779,6 @@ dependencies = [ "security-framework", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.14.1" diff --git a/Cargo.toml b/Cargo.toml index 8264e25b..b67abe9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,7 +90,6 @@ rand_core = { version = "0.9", default-features = false } realtime = { path = "realtime" } reqwest = { version = "0.13", default-features = true, features = ["json"] } rustls = { version = "0.23", default-features = true } -rustls-pemfile = "2" secp256k1 = { version = "0.30", features = ["recovery", "rand"] } serde = { version = "1.0", default-features = false, features = ["derive"] } serde_json = { version = "1.0", default-features = false } diff --git a/common/Cargo.toml b/common/Cargo.toml index 6a84d596..9fa7367f 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -33,7 +33,6 @@ k256 = { workspace = true } prometheus = { workspace = true } reqwest = { workspace = true } rustls = { workspace = true } -rustls-pemfile = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } strum = { workspace = true, features = ["derive"] } diff --git a/common/src/utils/rpc_client.rs b/common/src/utils/rpc_client.rs index c22df784..85d498d1 100644 --- a/common/src/utils/rpc_client.rs +++ b/common/src/utils/rpc_client.rs @@ -7,11 +7,9 @@ use jsonrpsee::{ }; use jsonwebtoken::{Algorithm, EncodingKey, Header, encode}; use rustls::RootCertStore; -use rustls::pki_types::{CertificateDer, PrivateKeyDer}; +use rustls::pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}; use serde::{Deserialize, Serialize}; use serde_json::Value; -use std::fs; -use std::io::BufReader; use std::path::{Path, PathBuf}; use std::time::Duration; use tokio::sync::RwLock; @@ -137,14 +135,11 @@ impl JSONRPCClient { } fn load_certs(path: &Path) -> anyhow::Result>> { - let mut reader = BufReader::new(fs::File::open(path)?); - Ok(rustls_pemfile::certs(&mut reader).collect::, _>>()?) + Ok(CertificateDer::pem_file_iter(path)?.collect::, _>>()?) } fn load_key(path: &Path) -> anyhow::Result> { - let mut reader = BufReader::new(fs::File::open(path)?); - rustls_pemfile::private_key(&mut reader)? - .ok_or_else(|| anyhow::anyhow!("no private key found in {}", path.display())) + Ok(PrivateKeyDer::from_pem_file(path)?) } fn create_client_with_tls(