diff --git a/config-live-example.toml b/config-live-example.toml index c0a5adba..90d8f5f4 100644 --- a/config-live-example.toml +++ b/config-live-example.toml @@ -34,12 +34,7 @@ max_concurrent_seals = 4 sbundle_mergeable_signers = [] live_builders = ["mp-ordering", "mgp-ordering", "merging"] -[[relays]] -name = "flashbots" -url = "https://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@boost-relay.flashbots.net" -priority = 0 -use_ssz_for_submit = false -use_gzip_for_submit = false +enabled_relays = ["flashbots"] [[builders]] name = "mgp-ordering" diff --git a/config-optimism-local.toml b/config-optimism-local.toml index 9a374e4b..fe7063a2 100644 --- a/config-optimism-local.toml +++ b/config-optimism-local.toml @@ -24,6 +24,8 @@ ignore_cancellable_orders = true sbundle_mergeable_signers = [] live_builders = ["mp-ordering"] +enabled_relays = ["custom"] + [[relays]] name = "custom" url = "http://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@localhost:5555" diff --git a/config-playground.toml b/config-playground.toml index e950acd9..6d53e0a6 100644 --- a/config-playground.toml +++ b/config-playground.toml @@ -27,9 +27,4 @@ ignore_cancellable_orders = true sbundle_mergeable_signers = [] live_builders = ["mp-ordering", "mgp-ordering", "parallel"] -[[relays]] -name = "custom" -url = "http://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@localhost:5555" -priority = 0 -use_ssz_for_submit = false -use_gzip_for_submit = false \ No newline at end of file +enabled_relays = ["playground"] diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index 89fecbf3..9f085d23 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -45,6 +45,7 @@ use ethereum_consensus::{ builder::compute_builder_domain, primitives::Version, state_transition::Context as ContextEth, }; use eyre::Context; +use lazy_static::lazy_static; use reth::revm::cached::CachedReads; use reth_chainspec::{Chain, ChainSpec, NamedChain}; use reth_db::{Database, DatabaseEnv}; @@ -57,6 +58,7 @@ use reth_provider::{ }; use serde::Deserialize; use serde_with::{serde_as, OneOrMany}; +use std::collections::HashMap; use std::{ fmt::Debug, path::{Path, PathBuf}, @@ -107,6 +109,8 @@ pub struct Config { pub struct L1Config { // Relay Submission configuration pub relays: Vec, + pub enabled_relays: Vec, + pub dry_run: bool, #[serde_as(deserialize_as = "OneOrMany<_>")] pub dry_run_validation_url: Vec, @@ -138,6 +142,7 @@ impl Default for L1Config { fn default() -> Self { Self { relays: vec![], + enabled_relays: vec![], dry_run: false, dry_run_validation_url: vec![], relay_secret_key: "".into(), @@ -168,10 +173,48 @@ impl L1Config { } pub fn create_relays(&self) -> eyre::Result> { + let mut relay_configs = DEFAULT_RELAYS.clone(); + + // Update relay configs from user configuration - replace if found + for relay in self.relays.clone() { + relay_configs.insert(relay.name.clone(), relay); + } + + // For backwards compatibility: add all user-configured relays to enabled_relays + let mut effective_enabled_relays: std::collections::HashSet = + self.enabled_relays.iter().cloned().collect(); + effective_enabled_relays.extend(self.relays.iter().map(|r| r.name.clone())); + + // Create enabled relays let mut results = Vec::new(); - for relay in &self.relays { - results.push(MevBoostRelay::from_config(relay)?); + for relay_name in effective_enabled_relays.iter() { + match relay_configs.get(relay_name) { + Some(relay_config) => match MevBoostRelay::from_config(relay_config) { + Ok(relay) => { + info!( + "Created relay: {:?} (priority: {})", + relay_name, relay.priority + ); + results.push(relay); + } + Err(e) => { + return Err(eyre::eyre!( + "Failed to create relay {}: {:?}", + relay_name, + e + )); + } + }, + None => { + return Err(eyre::eyre!("Relay {} not found in relays list", relay_name)); + } + } } + + if results.is_empty() { + return Err(eyre::eyre!("No relays enabled")); + } + Ok(results) } @@ -579,6 +622,89 @@ fn get_signing_domain( Ok(B256::from(&compute_builder_domain(&cl_context)?)) } +lazy_static! { + static ref DEFAULT_RELAYS: HashMap = { + let mut map = HashMap::new(); + map.insert( + "flashbots".to_string(), + RelayConfig { + name: "flashbots".to_string(), + url: "http://k8s-default-boostrel-9f278153f5-947835446.us-east-2.elb.amazonaws.com" + .to_string(), + use_ssz_for_submit: true, + use_gzip_for_submit: false, + priority: 0, + optimistic: false, + interval_between_submissions_ms: Some(250), + authorization_header: None, + builder_id_header: None, + api_token_header: None, + }, + ); + map.insert( + "ultrasound-us".to_string(), + RelayConfig { + name: "ultrasound-us".to_string(), + url: "https://relay-builders-us.ultrasound.money".to_string(), + use_ssz_for_submit: true, + use_gzip_for_submit: true, + priority: 0, + optimistic: true, + interval_between_submissions_ms: None, + authorization_header: None, + builder_id_header: None, + api_token_header: None, + }, + ); + map.insert( + "ultrasound-eu".to_string(), + RelayConfig { + name: "ultrasound-eu".to_string(), + url: "https://relay-builders-eu.ultrasound.money".to_string(), + use_ssz_for_submit: true, + use_gzip_for_submit: true, + priority: 0, + optimistic: true, + interval_between_submissions_ms: None, + authorization_header: None, + builder_id_header: None, + api_token_header: None, + }, + ); + map.insert( + "agnostic".to_string(), + RelayConfig { + name: "agnostic".to_string(), + url: "https://0xa7ab7a996c8584251c8f925da3170bdfd6ebc75d50f5ddc4050a6fdc77f2a3b5fce2cc750d0865e05d7228af97d69561@agnostic-relay.net".to_string(), + use_ssz_for_submit: true, + use_gzip_for_submit: true, + priority: 0, + optimistic: true, + interval_between_submissions_ms: None, + authorization_header: None, + builder_id_header: None, + api_token_header: None, + }, + ); + map.insert( + "playground".to_string(), + RelayConfig { + name: "playground".to_string(), + url: "http://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@localhost:5555".to_string(), + priority: 0, + use_ssz_for_submit: false, + use_gzip_for_submit: false, + optimistic: false, + interval_between_submissions_ms: None, + authorization_header: None, + builder_id_header: None, + api_token_header: None, + }, + ); + map + }; +} + #[cfg(test)] mod test { use super::*; @@ -636,6 +762,19 @@ mod test { .contains(&"http://localhost:3500".to_string())); } + #[test] + fn test_parse_enabled_relays() { + let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + p.push("./src/live_builder/testdata/config_with_relay_override.toml"); + + let config: Config = load_config_toml_and_env(p.clone()).expect("Config load"); + + let relays = config.l1_config.create_relays().unwrap(); + assert_eq!(relays.len(), 1); + assert_eq!(relays[0].id, "playground"); + assert_eq!(relays[0].priority, 10); + } + #[test] fn test_parse_backtest_example_config() { let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/crates/rbuilder/src/live_builder/testdata/config_with_relay_override.toml b/crates/rbuilder/src/live_builder/testdata/config_with_relay_override.toml new file mode 100644 index 00000000..8510eb4a --- /dev/null +++ b/crates/rbuilder/src/live_builder/testdata/config_with_relay_override.toml @@ -0,0 +1,42 @@ +log_json = true +log_level = "info,rbuilder=debug" +redacted_telemetry_server_port = 6061 +redacted_telemetry_server_ip = "0.0.0.0" +full_telemetry_server_port = 6060 +full_telemetry_server_ip = "0.0.0.0" + +chain = "mainnet" +reth_datadir = "/mnt/data/reth" + +coinbase_secret_key = "env:COINBASE_SECRET_KEY" +relay_secret_key = "env:RELAY_SECRET_KEY" +optimistic_relay_secret_key = "env:OPTIMISTIC_RELAY_SECRET_KEY" + +# cl_node_url can be a single value, array of values, or passed by an environment variables with values separated with a comma +# cl_node_url = "http://localhost:3500" +cl_node_url = ["env:CL_NODE_URL"] +jsonrpc_server_port = 8645 +jsonrpc_server_ip = "0.0.0.0" +el_node_ipc_path = "/tmp/reth.ipc" +extra_data = "⚡🤖" + +blocklist_file_path = "./blocklist.json" + +dry_run = true +dry_run_validation_url = "http://localhost:8545" + +ignore_cancellable_orders = true + +max_concurrent_seals = 4 + +# genesis_fork_version = "0x00112233" + +sbundle_mergeable_signers = [] +live_builders = ["mp-ordering", "mgp-ordering", "merging"] + +enabled_relays = ["playground"] + +[[relays]] +name = "playground" +url = "http://example.com" +priority = 10