Skip to content

Commit 9b46c9d

Browse files
authored
Fast relays cfg (#568)
## 📝 Summary Added a 2 new cfg: - Relay cfg has: /// critical blocks go only to fast relays. None -> true pub is_fast: Option<bool>, - L1Config: /// Bids above this value will only go to fast relays. pub fast_bid_threshold_eth: String, A block is sent to not fast relays only if its bid is < fast_bid_threshold_eth and it contains no bundle with replacement id. ## ✅ I have completed the following steps: * [X] Run `make lint` * [X] Run `make test` * [ ] Added tests (if applicable)
1 parent 11410f6 commit 9b46c9d

File tree

4 files changed

+105
-45
lines changed

4 files changed

+105
-45
lines changed

crates/rbuilder/src/live_builder/block_output/relay_submit.rs

Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use crate::{
66
submission::{BidMetadata, BidValueMetadata, SubmitBlockRequestWithMetadata},
77
BLSBlockSigner, RelayError, SubmitBlockErr,
88
},
9-
primitives::mev_boost::{MevBoostRelayBidSubmitter, MevBoostRelayID},
9+
primitives::{
10+
mev_boost::{MevBoostRelayBidSubmitter, MevBoostRelayID},
11+
Order,
12+
},
1013
telemetry::{
1114
add_relay_submit_time, add_subsidy_value, inc_conn_relay_errors,
1215
inc_failed_block_simulations, inc_initiated_submissions, inc_other_relay_errors,
@@ -23,7 +26,7 @@ use reth_chainspec::ChainSpec;
2326
use std::sync::Arc;
2427
use tokio::{sync::Notify, time::Instant};
2528
use tokio_util::sync::CancellationToken;
26-
use tracing::{error, info, info_span, trace, warn, Instrument};
29+
use tracing::{error, info, info_span, trace, warn, Instrument, Span};
2730

2831
use super::{
2932
bid_observer::BidObserver,
@@ -101,6 +104,8 @@ pub struct SubmissionConfig {
101104

102105
pub optimistic_config: Option<OptimisticConfig>,
103106
pub bid_observer: Box<dyn BidObserver + Send + Sync>,
107+
/// Bids above this value will only go to fast relays.
108+
pub fast_bid_threshold: U256,
104109
}
105110

106111
/// Configuration for optimistic block submission to relays.
@@ -232,7 +237,8 @@ async fn run_submit_to_relays_job(
232237
parent: &submission_span,
233238
"Submitting bid",
234239
);
235-
inc_initiated_submissions(optimistic_config.is_some());
240+
let send_to_slow_relays = can_send_to_slow_relay(&block, config.fast_bid_threshold);
241+
inc_initiated_submissions(optimistic_config.is_some(), send_to_slow_relays);
236242

237243
let (normal_signed_submission, optimistic_signed_submission) = {
238244
let normal_signed_submission = match sign_block_for_relay(
@@ -286,47 +292,34 @@ async fn run_submit_to_relays_job(
286292
};
287293

288294
mark_submission_start_time(block.trace.orders_sealed_at);
289-
290-
for relay in &normal_relays {
291-
let span = info_span!(parent: &submission_span, "relay_submit", relay = &relay.id(), optimistic = false);
292-
let relay = relay.clone();
293-
let cancel = cancel.clone();
294-
let submission = normal_signed_submission.clone();
295-
tokio::spawn(
296-
async move {
297-
submit_bid_to_the_relay(&relay, cancel.clone(), submission, false).await;
298-
}
299-
.instrument(span),
300-
);
301-
}
295+
submit_block_to_relays(
296+
&normal_relays,
297+
&normal_signed_submission,
298+
send_to_slow_relays,
299+
false,
300+
&submission_span,
301+
&cancel,
302+
);
302303

303304
if let Some((optimistic_signed_submission, _)) = &optimistic_signed_submission {
304-
for relay in &optimistic_relays {
305-
let span = info_span!(parent: &submission_span, "relay_submit", relay = &relay.id(), optimistic = true);
306-
let relay = relay.clone();
307-
let cancel = cancel.clone();
308-
let submission = optimistic_signed_submission.clone();
309-
tokio::spawn(
310-
async move {
311-
submit_bid_to_the_relay(&relay, cancel.clone(), submission, true).await;
312-
}
313-
.instrument(span),
314-
);
315-
}
305+
submit_block_to_relays(
306+
&optimistic_relays,
307+
optimistic_signed_submission,
308+
send_to_slow_relays,
309+
true,
310+
&submission_span,
311+
&cancel,
312+
);
316313
} else {
317314
// non-optimistic submission to optimistic relays
318-
for relay in &optimistic_relays {
319-
let span = info_span!(parent: &submission_span, "relay_submit", relay = &relay.id(), optimistic = false);
320-
let relay = relay.clone();
321-
let cancel = cancel.clone();
322-
let submission = normal_signed_submission.clone();
323-
tokio::spawn(
324-
async move {
325-
submit_bid_to_the_relay(&relay, cancel.clone(), submission, false).await;
326-
}
327-
.instrument(span),
328-
);
329-
}
315+
submit_block_to_relays(
316+
&optimistic_relays,
317+
&normal_signed_submission,
318+
send_to_slow_relays,
319+
false,
320+
&submission_span,
321+
&cancel,
322+
);
330323
}
331324

332325
submission_span.in_scope(|| {
@@ -342,6 +335,46 @@ async fn run_submit_to_relays_job(
342335
}
343336
}
344337

338+
fn submit_block_to_relays(
339+
relays: &Vec<MevBoostRelayBidSubmitter>,
340+
submission: &SubmitBlockRequestWithMetadata,
341+
send_to_slow_relays: bool,
342+
optimistic: bool,
343+
submission_span: &Span,
344+
cancel: &CancellationToken,
345+
) {
346+
for relay in relays {
347+
if relay.is_fast() || send_to_slow_relays {
348+
let span = info_span!(parent: submission_span, "relay_submit", relay = &relay.id(), optimistic);
349+
let relay = relay.clone();
350+
let cancel = cancel.clone();
351+
let submission = submission.clone();
352+
tokio::spawn(
353+
async move {
354+
submit_bid_to_the_relay(&relay, cancel.clone(), submission, optimistic).await;
355+
}
356+
.instrument(span),
357+
);
358+
}
359+
}
360+
}
361+
362+
/// can send only cheap blocks with no bundle replacement data.
363+
fn can_send_to_slow_relay(block: &Block, fast_bid_threshold: U256) -> bool {
364+
let has_replacement_uuid = block
365+
.trace
366+
.included_orders
367+
.iter()
368+
.flat_map(|exec_res| exec_res.order.original_orders())
369+
.any(|o| match o {
370+
Order::Bundle(bundle) => bundle.replacement_data.is_some(),
371+
Order::Tx(_) => false,
372+
Order::ShareBundle(_) => false,
373+
});
374+
let is_expensive_block = block.trace.bid_value > fast_bid_threshold;
375+
!has_replacement_uuid && !is_expensive_block
376+
}
377+
345378
pub async fn run_submit_to_relays_job_and_metrics(
346379
pending_bid: Arc<PendingBlockCell>,
347380
slot_data: MevBoostSlotData,

crates/rbuilder/src/live_builder/config.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,15 @@ pub struct L1Config {
125125
/// Bids above this value will always be submitted in non-optimistic mode.
126126
pub optimistic_max_bid_value_eth: String,
127127

128-
///Name kept singular for backwards compatibility
128+
/// Name kept singular for backwards compatibility
129129
#[serde_as(deserialize_as = "OneOrMany<EnvOrValue<String>>")]
130130
pub cl_node_url: Vec<EnvOrValue<String>>,
131131

132132
/// Genesis fork version for the chain. If not provided it will be fetched from the beacon client.
133133
pub genesis_fork_version: Option<String>,
134+
135+
/// Bids above this value will only go to fast relays.
136+
pub fast_bid_threshold_eth: String,
134137
}
135138

136139
impl Default for L1Config {
@@ -144,6 +147,7 @@ impl Default for L1Config {
144147
optimistic_max_bid_value_eth: "0.0".to_string(),
145148
cl_node_url: vec![EnvOrValue::from("http://127.0.0.1:3500")],
146149
genesis_fork_version: None,
150+
fast_bid_threshold_eth: "0".to_owned(),
147151
}
148152
}
149153
}
@@ -184,6 +188,7 @@ impl L1Config {
184188
relay_config.name.clone(),
185189
submit_config,
186190
relay_config.mode == RelayMode::Test,
191+
relay_config.is_fast(),
187192
));
188193
} else {
189194
eyre::bail!(
@@ -301,6 +306,7 @@ impl L1Config {
301306
signer,
302307
optimistic_config,
303308
bid_observer,
309+
fast_bid_threshold: parse_ether(&self.fast_bid_threshold_eth)?,
304310
})
305311
}
306312

@@ -691,6 +697,7 @@ lazy_static! {
691697
authorization_header: None,
692698
builder_id_header: None,
693699
api_token_header: None,
700+
is_fast: None,
694701
},
695702
);
696703
map.insert(
@@ -709,6 +716,7 @@ lazy_static! {
709716
authorization_header: None,
710717
builder_id_header: None,
711718
api_token_header: None,
719+
is_fast: None,
712720
},
713721
);
714722
map.insert(
@@ -727,6 +735,7 @@ lazy_static! {
727735
authorization_header: None,
728736
builder_id_header: None,
729737
api_token_header: None,
738+
is_fast: None,
730739
},
731740
);
732741
map.insert(
@@ -744,6 +753,7 @@ lazy_static! {
744753
authorization_header: None,
745754
builder_id_header: None,
746755
api_token_header: None,
756+
is_fast: None,
747757
},
748758
);
749759
map.insert(
@@ -762,6 +772,7 @@ lazy_static! {
762772
authorization_header: None,
763773
builder_id_header: None,
764774
api_token_header: None,
775+
is_fast: None,
765776
},
766777
);
767778
map

crates/rbuilder/src/primitives/mev_boost.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,11 @@ pub struct RelayConfig {
6161
pub submit_config: Option<RelaySubmitConfig>,
6262
/// Deprecated field that is not used
6363
pub priority: Option<usize>,
64+
/// critical blocks go only to fast relays. None -> true
65+
pub is_fast: Option<bool>,
6466
}
6567

68+
const IS_FAST_DEFAULT: bool = true;
6669
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Default)]
6770
#[serde(deny_unknown_fields)]
6871
pub struct RelaySubmitConfig {
@@ -91,6 +94,10 @@ impl RelayConfig {
9194
..self
9295
}
9396
}
97+
98+
pub fn is_fast(&self) -> bool {
99+
self.is_fast.unwrap_or(IS_FAST_DEFAULT)
100+
}
94101
}
95102

