From ac734020a0864dd9930e30e05ae46090e44bb718 Mon Sep 17 00:00:00 2001 From: File Large Date: Mon, 24 Nov 2025 17:13:37 +0100 Subject: [PATCH 1/2] feat(relay): support validator preferences in registrations --- .../rbuilder-primitives/src/mev_boost/mod.rs | 81 +++++++++++++++++++ crates/rbuilder/src/mev_boost/mod.rs | 23 ++++-- 2 files changed, 98 insertions(+), 6 deletions(-) diff --git a/crates/rbuilder-primitives/src/mev_boost/mod.rs b/crates/rbuilder-primitives/src/mev_boost/mod.rs index 51e8ec72f..c0751edc2 100644 --- a/crates/rbuilder-primitives/src/mev_boost/mod.rs +++ b/crates/rbuilder-primitives/src/mev_boost/mod.rs @@ -181,6 +181,9 @@ pub struct ValidatorSlotData { /// (Bloxroute) Collection of regional endpoints validator is connected to. #[serde(default)] pub regional_endpoints: Vec, + /// (Titan) Validator preferences. + #[serde(default)] + pub preferences: Option, } /// Bloxroute validator RProxy details. @@ -198,6 +201,13 @@ pub struct BloxrouteRegionalEndpoint { pub websocket_endpoint: String, } +/// Titan validator preferences. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)] +pub struct TitanValidatorPreferences { + /// Flag indicating whether the validator is censoring. + pub censoring: bool, +} + #[derive(Clone, Debug)] pub struct BidMetadata { pub sequence: u64, @@ -217,3 +227,74 @@ pub struct SubmitBlockRequestWithMetadata { pub submission: SubmitBlockRequest, pub metadata: BidMetadata, } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn validator_slot_data_ser_deser() { + let registrations = [ + r#" + { + "slot": "123", + "validator_index": "123", + "entry": { + "message": { + "fee_recipient": "0x0000000000000000000000000000000000000000", + "gas_limit": "60000000", + "timestamp": "123", + "pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + } + "#, + r#" + { + "slot": "123", + "validator_index": "123", + "entry": { + "message": { + "fee_recipient": "0x0000000000000000000000000000000000000000", + "gas_limit": "60000000", + "timestamp": "123", + "pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "regional_endpoints": [ + { + "name": "", + "region": "", + "http_endpoint": "http://0.0.0.0", + "grpc_endpoint": "grpc://0.0.0.0", + "websocket_endpoint": "ws://0.0.0.0" + } + ] + } + "#, + r#" + { + "slot": "123", + "validator_index": "123", + "entry": { + "message": { + "fee_recipient": "0x0000000000000000000000000000000000000000", + "gas_limit": "60000000", + "timestamp": "123", + "pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "preferences": { + "censoring": false + } + } + "#, + ]; + for raw in registrations { + assert!(serde_json::from_str::(raw).is_ok()); + } + } +} diff --git a/crates/rbuilder/src/mev_boost/mod.rs b/crates/rbuilder/src/mev_boost/mod.rs index 13af8b931..8ad8630e9 100644 --- a/crates/rbuilder/src/mev_boost/mod.rs +++ b/crates/rbuilder/src/mev_boost/mod.rs @@ -102,9 +102,10 @@ pub struct RelayConfig { /// Flag indicating whether the builder should only submit to rproxy endpoinds if available. #[serde(default)] pub bloxroute_rproxy_only: bool, - /// Adds "filtering=true" as query to the call relay/v1/builder/validators to get all validators (including those filtering OFAC) - /// On 2025/06/24 (my birthday!) only supported by ultrasound. - /// None -> false + /// Retrieves registrations for all validators, including filtering ones. + /// For ultrasound relay, the behavior is to add `filtering=true` as a query parameter. + /// For titan relay if the value is not set, the registrations will be filtered by `censoring=false` by default. + /// If the value is set to `true`, `censoring=true` validators would be included. pub ask_for_filtering_validators: Option, /// If we submit a block with a different gas than the one the validator registered with in this relay the relay does not mind. /// None -> false @@ -674,15 +675,25 @@ impl RelayClient { let mut headers = HeaderMap::new(); self.add_auth_headers(&mut headers) .map_err(|_| RelayError::InvalidHeader)?; - let validators = req + let registrations = req .headers(headers) .send() .await? .json::>>() .await?; - match validators { - RelayResponse::Ok(validators) => Ok(validators), + match registrations { + RelayResponse::Ok(registrations) => { + let registrations = registrations + .into_iter() + .filter(|r| { + r.preferences + .as_ref() + .is_none_or(|p| !p.censoring || self.ask_for_filtering_validators) + }) + .collect(); + Ok(registrations) + } RelayResponse::Error(error) => Err(RelayError::RelayError(error)), } } From 2ca4917d49746e4fa9ba41f49bb012e40bf4f62c Mon Sep 17 00:00:00 2001 From: File Large Date: Mon, 24 Nov 2025 17:43:01 +0100 Subject: [PATCH 2/2] fix tests --- .../src/live_builder/payload_events/relay_epoch_cache.rs | 1 + crates/rbuilder/src/mev_boost/mod.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/rbuilder/src/live_builder/payload_events/relay_epoch_cache.rs b/crates/rbuilder/src/live_builder/payload_events/relay_epoch_cache.rs index ff8fda824..f0e5fffed 100644 --- a/crates/rbuilder/src/live_builder/payload_events/relay_epoch_cache.rs +++ b/crates/rbuilder/src/live_builder/payload_events/relay_epoch_cache.rs @@ -237,6 +237,7 @@ mod test { validator_index: 1, slot: 2, regional_endpoints: Vec::new(), + preferences: None, }, adjustment_fee_payer: None, } diff --git a/crates/rbuilder/src/mev_boost/mod.rs b/crates/rbuilder/src/mev_boost/mod.rs index 8ad8630e9..dfca72228 100644 --- a/crates/rbuilder/src/mev_boost/mod.rs +++ b/crates/rbuilder/src/mev_boost/mod.rs @@ -1325,6 +1325,7 @@ mod tests { signature: Default::default(), }, regional_endpoints: Vec::new(), + preferences: None, }; relay .submit_block(&sub_relay, ®istration, true, true, false, false)