Skip to content

Commit

Permalink
wip: executor
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr committed Dec 25, 2024
1 parent d3e2509 commit 2184951
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
116 changes: 116 additions & 0 deletions crates/evm/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,119 @@
// complex unless we operate on something that yields `Tx`, and not blocks, this iterator style
// type must be aware of things like `gas_used`, invalid tx, etc... so that we can properly build
// a block.

use crate::evm::Evm;

/// Abstraction over block execution input.
///
/// This type must contain all of the context required to configure EVM and a way to obtain
/// transactions for the block.
pub trait BlockExecutionInput {
/// Transaction type.
type Transaction;
}

/// Abstraction over block execution outcome.
pub trait BlockExecutionOutcome {
/// Receipt type.
type Receipt;

fn receipts(&self) -> &[Self::Receipt];
}

/// Abstraction over type that is capable of executing a block.
///
/// This type knows how to configure an underlying EVM and execute transactions on top of it along
/// with any additional pre/post execution actions.
pub trait BlockExecutor {
/// Input for the block execution.
type Input: BlockExecutionInput;

/// Outcome of the block execution.
type Output: BlockExecutionOutcome;

/// Errors that can occur during block execution.
type Error;

fn execute(&mut self, input: Self::Input) -> Result<Self::Output, Self::Error>;
}

#[cfg(test)]
mod tests {
use crate::evm::{self, EvmFactory};

use super::*;

trait Primitives {
type Transaction: Default;
type Receipt: Default;
}

trait ReceiptBuilder<Tx, EvmRes> {
type Receipt: Default;

fn build_receipt<'a>(
&self,
ctx: &'a BlockExecutorContext,
tx: &'a Tx,
evm_res: &'a EvmRes,
) -> Self::Receipt;
}

#[derive(Default)]
struct BlockExecutorContext {
gas_used: u64,
blob_gas_used: u64,
}

struct BlockExecutorOutput<T> {
receipts: Vec<T>,
}

struct EthBlockExecutor<EvmF, ReceiptB, T> {
evm_factory: EvmF,
receipt_builder: ReceiptB,
_pd: core::marker::PhantomData<T>,
}

impl<EvmF, ReceiptB, T> BlockExecutor for EthBlockExecutor<EvmF, ReceiptB, T>
where
EvmF: EvmFactory<Evm: Evm<Tx: From<T>>>,
ReceiptB: ReceiptBuilder<T, <EvmF::Evm as Evm>::Outcome>,
{
type Input = alloy_consensus::Block<T>;
type Output = BlockExecutorOutput<ReceiptB::Receipt>;
type Error = <EvmF::Evm as Evm>::Error;

fn execute(&mut self, input: Self::Input) -> Result<Self::Output, Self::Error> {
let evm_input: EvmF::Input = todo!();
let mut evm = self.evm_factory.create_evm(evm_input);

let mut ctx = BlockExecutorContext::default();
let mut receipts = Vec::new();

for tx in input.body.transactions {
let result = evm.transact(tx.into())?;
// ctx.gas_used += result.gas_used();
// ctx.blob_gas_used += result.blob_gas_used();

let receipt = self.receipt_builder.build_receipt(&ctx, &tx, &result);
receipts.push(receipt);
}

Ok(BlockExecutorOutput { receipts })
}
}

impl<T> BlockExecutionInput for alloy_consensus::Block<T> {
type Transaction = T;
}

impl<R> BlockExecutionOutcome for BlockExecutorOutput<R> {
type Receipt = R;

fn receipts(&self) -> &[Self::Receipt] {
&self.receipts
}
}
}
1 change: 1 addition & 0 deletions crates/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@

pub mod block;
pub mod evm;
pub use evm::{Evm, EvmFactory};

0 comments on commit 2184951

Please sign in to comment.