diff --git a/Cargo.toml b/Cargo.toml index d2358bbac..0f6a6dbc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,23 +45,23 @@ op-alloy-rpc-jsonrpsee = { version = "0.10.9", path = "crates/rpc-jsonrpsee", de op-alloy-flz = { version = "0.10.9", path = "crates/flz", default-features = false } # Alloy -alloy-eips = { version = "0.11", default-features = false } -alloy-serde = { version = "0.11", default-features = false } -alloy-signer = { version = "0.11", default-features = false } -alloy-network = { version = "0.11", default-features = false } -alloy-provider = { version = "0.11", default-features = false } -alloy-transport = { version = "0.11", default-features = false } -alloy-consensus = { version = "0.11", default-features = false } -alloy-rpc-types-eth = { version = "0.11", default-features = false } -alloy-rpc-types-engine = { version = "0.11", default-features = false } -alloy-network-primitives = { version = "0.11", default-features = false } +alloy-eips = { version = "0.12", default-features = false } +alloy-serde = { version = "0.12", default-features = false } +alloy-signer = { version = "0.12", default-features = false } +alloy-network = { version = "0.12", default-features = false } +alloy-provider = { version = "0.12", default-features = false } +alloy-transport = { version = "0.12", default-features = false } +alloy-consensus = { version = "0.12", default-features = false } +alloy-rpc-types-eth = { version = "0.12", default-features = false } +alloy-rpc-types-engine = { version = "0.12", default-features = false } +alloy-network-primitives = { version = "0.12", default-features = false } # Alloy RLP alloy-rlp = { version = "0.3", default-features = false } # Alloy Core -alloy-sol-types = { version = "0.8.12", default-features = false } -alloy-primitives = { version = "0.8.12", default-features = false } +alloy-sol-types = { version = "0.8.22", default-features = false } +alloy-primitives = { version = "0.8.22", default-features = false } # Serde serde_repr = "0.1" @@ -115,14 +115,14 @@ rstest = "0.24.0" c-kzg = { version = "1.0", default-features = false } k256 = { version = "0.13", default-features = false, features = ["ecdsa"] } -[patch.crates-io] -#alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-network-primitives = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-rpc-types-eth = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-serde = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } -#alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "cfb13aa" } +# [patch.crates-io] +# alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-serde = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-rpc-types-eth = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } +# alloy-network-primitives = { git = "https://github.com/alloy-rs/alloy", rev = "a4e7099" } diff --git a/crates/consensus/Cargo.toml b/crates/consensus/Cargo.toml index 033727781..e8336bdb6 100644 --- a/crates/consensus/Cargo.toml +++ b/crates/consensus/Cargo.toml @@ -48,11 +48,7 @@ alloy-primitives = { workspace = true, features = ["rand", "arbitrary"] } [features] default = ["std"] -std = [ - "alloy-eips/std", - "alloy-consensus/std", - "derive_more/std", -] +std = ["alloy-eips/std", "alloy-consensus/std", "derive_more/std"] alloy-compat = ["serde", "dep:alloy-network", "dep:alloy-rpc-types-eth"] k256 = ["alloy-primitives/k256", "alloy-consensus/k256"] kzg = ["alloy-eips/kzg", "alloy-consensus/kzg", "std"] diff --git a/crates/consensus/src/alloy_compat.rs b/crates/consensus/src/alloy_compat.rs index e729cfa88..a5a0c24b1 100644 --- a/crates/consensus/src/alloy_compat.rs +++ b/crates/consensus/src/alloy_compat.rs @@ -42,9 +42,10 @@ impl TryFrom for OpTxEnvelope { type Error = ConversionError; fn try_from(tx: AnyRpcTransaction) -> Result { - let WithOtherFields { inner: AlloyRpcTransaction { inner, from, .. }, other: _ } = tx; + let WithOtherFields { inner: AlloyRpcTransaction { inner, .. }, other: _ } = tx.0; - match inner { + let from = inner.signer(); + match inner.into_inner() { AnyTxEnvelope::Ethereum(tx) => Self::try_from_eth_envelope(tx).map_err(|_| { ConversionError::Custom("unable to convert from ethereum type".to_string()) }), diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index 8f8d84394..72f98ef05 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -1,6 +1,6 @@ use crate::{OpTxType, OpTypedTransaction, TxDeposit}; use alloy_consensus::{ - transaction::RlpEcdsaTx, Sealable, Sealed, Signed, Transaction, TxEip1559, TxEip2930, + transaction::RlpEcdsaDecodableTx, Sealable, Sealed, Signed, Transaction, TxEip1559, TxEip2930, TxEip7702, TxEnvelope, TxLegacy, Typed2718, }; use alloy_eips::{ @@ -386,7 +386,7 @@ impl OpTxEnvelope { Ok(eth) => { Self::try_from_eth_envelope(eth).map_err(alloy_network::AnyTxEnvelope::Ethereum) } - Err(err) => match err { + Err(err) => match err.into_value() { alloy_network::AnyTxEnvelope::Unknown(unknown) => { let Ok(deposit) = unknown.inner.clone().try_into() else { return Err(alloy_network::AnyTxEnvelope::Unknown(unknown)); diff --git a/crates/consensus/src/transaction/pooled.rs b/crates/consensus/src/transaction/pooled.rs index 9e5ffc7a5..34baf8857 100644 --- a/crates/consensus/src/transaction/pooled.rs +++ b/crates/consensus/src/transaction/pooled.rs @@ -3,7 +3,7 @@ use crate::{OpTxEnvelope, OpTxType}; use alloy_consensus::{ - transaction::{RlpEcdsaTx, TxEip1559, TxEip2930, TxLegacy}, + transaction::{RlpEcdsaDecodableTx, TxEip1559, TxEip2930, TxLegacy}, SignableTransaction, Signed, Transaction, TxEip7702, TxEnvelope, Typed2718, }; use alloy_eips::{ @@ -50,7 +50,7 @@ impl OpPooledTransaction { } /// Reference to transaction hash. Used to identify transaction. - pub const fn hash(&self) -> &TxHash { + pub fn hash(&self) -> &TxHash { match self { Self::Legacy(tx) => tx.hash(), Self::Eip2930(tx) => tx.hash(), diff --git a/crates/consensus/src/transaction/typed.rs b/crates/consensus/src/transaction/typed.rs index b9ac870ea..2d3c347aa 100644 --- a/crates/consensus/src/transaction/typed.rs +++ b/crates/consensus/src/transaction/typed.rs @@ -1,9 +1,9 @@ use crate::{OpTxEnvelope, OpTxType, TxDeposit}; use alloy_consensus::{ - transaction::RlpEcdsaTx, SignableTransaction, Signed, Transaction, TxEip1559, TxEip2930, - TxEip7702, TxLegacy, Typed2718, + transaction::RlpEcdsaEncodableTx, SignableTransaction, Signed, Transaction, TxEip1559, + TxEip2930, TxEip7702, TxLegacy, Typed2718, }; -use alloy_eips::eip2930::AccessList; +use alloy_eips::{eip2930::AccessList, Encodable2718}; use alloy_primitives::{ bytes::BufMut, Address, Bytes, ChainId, PrimitiveSignature as Signature, TxHash, TxKind, B256, }; @@ -351,6 +351,91 @@ impl Transaction for OpTypedTransaction { } } +impl RlpEcdsaEncodableTx for OpTypedTransaction { + // Setting this to zero for enum txs type is alright, as it shouldn't be used. + const DEFAULT_TX_TYPE: u8 = 0; + + fn rlp_encoded_fields_length(&self) -> usize { + match self { + Self::Legacy(tx) => tx.rlp_encoded_fields_length(), + Self::Eip2930(tx) => tx.rlp_encoded_fields_length(), + Self::Eip1559(tx) => tx.rlp_encoded_fields_length(), + Self::Eip7702(tx) => tx.rlp_encoded_fields_length(), + Self::Deposit(tx) => tx.rlp_encoded_fields_length(), + } + } + + fn rlp_encode_fields(&self, out: &mut dyn alloy_rlp::BufMut) { + match self { + Self::Legacy(tx) => tx.rlp_encode_fields(out), + Self::Eip2930(tx) => tx.rlp_encode_fields(out), + Self::Eip1559(tx) => tx.rlp_encode_fields(out), + Self::Eip7702(tx) => tx.rlp_encode_fields(out), + Self::Deposit(tx) => tx.rlp_encode_fields(out), + } + } + + fn eip2718_encode_with_type(&self, signature: &Signature, _ty: u8, out: &mut dyn BufMut) { + match self { + Self::Legacy(tx) => tx.eip2718_encode_with_type(signature, tx.ty(), out), + Self::Eip2930(tx) => tx.eip2718_encode_with_type(signature, tx.ty(), out), + Self::Eip1559(tx) => tx.eip2718_encode_with_type(signature, tx.ty(), out), + Self::Eip7702(tx) => tx.eip2718_encode_with_type(signature, tx.ty(), out), + Self::Deposit(tx) => tx.encode_2718(out), + } + } + + fn eip2718_encode(&self, signature: &Signature, out: &mut dyn BufMut) { + match self { + Self::Legacy(tx) => tx.eip2718_encode(signature, out), + Self::Eip2930(tx) => tx.eip2718_encode(signature, out), + Self::Eip1559(tx) => tx.eip2718_encode(signature, out), + Self::Eip7702(tx) => tx.eip2718_encode(signature, out), + Self::Deposit(tx) => tx.encode_2718(out), + } + } + + fn network_encode_with_type(&self, signature: &Signature, _ty: u8, out: &mut dyn BufMut) { + match self { + Self::Legacy(tx) => tx.network_encode_with_type(signature, tx.ty(), out), + Self::Eip2930(tx) => tx.network_encode_with_type(signature, tx.ty(), out), + Self::Eip1559(tx) => tx.network_encode_with_type(signature, tx.ty(), out), + Self::Eip7702(tx) => tx.network_encode_with_type(signature, tx.ty(), out), + Self::Deposit(tx) => tx.network_encode(out), + } + } + + fn network_encode(&self, signature: &Signature, out: &mut dyn BufMut) { + match self { + Self::Legacy(tx) => tx.network_encode(signature, out), + Self::Eip2930(tx) => tx.network_encode(signature, out), + Self::Eip1559(tx) => tx.network_encode(signature, out), + Self::Eip7702(tx) => tx.network_encode(signature, out), + Self::Deposit(tx) => tx.network_encode(out), + } + } + + fn tx_hash_with_type(&self, signature: &Signature, _ty: u8) -> TxHash { + match self { + Self::Legacy(tx) => tx.tx_hash_with_type(signature, tx.ty()), + Self::Eip2930(tx) => tx.tx_hash_with_type(signature, tx.ty()), + Self::Eip1559(tx) => tx.tx_hash_with_type(signature, tx.ty()), + Self::Eip7702(tx) => tx.tx_hash_with_type(signature, tx.ty()), + Self::Deposit(tx) => tx.tx_hash(), + } + } + + fn tx_hash(&self, signature: &Signature) -> TxHash { + match self { + Self::Legacy(tx) => tx.tx_hash(signature), + Self::Eip2930(tx) => tx.tx_hash(signature), + Self::Eip1559(tx) => tx.tx_hash(signature), + Self::Eip7702(tx) => tx.tx_hash(signature), + Self::Deposit(tx) => tx.tx_hash(), + } + } +} + impl SignableTransaction for OpTypedTransaction { fn set_chain_id(&mut self, chain_id: ChainId) { match self { diff --git a/crates/rpc-types/Cargo.toml b/crates/rpc-types/Cargo.toml index 4ecebc921..2d9a591a6 100644 --- a/crates/rpc-types/Cargo.toml +++ b/crates/rpc-types/Cargo.toml @@ -33,7 +33,7 @@ serde = { workspace = true, features = ["derive"] } # arbitrary arbitrary = { workspace = true, features = ["derive"], optional = true } -derive_more.workspace = true +derive_more = { workspace = true, features = ["as_ref", "deref_mut"] } [dev-dependencies] rand.workspace = true @@ -46,11 +46,11 @@ similar-asserts.workspace = true [features] default = ["std"] std = [ - "alloy-network-primitives/std", - "alloy-eips/std", - "alloy-primitives/std", - "alloy-rpc-types-eth/std", - "op-alloy-consensus/std" + "alloy-network-primitives/std", + "alloy-eips/std", + "alloy-primitives/std", + "alloy-rpc-types-eth/std", + "op-alloy-consensus/std", ] arbitrary = [ "std", @@ -59,10 +59,5 @@ arbitrary = [ "alloy-rpc-types-eth/arbitrary", "op-alloy-consensus/arbitrary", ] -k256 = [ - "alloy-rpc-types-eth/k256", - "op-alloy-consensus/k256", -] -serde = [ - "op-alloy-consensus/serde" -] +k256 = ["alloy-rpc-types-eth/k256", "op-alloy-consensus/k256"] +serde = ["op-alloy-consensus/serde"] diff --git a/crates/rpc-types/src/transaction.rs b/crates/rpc-types/src/transaction.rs index 81504d5b2..aec15ac36 100644 --- a/crates/rpc-types/src/transaction.rs +++ b/crates/rpc-types/src/transaction.rs @@ -167,10 +167,12 @@ mod tx_serde { //! Helper module for serializing and deserializing OP [`Transaction`]. //! //! This is needed because we might need to deserialize the `from` field into both - //! [`alloy_rpc_types_eth::Transaction::from`] and [`op_alloy_consensus::TxDeposit::from`]. + //! [`alloy_consensus::transaction::Recovered::signer`] which resides in + //! [`alloy_rpc_types_eth::Transaction::inner`] and [`op_alloy_consensus::TxDeposit::from`]. //! //! Additionaly, we need similar logic for the `gasPrice` field use super::*; + use alloy_consensus::transaction::Recovered; use serde::de::Error; /// Helper struct which will be flattened into the transaction and will only contain `from` @@ -227,20 +229,23 @@ mod tx_serde { block_number, transaction_index, effective_gas_price, - from, }, deposit_receipt_version, deposit_nonce, } = value; // if inner transaction is a deposit, then don't serialize `from` directly - let from = if matches!(inner, OpTxEnvelope::Deposit(_)) { None } else { Some(from) }; + let from = if matches!(inner.inner(), OpTxEnvelope::Deposit(_)) { + None + } else { + Some(inner.signer()) + }; // if inner transaction has its own `gasPrice` don't serialize it in this struct. let effective_gas_price = effective_gas_price.filter(|_| inner.gas_price().is_none()); Self { - inner, + inner: inner.into_inner(), block_hash, block_number, transaction_index, @@ -280,11 +285,10 @@ mod tx_serde { Ok(Self { inner: alloy_rpc_types_eth::Transaction { - inner, + inner: Recovered::new_unchecked(inner, from), block_hash, block_number, transaction_index, - from, effective_gas_price, }, deposit_receipt_version, @@ -309,7 +313,7 @@ mod tests { let OpTxEnvelope::Deposit(inner) = tx.as_ref() else { panic!("Expected deposit transaction"); }; - assert_eq!(tx.from, inner.from); + assert_eq!(tx.inner.inner.signer(), inner.from); assert_eq!(tx.deposit_nonce, Some(22211221)); assert_eq!(tx.inner.effective_gas_price, Some(0));