Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: better custom evm abstraction #843

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
1,260 changes: 1,068 additions & 192 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ op-alloy-protocol = { version = "0.6.8", default-features = false }
op-alloy-consensus = { version = "0.6.8", default-features = false }
op-alloy-rpc-types-engine = { version = "0.6.8", default-features = false, features = ["serde"] }

# Reth
reth-evm = { git = "https://github.com/zobront/reth.git", branch = "roaring-optional", default-features = false }
reth-primitives-traits = { git = "https://github.com/zobront/reth.git", branch = "roaring-optional", default-features = false }
reth-primitives = { git = "https://github.com/zobront/reth.git", branch = "roaring-optional", default-features = false }
reth-optimism-chainspec = { git = "https://github.com/zobront/reth.git", branch = "roaring-optional", default-features = false }
reth-optimism-forks = { git = "https://github.com/zobront/reth.git", branch = "roaring-optional", default-features = false }

# General
lru = "0.12.4"
spin = "0.9.8"
Expand Down Expand Up @@ -130,7 +137,8 @@ serde_json = { version = "1.0.132", default-features = false }

# Ethereum
unsigned-varint = "0.8.0"
revm = { version = "16.0.0", default-features = false }
revm = { version = "18.0.0", default-features = false }
revm-primitives = { version = "14.0.0", default-features = false }

# K/V database
rocksdb = { version = "0.22", default-features = false }
3 changes: 3 additions & 0 deletions bin/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ op-alloy-genesis = { workspace = true, features = ["serde"] }
# Revm
revm.workspace = true

# Reth
reth-optimism-chainspec.workspace = true

# General
lru.workspace = true
spin.workspace = true
Expand Down
13 changes: 11 additions & 2 deletions bin/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use alloc::sync::Arc;
use alloy_primitives::B256;
use core::fmt::Debug;
use kona_driver::{Driver, DriverError};
use kona_executor::ExecutorError;
use kona_executor::{DefaultEvmConfig, ExecutorError};
use kona_preimage::{HintWriterClient, PreimageOracleClient};
use kona_proof::{
errors::OracleProviderError,
Expand All @@ -20,6 +20,7 @@ use kona_proof::{
sync::new_pipeline_cursor,
BootInfo, CachingOracle,
};
use reth_optimism_chainspec::OpChainSpecBuilder;
use thiserror::Error;
use tracing::{error, info, warn};

Expand Down Expand Up @@ -116,7 +117,15 @@ where
l1_provider.clone(),
l2_provider.clone(),
);
let executor = KonaExecutorConstructor::new(&cfg, l2_provider.clone(), l2_provider, None);
let executor = KonaExecutorConstructor::new(
&cfg,
DefaultEvmConfig::new(
// ZTODO: Use custom chainspec here, not defaulting to OP Mainnet
Arc::new(OpChainSpecBuilder::optimism_mainnet().build()),
),
Comment on lines +123 to +125
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@clabby Is this client only for OP Mainnet (ie is this safe) or should it work for any chain that uses FPVM? If the latter, I'll construct ChainSpec out of data in the RollupConfig.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It should work for any chain with a RollupConfig, yep!

l2_provider.clone(),
l2_provider,
);
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
8 changes: 8 additions & 0 deletions crates/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ op-alloy-rpc-types-engine.workspace = true

# Revm
revm = { workspace = true, features = ["optimism"] }
revm-primitives.workspace = true

# Reth
reth-evm.workspace = true
reth-primitives-traits.workspace = true
reth-primitives.workspace = true
reth-optimism-chainspec.workspace = true
reth-optimism-forks.workspace = true

# General
thiserror.workspace = true
Expand Down
9 changes: 8 additions & 1 deletion crates/executor/benches/execution.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
#![allow(missing_docs)]
//! Benches for the [StatelessL2BlockExecutor] implementation.

extern crate alloc;

use alloc::sync::Arc;
use alloy_consensus::{Header, Sealable};
use alloy_primitives::{address, b256, hex, Bytes, B256};
use alloy_rlp::Decodable;
use alloy_rpc_types_engine::PayloadAttributes;
use anyhow::{anyhow, Result};
use criterion::{criterion_group, criterion_main, Bencher, Criterion};
use kona_executor::{StatelessL2BlockExecutor, TrieDBProvider};
use kona_executor::{DefaultEvmConfig, StatelessL2BlockExecutor, TrieDBProvider};
use kona_mpt::{NoopTrieHinter, TrieNode, TrieProvider};
use op_alloy_genesis::{RollupConfig, OP_MAINNET_BASE_FEE_PARAMS};
use op_alloy_rpc_types_engine::OpPayloadAttributes;
use pprof::criterion::{Output, PProfProfiler};
use reth_optimism_chainspec::OpChainSpecBuilder;
use serde::Deserialize;
use std::collections::HashMap;

