Skip to content
Closed
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "trevm"
version = "0.31.2"
version = "0.31.3"
rust-version = "1.83.0"
edition = "2021"
authors = ["init4"]
Expand Down
54 changes: 37 additions & 17 deletions src/driver/alloy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ pub enum BundleError<Db: Database> {
/// An unsupported transaction type was encountered.
UnsupportedTransactionType,
/// An error occurred while decoding a transaction contained in the bundle.
TransactionDecodingError(alloy::eips::eip2718::Eip2718Error),
TransactionDecoding(alloy::eips::eip2718::Eip2718Error),
/// An error occurred while recovering the sender of a transaction.
TransactionSenderRecoveryError(alloy::consensus::crypto::RecoveryError),
TransactionSenderRecovery(alloy::consensus::crypto::RecoveryError),
/// An error occurred while running the EVM.
EVMError {
/// The error that occurred while running the EVM.
Expand All @@ -59,8 +59,8 @@ impl<Db: Database> core::fmt::Display for BundleError<Db> {
Self::BundleEmpty => write!(f, "bundle has no transactions"),
Self::Eip4844BlobGasExceeded => write!(f, "max blob gas limit exceeded"),
Self::UnsupportedTransactionType => write!(f, "unsupported transaction type"),
Self::TransactionDecodingError(err) => write!(f, "transaction decoding error: {err}"),
Self::TransactionSenderRecoveryError(err) => {
Self::TransactionDecoding(err) => write!(f, "transaction decoding error: {err}"),
Self::TransactionSenderRecovery(err) => {
write!(f, "transaction sender recovery error: {err}")
}
Self::EVMError { inner } => write!(f, "internal EVM error: {inner}"),
Expand All @@ -70,13 +70,13 @@ impl<Db: Database> core::fmt::Display for BundleError<Db> {

impl<Db: Database> From<alloy::eips::eip2718::Eip2718Error> for BundleError<Db> {
fn from(err: alloy::eips::eip2718::Eip2718Error) -> Self {
Self::TransactionDecodingError(err)
Self::TransactionDecoding(err)
}
}

impl<Db: Database> From<alloy::primitives::SignatureError> for BundleError<Db> {
fn from(err: alloy::primitives::SignatureError) -> Self {
Self::TransactionSenderRecoveryError(err.into())
Self::TransactionSenderRecovery(err.into())
}
}

Expand All @@ -89,16 +89,16 @@ impl<Db: Database> From<EVMError<Db::Error>> for BundleError<Db> {
impl<Db: Database> std::error::Error for BundleError<Db> {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::TransactionDecodingError(err) => Some(err),
Self::TransactionSenderRecoveryError(err) => Some(err),
Self::TransactionDecoding(err) => Some(err),
Self::TransactionSenderRecovery(err) => Some(err),
_ => None,
}
}
}

impl<Db: Database> From<RecoveryError> for BundleError<Db> {
fn from(err: RecoveryError) -> Self {
Self::TransactionSenderRecoveryError(err)
Self::TransactionSenderRecovery(err)
}
}

Expand All @@ -109,18 +109,18 @@ impl<Db: Database> core::fmt::Debug for BundleError<Db> {
Self::BlockNumberMismatch => write!(f, "BlockNumberMismatch"),
Self::BundleEmpty => write!(f, "BundleEmpty"),
Self::BundleReverted => write!(f, "BundleReverted"),
Self::TransactionDecodingError(e) => write!(f, "TransactionDecodingError({e:?})"),
Self::TransactionDecoding(e) => write!(f, "TransactionDecodingError({e:?})"),
Self::UnsupportedTransactionType => write!(f, "UnsupportedTransactionType"),
Self::Eip4844BlobGasExceeded => write!(f, "Eip4844BlobGasExceeded"),
Self::TransactionSenderRecoveryError(e) => {
Self::TransactionSenderRecovery(e) => {
write!(f, "TransactionSenderRecoveryError({e:?})")
}
Self::EVMError { .. } => write!(f, "EVMError"),
}
}
}

/// A bundle processor which can be used to drive a bundle with a [BundleDriver], accumulate the results of the bundle and dispatch
/// A bundle processor which can be used to drive a bundle with a [`BundleDriver`], accumulate the results of the bundle and dispatch
/// a response.
#[derive(Debug)]
pub struct BundleProcessor<B, R> {
Expand Down Expand Up @@ -156,7 +156,8 @@ where
}

impl<B, R> BundleProcessor<B, R> {
/// Decode and validate the transactions in the bundle, performing EIP4844 gas checks.
/// Decode and validate the transactions in the bundle, performing EIP4844
/// gas checks.
pub fn decode_and_validate_txs<Db: Database + DatabaseCommit>(
txs: &[Bytes],
) -> Result<Vec<TxEnvelope>, BundleError<Db>> {
Expand Down Expand Up @@ -190,7 +191,8 @@ impl BundleProcessor<EthCallBundle, EthCallBundleResponse> {
Self::new(bundle)
}

/// Process a bundle transaction and accumulate the results into a [EthCallBundleTransactionResult].
/// Process a bundle transaction and accumulate the results into a
/// [`EthCallBundleTransactionResult`].
pub fn process_call_bundle_tx<Db: Database + DatabaseCommit>(
tx: &TxEnvelope,
pre_sim_coinbase_balance: U256,
Expand Down Expand Up @@ -274,6 +276,10 @@ where
{
type Error = BundleError<Db>;

fn transactions(&self) -> impl IntoIterator<Item = &[u8]> {
self.bundle.txs.iter().map(|b| b.as_ref())
}

fn run_bundle(
&mut self,
trevm: crate::EvmNeedsTx<Db, Insp>,
Expand Down Expand Up @@ -411,6 +417,10 @@ where
{
type Error = BundleError<Db>;

fn transactions(&self) -> impl IntoIterator<Item = &[u8]> {
self.bundle.txs.iter().map(|b| b.as_ref())
}

fn run_bundle(
&mut self,
trevm: crate::EvmNeedsTx<Db, Insp>,
Expand Down Expand Up @@ -555,6 +565,10 @@ where
{
type Error = BundleError<Db>;

fn transactions(&self) -> impl IntoIterator<Item = &[u8]> {
self.txs.iter().map(|b| b.as_ref())
}

fn run_bundle(
&mut self,
trevm: crate::EvmNeedsTx<Db, Insp>,
Expand Down Expand Up @@ -637,16 +651,22 @@ where
}
}

/// An implementation of [BundleDriver] for [EthSendBundle].
/// This allows us to drive a bundle of transactions and accumulate the resulting state in the EVM.
/// Allows to simply take an [EthSendBundle] and get the resulting EVM state.
/// An implementation of [`BundleDriver`] for [`EthSendBundle`].
/// This allows us to drive a bundle of transactions and accumulate the
/// resulting state in the EVM.
///
/// Allows to simply take an [`EthSendBundle`] and get the resulting EVM state.
impl<Db, Insp> BundleDriver<Db, Insp> for EthSendBundle
where
Db: Database + DatabaseCommit,
Insp: Inspector<Ctx<Db>>,
{
type Error = BundleError<Db>;

fn transactions(&self) -> impl IntoIterator<Item = &[u8]> {
self.txs.iter().map(|b| b.as_ref())
}

fn run_bundle(
&mut self,
trevm: crate::EvmNeedsTx<Db, Insp>,
Expand Down
29 changes: 28 additions & 1 deletion src/driver/bundle.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
use crate::{helpers::Ctx, EvmBundleDriverErrored, EvmNeedsTx};
use crate::{helpers::Ctx, BundleError, EvmBundleDriverErrored, EvmNeedsTx};
use alloy::{
consensus::{
transaction::{Recovered, SignerRecoverable},
TxEnvelope,
},
eips::Decodable2718,
};
use revm::{
context::result::EVMError, inspector::NoOpInspector, Database, DatabaseCommit, Inspector,
};
Expand All @@ -17,6 +24,26 @@ where
/// An error type for this driver.
type Error: core::error::Error + From<EVMError<Db::Error>>;

/// Get an iterator over the raw transaction bytes in this bundle.
fn transactions(&self) -> impl IntoIterator<Item = &[u8]>;

/// Recover the transactions in this bundle.
fn recovered_transactions(
&self,
) -> impl IntoIterator<Item = Result<Recovered<TxEnvelope>, BundleError<Db>>>
where
Self: Sized,
Db: Database,
{
self.transactions().into_iter().map(|tx_bytes| {
TxEnvelope::decode_2718_exact(tx_bytes)
.map_err(BundleError::TransactionDecoding)
.and_then(|envelope| {
envelope.try_into_recovered().map_err(BundleError::TransactionSenderRecovery)
})
})
}

/// Run the transactions contained in the bundle.
fn run_bundle(&mut self, trevm: EvmNeedsTx<Db, Insp>) -> DriveBundleResult<Self, Db, Insp>;

Expand Down