feat: add standalone rayon recovery functions (#13710)

This commit is contained in:
Matthias Seitz
2025-01-07 21:21:05 +01:00
committed by GitHub
parent 35392bd8e9
commit 7fca8ceb3f
4 changed files with 72 additions and 19 deletions

View File

@ -13,9 +13,6 @@ pub trait FullBlockBody: BlockBody<Transaction: FullSignedTx> + MaybeSerdeBincod
impl<T> FullBlockBody for T where T: BlockBody<Transaction: FullSignedTx> + 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())
}
}

View File

@ -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",

View File

@ -5,6 +5,7 @@ pub mod signature;
pub mod signed;
pub mod error;
pub mod recover;
pub use alloy_consensus::transaction::{TransactionInfo, TransactionMeta};

View File

@ -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<Vec<Address>>
where
T: SignedTransaction,
I: IntoParallelIterator<Item = &'a T> + IntoIterator<Item = &'a T> + 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<Vec<Address>>
where
T: SignedTransaction,
I: IntoParallelIterator<Item = &'a T> + IntoIterator<Item = &'a T> + 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<Vec<Address>>
where
T: SignedTransaction,
I: IntoIterator<Item = &'a T> + IntoIterator<Item = &'a T>,
{
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<Vec<Address>>
where
T: SignedTransaction,
I: IntoIterator<Item = &'a T> + IntoIterator<Item = &'a T>,
{
txes.into_iter().map(|tx| tx.recover_signer_unchecked()).collect()
}
}