Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions common/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct Config {
pub preconf_heartbeat_ms: u64,
// L2
pub l2_rpc_url: String,
pub l2_ws_rpc_url: String,
pub l2_auth_rpc_url: String,
pub l2_driver_url: String,
/// jwt secret file path for L2 EL and L2 driver
Expand Down Expand Up @@ -121,6 +122,34 @@ fn get_env_with_deprecation(new_key: &str, deprecated_key: &str) -> Option<Strin
}
}

fn resolve_l2_ws_rpc_url(
l2_rpc_url: &str,
configured_l2_ws_rpc_url: Option<String>,
) -> Result<String, Error> {
let (source, url) = match configured_l2_ws_rpc_url {
Some(url) => ("L2_WS_RPC_URL", url),
None => ("L2_RPC_URL", l2_rpc_url.to_string()),
};

let parsed = reqwest::Url::parse(&url)
.map_err(|error| anyhow::anyhow!("{source} must be a valid URL: {error}"))?;

if matches!(parsed.scheme(), "ws" | "wss") {
return Ok(url);
}

if source == "L2_RPC_URL" {
return Err(anyhow::anyhow!(
"L2_WS_RPC_URL must be set to a ws:// or wss:// URL when L2_RPC_URL does not use WebSocket"
));
}

Err(anyhow::anyhow!(
"L2_WS_RPC_URL must use the ws or wss scheme, got '{}'",
parsed.scheme()
))
}

impl Config {
pub fn read_env_variables() -> Result<Self, Error> {
// Load environment variables from .env file
Expand Down Expand Up @@ -501,6 +530,9 @@ impl Config {
"ws://127.0.0.1:1234".to_string()
});

let l2_ws_rpc_url =
resolve_l2_ws_rpc_url(&l2_rpc_url, std::env::var("L2_WS_RPC_URL").ok())?;

let l2_auth_rpc_url =
get_env_with_deprecation("L2_AUTH_RPC_URL", "TAIKO_GETH_AUTH_RPC_URL").unwrap_or_else(
|| {
Expand All @@ -518,6 +550,7 @@ impl Config {
let config = Self {
preconfer_address,
l2_rpc_url,
l2_ws_rpc_url,
l2_auth_rpc_url,
l2_driver_url,
catalyst_node_ecdsa_private_key,
Expand Down Expand Up @@ -580,6 +613,7 @@ impl Config {
r#"
Configuration:{}
L2 RPC URL: {},
L2 WebSocket RPC URL: {},
L2 auth RPC URL: {},
L2 driver URL: {},
L1 RPC URL: {},
Expand Down Expand Up @@ -636,6 +670,7 @@ internal server port: {}
"".to_string()
},
config.l2_rpc_url,
config.l2_ws_rpc_url,
config.l2_auth_rpc_url,
config.l2_driver_url,
match config.l1_rpc_urls.split_first() {
Expand Down Expand Up @@ -697,3 +732,47 @@ internal server port: {}
Ok(config)
}
}

#[cfg(test)]
mod tests {
use super::resolve_l2_ws_rpc_url;

#[test]
fn explicit_l2_ws_rpc_url_is_used_with_http_rpc() {
let resolved = resolve_l2_ws_rpc_url(
"http://127.0.0.1:8545",
Some("ws://127.0.0.1:8546".to_string()),
)
.unwrap();

assert_eq!(resolved, "ws://127.0.0.1:8546");
}

#[test]
fn legacy_websocket_l2_rpc_url_is_reused() {
let resolved = resolve_l2_ws_rpc_url("wss://l2.example", None).unwrap();

assert_eq!(resolved, "wss://l2.example");
}

#[test]
fn http_l2_rpc_url_requires_explicit_websocket_url() {
let error = resolve_l2_ws_rpc_url("https://l2.example", None)
.unwrap_err()
.to_string();

assert!(error.contains("L2_WS_RPC_URL must be set"));
}

#[test]
fn explicit_l2_ws_rpc_url_rejects_non_websocket_scheme() {
let error = resolve_l2_ws_rpc_url(
"http://127.0.0.1:8545",
Some("http://127.0.0.1:8546".to_string()),
)
.unwrap_err()
.to_string();

assert!(error.contains("L2_WS_RPC_URL must use the ws or wss scheme"));
}
}
2 changes: 1 addition & 1 deletion realtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub async fn create_realtime_node(
.first()
.ok_or_else(|| anyhow::anyhow!("L1 RPC URL is required"))?
.clone(),
config.l2_rpc_url.clone(),
config.l2_ws_rpc_url.clone(),
realtime_config.realtime_inbox,
cancel_token.clone(),
"ProposedAndProved",
Expand Down
2 changes: 1 addition & 1 deletion shasta/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub async fn create_shasta_node(
.first()
.expect("L1 RPC URL is required")
.clone(),
config.l2_rpc_url.clone(),
config.l2_ws_rpc_url.clone(),
shasta_config.shasta_inbox,
cancel_token.clone(),
"Proposed",
Expand Down