From 7fca8ceb3fe0809fd5583f8e203001332e7d4f24 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 7 Jan 2025 21:21:05 +0100 Subject: [PATCH] feat: add standalone rayon recovery functions (#13710) --- crates/primitives-traits/src/block/body.rs | 21 +----- crates/primitives-traits/src/lib.rs | 1 + .../primitives-traits/src/transaction/mod.rs | 1 + .../src/transaction/recover.rs | 68 +++++++++++++++++++ 4 files changed, 72 insertions(+), 19 deletions(-) create mode 100644 crates/primitives-traits/src/transaction/recover.rs diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 58fe3c4b43..279e7d45cc 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -13,9 +13,6 @@ pub trait FullBlockBody: BlockBody + MaybeSerdeBincod impl FullBlockBody for T where T: BlockBody + MaybeSerdeBincodeCompat {} -#[cfg(feature = "rayon")] -use rayon::prelude::*; - /// Abstraction for block's body. pub trait BlockBody: Send @@ -115,14 +112,7 @@ pub trait BlockBody: where Self::Transaction: SignedTransaction, { - #[cfg(feature = "rayon")] - { - self.transactions().into_par_iter().map(|tx| tx.recover_signer()).collect() - } - #[cfg(not(feature = "rayon"))] - { - self.transactions().iter().map(|tx| tx.recover_signer()).collect() - } + crate::transaction::recover::recover_signers(self.transactions()) } /// Recover signer addresses for all transactions in the block body _without ensuring that the @@ -133,14 +123,7 @@ pub trait BlockBody: where Self::Transaction: SignedTransaction, { - #[cfg(feature = "rayon")] - { - self.transactions().into_par_iter().map(|tx| tx.recover_signer_unchecked()).collect() - } - #[cfg(not(feature = "rayon"))] - { - self.transactions().iter().map(|tx| tx.recover_signer_unchecked()).collect() - } + crate::transaction::recover::recover_signers_unchecked(self.transactions()) } } diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 322ed33eda..c5d9b710c1 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -16,6 +16,7 @@ //! - `serde`: Adds serde support for all types. //! - `secp256k1`: Adds secp256k1 support for transaction signing/recovery. (By default the no-std //! friendly `k256` is used) +//! - `rayon`: Uses `rayon` for parallel transaction sender recovery in [`BlockBody`] by default. #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", diff --git a/crates/primitives-traits/src/transaction/mod.rs b/crates/primitives-traits/src/transaction/mod.rs index 15b3df7fdb..43fe7899d9 100644 --- a/crates/primitives-traits/src/transaction/mod.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -5,6 +5,7 @@ pub mod signature; pub mod signed; pub mod error; +pub mod recover; pub use alloy_consensus::transaction::{TransactionInfo, TransactionMeta}; diff --git a/crates/primitives-traits/src/transaction/recover.rs b/crates/primitives-traits/src/transaction/recover.rs new file mode 100644 index 0000000000..cad57bc266 --- /dev/null +++ b/crates/primitives-traits/src/transaction/recover.rs @@ -0,0 +1,68 @@ +//! Helpers for recovering signers from a set of transactions + +#[cfg(feature = "rayon")] +pub use rayon::*; + +#[cfg(not(feature = "rayon"))] +pub use iter::*; + +#[cfg(feature = "rayon")] +mod rayon { + use crate::SignedTransaction; + use alloc::vec::Vec; + use alloy_primitives::Address; + use rayon::prelude::{IntoParallelIterator, ParallelIterator}; + + /// Recovers a list of signers from a transaction list iterator. + /// + /// Returns `None`, if some transaction's signature is invalid + pub fn recover_signers<'a, I, T>(txes: I) -> Option> + where + T: SignedTransaction, + I: IntoParallelIterator + IntoIterator + Send, + { + txes.into_par_iter().map(|tx| tx.recover_signer()).collect() + } + + /// Recovers a list of signers from a transaction list iterator _without ensuring that the + /// signature has a low `s` value_. + /// + /// Returns `None`, if some transaction's signature is invalid. + pub fn recover_signers_unchecked<'a, I, T>(txes: I) -> Option> + where + T: SignedTransaction, + I: IntoParallelIterator + IntoIterator + Send, + { + txes.into_par_iter().map(|tx| tx.recover_signer_unchecked()).collect() + } +} + +#[cfg(not(feature = "rayon"))] +mod iter { + use crate::SignedTransaction; + use alloc::vec::Vec; + use alloy_primitives::Address; + + /// Recovers a list of signers from a transaction list iterator. + /// + /// Returns `None`, if some transaction's signature is invalid + pub fn recover_signers<'a, I, T>(txes: I) -> Option> + where + T: SignedTransaction, + I: IntoIterator + IntoIterator, + { + txes.into_iter().map(|tx| tx.recover_signer()).collect() + } + + /// Recovers a list of signers from a transaction list iterator _without ensuring that the + /// signature has a low `s` value_. + /// + /// Returns `None`, if some transaction's signature is invalid. + pub fn recover_signers_unchecked<'a, I, T>(txes: I) -> Option> + where + T: SignedTransaction, + I: IntoIterator + IntoIterator, + { + txes.into_iter().map(|tx| tx.recover_signer_unchecked()).collect() + } +}