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
6 changes: 6 additions & 0 deletions crates/common/src/local_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ impl LocalCache {
CACHE_SIZE.with_label_values(&["merged_blocks"]).set(self.merged_blocks.len() as f64);
}

pub fn set_merged_block_header_served(&self, block_hash: &B256, time_ns: u64) {
if let Some(mut b) = self.merged_blocks.get_mut(block_hash) {
b.trace.header_served_time_ns = Some(time_ns);
}
}

pub fn get_merged_block(&self, block_hash: &B256) -> Option<MergedBlock> {
self.merged_blocks.get(block_hash).map(|b| b.value().clone())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE merged_blocks
ADD COLUMN header_served_time_ns BIGINT;
6 changes: 5 additions & 1 deletion crates/database/src/postgres/postgres_db_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2770,6 +2770,7 @@ impl PostgresDatabaseService {
sim_start_time_ns: i64,
sim_end_time_ns: i64,
finalize_time_ns: i64,
header_served_time_ns: Option<i64>,
inserted_at: SystemTime,
}

Expand All @@ -2794,12 +2795,13 @@ impl PostgresDatabaseService {
sim_start_time_ns: block.trace.sim_start_time_ns as i64,
sim_end_time_ns: block.trace.sim_end_time_ns as i64,
finalize_time_ns: block.trace.finalize_time_ns as i64,
header_served_time_ns: block.trace.header_served_time_ns.map(|v| v as i64),
inserted_at: SystemTime::now(),
});
}

