From 391a50944371aed0f07141022a689f5bcac71472 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 15 Nov 2022 16:24:13 +0100 Subject: [PATCH] feat: add FromRecoveredTransaction conversion trait (#207) --- crates/primitives/src/lib.rs | 4 +- crates/primitives/src/transaction/mod.rs | 32 +++++++++---- crates/transaction-pool/src/test_util/mock.rs | 47 ++++++++++++++++++- crates/transaction-pool/src/traits.rs | 4 +- 4 files changed, 74 insertions(+), 13 deletions(-) diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 4c172e4d3c..aaff276389 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -42,8 +42,8 @@ pub use log::Log; pub use receipt::Receipt; pub use storage::StorageEntry; pub use transaction::{ - AccessList, AccessListItem, Signature, Transaction, TransactionKind, TransactionSigned, - TransactionSignedEcRecovered, TxType, + AccessList, AccessListItem, FromRecoveredTransaction, Signature, Transaction, TransactionKind, + TransactionSigned, TransactionSignedEcRecovered, TxType, }; /// A block hash. diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index c6953f14ca..6a6dd826b0 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1,8 +1,3 @@ -mod access_list; -mod signature; -mod tx_type; -mod util; - use crate::{Address, Bytes, ChainId, TxHash, H256, U256}; pub use access_list::{AccessList, AccessListItem}; use bytes::{Buf, BytesMut}; @@ -13,13 +8,18 @@ use reth_rlp::{length_of_length, Decodable, DecodeError, Encodable, Header, EMPT pub use signature::Signature; pub use tx_type::TxType; +mod access_list; +mod signature; +mod tx_type; +mod util; + /// A raw transaction. /// /// Transaction types were introduced in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718). #[main_codec] #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Transaction { - /// Legacy transaciton. + /// Legacy transaction. Legacy { /// Added as EIP-155: Simple replay attack protection chain_id: Option, @@ -707,10 +707,25 @@ impl TransactionSignedEcRecovered { } } +/// A transaction type that can be created from a [`TransactionSignedEcRecovered`] transaction. +/// +/// This is a conversion trait that'll ensure transactions received via P2P can be converted to the +/// transaction type that the transaction pool uses. +pub trait FromRecoveredTransaction { + /// Converts to this type from the given [`TransactionSignedEcRecovered`]. + fn from_recovered_transaction(tx: TransactionSignedEcRecovered) -> Self; +} + +// Noop conversion +impl FromRecoveredTransaction for TransactionSignedEcRecovered { + #[inline] + fn from_recovered_transaction(tx: TransactionSignedEcRecovered) -> Self { + tx + } +} + #[cfg(test)] mod tests { - use std::str::FromStr; - use crate::{ transaction::{signature::Signature, TransactionKind}, AccessList, Address, Bytes, Transaction, TransactionSigned, H256, U256, @@ -718,6 +733,7 @@ mod tests { use bytes::BytesMut; use ethers_core::utils::hex; use reth_rlp::{Decodable, Encodable}; + use std::str::FromStr; #[test] fn test_decode_create() { diff --git a/crates/transaction-pool/src/test_util/mock.rs b/crates/transaction-pool/src/test_util/mock.rs index d5e5d3795e..31da05f5a8 100644 --- a/crates/transaction-pool/src/test_util/mock.rs +++ b/crates/transaction-pool/src/test_util/mock.rs @@ -11,7 +11,10 @@ use rand::{ distributions::{Uniform, WeightedIndex}, prelude::Distribution, }; -use reth_primitives::{Address, TxHash, H256, U256}; +use reth_primitives::{ + Address, FromRecoveredTransaction, Transaction, TransactionSignedEcRecovered, TxHash, H256, + U256, +}; use std::{ops::Range, sync::Arc, time::Instant}; pub type MockTxPool = TxPool; @@ -333,6 +336,48 @@ impl PoolTransaction for MockTransaction { } } +impl FromRecoveredTransaction for MockTransaction { + fn from_recovered_transaction(tx: TransactionSignedEcRecovered) -> Self { + let sender = tx.signer(); + let transaction = tx.into_signed(); + let hash = transaction.hash; + match transaction.transaction { + Transaction::Legacy { chain_id, nonce, gas_price, gas_limit, to, value, input } => { + MockTransaction::Legacy { + hash, + sender, + nonce, + gas_price: gas_price.into(), + gas_limit, + value, + } + } + Transaction::Eip1559 { + chain_id, + nonce, + gas_limit, + max_fee_per_gas, + max_priority_fee_per_gas, + to, + value, + input, + access_list, + } => MockTransaction::Eip1559 { + hash, + sender, + nonce, + max_fee_per_gas: max_fee_per_gas.into(), + max_priority_fee_per_gas: max_priority_fee_per_gas.into(), + gas_limit, + value, + }, + Transaction::Eip2930 { .. } => { + unimplemented!() + } + } + } +} + #[derive(Default)] pub struct MockTransactionFactory { pub ids: SenderIdentifiers, diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 81caa7206c..e07821eebf 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1,6 +1,6 @@ use crate::{error::PoolResult, pool::state::SubPool, validate::ValidPoolTransaction, BlockID}; use futures::{channel::mpsc::Receiver, future::Shared}; -use reth_primitives::{Address, TxHash, H256, U256}; +use reth_primitives::{Address, FromRecoveredTransaction, TxHash, H256, U256}; use std::{fmt, sync::Arc}; /// General purpose abstraction fo a transaction-pool. @@ -174,7 +174,7 @@ impl BestTransactions for std::iter::Empty { } /// Trait for transaction types used inside the pool -pub trait PoolTransaction: fmt::Debug + Send + Sync + 'static { +pub trait PoolTransaction: fmt::Debug + Send + Sync + FromRecoveredTransaction { /// Hash of the transaction. fn hash(&self) -> &TxHash;