Skip to content
Open
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
64 changes: 42 additions & 22 deletions crates/op-rbuilder/src/builder/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,11 @@ impl FlashblocksState {
self.target_flashblock_count
}

fn is_first_flashblock(&self) -> bool {
self.flashblock_index == 0
}

fn is_last_flashblock(&self) -> bool {
self.flashblock_index == self.target_flashblock_count
fn meta(&self) -> FlashblockMeta {
FlashblockMeta {
flashblock_index: self.flashblock_index,
target_flashblock_count: self.target_flashblock_count,
}
}

fn target_gas_for_batch(&self) -> u64 {
Expand Down Expand Up @@ -234,6 +233,24 @@ impl FlashblocksState {
}
}

/// Projection of [`FlashblocksState`] describing where the current
/// build sits within the slot's flashblock sequence.
#[derive(Debug, Clone, Copy)]
struct FlashblockMeta {
flashblock_index: u64,
target_flashblock_count: u64,
}

impl FlashblockMeta {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why not include other fields like the target count?

Copy link
Copy Markdown
Member Author

@julio4 julio4 May 27, 2026

Choose a reason for hiding this comment

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

The idea is that FlashblockMeta is a projection of FlashblocksState only for BuilderTx. And BuilderTx acts as some kind of pre-seal 'hook', so this projection can be expanded later on if needed but kept as minimal as possible now.

fn is_first(&self) -> bool {
self.flashblock_index == 0
}

fn is_last(&self) -> bool {
self.flashblock_index == self.target_flashblock_count
}
}

/// Optimism's payload builder
#[derive(Debug)]
pub(super) struct OpPayloadBuilder<Pool, Client, BuilderTx> {
Expand Down Expand Up @@ -863,23 +880,24 @@ where
ctx.metrics.sequencer_tx_gauge.set(sequencer_tx_time);

// We add first builder tx right after deposits
if !ctx.attributes().no_tx_pool
&& let Err(e) = self.builder_tx.add_builder_txs(
if !ctx.attributes().no_tx_pool {
let flashblock = fb_state.meta();
if let Err(e) = self.builder_tx.add_builder_txs(
&state_provider,
&mut info,
&ctx.builder_tx_env(),
&mut state,
false,
fb_state.is_first_flashblock(),
fb_state.is_last_flashblock(),
)
{
error!(
target: "payload_builder",
"Error adding builder txs to fallback block: {}",
e
);
};
flashblock.is_first(),
flashblock.is_last(),
) {
error!(
target: "payload_builder",
"Error adding builder txs to fallback block: {}",
e
);
}
}

let (payload, fb_payload) = ctx.block_assembly_input()?.assemble(
&mut state,
Expand Down Expand Up @@ -940,6 +958,7 @@ where
);
let flashblock_build_start_time = Instant::now();

let flashblock = fb_state.meta();
let builder_txs = self
.builder_tx
.add_builder_txs(
Expand All @@ -948,8 +967,8 @@ where
&ctx.builder_tx_env(),
state,
true,
fb_state.is_first_flashblock(),
fb_state.is_last_flashblock(),
flashblock.is_first(),
flashblock.is_last(),
)
.inspect_err(
|e| error!(target: "payload_builder", error = %e, "Error simulating builder txs"),
Expand Down Expand Up @@ -1023,14 +1042,15 @@ where
.payload_transaction_simulation_gauge
.set(payload_transaction_simulation_time);

let flashblock = fb_state.meta();
if let Err(e) = self.builder_tx.add_builder_txs(
&state_provider,
info,
&ctx.builder_tx_env(),
state,
false,
fb_state.is_first_flashblock(),
fb_state.is_last_flashblock(),
flashblock.is_first(),
flashblock.is_last(),
) {
error!(target: "payload_builder", error = %e, "Error simulating builder txs");
}
Expand Down
Loading