Skip to content

Commit 4ee212e

Browse files
authored
feat: optional adjustment data for optimistic v3 (#787)
## 📝 Summary Optional bid adjustment data for optimistic v3. ## ✅ I have completed the following steps: * [x] Run `make lint` * [x] Run `make test` * [ ] Added tests (if applicable)
1 parent 36da77b commit 4ee212e

File tree

4 files changed

+138
-29
lines changed

4 files changed

+138
-29
lines changed

crates/rbuilder-primitives/src/mev_boost/submit_header.rs

Lines changed: 99 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,7 @@ pub enum HeaderSubmission {
6464
}
6565

6666
/// Electra header submission.
67-
#[derive(
68-
PartialEq,
69-
Eq,
70-
Clone,
71-
Debug,
72-
serde::Serialize,
73-
serde::Deserialize,
74-
ssz_derive::Encode,
75-
ssz_derive::Decode,
76-
)]
67+
#[derive(PartialEq, Eq, Clone, Debug, serde::Serialize, serde::Deserialize)]
7768
pub struct HeaderSubmissionElectra {
7869
/// Bid trace.
7970
pub bid_trace: BidTrace,
@@ -84,7 +75,104 @@ pub struct HeaderSubmissionElectra {
8475
/// Blob KZG commitments.
8576
pub commitments: Vec<alloy_consensus::Bytes48>,
8677
/// Bid adjustment data V2.
87-
pub adjustment_data: BidAdjustmentDataV2,
78+
pub adjustment_data: Option<BidAdjustmentDataV2>,
79+
}
80+
81+
impl ssz::Encode for HeaderSubmissionElectra {
82+
fn is_ssz_fixed_len() -> bool {
83+
false
84+
}
85+
86+
fn ssz_append(&self, buf: &mut Vec<u8>) {
87+
let mut offset = <BidTrace as ssz::Encode>::ssz_fixed_len()
88+
+ <ExecutionPayloadHeaderElectra as ssz::Encode>::ssz_fixed_len()
89+
+ <ExecutionRequestsV4 as ssz::Encode>::ssz_fixed_len()
90+
+ <Vec<alloy_consensus::Bytes48> as ssz::Encode>::ssz_fixed_len();
91+
if self.adjustment_data.is_some() {
92+
offset += <BidAdjustmentDataV2 as ssz::Encode>::ssz_fixed_len();
93+
}
94+
95+
let mut encoder = ssz::SszEncoder::container(buf, offset);
96+
97+
encoder.append(&self.bid_trace);
98+
encoder.append(&self.execution_payload_header);
99+
encoder.append(&self.execution_requests);
100+
encoder.append(&self.commitments);
101+
if let Some(adjustment) = &self.adjustment_data {
102+
encoder.append(&adjustment);
103+
}
104+
105+
encoder.finalize();
106+
}
107+
108+
fn ssz_bytes_len(&self) -> usize {
109+
let mut len = <BidTrace as ssz::Encode>::ssz_bytes_len(&self.bid_trace)
110+
+ <ExecutionPayloadHeaderElectra as ssz::Encode>::ssz_bytes_len(
111+
&self.execution_payload_header,
112+
)
113+
+ <ExecutionRequestsV4 as ssz::Encode>::ssz_bytes_len(&self.execution_requests)
114+
+ <Vec<alloy_consensus::Bytes48> as ssz::Encode>::ssz_bytes_len(&self.commitments);
115+
if let Some(adjustment) = &self.adjustment_data {
116+
len += <BidAdjustmentDataV2 as ssz::Encode>::ssz_bytes_len(adjustment);
117+
}
118+
len
119+
}
120+
}
121+
122+
impl ssz::Decode for HeaderSubmissionElectra {
123+
fn is_ssz_fixed_len() -> bool {
124+
false
125+
}
126+
127+
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> {
128+
#[derive(ssz_derive::Decode)]
129+
struct HeaderSubmissionElectraSszHelper {
130+
bid_trace: BidTrace,
131+
execution_payload_header: ExecutionPayloadHeaderElectra,
132+
execution_requests: ExecutionRequestsV4,
133+
commitments: Vec<alloy_consensus::Bytes48>,
134+
adjustment_data: BidAdjustmentDataV2,
135+
}
136+
137+
#[derive(ssz_derive::Decode)]
138+
struct HeaderSubmissionElectraNoAdjustmentsSszHelper {
139+
bid_trace: BidTrace,
140+
execution_payload_header: ExecutionPayloadHeaderElectra,
141+
execution_requests: ExecutionRequestsV4,
142+
commitments: Vec<alloy_consensus::Bytes48>,
143+
}
144+
145+
if let Ok(submission) = HeaderSubmissionElectraSszHelper::from_ssz_bytes(bytes) {
146+
let HeaderSubmissionElectraSszHelper {
147+
bid_trace,
148+
execution_payload_header,
149+
execution_requests,
150+
commitments,
151+
adjustment_data,
152+
} = submission;
153+
Ok(Self {
154+
bid_trace,
155+
execution_payload_header,
156+
execution_requests,
157+
commitments,
158+
adjustment_data: Some(adjustment_data),
159+
})
160+
} else {
161+
let HeaderSubmissionElectraNoAdjustmentsSszHelper {
162+
bid_trace,
163+
execution_payload_header,
164+
execution_requests,
165+
commitments,
166+
} = HeaderSubmissionElectraNoAdjustmentsSszHelper::from_ssz_bytes(bytes)?;
167+
Ok(Self {
168+
bid_trace,
169+
execution_payload_header,
170+
execution_requests,
171+
commitments,
172+
adjustment_data: None,
173+
})
174+
}
175+
}
88176
}
89177

90178
/// Electra execution payload header.

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,12 @@ fn create_optimistic_v3_request(
361361
builder_url: &[u8],
362362
request: &SubmitBlockRequest,
363363
maybe_adjustment_data: Option<&BidAdjustmentData>,
364+
adjustment_data_required: bool,
364365
) -> eyre::Result<HeaderSubmissionOptimisticV3> {
365-
let Some(adjustment_data) = maybe_adjustment_data else {
366-
eyre::bail!("adjustment data must exist")
367-
};
366+
let maybe_adjustment_data_v2 = maybe_adjustment_data.map(|d| d.clone().into_v2());
367+
if maybe_adjustment_data_v2.is_none() && adjustment_data_required {
368+
eyre::bail!("adjustment data is required")
369+
}
368370

369371
let header_submission = match request {
370372
SubmitBlockRequest::Electra(request) => {
@@ -374,7 +376,7 @@ fn create_optimistic_v3_request(
374376
execution_payload_header: header,
375377
execution_requests: request.execution_requests.clone(),
376378
commitments: request.blobs_bundle.commitments.clone(),
377-
adjustment_data: adjustment_data.clone().into_v2(),
379+
adjustment_data: maybe_adjustment_data_v2,
378380
})
379381
}
380382
SubmitBlockRequest::Fulu(request) => {
@@ -384,7 +386,7 @@ fn create_optimistic_v3_request(
384386
execution_payload_header: header,
385387
execution_requests: request.execution_requests.clone(),
386388
commitments: request.blobs_bundle.commitments.clone(),
387-
adjustment_data: adjustment_data.clone().into_v2(),
389+
adjustment_data: maybe_adjustment_data_v2,
388390
})
389391
}
390392
_ => eyre::bail!("optimistic v3 submission is not supported for this fork"),
@@ -440,6 +442,7 @@ fn submit_block_to_relays(
440442
&config.builder_url,
441443
request,
442444
maybe_adjustment_data,
445+
relay.optimistic_v3_bid_adjustment_required(),
443446
)
444447
.map(|request| (config.clone(), request))
445448
.inspect_err(|error| {

crates/rbuilder/src/live_builder/config.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ impl L1Config {
231231
client.clone(),
232232
relay_config.name.clone(),
233233
submit_config,
234-
relay_config.optimistic_v3,
235234
relay_config.mode == RelayMode::Test,
236235
)?);
237236
} else {
@@ -384,7 +383,11 @@ impl L1Config {
384383
)?;
385384

386385
let mut optimistic_v3_config = None;
387-
if self.relays.iter().any(|r| r.optimistic_v3) {
386+
if self
387+
.relays
388+
.iter()
389+
.any(|r| r.submit_config.as_ref().is_some_and(|c| c.optimistic_v3))
390+
{
388391
let address = SocketAddr::V4(SocketAddrV4::new(
389392
self.optimistic_v3_server_ip,
390393
self.optimistic_v3_server_port,
@@ -905,6 +908,8 @@ lazy_static! {
905908
optimistic: false,
906909
interval_between_submissions_ms: Some(250),
907910
max_bid_eth: None,
911+
optimistic_v3: false,
912+
optimistic_v3_bid_adjustment_required: false,
908913
}),
909914
priority: Some(0),
910915
authorization_header: None,
@@ -915,7 +920,6 @@ lazy_static! {
915920
bloxroute_rproxy_regions: Vec::new(),
916921
ask_for_filtering_validators: None,
917922
can_ignore_gas_limit: None,
918-
optimistic_v3: false,
919923
},
920924
);
921925
map.insert(
@@ -931,6 +935,8 @@ lazy_static! {
931935
optimistic: true,
932936
interval_between_submissions_ms: None,
933937
max_bid_eth: None,
938+
optimistic_v3: false,
939+
optimistic_v3_bid_adjustment_required: false,
934940
}),
935941
priority: Some(0),
936942
authorization_header: None,
@@ -941,7 +947,6 @@ lazy_static! {
941947
bloxroute_rproxy_regions: Vec::new(),
942948
ask_for_filtering_validators: None,
943949
can_ignore_gas_limit: None,
944-
optimistic_v3: false,
945950
},
946951
);
947952
map.insert(
@@ -957,6 +962,8 @@ lazy_static! {
957962
optimistic: true,
958963
interval_between_submissions_ms: None,
959964
max_bid_eth: None,
965+
optimistic_v3: false,
966+
optimistic_v3_bid_adjustment_required: false,
960967
}),
961968
priority: Some(0),
962969
authorization_header: None,
@@ -967,7 +974,6 @@ lazy_static! {
967974
bloxroute_rproxy_regions: Vec::new(),
968975
ask_for_filtering_validators: None,
969976
can_ignore_gas_limit: None,
970-
optimistic_v3: false,
971977
},
972978
);
973979
map.insert(
@@ -983,7 +989,10 @@ lazy_static! {
983989
optimistic: true,
984990
interval_between_submissions_ms: None,
985991
max_bid_eth: None,
986-
}), priority: Some(0),
992+
optimistic_v3: false,
993+
optimistic_v3_bid_adjustment_required: false,
994+
}),
995+
priority: Some(0),
987996
authorization_header: None,
988997
builder_id_header: None,
989998
api_token_header: None,
@@ -992,7 +1001,6 @@ lazy_static! {
9921001
bloxroute_rproxy_regions: Vec::new(),
9931002
ask_for_filtering_validators: None,
9941003
can_ignore_gas_limit: None,
995-
optimistic_v3: false
9961004
},
9971005
);
9981006
map.insert(
@@ -1008,6 +1016,8 @@ lazy_static! {
10081016
optimistic: false,
10091017
interval_between_submissions_ms: None,
10101018
max_bid_eth: None,
1019+
optimistic_v3: false,
1020+
optimistic_v3_bid_adjustment_required: false,
10111021
}),
10121022
priority: Some(0),
10131023
authorization_header: None,
@@ -1018,7 +1028,6 @@ lazy_static! {
10181028
bloxroute_rproxy_regions: Vec::new(),
10191029
ask_for_filtering_validators: None,
10201030
can_ignore_gas_limit: None,
1021-
optimistic_v3: false
10221031
},
10231032
);
10241033
map

