diff --git a/crates/anvil/core/src/eth/transaction/mod.rs b/crates/anvil/core/src/eth/transaction/mod.rs index d45743ebccf81..e1059d7155203 100644 --- a/crates/anvil/core/src/eth/transaction/mod.rs +++ b/crates/anvil/core/src/eth/transaction/mod.rs @@ -12,7 +12,10 @@ use alloy_consensus::{ }, }; -use alloy_eips::eip2718::{Decodable2718, Eip2718Error, Encodable2718}; +use alloy_eips::{ + eip2718::{Decodable2718, Eip2718Error, Encodable2718}, + eip7594::BlobTransactionSidecarVariant, +}; use alloy_network::{AnyReceiptEnvelope, AnyRpcTransaction, AnyTransactionReceipt, AnyTxEnvelope}; use alloy_primitives::{Address, B256, Bloom, Bytes, Signature, TxHash, TxKind, U64, U256}; use alloy_rlp::{Decodable, Encodable, Header}; @@ -590,7 +593,7 @@ pub enum TypedTransaction { /// EIP-1559 transaction EIP1559(Signed), /// EIP-4844 transaction - EIP4844(Signed), + EIP4844(Signed>), /// EIP-7702 transaction EIP7702(Signed), /// op-stack deposit transaction @@ -608,7 +611,11 @@ impl TryFrom for TypedTransaction { TxEnvelope::Legacy(tx) => Ok(Self::Legacy(tx)), TxEnvelope::Eip2930(tx) => Ok(Self::EIP2930(tx)), TxEnvelope::Eip1559(tx) => Ok(Self::EIP1559(tx)), - TxEnvelope::Eip4844(tx) => Ok(Self::EIP4844(tx)), + TxEnvelope::Eip4844(tx) => { + let (variant, sig, hash) = tx.into_parts(); + let blob_variant = variant.into(); + Ok(Self::EIP4844(Signed::new_unchecked(blob_variant, sig, hash))) + } TxEnvelope::Eip7702(tx) => Ok(Self::EIP7702(tx)), }, AnyTxEnvelope::Unknown(mut tx) => { @@ -641,7 +648,30 @@ impl TypedTransaction { Self::Legacy(tx) => Ok(TxEnvelope::Legacy(tx)), Self::EIP2930(tx) => Ok(TxEnvelope::Eip2930(tx)), Self::EIP1559(tx) => Ok(TxEnvelope::Eip1559(tx)), - Self::EIP4844(tx) => Ok(TxEnvelope::Eip4844(tx)), + Self::EIP4844(tx) => { + // Convert BlobTransactionSidecarVariant back to standard TxEip4844Variant + let (variant, sig, hash) = tx.into_parts(); + let standard_variant = match variant { + TxEip4844Variant::TxEip4844(tx) => TxEip4844Variant::TxEip4844(tx), + TxEip4844Variant::TxEip4844WithSidecar(tx_with_sidecar) => { + match tx_with_sidecar.sidecar() { + BlobTransactionSidecarVariant::Eip4844(sidecar) => { + TxEip4844Variant::TxEip4844WithSidecar( + TxEip4844WithSidecar::from_tx_and_sidecar( + tx_with_sidecar.tx().clone(), + sidecar.clone(), + ), + ) + } + BlobTransactionSidecarVariant::Eip7594(_) => { + // For now, convert to Eip4844 variant without sidecar + TxEip4844Variant::TxEip4844(tx_with_sidecar.tx().clone()) + } + } + } + }; + Ok(TxEnvelope::Eip4844(Signed::new_unchecked(standard_variant, sig, hash))) + } Self::EIP7702(tx) => Ok(TxEnvelope::Eip7702(tx)), Self::Deposit(_) => Err(self), } @@ -734,7 +764,7 @@ impl TypedTransaction { } } - pub fn sidecar(&self) -> Option<&TxEip4844WithSidecar> { + pub fn sidecar(&self) -> Option<&TxEip4844WithSidecar> { match self { Self::EIP4844(signed_variant) => match signed_variant.tx() { TxEip4844Variant::TxEip4844WithSidecar(with_sidecar) => Some(with_sidecar), @@ -1009,7 +1039,30 @@ impl Encodable2718 for TypedTransaction { Self::Legacy(tx) => TxEnvelope::from(tx.clone()).encode_2718_len(), Self::EIP2930(tx) => TxEnvelope::from(tx.clone()).encode_2718_len(), Self::EIP1559(tx) => TxEnvelope::from(tx.clone()).encode_2718_len(), - Self::EIP4844(tx) => TxEnvelope::from(tx.clone()).encode_2718_len(), + Self::EIP4844(tx) => { + // Convert BlobTransactionSidecarVariant back to standard TxEip4844Variant + let (variant, sig, hash) = tx.clone().into_parts(); + let standard_variant = match variant { + TxEip4844Variant::TxEip4844(tx) => TxEip4844Variant::TxEip4844(tx), + TxEip4844Variant::TxEip4844WithSidecar(tx_with_sidecar) => { + match tx_with_sidecar.sidecar() { + BlobTransactionSidecarVariant::Eip4844(sidecar) => { + TxEip4844Variant::TxEip4844WithSidecar( + TxEip4844WithSidecar::from_tx_and_sidecar( + tx_with_sidecar.tx().clone(), + sidecar.clone(), + ), + ) + } + BlobTransactionSidecarVariant::Eip7594(_) => { + TxEip4844Variant::TxEip4844(tx_with_sidecar.tx().clone()) + } + } + } + }; + TxEnvelope::from(Signed::new_unchecked(standard_variant, sig, hash)) + .encode_2718_len() + } Self::EIP7702(tx) => TxEnvelope::from(tx.clone()).encode_2718_len(), Self::Deposit(tx) => 1 + tx.length(), } @@ -1020,7 +1073,30 @@ impl Encodable2718 for TypedTransaction { Self::Legacy(tx) => TxEnvelope::from(tx.clone()).encode_2718(out), Self::EIP2930(tx) => TxEnvelope::from(tx.clone()).encode_2718(out), Self::EIP1559(tx) => TxEnvelope::from(tx.clone()).encode_2718(out), - Self::EIP4844(tx) => TxEnvelope::from(tx.clone()).encode_2718(out), + Self::EIP4844(tx) => { + // Convert BlobTransactionSidecarVariant back to standard TxEip4844Variant + let (variant, sig, hash) = tx.clone().into_parts(); + let standard_variant = match variant { + TxEip4844Variant::TxEip4844(tx) => TxEip4844Variant::TxEip4844(tx), + TxEip4844Variant::TxEip4844WithSidecar(tx_with_sidecar) => { + match tx_with_sidecar.sidecar() { + BlobTransactionSidecarVariant::Eip4844(sidecar) => { + TxEip4844Variant::TxEip4844WithSidecar( + TxEip4844WithSidecar::from_tx_and_sidecar( + tx_with_sidecar.tx().clone(), + sidecar.clone(), + ), + ) + } + BlobTransactionSidecarVariant::Eip7594(_) => { + TxEip4844Variant::TxEip4844(tx_with_sidecar.tx().clone()) + } + } + } + }; + TxEnvelope::from(Signed::new_unchecked(standard_variant, sig, hash)) + .encode_2718(out) + } Self::EIP7702(tx) => TxEnvelope::from(tx.clone()).encode_2718(out), Self::Deposit(tx) => { tx.encode_2718(out); @@ -1037,7 +1113,11 @@ impl Decodable2718 for TypedTransaction { match TxEnvelope::typed_decode(ty, buf)? { TxEnvelope::Eip2930(tx) => Ok(Self::EIP2930(tx)), TxEnvelope::Eip1559(tx) => Ok(Self::EIP1559(tx)), - TxEnvelope::Eip4844(tx) => Ok(Self::EIP4844(tx)), + TxEnvelope::Eip4844(tx) => { + let (variant, sig, hash) = tx.into_parts(); + let blob_variant = variant.into(); + Ok(Self::EIP4844(Signed::new_unchecked(blob_variant, sig, hash))) + } TxEnvelope::Eip7702(tx) => Ok(Self::EIP7702(tx)), _ => Err(Eip2718Error::RlpError(alloy_rlp::Error::Custom("unexpected tx type"))), } @@ -1057,7 +1137,11 @@ impl From for TypedTransaction { TxEnvelope::Legacy(tx) => Self::Legacy(tx), TxEnvelope::Eip2930(tx) => Self::EIP2930(tx), TxEnvelope::Eip1559(tx) => Self::EIP1559(tx), - TxEnvelope::Eip4844(tx) => Self::EIP4844(tx), + TxEnvelope::Eip4844(tx) => { + let (variant, sig, hash) = tx.into_parts(); + let blob_variant = variant.into(); + Self::EIP4844(Signed::new_unchecked(blob_variant, sig, hash)) + } TxEnvelope::Eip7702(tx) => Self::EIP7702(tx), } } diff --git a/crates/anvil/src/eth/backend/mem/mod.rs b/crates/anvil/src/eth/backend/mem/mod.rs index 27aa3dbeaeb57..a4557ceedfe93 100644 --- a/crates/anvil/src/eth/backend/mem/mod.rs +++ b/crates/anvil/src/eth/backend/mem/mod.rs @@ -45,6 +45,7 @@ use alloy_eips::{ Encodable2718, eip1559::BaseFeeParams, eip4844::{BlobTransactionSidecar, kzg_to_versioned_hash}, + eip7594::BlobTransactionSidecarVariant, eip7840::BlobParams, eip7910::SystemContract, }; @@ -3340,7 +3341,7 @@ impl Backend { && let Ok(typed_tx) = TypedTransaction::try_from(tx) && let Some(sidecar) = typed_tx.sidecar() { - return Ok(Some(sidecar.sidecar.blobs.clone())); + return Ok(Some(sidecar.sidecar().blobs().to_vec())); } Ok(None) @@ -3357,7 +3358,7 @@ impl Backend { .iter() .filter_map(|tx| tx.as_ref().sidecar()) .flat_map(|sidecar| { - sidecar.sidecar.blobs.iter().zip(sidecar.sidecar.commitments.iter()) + sidecar.sidecar().blobs().iter().zip(sidecar.sidecar().commitments().iter()) }) .filter(|(_, commitment)| { // Filter blobs by versioned_hashes if provided @@ -3381,9 +3382,14 @@ impl Backend { typed_tx_result.ok()?.sidecar().map(|sidecar| sidecar.sidecar().clone()) }) .fold(BlobTransactionSidecar::default(), |mut acc, sidecar| { - acc.blobs.extend(sidecar.blobs); - acc.commitments.extend(sidecar.commitments); - acc.proofs.extend(sidecar.proofs); + acc.blobs.extend(sidecar.blobs()); + acc.commitments.extend(sidecar.commitments()); + match &sidecar { + BlobTransactionSidecarVariant::Eip4844(eip4844_sidecar) => { + acc.proofs.extend(eip4844_sidecar.proofs.clone()); + } + BlobTransactionSidecarVariant::Eip7594(_) => {} + } acc }); Ok(Some(sidecar)) @@ -3401,10 +3407,10 @@ impl Backend { for versioned_hash in sidecar.sidecar.versioned_hashes() { if versioned_hash == hash && let Some(index) = - sidecar.sidecar.commitments.iter().position(|commitment| { + sidecar.sidecar().commitments().iter().position(|commitment| { kzg_to_versioned_hash(commitment.as_slice()) == *hash }) - && let Some(blob) = sidecar.sidecar.blobs.get(index) + && let Some(blob) = sidecar.sidecar().blobs().get(index) { return Ok(Some(*blob)); } diff --git a/crates/anvil/src/eth/sign.rs b/crates/anvil/src/eth/sign.rs index 57f273953c620..760d810067c70 100644 --- a/crates/anvil/src/eth/sign.rs +++ b/crates/anvil/src/eth/sign.rs @@ -1,5 +1,5 @@ use crate::eth::error::BlockchainError; -use alloy_consensus::SignableTransaction; +use alloy_consensus::{SignableTransaction, Signed}; use alloy_dyn_abi::TypedData; use alloy_network::TxSignerSync; use alloy_primitives::{Address, B256, Signature, map::AddressHashMap}; @@ -131,7 +131,11 @@ pub fn build_typed_transaction( TypedTransaction::EIP7702(tx.into_signed(signature)) } TypedTransactionRequest::EIP4844(tx) => { - TypedTransaction::EIP4844(tx.into_signed(signature)) + let signed = tx.into_signed(signature); + // Convert from standard TxEip4844Variant to BlobTransactionSidecarVariant + let (variant, sig, hash) = signed.into_parts(); + let blob_variant = variant.into(); + TypedTransaction::EIP4844(Signed::new_unchecked(blob_variant, sig, hash)) } TypedTransactionRequest::Deposit(tx) => TypedTransaction::Deposit(tx), };