From f875746ede83993a680b191324e4f51454297df4 Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Thu, 21 Nov 2024 17:49:18 +0100 Subject: [PATCH 01/11] implement Scroll l1 message transaction Signed-off-by: Gregory Edison --- Cargo.lock | 37 ++- crates/scroll/primitives/Cargo.toml | 48 ++- .../scroll/primitives/src/l1_transaction.rs | 306 ++++++++++++++++++ crates/scroll/primitives/src/lib.rs | 3 + 4 files changed, 370 insertions(+), 24 deletions(-) create mode 100644 crates/scroll/primitives/src/l1_transaction.rs diff --git a/Cargo.lock b/Cargo.lock index 5c858dfa0b25..0ef6c3a8ec9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ "derive_more 1.0.0", "foldhash", "getrandom 0.2.15", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "hex-literal", "indexmap 2.6.0", "itoa", @@ -3569,9 +3569,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -4123,7 +4123,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "serde", ] @@ -4299,9 +4299,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jni" @@ -4606,9 +4606,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.164" +version = "0.2.165" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e" [[package]] name = "libloading" @@ -4779,7 +4779,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -4883,9 +4883,9 @@ dependencies = [ [[package]] name = "metrics-process" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ca8ecd85575fbb143b2678cb123bb818779391ec0f745b1c4a9dbabadde407" +checksum = "4a82c8add4382f29a122fa64fff1891453ed0f6b2867d971e7d60cb8dfa322ff" dependencies = [ "libc", "libproc", @@ -4905,7 +4905,7 @@ checksum = "15b482df36c13dd1869d73d14d28cd4855fbd6cfc32294bee109908a9f4a4ed7" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "indexmap 2.6.0", "metrics", "ordered-float", @@ -9130,12 +9130,21 @@ dependencies = [ name = "reth-scroll-primitives" version = "1.1.2" dependencies = [ + "alloy-consensus", + "alloy-eips", "alloy-primitives", + "alloy-rlp", + "alloy-serde", "arbitrary", + "bincode", "bytes", "modular-bitfield", "poseidon-bn254", + "proptest", + "proptest-arbitrary-interop", + "rand 0.8.5", "reth-codecs", + "reth-codecs-derive", "serde", "test-fuzz", ] @@ -11214,9 +11223,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", diff --git a/crates/scroll/primitives/Cargo.toml b/crates/scroll/primitives/Cargo.toml index a8c17e0ff514..98c33b844077 100644 --- a/crates/scroll/primitives/Cargo.toml +++ b/crates/scroll/primitives/Cargo.toml @@ -13,35 +13,63 @@ workspace = true [dependencies] # alloy +alloy-consensus.workspace = true +alloy-eips.workspace = true alloy-primitives.workspace = true +alloy-rlp.workspace = true +alloy-serde.workspace = true # reth -reth-codecs.workspace = true +reth-codecs = { workspace = true, optional = true } +reth-codecs-derive = { workspace = true, optional = true } # scroll poseidon-bn254 = { workspace = true, features = ["bn254"] } -# misc -arbitrary = { workspace = true, features = ["derive"], optional = true } - # required by reth-codecs bytes.workspace = true modular-bitfield.workspace = true serde.workspace = true +# misc +arbitrary = { workspace = true, features = ["derive"], optional = true } + [dev-dependencies] alloy-primitives = { workspace = true, features = ["arbitrary"] } arbitrary = { workspace = true, features = ["derive"] } +bincode.workspace = true +rand.workspace = true +reth-codecs = { workspace = true, features = ["test-utils"] } + +proptest-arbitrary-interop.workspace = true +proptest.workspace = true test-fuzz.workspace = true [features] -default = ["std"] -std = [ - "serde/std", - "alloy-primitives/std" +default = [ + "reth-codec", + "std" ] arbitrary = [ - "dep:arbitrary", - "alloy-primitives/arbitrary", + "dep:arbitrary", + "alloy-primitives/arbitrary", "reth-codecs/arbitrary" ] +reth-codec = [ + "dep:reth-codecs", + "dep:reth-codecs-derive", + "std" +] +serde = ["alloy-primitives/serde"] +std = [ + "serde/std", + "alloy-primitives/std", + "reth-codecs/std", + "alloy-consensus/std", + "alloy-eips/std", + "alloy-rlp/std", + "alloy-serde/std", + "bytes/std", + "proptest/std", + "rand/std" +] diff --git a/crates/scroll/primitives/src/l1_transaction.rs b/crates/scroll/primitives/src/l1_transaction.rs new file mode 100644 index 000000000000..34a942183990 --- /dev/null +++ b/crates/scroll/primitives/src/l1_transaction.rs @@ -0,0 +1,306 @@ +//! Scroll L1 message transaction + +use alloy_consensus::Transaction; +use alloy_primitives::{ + private::alloy_rlp::{Encodable, Header}, + Address, Bytes, ChainId, PrimitiveSignature as Signature, TxKind, B256, U256, +}; +use alloy_rlp::Decodable; +use bytes::BufMut; +use reth_codecs::Compact; +use reth_codecs_derive::add_arbitrary_tests; +use serde::{Deserialize, Serialize}; + +const L1_MESSAGE_TRANSACTION_TYPE: u8 = 0x7E; + +/// A message transaction sent from the settlement layer to the L2 for execution. +/// +/// The signature of the L1 message is already verified on the L1 and as such doesn't contain +/// a signature field. Gas for the transaction execution on Scroll is already paid for on the L1. +/// +/// # Bincode compatibility +/// +/// `bincode` crate doesn't work with optionally serializable serde fields and some of the execution +/// types require optional serialization for RPC compatibility. Since `TxL1Message` doesn't +/// contain optionally serializable fields, no `bincode` compatible bridge implementation is +/// required. +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Compact)] +#[cfg_attr(any(test, feature = "serde"), derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(any(test, feature = "serde"), serde(rename_all = "camelCase"))] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] +#[add_arbitrary_tests(compact, rlp)] +pub struct TxL1Message { + /// The queue index of the message in the L1 contract queue. + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] + pub queue_index: u64, + /// The gas limit for the transaction. Gas is paid for when message is sent from the L1. + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity", rename = "gas"))] + pub gas_limit: u64, + /// The destination for the transaction. `Address` is used in place of `TxKind` since contract + /// creations aren't allowed via L1 message transactions. + pub to: Address, + /// The value sent. + pub value: U256, + /// The L1 sender of the transaction. + pub sender: Address, + /// The input of the transaction. + pub input: Bytes, +} + +impl TxL1Message { + /// Returns an empty signature for the [`TxL1Message`], which don't include a signature. + pub fn signature() -> Signature { + Signature::new(U256::ZERO, U256::ZERO, false) + } + + /// Returns the destination of the transaction as a [`TxKind`]. + pub const fn to(&self) -> TxKind { + TxKind::Call(self.to) + } + + /// Decodes the inner [`TxL1Message`] fields from RLP bytes. + /// + /// NOTE: This assumes a RLP header has already been decoded, and _just_ decodes the following + /// RLP fields in the following order: + /// + /// - `queue_index` + /// - `gas_limit` + /// - `to` + /// - `value` + /// - `input` + /// - `sender` + pub fn rlp_decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result { + Ok(Self { + queue_index: Decodable::decode(buf)?, + gas_limit: Decodable::decode(buf)?, + to: Decodable::decode(buf)?, + value: Decodable::decode(buf)?, + input: Decodable::decode(buf)?, + sender: Decodable::decode(buf)?, + }) + } + + /// Decodes the transaction from RLP bytes. + pub fn rlp_decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let header = Header::decode(buf)?; + if !header.list { + return Err(alloy_rlp::Error::UnexpectedString); + } + let remaining = buf.len(); + + let this = Self::rlp_decode_fields(buf)?; + + if buf.len() + header.payload_length != remaining { + return Err(alloy_rlp::Error::ListLengthMismatch { + expected: header.payload_length, + got: remaining - buf.len(), + }); + } + + Ok(this) + } + + /// Outputs the length of the transaction's fields, without a RLP header. + fn rlp_encoded_fields_length(&self) -> usize { + self.queue_index.length() + + self.gas_limit.length() + + self.to.length() + + self.value.length() + + self.input.0.length() + + self.sender.length() + } + + /// Encode the fields of the transaction without a RLP header. + /// + pub(crate) fn rlp_encode_fields(&self, out: &mut dyn BufMut) { + self.queue_index.encode(out); + self.gas_limit.encode(out); + self.to.encode(out); + self.value.encode(out); + self.input.encode(out); + self.sender.encode(out); + } + + /// Create a RLP header for the transaction. + fn rlp_header(&self) -> Header { + Header { list: true, payload_length: self.rlp_encoded_fields_length() } + } + + /// RLP encodes the transaction. + pub fn rlp_encode(&self, out: &mut dyn BufMut) { + self.rlp_header().encode(out); + self.rlp_encode_fields(out); + } + + /// Get the length of the transaction when RLP encoded. + pub fn rlp_encoded_length(&self) -> usize { + self.rlp_header().length_with_payload() + } + + /// Get the length of the transaction when EIP-2718 encoded. This is the + /// 1 byte type flag + the length of the RLP encoded transaction. + pub fn eip2718_encoded_length(&self) -> usize { + self.rlp_encoded_length() + 1 + } + + /// EIP-2718 encode the transaction. + pub fn eip2718_encode(&self, out: &mut dyn BufMut) { + out.put_u8(L1_MESSAGE_TRANSACTION_TYPE); + self.rlp_encode(out) + } + + /// Calculates the in-memory size of the [`TxL1Message`] transaction. + #[inline] + pub fn size(&self) -> usize { + size_of::() + // queue_index + size_of::() + // gas_limit + size_of::
() + // to + size_of::() + // value + self.input.len() + // input + size_of::
() // sender + } +} + +impl Encodable for TxL1Message { + fn encode(&self, out: &mut dyn BufMut) { + self.rlp_encode(out) + } + + fn length(&self) -> usize { + self.rlp_encoded_length() + } +} + +impl Decodable for TxL1Message { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + Self::rlp_decode(buf) + } +} + +impl Transaction for TxL1Message { + fn chain_id(&self) -> Option { + None + } + + fn nonce(&self) -> u64 { + 0u64 + } + + fn gas_limit(&self) -> u64 { + self.gas_limit + } + + fn gas_price(&self) -> Option { + None + } + + fn max_fee_per_gas(&self) -> u128 { + 0 + } + + fn max_priority_fee_per_gas(&self) -> Option { + None + } + + fn max_fee_per_blob_gas(&self) -> Option { + None + } + + fn priority_fee_or_price(&self) -> u128 { + 0 + } + + fn effective_gas_price(&self, _base_fee: Option) -> u128 { + 0 + } + + fn is_dynamic_fee(&self) -> bool { + false + } + + fn kind(&self) -> TxKind { + self.to() + } + + fn value(&self) -> U256 { + self.value + } + + fn input(&self) -> &Bytes { + &self.input + } + + fn ty(&self) -> u8 { + L1_MESSAGE_TRANSACTION_TYPE + } + + fn access_list(&self) -> Option<&alloy_eips::eip2930::AccessList> { + None + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + None + } + + fn authorization_list(&self) -> Option<&[alloy_eips::eip7702::SignedAuthorization]> { + None + } +} + +/// Scroll specific transaction fields +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ScrollL1MessageTransactionFields { + /// The index of the transaction in the message queue. + #[serde(with = "alloy_serde::quantity")] + pub queue_index: u64, + /// The sender of the transaction on the L1. + pub sender: Address, +} + +#[cfg(test)] +mod tests { + use super::TxL1Message; + use alloy_primitives::{address, bytes, hex, Bytes, U256}; + use arbitrary::Arbitrary; + use bytes::BytesMut; + use rand::Rng; + use reth_codecs::{test_utils::UnusedBits, validate_bitflag_backwards_compat}; + + #[test] + fn test_bincode_roundtrip() { + let mut bytes = [0u8; 1024]; + rand::thread_rng().fill(bytes.as_mut_slice()); + let tx = TxL1Message::arbitrary(&mut arbitrary::Unstructured::new(&bytes)).unwrap(); + + let encoded = bincode::serialize(&tx).unwrap(); + let decoded: TxL1Message = bincode::deserialize(&encoded).unwrap(); + assert_eq!(decoded, tx); + } + + #[test] + fn test_eip2718_encode() { + let tx = + TxL1Message { + queue_index: 947883, + gas_limit: 2000000, + to: address!("781e90f1c8fc4611c9b7497c3b47f99ef6969cbc"), + value: U256::ZERO, + sender: address!("7885bcbd5cecef1336b5300fb5186a12ddd8c478"), + input: bytes!("8ef1332e000000000000000000000000c186fa914353c44b2e33ebe05f21846f1048beda0000000000000000000000003bad7ad0728f9917d1bf08af5782dcbd516cdd96000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e76ab00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000044493a4f84f464e58d4bfa93bcc57abfb14dbe1b8ff46cd132b5709aab227f269727943d2f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + } + ; + let bytes = Bytes::from_static(&hex!("7ef9015a830e76ab831e848094781e90f1c8fc4611c9b7497c3b47f99ef6969cbc80b901248ef1332e000000000000000000000000c186fa914353c44b2e33ebe05f21846f1048beda0000000000000000000000003bad7ad0728f9917d1bf08af5782dcbd516cdd96000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e76ab00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000044493a4f84f464e58d4bfa93bcc57abfb14dbe1b8ff46cd132b5709aab227f269727943d2f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000947885bcbd5cecef1336b5300fb5186a12ddd8c478")); + + let mut encoded = BytesMut::default(); + tx.eip2718_encode(&mut encoded); + + assert_eq!(encoded, bytes.as_ref()) + } + + #[test] + fn test_compaction_backwards_compatibility() { + assert_eq!(TxL1Message::bitflag_encoded_bytes(), 2); + validate_bitflag_backwards_compat!(TxL1Message, UnusedBits::NotZero); + } +} diff --git a/crates/scroll/primitives/src/lib.rs b/crates/scroll/primitives/src/lib.rs index 2a18616b307d..5318d3c4b16e 100644 --- a/crates/scroll/primitives/src/lib.rs +++ b/crates/scroll/primitives/src/lib.rs @@ -8,5 +8,8 @@ mod execution_context; pub use account_extension::AccountExtension; mod account_extension; +pub use l1_transaction::{ScrollL1MessageTransactionFields, TxL1Message}; +pub mod l1_transaction; + pub use poseidon::{hash_code, POSEIDON_EMPTY}; mod poseidon; From 3380674721234277f55a8d9dcce1d45a09b387a0 Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Thu, 21 Nov 2024 18:28:08 +0100 Subject: [PATCH 02/11] add scroll l1 message transaction to `Transaction` enum Signed-off-by: Gregory Edison --- crates/primitives/Cargo.toml | 7 +- crates/primitives/src/alloy_compat.rs | 129 +++++++++--- crates/primitives/src/lib.rs | 5 + crates/primitives/src/receipt.rs | 52 ++--- crates/primitives/src/transaction/compat.rs | 24 ++- crates/primitives/src/transaction/mod.rs | 206 ++++++++++++++----- crates/primitives/src/transaction/pooled.rs | 11 +- crates/primitives/src/transaction/tx_type.rs | 47 ++++- 8 files changed, 365 insertions(+), 116 deletions(-) diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 12066447ec2c..84e5a5c5f6e3 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -30,6 +30,7 @@ alloy-trie = { workspace = true, features = ["serde"] } # scroll revm-primitives = { package = "reth-scroll-revm", path = "../scroll/revm", features = ["serde"] } +reth-scroll-primitives = { workspace = true, optional = true, features = ["serde"] } # optimism op-alloy-rpc-types = { workspace = true, optional = true } @@ -132,7 +133,8 @@ arbitrary = [ "op-alloy-rpc-types?/arbitrary", "reth-codecs?/arbitrary", "alloy-trie/arbitrary", - "reth-trie-common/arbitrary" + "reth-trie-common/arbitrary", + "reth-scroll-primitives?/arbitrary" ] secp256k1 = ["dep:secp256k1"] c-kzg = [ @@ -170,7 +172,8 @@ serde-bincode-compat = [ scroll = [ "reth-trie-common/scroll", "reth-primitives-traits/scroll", - "reth-testing-utils/scroll" + "reth-testing-utils/scroll", + "reth-scroll-primitives" ] [[bench]] diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index a72c83996c01..90c9f4e55450 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -123,34 +123,64 @@ impl TryFrom for TransactionSigned { let (tx, signature, hash) = tx.into_parts(); (Transaction::Eip7702(tx), signature, hash) } - #[cfg(feature = "optimism")] - AnyTxEnvelope::Unknown(alloy_network::UnknownTxEnvelope { hash, inner }) => { + #[cfg(any(feature = "optimism", feature = "scroll"))] + AnyTxEnvelope::Unknown(alloy_network::UnknownTxEnvelope { hash: _hash, inner }) => { use alloy_consensus::Transaction as _; - if inner.ty() == crate::TxType::Deposit { - let fields: op_alloy_rpc_types::OpTransactionFields = inner - .fields - .clone() - .deserialize_into::() - .map_err(|e| ConversionError::Custom(e.to_string()))?; - ( - Transaction::Deposit(op_alloy_consensus::TxDeposit { - source_hash: fields.source_hash.ok_or_else(|| { - ConversionError::Custom("MissingSourceHash".to_string()) - })?, - from: tx.from, - to: revm_primitives::TxKind::from(inner.to()), - mint: fields.mint.filter(|n| *n != 0), - value: inner.value(), - gas_limit: inner.gas_limit(), - is_system_transaction: fields.is_system_tx.unwrap_or(false), - input: inner.input().clone(), - }), - op_alloy_consensus::TxDeposit::signature(), - hash, - ) - } else { - return Err(ConversionError::Custom("unknown transaction type".to_string())) + match TryInto::::try_into(inner.ty()) + .map_err(|e| ConversionError::Custom(e.to_string()))? + { + #[cfg(all(feature = "optimism", not(feature = "scroll")))] + crate::TxType::Deposit => { + let fields: op_alloy_rpc_types::OpTransactionFields = inner + .fields + .clone() + .deserialize_into::() + .map_err(|e| ConversionError::Custom(e.to_string()))?; + ( + Transaction::Deposit(op_alloy_consensus::TxDeposit { + source_hash: fields.source_hash.ok_or_else(|| { + ConversionError::Custom("MissingSourceHash".to_string()) + })?, + from: tx.from, + to: revm_primitives::TxKind::from(inner.to()), + mint: fields.mint.filter(|n| *n != 0), + value: inner.value(), + gas_limit: inner.gas_limit(), + is_system_transaction: fields.is_system_tx.unwrap_or(false), + input: inner.input().clone(), + }), + op_alloy_consensus::TxDeposit::signature(), + _hash, + ) + } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + crate::TxType::L1Message => { + let fields = + inner + .fields + .clone() + .deserialize_into::() + .map_err(|e| ConversionError::Custom(e.to_string()))?; + ( + Transaction::L1Message(reth_scroll_primitives::TxL1Message { + queue_index: fields.queue_index, + gas_limit: inner.gas_limit(), + to: inner.to().ok_or(ConversionError::Custom( + "Scroll L1 message transaction do not support create transaction" + .to_string(), + ))?, + value: inner.value(), + sender: fields.sender, + input: inner.input().clone(), + }), + reth_scroll_primitives::TxL1Message::signature(), + _hash, + ) + } + _ => { + return Err(ConversionError::Custom("unknown transaction type".to_string())) + } } } _ => return Err(ConversionError::Custom("unknown transaction type".to_string())), @@ -161,7 +191,7 @@ impl TryFrom for TransactionSigned { } #[cfg(test)] -#[cfg(feature = "optimism")] +#[cfg(all(feature = "optimism", not(feature = "scroll")))] mod tests { use super::*; use alloy_primitives::{address, Address, B256, U256}; @@ -270,3 +300,48 @@ mod tests { } } } + +#[cfg(test)] +#[cfg(all(feature = "scroll", not(feature = "optimism")))] +mod tests { + use super::*; + use alloy_primitives::{address, U256}; + + #[test] + fn test_scroll_l1_message_tx() { + // https://scrollscan.com/tx/0x36199419dbdb7823235de4b73e3d90a61c7b1f343b7a682a271c3055249e81f9 + let input = r#"{ + "hash":"0x36199419dbdb7823235de4b73e3d90a61c7b1f343b7a682a271c3055249e81f9", + "nonce":"0x0", + "blockHash":"0x4aca26460c31be3948e8466681ad87891326a964422c9370d4c1913f3bed4b10", + "blockNumber":"0xabf06f", + "transactionIndex":"0x0", + "from":"0x7885bcbd5cecef1336b5300fb5186a12ddd8c478", + "to":"0x781e90f1c8fc4611c9b7497c3b47f99ef6969cbc", + "value":"0x0", + "gasPrice":"0x0", + "gas":"0x1e8480", + "input":"0x8ef1332e000000000000000000000000c186fa914353c44b2e33ebe05f21846f1048beda0000000000000000000000003bad7ad0728f9917d1bf08af5782dcbd516cdd96000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e76ab00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000044493a4f84f464e58d4bfa93bcc57abfb14dbe1b8ff46cd132b5709aab227f269727943d2f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "r":"0x0", + "s":"0x0", + "v":"0x0", + "type":"0x7e", + "queueIndex":"0xe76ab", + "sender":"0x7885bcbd5cecef1336b5300fb5186a12ddd8c478" + }"#; + let alloy_tx: WithOtherFields> = + serde_json::from_str(input).expect("failed to deserialize"); + + let TransactionSigned { transaction: reth_tx, .. } = + alloy_tx.try_into().expect("failed to convert"); + if let Transaction::L1Message(l1_message_tx) = reth_tx { + assert_eq!(l1_message_tx.queue_index, 0xe76ab); + assert_eq!(l1_message_tx.gas_limit, 0x1e8480); + assert_eq!(l1_message_tx.to, address!("781e90f1c8fc4611c9b7497c3b47f99ef6969cbc")); + assert_eq!(l1_message_tx.value, U256::ZERO); + assert_eq!(l1_message_tx.sender, address!("7885bcbd5cecef1336b5300fb5186a12ddd8c478")); + } else { + panic!("Expected Deposit transaction"); + } + } +} diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 203880209a2f..ae840f7f84f0 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -19,6 +19,11 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(feature = "optimism")] +use op_alloy_consensus as _; +#[cfg(feature = "scroll")] +use reth_scroll_primitives as _; + extern crate alloc; #[cfg(feature = "alloy-compat")] diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 77a44dc39e53..96c01d7aaeed 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -40,7 +40,7 @@ pub struct Receipt { /// Log send from contracts. pub logs: Vec, /// Deposit nonce for Optimism deposit transactions - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] pub deposit_nonce: Option, /// Deposit receipt version for Optimism deposit transactions /// @@ -48,7 +48,7 @@ pub struct Receipt { /// The deposit receipt version was introduced in Canyon to indicate an update to how /// receipt hashes should be computed when set. The state transition process /// ensures this is only set for post-Canyon deposit transactions. - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] pub deposit_receipt_version: Option, } @@ -228,7 +228,7 @@ impl<'a> arbitrary::Arbitrary<'a> for Receipt { let logs = Vec::::arbitrary(u)?; // Only receipts for deposit transactions may contain a deposit nonce - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] let (deposit_nonce, deposit_receipt_version) = if tx_type == TxType::Deposit { let deposit_nonce = Option::::arbitrary(u)?; let deposit_nonce_version = @@ -243,9 +243,9 @@ impl<'a> arbitrary::Arbitrary<'a> for Receipt { success, cumulative_gas_used, logs, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_nonce, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_receipt_version, }) } @@ -308,7 +308,7 @@ impl ReceiptWithBloom { let logs = alloy_rlp::Decodable::decode(b)?; let receipt = match tx_type { - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] TxType::Deposit => { let remaining = |b: &[u8]| rlp_head.payload_length - (started_len - b.len()) > 0; let deposit_nonce = @@ -330,9 +330,9 @@ impl ReceiptWithBloom { success, cumulative_gas_used, logs, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_nonce: None, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_receipt_version: None, }, }; @@ -392,7 +392,7 @@ impl Decodable for ReceiptWithBloom { buf.advance(1); Self::decode_receipt(buf, TxType::Eip7702) } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] op_alloy_consensus::DEPOSIT_TX_TYPE_ID => { buf.advance(1); Self::decode_receipt(buf, TxType::Deposit) @@ -465,7 +465,7 @@ impl ReceiptWithBloomEncoder<'_> { rlp_head.payload_length += self.bloom.length(); rlp_head.payload_length += self.receipt.logs.length(); - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] if self.receipt.tx_type == TxType::Deposit { if let Some(deposit_nonce) = self.receipt.deposit_nonce { rlp_head.payload_length += deposit_nonce.length(); @@ -485,7 +485,7 @@ impl ReceiptWithBloomEncoder<'_> { self.receipt.cumulative_gas_used.encode(out); self.bloom.encode(out); self.receipt.logs.encode(out); - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] if self.receipt.tx_type == TxType::Deposit { if let Some(deposit_nonce) = self.receipt.deposit_nonce { deposit_nonce.encode(out) @@ -527,10 +527,14 @@ impl ReceiptWithBloomEncoder<'_> { TxType::Eip7702 => { out.put_u8(EIP7702_TX_TYPE_ID); } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] TxType::Deposit => { out.put_u8(op_alloy_consensus::DEPOSIT_TX_TYPE_ID); } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + TxType::L1Message => { + out.put_u8(crate::transaction::L1_MESSAGE_TX_TYPE_ID); + } } out.put_slice(payload.as_ref()); } @@ -596,9 +600,9 @@ mod tests { bytes!("0100ff"), )], success: false, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_nonce: None, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_receipt_version: None, }, bloom: [0; 256].into(), @@ -630,9 +634,9 @@ mod tests { bytes!("0100ff"), )], success: false, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_nonce: None, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_receipt_version: None, }, bloom: [0; 256].into(), @@ -642,7 +646,7 @@ mod tests { assert_eq!(receipt, expected); } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] #[test] fn decode_deposit_receipt_regolith_roundtrip() { let data = hex!("7ef9010c0182b741b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0833d3bbf"); @@ -668,7 +672,7 @@ mod tests { assert_eq!(buf, &data[..]); } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] #[test] fn decode_deposit_receipt_canyon_roundtrip() { let data = hex!("7ef9010d0182b741b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0833d3bbf01"); @@ -712,9 +716,9 @@ mod tests { Bytes::from(vec![1; 0xffffff]), ), ], - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_nonce: None, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_receipt_version: None, }; @@ -732,9 +736,9 @@ mod tests { success: true, cumulative_gas_used: 21000, logs: vec![], - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_nonce: None, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_receipt_version: None, }, bloom: Bloom::default(), @@ -754,9 +758,9 @@ mod tests { success: true, cumulative_gas_used: 21000, logs: vec![], - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_nonce: None, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] deposit_receipt_version: None, }, bloom: Bloom::default(), diff --git a/crates/primitives/src/transaction/compat.rs b/crates/primitives/src/transaction/compat.rs index 883c89c45f51..65ea1489655a 100644 --- a/crates/primitives/src/transaction/compat.rs +++ b/crates/primitives/src/transaction/compat.rs @@ -1,6 +1,6 @@ use crate::{Transaction, TransactionSigned}; use alloy_primitives::{Address, TxKind, U256}; -#[cfg(feature = "optimism")] +#[cfg(all(feature = "optimism", not(feature = "scroll")))] use op_alloy_consensus::DepositTransaction; use revm_primitives::{AuthorizationList, TxEnv}; @@ -12,7 +12,7 @@ pub trait FillTxEnv { impl FillTxEnv for TransactionSigned { fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address) { - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] let envelope = alloy_eips::eip2718::Encodable2718::encoded_2718(self); tx_env.caller = sender; @@ -88,7 +88,7 @@ impl FillTxEnv for TransactionSigned { tx_env.authorization_list = Some(AuthorizationList::Signed(tx.authorization_list.clone())); } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Transaction::Deposit(tx) => { tx_env.access_list.clear(); tx_env.gas_limit = tx.gas_limit; @@ -109,9 +109,25 @@ impl FillTxEnv for TransactionSigned { }; return; } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Transaction::L1Message(tx) => { + tx_env.access_list.clear(); + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::ZERO; + tx_env.gas_priority_fee = None; + tx_env.transact_to = tx.to(); + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = None; + tx_env.nonce = None; + tx_env.authorization_list = None; + + // TODO (scroll): fill in the Scroll fields when revm fork is introduced in Reth. + // + } } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] if !self.is_deposit() { tx_env.optimism = revm_primitives::OptimismFields { source_hash: None, diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index b8a3f4a719bc..eba6cadd5de8 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -19,12 +19,14 @@ use derive_more::{AsRef, Deref}; use once_cell as _; #[cfg(not(feature = "std"))] use once_cell::sync::{Lazy as LazyLock, OnceCell as OnceLock}; -#[cfg(feature = "optimism")] +#[cfg(all(feature = "optimism", not(feature = "scroll")))] use op_alloy_consensus::DepositTransaction; -#[cfg(feature = "optimism")] +#[cfg(all(feature = "optimism", not(feature = "scroll")))] use op_alloy_consensus::TxDeposit; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use reth_primitives_traits::{InMemorySize, SignedTransaction}; +#[cfg(all(feature = "scroll", not(feature = "optimism")))] +use reth_scroll_primitives::l1_transaction::TxL1Message; use revm_primitives::{AuthorizationList, TxEnv}; use serde::{Deserialize, Serialize}; use signature::decode_with_eip155_chain_id; @@ -123,11 +125,14 @@ pub enum Transaction { /// functionality to the EOA. Eip7702(TxEip7702), /// Optimism deposit transaction. - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Deposit(TxDeposit), + /// Scroll L1 messaging transaction. + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + L1Message(TxL1Message), } -#[cfg(feature = "optimism")] +#[cfg(all(feature = "optimism", not(feature = "scroll")))] impl DepositTransaction for Transaction { fn source_hash(&self) -> Option { match self { @@ -177,11 +182,16 @@ impl<'a> arbitrary::Arbitrary<'a> for Transaction { let tx = TxEip7702::arbitrary(u)?; Self::Eip7702(tx) } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] TxType::Deposit => { let tx = TxDeposit::arbitrary(u)?; Self::Deposit(tx) } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + TxType::L1Message => { + let tx = TxL1Message::arbitrary(u)?; + Self::L1Message(tx) + } }; // Otherwise we might overflow when calculating `v` on `recalculate_hash` @@ -205,8 +215,10 @@ impl Transaction { Self::Eip1559(tx) => tx.signature_hash(), Self::Eip4844(tx) => tx.signature_hash(), Self::Eip7702(tx) => tx.signature_hash(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(_) => B256::ZERO, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(_) => B256::ZERO, } } @@ -218,8 +230,10 @@ impl Transaction { Self::Eip1559(TxEip1559 { chain_id: ref mut c, .. }) | Self::Eip4844(TxEip4844 { chain_id: ref mut c, .. }) | Self::Eip7702(TxEip7702 { chain_id: ref mut c, .. }) => *c = chain_id, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(_) => { /* noop */ } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(_) => { /* noop */ } } } @@ -231,8 +245,10 @@ impl Transaction { Self::Eip1559(_) => TxType::Eip1559, Self::Eip4844(_) => TxType::Eip4844, Self::Eip7702(_) => TxType::Eip7702, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(_) => TxType::Deposit, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(_) => TxType::L1Message, } } @@ -285,8 +301,10 @@ impl Transaction { Self::Eip1559(tx) => tx.encode_for_signing(out), Self::Eip4844(tx) => tx.encode_for_signing(out), Self::Eip7702(tx) => tx.encode_for_signing(out), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(_) => {} + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(_) => {} } } @@ -307,8 +325,10 @@ impl Transaction { Self::Eip7702(set_code_tx) => { set_code_tx.eip2718_encode(signature, out); } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(deposit_tx) => deposit_tx.eip2718_encode(out), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(l1_message_tx) => l1_message_tx.eip2718_encode(out), } } @@ -320,8 +340,10 @@ impl Transaction { Self::Eip1559(tx) => tx.gas_limit = gas_limit, Self::Eip4844(tx) => tx.gas_limit = gas_limit, Self::Eip7702(tx) => tx.gas_limit = gas_limit, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.gas_limit = gas_limit, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.gas_limit = gas_limit, } } @@ -333,8 +355,10 @@ impl Transaction { Self::Eip1559(tx) => tx.nonce = nonce, Self::Eip4844(tx) => tx.nonce = nonce, Self::Eip7702(tx) => tx.nonce = nonce, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(_) => { /* noop */ } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(_) => { /* noop */ } } } @@ -346,8 +370,10 @@ impl Transaction { Self::Eip1559(tx) => tx.value = value, Self::Eip4844(tx) => tx.value = value, Self::Eip7702(tx) => tx.value = value, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.value = value, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.value = value, } } @@ -359,8 +385,10 @@ impl Transaction { Self::Eip1559(tx) => tx.input = input, Self::Eip4844(tx) => tx.input = input, Self::Eip7702(tx) => tx.input = input, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.input = input, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.input = input, } } @@ -394,6 +422,13 @@ impl Transaction { matches!(self, Self::Eip7702(_)) } + /// Returns true if the transaction is a Scroll L1 messaging transaction. + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + #[inline] + pub fn is_l1_messaging(&self) -> bool { + matches!(self, Self::L1Message(_)) + } + /// Returns the [`TxLegacy`] variant if the transaction is a legacy transaction. pub const fn as_legacy(&self) -> Option<&TxLegacy> { match self { @@ -445,8 +480,10 @@ impl InMemorySize for Transaction { Self::Eip1559(tx) => tx.size(), Self::Eip4844(tx) => tx.size(), Self::Eip7702(tx) => tx.size(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.size(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.size(), } } } @@ -476,10 +513,14 @@ impl reth_codecs::Compact for Transaction { Self::Eip7702(tx) => { tx.to_compact(buf); } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => { tx.to_compact(buf); } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => { + tx.to_compact(buf); + } } identifier } @@ -524,11 +565,16 @@ impl reth_codecs::Compact for Transaction { let (tx, buf) = TxEip7702::from_compact(buf, buf.len()); (Self::Eip7702(tx), buf) } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] op_alloy_consensus::DEPOSIT_TX_TYPE_ID => { let (tx, buf) = TxDeposit::from_compact(buf, buf.len()); (Self::Deposit(tx), buf) } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + tx_type::L1_MESSAGE_TX_TYPE_ID => { + let (tx, buf) = TxL1Message::from_compact(buf, buf.len()); + (Self::L1Message(tx), buf) + } _ => unreachable!( "Junk data in database: unknown Transaction variant: {identifier}" ), @@ -553,8 +599,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.chain_id(), Self::Eip4844(tx) => tx.chain_id(), Self::Eip7702(tx) => tx.chain_id(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.chain_id(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.chain_id(), } } @@ -565,8 +613,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.nonce(), Self::Eip4844(tx) => tx.nonce(), Self::Eip7702(tx) => tx.nonce(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.nonce(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.nonce(), } } @@ -577,8 +627,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.gas_limit(), Self::Eip4844(tx) => tx.gas_limit(), Self::Eip7702(tx) => tx.gas_limit(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.gas_limit(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.gas_limit(), } } @@ -589,8 +641,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.gas_price(), Self::Eip4844(tx) => tx.gas_price(), Self::Eip7702(tx) => tx.gas_price(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.gas_price(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.gas_price(), } } @@ -601,8 +655,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.max_fee_per_gas(), Self::Eip4844(tx) => tx.max_fee_per_gas(), Self::Eip7702(tx) => tx.max_fee_per_gas(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.max_fee_per_gas(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.max_fee_per_gas(), } } @@ -613,8 +669,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.max_priority_fee_per_gas(), Self::Eip4844(tx) => tx.max_priority_fee_per_gas(), Self::Eip7702(tx) => tx.max_priority_fee_per_gas(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.max_priority_fee_per_gas(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.max_priority_fee_per_gas(), } } @@ -625,7 +683,7 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.max_fee_per_blob_gas(), Self::Eip4844(tx) => tx.max_fee_per_blob_gas(), Self::Eip7702(tx) => tx.max_fee_per_blob_gas(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.max_fee_per_blob_gas(), } } @@ -637,8 +695,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.priority_fee_or_price(), Self::Eip4844(tx) => tx.priority_fee_or_price(), Self::Eip7702(tx) => tx.priority_fee_or_price(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.priority_fee_or_price(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.priority_fee_or_price(), } } @@ -649,8 +709,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.effective_gas_price(base_fee), Self::Eip4844(tx) => tx.effective_gas_price(base_fee), Self::Eip7702(tx) => tx.effective_gas_price(base_fee), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.effective_gas_price(base_fee), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.effective_gas_price(base_fee), } } @@ -658,8 +720,10 @@ impl alloy_consensus::Transaction for Transaction { match self { Self::Legacy(_) | Self::Eip2930(_) => false, Self::Eip1559(_) | Self::Eip4844(_) | Self::Eip7702(_) => true, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(_) => false, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.is_dynamic_fee(), } } @@ -670,8 +734,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.kind(), Self::Eip4844(tx) => tx.kind(), Self::Eip7702(tx) => tx.kind(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.kind(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.kind(), } } @@ -682,8 +748,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.value(), Self::Eip4844(tx) => tx.value(), Self::Eip7702(tx) => tx.value(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.value(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.value(), } } @@ -694,8 +762,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.input(), Self::Eip4844(tx) => tx.input(), Self::Eip7702(tx) => tx.input(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.input(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.input(), } } @@ -706,8 +776,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.ty(), Self::Eip4844(tx) => tx.ty(), Self::Eip7702(tx) => tx.ty(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.ty(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.ty(), } } @@ -718,8 +790,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.access_list(), Self::Eip4844(tx) => tx.access_list(), Self::Eip7702(tx) => tx.access_list(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.access_list(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.access_list(), } } @@ -730,8 +804,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.blob_versioned_hashes(), Self::Eip4844(tx) => tx.blob_versioned_hashes(), Self::Eip7702(tx) => tx.blob_versioned_hashes(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.blob_versioned_hashes(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.blob_versioned_hashes(), } } @@ -742,8 +818,10 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip1559(tx) => tx.authorization_list(), Self::Eip4844(tx) => tx.authorization_list(), Self::Eip7702(tx) => tx.authorization_list(), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.authorization_list(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.authorization_list(), } } } @@ -799,10 +877,15 @@ impl TransactionSignedNoHash { pub fn recover_signer(&self) -> Option
{ // Optimism's Deposit transaction does not have a signature. Directly return the // `from` address. - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction { return Some(from) } + // Scroll L1 messages don't have a signature. + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + if let Transaction::L1Message(TxL1Message { sender, .. }) = self.transaction { + return Some(sender) + } let signature_hash = self.signature_hash(); recover_signer(&self.signature, signature_hash) @@ -827,7 +910,7 @@ impl TransactionSignedNoHash { // Optimism's Deposit transaction does not have a signature. Directly return the // `from` address. - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] { if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction { return Some(from) @@ -841,6 +924,10 @@ impl TransactionSignedNoHash { return Some(Address::ZERO) } } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + if let Transaction::L1Message(TxL1Message { sender, .. }) = self.transaction { + return Some(sender) + } recover_signer_unchecked(&self.signature, keccak256(buffer)) } @@ -1086,10 +1173,14 @@ impl TransactionSigned { pub fn recover_signer(&self) -> Option
{ // Optimism's Deposit transaction does not have a signature. Directly return the // `from` address. - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction { return Some(from) } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + if let Transaction::L1Message(TxL1Message { sender, .. }) = self.transaction { + return Some(sender) + } let signature_hash = self.signature_hash(); recover_signer(&self.signature, signature_hash) } @@ -1102,10 +1193,14 @@ impl TransactionSigned { pub fn recover_signer_unchecked(&self) -> Option
{ // Optimism's Deposit transaction does not have a signature. Directly return the // `from` address. - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction { return Some(from) } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + if let Transaction::L1Message(TxL1Message { sender, .. }) = self.transaction { + return Some(sender) + } let signature_hash = self.signature_hash(); recover_signer_unchecked(&self.signature, signature_hash) } @@ -1366,8 +1461,10 @@ impl reth_primitives_traits::FillTxEnv for TransactionSigned { tx_env.authorization_list = Some(AuthorizationList::Signed(tx.authorization_list.clone())); } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Transaction::Deposit(_) => {} + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Transaction::L1Message(_) => {} // TODO (scroll): should this be something? } } } @@ -1531,8 +1628,10 @@ impl Encodable2718 for TransactionSigned { Transaction::Eip7702(set_code_tx) => { set_code_tx.eip2718_encoded_length(&self.signature) } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Transaction::Deposit(deposit_tx) => deposit_tx.eip2718_encoded_length(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Transaction::L1Message(l1_message_tx) => l1_message_tx.eip2718_encoded_length(), } } @@ -1565,11 +1664,16 @@ impl Decodable2718 for TransactionSigned { let (tx, signature, hash) = TxEip4844::rlp_decode_signed(buf)?.into_parts(); Ok(Self { transaction: Transaction::Eip4844(tx), signature, hash: hash.into() }) } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] TxType::Deposit => Ok(Self::new_unhashed( Transaction::Deposit(TxDeposit::rlp_decode(buf)?), TxDeposit::signature(), )), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + TxType::L1Message => Ok(Self::new_unhashed( + Transaction::L1Message(TxL1Message::rlp_decode(buf)?), + TxL1Message::signature(), + )), } } @@ -1621,18 +1725,22 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned { ) .unwrap(); - #[cfg(feature = "optimism")] // Both `Some(0)` and `None` values are encoded as empty string byte. This introduces // ambiguity in roundtrip tests. Patch the mint value of deposit transaction here, so that // it's `None` if zero. + #[cfg(all(feature = "optimism", not(feature = "scroll")))] if let Transaction::Deposit(ref mut tx_deposit) = transaction { if tx_deposit.mint == Some(0) { tx_deposit.mint = None; } } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] let signature = if transaction.is_deposit() { TxDeposit::signature() } else { signature }; + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + let signature = + if transaction.is_l1_messaging() { TxL1Message::signature() } else { signature }; + Ok(Self::new_unhashed(transaction, signature)) } } @@ -1751,8 +1859,10 @@ pub mod serde_bincode_compat { Eip1559(TxEip1559<'a>), Eip4844(Cow<'a, TxEip4844>), Eip7702(TxEip7702<'a>), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Deposit(op_alloy_consensus::serde_bincode_compat::TxDeposit<'a>), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + L1Message(Cow<'a, reth_scroll_primitives::l1_transaction::TxL1Message>), } impl<'a> From<&'a super::Transaction> for Transaction<'a> { @@ -1763,10 +1873,12 @@ pub mod serde_bincode_compat { super::Transaction::Eip1559(tx) => Self::Eip1559(TxEip1559::from(tx)), super::Transaction::Eip4844(tx) => Self::Eip4844(Cow::Borrowed(tx)), super::Transaction::Eip7702(tx) => Self::Eip7702(TxEip7702::from(tx)), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] super::Transaction::Deposit(tx) => { Self::Deposit(op_alloy_consensus::serde_bincode_compat::TxDeposit::from(tx)) } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + super::Transaction::L1Message(tx) => Self::L1Message(Cow::Borrowed(tx)), } } } @@ -1779,8 +1891,10 @@ pub mod serde_bincode_compat { Transaction::Eip1559(tx) => Self::Eip1559(tx.into()), Transaction::Eip4844(tx) => Self::Eip4844(tx.into_owned()), Transaction::Eip7702(tx) => Self::Eip7702(tx.into()), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Transaction::Deposit(tx) => Self::Deposit(tx.into()), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Transaction::L1Message(tx) => Self::L1Message(tx.into_owned()), } } } diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 2bd344ea2a17..ea9e91455ed4 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -69,9 +69,12 @@ impl PooledTransactionsElement { } // Not supported because missing blob sidecar tx @ TransactionSigned { transaction: Transaction::Eip4844(_), .. } => Err(tx), - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] // Not supported because deposit transactions are never pooled tx @ TransactionSigned { transaction: Transaction::Deposit(_), .. } => Err(tx), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + // Not supported because l1 message transactions are never pooled + tx @ TransactionSigned { transaction: Transaction::L1Message(_), .. } => Err(tx), } } @@ -384,8 +387,10 @@ impl Decodable2718 for PooledTransactionsElement { )), Transaction::Eip1559(tx) => Ok(Self::Eip1559( Signed::new_unchecked(tx, typed_tx.signature, hash))), Transaction::Eip7702(tx) => Ok(Self::Eip7702( Signed::new_unchecked(tx, typed_tx.signature, hash))), - #[cfg(feature = "optimism")] - Transaction::Deposit(_) => Err(RlpError::Custom("Optimism deposit transaction cannot be decoded to PooledTransactionsElement").into()) + #[cfg(all(feature = "optimism", not(feature = "scroll")))] + Transaction::Deposit(_) => Err(RlpError::Custom("Optimism deposit transaction cannot be decoded to PooledTransactionsElement").into()), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Transaction::L1Message(_) => Err(RlpError::Custom("Scroll L1 message transaction cannot be decoded to PooledTransactionsElement").into()) } } } diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 784a976ab792..6dc7a1d16a9b 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -68,9 +68,13 @@ pub enum TxType { #[display("eip7702 (4)")] Eip7702 = 4_isize, /// Optimism Deposit transaction. - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] #[display("deposit (126)")] Deposit = 126_isize, + /// Scroll L1 message transaction. + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + #[display("l1 message (126)")] + L1Message = 126_isize, } impl TxType { @@ -82,8 +86,10 @@ impl TxType { match self { Self::Legacy => false, Self::Eip2930 | Self::Eip1559 | Self::Eip4844 | Self::Eip7702 => true, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit => false, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message => false, } } } @@ -131,8 +137,10 @@ impl From for u8 { TxType::Eip1559 => EIP1559_TX_TYPE_ID, TxType::Eip4844 => EIP4844_TX_TYPE_ID, TxType::Eip7702 => EIP7702_TX_TYPE_ID, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] TxType::Deposit => op_alloy_consensus::DEPOSIT_TX_TYPE_ID, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + TxType::L1Message => L1_MESSAGE_TX_TYPE_ID, } } } @@ -147,11 +155,16 @@ impl TryFrom for TxType { type Error = &'static str; fn try_from(value: u8) -> Result { - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] if value == Self::Deposit { return Ok(Self::Deposit) } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + if value == Self::L1Message { + return Ok(Self::L1Message) + } + if value == Self::Legacy { return Ok(Self::Legacy) } else if value == Self::Eip2930 { @@ -205,11 +218,16 @@ impl reth_codecs::Compact for TxType { buf.put_u8(EIP7702_TX_TYPE_ID); COMPACT_EXTENDED_IDENTIFIER_FLAG } - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit => { buf.put_u8(op_alloy_consensus::DEPOSIT_TX_TYPE_ID); COMPACT_EXTENDED_IDENTIFIER_FLAG } + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message => { + buf.put_u8(L1_MESSAGE_TX_TYPE_ID); + COMPACT_EXTENDED_IDENTIFIER_FLAG + } } } @@ -228,8 +246,10 @@ impl reth_codecs::Compact for TxType { match extended_identifier { EIP4844_TX_TYPE_ID => Self::Eip4844, EIP7702_TX_TYPE_ID => Self::Eip7702, - #[cfg(feature = "optimism")] + #[cfg(all(feature = "optimism", not(feature = "scroll")))] op_alloy_consensus::DEPOSIT_TX_TYPE_ID => Self::Deposit, + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + L1_MESSAGE_TX_TYPE_ID => Self::L1Message, _ => panic!("Unsupported TxType identifier: {extended_identifier}"), } } @@ -292,9 +312,13 @@ mod tests { #[case(U64::from(EIP4844_TX_TYPE_ID), Ok(TxType::Eip4844))] #[case(U64::from(EIP7702_TX_TYPE_ID), Ok(TxType::Eip7702))] #[cfg_attr( - feature = "optimism", + all(feature = "optimism", not(feature = "scroll")), case(U64::from(op_alloy_consensus::DEPOSIT_TX_TYPE_ID), Ok(TxType::Deposit)) )] + #[cfg_attr( + all(feature = "scroll", not(feature = "optimism")), + case(U64::from(L1_MESSAGE_TX_TYPE_ID), Ok(TxType::L1Message)) + )] #[case(U64::MAX, Err("invalid tx type"))] fn test_u64_to_tx_type(#[case] input: U64, #[case] expected: Result) { let tx_type_result = TxType::try_from(input); @@ -307,7 +331,8 @@ mod tests { #[case(TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])] #[case(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID])] #[case(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] - #[cfg_attr(feature = "optimism", case(TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![op_alloy_consensus::DEPOSIT_TX_TYPE_ID]))] + #[cfg_attr(all(feature = "optimism", not(feature = "scroll")), case(TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![op_alloy_consensus::DEPOSIT_TX_TYPE_ID]))] + #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(TxType::L1Message, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![L1_MESSAGE_TX_TYPE_ID]))] fn test_txtype_to_compact( #[case] tx_type: TxType, #[case] expected_identifier: usize, @@ -326,7 +351,8 @@ mod tests { #[case(TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])] #[case(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID])] #[case(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] - #[cfg_attr(feature = "optimism", case(TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![op_alloy_consensus::DEPOSIT_TX_TYPE_ID]))] + #[cfg_attr(all(feature = "optimism", not(feature = "scroll")), case(TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![op_alloy_consensus::DEPOSIT_TX_TYPE_ID]))] + #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(TxType::L1Message, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![L1_MESSAGE_TX_TYPE_ID]))] fn test_txtype_from_compact( #[case] expected_type: TxType, #[case] identifier: usize, @@ -345,7 +371,8 @@ mod tests { #[case(&[EIP4844_TX_TYPE_ID], Ok(TxType::Eip4844))] #[case(&[EIP7702_TX_TYPE_ID], Ok(TxType::Eip7702))] #[case(&[u8::MAX], Err(alloy_rlp::Error::InputTooShort))] - #[cfg_attr(feature = "optimism", case(&[op_alloy_consensus::DEPOSIT_TX_TYPE_ID], Ok(TxType::Deposit)))] + #[cfg_attr(all(feature = "optimism", not(feature = "scroll")), case(&[op_alloy_consensus::DEPOSIT_TX_TYPE_ID], Ok(TxType::Deposit)))] + #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(&[L1_MESSAGE_TX_TYPE_ID], Ok(TxType::L1Message)))] fn decode_tx_type(#[case] input: &[u8], #[case] expected: Result) { let tx_type_result = TxType::decode(&mut &input[..]); assert_eq!(tx_type_result, expected) From 5a522412af0e32606d5e5ec8d1c50b792a32abad Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Thu, 21 Nov 2024 18:32:05 +0100 Subject: [PATCH 03/11] propagate scroll feature flag in optimism crates for conditional compilation Signed-off-by: Gregory Edison --- crates/optimism/bin/Cargo.toml | 2 ++ crates/optimism/bin/src/lib.rs | 6 ++---- crates/optimism/bin/src/main.rs | 6 ++---- crates/optimism/cli/src/lib.rs | 6 ++---- crates/optimism/consensus/Cargo.toml | 1 + crates/optimism/consensus/src/lib.rs | 3 ++- crates/optimism/evm/src/lib.rs | 6 ++---- crates/optimism/node/src/lib.rs | 6 ++---- crates/optimism/node/tests/e2e/main.rs | 2 +- crates/optimism/node/tests/it/main.rs | 4 ++-- crates/optimism/payload/Cargo.toml | 2 +- crates/optimism/payload/src/lib.rs | 6 ++---- crates/optimism/rpc/src/lib.rs | 6 ++---- 13 files changed, 23 insertions(+), 33 deletions(-) diff --git a/crates/optimism/bin/Cargo.toml b/crates/optimism/bin/Cargo.toml index efbea77454cc..1c16c8151179 100644 --- a/crates/optimism/bin/Cargo.toml +++ b/crates/optimism/bin/Cargo.toml @@ -59,6 +59,8 @@ min-info-logs = ["tracing/release_max_level_info"] min-debug-logs = ["tracing/release_max_level_debug"] min-trace-logs = ["tracing/release_max_level_trace"] +scroll = [] + [[bin]] name = "op-reth" path = "src/main.rs" diff --git a/crates/optimism/bin/src/lib.rs b/crates/optimism/bin/src/lib.rs index 3e9550949c1d..b3e274e678f5 100644 --- a/crates/optimism/bin/src/lib.rs +++ b/crates/optimism/bin/src/lib.rs @@ -24,11 +24,9 @@ issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -// The `optimism` feature must be enabled to use this crate. -#![cfg(feature = "optimism")] -// Don't use the crate if `scroll` feature is used. #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] -#![cfg(not(feature = "scroll"))] +// The `optimism` feature must be enabled to use this crate. +#![cfg(all(feature = "optimism", not(feature = "scroll")))] /// Re-exported from `reth_optimism_cli`. pub mod cli { diff --git a/crates/optimism/bin/src/main.rs b/crates/optimism/bin/src/main.rs index 7ba70272f77d..4fb016b34757 100644 --- a/crates/optimism/bin/src/main.rs +++ b/crates/optimism/bin/src/main.rs @@ -1,9 +1,7 @@ #![allow(missing_docs, rustdoc::missing_crate_level_docs)] -// The `optimism` feature must be enabled to use this crate. -#![cfg(feature = "optimism")] -// Don't use the crate if `scroll` feature is used. #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] -#![cfg(not(feature = "scroll"))] +// The `optimism` feature must be enabled to use this crate. +#![cfg(all(feature = "optimism", not(feature = "scroll")))] use clap::Parser; use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher}; diff --git a/crates/optimism/cli/src/lib.rs b/crates/optimism/cli/src/lib.rs index b02c128cbf33..900d4ddf4c99 100644 --- a/crates/optimism/cli/src/lib.rs +++ b/crates/optimism/cli/src/lib.rs @@ -7,11 +7,9 @@ )] #![cfg_attr(all(not(test), feature = "optimism"), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -// The `optimism` feature must be enabled to use this crate. -#![cfg(feature = "optimism")] -// Don't use the crate if `scroll` feature is used. #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] -#![cfg(not(feature = "scroll"))] +// The `optimism` feature must be enabled to use this crate. +#![cfg(all(feature = "optimism", not(feature = "scroll")))] /// Optimism chain specification parser. pub mod chainspec; diff --git a/crates/optimism/consensus/Cargo.toml b/crates/optimism/consensus/Cargo.toml index 0dffceaddca9..bfe2e3d52665 100644 --- a/crates/optimism/consensus/Cargo.toml +++ b/crates/optimism/consensus/Cargo.toml @@ -36,3 +36,4 @@ reth-optimism-chainspec.workspace = true [features] optimism = ["reth-primitives/optimism"] +scroll = [] diff --git a/crates/optimism/consensus/src/lib.rs b/crates/optimism/consensus/src/lib.rs index e8b7959dd277..f0468abaef5a 100644 --- a/crates/optimism/consensus/src/lib.rs +++ b/crates/optimism/consensus/src/lib.rs @@ -6,8 +6,9 @@ issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] // The `optimism` feature must be enabled to use this crate. -#![cfg(feature = "optimism")] +#![cfg(all(feature = "optimism", not(feature = "scroll")))] use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_primitives::{B64, U256}; diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index 78aa706eaf6f..661696aedd17 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -7,11 +7,9 @@ )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(feature = "std"), no_std)] -// The `optimism` feature must be enabled to use this crate. -#![cfg(feature = "optimism")] -// Don't use the crate if `scroll` feature is used. #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] -#![cfg(not(feature = "scroll"))] +// The `optimism` feature must be enabled to use this crate. +#![cfg(all(feature = "optimism", not(feature = "scroll")))] extern crate alloc; diff --git a/crates/optimism/node/src/lib.rs b/crates/optimism/node/src/lib.rs index 8bf8225bdef7..f228ae1fa2fd 100644 --- a/crates/optimism/node/src/lib.rs +++ b/crates/optimism/node/src/lib.rs @@ -6,11 +6,9 @@ issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -// The `optimism` feature must be enabled to use this crate. -#![cfg(feature = "optimism")] -// Don't use the crate if `scroll` feature is used. #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] -#![cfg(not(feature = "scroll"))] +// The `optimism` feature must be enabled to use this crate. +#![cfg(all(feature = "optimism", not(feature = "scroll")))] /// CLI argument parsing for the optimism node. pub mod args; diff --git a/crates/optimism/node/tests/e2e/main.rs b/crates/optimism/node/tests/e2e/main.rs index b3143d7c40ba..d0c12c52cd61 100644 --- a/crates/optimism/node/tests/e2e/main.rs +++ b/crates/optimism/node/tests/e2e/main.rs @@ -3,7 +3,7 @@ #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] #![cfg(not(feature = "scroll"))] -#[cfg(feature = "optimism")] +#[cfg(all(feature = "optimism", not(feature = "scroll")))] mod p2p; const fn main() {} diff --git a/crates/optimism/node/tests/it/main.rs b/crates/optimism/node/tests/it/main.rs index 2bfdeffc1c4a..6ac5cf6cf1c6 100644 --- a/crates/optimism/node/tests/it/main.rs +++ b/crates/optimism/node/tests/it/main.rs @@ -3,10 +3,10 @@ #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] #![cfg(not(feature = "scroll"))] -#[cfg(feature = "optimism")] +#[cfg(all(feature = "optimism", not(feature = "scroll")))] mod builder; -#[cfg(feature = "optimism")] +#[cfg(all(feature = "optimism", not(feature = "scroll")))] mod priority; const fn main() {} diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index 8873da14605e..b73dcfc5926f 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -60,4 +60,4 @@ optimism = [ "reth-execution-types/optimism", "reth-optimism-consensus/optimism" ] -scroll = [] \ No newline at end of file +scroll = [] diff --git a/crates/optimism/payload/src/lib.rs b/crates/optimism/payload/src/lib.rs index ee1f0a81dcee..ab7f9897bc83 100644 --- a/crates/optimism/payload/src/lib.rs +++ b/crates/optimism/payload/src/lib.rs @@ -8,11 +8,9 @@ #![cfg_attr(all(not(test), feature = "optimism"), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![allow(clippy::useless_let_if_seq)] -// The `optimism` feature must be enabled to use this crate. -#![cfg(feature = "optimism")] -// Don't use the crate if `scroll` feature is used. #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] -#![cfg(not(feature = "scroll"))] +// The `optimism` feature must be enabled to use this crate. +#![cfg(all(feature = "optimism", not(feature = "scroll")))] pub mod builder; pub use builder::OpPayloadBuilder; diff --git a/crates/optimism/rpc/src/lib.rs b/crates/optimism/rpc/src/lib.rs index d8ee748783b0..0f925459abab 100644 --- a/crates/optimism/rpc/src/lib.rs +++ b/crates/optimism/rpc/src/lib.rs @@ -7,11 +7,9 @@ )] #![cfg_attr(all(not(test), feature = "optimism"), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -// The `optimism` feature must be enabled to use this crate. -#![cfg(feature = "optimism")] -// Don't use the crate if `scroll` feature is used. #![cfg_attr(feature = "scroll", allow(unused_crate_dependencies))] -#![cfg(not(feature = "scroll"))] +// The `optimism` feature must be enabled to use this crate. +#![cfg(all(feature = "optimism", not(feature = "scroll")))] pub mod error; pub mod eth; From 72f3fa47e135eadbc34f23053ae14af99b1b3a23 Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Thu, 21 Nov 2024 19:07:15 +0100 Subject: [PATCH 04/11] nit fixes Signed-off-by: Gregory Edison --- crates/primitives/src/alloy_compat.rs | 2 +- crates/scroll/primitives/src/l1_transaction.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index 90c9f4e55450..f190316bcc8e 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -341,7 +341,7 @@ mod tests { assert_eq!(l1_message_tx.value, U256::ZERO); assert_eq!(l1_message_tx.sender, address!("7885bcbd5cecef1336b5300fb5186a12ddd8c478")); } else { - panic!("Expected Deposit transaction"); + panic!("Expected L1 message transaction"); } } } diff --git a/crates/scroll/primitives/src/l1_transaction.rs b/crates/scroll/primitives/src/l1_transaction.rs index 34a942183990..ec2cd1174271 100644 --- a/crates/scroll/primitives/src/l1_transaction.rs +++ b/crates/scroll/primitives/src/l1_transaction.rs @@ -112,7 +112,7 @@ impl TxL1Message { /// Encode the fields of the transaction without a RLP header. /// - pub(crate) fn rlp_encode_fields(&self, out: &mut dyn BufMut) { + fn rlp_encode_fields(&self, out: &mut dyn BufMut) { self.queue_index.encode(out); self.gas_limit.encode(out); self.to.encode(out); From b1c64659b839441c6f34a338b50223a48110e1f7 Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Fri, 22 Nov 2024 09:42:48 +0100 Subject: [PATCH 05/11] fix lints Signed-off-by: Gregory Edison --- Cargo.lock | 1 + crates/scroll/primitives/Cargo.toml | 14 ++++++++++++-- crates/scroll/primitives/src/l1_transaction.rs | 9 +++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ef6c3a8ec9f..3f292d96f213 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8612,6 +8612,7 @@ dependencies = [ "reth-codecs", "reth-ethereum-forks", "reth-primitives-traits", + "reth-scroll-primitives", "reth-scroll-revm", "reth-static-file-types", "reth-testing-utils", diff --git a/crates/scroll/primitives/Cargo.toml b/crates/scroll/primitives/Cargo.toml index 98c33b844077..09c018922711 100644 --- a/crates/scroll/primitives/Cargo.toml +++ b/crates/scroll/primitives/Cargo.toml @@ -53,14 +53,24 @@ default = [ arbitrary = [ "dep:arbitrary", "alloy-primitives/arbitrary", - "reth-codecs/arbitrary" + "alloy-consensus/arbitrary", + "alloy-eips/arbitrary", + "alloy-serde/arbitrary", + "reth-codecs/arbitrary" ] reth-codec = [ "dep:reth-codecs", "dep:reth-codecs-derive", "std" ] -serde = ["alloy-primitives/serde"] +serde = [ + "alloy-primitives/serde", + "alloy-consensus/serde", + "alloy-eips/serde", + "bytes/serde", + "rand/serde", + "reth-codecs/serde" +] std = [ "serde/std", "alloy-primitives/std", diff --git a/crates/scroll/primitives/src/l1_transaction.rs b/crates/scroll/primitives/src/l1_transaction.rs index ec2cd1174271..6597553e73b3 100644 --- a/crates/scroll/primitives/src/l1_transaction.rs +++ b/crates/scroll/primitives/src/l1_transaction.rs @@ -7,9 +7,9 @@ use alloy_primitives::{ }; use alloy_rlp::Decodable; use bytes::BufMut; -use reth_codecs::Compact; -use reth_codecs_derive::add_arbitrary_tests; use serde::{Deserialize, Serialize}; +#[cfg(any(test, feature = "reth-codec"))] +use {reth_codecs::Compact, reth_codecs_derive::add_arbitrary_tests}; const L1_MESSAGE_TRANSACTION_TYPE: u8 = 0x7E; @@ -24,11 +24,12 @@ const L1_MESSAGE_TRANSACTION_TYPE: u8 = 0x7E; /// types require optional serialization for RPC compatibility. Since `TxL1Message` doesn't /// contain optionally serializable fields, no `bincode` compatible bridge implementation is /// required. -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Compact)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(any(test, feature = "serde"), derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(any(test, feature = "serde"), serde(rename_all = "camelCase"))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[add_arbitrary_tests(compact, rlp)] +#[cfg_attr(any(test, feature = "reth-codec"), derive(Compact))] +#[cfg_attr(any(test, feature = "reth-codec"), add_arbitrary_tests(compact, rlp))] pub struct TxL1Message { /// The queue index of the message in the L1 contract queue. #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] From 1fdea5c8e86a66a076e93e0970b09eb85c2ef6c1 Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Tue, 26 Nov 2024 11:57:09 +0100 Subject: [PATCH 06/11] rebasing changes Signed-off-by: Gregory Edison --- Cargo.lock | 28 ++++++++++++++-------------- crates/optimism/bin/Cargo.toml | 2 -- crates/primitives-traits/Cargo.toml | 2 +- crates/scroll/revm/Cargo.toml | 3 ++- crates/storage/provider/Cargo.toml | 1 + crates/trie/db/Cargo.toml | 3 ++- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f292d96f213..c52f872d2449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ "derive_more 1.0.0", "foldhash", "getrandom 0.2.15", - "hashbrown 0.15.2", + "hashbrown 0.15.1", "hex-literal", "indexmap 2.6.0", "itoa", @@ -3569,9 +3569,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" dependencies = [ "allocator-api2", "equivalent", @@ -4123,7 +4123,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.1", "serde", ] @@ -4299,9 +4299,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" [[package]] name = "jni" @@ -4606,9 +4606,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.165" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "libloading" @@ -4779,7 +4779,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.1", ] [[package]] @@ -4883,9 +4883,9 @@ dependencies = [ [[package]] name = "metrics-process" -version = "2.4.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a82c8add4382f29a122fa64fff1891453ed0f6b2867d971e7d60cb8dfa322ff" +checksum = "57ca8ecd85575fbb143b2678cb123bb818779391ec0f745b1c4a9dbabadde407" dependencies = [ "libc", "libproc", @@ -4905,7 +4905,7 @@ checksum = "15b482df36c13dd1869d73d14d28cd4855fbd6cfc32294bee109908a9f4a4ed7" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.2", + "hashbrown 0.15.1", "indexmap 2.6.0", "metrics", "ordered-float", @@ -11224,9 +11224,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", diff --git a/crates/optimism/bin/Cargo.toml b/crates/optimism/bin/Cargo.toml index 1c16c8151179..efbea77454cc 100644 --- a/crates/optimism/bin/Cargo.toml +++ b/crates/optimism/bin/Cargo.toml @@ -59,8 +59,6 @@ min-info-logs = ["tracing/release_max_level_info"] min-debug-logs = ["tracing/release_max_level_debug"] min-trace-logs = ["tracing/release_max_level_trace"] -scroll = [] - [[bin]] name = "op-reth" path = "src/main.rs" diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index 27aa92f4edbb..87a96bec480e 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -97,9 +97,9 @@ serde = [ "bytes/serde", "rand/serde", "reth-codecs?/serde", - "revm-primitives/serde", "roaring/serde", "revm-primitives/serde", + "reth-scroll-primitives?/serde" ] reth-codec = [ "dep:reth-codecs", diff --git a/crates/scroll/revm/Cargo.toml b/crates/scroll/revm/Cargo.toml index b43263667797..7f1d25b9e9a2 100644 --- a/crates/scroll/revm/Cargo.toml +++ b/crates/scroll/revm/Cargo.toml @@ -33,7 +33,8 @@ c-kzg = ["revm/c-kzg"] optimism = ["revm/optimism"] serde = [ "revm/serde", - "serde/std" + "serde/std", + "reth-scroll-primitives/serde" ] scroll = [] test-utils = ["revm/test-utils"] diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index 9db25d5ee09b..6ca1e9c33efd 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -118,6 +118,7 @@ serde = [ "reth-codecs/serde", "reth-optimism-primitives?/serde", "reth-primitives-traits/serde", + "reth-scroll-primitives?/serde" ] test-utils = [ "reth-db/test-utils", diff --git a/crates/trie/db/Cargo.toml b/crates/trie/db/Cargo.toml index ef9517fb8b95..533a49cb48cb 100644 --- a/crates/trie/db/Cargo.toml +++ b/crates/trie/db/Cargo.toml @@ -75,7 +75,8 @@ serde = [ "alloy-consensus/serde", "alloy-primitives/serde", "revm/serde", - "similar-asserts/serde" + "similar-asserts/serde", + "reth-scroll-primitives/serde" ] test-utils = [ "triehash", From 3173693e893ced75606da274e2174750850c5c9a Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Tue, 26 Nov 2024 11:57:34 +0100 Subject: [PATCH 07/11] move `L1_MESSAGE_TRANSACTION_TYPE` to reth_scroll_primitives Signed-off-by: Gregory Edison --- crates/primitives/src/receipt.rs | 2 +- crates/primitives/src/transaction/mod.rs | 4 +++- crates/primitives/src/transaction/tx_type.rs | 17 ++++++++++------- crates/scroll/primitives/src/l1_transaction.rs | 3 ++- crates/scroll/primitives/src/lib.rs | 4 +++- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 96c01d7aaeed..53adb85eda05 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -533,7 +533,7 @@ impl ReceiptWithBloomEncoder<'_> { } #[cfg(all(feature = "scroll", not(feature = "optimism")))] TxType::L1Message => { - out.put_u8(crate::transaction::L1_MESSAGE_TX_TYPE_ID); + out.put_u8(reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE); } } out.put_slice(payload.as_ref()); diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index eba6cadd5de8..f60f649ef251 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -571,7 +571,7 @@ impl reth_codecs::Compact for Transaction { (Self::Deposit(tx), buf) } #[cfg(all(feature = "scroll", not(feature = "optimism")))] - tx_type::L1_MESSAGE_TX_TYPE_ID => { + reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE => { let (tx, buf) = TxL1Message::from_compact(buf, buf.len()); (Self::L1Message(tx), buf) } @@ -685,6 +685,8 @@ impl alloy_consensus::Transaction for Transaction { Self::Eip7702(tx) => tx.max_fee_per_blob_gas(), #[cfg(all(feature = "optimism", not(feature = "scroll")))] Self::Deposit(tx) => tx.max_fee_per_blob_gas(), + #[cfg(all(feature = "scroll", not(feature = "optimism")))] + Self::L1Message(tx) => tx.max_fee_per_blob_gas(), } } diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 6dc7a1d16a9b..9a2b0119124c 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -140,7 +140,7 @@ impl From for u8 { #[cfg(all(feature = "optimism", not(feature = "scroll")))] TxType::Deposit => op_alloy_consensus::DEPOSIT_TX_TYPE_ID, #[cfg(all(feature = "scroll", not(feature = "optimism")))] - TxType::L1Message => L1_MESSAGE_TX_TYPE_ID, + TxType::L1Message => reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE, } } } @@ -225,7 +225,7 @@ impl reth_codecs::Compact for TxType { } #[cfg(all(feature = "scroll", not(feature = "optimism")))] Self::L1Message => { - buf.put_u8(L1_MESSAGE_TX_TYPE_ID); + buf.put_u8(reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE); COMPACT_EXTENDED_IDENTIFIER_FLAG } } @@ -249,7 +249,7 @@ impl reth_codecs::Compact for TxType { #[cfg(all(feature = "optimism", not(feature = "scroll")))] op_alloy_consensus::DEPOSIT_TX_TYPE_ID => Self::Deposit, #[cfg(all(feature = "scroll", not(feature = "optimism")))] - L1_MESSAGE_TX_TYPE_ID => Self::L1Message, + reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE => Self::L1Message, _ => panic!("Unsupported TxType identifier: {extended_identifier}"), } } @@ -317,7 +317,10 @@ mod tests { )] #[cfg_attr( all(feature = "scroll", not(feature = "optimism")), - case(U64::from(L1_MESSAGE_TX_TYPE_ID), Ok(TxType::L1Message)) + case( + U64::from(reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE), + Ok(TxType::L1Message) + ) )] #[case(U64::MAX, Err("invalid tx type"))] fn test_u64_to_tx_type(#[case] input: U64, #[case] expected: Result) { @@ -332,7 +335,7 @@ mod tests { #[case(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID])] #[case(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] #[cfg_attr(all(feature = "optimism", not(feature = "scroll")), case(TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![op_alloy_consensus::DEPOSIT_TX_TYPE_ID]))] - #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(TxType::L1Message, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![L1_MESSAGE_TX_TYPE_ID]))] + #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(TxType::L1Message, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE]))] fn test_txtype_to_compact( #[case] tx_type: TxType, #[case] expected_identifier: usize, @@ -352,7 +355,7 @@ mod tests { #[case(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID])] #[case(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] #[cfg_attr(all(feature = "optimism", not(feature = "scroll")), case(TxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![op_alloy_consensus::DEPOSIT_TX_TYPE_ID]))] - #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(TxType::L1Message, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![L1_MESSAGE_TX_TYPE_ID]))] + #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(TxType::L1Message, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE]))] fn test_txtype_from_compact( #[case] expected_type: TxType, #[case] identifier: usize, @@ -372,7 +375,7 @@ mod tests { #[case(&[EIP7702_TX_TYPE_ID], Ok(TxType::Eip7702))] #[case(&[u8::MAX], Err(alloy_rlp::Error::InputTooShort))] #[cfg_attr(all(feature = "optimism", not(feature = "scroll")), case(&[op_alloy_consensus::DEPOSIT_TX_TYPE_ID], Ok(TxType::Deposit)))] - #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(&[L1_MESSAGE_TX_TYPE_ID], Ok(TxType::L1Message)))] + #[cfg_attr(all(feature = "scroll", not(feature = "optimism")), case(&[reth_scroll_primitives::L1_MESSAGE_TRANSACTION_TYPE], Ok(TxType::L1Message)))] fn decode_tx_type(#[case] input: &[u8], #[case] expected: Result) { let tx_type_result = TxType::decode(&mut &input[..]); assert_eq!(tx_type_result, expected) diff --git a/crates/scroll/primitives/src/l1_transaction.rs b/crates/scroll/primitives/src/l1_transaction.rs index 6597553e73b3..bfa099fcc243 100644 --- a/crates/scroll/primitives/src/l1_transaction.rs +++ b/crates/scroll/primitives/src/l1_transaction.rs @@ -11,7 +11,8 @@ use serde::{Deserialize, Serialize}; #[cfg(any(test, feature = "reth-codec"))] use {reth_codecs::Compact, reth_codecs_derive::add_arbitrary_tests}; -const L1_MESSAGE_TRANSACTION_TYPE: u8 = 0x7E; +/// L1 message transaction type id. +pub const L1_MESSAGE_TRANSACTION_TYPE: u8 = 0x7E; /// A message transaction sent from the settlement layer to the L2 for execution. /// diff --git a/crates/scroll/primitives/src/lib.rs b/crates/scroll/primitives/src/lib.rs index 5318d3c4b16e..2f2796db6e23 100644 --- a/crates/scroll/primitives/src/lib.rs +++ b/crates/scroll/primitives/src/lib.rs @@ -8,7 +8,9 @@ mod execution_context; pub use account_extension::AccountExtension; mod account_extension; -pub use l1_transaction::{ScrollL1MessageTransactionFields, TxL1Message}; +pub use l1_transaction::{ + ScrollL1MessageTransactionFields, TxL1Message, L1_MESSAGE_TRANSACTION_TYPE, +}; pub mod l1_transaction; pub use poseidon::{hash_code, POSEIDON_EMPTY}; From 675c02722bd605615006538f5f1c9e6f7a2df94a Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Tue, 26 Nov 2024 17:23:09 +0100 Subject: [PATCH 08/11] feature gate Compact derive Signed-off-by: Gregory Edison --- crates/scroll/primitives/Cargo.toml | 3 ++- crates/scroll/primitives/src/account_extension.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/scroll/primitives/Cargo.toml b/crates/scroll/primitives/Cargo.toml index 09c018922711..acbbdf3dd88f 100644 --- a/crates/scroll/primitives/Cargo.toml +++ b/crates/scroll/primitives/Cargo.toml @@ -28,7 +28,7 @@ poseidon-bn254 = { workspace = true, features = ["bn254"] } # required by reth-codecs bytes.workspace = true -modular-bitfield.workspace = true +modular-bitfield = { workspace = true, optional = true } serde.workspace = true # misc @@ -61,6 +61,7 @@ arbitrary = [ reth-codec = [ "dep:reth-codecs", "dep:reth-codecs-derive", + "modular-bitfield", "std" ] serde = [ diff --git a/crates/scroll/primitives/src/account_extension.rs b/crates/scroll/primitives/src/account_extension.rs index c48181f9ea21..6c732c18c38f 100644 --- a/crates/scroll/primitives/src/account_extension.rs +++ b/crates/scroll/primitives/src/account_extension.rs @@ -1,13 +1,13 @@ use crate::{hash_code, POSEIDON_EMPTY}; use alloy_primitives::B256; -use reth_codecs::Compact; use serde::{Deserialize, Serialize}; /// The extension for a Scroll account's representation in storage. /// /// The extension is used in order to maintain backwards compatibility if more fields need to be /// added to the account (see [reth codecs](reth_codecs::test_utils) for details). -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize, Compact)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "reth-codec", derive(reth_codecs::Compact))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct AccountExtension { /// Size in bytes of the account's bytecode. From f761a1186dff95ccf67c7e398ca6193bd8c9004e Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Thu, 28 Nov 2024 10:38:30 +0100 Subject: [PATCH 09/11] fix lints Signed-off-by: Gregory Edison --- crates/revm/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index ecccb30475e6..40c719ff734a 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -63,6 +63,7 @@ serde = [ "alloy-primitives/serde", "alloy-consensus/serde", "reth-primitives-traits/serde", + "reth-scroll-primitives/serde" ] scroll = [ "reth-scroll-primitives", From 779f7d3c777aba43ed99348801ad9585b85be6c9 Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Thu, 28 Nov 2024 10:55:56 +0100 Subject: [PATCH 10/11] reformat manifest Signed-off-by: Gregory Edison --- crates/primitives/src/transaction/mod.rs | 2 +- crates/revm/Cargo.toml | 2 +- crates/scroll/primitives/Cargo.toml | 60 ++++++++++++------------ 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index f60f649ef251..6ae94ad1bd32 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1466,7 +1466,7 @@ impl reth_primitives_traits::FillTxEnv for TransactionSigned { #[cfg(all(feature = "optimism", not(feature = "scroll")))] Transaction::Deposit(_) => {} #[cfg(all(feature = "scroll", not(feature = "optimism")))] - Transaction::L1Message(_) => {} // TODO (scroll): should this be something? + Transaction::L1Message(_) => {} } } } diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 40c719ff734a..ede5c78f45bf 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -63,7 +63,7 @@ serde = [ "alloy-primitives/serde", "alloy-consensus/serde", "reth-primitives-traits/serde", - "reth-scroll-primitives/serde" + "reth-scroll-primitives?/serde" ] scroll = [ "reth-scroll-primitives", diff --git a/crates/scroll/primitives/Cargo.toml b/crates/scroll/primitives/Cargo.toml index acbbdf3dd88f..4a0230276415 100644 --- a/crates/scroll/primitives/Cargo.toml +++ b/crates/scroll/primitives/Cargo.toml @@ -47,40 +47,40 @@ test-fuzz.workspace = true [features] default = [ - "reth-codec", - "std" + "reth-codec", + "std" +] +std = [ + "serde/std", + "alloy-primitives/std", + "reth-codecs/std", + "alloy-consensus/std", + "alloy-eips/std", + "alloy-rlp/std", + "alloy-serde/std", + "bytes/std", + "proptest/std", + "rand/std" ] arbitrary = [ - "dep:arbitrary", - "alloy-primitives/arbitrary", - "alloy-consensus/arbitrary", - "alloy-eips/arbitrary", - "alloy-serde/arbitrary", - "reth-codecs/arbitrary" + "dep:arbitrary", + "alloy-primitives/arbitrary", + "alloy-consensus/arbitrary", + "alloy-eips/arbitrary", + "alloy-serde/arbitrary", + "reth-codecs/arbitrary" ] reth-codec = [ - "dep:reth-codecs", - "dep:reth-codecs-derive", - "modular-bitfield", - "std" + "dep:reth-codecs", + "dep:reth-codecs-derive", + "modular-bitfield", + "std" ] serde = [ - "alloy-primitives/serde", - "alloy-consensus/serde", - "alloy-eips/serde", - "bytes/serde", - "rand/serde", - "reth-codecs/serde" -] -std = [ - "serde/std", - "alloy-primitives/std", - "reth-codecs/std", - "alloy-consensus/std", - "alloy-eips/std", - "alloy-rlp/std", - "alloy-serde/std", - "bytes/std", - "proptest/std", - "rand/std" + "alloy-primitives/serde", + "alloy-consensus/serde", + "alloy-eips/serde", + "bytes/serde", + "rand/serde", + "reth-codecs/serde" ] From 91674c28c14b8a58e3dbfe665da8d87dec33f2e9 Mon Sep 17 00:00:00 2001 From: Gregory Edison Date: Thu, 28 Nov 2024 15:11:39 +0100 Subject: [PATCH 11/11] fix: answer comments Signed-off-by: Gregory Edison --- crates/optimism/payload/Cargo.toml | 2 +- crates/primitives/src/transaction/mod.rs | 4 ++-- crates/scroll/primitives/src/l1_transaction.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index b73dcfc5926f..8873da14605e 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -60,4 +60,4 @@ optimism = [ "reth-execution-types/optimism", "reth-optimism-consensus/optimism" ] -scroll = [] +scroll = [] \ No newline at end of file diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 6ae94ad1bd32..e3868b9c1c98 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -425,7 +425,7 @@ impl Transaction { /// Returns true if the transaction is a Scroll L1 messaging transaction. #[cfg(all(feature = "scroll", not(feature = "optimism")))] #[inline] - pub fn is_l1_messaging(&self) -> bool { + pub fn is_l1_message(&self) -> bool { matches!(self, Self::L1Message(_)) } @@ -1741,7 +1741,7 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned { let signature = if transaction.is_deposit() { TxDeposit::signature() } else { signature }; #[cfg(all(feature = "scroll", not(feature = "optimism")))] let signature = - if transaction.is_l1_messaging() { TxL1Message::signature() } else { signature }; + if transaction.is_l1_message() { TxL1Message::signature() } else { signature }; Ok(Self::new_unhashed(transaction, signature)) } diff --git a/crates/scroll/primitives/src/l1_transaction.rs b/crates/scroll/primitives/src/l1_transaction.rs index bfa099fcc243..3f71d1e80754 100644 --- a/crates/scroll/primitives/src/l1_transaction.rs +++ b/crates/scroll/primitives/src/l1_transaction.rs @@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize}; #[cfg(any(test, feature = "reth-codec"))] use {reth_codecs::Compact, reth_codecs_derive::add_arbitrary_tests}; -/// L1 message transaction type id. -pub const L1_MESSAGE_TRANSACTION_TYPE: u8 = 0x7E; +/// L1 message transaction type id, 0x7e in hex. +pub const L1_MESSAGE_TRANSACTION_TYPE: u8 = 126; /// A message transaction sent from the settlement layer to the L2 for execution. ///