Skip to content
Merged
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
47 changes: 34 additions & 13 deletions crates/rbuilder/src/live_builder/block_output/relay_submit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub struct SubmissionConfig {
pub optimistic_config: Option<OptimisticConfig>,
pub bid_observer: Box<dyn BidObserver + Send + Sync>,
/// Bids above this value will only go to fast relays.
pub fast_bid_threshold: U256,
pub independent_bid_threshold: U256,
}

/// Configuration for optimistic block submission to relays.
Expand Down Expand Up @@ -244,8 +244,11 @@ async fn run_submit_to_relays_job(
parent: &submission_span,
"Submitting bid",
);
let send_to_slow_relays = can_send_to_slow_relay(&block, config.fast_bid_threshold);
inc_initiated_submissions(optimistic_config.is_some(), send_to_slow_relays);
let relay_filter = get_relay_filter_and_update_metrics(
&block,
optimistic_config.is_some(),
config.independent_bid_threshold,
);

let (normal_signed_submission, optimistic_signed_submission) = {
let normal_signed_submission = match sign_block_for_relay(
Expand Down Expand Up @@ -302,7 +305,7 @@ async fn run_submit_to_relays_job(
submit_block_to_relays(
&normal_relays,
&normal_signed_submission,
send_to_slow_relays,
&relay_filter,
false,
&submission_span,
&cancel,
Expand All @@ -312,7 +315,7 @@ async fn run_submit_to_relays_job(
submit_block_to_relays(
&optimistic_relays,
optimistic_signed_submission,
send_to_slow_relays,
&relay_filter,
true,
&submission_span,
&cancel,
Expand All @@ -322,7 +325,7 @@ async fn run_submit_to_relays_job(
submit_block_to_relays(
&optimistic_relays,
&normal_signed_submission,
send_to_slow_relays,
&relay_filter,
false,
&submission_span,
&cancel,
Expand All @@ -345,13 +348,13 @@ async fn run_submit_to_relays_job(
fn submit_block_to_relays(
relays: &Vec<MevBoostRelayBidSubmitter>,
submission: &SubmitBlockRequestWithMetadata,
send_to_slow_relays: bool,
relay_filter: &impl Fn(&MevBoostRelayBidSubmitter) -> bool,
optimistic: bool,
submission_span: &Span,
cancel: &CancellationToken,
) {
for relay in relays {
if relay.is_fast() || send_to_slow_relays {
if relay_filter(relay) {
let span = info_span!(parent: submission_span, "relay_submit", relay = &relay.id(), optimistic);
let relay = relay.clone();
let cancel = cancel.clone();
Expand All @@ -366,9 +369,19 @@ fn submit_block_to_relays(
}
}

/// can send only cheap blocks with no bundle replacement data.
fn can_send_to_slow_relay(block: &Block, fast_bid_threshold: U256) -> bool {
let has_replacement_uuid = block
/// Creates a Fn to decide if the block should go to a relay.
/// The cfg defines 2 flags on relays: fast and independent.
/// If a block has replacement ids it should NOT go to a relay that is not fast since it needs fast cancellations.
/// If a block is expensive it should NOT go to a non independent relay.
fn get_relay_filter_and_update_metrics(
block: &Block,
optimistic: bool,
independent_bid_threshold: U256,
) -> impl Fn(&MevBoostRelayBidSubmitter) -> bool {
// only_independent = expensive blocks.
let only_independent = block.trace.bid_value > independent_bid_threshold;
// only_fast = blocks with replaceable orders.
let only_fast = block
.trace
.included_orders
.iter()
Expand All @@ -378,8 +391,16 @@ fn can_send_to_slow_relay(block: &Block, fast_bid_threshold: U256) -> bool {
Order::Tx(_) => false,
Order::ShareBundle(_) => false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

share bundles can have replacements too

});
let is_expensive_block = block.trace.bid_value > fast_bid_threshold;
!has_replacement_uuid && !is_expensive_block
inc_initiated_submissions(optimistic, !only_fast, !only_independent);
move |relay: &MevBoostRelayBidSubmitter| {
if only_independent && !relay.is_independent() {
Copy link
Contributor

@dvush dvush May 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand the logic from the description and the docs and this code. This means the description can be improved.

Relays can be independent and fast at the same time?

  • only_fast bool is practically going to be true for every block
  • only_independent will be true for big blocks

So what will happen for big blocks with replacements?

They will be sent only to fast AND independent relays. Is this intended behavior?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the comments.

return false; // Sorry relay but this block is expensive and you are not independent :(
}
if only_fast && !relay.is_fast() {
return false; // Sorry relay but this block contains replacements and you are slow :(
}
true
}
}

pub async fn run_submit_to_relays_job_and_metrics(
Expand Down
15 changes: 11 additions & 4 deletions crates/rbuilder/src/live_builder/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ pub struct Config {
}

const DEFAULT_SLOT_DELTA_TO_START_BIDDING_MS: i64 = -8000;
const DEFAULT_INDEPENDENT_BID_THRESHOLD_ETH: &str = "0";

#[serde_as]
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
Expand All @@ -140,8 +141,8 @@ pub struct L1Config {
/// Genesis fork version for the chain. If not provided it will be fetched from the beacon client.
pub genesis_fork_version: Option<String>,

/// Bids above this value will only go to fast relays.
pub fast_bid_threshold_eth: String,
/// Bids above this value will only go to independent relays.
pub independent_bid_threshold_eth: String,
}

impl Default for L1Config {
Expand All @@ -155,7 +156,7 @@ impl Default for L1Config {
optimistic_max_bid_value_eth: "0.0".to_string(),
cl_node_url: vec![EnvOrValue::from("http://127.0.0.1:3500")],
genesis_fork_version: None,
fast_bid_threshold_eth: "0".to_owned(),
independent_bid_threshold_eth: DEFAULT_INDEPENDENT_BID_THRESHOLD_ETH.to_owned(),
}
}
}
Expand Down Expand Up @@ -197,6 +198,7 @@ impl L1Config {
submit_config,
relay_config.mode == RelayMode::Test,
relay_config.is_fast(),
relay_config.is_independent(),
));
} else {
eyre::bail!(
Expand Down Expand Up @@ -314,7 +316,7 @@ impl L1Config {
signer,
optimistic_config,
bid_observer,
fast_bid_threshold: parse_ether(&self.fast_bid_threshold_eth)?,
independent_bid_threshold: parse_ether(&self.independent_bid_threshold_eth)?,
})
}

Expand Down Expand Up @@ -719,6 +721,7 @@ lazy_static! {
builder_id_header: None,
api_token_header: None,
is_fast: None,
is_independent: None,
},
);
map.insert(
Expand All @@ -738,6 +741,7 @@ lazy_static! {
builder_id_header: None,
api_token_header: None,
is_fast: None,
is_independent: None,
},
);
map.insert(
Expand All @@ -757,6 +761,7 @@ lazy_static! {
builder_id_header: None,
api_token_header: None,
is_fast: None,
is_independent: None,
},
);
map.insert(
Expand All @@ -775,6 +780,7 @@ lazy_static! {
builder_id_header: None,
api_token_header: None,
is_fast: None,
is_independent: None,
},
);
map.insert(
Expand All @@ -794,6 +800,7 @@ lazy_static! {
builder_id_header: None,
api_token_header: None,
is_fast: None,
is_independent: None,
},
);
map
Expand Down
16 changes: 15 additions & 1 deletion crates/rbuilder/src/primitives/mev_boost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,14 @@ pub struct RelayConfig {
pub submit_config: Option<RelaySubmitConfig>,
/// Deprecated field that is not used
pub priority: Option<usize>,
/// critical blocks go only to fast relays. None -> true
/// Critical blocks (containing bundles with replacement ids) go only to fast relays. None -> true
pub is_fast: Option<bool>,
/// Big blocks (bid > [L1Config::independent_bid_threshold_eth]) go only to independent relays. None -> true
pub is_independent: Option<bool>,
}

const IS_FAST_DEFAULT: bool = true;
const IS_INDEPENDENT_DEFAULT: bool = true;
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Default)]
#[serde(deny_unknown_fields)]
pub struct RelaySubmitConfig {
Expand Down Expand Up @@ -98,6 +101,10 @@ impl RelayConfig {
pub fn is_fast(&self) -> bool {
self.is_fast.unwrap_or(IS_FAST_DEFAULT)
}

pub fn is_independent(&self) -> bool {
self.is_independent.unwrap_or(IS_INDEPENDENT_DEFAULT)
}
}

/// Wrapper in RelayClient to submit blocks.
Expand All @@ -120,6 +127,7 @@ pub struct MevBoostRelayBidSubmitter {
/// Parameter for the relay
cancellations: bool,
is_fast: bool,
is_independent: bool,
}

impl MevBoostRelayBidSubmitter {
Expand All @@ -129,6 +137,7 @@ impl MevBoostRelayBidSubmitter {
config: &RelaySubmitConfig,
test_relay: bool,
is_fast: bool,
is_independent: bool,
) -> Self {
let submission_rate_limiter = config.interval_between_submissions_ms.map(|d| {
Arc::new(RateLimiter::direct(
Expand All @@ -145,13 +154,18 @@ impl MevBoostRelayBidSubmitter {
test_relay,
cancellations: true,
is_fast,
is_independent,
}
}

pub fn is_fast(&self) -> bool {
self.is_fast
}

pub fn is_independent(&self) -> bool {
self.is_independent
}

pub fn test_relay(&self) -> bool {
self.test_relay
}
Expand Down
14 changes: 11 additions & 3 deletions crates/rbuilder/src/telemetry/metrics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ register_metrics! {
"initiated_submissions",
"Number of initiated submissions to the relays"
),
&["optimistic","sent_to_slow"],
&["optimistic","sent_to_slow","send_to_non_independent"],
)
.unwrap();

Expand Down Expand Up @@ -469,9 +469,17 @@ pub fn inc_active_slots() {
ACTIVE_SLOTS.inc();
}

pub fn inc_initiated_submissions(optimistic: bool, sent_to_slow_relays: bool) {
pub fn inc_initiated_submissions(
optimistic: bool,
sent_to_slow_relays: bool,
send_to_non_independent: bool,
) {
INITIATED_SUBMISSIONS
.with_label_values(&[&optimistic.to_string(), &sent_to_slow_relays.to_string()])
.with_label_values(&[
&optimistic.to_string(),
&sent_to_slow_relays.to_string(),
&send_to_non_independent.to_string(),
])
.inc();
}

Expand Down
4 changes: 3 additions & 1 deletion docs/CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,16 @@ Every field has a default if omitted.
|RelayConfig.use_gzip_for_submit|optional bool||false|
|RelayConfig.optimistic|optional bool||false|
|RelayConfig.interval_between_submissions_ms|optional int| Caps the submission rate to the relay|None|
|RelayConfig.is_fast|optional bool| Critical blocks (the ones containing orders with replacement id) will go only to fast relays.|true|
|RelayConfig.is_independent|optional bool| Big blocks (bid value > independent_bid_threshold_eth) will go only to independent relays.|true|
|enabled_relays| vec["string"]| Extra hardcoded relays to add (see DEFAULT_RELAYS in [config.rs](../crates/rbuilder/src/live_builder/config.rs))|[]|
|relay_secret_key|optional env/string|Secret key that will be used to sign normal submissions to the relay.|None|
|optimistic_relay_secret_key|optional env/string|Secret key that will be used to sign optimistic submissions to the relay.|None|
|optimistic_enabled|bool|When enabled builder will make optimistic submissions to optimistic relays|false|
|optimistic_max_bid_value_eth|string| Bids above this value will always be submitted in non-optimistic mode.|"0.0"|
|cl_node_url|vec[env/stirng]| Array if urls to CL clients to get the new payload events|["http://127.0.0.1:3500"]
|genesis_fork_version|optional string|Genesis fork version for the chain. If not provided it will be fetched from the beacon client.|None|

|independent_bid_threshold_eth|optional string|Bids above this value will only go to independent relays.| "0"|
## Building algorithms
rbuilder can multiple building algorithms and each algorithm can be instantiated multiple times with it's own set of parameters each time.
Each instantiated algorithm starts with:
Expand Down
Loading