@@ -87,6 +87,94 @@ impl<B, R> BundleProcessor<B, R> {
87
87
}
88
88
}
89
89
90
+ impl BundleProcessor < EthCallBundle , EthCallBundleResponse > {
91
+ /// Create a new bundle simulator with the given bundle.
92
+ pub fn new_call ( bundle : EthCallBundle ) -> Self {
93
+ Self :: new ( bundle, EthCallBundleResponse :: default ( ) )
94
+ }
95
+
96
+ /// Process a bundle transaction and accumulate the results into a [EthCallBundleTransactionResult].
97
+ pub fn process_bundle_tx < Db : revm:: Database > (
98
+ tx : & TxEnvelope ,
99
+ pre_sim_coinbase_balance : U256 ,
100
+ post_sim_coinbase_balance : U256 ,
101
+ basefee : U256 ,
102
+ execution_result : ExecutionResult ,
103
+ ) -> Result < ( EthCallBundleTransactionResult , U256 ) , BundleError < Db > > {
104
+ let gas_used = execution_result. gas_used ( ) ;
105
+
106
+ // Calculate the gas price
107
+ let gas_price = match tx {
108
+ TxEnvelope :: Legacy ( tx) => U256 :: from ( tx. tx ( ) . gas_price ) ,
109
+ TxEnvelope :: Eip2930 ( tx) => U256 :: from ( tx. tx ( ) . gas_price ) ,
110
+ TxEnvelope :: Eip1559 ( tx) => {
111
+ U256 :: from ( tx. tx ( ) . effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
112
+ }
113
+ TxEnvelope :: Eip4844 ( tx) => match tx. tx ( ) {
114
+ TxEip4844Variant :: TxEip4844 ( tx) => {
115
+ U256 :: from ( tx. effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
116
+ }
117
+ TxEip4844Variant :: TxEip4844WithSidecar ( tx) => {
118
+ U256 :: from ( tx. tx . effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
119
+ }
120
+ } ,
121
+ _ => return Err ( BundleError :: UnsupportedTransactionType ) ,
122
+ } ;
123
+
124
+ // Calculate the gas fees paid
125
+ let gas_fees = match tx {
126
+ TxEnvelope :: Legacy ( tx) => U256 :: from ( tx. tx ( ) . gas_price ) * U256 :: from ( gas_used) ,
127
+ TxEnvelope :: Eip2930 ( tx) => U256 :: from ( tx. tx ( ) . gas_price ) * U256 :: from ( gas_used) ,
128
+ TxEnvelope :: Eip1559 ( tx) => {
129
+ U256 :: from ( tx. tx ( ) . effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
130
+ * U256 :: from ( gas_used)
131
+ }
132
+ TxEnvelope :: Eip4844 ( tx) => match tx. tx ( ) {
133
+ TxEip4844Variant :: TxEip4844 ( tx) => {
134
+ U256 :: from ( tx. effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
135
+ * U256 :: from ( gas_used)
136
+ }
137
+ TxEip4844Variant :: TxEip4844WithSidecar ( tx) => {
138
+ U256 :: from ( tx. tx . effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
139
+ * U256 :: from ( gas_used)
140
+ }
141
+ } ,
142
+ _ => return Err ( BundleError :: UnsupportedTransactionType ) ,
143
+ } ;
144
+
145
+ // set the return data for the response
146
+ let ( value, revert) = if execution_result. is_success ( ) {
147
+ let value = execution_result. into_output ( ) . unwrap_or_default ( ) ;
148
+ ( Some ( value) , None )
149
+ } else {
150
+ let revert = execution_result. into_output ( ) . unwrap_or_default ( ) ;
151
+ ( None , Some ( revert) )
152
+ } ;
153
+
154
+ let coinbase_diff = post_sim_coinbase_balance. saturating_sub ( pre_sim_coinbase_balance) ;
155
+ let eth_sent_to_coinbase = coinbase_diff. saturating_sub ( gas_fees) ;
156
+
157
+ Ok ( (
158
+ EthCallBundleTransactionResult {
159
+ tx_hash : * tx. tx_hash ( ) ,
160
+ coinbase_diff,
161
+ eth_sent_to_coinbase,
162
+ from_address : tx. recover_signer ( ) ?,
163
+ to_address : match tx. to ( ) {
164
+ TxKind :: Call ( to) => Some ( to) ,
165
+ _ => Some ( Address :: ZERO ) ,
166
+ } ,
167
+ value,
168
+ revert,
169
+ gas_used,
170
+ gas_price,
171
+ gas_fees,
172
+ } ,
173
+ post_sim_coinbase_balance,
174
+ ) )
175
+ }
176
+ }
177
+
90
178
impl < Ext > BundleDriver < Ext > for BundleProcessor < EthCallBundle , EthCallBundleResponse > {
91
179
type Error < Db : revm:: Database > = BundleError < Db > ;
92
180
@@ -175,19 +263,9 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthCallBundle, EthCallBundleResp
175
263
Ok ( res) => {
176
264
let ( execution_result, mut committed_trevm) = res. accept ( ) ;
177
265
266
+ // Get the coinbase and basefee from the block
178
267
let coinbase = committed_trevm. inner ( ) . block ( ) . coinbase ;
179
268
let basefee = committed_trevm. inner ( ) . block ( ) . basefee ;
180
- let gas_used = execution_result. gas_used ( ) ;
181
-
182
- // Fetch the address and coinbase balance after the transaction, to start calculating and results
183
- let from_address = unwrap_or_trevm_err ! (
184
- tx. recover_signer( )
185
- . map_err( |e| BundleError :: TransactionSenderRecoveryError ( e) ) ,
186
- committed_trevm
187
- ) ;
188
-
189
- // Extend the hash bytes with the transaction hash to calculate the bundle hash later
190
- hash_bytes. extend_from_slice ( tx. tx_hash ( ) . as_slice ( ) ) ;
191
269
192
270
// Get the post simulation coinbase balance
193
271
let post_sim_coinbase_balance = unwrap_or_trevm_err ! (
@@ -199,98 +277,33 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthCallBundle, EthCallBundleResp
199
277
committed_trevm
200
278
) ;
201
279
202
- // Calculate the gas fees paid
203
- let gas_fees = match tx {
204
- TxEnvelope :: Legacy ( tx) => {
205
- U256 :: from ( tx. tx ( ) . gas_price ) * U256 :: from ( gas_used)
206
- }
207
- TxEnvelope :: Eip2930 ( tx) => {
208
- U256 :: from ( tx. tx ( ) . gas_price ) * U256 :: from ( gas_used)
209
- }
210
- TxEnvelope :: Eip1559 ( tx) => {
211
- U256 :: from ( tx. tx ( ) . effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
212
- * U256 :: from ( gas_used)
213
- }
214
- TxEnvelope :: Eip4844 ( tx) => match tx. tx ( ) {
215
- TxEip4844Variant :: TxEip4844 ( tx) => {
216
- U256 :: from ( tx. effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
217
- * U256 :: from ( gas_used)
218
- }
219
- TxEip4844Variant :: TxEip4844WithSidecar ( tx) => {
220
- U256 :: from ( tx. tx . effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
221
- * U256 :: from ( gas_used)
222
- }
223
- } ,
224
- _ => {
225
- trevm_bail ! (
226
- committed_trevm,
227
- BundleError :: UnsupportedTransactionType
228
- )
229
- }
230
- } ;
231
-
232
- // Calculate the gas price
233
- let gas_price = match tx {
234
- TxEnvelope :: Legacy ( tx) => U256 :: from ( tx. tx ( ) . gas_price ) ,
235
- TxEnvelope :: Eip2930 ( tx) => U256 :: from ( tx. tx ( ) . gas_price ) ,
236
- TxEnvelope :: Eip1559 ( tx) => {
237
- U256 :: from ( tx. tx ( ) . effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
238
- }
239
- TxEnvelope :: Eip4844 ( tx) => match tx. tx ( ) {
240
- TxEip4844Variant :: TxEip4844 ( tx) => {
241
- U256 :: from ( tx. effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
242
- }
243
- TxEip4844Variant :: TxEip4844WithSidecar ( tx) => {
244
- U256 :: from ( tx. tx . effective_gas_price ( Some ( basefee. to :: < u64 > ( ) ) ) )
245
- }
246
- } ,
247
- _ => {
248
- trevm_bail ! (
249
- committed_trevm,
250
- BundleError :: UnsupportedTransactionType
251
- )
252
- }
253
- } ;
254
-
255
- let coinbase_diff =
256
- post_sim_coinbase_balance. saturating_sub ( pre_sim_coinbase_balance) ;
257
- let eth_sent_to_coinbase = coinbase_diff. saturating_sub ( gas_fees) ;
258
-
259
- total_gas_used += execution_result. gas_used ( ) ;
260
- total_gas_fees += gas_fees;
280
+ // Process the transaction and accumulate the results
281
+ let ( response, post_sim_coinbase_balance) = unwrap_or_trevm_err ! (
282
+ Self :: process_bundle_tx(
283
+ tx,
284
+ pre_sim_coinbase_balance,
285
+ post_sim_coinbase_balance,
286
+ basefee,
287
+ execution_result
288
+ ) ,
289
+ committed_trevm
290
+ ) ;
291
+
292
+ // Accumulate overall results from response
293
+ total_gas_used += response. gas_used ;
294
+ total_gas_fees += response. gas_fees ;
295
+ self . response . results . push ( response) ;
296
+ hash_bytes. extend_from_slice ( tx. tx_hash ( ) . as_slice ( ) ) ;
261
297
262
298
// update the coinbase balance
263
299
pre_sim_coinbase_balance = post_sim_coinbase_balance;
264
300
265
- // set the return data for the response
266
- let ( value, revert) = if execution_result. is_success ( ) {
267
- let value = execution_result. into_output ( ) . unwrap_or_default ( ) ;
268
- ( Some ( value) , None )
269
- } else {
270
- let revert = execution_result. into_output ( ) . unwrap_or_default ( ) ;
271
- ( None , Some ( revert) )
272
- } ;
273
-
274
- // Push the result of the bundle's transaction to the response
275
- self . response . results . push ( EthCallBundleTransactionResult {
276
- tx_hash : * tx. tx_hash ( ) ,
277
- coinbase_diff,
278
- eth_sent_to_coinbase,
279
- from_address,
280
- to_address : match tx. to ( ) {
281
- TxKind :: Call ( to) => Some ( to) ,
282
- _ => Some ( Address :: ZERO ) ,
283
- } ,
284
- value,
285
- revert,
286
- gas_used,
287
- gas_price,
288
- gas_fees,
289
- } ) ;
301
+ // Set the trevm instance to the committed one
290
302
trevm = committed_trevm;
291
303
}
292
304
}
293
305
}
306
+
294
307
// Accumulate the total results
295
308
self . response . total_gas_used = total_gas_used;
296
309
self . response . coinbase_diff =
0 commit comments