From ace979ec0515ea139c7c1f795ebb57b6706b828b Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Wed, 2 Oct 2024 15:50:37 +0200 Subject: [PATCH 01/23] Checkout trait SignedTransaction from emhane/signed-tx-trait --- crates/primitives/src/traits/mod.rs | 4 +- .../primitives/src/traits/transaction/mod.rs | 3 + .../src/traits/transaction/signed.rs | 118 ++++++++++++++++++ 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 crates/primitives/src/traits/transaction/mod.rs create mode 100644 crates/primitives/src/traits/transaction/signed.rs diff --git a/crates/primitives/src/traits/mod.rs b/crates/primitives/src/traits/mod.rs index 8c84c6729753..736f99cc881c 100644 --- a/crates/primitives/src/traits/mod.rs +++ b/crates/primitives/src/traits/mod.rs @@ -1,7 +1,9 @@ //! Abstractions of primitive data types pub mod block; +pub mod signed; +pub use signed::SignedTransaction; pub use block::{body::BlockBody, Block}; -pub use alloy_consensus::BlockHeader; +pub use alloy_consensus::BlockHeader; \ No newline at end of file diff --git a/crates/primitives/src/traits/transaction/mod.rs b/crates/primitives/src/traits/transaction/mod.rs new file mode 100644 index 000000000000..c41bc794c233 --- /dev/null +++ b/crates/primitives/src/traits/transaction/mod.rs @@ -0,0 +1,3 @@ +//! Transaction abstraction + +pub mod signed; \ No newline at end of file diff --git a/crates/primitives/src/traits/transaction/signed.rs b/crates/primitives/src/traits/transaction/signed.rs new file mode 100644 index 000000000000..58c42b6531d4 --- /dev/null +++ b/crates/primitives/src/traits/transaction/signed.rs @@ -0,0 +1,118 @@ +//! API of a signed transaction, w.r.t. network stack. + +use alloy_consensus::TxLegacy; +use alloy_eips::eip2718::Encodable2718; +use alloy_primitives::{keccak256, Address, Signature, TxHash, B256}; + +use crate::{transaction::decode_with_eip155_chain_id, Transaction}; + +/// A signed transaction. +pub trait SignedTransaction: Sized { + /// Recover signer from signature and hash. + /// + /// Returns `None` if the transaction's signature is invalid following [EIP-2](https://eips.ethereum.org/EIPS/eip-2), see also [`recover_signer`](crate::transaction::recover_signer). + /// + /// Note: + /// + /// This can fail for some early ethereum mainnet transactions pre EIP-2, use + /// [`Self::recover_signer_unchecked`] if you want to recover the signer without ensuring that + /// the signature has a low `s` value. + fn recover_signer(&self) -> Option
; + + /// Recover signer from signature and hash _without ensuring that the signature has a low `s` + /// value_. + /// + /// Returns `None` if the transaction's signature is invalid, see also + /// [`recover_signer_unchecked`](crate::transaction::recover_signer_unchecked). + fn recover_signer_unchecked(&self) -> Option
; + + /// Output the length of the `encode_inner(out`, true). Note to assume that `with_header` is + /// only `true`. + fn payload_len_inner(&self) -> usize; + + /// Decodes an enveloped EIP-2718 typed transaction. + /// + /// This should _only_ be used internally in general transaction decoding methods, + /// which have already ensured that the input is a typed transaction with the following format: + /// `tx-type || rlp(tx-data)` + /// + /// Note that this format does not start with any RLP header, and instead starts with a single + /// byte indicating the transaction type. + /// + /// CAUTION: this expects that `data` is `tx-type || rlp(tx-data)` + fn decode_enveloped_typed_transaction(data: &mut &[u8]) -> alloy_rlp::Result; + + /// Returns the length without an RLP header - this is used for eth/68 sizes. + fn length_without_header(&self) -> usize; + + /// Decodes legacy transaction from the data buffer. + /// + /// This should be used _only_ be used in general transaction decoding methods, which have + /// already ensured that the input is a legacy transaction with the following format: + /// `rlp(legacy_tx)` + /// + /// Legacy transactions are encoded as lists, so the input should start with a RLP list header. + /// + /// This expects `rlp(legacy_tx)` + // TODO: make buf advancement semantics consistent with `decode_enveloped_typed_transaction`, + // so decoding methods do not need to manually advance the buffer + fn decode_rlp_legacy_transaction(data: &mut &[u8]) -> alloy_rlp::Result; + + /// Decodes legacy transaction from the data buffer into a tuple. + /// + /// This expects `rlp(legacy_tx)` + /// + /// Refer to the docs for [`Self::decode_rlp_legacy_transaction`] for details on the exact + /// format expected. + fn decode_rlp_legacy_transaction_tuple( + data: &mut &[u8], + ) -> alloy_rlp::Result<(TxLegacy, TxHash, Signature)> { + // keep this around, so we can use it to calculate the hash + let original_encoding = *data; + + let header = alloy_rlp::Header::decode(data)?; + let remaining_len = data.len(); + + let transaction_payload_len = header.payload_length; + + if transaction_payload_len > remaining_len { + return Err(alloy_rlp::Error::InputTooShort) + } + + let mut transaction = TxLegacy { + nonce: alloy_rlp::Decodable::decode(data)?, + gas_price: alloy_rlp::Decodable::decode(data)?, + gas_limit: alloy_rlp::Decodable::decode(data)?, + to: alloy_rlp::Decodable::decode(data)?, + value: alloy_rlp::Decodable::decode(data)?, + input: alloy_rlp::Decodable::decode(data)?, + chain_id: None, + }; + let (signature, extracted_id) = decode_with_eip155_chain_id(data)?; + transaction.chain_id = extracted_id; + + // check the new length, compared to the original length and the header length + let decoded = remaining_len - data.len(); + if decoded != transaction_payload_len { + return Err(alloy_rlp::Error::UnexpectedLength) + } + + let tx_length = header.payload_length + header.length(); + let hash = keccak256(&original_encoding[..tx_length]); + Ok((transaction, hash, signature)) + } + + /// Create a new signed transaction from a transaction and its signature. + /// + /// This will also calculate the transaction hash using its encoding. + fn from_transaction_and_signature(transaction: Transaction, signature: Signature) -> Self; + + /// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with + /// tx type. + fn recalculate_hash(&self) -> B256 + where + Self: Encodable2718, + { + keccak256(self.encoded_2718()) + } +} From f758c85573e4ab0bddb9dcdb35efa949a9da0334 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Wed, 2 Oct 2024 15:55:59 +0200 Subject: [PATCH 02/23] Checkout SignedTransaction getter trait methods from emhane/tx-signed-2 --- crates/primitives/src/transaction/signed.rs | 127 ++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 crates/primitives/src/transaction/signed.rs diff --git a/crates/primitives/src/transaction/signed.rs b/crates/primitives/src/transaction/signed.rs new file mode 100644 index 000000000000..fcf93e2788de --- /dev/null +++ b/crates/primitives/src/transaction/signed.rs @@ -0,0 +1,127 @@ +//! API of a signed transaction, w.r.t. network stack. + +use alloy_consensus::TxLegacy; +use alloy_eips::eip2718::Encodable2718; +use alloy_primitives::{keccak256, Address, Signature, TxHash, B256}; + +use crate::{transaction::decode_with_eip155_chain_id, Transaction}; + +/// A signed transaction. +pub trait SignedTransaction: Sized { + /// Transaction signature. + fn signature(&self) -> &Signature; + + /// Transaction hash. Used to identify transaction. + fn hash(&self) -> TxHash; + + /// Reference to transaction hash. Used to identify transaction. + fn hash_ref(&self) -> &TxHash; + + /// Recover signer from signature and hash. + /// + /// Returns `None` if the transaction's signature is invalid following [EIP-2](https://eips.ethereum.org/EIPS/eip-2), see also [`recover_signer`](crate::transaction::recover_signer). + /// + /// Note: + /// + /// This can fail for some early ethereum mainnet transactions pre EIP-2, use + /// [`Self::recover_signer_unchecked`] if you want to recover the signer without ensuring that + /// the signature has a low `s` value. + fn recover_signer(&self) -> Option
; + + /// Recover signer from signature and hash _without ensuring that the signature has a low `s` + /// value_. + /// + /// Returns `None` if the transaction's signature is invalid, see also + /// [`recover_signer_unchecked`](crate::transaction::recover_signer_unchecked). + fn recover_signer_unchecked(&self) -> Option
; + + /// Output the length of the `encode_inner(out`, true). Note to assume that `with_header` is + /// only `true`. + fn payload_len_inner(&self) -> usize; + + /// Decodes an enveloped EIP-2718 typed transaction. + /// + /// This should _only_ be used internally in general transaction decoding methods, + /// which have already ensured that the input is a typed transaction with the following format: + /// `tx-type || rlp(tx-data)` + /// + /// Note that this format does not start with any RLP header, and instead starts with a single + /// byte indicating the transaction type. + /// + /// CAUTION: this expects that `data` is `tx-type || rlp(tx-data)` + fn decode_enveloped_typed_transaction(data: &mut &[u8]) -> alloy_rlp::Result; + + /// Returns the length without an RLP header - this is used for eth/68 sizes. + fn length_without_header(&self) -> usize; + + /// Decodes legacy transaction from the data buffer. + /// + /// This should be used _only_ be used in general transaction decoding methods, which have + /// already ensured that the input is a legacy transaction with the following format: + /// `rlp(legacy_tx)` + /// + /// Legacy transactions are encoded as lists, so the input should start with a RLP list header. + /// + /// This expects `rlp(legacy_tx)` + // TODO: make buf advancement semantics consistent with `decode_enveloped_typed_transaction`, + // so decoding methods do not need to manually advance the buffer + fn decode_rlp_legacy_transaction(data: &mut &[u8]) -> alloy_rlp::Result; + + /// Decodes legacy transaction from the data buffer into a tuple. + /// + /// This expects `rlp(legacy_tx)` + /// + /// Refer to the docs for [`Self::decode_rlp_legacy_transaction`] for details on the exact + /// format expected. + fn decode_rlp_legacy_transaction_tuple( + data: &mut &[u8], + ) -> alloy_rlp::Result<(TxLegacy, TxHash, Signature)> { + // keep this around, so we can use it to calculate the hash + let original_encoding = *data; + + let header = alloy_rlp::Header::decode(data)?; + let remaining_len = data.len(); + + let transaction_payload_len = header.payload_length; + + if transaction_payload_len > remaining_len { + return Err(alloy_rlp::Error::InputTooShort) + } + + let mut transaction = TxLegacy { + nonce: alloy_rlp::Decodable::decode(data)?, + gas_price: alloy_rlp::Decodable::decode(data)?, + gas_limit: alloy_rlp::Decodable::decode(data)?, + to: alloy_rlp::Decodable::decode(data)?, + value: alloy_rlp::Decodable::decode(data)?, + input: alloy_rlp::Decodable::decode(data)?, + chain_id: None, + }; + let (signature, extracted_id) = decode_with_eip155_chain_id(data)?; + transaction.chain_id = extracted_id; + + // check the new length, compared to the original length and the header length + let decoded = remaining_len - data.len(); + if decoded != transaction_payload_len { + return Err(alloy_rlp::Error::UnexpectedLength) + } + + let tx_length = header.payload_length + header.length(); + let hash = keccak256(&original_encoding[..tx_length]); + Ok((transaction, hash, signature)) + } + + /// Create a new signed transaction from a transaction and its signature. + /// + /// This will also calculate the transaction hash using its encoding. + fn from_transaction_and_signature(transaction: Transaction, signature: Signature) -> Self; + + /// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with + /// tx type. + fn recalculate_hash(&self) -> B256 + where + Self: Encodable2718, + { + keccak256(self.encoded_2718()) + } +} From d08c5c1ae2b7a5bb51f775e6f8a1f0fc00f1c302 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Wed, 2 Oct 2024 16:16:28 +0200 Subject: [PATCH 03/23] Fix export SignedTransaction --- crates/primitives/src/traits/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/primitives/src/traits/mod.rs b/crates/primitives/src/traits/mod.rs index 736f99cc881c..d7be18df91c5 100644 --- a/crates/primitives/src/traits/mod.rs +++ b/crates/primitives/src/traits/mod.rs @@ -1,9 +1,9 @@ //! Abstractions of primitive data types pub mod block; -pub mod signed; +pub mod transaction; -pub use signed::SignedTransaction; +pub use transaction::signed::SignedTransaction; pub use block::{body::BlockBody, Block}; pub use alloy_consensus::BlockHeader; \ No newline at end of file From 21af26e72fefabca4a597c6bd5b50c8865b0c242 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Fri, 4 Oct 2024 18:46:25 +0200 Subject: [PATCH 04/23] Remove duplicate file --- crates/primitives/src/transaction/signed.rs | 127 -------------------- 1 file changed, 127 deletions(-) delete mode 100644 crates/primitives/src/transaction/signed.rs diff --git a/crates/primitives/src/transaction/signed.rs b/crates/primitives/src/transaction/signed.rs deleted file mode 100644 index fcf93e2788de..000000000000 --- a/crates/primitives/src/transaction/signed.rs +++ /dev/null @@ -1,127 +0,0 @@ -//! API of a signed transaction, w.r.t. network stack. - -use alloy_consensus::TxLegacy; -use alloy_eips::eip2718::Encodable2718; -use alloy_primitives::{keccak256, Address, Signature, TxHash, B256}; - -use crate::{transaction::decode_with_eip155_chain_id, Transaction}; - -/// A signed transaction. -pub trait SignedTransaction: Sized { - /// Transaction signature. - fn signature(&self) -> &Signature; - - /// Transaction hash. Used to identify transaction. - fn hash(&self) -> TxHash; - - /// Reference to transaction hash. Used to identify transaction. - fn hash_ref(&self) -> &TxHash; - - /// Recover signer from signature and hash. - /// - /// Returns `None` if the transaction's signature is invalid following [EIP-2](https://eips.ethereum.org/EIPS/eip-2), see also [`recover_signer`](crate::transaction::recover_signer). - /// - /// Note: - /// - /// This can fail for some early ethereum mainnet transactions pre EIP-2, use - /// [`Self::recover_signer_unchecked`] if you want to recover the signer without ensuring that - /// the signature has a low `s` value. - fn recover_signer(&self) -> Option
; - - /// Recover signer from signature and hash _without ensuring that the signature has a low `s` - /// value_. - /// - /// Returns `None` if the transaction's signature is invalid, see also - /// [`recover_signer_unchecked`](crate::transaction::recover_signer_unchecked). - fn recover_signer_unchecked(&self) -> Option
; - - /// Output the length of the `encode_inner(out`, true). Note to assume that `with_header` is - /// only `true`. - fn payload_len_inner(&self) -> usize; - - /// Decodes an enveloped EIP-2718 typed transaction. - /// - /// This should _only_ be used internally in general transaction decoding methods, - /// which have already ensured that the input is a typed transaction with the following format: - /// `tx-type || rlp(tx-data)` - /// - /// Note that this format does not start with any RLP header, and instead starts with a single - /// byte indicating the transaction type. - /// - /// CAUTION: this expects that `data` is `tx-type || rlp(tx-data)` - fn decode_enveloped_typed_transaction(data: &mut &[u8]) -> alloy_rlp::Result; - - /// Returns the length without an RLP header - this is used for eth/68 sizes. - fn length_without_header(&self) -> usize; - - /// Decodes legacy transaction from the data buffer. - /// - /// This should be used _only_ be used in general transaction decoding methods, which have - /// already ensured that the input is a legacy transaction with the following format: - /// `rlp(legacy_tx)` - /// - /// Legacy transactions are encoded as lists, so the input should start with a RLP list header. - /// - /// This expects `rlp(legacy_tx)` - // TODO: make buf advancement semantics consistent with `decode_enveloped_typed_transaction`, - // so decoding methods do not need to manually advance the buffer - fn decode_rlp_legacy_transaction(data: &mut &[u8]) -> alloy_rlp::Result; - - /// Decodes legacy transaction from the data buffer into a tuple. - /// - /// This expects `rlp(legacy_tx)` - /// - /// Refer to the docs for [`Self::decode_rlp_legacy_transaction`] for details on the exact - /// format expected. - fn decode_rlp_legacy_transaction_tuple( - data: &mut &[u8], - ) -> alloy_rlp::Result<(TxLegacy, TxHash, Signature)> { - // keep this around, so we can use it to calculate the hash - let original_encoding = *data; - - let header = alloy_rlp::Header::decode(data)?; - let remaining_len = data.len(); - - let transaction_payload_len = header.payload_length; - - if transaction_payload_len > remaining_len { - return Err(alloy_rlp::Error::InputTooShort) - } - - let mut transaction = TxLegacy { - nonce: alloy_rlp::Decodable::decode(data)?, - gas_price: alloy_rlp::Decodable::decode(data)?, - gas_limit: alloy_rlp::Decodable::decode(data)?, - to: alloy_rlp::Decodable::decode(data)?, - value: alloy_rlp::Decodable::decode(data)?, - input: alloy_rlp::Decodable::decode(data)?, - chain_id: None, - }; - let (signature, extracted_id) = decode_with_eip155_chain_id(data)?; - transaction.chain_id = extracted_id; - - // check the new length, compared to the original length and the header length - let decoded = remaining_len - data.len(); - if decoded != transaction_payload_len { - return Err(alloy_rlp::Error::UnexpectedLength) - } - - let tx_length = header.payload_length + header.length(); - let hash = keccak256(&original_encoding[..tx_length]); - Ok((transaction, hash, signature)) - } - - /// Create a new signed transaction from a transaction and its signature. - /// - /// This will also calculate the transaction hash using its encoding. - fn from_transaction_and_signature(transaction: Transaction, signature: Signature) -> Self; - - /// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with - /// tx type. - fn recalculate_hash(&self) -> B256 - where - Self: Encodable2718, - { - keccak256(self.encoded_2718()) - } -} From c147f66a3222e41a7341a6cfd602a1193f8e6e58 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Fri, 4 Oct 2024 18:50:16 +0200 Subject: [PATCH 05/23] Remove deprecated method --- crates/primitives/src/traits/transaction/signed.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/crates/primitives/src/traits/transaction/signed.rs b/crates/primitives/src/traits/transaction/signed.rs index 58c42b6531d4..811b15d565c7 100644 --- a/crates/primitives/src/traits/transaction/signed.rs +++ b/crates/primitives/src/traits/transaction/signed.rs @@ -30,18 +30,6 @@ pub trait SignedTransaction: Sized { /// only `true`. fn payload_len_inner(&self) -> usize; - /// Decodes an enveloped EIP-2718 typed transaction. - /// - /// This should _only_ be used internally in general transaction decoding methods, - /// which have already ensured that the input is a typed transaction with the following format: - /// `tx-type || rlp(tx-data)` - /// - /// Note that this format does not start with any RLP header, and instead starts with a single - /// byte indicating the transaction type. - /// - /// CAUTION: this expects that `data` is `tx-type || rlp(tx-data)` - fn decode_enveloped_typed_transaction(data: &mut &[u8]) -> alloy_rlp::Result; - /// Returns the length without an RLP header - this is used for eth/68 sizes. fn length_without_header(&self) -> usize; From cfd372fabbf241ae3692c2bd3a51752cd7414792 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 18:20:05 +0200 Subject: [PATCH 06/23] Add super traits for SignedTransaction --- Cargo.lock | 27 +- crates/primitives/src/traits/mod.rs | 4 +- .../primitives/src/traits/transaction/mod.rs | 2 +- .../src/traits/transaction/signed.rs | 21 +- crates/primitives/src/transaction/mod.rs | 422 +++++++++--------- .../primitives/src/transaction/signature.rs | 7 +- 6 files changed, 251 insertions(+), 232 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e75ea0ec095c..3f9d014fe114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5158,9 +5158,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f7f318f885db6e1455370ca91f74b7faed152c8142f6418f0936d606e582ff" +checksum = "c662868734bd5a274c4474dc0642b5211f008367e591573277e5895333cb78f5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5176,9 +5176,9 @@ dependencies = [ [[package]] name = "op-alloy-genesis" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8215c87b74d2fbbaff0fd2887868a8341df33a3c495ee01f813e5ddd5be9c46" +checksum = "67b4faf4f93b34c263e66cb163a085d9da72ced1f3adb34b7bd70c6e9fc7e5d6" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5190,9 +5190,9 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd514c4ccd0b3c69fa3e7050cde77db842d4c308ae48f9a3e1ce263e823e45e" +checksum = "a51504fd83b75b5d5e09320a0b4657b3bf23fc8018d40038ebab4eafcd7b9a40" dependencies = [ "alloy-consensus", "alloy-network", @@ -5204,9 +5204,9 @@ dependencies = [ [[package]] name = "op-alloy-protocol" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa5c397fbe35e07f9c95a571440ca2e90df754e198496d82ff4127de00b89dd9" +checksum = "20bec4f5aff4fe44e1e5beecd988096e6b757bd4bdfe6b10bb3f08c410287348" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5221,9 +5221,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "547d29c5ab957ff32e14edddb93652dad748d2ef6cbe4b0fe8615ce06b0a3ddb" +checksum = "971fb1d31a1764327e4cf27a5372d2fde5db8bead90f75a750eeab306979b34c" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5238,14 +5238,17 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041122e20b76644cc690bba688671eecdc4626e6384a76eb740535d6ddcef14" +checksum = "eb2b515967262eae36ccecf868ab123dd8a098476f08f28f8ab4c3db5e1ee306" dependencies = [ + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "alloy-serde", "derive_more 1.0.0", + "op-alloy-consensus", + "op-alloy-genesis", "op-alloy-protocol", "serde", ] diff --git a/crates/primitives/src/traits/mod.rs b/crates/primitives/src/traits/mod.rs index d7be18df91c5..49fb73ea5555 100644 --- a/crates/primitives/src/traits/mod.rs +++ b/crates/primitives/src/traits/mod.rs @@ -3,7 +3,7 @@ pub mod block; pub mod transaction; -pub use transaction::signed::SignedTransaction; pub use block::{body::BlockBody, Block}; +pub use transaction::signed::SignedTransaction; -pub use alloy_consensus::BlockHeader; \ No newline at end of file +pub use alloy_consensus::BlockHeader; diff --git a/crates/primitives/src/traits/transaction/mod.rs b/crates/primitives/src/traits/transaction/mod.rs index c41bc794c233..93519eac01eb 100644 --- a/crates/primitives/src/traits/transaction/mod.rs +++ b/crates/primitives/src/traits/transaction/mod.rs @@ -1,3 +1,3 @@ //! Transaction abstraction -pub mod signed; \ No newline at end of file +pub mod signed; diff --git a/crates/primitives/src/traits/transaction/signed.rs b/crates/primitives/src/traits/transaction/signed.rs index 811b15d565c7..7af8363b8d3a 100644 --- a/crates/primitives/src/traits/transaction/signed.rs +++ b/crates/primitives/src/traits/transaction/signed.rs @@ -1,13 +1,30 @@ //! API of a signed transaction, w.r.t. network stack. +use alloc::fmt; +use core::hash::Hash; + use alloy_consensus::TxLegacy; -use alloy_eips::eip2718::Encodable2718; +use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, Signature, TxHash, B256}; use crate::{transaction::decode_with_eip155_chain_id, Transaction}; /// A signed transaction. -pub trait SignedTransaction: Sized { +pub trait SignedTransaction: + fmt::Debug + + Clone + + PartialEq + + Eq + + Hash + + Send + + Sync + + serde::Serialize + + for<'a> serde::Deserialize<'a> + + alloy_rlp::Encodable + + alloy_rlp::Decodable + + Encodable2718 + + Decodable2718 +{ /// Recover signer from signature and hash. /// /// Returns `None` if the transaction's signature is invalid following [EIP-2](https://eips.ethereum.org/EIPS/eip-2), see also [`recover_signer`](crate::transaction::recover_signer). diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 7ef2c0c1fb76..d0043e1c4bf1 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -16,7 +16,6 @@ use derive_more::{AsRef, Deref}; use once_cell::sync::Lazy; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; -use signature::{decode_with_eip155_chain_id, with_eip155_parity}; pub use error::{ InvalidTransactionError, TransactionConversionError, TryFromRecoveredTransactionError, @@ -31,7 +30,8 @@ pub use sidecar::{BlobTransaction, BlobTransactionSidecar}; pub use compat::FillTxEnv; pub use signature::{ - extract_chain_id, legacy_parity, recover_signer, recover_signer_unchecked, Signature, + decode_with_eip155_chain_id, extract_chain_id, legacy_parity, recover_signer, + recover_signer_unchecked, with_eip155_parity, Signature, }; pub use tx_type::{ TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID, @@ -51,9 +51,9 @@ pub(crate) mod util; mod variant; #[cfg(feature = "optimism")] -use op_alloy_consensus::TxDeposit; +pub use op_alloy_consensus::TxDeposit; #[cfg(feature = "optimism")] -use reth_optimism_chainspec::optimism_deposit_tx_signature; +pub use reth_optimism_chainspec::optimism_deposit_tx_signature; #[cfg(feature = "optimism")] pub use tx_type::DEPOSIT_TX_TYPE_ID; #[cfg(any(test, feature = "reth-codec"))] @@ -1570,213 +1570,6 @@ impl WithEncoded> { } } -/// Bincode-compatible transaction type serde implementations. -#[cfg(feature = "serde-bincode-compat")] -pub mod serde_bincode_compat { - use alloc::borrow::Cow; - use alloy_consensus::{ - transaction::serde_bincode_compat::{TxEip1559, TxEip2930, TxEip7702, TxLegacy}, - TxEip4844, - }; - use alloy_primitives::{Signature, TxHash}; - #[cfg(feature = "optimism")] - use op_alloy_consensus::serde_bincode_compat::TxDeposit; - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use serde_with::{DeserializeAs, SerializeAs}; - - /// Bincode-compatible [`super::Transaction`] serde implementation. - /// - /// Intended to use with the [`serde_with::serde_as`] macro in the following way: - /// ```rust - /// use reth_primitives::{serde_bincode_compat, Transaction}; - /// use serde::{Deserialize, Serialize}; - /// use serde_with::serde_as; - /// - /// #[serde_as] - /// #[derive(Serialize, Deserialize)] - /// struct Data { - /// #[serde_as(as = "serde_bincode_compat::transaction::Transaction")] - /// transaction: Transaction, - /// } - /// ``` - #[derive(Debug, Serialize, Deserialize)] - #[allow(missing_docs)] - pub enum Transaction<'a> { - Legacy(TxLegacy<'a>), - Eip2930(TxEip2930<'a>), - Eip1559(TxEip1559<'a>), - Eip4844(Cow<'a, TxEip4844>), - Eip7702(TxEip7702<'a>), - #[cfg(feature = "optimism")] - #[cfg(feature = "optimism")] - Deposit(TxDeposit<'a>), - } - - impl<'a> From<&'a super::Transaction> for Transaction<'a> { - fn from(value: &'a super::Transaction) -> Self { - match value { - super::Transaction::Legacy(tx) => Self::Legacy(TxLegacy::from(tx)), - super::Transaction::Eip2930(tx) => Self::Eip2930(TxEip2930::from(tx)), - 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")] - super::Transaction::Deposit(tx) => Self::Deposit(TxDeposit::from(tx)), - } - } - } - - impl<'a> From> for super::Transaction { - fn from(value: Transaction<'a>) -> Self { - match value { - Transaction::Legacy(tx) => Self::Legacy(tx.into()), - Transaction::Eip2930(tx) => Self::Eip2930(tx.into()), - 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")] - Transaction::Deposit(tx) => Self::Deposit(tx.into()), - } - } - } - - impl SerializeAs for Transaction<'_> { - fn serialize_as(source: &super::Transaction, serializer: S) -> Result - where - S: Serializer, - { - Transaction::from(source).serialize(serializer) - } - } - - impl<'de> DeserializeAs<'de, super::Transaction> for Transaction<'de> { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Transaction::deserialize(deserializer).map(Into::into) - } - } - - /// Bincode-compatible [`super::TransactionSigned`] serde implementation. - /// - /// Intended to use with the [`serde_with::serde_as`] macro in the following way: - /// ```rust - /// use reth_primitives::{serde_bincode_compat, TransactionSigned}; - /// use serde::{Deserialize, Serialize}; - /// use serde_with::serde_as; - /// - /// #[serde_as] - /// #[derive(Serialize, Deserialize)] - /// struct Data { - /// #[serde_as(as = "serde_bincode_compat::transaction::TransactionSigned")] - /// transaction: TransactionSigned, - /// } - /// ``` - #[derive(Debug, Serialize, Deserialize)] - pub struct TransactionSigned<'a> { - hash: TxHash, - signature: Signature, - transaction: Transaction<'a>, - } - - impl<'a> From<&'a super::TransactionSigned> for TransactionSigned<'a> { - fn from(value: &'a super::TransactionSigned) -> Self { - Self { - hash: value.hash, - signature: value.signature, - transaction: Transaction::from(&value.transaction), - } - } - } - - impl<'a> From> for super::TransactionSigned { - fn from(value: TransactionSigned<'a>) -> Self { - Self { - hash: value.hash, - signature: value.signature, - transaction: value.transaction.into(), - } - } - } - - impl SerializeAs for TransactionSigned<'_> { - fn serialize_as( - source: &super::TransactionSigned, - serializer: S, - ) -> Result - where - S: Serializer, - { - TransactionSigned::from(source).serialize(serializer) - } - } - - impl<'de> DeserializeAs<'de, super::TransactionSigned> for TransactionSigned<'de> { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - TransactionSigned::deserialize(deserializer).map(Into::into) - } - } - - #[cfg(test)] - mod tests { - use super::super::{serde_bincode_compat, Transaction, TransactionSigned}; - - use arbitrary::Arbitrary; - use rand::Rng; - use reth_testing_utils::generators; - use serde::{Deserialize, Serialize}; - use serde_with::serde_as; - - #[test] - fn test_transaction_bincode_roundtrip() { - #[serde_as] - #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] - struct Data { - #[serde_as(as = "serde_bincode_compat::Transaction")] - transaction: Transaction, - } - - let mut bytes = [0u8; 1024]; - generators::rng().fill(bytes.as_mut_slice()); - let data = Data { - transaction: Transaction::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) - .unwrap(), - }; - - let encoded = bincode::serialize(&data).unwrap(); - let decoded: Data = bincode::deserialize(&encoded).unwrap(); - assert_eq!(decoded, data); - } - - #[test] - fn test_transaction_signed_bincode_roundtrip() { - #[serde_as] - #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] - struct Data { - #[serde_as(as = "serde_bincode_compat::TransactionSigned")] - transaction: TransactionSigned, - } - - let mut bytes = [0u8; 1024]; - generators::rng().fill(bytes.as_mut_slice()); - let data = Data { - transaction: TransactionSigned::arbitrary(&mut arbitrary::Unstructured::new( - &bytes, - )) - .unwrap(), - }; - - let encoded = bincode::serialize(&data).unwrap(); - let decoded: Data = bincode::deserialize(&encoded).unwrap(); - assert_eq!(decoded, data); - } - } -} - #[cfg(test)] mod tests { use crate::{ @@ -2183,3 +1976,210 @@ mod tests { assert!(res.is_err()); } } + +/// Bincode-compatible transaction type serde implementations. +#[cfg(feature = "serde-bincode-compat")] +pub mod serde_bincode_compat { + use alloc::borrow::Cow; + use alloy_consensus::{ + transaction::serde_bincode_compat::{TxEip1559, TxEip2930, TxEip7702, TxLegacy}, + TxEip4844, + }; + use alloy_primitives::{Signature, TxHash}; + #[cfg(feature = "optimism")] + use op_alloy_consensus::serde_bincode_compat::TxDeposit; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use serde_with::{DeserializeAs, SerializeAs}; + + /// Bincode-compatible [`super::Transaction`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use reth_primitives::{serde_bincode_compat, Transaction}; + /// use serde::{Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data { + /// #[serde_as(as = "serde_bincode_compat::transaction::Transaction")] + /// transaction: Transaction, + /// } + /// ``` + #[derive(Debug, Serialize, Deserialize)] + #[allow(missing_docs)] + pub enum Transaction<'a> { + Legacy(TxLegacy<'a>), + Eip2930(TxEip2930<'a>), + Eip1559(TxEip1559<'a>), + Eip4844(Cow<'a, TxEip4844>), + Eip7702(TxEip7702<'a>), + #[cfg(feature = "optimism")] + #[cfg(feature = "optimism")] + Deposit(TxDeposit<'a>), + } + + impl<'a> From<&'a super::Transaction> for Transaction<'a> { + fn from(value: &'a super::Transaction) -> Self { + match value { + super::Transaction::Legacy(tx) => Self::Legacy(TxLegacy::from(tx)), + super::Transaction::Eip2930(tx) => Self::Eip2930(TxEip2930::from(tx)), + 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")] + super::Transaction::Deposit(tx) => Self::Deposit(TxDeposit::from(tx)), + } + } + } + + impl<'a> From> for super::Transaction { + fn from(value: Transaction<'a>) -> Self { + match value { + Transaction::Legacy(tx) => Self::Legacy(tx.into()), + Transaction::Eip2930(tx) => Self::Eip2930(tx.into()), + 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")] + Transaction::Deposit(tx) => Self::Deposit(tx.into()), + } + } + } + + impl<'a> SerializeAs for Transaction<'a> { + fn serialize_as(source: &super::Transaction, serializer: S) -> Result + where + S: Serializer, + { + Transaction::from(source).serialize(serializer) + } + } + + impl<'de> DeserializeAs<'de, super::Transaction> for Transaction<'de> { + fn deserialize_as(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Transaction::deserialize(deserializer).map(Into::into) + } + } + + /// Bincode-compatible [`super::TransactionSigned`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use reth_primitives::{serde_bincode_compat, TransactionSigned}; + /// use serde::{Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data { + /// #[serde_as(as = "serde_bincode_compat::transaction::TransactionSigned")] + /// transaction: TransactionSigned, + /// } + /// ``` + #[derive(Debug, Serialize, Deserialize)] + pub struct TransactionSigned<'a> { + hash: TxHash, + signature: Signature, + transaction: Transaction<'a>, + } + + impl<'a> From<&'a super::TransactionSigned> for TransactionSigned<'a> { + fn from(value: &'a super::TransactionSigned) -> Self { + Self { + hash: value.hash, + signature: value.signature, + transaction: Transaction::from(&value.transaction), + } + } + } + + impl<'a> From> for super::TransactionSigned { + fn from(value: TransactionSigned<'a>) -> Self { + Self { + hash: value.hash, + signature: value.signature, + transaction: value.transaction.into(), + } + } + } + + impl<'a> SerializeAs for TransactionSigned<'a> { + fn serialize_as( + source: &super::TransactionSigned, + serializer: S, + ) -> Result + where + S: Serializer, + { + TransactionSigned::from(source).serialize(serializer) + } + } + + impl<'de> DeserializeAs<'de, super::TransactionSigned> for TransactionSigned<'de> { + fn deserialize_as(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + TransactionSigned::deserialize(deserializer).map(Into::into) + } + } + + #[cfg(test)] + mod tests { + use super::super::{serde_bincode_compat, Transaction, TransactionSigned}; + + use arbitrary::Arbitrary; + use rand::Rng; + use reth_testing_utils::generators; + use serde::{Deserialize, Serialize}; + use serde_with::serde_as; + + #[test] + fn test_transaction_bincode_roundtrip() { + #[serde_as] + #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] + struct Data { + #[serde_as(as = "serde_bincode_compat::Transaction")] + transaction: Transaction, + } + + let mut bytes = [0u8; 1024]; + generators::rng().fill(bytes.as_mut_slice()); + let data = Data { + transaction: Transaction::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) + .unwrap(), + }; + + let encoded = bincode::serialize(&data).unwrap(); + let decoded: Data = bincode::deserialize(&encoded).unwrap(); + assert_eq!(decoded, data); + } + + #[test] + fn test_transaction_signed_bincode_roundtrip() { + #[serde_as] + #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] + struct Data { + #[serde_as(as = "serde_bincode_compat::TransactionSigned")] + transaction: TransactionSigned, + } + + let mut bytes = [0u8; 1024]; + generators::rng().fill(bytes.as_mut_slice()); + let data = Data { + transaction: TransactionSigned::arbitrary(&mut arbitrary::Unstructured::new( + &bytes, + )) + .unwrap(), + }; + + let encoded = bincode::serialize(&data).unwrap(); + let decoded: Data = bincode::deserialize(&encoded).unwrap(); + assert_eq!(decoded, data); + } + } +} diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index 39c0f92fda88..ee4572f83c4d 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -16,9 +16,8 @@ const SECP256K1N_HALF: U256 = U256::from_be_bytes([ 0x5D, 0x57, 0x6E, 0x73, 0x57, 0xA4, 0x50, 0x1D, 0xDF, 0xE9, 0x2F, 0x46, 0x68, 0x1B, 0x20, 0xA0, ]); -pub(crate) fn decode_with_eip155_chain_id( - buf: &mut &[u8], -) -> alloy_rlp::Result<(Signature, Option)> { +/// Decodes [`Signature`] w.r.t. chain ID. +pub fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Signature, Option)> { let v: Parity = Decodable::decode(buf)?; let r: U256 = Decodable::decode(buf)?; let s: U256 = Decodable::decode(buf)?; @@ -90,7 +89,7 @@ pub fn legacy_parity(signature: &Signature, chain_id: Option) -> Parity { } /// Returns a signature with the given chain ID applied to the `v` value. -pub(crate) fn with_eip155_parity(signature: &Signature, chain_id: Option) -> Signature { +pub fn with_eip155_parity(signature: &Signature, chain_id: Option) -> Signature { Signature::new(signature.r(), signature.s(), legacy_parity(signature, chain_id)) } From 9d1473ed0ec53bbca93b6a401c6cb3b37da3c1d2 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 18:23:06 +0200 Subject: [PATCH 07/23] Define SignedTransaction::Transaction and SignedTransaction::Signature --- .../src/traits/transaction/signed.rs | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/crates/primitives/src/traits/transaction/signed.rs b/crates/primitives/src/traits/transaction/signed.rs index 7af8363b8d3a..0224786cd719 100644 --- a/crates/primitives/src/traits/transaction/signed.rs +++ b/crates/primitives/src/traits/transaction/signed.rs @@ -3,11 +3,11 @@ use alloc::fmt; use core::hash::Hash; -use alloy_consensus::TxLegacy; +use alloy_consensus::{SignableTransaction, TxLegacy}; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; -use alloy_primitives::{keccak256, Address, Signature, TxHash, B256}; +use alloy_primitives::{keccak256, Address, TxHash, B256}; -use crate::{transaction::decode_with_eip155_chain_id, Transaction}; +use crate::transaction::decode_with_eip155_chain_id; /// A signed transaction. pub trait SignedTransaction: @@ -25,6 +25,18 @@ pub trait SignedTransaction: + Encodable2718 + Decodable2718 { + /// Transaction type that is signed. + type Transaction: SignableTransaction; + + /// Signature type that results from signing transaction. + type Signature; + + /// Returns reference to transaction. + fn transaction(&self) -> &Self::Transaction; + + /// Returns reference to signature. + fn signature(&self) -> &Self::Signature; + /// Recover signer from signature and hash. /// /// Returns `None` if the transaction's signature is invalid following [EIP-2](https://eips.ethereum.org/EIPS/eip-2), see also [`recover_signer`](crate::transaction::recover_signer). @@ -71,7 +83,7 @@ pub trait SignedTransaction: /// format expected. fn decode_rlp_legacy_transaction_tuple( data: &mut &[u8], - ) -> alloy_rlp::Result<(TxLegacy, TxHash, Signature)> { + ) -> alloy_rlp::Result<(TxLegacy, TxHash, Self::Signature)> { // keep this around, so we can use it to calculate the hash let original_encoding = *data; @@ -110,7 +122,10 @@ pub trait SignedTransaction: /// Create a new signed transaction from a transaction and its signature. /// /// This will also calculate the transaction hash using its encoding. - fn from_transaction_and_signature(transaction: Transaction, signature: Signature) -> Self; + fn from_transaction_and_signature( + transaction: Self::Transaction, + signature: Self::Signature, + ) -> Self; /// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with /// tx type. From e46aada023b18a6eb69a4c8e8dd5b05edcee3fcf Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 18:30:09 +0200 Subject: [PATCH 08/23] Add getter trait method SignedTransaction::tx_hash --- crates/primitives/src/traits/transaction/signed.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/primitives/src/traits/transaction/signed.rs b/crates/primitives/src/traits/transaction/signed.rs index 0224786cd719..7a4a755aa697 100644 --- a/crates/primitives/src/traits/transaction/signed.rs +++ b/crates/primitives/src/traits/transaction/signed.rs @@ -31,6 +31,9 @@ pub trait SignedTransaction: /// Signature type that results from signing transaction. type Signature; + /// Returns reference to transaction hash. + fn tx_hash(&self) -> &TxHash; + /// Returns reference to transaction. fn transaction(&self) -> &Self::Transaction; From 6302e9b38737c2a41c7ccfaddb78fa699a4c4c3f Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 18:54:33 +0200 Subject: [PATCH 09/23] Move SignedTransaction into reth-primitives-traits --- crates/primitives-traits/src/lib.rs | 5 ++++ crates/primitives-traits/src/signature.rs | 24 +++++++++++++++++++ .../src/signed_tx.rs} | 0 .../primitives/src/traits/transaction/mod.rs | 3 --- .../primitives/src/transaction/signature.rs | 23 ------------------ 5 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 crates/primitives-traits/src/signature.rs rename crates/{primitives/src/traits/transaction/signed.rs => primitives-traits/src/signed_tx.rs} (100%) delete mode 100644 crates/primitives/src/traits/transaction/mod.rs diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index ccc3ea13baf6..8b4397712799 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -20,6 +20,11 @@ pub use constants::gas_units::{format_gas, format_gas_throughput}; pub mod account; pub use account::{Account, Bytecode}; +pub mod signed_tx; +pub use signed_tx::SignedTransaction; + +pub mod signature; + mod integer_list; pub use integer_list::{IntegerList, IntegerListError}; diff --git a/crates/primitives-traits/src/signature.rs b/crates/primitives-traits/src/signature.rs new file mode 100644 index 000000000000..b6775153f187 --- /dev/null +++ b/crates/primitives-traits/src/signature.rs @@ -0,0 +1,24 @@ +//! Signature abstraction tba + +/// Decodes [`Signature`] w.r.t. chain ID. +pub fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Signature, Option)> { + let v: Parity = Decodable::decode(buf)?; + let r: U256 = Decodable::decode(buf)?; + let s: U256 = Decodable::decode(buf)?; + + #[cfg(not(feature = "optimism"))] + if matches!(v, Parity::Parity(_)) { + return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); + } + + #[cfg(feature = "optimism")] + // pre bedrock system transactions were sent from the zero address as legacy + // transactions with an empty signature + // + // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock + if matches!(v, Parity::Parity(false)) && r.is_zero() && s.is_zero() { + return Ok((Signature::new(r, s, Parity::Parity(false)), None)) + } + + Ok((Signature::new(r, s, v), v.chain_id())) +} diff --git a/crates/primitives/src/traits/transaction/signed.rs b/crates/primitives-traits/src/signed_tx.rs similarity index 100% rename from crates/primitives/src/traits/transaction/signed.rs rename to crates/primitives-traits/src/signed_tx.rs diff --git a/crates/primitives/src/traits/transaction/mod.rs b/crates/primitives/src/traits/transaction/mod.rs deleted file mode 100644 index 93519eac01eb..000000000000 --- a/crates/primitives/src/traits/transaction/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Transaction abstraction - -pub mod signed; diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index ee4572f83c4d..ba4ed5ac580c 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -16,29 +16,6 @@ const SECP256K1N_HALF: U256 = U256::from_be_bytes([ 0x5D, 0x57, 0x6E, 0x73, 0x57, 0xA4, 0x50, 0x1D, 0xDF, 0xE9, 0x2F, 0x46, 0x68, 0x1B, 0x20, 0xA0, ]); -/// Decodes [`Signature`] w.r.t. chain ID. -pub fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Signature, Option)> { - let v: Parity = Decodable::decode(buf)?; - let r: U256 = Decodable::decode(buf)?; - let s: U256 = Decodable::decode(buf)?; - - #[cfg(not(feature = "optimism"))] - if matches!(v, Parity::Parity(_)) { - return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); - } - - #[cfg(feature = "optimism")] - // pre bedrock system transactions were sent from the zero address as legacy - // transactions with an empty signature - // - // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock - if matches!(v, Parity::Parity(false)) && r.is_zero() && s.is_zero() { - return Ok((Signature::new(r, s, Parity::Parity(false)), None)) - } - - Ok((Signature::new(r, s, v), v.chain_id())) -} - /// Recover signer from message hash, _without ensuring that the signature has a low `s` /// value_. /// From fc81039a61c86b247b9546f8c80bb9a7d6e5b874 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 19:09:11 +0200 Subject: [PATCH 10/23] Define trait Signature and add as trait bound for SignedTransaction::Signature --- crates/primitives-traits/Cargo.toml | 1 + crates/primitives-traits/src/lib.rs | 1 + crates/primitives-traits/src/signature.rs | 47 ++++++++++++++--------- crates/primitives-traits/src/signed_tx.rs | 6 +-- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index 2fec75666568..1e3679ebcd0c 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -65,3 +65,4 @@ arbitrary = [ "dep:proptest-arbitrary-interop", ] serde-bincode-compat = ["serde_with", "alloy-consensus/serde-bincode-compat"] +optimism = [] \ No newline at end of file diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 8b4397712799..3867c9061a68 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -24,6 +24,7 @@ pub mod signed_tx; pub use signed_tx::SignedTransaction; pub mod signature; +pub use signature::Signature; mod integer_list; pub use integer_list::{IntegerList, IntegerListError}; diff --git a/crates/primitives-traits/src/signature.rs b/crates/primitives-traits/src/signature.rs index b6775153f187..d74ccc557010 100644 --- a/crates/primitives-traits/src/signature.rs +++ b/crates/primitives-traits/src/signature.rs @@ -1,24 +1,33 @@ -//! Signature abstraction tba +//! Signature abstraction -/// Decodes [`Signature`] w.r.t. chain ID. -pub fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Signature, Option)> { - let v: Parity = Decodable::decode(buf)?; - let r: U256 = Decodable::decode(buf)?; - let s: U256 = Decodable::decode(buf)?; +use alloy_primitives::{Parity, U256}; - #[cfg(not(feature = "optimism"))] - if matches!(v, Parity::Parity(_)) { - return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); - } +/// A signature. +pub trait Signature: Sized + Send + Sync { + /// Decodes RLP-encoded signature, w.r.t. chain ID. + fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Self, Option)>; +} - #[cfg(feature = "optimism")] - // pre bedrock system transactions were sent from the zero address as legacy - // transactions with an empty signature - // - // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock - if matches!(v, Parity::Parity(false)) && r.is_zero() && s.is_zero() { - return Ok((Signature::new(r, s, Parity::Parity(false)), None)) - } +impl Signature for alloy_primitives::Signature { + fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Self, Option)> { + let v: Parity = alloy_rlp::Decodable::decode(buf)?; + let r: U256 = alloy_rlp::Decodable::decode(buf)?; + let s: U256 = alloy_rlp::Decodable::decode(buf)?; - Ok((Signature::new(r, s, v), v.chain_id())) + #[cfg(not(feature = "optimism"))] + if matches!(v, Parity::Parity(_)) { + return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); + } + + #[cfg(feature = "optimism")] + // pre bedrock system transactions were sent from the zero address as legacy + // transactions with an empty signature + // + // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock + if matches!(v, Parity::Parity(false)) && r.is_zero() && s.is_zero() { + return Ok((alloy_primitives::Signature::new(r, s, Parity::Parity(false)), None)) + } + + Ok((alloy_primitives::Signature::new(r, s, v), v.chain_id())) + } } diff --git a/crates/primitives-traits/src/signed_tx.rs b/crates/primitives-traits/src/signed_tx.rs index 7a4a755aa697..97981aa8e8f2 100644 --- a/crates/primitives-traits/src/signed_tx.rs +++ b/crates/primitives-traits/src/signed_tx.rs @@ -7,7 +7,7 @@ use alloy_consensus::{SignableTransaction, TxLegacy}; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, TxHash, B256}; -use crate::transaction::decode_with_eip155_chain_id; +use crate::Signature; /// A signed transaction. pub trait SignedTransaction: @@ -29,7 +29,7 @@ pub trait SignedTransaction: type Transaction: SignableTransaction; /// Signature type that results from signing transaction. - type Signature; + type Signature: Signature; /// Returns reference to transaction hash. fn tx_hash(&self) -> &TxHash; @@ -108,7 +108,7 @@ pub trait SignedTransaction: input: alloy_rlp::Decodable::decode(data)?, chain_id: None, }; - let (signature, extracted_id) = decode_with_eip155_chain_id(data)?; + let (signature, extracted_id) = Self::Signature::decode_with_eip155_chain_id(data)?; transaction.chain_id = extracted_id; // check the new length, compared to the original length and the header length From 3294a4e335f77c13f029596b4250432fef4cc4cc Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 19:20:14 +0200 Subject: [PATCH 11/23] Fix conflicts and lint --- crates/primitives-traits/src/signature.rs | 2 +- crates/primitives-traits/src/signed_tx.rs | 5 +---- crates/primitives/src/transaction/mod.rs | 7 ++++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/crates/primitives-traits/src/signature.rs b/crates/primitives-traits/src/signature.rs index d74ccc557010..36b96b9922bb 100644 --- a/crates/primitives-traits/src/signature.rs +++ b/crates/primitives-traits/src/signature.rs @@ -28,6 +28,6 @@ impl Signature for alloy_primitives::Signature { return Ok((alloy_primitives::Signature::new(r, s, Parity::Parity(false)), None)) } - Ok((alloy_primitives::Signature::new(r, s, v), v.chain_id())) + Ok((Self::new(r, s, v), v.chain_id())) } } diff --git a/crates/primitives-traits/src/signed_tx.rs b/crates/primitives-traits/src/signed_tx.rs index 97981aa8e8f2..2a622f49cb8a 100644 --- a/crates/primitives-traits/src/signed_tx.rs +++ b/crates/primitives-traits/src/signed_tx.rs @@ -132,10 +132,7 @@ pub trait SignedTransaction: /// Calculate transaction hash, eip2728 transaction does not contain rlp header and start with /// tx type. - fn recalculate_hash(&self) -> B256 - where - Self: Encodable2718, - { + fn recalculate_hash(&self) -> B256 { keccak256(self.encoded_2718()) } } diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index d0043e1c4bf1..dcbfa3b69b85 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -15,6 +15,7 @@ use core::mem; use derive_more::{AsRef, Deref}; use once_cell::sync::Lazy; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; +use reth_primitives_traits::Signature as _; use serde::{Deserialize, Serialize}; pub use error::{ @@ -30,8 +31,8 @@ pub use sidecar::{BlobTransaction, BlobTransactionSidecar}; pub use compat::FillTxEnv; pub use signature::{ - decode_with_eip155_chain_id, extract_chain_id, legacy_parity, recover_signer, - recover_signer_unchecked, with_eip155_parity, Signature, + extract_chain_id, legacy_parity, recover_signer, recover_signer_unchecked, with_eip155_parity, + Signature, }; pub use tx_type::{ TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID, @@ -1251,7 +1252,7 @@ impl TransactionSigned { input: Decodable::decode(data)?, chain_id: None, }; - let (signature, extracted_id) = decode_with_eip155_chain_id(data)?; + let (signature, extracted_id) = Signature::decode_with_eip155_chain_id(data)?; transaction.chain_id = extracted_id; // check the new length, compared to the original length and the header length From fdf5baec8f368644e8f05f838cf008a6884964ff Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 19:31:34 +0200 Subject: [PATCH 12/23] Fix lint --- crates/primitives-traits/src/signature.rs | 2 +- crates/primitives/src/transaction/signature.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/primitives-traits/src/signature.rs b/crates/primitives-traits/src/signature.rs index 36b96b9922bb..765f61a25fad 100644 --- a/crates/primitives-traits/src/signature.rs +++ b/crates/primitives-traits/src/signature.rs @@ -25,7 +25,7 @@ impl Signature for alloy_primitives::Signature { // // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock if matches!(v, Parity::Parity(false)) && r.is_zero() && s.is_zero() { - return Ok((alloy_primitives::Signature::new(r, s, Parity::Parity(false)), None)) + return Ok((Self::new(r, s, Parity::Parity(false)), None)) } Ok((Self::new(r, s, v), v.chain_id())) diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index ba4ed5ac580c..1ff56b559475 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -1,6 +1,6 @@ use crate::transaction::util::secp256k1; use alloy_primitives::{Address, Parity, B256, U256}; -use alloy_rlp::{Decodable, Error as RlpError}; +use alloy_rlp::Error as RlpError; pub use alloy_primitives::Signature; From e61f0f8f0f18ed29a1c2e5fdf950ad17ef37c217 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 19:58:22 +0200 Subject: [PATCH 13/23] Fix docs --- crates/primitives-traits/src/signed_tx.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/primitives-traits/src/signed_tx.rs b/crates/primitives-traits/src/signed_tx.rs index 2a622f49cb8a..172d6328aa5d 100644 --- a/crates/primitives-traits/src/signed_tx.rs +++ b/crates/primitives-traits/src/signed_tx.rs @@ -42,7 +42,7 @@ pub trait SignedTransaction: /// Recover signer from signature and hash. /// - /// Returns `None` if the transaction's signature is invalid following [EIP-2](https://eips.ethereum.org/EIPS/eip-2), see also [`recover_signer`](crate::transaction::recover_signer). + /// Returns `None` if the transaction's signature is invalid following [EIP-2](https://eips.ethereum.org/EIPS/eip-2), see also `reth_primitives::transaction::recover_signer`. /// /// Note: /// @@ -55,7 +55,7 @@ pub trait SignedTransaction: /// value_. /// /// Returns `None` if the transaction's signature is invalid, see also - /// [`recover_signer_unchecked`](crate::transaction::recover_signer_unchecked). + /// `reth_primitives::transaction::recover_signer_unchecked`. fn recover_signer_unchecked(&self) -> Option
; /// Output the length of the `encode_inner(out`, true). Note to assume that `with_header` is From 4c8e217a46ea03a96a9cead898c43685e3808d5f Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 5 Oct 2024 20:12:28 +0200 Subject: [PATCH 14/23] feat: expose Op node network_config helper (#11506) --- crates/net/network/src/config.rs | 8 +++++++ crates/optimism/node/src/node.rs | 41 ++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/crates/net/network/src/config.rs b/crates/net/network/src/config.rs index 8217a02a1bab..60b559b9dbc3 100644 --- a/crates/net/network/src/config.rs +++ b/crates/net/network/src/config.rs @@ -106,6 +106,14 @@ impl NetworkConfig { NetworkConfig::builder(secret_key).build(client) } + /// Apply a function to the config. + pub fn apply(self, f: F) -> Self + where + F: FnOnce(Self) -> Self, + { + f(self) + } + /// Sets the config to use for the discovery v4 protocol. pub fn set_discovery_v4(mut self, discovery_config: Discv4Config) -> Self { self.discovery_v4_config = Some(discovery_config); diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 8ae47897084b..caeab3741a2e 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -3,8 +3,9 @@ use std::sync::Arc; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; +use reth_chainspec::{EthChainSpec, Hardforks}; use reth_evm::ConfigureEvm; -use reth_network::{NetworkHandle, NetworkManager}; +use reth_network::{NetworkConfig, NetworkHandle, NetworkManager}; use reth_node_api::{EngineValidator, FullNodeComponents, NodeAddOns}; use reth_node_builder::{ components::{ @@ -330,18 +331,18 @@ pub struct OptimismNetworkBuilder { pub disable_discovery_v4: bool, } -impl NetworkBuilder for OptimismNetworkBuilder -where - Node: FullNodeTypes>, - Pool: TransactionPool + Unpin + 'static, -{ - async fn build_network( - self, +impl OptimismNetworkBuilder { + /// Returns the [`NetworkConfig`] that contains the settings to launch the p2p network. + /// + /// This applies the configured [`OptimismNetworkBuilder`] settings. + pub fn network_config( + &self, ctx: &BuilderContext, - pool: Pool, - ) -> eyre::Result { - let Self { disable_txpool_gossip, disable_discovery_v4 } = self; - + ) -> eyre::Result::Provider>> + where + Node: FullNodeTypes>, + { + let Self { disable_txpool_gossip, disable_discovery_v4 } = self.clone(); let args = &ctx.config().network; let network_builder = ctx .network_config_builder()? @@ -374,8 +375,22 @@ where // gossip to prevent other parties in the network from learning about them. network_config.tx_gossip_disabled = disable_txpool_gossip; - let network = NetworkManager::builder(network_config).await?; + Ok(network_config) + } +} +impl NetworkBuilder for OptimismNetworkBuilder +where + Node: FullNodeTypes>, + Pool: TransactionPool + Unpin + 'static, +{ + async fn build_network( + self, + ctx: &BuilderContext, + pool: Pool, + ) -> eyre::Result { + let network_config = self.network_config(ctx)?; + let network = NetworkManager::builder(network_config).await?; let handle = ctx.start_network(network, pool); Ok(handle) From 00f899f1f5402b4063f09c0a0bc446f2626aaf9b Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 5 Oct 2024 20:30:09 +0200 Subject: [PATCH 15/23] Fix merge conflicts --- crates/primitives/src/transaction/mod.rs | 418 +++++++++++------------ 1 file changed, 209 insertions(+), 209 deletions(-) diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index dcbfa3b69b85..6f90f974c048 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -52,9 +52,9 @@ pub(crate) mod util; mod variant; #[cfg(feature = "optimism")] -pub use op_alloy_consensus::TxDeposit; +use op_alloy_consensus::TxDeposit; #[cfg(feature = "optimism")] -pub use reth_optimism_chainspec::optimism_deposit_tx_signature; +use reth_optimism_chainspec::optimism_deposit_tx_signature; #[cfg(feature = "optimism")] pub use tx_type::DEPOSIT_TX_TYPE_ID; #[cfg(any(test, feature = "reth-codec"))] @@ -1571,6 +1571,213 @@ impl WithEncoded> { } } +/// Bincode-compatible transaction type serde implementations. +#[cfg(feature = "serde-bincode-compat")] +pub mod serde_bincode_compat { + use alloc::borrow::Cow; + use alloy_consensus::{ + transaction::serde_bincode_compat::{TxEip1559, TxEip2930, TxEip7702, TxLegacy}, + TxEip4844, + }; + use alloy_primitives::{Signature, TxHash}; + #[cfg(feature = "optimism")] + use op_alloy_consensus::serde_bincode_compat::TxDeposit; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use serde_with::{DeserializeAs, SerializeAs}; + + /// Bincode-compatible [`super::Transaction`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use reth_primitives::{serde_bincode_compat, Transaction}; + /// use serde::{Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data { + /// #[serde_as(as = "serde_bincode_compat::transaction::Transaction")] + /// transaction: Transaction, + /// } + /// ``` + #[derive(Debug, Serialize, Deserialize)] + #[allow(missing_docs)] + pub enum Transaction<'a> { + Legacy(TxLegacy<'a>), + Eip2930(TxEip2930<'a>), + Eip1559(TxEip1559<'a>), + Eip4844(Cow<'a, TxEip4844>), + Eip7702(TxEip7702<'a>), + #[cfg(feature = "optimism")] + #[cfg(feature = "optimism")] + Deposit(TxDeposit<'a>), + } + + impl<'a> From<&'a super::Transaction> for Transaction<'a> { + fn from(value: &'a super::Transaction) -> Self { + match value { + super::Transaction::Legacy(tx) => Self::Legacy(TxLegacy::from(tx)), + super::Transaction::Eip2930(tx) => Self::Eip2930(TxEip2930::from(tx)), + 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")] + super::Transaction::Deposit(tx) => Self::Deposit(TxDeposit::from(tx)), + } + } + } + + impl<'a> From> for super::Transaction { + fn from(value: Transaction<'a>) -> Self { + match value { + Transaction::Legacy(tx) => Self::Legacy(tx.into()), + Transaction::Eip2930(tx) => Self::Eip2930(tx.into()), + 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")] + Transaction::Deposit(tx) => Self::Deposit(tx.into()), + } + } + } + + impl SerializeAs for Transaction<'_> { + fn serialize_as(source: &super::Transaction, serializer: S) -> Result + where + S: Serializer, + { + Transaction::from(source).serialize(serializer) + } + } + + impl<'de> DeserializeAs<'de, super::Transaction> for Transaction<'de> { + fn deserialize_as(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Transaction::deserialize(deserializer).map(Into::into) + } + } + + /// Bincode-compatible [`super::TransactionSigned`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use reth_primitives::{serde_bincode_compat, TransactionSigned}; + /// use serde::{Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data { + /// #[serde_as(as = "serde_bincode_compat::transaction::TransactionSigned")] + /// transaction: TransactionSigned, + /// } + /// ``` + #[derive(Debug, Serialize, Deserialize)] + pub struct TransactionSigned<'a> { + hash: TxHash, + signature: Signature, + transaction: Transaction<'a>, + } + + impl<'a> From<&'a super::TransactionSigned> for TransactionSigned<'a> { + fn from(value: &'a super::TransactionSigned) -> Self { + Self { + hash: value.hash, + signature: value.signature, + transaction: Transaction::from(&value.transaction), + } + } + } + + impl<'a> From> for super::TransactionSigned { + fn from(value: TransactionSigned<'a>) -> Self { + Self { + hash: value.hash, + signature: value.signature, + transaction: value.transaction.into(), + } + } + } + + impl SerializeAs for TransactionSigned<'_> { + fn serialize_as( + source: &super::TransactionSigned, + serializer: S, + ) -> Result + where + S: Serializer, + { + TransactionSigned::from(source).serialize(serializer) + } + } + + impl<'de> DeserializeAs<'de, super::TransactionSigned> for TransactionSigned<'de> { + fn deserialize_as(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + TransactionSigned::deserialize(deserializer).map(Into::into) + } + } + + #[cfg(test)] + mod tests { + use super::super::{serde_bincode_compat, Transaction, TransactionSigned}; + + use arbitrary::Arbitrary; + use rand::Rng; + use reth_testing_utils::generators; + use serde::{Deserialize, Serialize}; + use serde_with::serde_as; + + #[test] + fn test_transaction_bincode_roundtrip() { + #[serde_as] + #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] + struct Data { + #[serde_as(as = "serde_bincode_compat::Transaction")] + transaction: Transaction, + } + + let mut bytes = [0u8; 1024]; + generators::rng().fill(bytes.as_mut_slice()); + let data = Data { + transaction: Transaction::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) + .unwrap(), + }; + + let encoded = bincode::serialize(&data).unwrap(); + let decoded: Data = bincode::deserialize(&encoded).unwrap(); + assert_eq!(decoded, data); + } + + #[test] + fn test_transaction_signed_bincode_roundtrip() { + #[serde_as] + #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] + struct Data { + #[serde_as(as = "serde_bincode_compat::TransactionSigned")] + transaction: TransactionSigned, + } + + let mut bytes = [0u8; 1024]; + generators::rng().fill(bytes.as_mut_slice()); + let data = Data { + transaction: TransactionSigned::arbitrary(&mut arbitrary::Unstructured::new( + &bytes, + )) + .unwrap(), + }; + + let encoded = bincode::serialize(&data).unwrap(); + let decoded: Data = bincode::deserialize(&encoded).unwrap(); + assert_eq!(decoded, data); + } + } +} + #[cfg(test)] mod tests { use crate::{ @@ -1977,210 +2184,3 @@ mod tests { assert!(res.is_err()); } } - -/// Bincode-compatible transaction type serde implementations. -#[cfg(feature = "serde-bincode-compat")] -pub mod serde_bincode_compat { - use alloc::borrow::Cow; - use alloy_consensus::{ - transaction::serde_bincode_compat::{TxEip1559, TxEip2930, TxEip7702, TxLegacy}, - TxEip4844, - }; - use alloy_primitives::{Signature, TxHash}; - #[cfg(feature = "optimism")] - use op_alloy_consensus::serde_bincode_compat::TxDeposit; - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use serde_with::{DeserializeAs, SerializeAs}; - - /// Bincode-compatible [`super::Transaction`] serde implementation. - /// - /// Intended to use with the [`serde_with::serde_as`] macro in the following way: - /// ```rust - /// use reth_primitives::{serde_bincode_compat, Transaction}; - /// use serde::{Deserialize, Serialize}; - /// use serde_with::serde_as; - /// - /// #[serde_as] - /// #[derive(Serialize, Deserialize)] - /// struct Data { - /// #[serde_as(as = "serde_bincode_compat::transaction::Transaction")] - /// transaction: Transaction, - /// } - /// ``` - #[derive(Debug, Serialize, Deserialize)] - #[allow(missing_docs)] - pub enum Transaction<'a> { - Legacy(TxLegacy<'a>), - Eip2930(TxEip2930<'a>), - Eip1559(TxEip1559<'a>), - Eip4844(Cow<'a, TxEip4844>), - Eip7702(TxEip7702<'a>), - #[cfg(feature = "optimism")] - #[cfg(feature = "optimism")] - Deposit(TxDeposit<'a>), - } - - impl<'a> From<&'a super::Transaction> for Transaction<'a> { - fn from(value: &'a super::Transaction) -> Self { - match value { - super::Transaction::Legacy(tx) => Self::Legacy(TxLegacy::from(tx)), - super::Transaction::Eip2930(tx) => Self::Eip2930(TxEip2930::from(tx)), - 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")] - super::Transaction::Deposit(tx) => Self::Deposit(TxDeposit::from(tx)), - } - } - } - - impl<'a> From> for super::Transaction { - fn from(value: Transaction<'a>) -> Self { - match value { - Transaction::Legacy(tx) => Self::Legacy(tx.into()), - Transaction::Eip2930(tx) => Self::Eip2930(tx.into()), - 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")] - Transaction::Deposit(tx) => Self::Deposit(tx.into()), - } - } - } - - impl<'a> SerializeAs for Transaction<'a> { - fn serialize_as(source: &super::Transaction, serializer: S) -> Result - where - S: Serializer, - { - Transaction::from(source).serialize(serializer) - } - } - - impl<'de> DeserializeAs<'de, super::Transaction> for Transaction<'de> { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Transaction::deserialize(deserializer).map(Into::into) - } - } - - /// Bincode-compatible [`super::TransactionSigned`] serde implementation. - /// - /// Intended to use with the [`serde_with::serde_as`] macro in the following way: - /// ```rust - /// use reth_primitives::{serde_bincode_compat, TransactionSigned}; - /// use serde::{Deserialize, Serialize}; - /// use serde_with::serde_as; - /// - /// #[serde_as] - /// #[derive(Serialize, Deserialize)] - /// struct Data { - /// #[serde_as(as = "serde_bincode_compat::transaction::TransactionSigned")] - /// transaction: TransactionSigned, - /// } - /// ``` - #[derive(Debug, Serialize, Deserialize)] - pub struct TransactionSigned<'a> { - hash: TxHash, - signature: Signature, - transaction: Transaction<'a>, - } - - impl<'a> From<&'a super::TransactionSigned> for TransactionSigned<'a> { - fn from(value: &'a super::TransactionSigned) -> Self { - Self { - hash: value.hash, - signature: value.signature, - transaction: Transaction::from(&value.transaction), - } - } - } - - impl<'a> From> for super::TransactionSigned { - fn from(value: TransactionSigned<'a>) -> Self { - Self { - hash: value.hash, - signature: value.signature, - transaction: value.transaction.into(), - } - } - } - - impl<'a> SerializeAs for TransactionSigned<'a> { - fn serialize_as( - source: &super::TransactionSigned, - serializer: S, - ) -> Result - where - S: Serializer, - { - TransactionSigned::from(source).serialize(serializer) - } - } - - impl<'de> DeserializeAs<'de, super::TransactionSigned> for TransactionSigned<'de> { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - TransactionSigned::deserialize(deserializer).map(Into::into) - } - } - - #[cfg(test)] - mod tests { - use super::super::{serde_bincode_compat, Transaction, TransactionSigned}; - - use arbitrary::Arbitrary; - use rand::Rng; - use reth_testing_utils::generators; - use serde::{Deserialize, Serialize}; - use serde_with::serde_as; - - #[test] - fn test_transaction_bincode_roundtrip() { - #[serde_as] - #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] - struct Data { - #[serde_as(as = "serde_bincode_compat::Transaction")] - transaction: Transaction, - } - - let mut bytes = [0u8; 1024]; - generators::rng().fill(bytes.as_mut_slice()); - let data = Data { - transaction: Transaction::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) - .unwrap(), - }; - - let encoded = bincode::serialize(&data).unwrap(); - let decoded: Data = bincode::deserialize(&encoded).unwrap(); - assert_eq!(decoded, data); - } - - #[test] - fn test_transaction_signed_bincode_roundtrip() { - #[serde_as] - #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] - struct Data { - #[serde_as(as = "serde_bincode_compat::TransactionSigned")] - transaction: TransactionSigned, - } - - let mut bytes = [0u8; 1024]; - generators::rng().fill(bytes.as_mut_slice()); - let data = Data { - transaction: TransactionSigned::arbitrary(&mut arbitrary::Unstructured::new( - &bytes, - )) - .unwrap(), - }; - - let encoded = bincode::serialize(&data).unwrap(); - let decoded: Data = bincode::deserialize(&encoded).unwrap(); - assert_eq!(decoded, data); - } - } -} From d5ebe55e5be806842740634bcf38ee02dd4d9e0d Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 8 Oct 2024 12:00:55 +0200 Subject: [PATCH 16/23] Remove optimism code from reth-primitives-traits --- crates/primitives-traits/Cargo.toml | 3 +-- crates/primitives-traits/src/signature.rs | 12 ++---------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index 1e3679ebcd0c..b34987327ee8 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -64,5 +64,4 @@ arbitrary = [ "dep:proptest", "dep:proptest-arbitrary-interop", ] -serde-bincode-compat = ["serde_with", "alloy-consensus/serde-bincode-compat"] -optimism = [] \ No newline at end of file +serde-bincode-compat = ["serde_with", "alloy-consensus/serde-bincode-compat"] \ No newline at end of file diff --git a/crates/primitives-traits/src/signature.rs b/crates/primitives-traits/src/signature.rs index 765f61a25fad..8d50a2c1b8c3 100644 --- a/crates/primitives-traits/src/signature.rs +++ b/crates/primitives-traits/src/signature.rs @@ -8,26 +8,18 @@ pub trait Signature: Sized + Send + Sync { fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Self, Option)>; } +// todo: add optimism type that wraps Signature, to impl separately for OP to account for system +// null signature impl Signature for alloy_primitives::Signature { fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Self, Option)> { let v: Parity = alloy_rlp::Decodable::decode(buf)?; let r: U256 = alloy_rlp::Decodable::decode(buf)?; let s: U256 = alloy_rlp::Decodable::decode(buf)?; - #[cfg(not(feature = "optimism"))] if matches!(v, Parity::Parity(_)) { return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); } - #[cfg(feature = "optimism")] - // pre bedrock system transactions were sent from the zero address as legacy - // transactions with an empty signature - // - // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock - if matches!(v, Parity::Parity(false)) && r.is_zero() && s.is_zero() { - return Ok((Self::new(r, s, Parity::Parity(false)), None)) - } - Ok((Self::new(r, s, v), v.chain_id())) } } From 86eaa113e0e3e36c3394ddda3660dc28b37c2006 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 8 Oct 2024 12:16:58 +0200 Subject: [PATCH 17/23] Remove trait methods from SignedTransaction related to rlp encoding --- crates/primitives-traits/src/signed_tx.rs | 59 +------------------ crates/primitives/src/transaction/mod.rs | 7 +-- .../primitives/src/transaction/signature.rs | 28 ++++++++- 3 files changed, 30 insertions(+), 64 deletions(-) diff --git a/crates/primitives-traits/src/signed_tx.rs b/crates/primitives-traits/src/signed_tx.rs index 172d6328aa5d..56ef8772bb3e 100644 --- a/crates/primitives-traits/src/signed_tx.rs +++ b/crates/primitives-traits/src/signed_tx.rs @@ -3,7 +3,7 @@ use alloc::fmt; use core::hash::Hash; -use alloy_consensus::{SignableTransaction, TxLegacy}; +use alloy_consensus::SignableTransaction; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, TxHash, B256}; @@ -65,63 +65,6 @@ pub trait SignedTransaction: /// Returns the length without an RLP header - this is used for eth/68 sizes. fn length_without_header(&self) -> usize; - /// Decodes legacy transaction from the data buffer. - /// - /// This should be used _only_ be used in general transaction decoding methods, which have - /// already ensured that the input is a legacy transaction with the following format: - /// `rlp(legacy_tx)` - /// - /// Legacy transactions are encoded as lists, so the input should start with a RLP list header. - /// - /// This expects `rlp(legacy_tx)` - // TODO: make buf advancement semantics consistent with `decode_enveloped_typed_transaction`, - // so decoding methods do not need to manually advance the buffer - fn decode_rlp_legacy_transaction(data: &mut &[u8]) -> alloy_rlp::Result; - - /// Decodes legacy transaction from the data buffer into a tuple. - /// - /// This expects `rlp(legacy_tx)` - /// - /// Refer to the docs for [`Self::decode_rlp_legacy_transaction`] for details on the exact - /// format expected. - fn decode_rlp_legacy_transaction_tuple( - data: &mut &[u8], - ) -> alloy_rlp::Result<(TxLegacy, TxHash, Self::Signature)> { - // keep this around, so we can use it to calculate the hash - let original_encoding = *data; - - let header = alloy_rlp::Header::decode(data)?; - let remaining_len = data.len(); - - let transaction_payload_len = header.payload_length; - - if transaction_payload_len > remaining_len { - return Err(alloy_rlp::Error::InputTooShort) - } - - let mut transaction = TxLegacy { - nonce: alloy_rlp::Decodable::decode(data)?, - gas_price: alloy_rlp::Decodable::decode(data)?, - gas_limit: alloy_rlp::Decodable::decode(data)?, - to: alloy_rlp::Decodable::decode(data)?, - value: alloy_rlp::Decodable::decode(data)?, - input: alloy_rlp::Decodable::decode(data)?, - chain_id: None, - }; - let (signature, extracted_id) = Self::Signature::decode_with_eip155_chain_id(data)?; - transaction.chain_id = extracted_id; - - // check the new length, compared to the original length and the header length - let decoded = remaining_len - data.len(); - if decoded != transaction_payload_len { - return Err(alloy_rlp::Error::UnexpectedLength) - } - - let tx_length = header.payload_length + header.length(); - let hash = keccak256(&original_encoding[..tx_length]); - Ok((transaction, hash, signature)) - } - /// Create a new signed transaction from a transaction and its signature. /// /// This will also calculate the transaction hash using its encoding. diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 6f90f974c048..7ef2c0c1fb76 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -15,8 +15,8 @@ use core::mem; use derive_more::{AsRef, Deref}; use once_cell::sync::Lazy; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; -use reth_primitives_traits::Signature as _; use serde::{Deserialize, Serialize}; +use signature::{decode_with_eip155_chain_id, with_eip155_parity}; pub use error::{ InvalidTransactionError, TransactionConversionError, TryFromRecoveredTransactionError, @@ -31,8 +31,7 @@ pub use sidecar::{BlobTransaction, BlobTransactionSidecar}; pub use compat::FillTxEnv; pub use signature::{ - extract_chain_id, legacy_parity, recover_signer, recover_signer_unchecked, with_eip155_parity, - Signature, + extract_chain_id, legacy_parity, recover_signer, recover_signer_unchecked, Signature, }; pub use tx_type::{ TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID, @@ -1252,7 +1251,7 @@ impl TransactionSigned { input: Decodable::decode(data)?, chain_id: None, }; - let (signature, extracted_id) = Signature::decode_with_eip155_chain_id(data)?; + let (signature, extracted_id) = decode_with_eip155_chain_id(data)?; transaction.chain_id = extracted_id; // check the new length, compared to the original length and the header length diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index 1ff56b559475..39c0f92fda88 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -1,6 +1,6 @@ use crate::transaction::util::secp256k1; use alloy_primitives::{Address, Parity, B256, U256}; -use alloy_rlp::Error as RlpError; +use alloy_rlp::{Decodable, Error as RlpError}; pub use alloy_primitives::Signature; @@ -16,6 +16,30 @@ const SECP256K1N_HALF: U256 = U256::from_be_bytes([ 0x5D, 0x57, 0x6E, 0x73, 0x57, 0xA4, 0x50, 0x1D, 0xDF, 0xE9, 0x2F, 0x46, 0x68, 0x1B, 0x20, 0xA0, ]); +pub(crate) fn decode_with_eip155_chain_id( + buf: &mut &[u8], +) -> alloy_rlp::Result<(Signature, Option)> { + let v: Parity = Decodable::decode(buf)?; + let r: U256 = Decodable::decode(buf)?; + let s: U256 = Decodable::decode(buf)?; + + #[cfg(not(feature = "optimism"))] + if matches!(v, Parity::Parity(_)) { + return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); + } + + #[cfg(feature = "optimism")] + // pre bedrock system transactions were sent from the zero address as legacy + // transactions with an empty signature + // + // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock + if matches!(v, Parity::Parity(false)) && r.is_zero() && s.is_zero() { + return Ok((Signature::new(r, s, Parity::Parity(false)), None)) + } + + Ok((Signature::new(r, s, v), v.chain_id())) +} + /// Recover signer from message hash, _without ensuring that the signature has a low `s` /// value_. /// @@ -66,7 +90,7 @@ pub fn legacy_parity(signature: &Signature, chain_id: Option) -> Parity { } /// Returns a signature with the given chain ID applied to the `v` value. -pub fn with_eip155_parity(signature: &Signature, chain_id: Option) -> Signature { +pub(crate) fn with_eip155_parity(signature: &Signature, chain_id: Option) -> Signature { Signature::new(signature.r(), signature.s(), legacy_parity(signature, chain_id)) } From 6239a6be8e68d76670dc96000e829263e3e5b8c6 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 8 Oct 2024 13:04:48 +0200 Subject: [PATCH 18/23] Remove Signature trait from scope --- Makefile | 6 +++--- crates/primitives-traits/src/lib.rs | 3 --- crates/primitives-traits/src/signature.rs | 25 ----------------------- crates/primitives-traits/src/signed_tx.rs | 4 +--- 4 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 crates/primitives-traits/src/signature.rs diff --git a/Makefile b/Makefile index 4d897c7ee482..53238c349937 100644 --- a/Makefile +++ b/Makefile @@ -325,7 +325,7 @@ fmt: cargo +nightly fmt lint-reth: - cargo +nightly clippy \ + cargo +nightly-2024-09-25-aarch64-apple-darwin clippy \ --workspace \ --bin "reth" \ --lib \ @@ -336,7 +336,7 @@ lint-reth: -- -D warnings lint-op-reth: - cargo +nightly clippy \ + cargo +nightly-2024-09-25-aarch64-apple-darwin clippy \ --workspace \ --bin "op-reth" \ --lib \ @@ -347,7 +347,7 @@ lint-op-reth: -- -D warnings lint-other-targets: - cargo +nightly clippy \ + cargo +nightly-2024-09-25-aarch64-apple-darwin clippy \ --workspace \ --lib \ --examples \ diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 3867c9061a68..17f9b0852b2e 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -23,9 +23,6 @@ pub use account::{Account, Bytecode}; pub mod signed_tx; pub use signed_tx::SignedTransaction; -pub mod signature; -pub use signature::Signature; - mod integer_list; pub use integer_list::{IntegerList, IntegerListError}; diff --git a/crates/primitives-traits/src/signature.rs b/crates/primitives-traits/src/signature.rs deleted file mode 100644 index 8d50a2c1b8c3..000000000000 --- a/crates/primitives-traits/src/signature.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Signature abstraction - -use alloy_primitives::{Parity, U256}; - -/// A signature. -pub trait Signature: Sized + Send + Sync { - /// Decodes RLP-encoded signature, w.r.t. chain ID. - fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Self, Option)>; -} - -// todo: add optimism type that wraps Signature, to impl separately for OP to account for system -// null signature -impl Signature for alloy_primitives::Signature { - fn decode_with_eip155_chain_id(buf: &mut &[u8]) -> alloy_rlp::Result<(Self, Option)> { - let v: Parity = alloy_rlp::Decodable::decode(buf)?; - let r: U256 = alloy_rlp::Decodable::decode(buf)?; - let s: U256 = alloy_rlp::Decodable::decode(buf)?; - - if matches!(v, Parity::Parity(_)) { - return Err(alloy_rlp::Error::Custom("invalid parity for legacy transaction")); - } - - Ok((Self::new(r, s, v), v.chain_id())) - } -} diff --git a/crates/primitives-traits/src/signed_tx.rs b/crates/primitives-traits/src/signed_tx.rs index 56ef8772bb3e..59603aae6cdc 100644 --- a/crates/primitives-traits/src/signed_tx.rs +++ b/crates/primitives-traits/src/signed_tx.rs @@ -7,8 +7,6 @@ use alloy_consensus::SignableTransaction; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, TxHash, B256}; -use crate::Signature; - /// A signed transaction. pub trait SignedTransaction: fmt::Debug @@ -29,7 +27,7 @@ pub trait SignedTransaction: type Transaction: SignableTransaction; /// Signature type that results from signing transaction. - type Signature: Signature; + type Signature; /// Returns reference to transaction hash. fn tx_hash(&self) -> &TxHash; From a232b2a233d8869b87171e7d108a54b8cd765463 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 8 Oct 2024 13:05:41 +0200 Subject: [PATCH 19/23] Remove trait bound SigneableTransaction off SignedTransaction::Transaction --- crates/primitives-traits/src/signed_tx.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/primitives-traits/src/signed_tx.rs b/crates/primitives-traits/src/signed_tx.rs index 59603aae6cdc..8e6261e3e462 100644 --- a/crates/primitives-traits/src/signed_tx.rs +++ b/crates/primitives-traits/src/signed_tx.rs @@ -3,7 +3,7 @@ use alloc::fmt; use core::hash::Hash; -use alloy_consensus::SignableTransaction; +use alloy_consensus::Transaction; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, TxHash, B256}; @@ -24,7 +24,7 @@ pub trait SignedTransaction: + Decodable2718 { /// Transaction type that is signed. - type Transaction: SignableTransaction; + type Transaction: Transaction; /// Signature type that results from signing transaction. type Signature; From 5ea4e68344b6b8d5c07ff162cf6efac9c8ea6b36 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 8 Oct 2024 14:04:07 +0200 Subject: [PATCH 20/23] Revert changes to Makefile --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 53238c349937..4d897c7ee482 100644 --- a/Makefile +++ b/Makefile @@ -325,7 +325,7 @@ fmt: cargo +nightly fmt lint-reth: - cargo +nightly-2024-09-25-aarch64-apple-darwin clippy \ + cargo +nightly clippy \ --workspace \ --bin "reth" \ --lib \ @@ -336,7 +336,7 @@ lint-reth: -- -D warnings lint-op-reth: - cargo +nightly-2024-09-25-aarch64-apple-darwin clippy \ + cargo +nightly clippy \ --workspace \ --bin "op-reth" \ --lib \ @@ -347,7 +347,7 @@ lint-op-reth: -- -D warnings lint-other-targets: - cargo +nightly-2024-09-25-aarch64-apple-darwin clippy \ + cargo +nightly clippy \ --workspace \ --lib \ --examples \ From 086c866aceb65ff621df0a091e945a3e974de1b4 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 17 Oct 2024 17:40:01 +0200 Subject: [PATCH 21/23] Move module signed_tx->transaction::signed --- crates/primitives-traits/src/lib.rs | 5 +---- crates/primitives-traits/src/mod.rs | 0 .../src/{transaction.rs => transaction/mod.rs} | 2 ++ .../src/{signed_tx.rs => transaction/signed.rs} | 0 4 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 crates/primitives-traits/src/mod.rs rename crates/primitives-traits/src/{transaction.rs => transaction/mod.rs} (97%) rename crates/primitives-traits/src/{signed_tx.rs => transaction/signed.rs} (100%) diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 73de78288498..dd10ac9c5f1e 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -20,14 +20,11 @@ pub use constants::gas_units::{format_gas, format_gas_throughput}; pub mod account; pub use account::{Account, Bytecode}; -pub mod signed_tx; -pub use signed_tx::SignedTransaction; - pub mod receipt; pub use receipt::Receipt; pub mod transaction; -pub use transaction::Transaction; +pub use transaction::{signed::SignedTransaction, Transaction}; mod integer_list; pub use integer_list::{IntegerList, IntegerListError}; diff --git a/crates/primitives-traits/src/mod.rs b/crates/primitives-traits/src/mod.rs new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/crates/primitives-traits/src/transaction.rs b/crates/primitives-traits/src/transaction/mod.rs similarity index 97% rename from crates/primitives-traits/src/transaction.rs rename to crates/primitives-traits/src/transaction/mod.rs index 93645ead82e8..a306c5f76ed5 100644 --- a/crates/primitives-traits/src/transaction.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -1,5 +1,7 @@ //! Transaction abstraction +pub mod signed; + use alloc::fmt; use reth_codecs::Compact; diff --git a/crates/primitives-traits/src/signed_tx.rs b/crates/primitives-traits/src/transaction/signed.rs similarity index 100% rename from crates/primitives-traits/src/signed_tx.rs rename to crates/primitives-traits/src/transaction/signed.rs From 34618296801e20dbf7ccfe9b69fc4031dcf79cc8 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 17 Oct 2024 17:40:48 +0200 Subject: [PATCH 22/23] Update docs --- crates/primitives-traits/src/transaction/signed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 8e6261e3e462..c80adcac6eda 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -1,4 +1,4 @@ -//! API of a signed transaction, w.r.t. network stack. +//! API of a signed transaction. use alloc::fmt; use core::hash::Hash; From e785d3b3a652af214b0dc9756f05765a47e02373 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Fri, 18 Oct 2024 11:28:56 +0200 Subject: [PATCH 23/23] Remove redundant trait methods from SignedTransaction --- crates/primitives-traits/src/transaction/signed.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index c80adcac6eda..1bc8308b13f0 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -56,13 +56,6 @@ pub trait SignedTransaction: /// `reth_primitives::transaction::recover_signer_unchecked`. fn recover_signer_unchecked(&self) -> Option
; - /// Output the length of the `encode_inner(out`, true). Note to assume that `with_header` is - /// only `true`. - fn payload_len_inner(&self) -> usize; - - /// Returns the length without an RLP header - this is used for eth/68 sizes. - fn length_without_header(&self) -> usize; - /// Create a new signed transaction from a transaction and its signature. /// /// This will also calculate the transaction hash using its encoding.