Expand Down Expand Up @@ -93,6 +97,9 @@ fn op_mainnet_exec_bench(
NoopTrieHinter,
)
.with_parent_header(pre_state_header.clone().seal_slow())
.with_evm_config(DefaultEvmConfig::new(Arc::new(
OpChainSpecBuilder::optimism_mainnet().build(),
)))
.build();
l2_block_executor.execute_payload(payload_attrs.clone()).unwrap();
});
Expand Down
6 changes: 6 additions & 0 deletions crates/executor/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ pub enum ExecutorError {
/// RLP error.
#[error("RLP error: {0}")]
RLPError(alloy_eips::eip2718::Eip2718Error),
/// EVM Config error.
#[error("Unable to generate EVM config from parent header and attributes")]
EvmConfigError,
/// Invalid transaction.
#[error("Invalid transaction signature")]
TransactionSignatureError,
}

/// A [Result] type for the [ExecutorError] enum.
Expand Down
51 changes: 22 additions & 29 deletions crates/executor/src/executor/builder.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
//! Contains the builder pattern for the [StatelessL2BlockExecutor].

use super::StatelessL2BlockExecutor;
use super::{ConfigureEvm, StatelessL2BlockExecutor};
use crate::db::{TrieDB, TrieDBProvider};
use alloy_consensus::{Header, Sealable, Sealed};
use kona_mpt::TrieHinter;
use op_alloy_genesis::RollupConfig;
use revm::{db::State, handler::register::EvmHandler};

/// A type alias for the [revm::handler::register::HandleRegister] for kona's block executor.
pub type KonaHandleRegister<F, H> =
for<'i> fn(&mut EvmHandler<'i, (), &mut State<&mut TrieDB<F, H>>>);

/// The builder pattern for the [StatelessL2BlockExecutor].
#[derive(Debug)]
pub struct StatelessL2BlockExecutorBuilder<'a, F, H>
pub struct StatelessL2BlockExecutorBuilder<'a, F, H, C>
where
F: TrieDBProvider,
H: TrieHinter,
C: ConfigureEvm,
{
/// The [RollupConfig].
config: &'a RollupConfig,
Expand All @@ -26,18 +22,19 @@ where
hinter: H,
/// The parent [Header] to begin execution from.
parent_header: Option<Sealed<Header>>,
/// The [KonaHandleRegister] to use during execution.
handler_register: Option<KonaHandleRegister<F, H>>,
/// The [ConfigureEvm] or chainspec used to derive it.
evm_config: Option<C>,
}

impl<'a, F, H> StatelessL2BlockExecutorBuilder<'a, F, H>
impl<'a, F, H, C> StatelessL2BlockExecutorBuilder<'a, F, H, C>
where
F: TrieDBProvider,
H: TrieHinter,
C: ConfigureEvm,
{
/// Instantiate a new builder with the given [RollupConfig].
pub fn new(config: &'a RollupConfig, provider: F, hinter: H) -> Self {
Self { config, provider, hinter, parent_header: None, handler_register: None }
Self { config, provider, hinter, parent_header: None, evm_config: None }
}

/// Set the [Header] to begin execution from.
Expand All @@ -46,50 +43,46 @@ where
self
}

/// Set the [KonaHandleRegister] for execution.
pub fn with_handle_register(mut self, handler_register: KonaHandleRegister<F, H>) -> Self {
self.handler_register = Some(handler_register);
/// Set the [ConfigureEvm] for execution.
pub fn with_evm_config(mut self, evm_config: C) -> Self {
self.evm_config = Some(evm_config);
self
}

/// Build the [StatelessL2BlockExecutor] from the builder configuration.
pub fn build(self) -> StatelessL2BlockExecutor<'a, F, H> {
pub fn build(self) -> StatelessL2BlockExecutor<'a, F, H, C> {
let parent_header = self.parent_header.unwrap_or_else(|| {
let default_header = Header::default();
default_header.seal_slow()
});

let evm_config = self.evm_config.expect("evm config must be set");

let trie_db =
TrieDB::new(parent_header.state_root, parent_header, self.provider, self.hinter);
StatelessL2BlockExecutor {
config: self.config,
trie_db,
handler_register: self.handler_register,
}

StatelessL2BlockExecutor { config: self.config, trie_db, evm_config }
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::NoopTrieDBProvider;
use crate::{DefaultEvmConfig, NoopTrieDBProvider};
use alloc::sync::Arc;
use kona_mpt::NoopTrieHinter;
use reth_optimism_chainspec::OpChainSpecBuilder;

#[test]
fn test_build_full() {
let config = RollupConfig::default();
let parent_header = Header::default().seal_slow();

fn test_handler_register<F, H>(_: &mut EvmHandler<'_, (), &mut State<&mut TrieDB<F, H>>>)
where
F: TrieDBProvider,
H: TrieHinter,
{
}

let executor =
StatelessL2BlockExecutorBuilder::new(&config, NoopTrieDBProvider, NoopTrieHinter)
.with_handle_register(test_handler_register)
.with_evm_config(DefaultEvmConfig::new(Arc::new(
OpChainSpecBuilder::optimism_mainnet().build(),
)))
.build();

assert_eq!(*executor.config, config);
Expand Down
Loading