1use crate::{execute::ExecutableTxFor, ConfigureEvm, EvmEnvFor, ExecutionCtxFor, TxEnvFor};
2use alloy_consensus::transaction::Either;
3use alloy_evm::{block::ExecutableTxParts, RecoveredTx};
4use rayon::prelude::*;
5use reth_primitives_traits::TxTy;
6
7pub trait ConfigureEngineEvm<ExecutionData>: ConfigureEvm {
9 fn evm_env_for_payload(&self, payload: &ExecutionData) -> Result<EvmEnvFor<Self>, Self::Error>;
11
12 fn context_for_payload<'a>(
14 &self,
15 payload: &'a ExecutionData,
16 ) -> Result<ExecutionCtxFor<'a, Self>, Self::Error>;
17
18 fn tx_iterator_for_payload(
20 &self,
21 payload: &ExecutionData,
22 ) -> Result<impl ExecutableTxIterator<Self>, Self::Error>;
23}
24
25pub trait ConvertTx<RawTx>: Send + Sync + 'static {
30 type Tx;
32 type Error;
34 fn convert(&self, raw: RawTx) -> Result<Self::Tx, Self::Error>;
36}
37
38impl<F, RawTx, Tx, Err> ConvertTx<RawTx> for F
40where
41 F: Fn(RawTx) -> Result<Tx, Err> + Send + Sync + 'static,
42{
43 type Tx = Tx;
44 type Error = Err;
45 fn convert(&self, raw: RawTx) -> Result<Tx, Err> {
46 self(raw)
47 }
48}
49
50impl<A, B, RA, RB> ConvertTx<Either<RA, RB>> for Either<A, B>
51where
52 A: ConvertTx<RA>,
53 B: ConvertTx<RB>,
54{
55 type Tx = Either<A::Tx, B::Tx>;
56 type Error = Either<A::Error, B::Error>;
57 fn convert(&self, raw: Either<RA, RB>) -> Result<Self::Tx, Self::Error> {
58 match (self, raw) {
59 (Self::Left(a), Either::Left(raw)) => {
60 a.convert(raw).map(Either::Left).map_err(Either::Left)
61 }
62 (Self::Right(b), Either::Right(raw)) => {
63 b.convert(raw).map(Either::Right).map_err(Either::Right)
64 }
65 _ => unreachable!(),
66 }
67 }
68}
69
70pub trait ExecutableTxTuple: Send + 'static {
74 type RawTx: Send + Sync + 'static;
79 type Tx: Clone + Send + Sync + 'static;
81 type Error: core::error::Error + Send + Sync + 'static;
83
84 type IntoIter: IntoParallelIterator<Item = Self::RawTx, Iter: IndexedParallelIterator>
86 + IntoIterator<Item = Self::RawTx, IntoIter: Send>
87 + Send
88 + 'static;
89 type Convert: ConvertTx<Self::RawTx, Tx = Self::Tx, Error = Self::Error>;
93
94 fn into_parts(self) -> (Self::IntoIter, Self::Convert);
96}
97
98impl<RawTx, Tx, Err, I, F> ExecutableTxTuple for (I, F)
99where
100 RawTx: Send + Sync + 'static,
101 Tx: Clone + Send + Sync + 'static,
102 Err: core::error::Error + Send + Sync + 'static,
103 I: IntoParallelIterator<Item = RawTx, Iter: IndexedParallelIterator>
104 + IntoIterator<Item = RawTx, IntoIter: Send>
105 + Send
106 + 'static,
107 F: Fn(RawTx) -> Result<Tx, Err> + Send + Sync + 'static,
108{
109 type RawTx = RawTx;
110 type Tx = Tx;
111 type Error = Err;
112
113 type IntoIter = I;
114 type Convert = F;
115
116 fn into_parts(self) -> (I, F) {
117 self
118 }
119}
120
121pub trait ExecutableTxIterator<Evm: ConfigureEvm>:
126 ExecutableTxTuple<Tx: ExecutableTxFor<Evm, Recovered = Self::Recovered>>
127{
128 type Recovered: RecoveredTx<TxTy<Evm::Primitives>> + Send + Sync;
131}
132
133impl<T, Evm: ConfigureEvm> ExecutableTxIterator<Evm> for T
134where
135 T: ExecutableTxTuple<Tx: ExecutableTxFor<Evm, Recovered: Send + Sync>>,
136{
137 type Recovered = <T::Tx as ExecutableTxParts<TxEnvFor<Evm>, TxTy<Evm::Primitives>>>::Recovered;
138}
139
140#[derive(Debug)]
143pub struct EitherIter<L, R>(Either<L, R>);
144
145impl<L, R> IntoParallelIterator for EitherIter<L, R>
146where
147 L: IntoParallelIterator,
148 R: IntoParallelIterator,
149 L::Iter: IndexedParallelIterator,
150 R::Iter: IndexedParallelIterator,
151{
152 type Item = Either<L::Item, R::Item>;
153 type Iter = Either<
154 rayon::iter::Map<L::Iter, fn(L::Item) -> Either<L::Item, R::Item>>,
155 rayon::iter::Map<R::Iter, fn(R::Item) -> Either<L::Item, R::Item>>,
156 >;
157
158 fn into_par_iter(self) -> Self::Iter {
159 match self.0 {
160 Either::Left(l) => Either::Left(l.into_par_iter().map(Either::Left)),
161 Either::Right(r) => Either::Right(r.into_par_iter().map(Either::Right)),
162 }
163 }
164}
165
166impl<L, R> IntoIterator for EitherIter<L, R>
167where
168 L: IntoIterator,
169 R: IntoIterator,
170{
171 type Item = Either<L::Item, R::Item>;
172 type IntoIter = Either<
173 core::iter::Map<L::IntoIter, fn(L::Item) -> Either<L::Item, R::Item>>,
174 core::iter::Map<R::IntoIter, fn(R::Item) -> Either<L::Item, R::Item>>,
175 >;
176
177 fn into_iter(self) -> Self::IntoIter {
178 match self.0 {
179 Either::Left(l) => Either::Left(l.into_iter().map(Either::Left)),
180 Either::Right(r) => Either::Right(r.into_iter().map(Either::Right)),
181 }
182 }
183}
184
185unsafe impl<L: Send, R: Send> Send for EitherIter<L, R> {}
187
188impl<A: ExecutableTxTuple, B: ExecutableTxTuple> ExecutableTxTuple for Either<A, B> {
189 type RawTx = Either<A::RawTx, B::RawTx>;
190 type Tx = Either<A::Tx, B::Tx>;
191 type Error = Either<A::Error, B::Error>;
192 type IntoIter = EitherIter<A::IntoIter, B::IntoIter>;
193 type Convert = Either<A::Convert, B::Convert>;
194
195 fn into_parts(self) -> (Self::IntoIter, Self::Convert) {
196 match self {
197 Self::Left(a) => {
198 let (iter, convert) = a.into_parts();
199 (EitherIter(Either::Left(iter)), Either::Left(convert))
200 }
201 Self::Right(b) => {
202 let (iter, convert) = b.into_parts();
203 (EitherIter(Either::Right(iter)), Either::Right(convert))
204 }
205 }
206 }
207}