@@ -3,7 +3,7 @@ use crate::{
3
3
} ;
4
4
use alloy_consensus:: { Transaction , TxEip4844Variant , TxEnvelope } ;
5
5
use alloy_eips:: { eip2718:: Decodable2718 , BlockNumberOrTag } ;
6
- use alloy_primitives:: { bytes:: Buf , keccak256, Address , TxKind , U256 } ;
6
+ use alloy_primitives:: { bytes:: Buf , keccak256, Address , Bytes , TxKind , U256 } ;
7
7
use alloy_rpc_types_mev:: {
8
8
EthBundleHash , EthCallBundle , EthCallBundleResponse , EthCallBundleTransactionResult ,
9
9
EthSendBundle ,
@@ -87,6 +87,30 @@ impl<B, R> BundleProcessor<B, R> {
87
87
}
88
88
}
89
89
90
+ impl < B , R > BundleProcessor < B , R > {
91
+ /// Decode and validate the transactions in the bundle, performing EIP4844 gas checks.
92
+ pub fn decode_and_validate_txs < Db : revm:: Database > (
93
+ txs : & [ Bytes ] ,
94
+ ) -> Result < Vec < TxEnvelope > , BundleError < Db > > {
95
+ let txs = txs
96
+ . iter ( )
97
+ . map ( |tx| TxEnvelope :: decode_2718 ( & mut tx. chunk ( ) ) )
98
+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
99
+
100
+ if txs
101
+ . iter ( )
102
+ . filter_map ( |tx| tx. as_eip4844 ( ) )
103
+ . map ( |tx| tx. tx ( ) . tx ( ) . blob_gas ( ) )
104
+ . sum :: < u64 > ( )
105
+ > MAX_BLOB_GAS_PER_BLOCK
106
+ {
107
+ Err ( BundleError :: Eip4844BlobGasExceeded )
108
+ } else {
109
+ Ok ( txs)
110
+ }
111
+ }
112
+ }
113
+
90
114
impl BundleProcessor < EthCallBundle , EthCallBundleResponse > {
91
115
/// Create a new bundle simulator with the given bundle.
92
116
pub fn new_call ( bundle : EthCallBundle ) -> Self {
@@ -214,25 +238,8 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthCallBundle, EthCallBundleResp
214
238
// Therefore we keep this mutable trevm instance, and set it to the new one after we're done simulating.
215
239
let mut trevm = trevm;
216
240
217
- let txs = unwrap_or_trevm_err ! (
218
- self . bundle
219
- . txs
220
- . iter( )
221
- . map( |tx| TxEnvelope :: decode_2718( & mut tx. chunk( ) ) )
222
- . collect:: <Result <Vec <_>, _>>( ) ,
223
- trevm
224
- ) ;
225
-
226
- // Check that the bundle does not exceed the maximum gas limit for blob transactions
227
- trevm_ensure ! (
228
- txs. iter( )
229
- . filter_map( |tx| tx. as_eip4844( ) )
230
- . map( |tx| tx. tx( ) . tx( ) . blob_gas( ) )
231
- . sum:: <u64 >( )
232
- <= MAX_BLOB_GAS_PER_BLOCK ,
233
- trevm,
234
- BundleError :: Eip4844BlobGasExceeded
235
- ) ;
241
+ // Decode and validate the transactions in the bundle
242
+ let txs = unwrap_or_trevm_err ! ( Self :: decode_and_validate_txs( & self . bundle. txs) , trevm) ;
236
243
237
244
// Cache the pre simulation coinbase balance, so we can use it to calculate the coinbase diff after every tx simulated.
238
245
let initial_coinbase_balance =
@@ -372,25 +379,8 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthSendBundle, EthBundleHash> {
372
379
// Check if the bundle has any transactions
373
380
trevm_ensure ! ( !self . bundle. txs. is_empty( ) , trevm, BundleError :: BundleEmpty ) ;
374
381
375
- let txs = unwrap_or_trevm_err ! (
376
- self . bundle
377
- . txs
378
- . iter( )
379
- . map( |tx| TxEnvelope :: decode_2718( & mut tx. chunk( ) ) )
380
- . collect:: <Result <Vec <_>, _>>( ) ,
381
- trevm
382
- ) ;
383
-
384
- // Check that the bundle does not exceed the maximum gas limit for blob transactions
385
- if txs
386
- . iter ( )
387
- . filter_map ( |tx| tx. as_eip4844 ( ) )
388
- . map ( |tx| tx. tx ( ) . tx ( ) . blob_gas ( ) )
389
- . sum :: < u64 > ( )
390
- > MAX_BLOB_GAS_PER_BLOCK
391
- {
392
- return Err ( trevm. errored ( BundleError :: Eip4844BlobGasExceeded ) ) ;
393
- }
382
+ // Decode and validate the transactions in the bundle
383
+ let txs = unwrap_or_trevm_err ! ( Self :: decode_and_validate_txs( & self . bundle. txs) , trevm) ;
394
384
395
385
// Store the current evm state in this mutable variable, so we can continually use the freshest state for each simulation
396
386
let mut t = trevm;
0 commit comments