mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-08 14:05:16 -05:00
feat(examples): Make CustomEvmTransaction local and implement FromRecoveredTx and FromTxWithEncoded in custom_node example (#16415)
This commit is contained in:
@@ -4,7 +4,7 @@ use alloy_primitives::{Address, Bytes, TxKind, U256};
|
||||
use op_alloy_consensus::OpTxType;
|
||||
use op_revm::{
|
||||
precompiles::OpPrecompiles, transaction::deposit::DepositTransactionParts, DefaultOp,
|
||||
L1BlockInfo, OpBuilder, OpHaltReason, OpSpecId, OpTransactionError,
|
||||
L1BlockInfo, OpBuilder, OpHaltReason, OpSpecId, OpTransaction, OpTransactionError,
|
||||
};
|
||||
use reth_ethereum::evm::revm::{
|
||||
context::{result::ResultAndState, BlockEnv, CfgEnv, TxEnv},
|
||||
@@ -20,7 +20,7 @@ use std::error::Error;
|
||||
|
||||
/// EVM context contains data that EVM needs for execution of [`CustomEvmTransaction`].
|
||||
pub type CustomContext<DB> =
|
||||
Context<BlockEnv, CustomEvmTransaction, CfgEnv<OpSpecId>, DB, Journal<DB>, L1BlockInfo>;
|
||||
Context<BlockEnv, OpTransaction<CustomTxEnv>, CfgEnv<OpSpecId>, DB, Journal<DB>, L1BlockInfo>;
|
||||
|
||||
pub struct CustomEvm<DB: Database, I, P = OpPrecompiles> {
|
||||
inner:
|
||||
@@ -55,10 +55,10 @@ where
|
||||
tx: Self::Tx,
|
||||
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
|
||||
if self.inspect {
|
||||
self.inner.set_tx(tx);
|
||||
self.inner.set_tx(tx.0);
|
||||
self.inner.inspect_replay()
|
||||
} else {
|
||||
self.inner.transact(tx)
|
||||
self.inner.transact(tx.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ where
|
||||
contract: Address,
|
||||
data: Bytes,
|
||||
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
|
||||
let tx = CustomEvmTransaction {
|
||||
let tx = CustomEvmTransaction(OpTransaction {
|
||||
base: CustomTxEnv(TxEnv {
|
||||
caller,
|
||||
kind: TxKind::Call(contract),
|
||||
@@ -97,9 +97,9 @@ where
|
||||
// enveloped tx size.
|
||||
enveloped_tx: Some(Bytes::default()),
|
||||
deposit: Default::default(),
|
||||
};
|
||||
});
|
||||
|
||||
let mut gas_limit = tx.base.0.gas_limit;
|
||||
let mut gas_limit = tx.0.base.0.gas_limit;
|
||||
let mut basefee = 0;
|
||||
let mut disable_nonce_check = true;
|
||||
|
||||
@@ -165,6 +165,16 @@ where
|
||||
|
||||
pub struct CustomEvmFactory;
|
||||
|
||||
impl CustomEvmFactory {
|
||||
fn default_tx() -> CustomEvmTransaction {
|
||||
CustomEvmTransaction(OpTransaction {
|
||||
base: CustomTxEnv::default(),
|
||||
enveloped_tx: Some(vec![0x00].into()),
|
||||
deposit: DepositTransactionParts::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl EvmFactory for CustomEvmFactory {
|
||||
type Evm<DB: Database, I: Inspector<CustomContext<DB>>> = CustomEvm<DB, I, Self::Precompiles>;
|
||||
type Context<DB: Database> = CustomContext<DB>;
|
||||
@@ -182,11 +192,7 @@ impl EvmFactory for CustomEvmFactory {
|
||||
let spec_id = input.cfg_env.spec;
|
||||
CustomEvm {
|
||||
inner: Context::op()
|
||||
.with_tx(CustomEvmTransaction {
|
||||
base: CustomTxEnv::default(),
|
||||
enveloped_tx: Some(vec![0x00].into()),
|
||||
deposit: DepositTransactionParts::default(),
|
||||
})
|
||||
.with_tx(Self::default_tx().0)
|
||||
.with_db(db)
|
||||
.with_block(input.block_env)
|
||||
.with_cfg(input.cfg_env)
|
||||
@@ -207,11 +213,7 @@ impl EvmFactory for CustomEvmFactory {
|
||||
let spec_id = input.cfg_env.spec;
|
||||
CustomEvm {
|
||||
inner: Context::op()
|
||||
.with_tx(CustomEvmTransaction {
|
||||
base: CustomTxEnv::default(),
|
||||
enveloped_tx: Some(vec![0x00].into()),
|
||||
deposit: DepositTransactionParts::default(),
|
||||
})
|
||||
.with_tx(Self::default_tx().0)
|
||||
.with_db(db)
|
||||
.with_block(input.block_env)
|
||||
.with_cfg(input.cfg_env)
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
use crate::primitives::{CustomTransaction, CustomTransactionEnvelope, TxPayment};
|
||||
use alloy_eips::Typed2718;
|
||||
use alloy_evm::{FromRecoveredTx, FromTxWithEncoded};
|
||||
use alloy_eips::{
|
||||
eip2718::{EIP2930_TX_TYPE_ID, LEGACY_TX_TYPE_ID},
|
||||
eip2930::AccessList,
|
||||
Typed2718,
|
||||
};
|
||||
use alloy_evm::{FromRecoveredTx, FromTxWithEncoded, IntoTxEnv};
|
||||
use alloy_primitives::{Address, Bytes, TxKind, B256, U256};
|
||||
use op_revm::OpTransaction;
|
||||
use reth_ethereum::evm::revm::context::TxEnv;
|
||||
use reth_ethereum::evm::{primitives::TransactionEnv, revm::context::TxEnv};
|
||||
|
||||
/// An Optimism extended Ethereum transaction that can be fed to [`Evm`] because it contains
|
||||
/// [`CustomTxEnv`].
|
||||
///
|
||||
/// [`Evm`]: alloy_evm::Evm
|
||||
pub type CustomEvmTransaction = OpTransaction<CustomTxEnv>;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CustomEvmTransaction(pub OpTransaction<CustomTxEnv>);
|
||||
|
||||
/// A transaction environment is a set of information related to an Ethereum transaction that can be
|
||||
/// fed to [`Evm`] for execution.
|
||||
///
|
||||
/// [`Evm`]: alloy_evm::Evm
|
||||
#[derive(Default)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct CustomTxEnv(pub TxEnv);
|
||||
|
||||
impl revm::context::Transaction for CustomTxEnv {
|
||||
impl revm::context::Transaction for CustomEvmTransaction {
|
||||
type AccessListItem<'a>
|
||||
= <TxEnv as revm::context::Transaction>::AccessListItem<'a>
|
||||
where
|
||||
@@ -49,7 +54,7 @@ impl revm::context::Transaction for CustomTxEnv {
|
||||
}
|
||||
|
||||
fn nonce(&self) -> u64 {
|
||||
self.0.nonce()
|
||||
revm::context::Transaction::nonce(&self.0)
|
||||
}
|
||||
|
||||
fn kind(&self) -> TxKind {
|
||||
@@ -89,6 +94,119 @@ impl revm::context::Transaction for CustomTxEnv {
|
||||
}
|
||||
}
|
||||
|
||||
impl revm::context::Transaction for CustomTxEnv {
|
||||
type AccessListItem<'a>
|
||||
= <TxEnv as revm::context::Transaction>::AccessListItem<'a>
|
||||
where
|
||||
Self: 'a;
|
||||
type Authorization<'a>
|
||||
= <TxEnv as revm::context::Transaction>::Authorization<'a>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
fn tx_type(&self) -> u8 {
|
||||
self.0.tx_type()
|
||||
}
|
||||
|
||||
fn caller(&self) -> Address {
|
||||
self.0.caller()
|
||||
}
|
||||
|
||||
fn gas_limit(&self) -> u64 {
|
||||
self.0.gas_limit()
|
||||
}
|
||||
|
||||
fn value(&self) -> U256 {
|
||||
self.0.value()
|
||||
}
|
||||
|
||||
fn input(&self) -> &Bytes {
|
||||
self.0.input()
|
||||
}
|
||||
|
||||
fn nonce(&self) -> u64 {
|
||||
revm::context::Transaction::nonce(&self.0)
|
||||
}
|
||||
|
||||
fn kind(&self) -> TxKind {
|
||||
self.0.kind()
|
||||
}
|
||||
|
||||
fn chain_id(&self) -> Option<u64> {
|
||||
self.0.chain_id()
|
||||
}
|
||||
|
||||
fn gas_price(&self) -> u128 {
|
||||
self.0.gas_price()
|
||||
}
|
||||
|
||||
fn access_list(&self) -> Option<impl Iterator<Item = Self::AccessListItem<'_>>> {
|
||||
self.0.access_list()
|
||||
}
|
||||
|
||||
fn blob_versioned_hashes(&self) -> &[B256] {
|
||||
self.0.blob_versioned_hashes()
|
||||
}
|
||||
|
||||
fn max_fee_per_blob_gas(&self) -> u128 {
|
||||
self.0.max_fee_per_blob_gas()
|
||||
}
|
||||
|
||||
fn authorization_list_len(&self) -> usize {
|
||||
self.0.authorization_list_len()
|
||||
}
|
||||
|
||||
fn authorization_list(&self) -> impl Iterator<Item = Self::Authorization<'_>> {
|
||||
self.0.authorization_list()
|
||||
}
|
||||
|
||||
fn max_priority_fee_per_gas(&self) -> Option<u128> {
|
||||
self.0.max_priority_fee_per_gas()
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionEnv for CustomTxEnv {
|
||||
fn set_gas_limit(&mut self, gas_limit: u64) {
|
||||
self.0.gas_limit = gas_limit;
|
||||
}
|
||||
|
||||
fn nonce(&self) -> u64 {
|
||||
self.0.nonce
|
||||
}
|
||||
|
||||
fn set_nonce(&mut self, nonce: u64) {
|
||||
self.0.nonce = nonce;
|
||||
}
|
||||
|
||||
fn set_access_list(&mut self, access_list: AccessList) {
|
||||
self.0.access_list = access_list;
|
||||
|
||||
if self.0.tx_type == LEGACY_TX_TYPE_ID {
|
||||
// if this was previously marked as legacy tx, this must be upgraded to eip2930 with an
|
||||
// accesslist
|
||||
self.0.tx_type = EIP2930_TX_TYPE_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionEnv for CustomEvmTransaction {
|
||||
fn set_gas_limit(&mut self, gas_limit: u64) {
|
||||
self.0.base.set_gas_limit(gas_limit)
|
||||
}
|
||||
|
||||
fn nonce(&self) -> u64 {
|
||||
self.0.base.nonce()
|
||||
}
|
||||
|
||||
fn set_nonce(&mut self, nonce: u64) {
|
||||
self.0.base.set_nonce(nonce)
|
||||
}
|
||||
|
||||
fn set_access_list(&mut self, access_list: AccessList) {
|
||||
self.0.base.set_access_list(access_list)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRecoveredTx<CustomTransaction> for CustomTxEnv {
|
||||
fn from_recovered_tx(tx: &CustomTransaction, sender: Address) -> Self {
|
||||
CustomTxEnv(match tx {
|
||||
@@ -148,3 +266,41 @@ impl FromTxWithEncoded<CustomTransactionEnvelope> for TxEnv {
|
||||
Self::from_recovered_tx(tx.inner.tx(), sender)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRecoveredTx<CustomTransaction> for CustomEvmTransaction {
|
||||
fn from_recovered_tx(tx: &CustomTransaction, sender: Address) -> Self {
|
||||
Self(match tx {
|
||||
CustomTransaction::BuiltIn(tx) => {
|
||||
let tx = OpTransaction::<TxEnv>::from_recovered_tx(tx, sender);
|
||||
let base = CustomTxEnv(tx.base);
|
||||
|
||||
OpTransaction { base, enveloped_tx: tx.enveloped_tx, deposit: tx.deposit }
|
||||
}
|
||||
CustomTransaction::Other(tx) => {
|
||||
OpTransaction::new(CustomTxEnv(TxEnv::from_recovered_tx(tx, sender)))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FromTxWithEncoded<CustomTransaction> for CustomEvmTransaction {
|
||||
fn from_encoded_tx(tx: &CustomTransaction, sender: Address, encoded: Bytes) -> Self {
|
||||
Self(match tx {
|
||||
CustomTransaction::BuiltIn(tx) => {
|
||||
let tx = OpTransaction::<TxEnv>::from_encoded_tx(tx, sender, encoded);
|
||||
let base = CustomTxEnv(tx.base);
|
||||
|
||||
OpTransaction { base, enveloped_tx: tx.enveloped_tx, deposit: tx.deposit }
|
||||
}
|
||||
CustomTransaction::Other(tx) => {
|
||||
OpTransaction::new(CustomTxEnv(TxEnv::from_encoded_tx(tx, sender, encoded)))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTxEnv<Self> for CustomEvmTransaction {
|
||||
fn into_tx_env(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user