Skip to content

Commit 648b929

Browse files
authored
fix: handle finalized head in reconciliation (#431)
* handle finalized head in reconciliation * handle finalized head in reconciliation
1 parent 2edf7a0 commit 648b929

File tree

4 files changed

+26
-14
lines changed

4 files changed

+26
-14
lines changed

crates/chain-orchestrator/src/consolidation.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,14 @@ pub(crate) async fn reconcile_batch<L2P: Provider<Scroll>>(
3838

3939
// The block matches the derived attributes and the block is below or equal to the
4040
// safe current safe head.
41-
if attributes.block_number <= fcs.safe_block_info().number {
41+
if attributes.block_number <= fcs.finalized_block_info().number ||
42+
((attributes.block_number <= fcs.safe_block_info().number) &&
43+
batch.target_status.is_consolidated())
44+
{
4245
Ok::<_, ChainOrchestratorError>(BlockConsolidationAction::Skip(block_info))
4346
} else {
4447
// The block matches the derived attributes, no action is needed.
45-
Ok::<_, ChainOrchestratorError>(BlockConsolidationAction::UpdateSafeHead(
46-
block_info,
47-
))
48+
Ok::<_, ChainOrchestratorError>(BlockConsolidationAction::UpdateFcs(block_info))
4849
}
4950
} else {
5051
// The block does not match the derived attributes, a reorg is needed.
@@ -81,7 +82,7 @@ impl BatchReconciliationResult {
8182
for next in &self.actions {
8283
if let Some(last) = actions.last_mut() {
8384
match (last, next) {
84-
(last, next) if last.is_update_safe_head() && next.is_update_safe_head() => {
85+
(last, next) if last.is_update_fcs() && next.is_update_fcs() => {
8586
*last = next.clone();
8687
}
8788
_ => {
@@ -128,8 +129,8 @@ pub(crate) struct AggregatedBatchConsolidationActions {
128129
/// An action that must be performed on the L2 chain to consolidate a block.
129130
#[derive(Debug, Clone)]
130131
pub(crate) enum BlockConsolidationAction {
131-
/// Update the safe head to the given block.
132-
UpdateSafeHead(L2BlockInfoWithL1Messages),
132+
/// Update the fcs to the given block.
133+
UpdateFcs(L2BlockInfoWithL1Messages),
133134
/// The derived attributes match the L2 chain and the safe head is already at or beyond the
134135
/// block, so no action is needed.
135136
Skip(L2BlockInfoWithL1Messages),
@@ -138,9 +139,9 @@ pub(crate) enum BlockConsolidationAction {
138139
}
139140

140141
impl BlockConsolidationAction {
141-
/// Returns true if the action is to update the safe head.
142-
pub(crate) const fn is_update_safe_head(&self) -> bool {
143-
matches!(self, Self::UpdateSafeHead(_))
142+
/// Returns true if the action is to update the fcs.
143+
pub(crate) const fn is_update_fcs(&self) -> bool {
144+
matches!(self, Self::UpdateFcs(_))
144145
}
145146

146147
/// Returns true if the action is to skip the block.
@@ -157,7 +158,7 @@ impl BlockConsolidationAction {
157158
/// skip, returns None for reorg.
158159
pub(crate) fn into_block_info(self) -> Option<L2BlockInfoWithL1Messages> {
159160
match self {
160-
Self::UpdateSafeHead(info) | Self::Skip(info) => Some(info),
161+
Self::UpdateFcs(info) | Self::Skip(info) => Some(info),
161162
Self::Reorg(_attrs) => None,
162163
}
163164
}
@@ -166,7 +167,7 @@ impl BlockConsolidationAction {
166167
impl std::fmt::Display for BlockConsolidationAction {
167168
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168169
match self {
169-
Self::UpdateSafeHead(info) => {
170+
Self::UpdateFcs(info) => {
170171
write!(f, "UpdateSafeHead to block {}", info.block_info.number)
171172
}
172173
Self::Skip(info) => write!(f, "Skip block {}", info.block_info.number),

crates/chain-orchestrator/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ impl<
454454
BlockConsolidationAction::Skip(_) => {
455455
unreachable!("Skip actions have been filtered out in aggregation")
456456
}
457-
BlockConsolidationAction::UpdateSafeHead(block_info) => {
457+
BlockConsolidationAction::UpdateFcs(block_info) => {
458458
tracing::info!(target: "scroll::chain_orchestrator", ?block_info, "Updating safe head to consolidated block");
459459
let finalized_block_info = batch_reconciliation_result
460460
.target_status

crates/engine/src/fcs.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,16 @@ impl ForkchoiceState {
4848
pub async fn from_provider<P: Provider<Scroll>>(provider: &P) -> Option<Self> {
4949
let latest_block =
5050
provider.get_block(BlockId::Number(BlockNumberOrTag::Latest)).await.ok()??;
51-
let safe_block =
51+
let mut safe_block =
5252
provider.get_block(BlockId::Number(BlockNumberOrTag::Safe)).await.ok()??;
5353
let finalized_block =
5454
provider.get_block(BlockId::Number(BlockNumberOrTag::Finalized)).await.ok()??;
55+
56+
// Ensure safe is at least finalized.
57+
if safe_block.header.number < finalized_block.header.number {
58+
safe_block = finalized_block.clone();
59+
}
60+
5561
Some(Self {
5662
head: BlockInfo { number: latest_block.header.number, hash: latest_block.header.hash },
5763
safe: BlockInfo { number: safe_block.header.number, hash: safe_block.header.hash },

crates/primitives/src/batch.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ pub enum BatchStatus {
7979
}
8080

8181
impl BatchStatus {
82+
/// Returns true if the batch status is consolidated.
83+
pub const fn is_consolidated(&self) -> bool {
84+
matches!(self, Self::Consolidated)
85+
}
86+
8287
/// Returns true if the batch status is finalized.
8388
pub const fn is_finalized(&self) -> bool {
8489
matches!(self, Self::Finalized)

0 commit comments

Comments
 (0)