crates/rbuilder/src/mev_boost/mod.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@ pub struct RelayConfig {
105105
/// If we submit a block with a different gas than the one the validator registered with in this relay the relay does not mind.
106106
/// None -> false
107107
pub can_ignore_gas_limit: Option<bool>,
108-
/// Flag indicating whether optimistic V3 submissions should be used.
109-
#[serde(default)]
110-
pub optimistic_v3: bool,
111108
}
112109

113110
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Default)]
@@ -120,6 +117,12 @@ pub struct RelaySubmitConfig {
120117
pub use_gzip_for_submit: bool,
121118
#[serde(default)]
122119
pub optimistic: bool,
120+
/// Flag indicating whether optimistic V3 submissions should be used.
121+
#[serde(default)]
122+
pub optimistic_v3: bool,
123+
/// Flag indicating whether bid adjustments are required for optimistic v3 submissions.
124+
#[serde(default)]
125+
pub optimistic_v3_bid_adjustment_required: bool,
123126
#[serde(default)]
124127
pub interval_between_submissions_ms: Option<u64>,
125128
/// Max bid we can submit to this relay. Any bid above this will be skipped.
@@ -238,6 +241,8 @@ pub struct MevBoostRelayBidSubmitter {
238241
cancellations: bool,
239242
/// Flag indicating whether optimistic v3 submissions should be used.
240243
optimistic_v3: bool,
244+
/// Flag indicating whether bid adjustments are required for optimistic v3 submissions.
245+
optimistic_v3_bid_adjustment_required: bool,
241246
/// Max bid we can submit to this relay. Any bid above this will be skipped.
242247
/// None -> No limit.
243248
max_bid: Option<U256>,
@@ -250,7 +255,6 @@ impl MevBoostRelayBidSubmitter {
250255
client: RelayClient,
251256
id: String,
252257
config: &RelaySubmitConfig,
253-
optimistic_v3: bool,
254258
test_relay: bool,
255259
) -> eyre::Result<Self> {
256260
let max_bid = config
@@ -272,7 +276,8 @@ impl MevBoostRelayBidSubmitter {
272276
optimistic: config.optimistic,
273277
submission_rate_limiter,
274278
cancellations: true,
275-
optimistic_v3,
279+
optimistic_v3: config.optimistic_v3,
280+
optimistic_v3_bid_adjustment_required: config.optimistic_v3_bid_adjustment_required,
276281
max_bid,
277282
test_relay,
278283
})
@@ -294,6 +299,10 @@ impl MevBoostRelayBidSubmitter {
294299
self.optimistic_v3
295300
}
296301

302+
pub fn optimistic_v3_bid_adjustment_required(&self) -> bool {
303+
self.optimistic_v3_bid_adjustment_required
304+
}
305+
297306
pub fn max_bid(&self) -> Option<U256> {
298307
self.max_bid
299308
}

0 commit comments

Comments
 (0)