Skip to content
Merged
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
53 changes: 49 additions & 4 deletions crates/rbuilder/src/backtest/fetch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::{
sync::{Arc, RwLock},
};
use tokio::sync::Mutex;
use tracing::{info, trace};
use tracing::{info, trace, warn};

/// Struct that brings block information ([BlockData]) from several [DataSource]s
/// Filters txs already landed (onchain nonce > tx nonce)
Expand All @@ -43,6 +43,7 @@ pub struct HistoricalDataFetcher {
eth_rpc_parallel: usize,
data_sources: Vec<Box<dyn DataSource>>,
payload_delivered_fetcher: PayloadDeliveredFetcher,
require_delivered_payload_from_relays: bool,
}

impl HistoricalDataFetcher {
Expand All @@ -52,6 +53,14 @@ impl HistoricalDataFetcher {
eth_rpc_parallel,
data_sources: vec![],
payload_delivered_fetcher: PayloadDeliveredFetcher::default(),
require_delivered_payload_from_relays: true,
}
}

pub fn with_require_delivered_payload_from_relays(self, require: bool) -> Self {
Self {
require_delivered_payload_from_relays: require,
..self
}
}

Expand Down Expand Up @@ -135,14 +144,27 @@ impl HistoricalDataFetcher {
) -> eyre::Result<(BlockRef, Block, BuilderBlockReceived)> {
info!(block_number, "Fetching historical data for block");

info!("Fetching payload delivered");
let winning_bid_trace = self.get_payload_delivered_bid_trace(block_number).await?;

info!("Fetching block from eth provider");
let onchain_block = self.get_onchain_block(block_number).await?;

let block_timestamp: u64 = timestamp_as_u64(&onchain_block);

info!("Fetching payload delivered");
let winning_bid_trace = match self.get_payload_delivered_bid_trace(block_number).await {
Ok(res) => res,
Err(err) => {
if self.require_delivered_payload_from_relays {
return Err(err);
} else {
warn!(
?err,
"Failed to fetch payload from the relay, using fake payload"
);
generate_fake_delivered_payload(&onchain_block)
}
}
};

let block_ref = BlockRef::new(
block_number,
block_timestamp,
Expand Down Expand Up @@ -297,3 +319,26 @@ pub async fn filter_order_by_nonces(
.filter_map(|(idx, order)| if retain[idx] { Some(order) } else { None })
.collect())
}

fn generate_fake_delivered_payload(block: &Block) -> BuilderBlockReceived {
BuilderBlockReceived {
slot: 0,
Comment on lines +323 to +325
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

Using a hardcoded slot value of 0 in the fake payload may not accurately represent the actual slot for the block. Consider calculating or deriving the appropriate slot value based on the block timestamp and genesis time.

Suggested change
fn generate_fake_delivered_payload(block: &Block) -> BuilderBlockReceived {
BuilderBlockReceived {
slot: 0,
fn generate_fake_delivered_payload(block: &Block, genesis_time: u64, slot_duration: u64) -> BuilderBlockReceived {
let slot = (block.header.timestamp - genesis_time) / slot_duration;
BuilderBlockReceived {
slot,

Copilot uses AI. Check for mistakes.
parent_hash: block.header.parent_hash,
block_hash: block.header.hash,
builder_pubkey: Default::default(),
proposer_pubkey: Default::default(),
// insignificant random address
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

The comment 'insignificant random address' is vague and doesn't explain why this specific address was chosen or its purpose. Consider explaining what this address represents or documenting the criteria for its selection.

Suggested change
// insignificant random address
// Placeholder address for testing purposes; has no functional significance

Copilot uses AI. Check for mistakes.
proposer_fee_recipient: alloy_primitives::address!(
"4e577795E42e1Df9234dc7F572aFd8Cc2777F739"
),
gas_limit: block.header.gas_limit,
gas_used: block.header.gas_used,
value: Default::default(),
num_tx: block.transactions.len() as u64,
block_number: block.header.number,
timestamp: block.header.timestamp,
// assume that payload is generated 3 seconds after the slot timestamp
timestamp_ms: (block.header.timestamp + 3) * 1000,
Comment on lines +340 to +341
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

The hardcoded 3-second offset appears to be a magic number. Consider defining this as a named constant with documentation explaining the rationale behind this timing assumption.

Suggested change
// assume that payload is generated 3 seconds after the slot timestamp
timestamp_ms: (block.header.timestamp + 3) * 1000,
// assume that payload is generated after a fixed offset defined by PAYLOAD_GENERATION_OFFSET_SECONDS
timestamp_ms: (block.header.timestamp + PAYLOAD_GENERATION_OFFSET_SECONDS) * 1000,

Copilot uses AI. Check for mistakes.
optimistic_submission: false,
}
}
Loading