From c1c6b62d401d730115b6285c2aad850d896accdb Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 31 Dec 2024 11:20:59 +0100 Subject: [PATCH 01/12] Add list of default relays and config to enable them --- config-playground.toml | 7 +- crates/rbuilder/src/live_builder/config.rs | 82 +++++++++++++++++++++- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/config-playground.toml b/config-playground.toml index 114ecc22..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 +enabled_relays = ["playground"] diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index bf17e5c0..b65fca91 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -108,6 +108,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,7 +140,70 @@ pub struct L1Config { impl Default for L1Config { fn default() -> Self { Self { - relays: vec![], + relays: vec![ + 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, + }, + 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, + }, + 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, + }, + 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, + }, + // Local relay configuration for the playground + 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, + } + ], + enabled_relays: vec![], dry_run: false, dry_run_validation_url: vec![], relay_secret_key: "".into(), @@ -170,8 +235,19 @@ impl L1Config { pub fn create_relays(&self) -> eyre::Result> { let mut results = Vec::new(); - for relay in &self.relays { - results.push(MevBoostRelay::from_config(relay)?); + for relay_name in &self.enabled_relays { + match self.relays.iter().find(|r| r.name == *relay_name) { + Some(relay) => { + match MevBoostRelay::from_config(relay) { + 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)), + } } Ok(results) } From 1124f4bb40b9422d5904a54721a2866f66a19ad9 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 31 Dec 2024 17:54:54 +0100 Subject: [PATCH 02/12] Fix --- crates/rbuilder/src/live_builder/config.rs | 205 +++++++++++------- .../testdata/config_with_relay_empty_url.toml | 41 ++++ .../testdata/config_with_relay_override.toml | 41 ++++ crates/rbuilder/src/primitives/mev_boost.rs | 39 +++- 4 files changed, 249 insertions(+), 77 deletions(-) create mode 100644 crates/rbuilder/src/live_builder/testdata/config_with_relay_empty_url.toml create mode 100644 crates/rbuilder/src/live_builder/testdata/config_with_relay_override.toml diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index b65fca91..9bf79fc1 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -46,6 +46,7 @@ use ethereum_consensus::{ 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}; @@ -65,7 +66,7 @@ use std::{ sync::Arc, time::Duration, }; -use tracing::info; +use tracing::{info, warn}; use url::Url; /// We initialize the wallet with the last full day. This should be enough for any bidder. @@ -140,69 +141,7 @@ pub struct L1Config { impl Default for L1Config { fn default() -> Self { Self { - relays: vec![ - 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, - }, - 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, - }, - 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, - }, - 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, - }, - // Local relay configuration for the playground - 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, - } - ], + relays: vec![], enabled_relays: vec![], dry_run: false, dry_run_validation_url: vec![], @@ -234,18 +173,45 @@ impl L1Config { } pub fn create_relays(&self) -> eyre::Result> { + let mut relays = DEFAULT_RELAYS.to_vec(); + + for relay in self.relays.clone() { + if let Some(default) = relays.iter_mut().find(|d| d.name == relay.name) { + // If found in defaults, update it with an or operation + *default = default.clone() | relay.clone(); + } else { + // If not found in defaults, add as new relay + relays.push(relay.clone()); + } + + // Emit warning if this relay is defined but not enabled + if !self.enabled_relays.contains(&relay.name) { + warn!( + "Relay '{}' is defined but not enabled in enabled_relays", + relay.name + ); + } + } + let mut results = Vec::new(); for relay_name in &self.enabled_relays { - match self.relays.iter().find(|r| r.name == *relay_name) { - Some(relay) => { - match MevBoostRelay::from_config(relay) { - 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)), + match relays.iter().find(|r| r.name == *relay_name) { + Some(relay) => match MevBoostRelay::from_config(relay) { + 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)), } } @@ -672,6 +638,72 @@ fn get_signing_domain( Ok(B256::from(&compute_builder_domain(&cl_context)?)) } +lazy_static! { + static ref DEFAULT_RELAYS: Vec = vec![ + RelayConfig { + name: "flashbots".to_string(), + url: Some("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, + }, + RelayConfig { + name: "ultrasound-us".to_string(), + url: Some("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, + }, + RelayConfig { + name: "ultrasound-eu".to_string(), + url: Some("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, + }, + RelayConfig { + name: "agnostic".to_string(), + url:Some("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, + }, + // Local relay configuration for the playground + RelayConfig { + name: "playground".to_string(), + url:Some("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, + } + ]; +} + #[cfg(test)] mod test { use super::*; @@ -729,6 +761,33 @@ 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_empty_relay_url() { + let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + p.push("./src/live_builder/testdata/config_with_relay_empty_url.toml"); + + let config: Config = load_config_toml_and_env(p).expect("Config load"); + assert!(config + .l1_config + .create_relays() + .unwrap_err() + .to_string() + .contains("url is required")); + } + #[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_empty_url.toml b/crates/rbuilder/src/live_builder/testdata/config_with_relay_empty_url.toml new file mode 100644 index 00000000..dc7f7ffa --- /dev/null +++ b/crates/rbuilder/src/live_builder/testdata/config_with_relay_empty_url.toml @@ -0,0 +1,41 @@ +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 = ["custom"] + +[[relays]] +name = "custom" +priority = 10 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..5b9afae7 --- /dev/null +++ b/crates/rbuilder/src/live_builder/testdata/config_with_relay_override.toml @@ -0,0 +1,41 @@ +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" +priority = 10 diff --git a/crates/rbuilder/src/primitives/mev_boost.rs b/crates/rbuilder/src/primitives/mev_boost.rs index 0881ef1a..1457d8da 100644 --- a/crates/rbuilder/src/primitives/mev_boost.rs +++ b/crates/rbuilder/src/primitives/mev_boost.rs @@ -1,6 +1,7 @@ use crate::mev_boost::{RelayClient, SubmitBlockErr, SubmitBlockRequest}; use governor::{DefaultDirectRateLimiter, Quota, RateLimiter}; use serde::{Deserialize, Deserializer}; +use std::ops::BitOr; use std::{env, sync::Arc, time::Duration}; use url::Url; @@ -11,7 +12,8 @@ pub type MevBoostRelayID = String; #[serde(deny_unknown_fields)] pub struct RelayConfig { pub name: String, - pub url: String, + pub url: Option, + #[serde(default)] pub priority: usize, // true->ssz false->json #[serde(default)] @@ -33,7 +35,7 @@ pub struct RelayConfig { impl RelayConfig { pub fn with_url(self, url: &str) -> Self { Self { - url: url.to_string(), + url: Some(url.to_string()), ..self } } @@ -46,6 +48,30 @@ impl RelayConfig { } } +impl BitOr for RelayConfig { + type Output = Self; + + fn bitor(self, other: Self) -> Self { + if self.name != other.name { + return self; + } + Self { + name: self.name, + url: other.url.or(self.url), + priority: self.priority | other.priority, + use_ssz_for_submit: self.use_ssz_for_submit | other.use_ssz_for_submit, + use_gzip_for_submit: self.use_gzip_for_submit | other.use_gzip_for_submit, + optimistic: self.optimistic | other.optimistic, + authorization_header: other.authorization_header.or(self.authorization_header), + builder_id_header: other.builder_id_header.or(self.builder_id_header), + api_token_header: other.api_token_header.or(self.api_token_header), + interval_between_submissions_ms: other + .interval_between_submissions_ms + .or(self.interval_between_submissions_ms), + } + } +} + /// Wrapper over RelayClient that allows to submit blocks and /// hides the particular configuration (eg: ssz, gip, optimistic). /// Sometimes the client is used externally. @@ -66,8 +92,13 @@ pub struct MevBoostRelay { impl MevBoostRelay { pub fn from_config(config: &RelayConfig) -> eyre::Result { + let url = config + .url + .as_ref() + .ok_or_else(|| eyre::eyre!("url is required"))?; + let client = { - let url: Url = config.url.parse()?; + let url: Url = url.parse()?; RelayClient::from_url( url, config.authorization_header.clone(), @@ -135,7 +166,7 @@ mod test { let config: RelayConfig = toml::from_str(example).unwrap(); assert_eq!(config.name, "relay1"); - assert_eq!(config.url, "url"); + assert_eq!(config.url.expect("url expected"), "url"); assert_eq!(config.priority, 0); assert_eq!(config.authorization_header.unwrap(), "AAA"); assert_eq!(config.builder_id_header.unwrap(), "BBB"); From ccfa807c7fb24058a40b2b15576bcc165418732b Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 31 Dec 2024 17:55:42 +0100 Subject: [PATCH 03/12] Update config files --- config-live-example.toml | 7 +------ config-optimism-local.toml | 2 ++ 2 files changed, 3 insertions(+), 6 deletions(-) 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" From 9963b7c2a7f5055c58001814e87cc100e3884d21 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Fri, 3 Jan 2025 17:19:07 +0100 Subject: [PATCH 04/12] Use hashmap --- crates/rbuilder/src/live_builder/config.rs | 182 ++++++++++++--------- 1 file changed, 105 insertions(+), 77 deletions(-) diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index 04169d17..958e0ed5 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -58,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}, @@ -172,18 +173,18 @@ impl L1Config { } pub fn create_relays(&self) -> eyre::Result> { - let mut relays = DEFAULT_RELAYS.to_vec(); + let mut relay_configs = DEFAULT_RELAYS.clone(); + // Update or add new relay configs from user configuration for relay in self.relays.clone() { - if let Some(default) = relays.iter_mut().find(|d| d.name == relay.name) { - // If found in defaults, update it with an or operation - *default = default.clone() | relay.clone(); - } else { - // If not found in defaults, add as new relay - relays.push(relay.clone()); - } + relay_configs + .entry(relay.name.clone()) + .and_modify(|default| *default = default.clone() | relay.clone()) + .or_insert(relay); + } - // Emit warning if this relay is defined but not enabled + // Warn about defined but not enabled relays + for relay in &self.relays { if !self.enabled_relays.contains(&relay.name) { warn!( "Relay '{}' is defined but not enabled in enabled_relays", @@ -192,28 +193,36 @@ impl L1Config { } } + // Create enabled relays let mut results = Vec::new(); for relay_name in &self.enabled_relays { - match relays.iter().find(|r| r.name == *relay_name) { - Some(relay) => match MevBoostRelay::from_config(relay) { + 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) + 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)), + 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) } @@ -622,69 +631,88 @@ fn get_signing_domain( } lazy_static! { - static ref DEFAULT_RELAYS: Vec = vec![ - RelayConfig { - name: "flashbots".to_string(), - url: Some("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, - }, - RelayConfig { - name: "ultrasound-us".to_string(), - url: Some("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, - }, - RelayConfig { - name: "ultrasound-eu".to_string(), - url: Some("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, - }, - RelayConfig { - name: "agnostic".to_string(), - url:Some("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, - }, - // Local relay configuration for the playground - RelayConfig { - name: "playground".to_string(), - url:Some("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, - } - ]; + static ref DEFAULT_RELAYS: HashMap = { + let mut map = HashMap::new(); + map.insert( + "flashbots".to_string(), + RelayConfig { + name: "flashbots".to_string(), + url: Some( + "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: Some("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: Some("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: Some("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: Some("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)] From 3ce1010aff7dfa4b5fc40bc70c03748ec054c640 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Fri, 3 Jan 2025 17:30:35 +0100 Subject: [PATCH 05/12] Keep backward compatibility --- crates/rbuilder/src/live_builder/config.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index 958e0ed5..0d45dc6c 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -183,19 +183,13 @@ impl L1Config { .or_insert(relay); } - // Warn about defined but not enabled relays - for relay in &self.relays { - if !self.enabled_relays.contains(&relay.name) { - warn!( - "Relay '{}' is defined but not enabled in enabled_relays", - relay.name - ); - } - } + // For backwards compatibility: add all user-configured relays to enabled_relays + let mut effective_enabled_relays: Vec = self.enabled_relays.clone(); + effective_enabled_relays.extend(self.relays.iter().map(|r| r.name.clone())); // Create enabled relays let mut results = Vec::new(); - for relay_name in &self.enabled_relays { + for relay_name in &effective_enabled_relays { match relay_configs.get(relay_name) { Some(relay_config) => match MevBoostRelay::from_config(relay_config) { Ok(relay) => { From 120a8d6e47020c8f4cced69260ad8ab0ebcda027 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Fri, 3 Jan 2025 17:33:57 +0100 Subject: [PATCH 06/12] Fix lint --- crates/rbuilder/src/live_builder/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index 0d45dc6c..52c42754 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -66,7 +66,7 @@ use std::{ sync::Arc, time::Duration, }; -use tracing::{info, warn}; +use tracing::info; use url::Url; /// We initialize the wallet with the last full day. This should be enough for any bidder. From 0e206161a4f41dd3565e66baa6378756a8e7de42 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Sat, 4 Jan 2025 00:18:43 +0100 Subject: [PATCH 07/12] Fix test --- crates/rbuilder/src/live_builder/config.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index 52c42754..d626470f 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -184,8 +184,10 @@ impl L1Config { } // For backwards compatibility: add all user-configured relays to enabled_relays - let mut effective_enabled_relays: Vec = self.enabled_relays.clone(); + 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())); + let effective_enabled_relays: Vec = effective_enabled_relays.into_iter().collect(); // Create enabled relays let mut results = Vec::new(); From ddc821ee4aa110ac1e7f723eac3da90f580a6387 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 6 Jan 2025 18:41:53 +0000 Subject: [PATCH 08/12] Do not override configs, just replace them --- crates/rbuilder/src/live_builder/config.rs | 21 +++++------ crates/rbuilder/src/primitives/mev_boost.rs | 40 +++------------------ 2 files changed, 12 insertions(+), 49 deletions(-) diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index d626470f..c501047c 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -175,12 +175,9 @@ impl L1Config { pub fn create_relays(&self) -> eyre::Result> { let mut relay_configs = DEFAULT_RELAYS.clone(); - // Update or add new relay configs from user configuration + // Update relay configs from user configuration - replace if found for relay in self.relays.clone() { - relay_configs - .entry(relay.name.clone()) - .and_modify(|default| *default = default.clone() | relay.clone()) - .or_insert(relay); + relay_configs.insert(relay.name.clone(), relay); } // For backwards compatibility: add all user-configured relays to enabled_relays @@ -633,10 +630,8 @@ lazy_static! { "flashbots".to_string(), RelayConfig { name: "flashbots".to_string(), - url: Some( - "http://k8s-default-boostrel-9f278153f5-947835446.us-east-2.elb.amazonaws.com" - .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, @@ -651,7 +646,7 @@ lazy_static! { "ultrasound-us".to_string(), RelayConfig { name: "ultrasound-us".to_string(), - url: Some("https://relay-builders-us.ultrasound.money".to_string()), + url: "https://relay-builders-us.ultrasound.money".to_string(), use_ssz_for_submit: true, use_gzip_for_submit: true, priority: 0, @@ -666,7 +661,7 @@ lazy_static! { "ultrasound-eu".to_string(), RelayConfig { name: "ultrasound-eu".to_string(), - url: Some("https://relay-builders-eu.ultrasound.money".to_string()), + url: "https://relay-builders-eu.ultrasound.money".to_string(), use_ssz_for_submit: true, use_gzip_for_submit: true, priority: 0, @@ -681,7 +676,7 @@ lazy_static! { "agnostic".to_string(), RelayConfig { name: "agnostic".to_string(), - url: Some("https://0xa7ab7a996c8584251c8f925da3170bdfd6ebc75d50f5ddc4050a6fdc77f2a3b5fce2cc750d0865e05d7228af97d69561@agnostic-relay.net".to_string()), + url: "https://0xa7ab7a996c8584251c8f925da3170bdfd6ebc75d50f5ddc4050a6fdc77f2a3b5fce2cc750d0865e05d7228af97d69561@agnostic-relay.net".to_string(), use_ssz_for_submit: true, use_gzip_for_submit: true, priority: 0, @@ -696,7 +691,7 @@ lazy_static! { "playground".to_string(), RelayConfig { name: "playground".to_string(), - url: Some("http://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@localhost:5555".to_string()), + url: "http://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@localhost:5555".to_string(), priority: 0, use_ssz_for_submit: false, use_gzip_for_submit: false, diff --git a/crates/rbuilder/src/primitives/mev_boost.rs b/crates/rbuilder/src/primitives/mev_boost.rs index 1457d8da..babaa643 100644 --- a/crates/rbuilder/src/primitives/mev_boost.rs +++ b/crates/rbuilder/src/primitives/mev_boost.rs @@ -1,9 +1,7 @@ use crate::mev_boost::{RelayClient, SubmitBlockErr, SubmitBlockRequest}; use governor::{DefaultDirectRateLimiter, Quota, RateLimiter}; use serde::{Deserialize, Deserializer}; -use std::ops::BitOr; use std::{env, sync::Arc, time::Duration}; -use url::Url; /// Usually human readable id for relays. Not used on anything on any protocol just to identify the relays. pub type MevBoostRelayID = String; @@ -12,8 +10,7 @@ pub type MevBoostRelayID = String; #[serde(deny_unknown_fields)] pub struct RelayConfig { pub name: String, - pub url: Option, - #[serde(default)] + pub url: String, pub priority: usize, // true->ssz false->json #[serde(default)] @@ -35,7 +32,7 @@ pub struct RelayConfig { impl RelayConfig { pub fn with_url(self, url: &str) -> Self { Self { - url: Some(url.to_string()), + url: url.to_string(), ..self } } @@ -48,30 +45,6 @@ impl RelayConfig { } } -impl BitOr for RelayConfig { - type Output = Self; - - fn bitor(self, other: Self) -> Self { - if self.name != other.name { - return self; - } - Self { - name: self.name, - url: other.url.or(self.url), - priority: self.priority | other.priority, - use_ssz_for_submit: self.use_ssz_for_submit | other.use_ssz_for_submit, - use_gzip_for_submit: self.use_gzip_for_submit | other.use_gzip_for_submit, - optimistic: self.optimistic | other.optimistic, - authorization_header: other.authorization_header.or(self.authorization_header), - builder_id_header: other.builder_id_header.or(self.builder_id_header), - api_token_header: other.api_token_header.or(self.api_token_header), - interval_between_submissions_ms: other - .interval_between_submissions_ms - .or(self.interval_between_submissions_ms), - } - } -} - /// Wrapper over RelayClient that allows to submit blocks and /// hides the particular configuration (eg: ssz, gip, optimistic). /// Sometimes the client is used externally. @@ -92,13 +65,8 @@ pub struct MevBoostRelay { impl MevBoostRelay { pub fn from_config(config: &RelayConfig) -> eyre::Result { - let url = config - .url - .as_ref() - .ok_or_else(|| eyre::eyre!("url is required"))?; - let client = { - let url: Url = url.parse()?; + let url = config.url.parse()?; RelayClient::from_url( url, config.authorization_header.clone(), @@ -166,7 +134,7 @@ mod test { let config: RelayConfig = toml::from_str(example).unwrap(); assert_eq!(config.name, "relay1"); - assert_eq!(config.url.expect("url expected"), "url"); + assert_eq!(config.url, "url"); assert_eq!(config.priority, 0); assert_eq!(config.authorization_header.unwrap(), "AAA"); assert_eq!(config.builder_id_header.unwrap(), "BBB"); From d7679489ab70be399ecb22a30466757b7ac35e2a Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 6 Jan 2025 18:47:12 +0000 Subject: [PATCH 09/12] Fix tests --- crates/rbuilder/src/live_builder/config.rs | 14 ------- .../testdata/config_with_relay_empty_url.toml | 41 ------------------- .../testdata/config_with_relay_override.toml | 1 + 3 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 crates/rbuilder/src/live_builder/testdata/config_with_relay_empty_url.toml diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index c501047c..8e8239f4 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -776,20 +776,6 @@ mod test { assert_eq!(relays[0].priority, 10); } - #[test] - fn test_parse_empty_relay_url() { - let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - p.push("./src/live_builder/testdata/config_with_relay_empty_url.toml"); - - let config: Config = load_config_toml_and_env(p).expect("Config load"); - assert!(config - .l1_config - .create_relays() - .unwrap_err() - .to_string() - .contains("url is required")); - } - #[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_empty_url.toml b/crates/rbuilder/src/live_builder/testdata/config_with_relay_empty_url.toml deleted file mode 100644 index dc7f7ffa..00000000 --- a/crates/rbuilder/src/live_builder/testdata/config_with_relay_empty_url.toml +++ /dev/null @@ -1,41 +0,0 @@ -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 = ["custom"] - -[[relays]] -name = "custom" -priority = 10 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 index 5b9afae7..8510eb4a 100644 --- a/crates/rbuilder/src/live_builder/testdata/config_with_relay_override.toml +++ b/crates/rbuilder/src/live_builder/testdata/config_with_relay_override.toml @@ -38,4 +38,5 @@ enabled_relays = ["playground"] [[relays]] name = "playground" +url = "http://example.com" priority = 10 From 469fd2dc4bea7d36a01f14cf2284024e1c6a4639 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 6 Jan 2025 18:47:56 +0000 Subject: [PATCH 10/12] Fix --- crates/rbuilder/src/primitives/mev_boost.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rbuilder/src/primitives/mev_boost.rs b/crates/rbuilder/src/primitives/mev_boost.rs index babaa643..f9d83864 100644 --- a/crates/rbuilder/src/primitives/mev_boost.rs +++ b/crates/rbuilder/src/primitives/mev_boost.rs @@ -66,7 +66,7 @@ pub struct MevBoostRelay { impl MevBoostRelay { pub fn from_config(config: &RelayConfig) -> eyre::Result { let client = { - let url = config.url.parse()?; + let url: Url = config.url.parse()?; RelayClient::from_url( url, config.authorization_header.clone(), From 590d5ce5a72b896dafd7035a12dfc1af1304bf66 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 6 Jan 2025 18:48:21 +0000 Subject: [PATCH 11/12] Fix --- crates/rbuilder/src/primitives/mev_boost.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/rbuilder/src/primitives/mev_boost.rs b/crates/rbuilder/src/primitives/mev_boost.rs index f9d83864..0881ef1a 100644 --- a/crates/rbuilder/src/primitives/mev_boost.rs +++ b/crates/rbuilder/src/primitives/mev_boost.rs @@ -2,6 +2,7 @@ use crate::mev_boost::{RelayClient, SubmitBlockErr, SubmitBlockRequest}; use governor::{DefaultDirectRateLimiter, Quota, RateLimiter}; use serde::{Deserialize, Deserializer}; use std::{env, sync::Arc, time::Duration}; +use url::Url; /// Usually human readable id for relays. Not used on anything on any protocol just to identify the relays. pub type MevBoostRelayID = String; From d06617c33d6e62c40109b0b045b53131d652f132 Mon Sep 17 00:00:00 2001 From: Daniel Xifra Date: Mon, 6 Jan 2025 15:55:18 -0300 Subject: [PATCH 12/12] removed unnecessary collect() --- crates/rbuilder/src/live_builder/config.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs index 8e8239f4..9f085d23 100644 --- a/crates/rbuilder/src/live_builder/config.rs +++ b/crates/rbuilder/src/live_builder/config.rs @@ -184,11 +184,10 @@ impl L1Config { 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())); - let effective_enabled_relays: Vec = effective_enabled_relays.into_iter().collect(); // Create enabled relays let mut results = Vec::new(); - for relay_name in &effective_enabled_relays { + 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) => {