reth_payload_util/
transaction.rs1use crate::PayloadTransactions;
2use alloy_consensus::Transaction;
3use alloy_primitives::Address;
4use reth_primitives::RecoveredTx;
5
6#[derive(Debug)]
12pub struct PayloadTransactionsFixed<T> {
13 transactions: Vec<T>,
14 index: usize,
15}
16
17impl<T> PayloadTransactionsFixed<T> {
18 pub fn new(transactions: Vec<T>) -> Self {
20 Self { transactions, index: Default::default() }
21 }
22
23 pub fn single(transaction: T) -> Self {
25 Self { transactions: vec![transaction], index: Default::default() }
26 }
27}
28
29impl<T: Clone> PayloadTransactions for PayloadTransactionsFixed<RecoveredTx<T>> {
30 type Transaction = T;
31
32 fn next(&mut self, _ctx: ()) -> Option<RecoveredTx<T>> {
33 (self.index < self.transactions.len()).then(|| {
34 let tx = self.transactions[self.index].clone();
35 self.index += 1;
36 tx
37 })
38 }
39
40 fn mark_invalid(&mut self, _sender: Address, _nonce: u64) {}
41}
42
43#[derive(Debug)]
56pub struct PayloadTransactionsChain<B: PayloadTransactions, A: PayloadTransactions> {
57 before: B,
59 before_max_gas: Option<u64>,
62 before_gas: u64,
64 after: A,
66 after_max_gas: Option<u64>,
69 after_gas: u64,
71}
72
73impl<B: PayloadTransactions, A: PayloadTransactions> PayloadTransactionsChain<B, A> {
74 pub fn new(
76 before: B,
77 before_max_gas: Option<u64>,
78 after: A,
79 after_max_gas: Option<u64>,
80 ) -> Self {
81 Self {
82 before,
83 before_max_gas,
84 before_gas: Default::default(),
85 after,
86 after_max_gas,
87 after_gas: Default::default(),
88 }
89 }
90}
91
92impl<A, B> PayloadTransactions for PayloadTransactionsChain<A, B>
93where
94 A: PayloadTransactions<Transaction: Transaction>,
95 B: PayloadTransactions<Transaction = A::Transaction>,
96{
97 type Transaction = A::Transaction;
98
99 fn next(&mut self, ctx: ()) -> Option<RecoveredTx<Self::Transaction>> {
100 while let Some(tx) = self.before.next(ctx) {
101 if let Some(before_max_gas) = self.before_max_gas {
102 if self.before_gas + tx.as_signed().gas_limit() <= before_max_gas {
103 self.before_gas += tx.as_signed().gas_limit();
104 return Some(tx);
105 }
106 self.before.mark_invalid(tx.signer(), tx.as_signed().nonce());
107 self.after.mark_invalid(tx.signer(), tx.as_signed().nonce());
108 } else {
109 return Some(tx);
110 }
111 }
112
113 while let Some(tx) = self.after.next(ctx) {
114 if let Some(after_max_gas) = self.after_max_gas {
115 if self.after_gas + tx.as_signed().gas_limit() <= after_max_gas {
116 self.after_gas += tx.as_signed().gas_limit();
117 return Some(tx);
118 }
119 self.after.mark_invalid(tx.signer(), tx.as_signed().nonce());
120 } else {
121 return Some(tx);
122 }
123 }
124
125 None
126 }
127
128 fn mark_invalid(&mut self, sender: Address, nonce: u64) {
129 self.before.mark_invalid(sender, nonce);
130 self.after.mark_invalid(sender, nonce);
131 }
132}