diff --git a/Cargo.lock b/Cargo.lock index 57ebbdfe65a7..cf109a11dc36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9926,7 +9926,7 @@ dependencies = [ [[package]] name = "revm" version = "19.4.0" -source = "git+https://github.com/scroll-tech/revm.git?branch=scroll-evm-executor/reth/v55#8e3fd7b8640a776bd28cc421f33b1f38949490d6" +source = "git+https://github.com/scroll-tech/revm.git?branch=scroll-evm-executor/feat/v55/euclid-v2#2841ff8bb31c6a7d4da06de469ae234e36f10148" dependencies = [ "auto_impl", "cfg-if", @@ -9961,9 +9961,8 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "15.1.0" -source = "git+https://github.com/scroll-tech/revm.git?branch=scroll-evm-executor/reth/v55#8e3fd7b8640a776bd28cc421f33b1f38949490d6" +source = "git+https://github.com/scroll-tech/revm.git?branch=scroll-evm-executor/feat/v55/euclid-v2#2841ff8bb31c6a7d4da06de469ae234e36f10148" dependencies = [ - "cfg-if", "revm-primitives", "serde", ] @@ -9971,7 +9970,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "16.0.0" -source = "git+https://github.com/scroll-tech/revm.git?branch=scroll-evm-executor/reth/v55#8e3fd7b8640a776bd28cc421f33b1f38949490d6" +source = "git+https://github.com/scroll-tech/revm.git?branch=scroll-evm-executor/feat/v55/euclid-v2#2841ff8bb31c6a7d4da06de469ae234e36f10148" dependencies = [ "aurora-engine-modexp", "blst", @@ -9990,7 +9989,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "15.1.0" -source = "git+https://github.com/scroll-tech/revm.git?branch=scroll-evm-executor/reth/v55#8e3fd7b8640a776bd28cc421f33b1f38949490d6" +source = "git+https://github.com/scroll-tech/revm.git?branch=scroll-evm-executor/feat/v55/euclid-v2#2841ff8bb31c6a7d4da06de469ae234e36f10148" dependencies = [ "alloy-eip2930", "alloy-eip7702", diff --git a/Cargo.toml b/Cargo.toml index 56e94bc851a6..5ea4dd3c0de6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -678,10 +678,10 @@ crunchy = "=0.2.2" # # revm-inspectors = { git = "https://github.com/paradigmxyz/revm-inspectors", rev = "1207e33" } -[patch.crates-io] -revm = { git = "https://github.com/scroll-tech/revm.git", branch = "scroll-evm-executor/reth/v55" } -revm-primitives = { git = "https://github.com/scroll-tech/revm.git", branch = "scroll-evm-executor/reth/v55" } -revm-interpreter = { git = "https://github.com/scroll-tech/revm.git", branch = "scroll-evm-executor/reth/v55" } +[patch.crates-io] # FIXME: replace by v55 when it's merged +revm = { git = "https://github.com/scroll-tech/revm.git", branch = "scroll-evm-executor/feat/v55/euclid-v2" } +revm-primitives = { git = "https://github.com/scroll-tech/revm.git", branch = "scroll-evm-executor/feat/v55/euclid-v2" } +revm-interpreter = { git = "https://github.com/scroll-tech/revm.git", branch = "scroll-evm-executor/feat/v55/euclid-v2" } ff = { git = "https://github.com/scroll-tech/ff", branch = "feat/sp1" } diff --git a/crates/primitives-traits/src/size.rs b/crates/primitives-traits/src/size.rs index 8413a45a6d45..5d924011fa47 100644 --- a/crates/primitives-traits/src/size.rs +++ b/crates/primitives-traits/src/size.rs @@ -161,6 +161,7 @@ mod scroll { Self::Legacy(tx) => tx.size(), Self::Eip2930(tx) => tx.size(), Self::Eip1559(tx) => tx.size(), + Self::Eip7702(tx) => tx.size(), Self::L1Message(tx) => tx.size(), } } @@ -172,6 +173,7 @@ mod scroll { Self::Legacy(tx) => tx.size(), Self::Eip2930(tx) => tx.size(), Self::Eip1559(tx) => tx.size(), + Self::Eip7702(tx) => tx.size(), } } } diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 496e6963819c..a7bed22b2f0f 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -191,6 +191,7 @@ impl SignedTransaction for scroll_alloy_consensus::ScrollPooledTransaction { Self::Legacy(tx) => tx.hash(), Self::Eip2930(tx) => tx.hash(), Self::Eip1559(tx) => tx.hash(), + Self::Eip7702(tx) => tx.hash(), } } @@ -199,6 +200,7 @@ impl SignedTransaction for scroll_alloy_consensus::ScrollPooledTransaction { Self::Legacy(tx) => tx.signature(), Self::Eip2930(tx) => tx.signature(), Self::Eip1559(tx) => tx.signature(), + Self::Eip7702(tx) => tx.signature(), } } @@ -215,6 +217,7 @@ impl SignedTransaction for scroll_alloy_consensus::ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().encode_for_signing(buf), Self::Eip2930(tx) => tx.tx().encode_for_signing(buf), Self::Eip1559(tx) => tx.tx().encode_for_signing(buf), + Self::Eip7702(tx) => tx.tx().encode_for_signing(buf), } let signature_hash = keccak256(buf); recover_signer_unchecked(self.signature(), signature_hash) diff --git a/crates/scroll/alloy/consensus/src/receipt/envelope.rs b/crates/scroll/alloy/consensus/src/receipt/envelope.rs index 18fb884b129c..84d86f32644f 100644 --- a/crates/scroll/alloy/consensus/src/receipt/envelope.rs +++ b/crates/scroll/alloy/consensus/src/receipt/envelope.rs @@ -37,6 +37,11 @@ pub enum ScrollReceiptEnvelope { /// [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559 #[cfg_attr(feature = "serde", serde(rename = "0x2", alias = "0x02"))] Eip1559(ReceiptWithBloom>), + /// Receipt envelope with type flag 4, containing a [EIP-7702] receipt. + /// + /// [EIP-7702]: https://eips.ethereum.org/EIPS/eip-7702 + #[cfg_attr(feature = "serde", serde(rename = "0x4", alias = "0x04"))] + Eip7702(ReceiptWithBloom>), /// Receipt envelope with type flag 126, containing a [Scroll-L1-Message] receipt. #[cfg_attr(feature = "serde", serde(rename = "0x7e", alias = "0x7E"))] L1Message(ReceiptWithBloom>), @@ -64,6 +69,9 @@ impl ScrollReceiptEnvelope { ScrollTxType::Eip1559 => { Self::Eip1559(ReceiptWithBloom { receipt: inner_receipt, logs_bloom }) } + ScrollTxType::Eip7702 => { + Self::Eip7702(ReceiptWithBloom { receipt: inner_receipt, logs_bloom }) + } ScrollTxType::L1Message => { Self::L1Message(ReceiptWithBloom { receipt: inner_receipt, logs_bloom }) } @@ -78,6 +86,7 @@ impl ScrollReceiptEnvelope { Self::Legacy(_) => ScrollTxType::Legacy, Self::Eip2930(_) => ScrollTxType::Eip2930, Self::Eip1559(_) => ScrollTxType::Eip1559, + Self::Eip7702(_) => ScrollTxType::Eip7702, Self::L1Message(_) => ScrollTxType::L1Message, } } @@ -105,9 +114,11 @@ impl ScrollReceiptEnvelope { /// Return the receipt's bloom. pub const fn logs_bloom(&self) -> &Bloom { match self { - Self::Legacy(t) | Self::Eip2930(t) | Self::Eip1559(t) | Self::L1Message(t) => { - &t.logs_bloom - } + Self::Legacy(t) | + Self::Eip2930(t) | + Self::Eip1559(t) | + Self::Eip7702(t) | + Self::L1Message(t) => &t.logs_bloom, } } @@ -131,9 +142,11 @@ impl ScrollReceiptEnvelope { /// receipt types may be added. pub const fn as_receipt(&self) -> Option<&Receipt> { match self { - Self::Legacy(t) | Self::Eip2930(t) | Self::Eip1559(t) | Self::L1Message(t) => { - Some(&t.receipt) - } + Self::Legacy(t) | + Self::Eip2930(t) | + Self::Eip1559(t) | + Self::Eip7702(t) | + Self::L1Message(t) => Some(&t.receipt), } } } @@ -142,9 +155,11 @@ impl ScrollReceiptEnvelope { /// Get the length of the inner receipt in the 2718 encoding. pub fn inner_length(&self) -> usize { match self { - Self::Legacy(t) | Self::Eip2930(t) | Self::Eip1559(t) | Self::L1Message(t) => { - t.length() - } + Self::Legacy(t) | + Self::Eip2930(t) | + Self::Eip1559(t) | + Self::Eip7702(t) | + Self::L1Message(t) => t.length(), } } @@ -219,6 +234,7 @@ impl Encodable2718 for ScrollReceiptEnvelope { Self::Legacy(_) => None, Self::Eip2930(_) => Some(ScrollTxType::Eip2930 as u8), Self::Eip1559(_) => Some(ScrollTxType::Eip1559 as u8), + Self::Eip7702(_) => Some(ScrollTxType::Eip7702 as u8), Self::L1Message(_) => Some(ScrollTxType::L1Message as u8), } } @@ -233,9 +249,11 @@ impl Encodable2718 for ScrollReceiptEnvelope { Some(ty) => out.put_u8(ty), } match self { - Self::L1Message(t) | Self::Legacy(t) | Self::Eip2930(t) | Self::Eip1559(t) => { - t.encode(out) - } + Self::L1Message(t) | + Self::Legacy(t) | + Self::Eip2930(t) | + Self::Eip1559(t) | + Self::Eip7702(t) => t.encode(out), } } } @@ -246,6 +264,7 @@ impl Typed2718 for ScrollReceiptEnvelope { Self::Legacy(_) => ScrollTxType::Legacy, Self::Eip2930(_) => ScrollTxType::Eip2930, Self::Eip1559(_) => ScrollTxType::Eip1559, + Self::Eip7702(_) => ScrollTxType::Eip7702, Self::L1Message(_) => ScrollTxType::L1Message, }; ty as u8 @@ -261,6 +280,7 @@ impl Decodable2718 for ScrollReceiptEnvelope { } ScrollTxType::Eip1559 => Ok(Self::Eip1559(Decodable::decode(buf)?)), ScrollTxType::Eip2930 => Ok(Self::Eip2930(Decodable::decode(buf)?)), + ScrollTxType::Eip7702 => Ok(Self::Eip7702(Decodable::decode(buf)?)), ScrollTxType::L1Message => Ok(Self::L1Message(Decodable::decode(buf)?)), } } @@ -280,6 +300,7 @@ where 0 => Ok(Self::Legacy(ReceiptWithBloom::arbitrary(u)?)), 1 => Ok(Self::Eip2930(ReceiptWithBloom::arbitrary(u)?)), 2 => Ok(Self::Eip1559(ReceiptWithBloom::arbitrary(u)?)), + 4 => Ok(Self::Eip1559(ReceiptWithBloom::arbitrary(u)?)), _ => Ok(Self::L1Message(ReceiptWithBloom::arbitrary(u)?)), } } diff --git a/crates/scroll/alloy/consensus/src/transaction/envelope.rs b/crates/scroll/alloy/consensus/src/transaction/envelope.rs index 9c5f88f779b3..1deff3af1f8f 100644 --- a/crates/scroll/alloy/consensus/src/transaction/envelope.rs +++ b/crates/scroll/alloy/consensus/src/transaction/envelope.rs @@ -1,6 +1,6 @@ use alloy_consensus::{ - transaction::RlpEcdsaTx, Sealable, Sealed, Signed, Transaction, TxEip1559, TxEip2930, TxLegacy, - Typed2718, + transaction::RlpEcdsaTx, Sealable, Sealed, Signed, Transaction, TxEip1559, TxEip2930, + TxEip7702, TxLegacy, Typed2718, }; use alloy_eips::{ eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, @@ -38,6 +38,8 @@ pub enum ScrollTxEnvelope { Eip2930(Signed), /// A [`TxEip1559`] tagged with type 2. Eip1559(Signed), + /// EIP-7702 transaction + Eip7702(Signed), /// A [`TxL1Message`] tagged with type 0x7E. L1Message(Sealed), } @@ -60,6 +62,12 @@ impl From> for ScrollTxEnvelope { } } +impl From> for ScrollTxEnvelope { + fn from(v: Signed) -> Self { + Self::Eip7702(v) + } +} + impl From for ScrollTxEnvelope { fn from(v: TxL1Message) -> Self { v.seal_slow().into() @@ -78,6 +86,7 @@ impl Typed2718 for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().ty(), Self::Eip2930(tx) => tx.tx().ty(), Self::Eip1559(tx) => tx.tx().ty(), + Self::Eip7702(tx) => tx.tx().ty(), Self::L1Message(tx) => tx.ty(), } } @@ -89,6 +98,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().chain_id(), Self::Eip2930(tx) => tx.tx().chain_id(), Self::Eip1559(tx) => tx.tx().chain_id(), + Self::Eip7702(tx) => tx.tx().chain_id(), Self::L1Message(tx) => tx.chain_id(), } } @@ -98,6 +108,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().nonce(), Self::Eip2930(tx) => tx.tx().nonce(), Self::Eip1559(tx) => tx.tx().nonce(), + Self::Eip7702(tx) => tx.tx().nonce(), Self::L1Message(tx) => tx.nonce(), } } @@ -107,6 +118,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().gas_limit(), Self::Eip2930(tx) => tx.tx().gas_limit(), Self::Eip1559(tx) => tx.tx().gas_limit(), + Self::Eip7702(tx) => tx.tx().gas_limit(), Self::L1Message(tx) => tx.gas_limit(), } } @@ -116,6 +128,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().gas_price(), Self::Eip2930(tx) => tx.tx().gas_price(), Self::Eip1559(tx) => tx.tx().gas_price(), + Self::Eip7702(tx) => tx.tx().gas_price(), Self::L1Message(tx) => tx.gas_price(), } } @@ -125,6 +138,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().max_fee_per_gas(), Self::Eip2930(tx) => tx.tx().max_fee_per_gas(), Self::Eip1559(tx) => tx.tx().max_fee_per_gas(), + Self::Eip7702(tx) => tx.tx().max_fee_per_gas(), Self::L1Message(tx) => tx.max_fee_per_gas(), } } @@ -134,6 +148,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().max_priority_fee_per_gas(), Self::Eip2930(tx) => tx.tx().max_priority_fee_per_gas(), Self::Eip1559(tx) => tx.tx().max_priority_fee_per_gas(), + Self::Eip7702(tx) => tx.tx().max_priority_fee_per_gas(), Self::L1Message(tx) => tx.max_priority_fee_per_gas(), } } @@ -143,6 +158,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().max_fee_per_blob_gas(), Self::Eip2930(tx) => tx.tx().max_fee_per_blob_gas(), Self::Eip1559(tx) => tx.tx().max_fee_per_blob_gas(), + Self::Eip7702(tx) => tx.tx().max_fee_per_blob_gas(), Self::L1Message(tx) => tx.max_fee_per_blob_gas(), } } @@ -152,6 +168,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().priority_fee_or_price(), Self::Eip2930(tx) => tx.tx().priority_fee_or_price(), Self::Eip1559(tx) => tx.tx().priority_fee_or_price(), + Self::Eip7702(tx) => tx.tx().priority_fee_or_price(), Self::L1Message(tx) => tx.priority_fee_or_price(), } } @@ -161,6 +178,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().to(), Self::Eip2930(tx) => tx.tx().to(), Self::Eip1559(tx) => tx.tx().to(), + Self::Eip7702(tx) => tx.tx().to(), Self::L1Message(tx) => tx.to(), } } @@ -170,6 +188,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().kind(), Self::Eip2930(tx) => tx.tx().kind(), Self::Eip1559(tx) => tx.tx().kind(), + Self::Eip7702(tx) => tx.tx().kind(), Self::L1Message(tx) => tx.kind(), } } @@ -179,6 +198,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().value(), Self::Eip2930(tx) => tx.tx().value(), Self::Eip1559(tx) => tx.tx().value(), + Self::Eip7702(tx) => tx.tx().value(), Self::L1Message(tx) => tx.value(), } } @@ -188,6 +208,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().input(), Self::Eip2930(tx) => tx.tx().input(), Self::Eip1559(tx) => tx.tx().input(), + Self::Eip7702(tx) => tx.tx().input(), Self::L1Message(tx) => tx.input(), } } @@ -197,6 +218,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().access_list(), Self::Eip2930(tx) => tx.tx().access_list(), Self::Eip1559(tx) => tx.tx().access_list(), + Self::Eip7702(tx) => tx.tx().access_list(), Self::L1Message(tx) => tx.access_list(), } } @@ -206,6 +228,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().blob_versioned_hashes(), Self::Eip2930(tx) => tx.tx().blob_versioned_hashes(), Self::Eip1559(tx) => tx.tx().blob_versioned_hashes(), + Self::Eip7702(tx) => tx.tx().blob_versioned_hashes(), Self::L1Message(tx) => tx.blob_versioned_hashes(), } } @@ -215,6 +238,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().authorization_list(), Self::Eip2930(tx) => tx.tx().authorization_list(), Self::Eip1559(tx) => tx.tx().authorization_list(), + Self::Eip7702(tx) => tx.tx().authorization_list(), Self::L1Message(tx) => tx.authorization_list(), } } @@ -224,6 +248,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().is_dynamic_fee(), Self::Eip2930(tx) => tx.tx().is_dynamic_fee(), Self::Eip1559(tx) => tx.tx().is_dynamic_fee(), + Self::Eip7702(tx) => tx.tx().is_dynamic_fee(), Self::L1Message(tx) => tx.is_dynamic_fee(), } } @@ -233,6 +258,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().effective_gas_price(base_fee), Self::Eip2930(tx) => tx.tx().effective_gas_price(base_fee), Self::Eip1559(tx) => tx.tx().effective_gas_price(base_fee), + Self::Eip7702(tx) => tx.tx().effective_gas_price(base_fee), Self::L1Message(tx) => tx.effective_gas_price(base_fee), } } @@ -242,6 +268,7 @@ impl Transaction for ScrollTxEnvelope { Self::Legacy(tx) => tx.tx().is_create(), Self::Eip2930(tx) => tx.tx().is_create(), Self::Eip1559(tx) => tx.tx().is_create(), + Self::Eip7702(tx) => tx.tx().is_create(), Self::L1Message(tx) => tx.is_create(), } } @@ -266,6 +293,12 @@ impl ScrollTxEnvelope { matches!(self, Self::Eip1559(_)) } + /// Returns true if the transaction is an EIP-7702 transaction. + #[inline] + pub const fn is_eip7702(&self) -> bool { + matches!(self, Self::Eip7702(_)) + } + /// Returns true if the transaction is a deposit transaction. #[inline] pub const fn is_l1_message(&self) -> bool { @@ -296,6 +329,14 @@ impl ScrollTxEnvelope { } } + /// Returns the [`TxEip7702`] variant if the transaction is an EIP-1559 transaction. + pub const fn as_eip7702(&self) -> Option<&Signed> { + match self { + Self::Eip7702(tx) => Some(tx), + _ => None, + } + } + /// Returns the [`TxL1Message`] variant if the transaction is a deposit transaction. pub const fn as_l1_message(&self) -> Option<&Sealed> { match self { @@ -310,6 +351,7 @@ impl ScrollTxEnvelope { Self::Legacy(_) => ScrollTxType::Legacy, Self::Eip2930(_) => ScrollTxType::Eip2930, Self::Eip1559(_) => ScrollTxType::Eip1559, + Self::Eip7702(_) => ScrollTxType::Eip7702, Self::L1Message(_) => ScrollTxType::L1Message, } } @@ -320,6 +362,7 @@ impl ScrollTxEnvelope { Self::Legacy(t) => t.eip2718_encoded_length(), Self::Eip2930(t) => t.eip2718_encoded_length(), Self::Eip1559(t) => t.eip2718_encoded_length(), + Self::Eip7702(t) => t.eip2718_encoded_length(), Self::L1Message(t) => t.eip2718_encoded_length(), } } @@ -346,6 +389,7 @@ impl Decodable2718 for ScrollTxEnvelope { match ty.try_into().map_err(|_| Eip2718Error::UnexpectedType(ty))? { ScrollTxType::Eip2930 => Ok(Self::Eip2930(TxEip2930::rlp_decode_signed(buf)?)), ScrollTxType::Eip1559 => Ok(Self::Eip1559(TxEip1559::rlp_decode_signed(buf)?)), + ScrollTxType::Eip7702 => Ok(Self::Eip7702(TxEip7702::rlp_decode_signed(buf)?)), ScrollTxType::L1Message => Ok(Self::L1Message(TxL1Message::decode(buf)?.seal_slow())), ScrollTxType::Legacy => { Err(alloy_rlp::Error::Custom("type-0 eip2718 transactions are not supported") @@ -365,6 +409,7 @@ impl Encodable2718 for ScrollTxEnvelope { Self::Legacy(_) => None, Self::Eip2930(_) => Some(ScrollTxType::Eip2930 as u8), Self::Eip1559(_) => Some(ScrollTxType::Eip1559 as u8), + Self::Eip7702(_) => Some(ScrollTxType::Eip7702 as u8), Self::L1Message(_) => Some(ScrollTxType::L1Message as u8), } } @@ -383,6 +428,9 @@ impl Encodable2718 for ScrollTxEnvelope { Self::Eip1559(tx) => { tx.eip2718_encode(out); } + Self::Eip7702(tx) => { + tx.eip2718_encode(out); + } Self::L1Message(tx) => { tx.eip2718_encode(out); } @@ -394,6 +442,7 @@ impl Encodable2718 for ScrollTxEnvelope { Self::Legacy(tx) => *tx.hash(), Self::Eip1559(tx) => *tx.hash(), Self::Eip2930(tx) => *tx.hash(), + Self::Eip7702(tx) => *tx.hash(), Self::L1Message(tx) => tx.seal(), } } @@ -433,6 +482,8 @@ mod serde_from { Eip2930(Signed), #[serde(rename = "0x2", alias = "0x02")] Eip1559(Signed), + #[serde(rename = "0x4", alias = "0x04")] + Eip7702(Signed), #[serde( rename = "0x7e", alias = "0x7E", @@ -456,6 +507,7 @@ mod serde_from { TaggedTxEnvelope::Legacy(signed) => Self::Legacy(signed), TaggedTxEnvelope::Eip2930(signed) => Self::Eip2930(signed), TaggedTxEnvelope::Eip1559(signed) => Self::Eip1559(signed), + TaggedTxEnvelope::Eip7702(signed) => Self::Eip7702(signed), TaggedTxEnvelope::L1Message(tx) => Self::L1Message(tx), } } @@ -467,6 +519,7 @@ mod serde_from { ScrollTxEnvelope::Legacy(signed) => Self::Legacy(signed), ScrollTxEnvelope::Eip2930(signed) => Self::Eip2930(signed), ScrollTxEnvelope::Eip1559(signed) => Self::Eip1559(signed), + ScrollTxEnvelope::Eip7702(signed) => Self::Eip7702(signed), ScrollTxEnvelope::L1Message(tx) => Self::L1Message(tx), } } diff --git a/crates/scroll/alloy/consensus/src/transaction/pooled.rs b/crates/scroll/alloy/consensus/src/transaction/pooled.rs index ec370896753a..fbc397a27f2e 100644 --- a/crates/scroll/alloy/consensus/src/transaction/pooled.rs +++ b/crates/scroll/alloy/consensus/src/transaction/pooled.rs @@ -4,7 +4,7 @@ use crate::{ScrollTxEnvelope, ScrollTxType}; use alloy_consensus::{ transaction::{RlpEcdsaTx, TxEip1559, TxEip2930, TxLegacy}, - SignableTransaction, Signed, Transaction, TxEnvelope, Typed2718, + SignableTransaction, Signed, Transaction, TxEip7702, TxEnvelope, Typed2718, }; use alloy_eips::{ eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, @@ -33,6 +33,8 @@ pub enum ScrollPooledTransaction { Eip2930(Signed), /// A [`TxEip1559`] transaction tagged with type 2. Eip1559(Signed), + /// A [`TxEip7702`] transaction tagged with type 4. + Eip7702(Signed), } impl ScrollPooledTransaction { @@ -43,6 +45,7 @@ impl ScrollPooledTransaction { Self::Legacy(tx) => tx.signature_hash(), Self::Eip2930(tx) => tx.signature_hash(), Self::Eip1559(tx) => tx.signature_hash(), + Self::Eip7702(tx) => tx.signature_hash(), } } @@ -52,6 +55,7 @@ impl ScrollPooledTransaction { Self::Legacy(tx) => tx.hash(), Self::Eip2930(tx) => tx.hash(), Self::Eip1559(tx) => tx.hash(), + Self::Eip7702(tx) => tx.hash(), } } @@ -61,6 +65,7 @@ impl ScrollPooledTransaction { Self::Legacy(tx) => tx.signature(), Self::Eip2930(tx) => tx.signature(), Self::Eip1559(tx) => tx.signature(), + Self::Eip7702(tx) => tx.signature(), } } @@ -84,6 +89,7 @@ impl ScrollPooledTransaction { Self::Legacy(tx) => tx.recover_signer(), Self::Eip2930(tx) => tx.recover_signer(), Self::Eip1559(tx) => tx.recover_signer(), + Self::Eip7702(tx) => tx.recover_signer(), } } @@ -94,6 +100,7 @@ impl ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().encode_for_signing(out), Self::Eip2930(tx) => tx.tx().encode_for_signing(out), Self::Eip1559(tx) => tx.tx().encode_for_signing(out), + Self::Eip7702(tx) => tx.tx().encode_for_signing(out), } } @@ -103,6 +110,7 @@ impl ScrollPooledTransaction { Self::Legacy(tx) => tx.into(), Self::Eip2930(tx) => tx.into(), Self::Eip1559(tx) => tx.into(), + Self::Eip7702(tx) => tx.into(), } } @@ -112,6 +120,7 @@ impl ScrollPooledTransaction { Self::Legacy(tx) => tx.into(), Self::Eip2930(tx) => tx.into(), Self::Eip1559(tx) => tx.into(), + Self::Eip7702(tx) => tx.into(), } } @@ -138,6 +147,14 @@ impl ScrollPooledTransaction { _ => None, } } + + /// Returns the [`TxEip7702`] variant if the transaction is an EIP-1559 transaction. + pub const fn as_eip7702(&self) -> Option<&TxEip7702> { + match self { + Self::Eip7702(tx) => Some(tx.tx()), + _ => None, + } + } } impl From> for ScrollPooledTransaction { @@ -158,6 +175,12 @@ impl From> for ScrollPooledTransaction { } } +impl From> for ScrollPooledTransaction { + fn from(v: Signed) -> Self { + Self::Eip7702(v) + } +} + impl Hash for ScrollPooledTransaction { fn hash(&self, state: &mut H) { self.trie_hash().hash(state); @@ -197,6 +220,7 @@ impl Encodable2718 for ScrollPooledTransaction { Self::Legacy(_) => None, Self::Eip2930(_) => Some(0x01), Self::Eip1559(_) => Some(0x02), + Self::Eip7702(_) => Some(0x04), } } @@ -205,6 +229,7 @@ impl Encodable2718 for ScrollPooledTransaction { Self::Legacy(tx) => tx.eip2718_encoded_length(), Self::Eip2930(tx) => tx.eip2718_encoded_length(), Self::Eip1559(tx) => tx.eip2718_encoded_length(), + Self::Eip7702(tx) => tx.eip2718_encoded_length(), } } @@ -213,6 +238,7 @@ impl Encodable2718 for ScrollPooledTransaction { Self::Legacy(tx) => tx.eip2718_encode(out), Self::Eip2930(tx) => tx.eip2718_encode(out), Self::Eip1559(tx) => tx.eip2718_encode(out), + Self::Eip7702(tx) => tx.eip2718_encode(out), } } @@ -226,6 +252,7 @@ impl Decodable2718 for ScrollPooledTransaction { match ty.try_into().map_err(|_| alloy_rlp::Error::Custom("unexpected tx type"))? { ScrollTxType::Eip2930 => Ok(TxEip2930::rlp_decode_signed(buf)?.into()), ScrollTxType::Eip1559 => Ok(TxEip1559::rlp_decode_signed(buf)?.into()), + ScrollTxType::Eip7702 => Ok(TxEip7702::rlp_decode_signed(buf)?.into()), ScrollTxType::Legacy => Err(Eip2718Error::UnexpectedType(ScrollTxType::Legacy.into())), ScrollTxType::L1Message => { Err(Eip2718Error::UnexpectedType(ScrollTxType::L1Message.into())) @@ -244,6 +271,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().chain_id(), Self::Eip2930(tx) => tx.tx().chain_id(), Self::Eip1559(tx) => tx.tx().chain_id(), + Self::Eip7702(tx) => tx.tx().chain_id(), } } @@ -252,6 +280,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().nonce(), Self::Eip2930(tx) => tx.tx().nonce(), Self::Eip1559(tx) => tx.tx().nonce(), + Self::Eip7702(tx) => tx.tx().nonce(), } } @@ -260,6 +289,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().gas_limit(), Self::Eip2930(tx) => tx.tx().gas_limit(), Self::Eip1559(tx) => tx.tx().gas_limit(), + Self::Eip7702(tx) => tx.tx().gas_limit(), } } @@ -268,6 +298,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().gas_price(), Self::Eip2930(tx) => tx.tx().gas_price(), Self::Eip1559(tx) => tx.tx().gas_price(), + Self::Eip7702(tx) => tx.tx().gas_price(), } } @@ -276,6 +307,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().max_fee_per_gas(), Self::Eip2930(tx) => tx.tx().max_fee_per_gas(), Self::Eip1559(tx) => tx.tx().max_fee_per_gas(), + Self::Eip7702(tx) => tx.tx().max_fee_per_gas(), } } @@ -284,6 +316,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().max_priority_fee_per_gas(), Self::Eip2930(tx) => tx.tx().max_priority_fee_per_gas(), Self::Eip1559(tx) => tx.tx().max_priority_fee_per_gas(), + Self::Eip7702(tx) => tx.tx().max_priority_fee_per_gas(), } } @@ -292,6 +325,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().max_fee_per_blob_gas(), Self::Eip2930(tx) => tx.tx().max_fee_per_blob_gas(), Self::Eip1559(tx) => tx.tx().max_fee_per_blob_gas(), + Self::Eip7702(tx) => tx.tx().max_fee_per_blob_gas(), } } @@ -300,6 +334,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().priority_fee_or_price(), Self::Eip2930(tx) => tx.tx().priority_fee_or_price(), Self::Eip1559(tx) => tx.tx().priority_fee_or_price(), + Self::Eip7702(tx) => tx.tx().priority_fee_or_price(), } } @@ -308,6 +343,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().effective_gas_price(base_fee), Self::Eip2930(tx) => tx.tx().effective_gas_price(base_fee), Self::Eip1559(tx) => tx.tx().effective_gas_price(base_fee), + Self::Eip7702(tx) => tx.tx().effective_gas_price(base_fee), } } @@ -316,6 +352,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().is_dynamic_fee(), Self::Eip2930(tx) => tx.tx().is_dynamic_fee(), Self::Eip1559(tx) => tx.tx().is_dynamic_fee(), + Self::Eip7702(tx) => tx.tx().is_dynamic_fee(), } } @@ -324,6 +361,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().kind(), Self::Eip2930(tx) => tx.tx().kind(), Self::Eip1559(tx) => tx.tx().kind(), + Self::Eip7702(tx) => tx.tx().kind(), } } @@ -332,6 +370,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().is_create(), Self::Eip2930(tx) => tx.tx().is_create(), Self::Eip1559(tx) => tx.tx().is_create(), + Self::Eip7702(tx) => tx.tx().is_create(), } } @@ -340,6 +379,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().value(), Self::Eip2930(tx) => tx.tx().value(), Self::Eip1559(tx) => tx.tx().value(), + Self::Eip7702(tx) => tx.tx().value(), } } @@ -348,6 +388,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().input(), Self::Eip2930(tx) => tx.tx().input(), Self::Eip1559(tx) => tx.tx().input(), + Self::Eip7702(tx) => tx.tx().input(), } } @@ -356,6 +397,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().access_list(), Self::Eip2930(tx) => tx.tx().access_list(), Self::Eip1559(tx) => tx.tx().access_list(), + Self::Eip7702(tx) => tx.tx().access_list(), } } @@ -364,6 +406,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().blob_versioned_hashes(), Self::Eip2930(tx) => tx.tx().blob_versioned_hashes(), Self::Eip1559(tx) => tx.tx().blob_versioned_hashes(), + Self::Eip7702(tx) => tx.tx().blob_versioned_hashes(), } } @@ -372,6 +415,7 @@ impl Transaction for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().authorization_list(), Self::Eip2930(tx) => tx.tx().authorization_list(), Self::Eip1559(tx) => tx.tx().authorization_list(), + Self::Eip7702(tx) => tx.tx().authorization_list(), } } } @@ -382,6 +426,7 @@ impl Typed2718 for ScrollPooledTransaction { Self::Legacy(tx) => tx.tx().ty(), Self::Eip2930(tx) => tx.tx().ty(), Self::Eip1559(tx) => tx.tx().ty(), + Self::Eip7702(tx) => tx.tx().ty(), } } } diff --git a/crates/scroll/alloy/consensus/src/transaction/tx_type.rs b/crates/scroll/alloy/consensus/src/transaction/tx_type.rs index e1892884f1b2..d0f9d8b07b90 100644 --- a/crates/scroll/alloy/consensus/src/transaction/tx_type.rs +++ b/crates/scroll/alloy/consensus/src/transaction/tx_type.rs @@ -9,7 +9,7 @@ use reth_codecs::{ __private::bytes, txtype::{ COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, - COMPACT_IDENTIFIER_LEGACY, + COMPACT_IDENTIFIER_EIP7702, COMPACT_IDENTIFIER_LEGACY, }, Compact, }; @@ -30,6 +30,9 @@ pub enum ScrollTxType { /// EIP-1559 transaction type. #[display("eip1559")] Eip1559 = 2, + /// EIP-7702 transaction type. + #[display("eip7702")] + Eip7702 = 4, /// L1 message transaction type. #[display("l1_message")] L1Message = L1_MESSAGE_TX_TYPE_ID, @@ -37,7 +40,8 @@ pub enum ScrollTxType { impl ScrollTxType { /// List of all variants. - pub const ALL: [Self; 4] = [Self::Legacy, Self::Eip1559, Self::Eip2930, Self::L1Message]; + pub const ALL: [Self; 5] = + [Self::Legacy, Self::Eip1559, Self::Eip2930, Self::Eip7702, Self::L1Message]; } #[cfg(any(test, feature = "arbitrary"))] @@ -68,6 +72,7 @@ impl TryFrom for ScrollTxType { x if x == Self::Legacy as u8 => Self::Legacy, x if x == Self::Eip2930 as u8 => Self::Eip2930, x if x == Self::Eip1559 as u8 => Self::Eip1559, + x if x == Self::Eip7702 as u8 => Self::Eip1559, x if x == Self::L1Message as u8 => Self::L1Message, _ => return Err(Eip2718Error::UnexpectedType(value)), }) @@ -131,6 +136,7 @@ impl Compact for ScrollTxType { Self::Legacy => COMPACT_IDENTIFIER_LEGACY, Self::Eip2930 => COMPACT_IDENTIFIER_EIP2930, Self::Eip1559 => COMPACT_IDENTIFIER_EIP1559, + Self::Eip7702 => COMPACT_IDENTIFIER_EIP7702, Self::L1Message => { buf.put_u8(L1_MESSAGE_TX_TYPE_ID); COMPACT_EXTENDED_IDENTIFIER_FLAG @@ -148,6 +154,7 @@ impl Compact for ScrollTxType { COMPACT_IDENTIFIER_LEGACY => Self::Legacy, COMPACT_IDENTIFIER_EIP2930 => Self::Eip2930, COMPACT_IDENTIFIER_EIP1559 => Self::Eip1559, + COMPACT_IDENTIFIER_EIP7702 => Self::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG => { let extended_identifier = buf.get_u8(); match extended_identifier { @@ -176,11 +183,12 @@ mod tests { #[test] fn test_all_tx_types() { - assert_eq!(ScrollTxType::ALL.len(), 4); + assert_eq!(ScrollTxType::ALL.len(), 5); let all = vec![ ScrollTxType::Legacy, ScrollTxType::Eip1559, ScrollTxType::Eip2930, + ScrollTxType::Eip7702, ScrollTxType::L1Message, ]; assert_eq!(ScrollTxType::ALL.to_vec(), all); diff --git a/crates/scroll/alloy/consensus/src/transaction/typed.rs b/crates/scroll/alloy/consensus/src/transaction/typed.rs index cb4426346704..b6377ef8ee56 100644 --- a/crates/scroll/alloy/consensus/src/transaction/typed.rs +++ b/crates/scroll/alloy/consensus/src/transaction/typed.rs @@ -1,6 +1,6 @@ use crate::{ScrollTxEnvelope, ScrollTxType, TxL1Message}; use alloy_consensus::{ - SignableTransaction, Transaction, TxEip1559, TxEip2930, TxLegacy, Typed2718, + SignableTransaction, Transaction, TxEip1559, TxEip2930, TxEip7702, TxLegacy, Typed2718, }; use alloy_eips::eip2930::AccessList; use alloy_primitives::{Address, Bytes, TxKind, B256}; @@ -14,7 +14,8 @@ use reth_codecs_derive::generate_tests; /// 1. `Legacy` (pre-EIP2718) [`TxLegacy`] /// 2. `EIP2930` (state access lists) [`TxEip2930`] /// 3. `EIP1559` [`TxEip1559`] -/// 4. `L1Message` [`TxL1Message`] +/// 4. `Eip7702` [`TxEip7702`] +/// 5. `L1Message` [`TxL1Message`] #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -32,6 +33,8 @@ pub enum ScrollTypedTransaction { Eip2930(TxEip2930), /// EIP-1559 transaction Eip1559(TxEip1559), + /// EIP-7702 transaction + Eip7702(TxEip7702), /// Scroll L1 message transaction L1Message(TxL1Message), } @@ -54,6 +57,12 @@ impl From for ScrollTypedTransaction { } } +impl From for ScrollTypedTransaction { + fn from(tx: TxEip7702) -> Self { + Self::Eip7702(tx) + } +} + impl From for ScrollTypedTransaction { fn from(tx: TxL1Message) -> Self { Self::L1Message(tx) @@ -66,6 +75,7 @@ impl From for ScrollTypedTransaction { ScrollTxEnvelope::Legacy(tx) => Self::Legacy(tx.strip_signature()), ScrollTxEnvelope::Eip2930(tx) => Self::Eip2930(tx.strip_signature()), ScrollTxEnvelope::Eip1559(tx) => Self::Eip1559(tx.strip_signature()), + ScrollTxEnvelope::Eip7702(tx) => Self::Eip7702(tx.strip_signature()), ScrollTxEnvelope::L1Message(tx) => Self::L1Message(tx.into_inner()), } } @@ -78,6 +88,7 @@ impl ScrollTypedTransaction { Self::Legacy(_) => ScrollTxType::Legacy, Self::Eip2930(_) => ScrollTxType::Eip2930, Self::Eip1559(_) => ScrollTxType::Eip1559, + Self::Eip7702(_) => ScrollTxType::Eip7702, Self::L1Message(_) => ScrollTxType::L1Message, } } @@ -106,6 +117,14 @@ impl ScrollTypedTransaction { } } + /// Return the inner EIP-1559 transaction if it exists. + pub const fn eip7702(&self) -> Option<&TxEip7702> { + match self { + Self::Eip7702(tx) => Some(tx), + _ => None, + } + } + /// Return the inner l1 message if it exists. pub const fn l1_message(&self) -> Option<&TxL1Message> { match self { @@ -120,6 +139,7 @@ impl ScrollTypedTransaction { Self::Legacy(tx) => tx.signature_hash(), Self::Eip2930(tx) => tx.signature_hash(), Self::Eip1559(tx) => tx.signature_hash(), + Self::Eip7702(tx) => tx.signature_hash(), Self::L1Message(_) => B256::ZERO, } } @@ -131,6 +151,7 @@ impl Typed2718 for ScrollTypedTransaction { Self::Legacy(_) => ScrollTxType::Legacy as u8, Self::Eip2930(_) => ScrollTxType::Eip2930 as u8, Self::Eip1559(_) => ScrollTxType::Eip1559 as u8, + Self::Eip7702(_) => ScrollTxType::Eip7702 as u8, Self::L1Message(_) => ScrollTxType::L1Message as u8, } } @@ -142,6 +163,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.chain_id(), Self::Eip2930(tx) => tx.chain_id(), Self::Eip1559(tx) => tx.chain_id(), + Self::Eip7702(tx) => tx.chain_id(), Self::L1Message(tx) => tx.chain_id(), } } @@ -151,6 +173,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.nonce(), Self::Eip2930(tx) => tx.nonce(), Self::Eip1559(tx) => tx.nonce(), + Self::Eip7702(tx) => tx.nonce(), Self::L1Message(tx) => tx.nonce(), } } @@ -160,6 +183,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.gas_limit(), Self::Eip2930(tx) => tx.gas_limit(), Self::Eip1559(tx) => tx.gas_limit(), + Self::Eip7702(tx) => tx.gas_limit(), Self::L1Message(tx) => tx.gas_limit(), } } @@ -169,6 +193,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.gas_price(), Self::Eip2930(tx) => tx.gas_price(), Self::Eip1559(tx) => tx.gas_price(), + Self::Eip7702(tx) => tx.gas_price(), Self::L1Message(tx) => tx.gas_price(), } } @@ -178,6 +203,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.max_fee_per_gas(), Self::Eip2930(tx) => tx.max_fee_per_gas(), Self::Eip1559(tx) => tx.max_fee_per_gas(), + Self::Eip7702(tx) => tx.max_fee_per_gas(), Self::L1Message(tx) => tx.max_fee_per_gas(), } } @@ -187,6 +213,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.max_priority_fee_per_gas(), Self::Eip2930(tx) => tx.max_priority_fee_per_gas(), Self::Eip1559(tx) => tx.max_priority_fee_per_gas(), + Self::Eip7702(tx) => tx.max_priority_fee_per_gas(), Self::L1Message(tx) => tx.max_priority_fee_per_gas(), } } @@ -196,6 +223,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.max_fee_per_blob_gas(), Self::Eip2930(tx) => tx.max_fee_per_blob_gas(), Self::Eip1559(tx) => tx.max_fee_per_blob_gas(), + Self::Eip7702(tx) => tx.max_fee_per_blob_gas(), Self::L1Message(tx) => tx.max_fee_per_blob_gas(), } } @@ -205,6 +233,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.priority_fee_or_price(), Self::Eip2930(tx) => tx.priority_fee_or_price(), Self::Eip1559(tx) => tx.priority_fee_or_price(), + Self::Eip7702(tx) => tx.priority_fee_or_price(), Self::L1Message(tx) => tx.priority_fee_or_price(), } } @@ -214,6 +243,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.to(), Self::Eip2930(tx) => tx.to(), Self::Eip1559(tx) => tx.to(), + Self::Eip7702(tx) => tx.to(), Self::L1Message(tx) => tx.to(), } } @@ -223,6 +253,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.kind(), Self::Eip2930(tx) => tx.kind(), Self::Eip1559(tx) => tx.kind(), + Self::Eip7702(tx) => tx.kind(), Self::L1Message(tx) => tx.kind(), } } @@ -232,6 +263,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.value(), Self::Eip2930(tx) => tx.value(), Self::Eip1559(tx) => tx.value(), + Self::Eip7702(tx) => tx.value(), Self::L1Message(tx) => tx.value(), } } @@ -241,6 +273,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.input(), Self::Eip2930(tx) => tx.input(), Self::Eip1559(tx) => tx.input(), + Self::Eip7702(tx) => tx.input(), Self::L1Message(tx) => tx.input(), } } @@ -250,6 +283,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.access_list(), Self::Eip2930(tx) => tx.access_list(), Self::Eip1559(tx) => tx.access_list(), + Self::Eip7702(tx) => tx.access_list(), Self::L1Message(tx) => tx.access_list(), } } @@ -259,6 +293,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.blob_versioned_hashes(), Self::Eip2930(tx) => tx.blob_versioned_hashes(), Self::Eip1559(tx) => tx.blob_versioned_hashes(), + Self::Eip7702(tx) => tx.blob_versioned_hashes(), Self::L1Message(tx) => tx.blob_versioned_hashes(), } } @@ -268,6 +303,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.authorization_list(), Self::Eip2930(tx) => tx.authorization_list(), Self::Eip1559(tx) => tx.authorization_list(), + Self::Eip7702(tx) => tx.authorization_list(), Self::L1Message(tx) => tx.authorization_list(), } } @@ -277,6 +313,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.is_dynamic_fee(), Self::Eip2930(tx) => tx.is_dynamic_fee(), Self::Eip1559(tx) => tx.is_dynamic_fee(), + Self::Eip7702(tx) => tx.is_dynamic_fee(), Self::L1Message(tx) => tx.is_dynamic_fee(), } } @@ -286,6 +323,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.effective_gas_price(base_fee), Self::Eip2930(tx) => tx.effective_gas_price(base_fee), Self::Eip1559(tx) => tx.effective_gas_price(base_fee), + Self::Eip7702(tx) => tx.effective_gas_price(base_fee), Self::L1Message(tx) => tx.effective_gas_price(base_fee), } } @@ -295,6 +333,7 @@ impl Transaction for ScrollTypedTransaction { Self::Legacy(tx) => tx.is_create(), Self::Eip2930(tx) => tx.is_create(), Self::Eip1559(tx) => tx.is_create(), + Self::Eip7702(tx) => tx.is_create(), Self::L1Message(tx) => tx.is_create(), } } @@ -310,6 +349,7 @@ impl Compact for ScrollTypedTransaction { Self::Legacy(tx) => tx.to_compact(out), Self::Eip2930(tx) => tx.to_compact(out), Self::Eip1559(tx) => tx.to_compact(out), + Self::Eip7702(tx) => tx.to_compact(out), Self::L1Message(tx) => tx.to_compact(out), }; identifier @@ -330,6 +370,10 @@ impl Compact for ScrollTypedTransaction { let (tx, buf) = Compact::from_compact(buf, buf.len()); (Self::Eip1559(tx), buf) } + ScrollTxType::Eip7702 => { + let (tx, buf) = Compact::from_compact(buf, buf.len()); + (Self::Eip7702(tx), buf) + } ScrollTxType::L1Message => { let (tx, buf) = Compact::from_compact(buf, buf.len()); (Self::L1Message(tx), buf) @@ -378,6 +422,9 @@ mod serde_from { /// `EIP-1559` transaction #[serde(rename = "0x02", alias = "0x2")] Eip1559(TxEip1559), + /// `EIP-7702` transaction + #[serde(rename = "0x04", alias = "0x4")] + Eip7702(TxEip7702), /// `L1Message` transaction #[serde( rename = "0x7e", @@ -402,6 +449,7 @@ mod serde_from { TaggedTypedTransaction::Legacy(signed) => Self::Legacy(signed), TaggedTypedTransaction::Eip2930(signed) => Self::Eip2930(signed), TaggedTypedTransaction::Eip1559(signed) => Self::Eip1559(signed), + TaggedTypedTransaction::Eip7702(signed) => Self::Eip7702(signed), TaggedTypedTransaction::L1Message(tx) => Self::L1Message(tx), } } @@ -413,6 +461,7 @@ mod serde_from { ScrollTypedTransaction::Legacy(signed) => Self::Legacy(signed), ScrollTypedTransaction::Eip2930(signed) => Self::Eip2930(signed), ScrollTypedTransaction::Eip1559(signed) => Self::Eip1559(signed), + ScrollTypedTransaction::Eip7702(signed) => Self::Eip7702(signed), ScrollTypedTransaction::L1Message(tx) => Self::L1Message(tx), } } diff --git a/crates/scroll/alloy/network/src/lib.rs b/crates/scroll/alloy/network/src/lib.rs index e0a171d82e04..e2f3c9afb72c 100644 --- a/crates/scroll/alloy/network/src/lib.rs +++ b/crates/scroll/alloy/network/src/lib.rs @@ -155,7 +155,7 @@ impl TransactionBuilder for ScrollTransactionRequest { TxType::Eip1559 | TxType::Eip4844 => ScrollTxType::Eip1559, TxType::Eip2930 => ScrollTxType::Eip2930, TxType::Legacy => ScrollTxType::Legacy, - TxType::Eip7702 => unimplemented!(), + TxType::Eip7702 => ScrollTxType::Eip7702, } } @@ -165,7 +165,7 @@ impl TransactionBuilder for ScrollTransactionRequest { TxType::Eip1559 | TxType::Eip4844 => ScrollTxType::Eip1559, TxType::Eip2930 => ScrollTxType::Eip2930, TxType::Legacy => ScrollTxType::Legacy, - TxType::Eip7702 => unimplemented!(), + TxType::Eip7702 => ScrollTxType::Eip7702, }) } @@ -212,6 +212,7 @@ impl NetworkWallet for EthereumWallet { ScrollTypedTransaction::Legacy(tx) => TypedTransaction::Legacy(tx), ScrollTypedTransaction::Eip2930(tx) => TypedTransaction::Eip2930(tx), ScrollTypedTransaction::Eip1559(tx) => TypedTransaction::Eip1559(tx), + ScrollTypedTransaction::Eip7702(tx) => TypedTransaction::Eip7702(tx), ScrollTypedTransaction::L1Message(_) => { return Err(alloy_signer::Error::other("not implemented for deposit tx")) } @@ -221,6 +222,7 @@ impl NetworkWallet for EthereumWallet { Ok(match tx { TxEnvelope::Eip1559(tx) => ScrollTxEnvelope::Eip1559(tx), TxEnvelope::Eip2930(tx) => ScrollTxEnvelope::Eip2930(tx), + TxEnvelope::Eip7702(tx) => ScrollTxEnvelope::Eip7702(tx), TxEnvelope::Legacy(tx) => ScrollTxEnvelope::Legacy(tx), _ => unreachable!(), }) diff --git a/crates/scroll/alloy/rpc-types/src/transaction/request.rs b/crates/scroll/alloy/rpc-types/src/transaction/request.rs index b3185fd263e3..d55f8d424a88 100644 --- a/crates/scroll/alloy/rpc-types/src/transaction/request.rs +++ b/crates/scroll/alloy/rpc-types/src/transaction/request.rs @@ -165,6 +165,7 @@ impl From for ScrollTransactionRequest { ScrollTypedTransaction::Legacy(tx) => Self(tx.into()), ScrollTypedTransaction::Eip2930(tx) => Self(tx.into()), ScrollTypedTransaction::Eip1559(tx) => Self(tx.into()), + ScrollTypedTransaction::Eip7702(tx) => Self(tx.into()), ScrollTypedTransaction::L1Message(tx) => tx.into(), } } @@ -175,6 +176,7 @@ impl From for ScrollTransactionRequest { match value { ScrollTxEnvelope::Eip2930(tx) => tx.into(), ScrollTxEnvelope::Eip1559(tx) => tx.into(), + ScrollTxEnvelope::Eip7702(tx) => tx.into(), ScrollTxEnvelope::L1Message(tx) => tx.into(), _ => Default::default(), } diff --git a/crates/scroll/evm/src/config.rs b/crates/scroll/evm/src/config.rs index e3bf8d71e9e5..6cbba35eb6ff 100644 --- a/crates/scroll/evm/src/config.rs +++ b/crates/scroll/evm/src/config.rs @@ -72,7 +72,9 @@ impl ScrollEvmConfig { /// Returns the spec id at the given head. pub fn spec_id_at_head(&self, head: &Head) -> SpecId { let chain_spec = &self.chain_spec; - if chain_spec.fork(ScrollHardfork::Curie).active_at_head(head) { + if chain_spec.fork(ScrollHardfork::EuclidV2).active_at_head(head) { + SpecId::EUCLID_V2 + } else if chain_spec.fork(ScrollHardfork::Curie).active_at_head(head) { SpecId::CURIE } else if chain_spec.fork(ScrollHardfork::Bernoulli).active_at_head(head) { SpecId::BERNOULLI diff --git a/crates/scroll/evm/src/execute.rs b/crates/scroll/evm/src/execute.rs index 03ebc11f0567..d8b0f399754b 100644 --- a/crates/scroll/evm/src/execute.rs +++ b/crates/scroll/evm/src/execute.rs @@ -137,7 +137,9 @@ where ) .into()) } - if transaction.is_eip7702() { + if transaction.is_eip7702() && + !chain_spec.is_euclid_v2_active_at_timestamp(block.timestamp) + { return Err(ConsensusError::InvalidTransaction( InvalidTransactionError::Eip7702Disabled, ) diff --git a/crates/scroll/evm/src/receipt.rs b/crates/scroll/evm/src/receipt.rs index fee0f964ab0e..613c71a1c80d 100644 --- a/crates/scroll/evm/src/receipt.rs +++ b/crates/scroll/evm/src/receipt.rs @@ -50,6 +50,7 @@ impl ScrollReceiptBuilder for BasicScrollReceiptBuilder ScrollTxType::Legacy => ScrollReceipt::Legacy(into_scroll_receipt(inner)), ScrollTxType::Eip2930 => ScrollReceipt::Eip2930(into_scroll_receipt(inner)), ScrollTxType::Eip1559 => ScrollReceipt::Eip1559(into_scroll_receipt(inner)), + ScrollTxType::Eip7702 => ScrollReceipt::Eip7702(into_scroll_receipt(inner)), ScrollTxType::L1Message => ScrollReceipt::L1Message(inner), } } diff --git a/crates/scroll/hardforks/src/dev.rs b/crates/scroll/hardforks/src/dev.rs index 33fcd0d00776..58a2bbe24f6f 100644 --- a/crates/scroll/hardforks/src/dev.rs +++ b/crates/scroll/hardforks/src/dev.rs @@ -23,5 +23,7 @@ pub static DEV_HARDFORKS: LazyLock = LazyLock::new(|| { (crate::ScrollHardfork::Curie.boxed(), ForkCondition::Block(0)), (crate::ScrollHardfork::Darwin.boxed(), ForkCondition::Timestamp(0)), (crate::ScrollHardfork::DarwinV2.boxed(), ForkCondition::Timestamp(0)), + (crate::ScrollHardfork::Euclid.boxed(), ForkCondition::Timestamp(0)), + (crate::ScrollHardfork::EuclidV2.boxed(), ForkCondition::Timestamp(0)), ]) }); diff --git a/crates/scroll/hardforks/src/hardfork.rs b/crates/scroll/hardforks/src/hardfork.rs index 6a49e2fcffdf..ff62d7da31f5 100644 --- a/crates/scroll/hardforks/src/hardfork.rs +++ b/crates/scroll/hardforks/src/hardfork.rs @@ -25,6 +25,8 @@ hardfork!( Darwin, /// DarwinV2 . DarwinV2, + Euclid, + EuclidV2, } ); @@ -80,6 +82,7 @@ impl ScrollHardfork { Self::Curie => Some(4740239), Self::Darwin => Some(6075509), Self::DarwinV2 => Some(6375501), + _ => None, }, ) } @@ -107,6 +110,7 @@ impl ScrollHardfork { Self::Curie => Some(7096836), Self::Darwin => Some(8568134), Self::DarwinV2 => Some(8923772), + _ => None, }, ) } @@ -134,6 +138,7 @@ impl ScrollHardfork { Self::Curie => Some(1718616171), Self::Darwin => Some(1723622400), Self::DarwinV2 => Some(1724832000), + _ => None, }, ) } @@ -161,6 +166,7 @@ impl ScrollHardfork { Self::Curie => Some(1719994277), Self::Darwin => Some(1724227200), Self::DarwinV2 => Some(1725264000), + _ => None, }, ) } diff --git a/crates/scroll/hardforks/src/lib.rs b/crates/scroll/hardforks/src/lib.rs index 79ddb3e726cf..f08bdd6d535a 100644 --- a/crates/scroll/hardforks/src/lib.rs +++ b/crates/scroll/hardforks/src/lib.rs @@ -39,4 +39,14 @@ pub trait ScrollHardforks: EthereumHardforks { fn is_darwin_v2_active_at_timestamp(&self, timestamp: u64) -> bool { self.scroll_fork_activation(ScrollHardfork::DarwinV2).active_at_timestamp(timestamp) } + + /// Returns `true` if [`Euclid`](ScrollHardfork::Euclid) is active at given block timestamp. + fn is_euclid_active_at_timestamp(&self, timestamp: u64) -> bool { + self.scroll_fork_activation(ScrollHardfork::Euclid).active_at_timestamp(timestamp) + } + + /// Returns `true` if [`EuclidV2`](ScrollHardfork::EuclidV2) is active at given block timestamp. + fn is_euclid_v2_active_at_timestamp(&self, timestamp: u64) -> bool { + self.scroll_fork_activation(ScrollHardfork::EuclidV2).active_at_timestamp(timestamp) + } } diff --git a/crates/scroll/primitives/src/receipt.rs b/crates/scroll/primitives/src/receipt.rs index 28107f13c248..dea630248040 100644 --- a/crates/scroll/primitives/src/receipt.rs +++ b/crates/scroll/primitives/src/receipt.rs @@ -20,6 +20,8 @@ pub enum ScrollReceipt { Eip2930(ScrollTransactionReceipt), /// EIP-1559 receipt Eip1559(ScrollTransactionReceipt), + /// EIP-7702 receipt + Eip7702(ScrollTransactionReceipt), /// L1 message receipt L1Message(Receipt), } @@ -31,6 +33,7 @@ impl ScrollReceipt { Self::Legacy(_) => ScrollTxType::Legacy, Self::Eip2930(_) => ScrollTxType::Eip2930, Self::Eip1559(_) => ScrollTxType::Eip1559, + Self::Eip7702(_) => ScrollTxType::Eip7702, Self::L1Message(_) => ScrollTxType::L1Message, } } @@ -38,9 +41,10 @@ impl ScrollReceipt { /// Returns inner [`Receipt`], pub const fn as_receipt(&self) -> &Receipt { match self { - Self::Legacy(receipt) | Self::Eip2930(receipt) | Self::Eip1559(receipt) => { - &receipt.inner - } + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip7702(receipt) => &receipt.inner, Self::L1Message(receipt) => receipt, } } @@ -48,9 +52,10 @@ impl ScrollReceipt { /// Returns length of RLP-encoded receipt fields with the given [`Bloom`] without an RLP header. pub fn rlp_encoded_fields_length(&self, bloom: &Bloom) -> usize { match self { - Self::Legacy(receipt) | Self::Eip2930(receipt) | Self::Eip1559(receipt) => { - receipt.rlp_encoded_fields_length_with_bloom(bloom) - } + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip7702(receipt) => receipt.rlp_encoded_fields_length_with_bloom(bloom), Self::L1Message(receipt) => receipt.rlp_encoded_fields_length_with_bloom(bloom), } } @@ -58,9 +63,10 @@ impl ScrollReceipt { /// RLP-encodes receipt fields with the given [`Bloom`] without an RLP header. pub fn rlp_encode_fields(&self, bloom: &Bloom, out: &mut dyn BufMut) { match self { - Self::Legacy(receipt) | Self::Eip2930(receipt) | Self::Eip1559(receipt) => { - receipt.rlp_encode_fields_with_bloom(bloom, out) - } + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip7702(receipt) => receipt.rlp_encode_fields_with_bloom(bloom, out), Self::L1Message(receipt) => receipt.rlp_encode_fields_with_bloom(bloom, out), } } @@ -92,6 +98,11 @@ impl ScrollReceipt { RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; Ok(ReceiptWithBloom { receipt: Self::Eip1559(receipt), logs_bloom }) } + ScrollTxType::Eip7702 => { + let ReceiptWithBloom { receipt, logs_bloom } = + RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; + Ok(ReceiptWithBloom { receipt: Self::Eip7702(receipt), logs_bloom }) + } ScrollTxType::L1Message => { let ReceiptWithBloom { receipt, logs_bloom } = RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; @@ -103,9 +114,10 @@ impl ScrollReceipt { /// Returns the l1 fee for the transaction receipt. pub const fn l1_fee(&self) -> U256 { match self { - Self::Legacy(receipt) | Self::Eip2930(receipt) | Self::Eip1559(receipt) => { - receipt.l1_fee - } + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip7702(receipt) => receipt.l1_fee, Self::L1Message(_) => U256::ZERO, } } @@ -268,6 +280,9 @@ mod compact { ScrollTxType::Eip1559 => { Self::Eip1559(ScrollTransactionReceipt::new(inner, l1_fee.unwrap_or_default())) } + ScrollTxType::Eip7702 => { + Self::Eip7702(ScrollTransactionReceipt::new(inner, l1_fee.unwrap_or_default())) + } ScrollTxType::L1Message => Self::L1Message(inner), } } diff --git a/crates/scroll/primitives/src/transaction/signed.rs b/crates/scroll/primitives/src/transaction/signed.rs index f5045d214e7e..de818a0b289d 100644 --- a/crates/scroll/primitives/src/transaction/signed.rs +++ b/crates/scroll/primitives/src/transaction/signed.rs @@ -4,7 +4,7 @@ use crate::ScrollTxType; use alloc::vec::Vec; use alloy_consensus::{ transaction::RlpEcdsaTx, SignableTransaction, Signed, Transaction, TxEip1559, TxEip2930, - TxLegacy, Typed2718, + TxEip7702, TxLegacy, Typed2718, }; use alloy_eips::{ eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, @@ -116,6 +116,7 @@ impl SignedTransaction for ScrollTransactionSigned { ScrollTypedTransaction::Legacy(tx) => tx.encode_for_signing(buf), ScrollTypedTransaction::Eip2930(tx) => tx.encode_for_signing(buf), ScrollTypedTransaction::Eip1559(tx) => tx.encode_for_signing(buf), + ScrollTypedTransaction::Eip7702(tx) => tx.encode_for_signing(buf), }; recover_signer_unchecked(&self.signature, keccak256(buf)) } @@ -175,6 +176,21 @@ impl reth_primitives_traits::FillTxEnv for ScrollTransactionSigned { tx_env.max_fee_per_blob_gas.take(); tx_env.authorization_list = None; } + ScrollTypedTransaction::Eip7702(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = alloy_primitives::U256::from(tx.max_fee_per_gas); + tx_env.gas_priority_fee = + Some(alloy_primitives::U256::from(tx.max_priority_fee_per_gas)); + tx_env.transact_to = tx.to.into(); + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = Some(tx.chain_id); + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clone_from(&tx.access_list.0); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = Some(tx.authorization_list.clone().into()); + } ScrollTypedTransaction::L1Message(tx) => { tx_env.access_list.clear(); tx_env.gas_limit = tx.gas_limit; @@ -248,6 +264,9 @@ impl Encodable2718 for ScrollTransactionSigned { ScrollTypedTransaction::Eip1559(dynamic_fee_tx) => { dynamic_fee_tx.eip2718_encoded_length(&self.signature) } + ScrollTypedTransaction::Eip7702(dynamic_fee_tx) => { + dynamic_fee_tx.eip2718_encoded_length(&self.signature) + } ScrollTypedTransaction::L1Message(l1_message) => l1_message.eip2718_encoded_length(), } } @@ -266,6 +285,9 @@ impl Encodable2718 for ScrollTransactionSigned { ScrollTypedTransaction::Eip1559(dynamic_fee_tx) => { dynamic_fee_tx.eip2718_encode(signature, out) } + ScrollTypedTransaction::Eip7702(dynamic_fee_tx) => { + dynamic_fee_tx.eip2718_encode(signature, out) + } ScrollTypedTransaction::L1Message(l1_message) => l1_message.encode_2718(out), } } @@ -287,6 +309,12 @@ impl Decodable2718 for ScrollTransactionSigned { signed_tx.hash.get_or_init(|| hash); Ok(signed_tx) } + ScrollTxType::Eip7702 => { + let (tx, signature, hash) = TxEip7702::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(ScrollTypedTransaction::Eip7702(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } ScrollTxType::L1Message => Ok(Self::new_unhashed( ScrollTypedTransaction::L1Message(TxL1Message::rlp_decode(buf)?), TxL1Message::signature(), @@ -544,6 +572,9 @@ impl TryFrom for ScrollPooledTransaction { ScrollTypedTransaction::Eip1559(tx) => { Ok(Self::Eip1559(Signed::new_unchecked(tx, signature, hash))) } + ScrollTypedTransaction::Eip7702(tx) => { + Ok(Self::Eip7702(Signed::new_unchecked(tx, signature, hash))) + } ScrollTypedTransaction::L1Message(_) => { Err(TryFromRecoveredTransactionError::UnsupportedTransactionType(0xfe)) } @@ -557,6 +588,7 @@ impl From for ScrollTransactionSigned { ScrollPooledTransaction::Legacy(tx) => tx.into(), ScrollPooledTransaction::Eip2930(tx) => tx.into(), ScrollPooledTransaction::Eip1559(tx) => tx.into(), + ScrollPooledTransaction::Eip7702(tx) => tx.into(), } } } @@ -565,7 +597,9 @@ impl From for ScrollTransactionSigned { #[cfg(feature = "serde-bincode-compat")] pub mod serde_bincode_compat { use alloc::borrow::Cow; - use alloy_consensus::transaction::serde_bincode_compat::{TxEip1559, TxEip2930, TxLegacy}; + use alloy_consensus::transaction::serde_bincode_compat::{ + TxEip1559, TxEip2930, TxEip7702, TxLegacy, + }; use alloy_primitives::{PrimitiveSignature as Signature, TxHash}; use reth_primitives_traits::{serde_bincode_compat::SerdeBincodeCompat, SignedTransaction}; use serde::{Deserialize, Serialize}; @@ -577,6 +611,7 @@ pub mod serde_bincode_compat { Legacy(TxLegacy<'a>), Eip2930(TxEip2930<'a>), Eip1559(TxEip1559<'a>), + Eip7702(TxEip7702<'a>), L1Message(Cow<'a, scroll_alloy_consensus::TxL1Message>), } @@ -586,6 +621,7 @@ pub mod serde_bincode_compat { super::ScrollTypedTransaction::Legacy(tx) => Self::Legacy(TxLegacy::from(tx)), super::ScrollTypedTransaction::Eip2930(tx) => Self::Eip2930(TxEip2930::from(tx)), super::ScrollTypedTransaction::Eip1559(tx) => Self::Eip1559(TxEip1559::from(tx)), + super::ScrollTypedTransaction::Eip7702(tx) => Self::Eip7702(TxEip7702::from(tx)), super::ScrollTypedTransaction::L1Message(tx) => Self::L1Message(Cow::Borrowed(tx)), } } @@ -597,6 +633,7 @@ pub mod serde_bincode_compat { ScrollTypedTransaction::Legacy(tx) => Self::Legacy(tx.into()), ScrollTypedTransaction::Eip2930(tx) => Self::Eip2930(tx.into()), ScrollTypedTransaction::Eip1559(tx) => Self::Eip1559(tx.into()), + ScrollTypedTransaction::Eip7702(tx) => Self::Eip7702(tx.into()), ScrollTypedTransaction::L1Message(tx) => Self::L1Message(tx.into_owned()), } } diff --git a/crates/scroll/rpc/src/eth/pending_block.rs b/crates/scroll/rpc/src/eth/pending_block.rs index aca3a172a1fd..e556738ea748 100644 --- a/crates/scroll/rpc/src/eth/pending_block.rs +++ b/crates/scroll/rpc/src/eth/pending_block.rs @@ -132,6 +132,7 @@ where ScrollTxType::Legacy => ScrollReceipt::Legacy(into_scroll_receipt(receipt)), ScrollTxType::Eip2930 => ScrollReceipt::Eip2930(into_scroll_receipt(receipt)), ScrollTxType::Eip1559 => ScrollReceipt::Eip1559(into_scroll_receipt(receipt)), + ScrollTxType::Eip7702 => ScrollReceipt::Eip7702(into_scroll_receipt(receipt)), ScrollTxType::L1Message => ScrollReceipt::L1Message(receipt), } } diff --git a/crates/scroll/rpc/src/eth/receipt.rs b/crates/scroll/rpc/src/eth/receipt.rs index f83f58eca904..254fb1f546b7 100644 --- a/crates/scroll/rpc/src/eth/receipt.rs +++ b/crates/scroll/rpc/src/eth/receipt.rs @@ -70,6 +70,9 @@ impl ScrollReceiptBuilder { ScrollReceipt::Eip1559(_) => { ScrollReceiptEnvelope::::Eip1559(receipt_with_bloom) } + ScrollReceipt::Eip7702(_) => { + ScrollReceiptEnvelope::::Eip7702(receipt_with_bloom) + } ScrollReceipt::L1Message(_) => { ScrollReceiptEnvelope::::L1Message(receipt_with_bloom) } diff --git a/crates/scroll/rpc/src/eth/transaction.rs b/crates/scroll/rpc/src/eth/transaction.rs index 8c745be547c0..aab0f5f812bb 100644 --- a/crates/scroll/rpc/src/eth/transaction.rs +++ b/crates/scroll/rpc/src/eth/transaction.rs @@ -81,6 +81,9 @@ where ScrollTypedTransaction::Eip1559(tx) => { Signed::new_unchecked(tx, signature, hash).into() } + ScrollTypedTransaction::Eip7702(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } ScrollTypedTransaction::L1Message(tx) => { ScrollTxEnvelope::L1Message(tx.seal_unchecked(hash)) } diff --git a/crates/storage/codecs/src/txtype.rs b/crates/storage/codecs/src/txtype.rs index ce392b59cd08..4336dfacb63c 100644 --- a/crates/storage/codecs/src/txtype.rs +++ b/crates/storage/codecs/src/txtype.rs @@ -9,6 +9,9 @@ pub const COMPACT_IDENTIFIER_EIP2930: usize = 1; /// Identifier parameter for EIP-1559 transaction pub const COMPACT_IDENTIFIER_EIP1559: usize = 2; +/// Identifier parameter for EIP-1559 transaction +pub const COMPACT_IDENTIFIER_EIP7702: usize = 4; + /// For backwards compatibility purposes only 2 bits of the type are encoded in the identifier /// parameter. In the case of a [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type is /// read from the buffer as a single byte.