96103
/// Wrapper in RelayClient to submit blocks.
@@ -112,6 +119,7 @@ pub struct MevBoostRelayBidSubmitter {
112119
test_relay: bool,
113120
/// Parameter for the relay
114121
cancellations: bool,
122+
is_fast: bool,
115123
}
116124

117125
impl MevBoostRelayBidSubmitter {
@@ -120,6 +128,7 @@ impl MevBoostRelayBidSubmitter {
120128
id: String,
121129
config: &RelaySubmitConfig,
122130
test_relay: bool,
131+
is_fast: bool,
123132
) -> Self {
124133
let submission_rate_limiter = config.interval_between_submissions_ms.map(|d| {
125134
Arc::new(RateLimiter::direct(
@@ -135,9 +144,14 @@ impl MevBoostRelayBidSubmitter {
135144
submission_rate_limiter,
136145
test_relay,
137146
cancellations: true,
147+
is_fast,
138148
}
139149
}
140150

151+
pub fn is_fast(&self) -> bool {
152+
self.is_fast
153+
}
154+
141155
pub fn test_relay(&self) -> bool {
142156
self.test_relay
143157
}

crates/rbuilder/src/telemetry/metrics/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,10 @@ register_metrics! {
133133
"initiated_submissions",
134134
"Number of initiated submissions to the relays"
135135
),
136-
&["optimistic"],
136+
&["optimistic","sent_to_slow"],
137137
)
138138
.unwrap();
139+
139140
pub static RELAY_SUBMIT_TIME: HistogramVec = HistogramVec::new(
140141
HistogramOpts::new("relay_submit_time", "Time to send bid to the relay (ms)")
141142
.buckets(linear_buckets_range(0.0, 3000.0, 50)),
@@ -298,6 +299,7 @@ register_metrics! {
298299
&[]
299300
)
300301
.unwrap();
302+
301303
}
302304

303305
// This function should be called periodically to reset histogram metrics.
@@ -466,10 +468,10 @@ pub fn inc_active_slots() {
466468
ACTIVE_SLOTS.inc();
467469
}
468470

469-
pub fn inc_initiated_submissions(optimistic: bool) {
471+
pub fn inc_initiated_submissions(optimistic: bool, sent_to_slow_relays: bool) {
470472
INITIATED_SUBMISSIONS
471-
.with_label_values(&[&optimistic.to_string()])
472-
.inc()
473+
.with_label_values(&[&optimistic.to_string(), &sent_to_slow_relays.to_string()])
474+
.inc();
473475
}
474476

475477
pub fn add_relay_submit_time(relay: &MevBoostRelayID, duration: Duration) {

0 commit comments

Comments
 (0)