// Flatten into SQL params
const FIELD_COUNT: usize = 16;
const FIELD_COUNT: usize = 17;
let mut params: Vec<&(dyn ToSql + Sync)> =
Vec::with_capacity(structured_blocks.len() * FIELD_COUNT);
for block in &structured_blocks {
Expand All @@ -2818,6 +2820,7 @@ impl PostgresDatabaseService {
params.push(&block.sim_start_time_ns);
params.push(&block.sim_end_time_ns);
params.push(&block.finalize_time_ns);
params.push(&block.header_served_time_ns);
params.push(&block.inserted_at);
}

Expand All @@ -2838,6 +2841,7 @@ impl PostgresDatabaseService {
sim_start_time_ns,
sim_end_time_ns,
finalize_time_ns,
header_served_time_ns,
inserted_at
) VALUES ",
);
Expand Down
2 changes: 1 addition & 1 deletion crates/relay/src/api/proposer/get_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl<A: Api> ProposerApi<A> {

trace!("done sleep");

let Ok(rx) = proposer_api.auctioneer_handle.get_header(params) else {
let Ok(rx) = proposer_api.auctioneer_handle.get_header(params, is_mev_boost) else {
error!("failed to send get_header to auctioneer");
return Err(ProposerApiError::InternalServerError);
};
Expand Down
11 changes: 10 additions & 1 deletion crates/relay/src/auctioneer/block_merger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,11 @@ impl BlockMerger {
}

#[timed]
pub fn get_header(&self, original_bid: &PayloadEntry) -> Option<PayloadEntry> {
pub fn get_header(
&self,
original_bid: &PayloadEntry,
is_mev_boost: bool,
) -> Option<PayloadEntry> {
trace!("fetching merged header");
let start_time = Instant::now();
let entry = self.best_merged_block.as_ref()?;
Expand All @@ -191,6 +195,10 @@ impl BlockMerger {
record_step("get_header", start_time.elapsed());
trace!("fetched merged header");

if is_mev_boost {
self.local_cache.set_merged_block_header_served(entry.bid.block_hash(), utcnow_ns());
}

if self.config.block_merging_config.is_dry_run {
info!("dry run mode enabled, not returning merged header");
return None;
Expand Down Expand Up @@ -307,6 +315,7 @@ impl BlockMerger {
sim_start_time_ns: 0,
sim_end_time_ns: 0,
finalize_time_ns: 0,
header_served_time_ns: None,
},
}),
block_hash: base_block_hash,
Expand Down
7 changes: 5 additions & 2 deletions crates/relay/src/auctioneer/get_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ impl<B: BidAdjustor> Context<B> {
slot_data: &SlotData,
res_tx: oneshot::Sender<GetHeaderResult>,
producers: &mut HelixSpineProducers,
is_mev_boost: bool,
) {
assert_eq!(params.slot, self.bid_slot.as_u64(), "params should already be validated!");
let _ = res_tx.send(self.get_header(params.parent_hash, slot_data, producers));
let _ =
res_tx.send(self.get_header(params.parent_hash, slot_data, producers, is_mev_boost));
}

#[timed]
Expand All @@ -34,6 +36,7 @@ impl<B: BidAdjustor> Context<B> {
parent_hash: B256,
slot_data: &SlotData,
producers: &mut HelixSpineProducers,
is_mev_boost: bool,
) -> GetHeaderResult {
let Some(best_block_hash) = self.bid_sorter.get_header(&parent_hash) else {
warn!(%parent_hash, "no bids for this fork");
Expand All @@ -45,7 +48,7 @@ impl<B: BidAdjustor> Context<B> {
return Err(ProposerApiError::NoBidPrepared);
};

if let Some(merged_bid) = self.block_merger.get_header(original_bid) {
if let Some(merged_bid) = self.block_merger.get_header(original_bid, is_mev_boost) {
return Ok(merged_bid);
};

Expand Down
8 changes: 7 additions & 1 deletion crates/relay/src/auctioneer/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,17 @@ impl AuctioneerHandle {
pub fn get_header(
&self,
params: GetHeaderParams,
is_mev_boost: bool,
) -> Result<oneshot::Receiver<GetHeaderResult>, ChannelFull> {
let (tx, rx) = oneshot::channel();
trace!("sending to auctioneer");
self.auctioneer
.try_send(Event::GetHeader { params, res_tx: tx, span: tracing::Span::current() })
.try_send(Event::GetHeader {
params,
res_tx: tx,
span: tracing::Span::current(),
is_mev_boost,
})
.map_err(|_| ChannelFull)?;
Ok(rx)
}
Expand Down
7 changes: 5 additions & 2 deletions crates/relay/src/auctioneer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,10 @@ impl State {
}

// get_header
(State::Sorting(slot_data), Event::GetHeader { params, res_tx, span }) => {
(
State::Sorting(slot_data),
Event::GetHeader { params, res_tx, span, is_mev_boost },
) => {
let _guard = span.enter();
trace!("received in auctioneer");

Expand All @@ -425,7 +428,7 @@ impl State {
warn!(req =% params.pubkey, this =% slot_data.registration_data.entry.registration.message.pubkey, "get header for mismatched proposer");
let _ = res_tx.send(Err(ProposerApiError::NoBidPrepared));
} else {
ctx.handle_get_header(params, slot_data, res_tx, producers)
ctx.handle_get_header(params, slot_data, res_tx, producers, is_mev_boost)
}

trace!("finished processing");
Expand Down
1 change: 1 addition & 0 deletions crates/relay/src/auctioneer/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ pub enum Event {
params: GetHeaderParams,
res_tx: oneshot::Sender<GetHeaderResult>,
span: tracing::Span,
is_mev_boost: bool,
},
// Receive multiple of these potentially, assume some light validation
GetPayload {
Expand Down
2 changes: 2 additions & 0 deletions crates/relay/src/block_merging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ fn merged_block_to_response(m: MergedBlockV1) -> BlockMergeResponse {
sim_start_time_ns: m.trace.sim_start_ns,
sim_end_time_ns: m.trace.sim_end_ns,
finalize_time_ns: m.trace.finalize_ns,
header_served_time_ns: None, /* filled in by the auctioneer when it sends the header
* to the proposer */
},
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/types/src/block_merging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ pub struct MergedBlockTrace {
pub sim_start_time_ns: u64,
pub sim_end_time_ns: u64,
pub finalize_time_ns: u64,
pub header_served_time_ns: Option<u64>,
}

#[cfg(test)]
Expand Down
Loading