Skip to content

Commit

Permalink
feat(driver): refines the executor interface for the driver (#850)
Browse files Browse the repository at this point in the history
  • Loading branch information
refcell authored Nov 27, 2024
1 parent d1f46f2 commit 39ad652
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 78 deletions.
4 changes: 2 additions & 2 deletions bin/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use kona_executor::ExecutorError;
use kona_preimage::{HintWriterClient, PreimageOracleClient};
use kona_proof::{
errors::OracleProviderError,
executor::KonaExecutorConstructor,
executor::KonaExecutor,
l1::{OracleBlobProvider, OracleL1ChainProvider, OraclePipeline},
l2::OracleL2ChainProvider,
sync::new_pipeline_cursor,
Expand Down Expand Up @@ -116,7 +116,7 @@ where
l1_provider.clone(),
l2_provider.clone(),
);
let executor = KonaExecutorConstructor::new(&cfg, l2_provider.clone(), l2_provider, None);
let executor = KonaExecutor::new(&cfg, l2_provider.clone(), l2_provider, None, None);
let mut driver = Driver::new(cursor, executor, pipeline);

// Run the derivation pipeline until we are able to produce the output root of the claimed
Expand Down
29 changes: 11 additions & 18 deletions crates/driver/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,13 @@ use op_alloy_genesis::RollupConfig;
use op_alloy_protocol::L2BlockInfo;
use op_alloy_rpc_types_engine::OpAttributesWithParent;

use crate::{
DriverError, DriverPipeline, DriverResult, Executor, ExecutorConstructor, PipelineCursor,
TipCursor,
};
use crate::{DriverError, DriverPipeline, DriverResult, Executor, PipelineCursor, TipCursor};

/// The Rollup Driver entrypoint.
#[derive(Debug)]
pub struct Driver<E, EC, DP, P>
pub struct Driver<E, DP, P>
where
E: Executor + Send + Sync + Debug,
EC: ExecutorConstructor<E> + Send + Sync + Debug,
DP: DriverPipeline<P> + Send + Sync + Debug,
P: Pipeline + SignalReceiver + Send + Sync + Debug,
{
Expand All @@ -37,19 +33,18 @@ where
pub pipeline: DP,
/// Cursor to keep track of the L2 tip
pub cursor: PipelineCursor,
/// Executor constructor.
pub executor: EC,
/// The Executor.
pub executor: E,
}

impl<E, EC, DP, P> Driver<E, EC, DP, P>
impl<E, DP, P> Driver<E, DP, P>
where
E: Executor + Send + Sync + Debug,
EC: ExecutorConstructor<E> + Send + Sync + Debug,
DP: DriverPipeline<P> + Send + Sync + Debug,
P: Pipeline + SignalReceiver + Send + Sync + Debug,
{
/// Creates a new [Driver].
pub const fn new(cursor: PipelineCursor, executor: EC, pipeline: DP) -> Self {
pub const fn new(cursor: PipelineCursor, executor: E, pipeline: DP) -> Self {
Self {
_marker: core::marker::PhantomData,
_marker2: core::marker::PhantomData,
Expand Down Expand Up @@ -108,9 +103,8 @@ where
}
};

let mut executor =
self.executor.new_executor(self.cursor.l2_safe_head_header().clone());
let header = match executor.execute_payload(attributes.clone()) {
self.executor.update_safe_head(self.cursor.l2_safe_head_header().clone());
let header = match self.executor.execute_payload(attributes.clone()) {
Ok(header) => header,
Err(e) => {
error!(target: "client", "Failed to execute L2 block: {}", e);
Expand All @@ -133,9 +127,8 @@ where
});

// Retry the execution.
executor =
self.executor.new_executor(self.cursor.l2_safe_head_header().clone());
match executor.execute_payload(attributes.clone()) {
self.executor.update_safe_head(self.cursor.l2_safe_head_header().clone());
match self.executor.execute_payload(attributes.clone()) {
Ok(header) => header,
Err(e) => {
error!(
Expand Down Expand Up @@ -176,7 +169,7 @@ where
let cursor = TipCursor::new(
l2_info,
header.clone().seal_slow(),
executor.compute_output_root().map_err(DriverError::Executor)?,
self.executor.compute_output_root().map_err(DriverError::Executor)?,
);
self.cursor.advance(origin, cursor);
}
Expand Down
14 changes: 3 additions & 11 deletions crates/driver/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,13 @@ pub trait Executor {
/// The error type for the Executor.
type Error: Error + Debug + Display + ToString;

/// Updates the safe header.
fn update_safe_head(&mut self, header: Sealed<Header>);

/// Execute the gicen [OpPayloadAttributes].
fn execute_payload(&mut self, attributes: OpPayloadAttributes) -> Result<&Header, Self::Error>;

/// Computes the output root.
/// Expected to be called after the payload has been executed.
fn compute_output_root(&mut self) -> Result<B256, Self::Error>;
}

/// Constructs the Executor.
///
/// This trait abstracts the construction of the Executor.
pub trait ExecutorConstructor<E>
where
E: Executor,
{
/// Construct the Executor.
fn new_executor(&self, header: Sealed<Header>) -> E;
}
2 changes: 1 addition & 1 deletion crates/driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mod pipeline;
pub use pipeline::DriverPipeline;

mod executor;
pub use executor::{Executor, ExecutorConstructor};
pub use executor::Executor;

mod core;
pub use core::Driver;
Expand Down
3 changes: 3 additions & 0 deletions crates/executor/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ pub enum ExecutorError {
/// RLP error.
#[error("RLP error: {0}")]
RLPError(alloy_eips::eip2718::Eip2718Error),
/// Missing the executor.
#[error("Missing the executor")]
MissingExecutor,
}

/// A [Result] type for the [ExecutorError] enum.
Expand Down
79 changes: 33 additions & 46 deletions crates/proof-sdk/proof/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,15 @@
use alloc::sync::Arc;
use alloy_consensus::{Header, Sealed};
use alloy_primitives::B256;
use kona_driver::{Executor, ExecutorConstructor};
use kona_driver::Executor;
use kona_executor::{KonaHandleRegister, StatelessL2BlockExecutor, TrieDBProvider};
use kona_mpt::TrieHinter;
use op_alloy_genesis::RollupConfig;
use op_alloy_rpc_types_engine::OpPayloadAttributes;

/// An executor wrapper type.
#[derive(Debug)]
pub struct KonaExecutor<'a, P, H>(StatelessL2BlockExecutor<'a, P, H>)
where
P: TrieDBProvider + Send + Sync + Clone,
H: TrieHinter + Send + Sync + Clone;

impl<'a, P, H> KonaExecutor<'a, P, H>
where
P: TrieDBProvider + Send + Sync + Clone,
H: TrieHinter + Send + Sync + Clone,
{
/// Creates a new executor.
pub const fn new(executor: StatelessL2BlockExecutor<'a, P, H>) -> Self {
Self(executor)
}
}

impl<P, H> Executor for KonaExecutor<'_, P, H>
where
P: TrieDBProvider + Send + Sync + Clone,
H: TrieHinter + Send + Sync + Clone,
{
type Error = kona_executor::ExecutorError;

/// Execute the given payload attributes.
fn execute_payload(&mut self, attributes: OpPayloadAttributes) -> Result<&Header, Self::Error> {
self.0.execute_payload(attributes)
}

/// Computes the output root.
fn compute_output_root(&mut self) -> Result<B256, Self::Error> {
self.0.compute_output_root()
}
}

/// An executor constructor.
#[derive(Debug)]
pub struct KonaExecutorConstructor<'a, P, H>
pub struct KonaExecutor<'a, P, H>
where
P: TrieDBProvider + Send + Sync + Clone,
H: TrieHinter + Send + Sync + Clone,
Expand All @@ -60,31 +24,39 @@ where
trie_hinter: H,
/// The handle register for the executor.
handle_register: Option<KonaHandleRegister<P, H>>,
/// The executor.
inner: Option<StatelessL2BlockExecutor<'a, P, H>>,
}

impl<'a, P, H> KonaExecutorConstructor<'a, P, H>
impl<'a, P, H> KonaExecutor<'a, P, H>
where
P: TrieDBProvider + Send + Sync + Clone,
H: TrieHinter + Send + Sync + Clone,
{
/// Creates a new executor constructor.
pub fn new(
/// Creates a new executor.
pub const fn new(
rollup_config: &'a Arc<RollupConfig>,
trie_provider: P,
trie_hinter: H,
handle_register: Option<KonaHandleRegister<P, H>>,
inner: Option<StatelessL2BlockExecutor<'a, P, H>>,
) -> Self {
Self { rollup_config, trie_provider, trie_hinter, handle_register }
Self { rollup_config, trie_provider, trie_hinter, handle_register, inner }
}
}

impl<'a, P, H> ExecutorConstructor<KonaExecutor<'a, P, H>> for KonaExecutorConstructor<'a, P, H>
impl<P, H> Executor for KonaExecutor<'_, P, H>
where
P: TrieDBProvider + Send + Sync + Clone,
H: TrieHinter + Send + Sync + Clone,
{
/// Constructs the executor.
fn new_executor(&self, header: Sealed<Header>) -> KonaExecutor<'a, P, H> {
type Error = kona_executor::ExecutorError;

/// Updates the safe header.
///
/// Since the L2 block executor is stateless, on an update to the safe head,
/// a new executor is created with the updated header.
fn update_safe_head(&mut self, header: Sealed<Header>) {
let mut builder = StatelessL2BlockExecutor::builder(
self.rollup_config,
self.trie_provider.clone(),
Expand All @@ -95,7 +67,22 @@ where
if let Some(register) = self.handle_register {
builder = builder.with_handle_register(register);
}
self.inner = Some(builder.build());
}

/// Execute the given payload attributes.
fn execute_payload(&mut self, attributes: OpPayloadAttributes) -> Result<&Header, Self::Error> {
self.inner.as_mut().map_or_else(
|| Err(kona_executor::ExecutorError::MissingExecutor),
|e| e.execute_payload(attributes),
)
}

KonaExecutor::new(builder.build())
/// Computes the output root.
fn compute_output_root(&mut self) -> Result<B256, Self::Error> {
self.inner.as_mut().map_or_else(
|| Err(kona_executor::ExecutorError::MissingExecutor),
|e| e.compute_output_root(),
)
}
}

0 comments on commit 39ad652

Please sign in to comment.