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