diff --git a/crates/context/src/tx.rs b/crates/context/src/tx.rs index e0acec0970..687eea2169 100644 --- a/crates/context/src/tx.rs +++ b/crates/context/src/tx.rs @@ -1,3 +1,4 @@ +use crate::TransactionType; use context_interface::transaction::{AccessList, SignedAuthorization, Transaction}; use core::fmt::Debug; use primitives::{Address, Bytes, TxKind, B256, U256}; @@ -95,6 +96,48 @@ impl Default for TxEnv { } } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum DeriveTxTypeError { + MissingTargetForEip4844, + MissingTargetForEip7702, +} + +impl TxEnv { + /// Derives tx type from transaction fields and sets it to `tx_type`. + /// Returns error in case some fields were not set correctly. + pub fn derive_tx_type(&mut self) -> Result<(), DeriveTxTypeError> { + let mut tx_type = TransactionType::Legacy; + + if !self.access_list.0.is_empty() { + tx_type = TransactionType::Eip2930; + } + + if self.gas_priority_fee.is_some() { + tx_type = TransactionType::Eip1559; + } + + if !self.blob_hashes.is_empty() { + if let TxKind::Call(_) = self.kind { + tx_type = TransactionType::Eip4844; + } else { + return Err(DeriveTxTypeError::MissingTargetForEip4844); + } + } + + if !self.authorization_list.is_empty() { + if let TxKind::Call(_) = self.kind { + tx_type = TransactionType::Eip7702; + } else { + return Err(DeriveTxTypeError::MissingTargetForEip7702); + } + } + + self.tx_type = tx_type as u8; + Ok(()) + } +} + impl Transaction for TxEnv { type AccessList = AccessList; type Authorization = SignedAuthorization;