use crate::{
EngineClient, EngineState, EngineTaskExt, FinalizeTaskError, SynchronizeTask,
state::EngineSyncStateUpdate,
};
use alloy_provider::Provider;
use async_trait::async_trait;
use kona_genesis::RollupConfig;
use kona_protocol::L2BlockInfo;
use std::{sync::Arc, time::Instant};
#[derive(Debug, Clone)]
pub struct FinalizeTask {
pub client: Arc<EngineClient>,
pub cfg: Arc<RollupConfig>,
pub block_number: u64,
}
impl FinalizeTask {
pub const fn new(client: Arc<EngineClient>, cfg: Arc<RollupConfig>, block_number: u64) -> Self {
Self { client, cfg, block_number }
}
}
#[async_trait]
impl EngineTaskExt for FinalizeTask {
type Output = ();
type Error = FinalizeTaskError;
async fn execute(&self, state: &mut EngineState) -> Result<(), FinalizeTaskError> {
if state.sync_state.safe_head().block_info.number < self.block_number {
return Err(FinalizeTaskError::BlockNotSafe);
}
let block_fetch_start = Instant::now();
let block = self
.client
.l2_engine()
.get_block(self.block_number.into())
.full()
.await
.map_err(FinalizeTaskError::TransportError)?
.ok_or(FinalizeTaskError::BlockNotFound(self.block_number))?
.into_consensus();
let block_info = L2BlockInfo::from_block_and_genesis(&block, &self.client.cfg().genesis)
.map_err(FinalizeTaskError::FromBlock)?;
let block_fetch_duration = block_fetch_start.elapsed();
let fcu_start = Instant::now();
SynchronizeTask::new(
self.client.clone(),
self.cfg.clone(),
EngineSyncStateUpdate { finalized_head: Some(block_info), ..Default::default() },
)
.execute(state)
.await?;
let fcu_duration = fcu_start.elapsed();
info!(
target: "engine",
hash = %block_info.block_info.hash,
number = block_info.block_info.number,
?block_fetch_duration,
?fcu_duration,
"Updated finalized head"
);
Ok(())
}
}