1
- use crate :: { Block , BundleDriver , DriveBundleResult } ;
1
+ use crate :: {
2
+ trevm_bail, trevm_ensure, unwrap_or_trevm_err, Block , BundleDriver , DriveBundleResult ,
3
+ } ;
2
4
use alloy_consensus:: { Transaction , TxEip4844Variant , TxEnvelope } ;
3
5
use alloy_eips:: { eip2718:: Decodable2718 , BlockNumberOrTag } ;
4
6
use alloy_primitives:: { bytes:: Buf , keccak256, Address , TxKind , U256 } ;
@@ -93,21 +95,22 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthCallBundle, EthCallBundleResp
93
95
trevm : crate :: EvmNeedsTx < ' a , Ext , Db > ,
94
96
) -> DriveBundleResult < ' a , Ext , Db , Self > {
95
97
// Check if the block we're in is valid for this bundle. Both must match
96
- if trevm. inner ( ) . block ( ) . number . to :: < u64 > ( ) != self . bundle . block_number {
97
- return Err ( trevm. errored ( BundleError :: BlockNumberMismatch ) ) ;
98
- }
98
+ trevm_ensure ! (
99
+ trevm. inner( ) . block( ) . number. to:: <u64 >( ) == self . bundle. block_number,
100
+ trevm,
101
+ BundleError :: BlockNumberMismatch
102
+ ) ;
99
103
100
104
// Check if the bundle has any transactions
101
- if self . bundle . txs . is_empty ( ) {
102
- return Err ( trevm. errored ( BundleError :: BundleEmpty ) ) ;
103
- }
105
+ trevm_ensure ! ( !self . bundle. txs. is_empty( ) , trevm, BundleError :: BundleEmpty ) ;
104
106
105
107
// Check if the state block number is valid (not 0, and not a tag)
106
- if !self . bundle . state_block_number . is_number ( )
107
- || self . bundle . state_block_number . as_number ( ) . unwrap_or ( 0 ) == 0
108
- {
109
- return Err ( trevm. errored ( BundleError :: BlockNumberMismatch ) ) ;
110
- }
108
+ trevm_ensure ! (
109
+ self . bundle. state_block_number. is_number( )
110
+ && self . bundle. state_block_number. as_number( ) . unwrap_or( 0 ) != 0 ,
111
+ trevm,
112
+ BundleError :: BlockNumberMismatch
113
+ ) ;
111
114
112
115
// Set the state block number this simulation was based on
113
116
self . response . state_block_number = self
@@ -123,27 +126,25 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthCallBundle, EthCallBundleResp
123
126
// Therefore we keep this mutable trevm instance, and set it to the new one after we're done simulating.
124
127
let mut trevm = trevm;
125
128
126
- let txs = self
127
- . bundle
128
- . txs
129
- . iter ( )
130
- . map ( |tx| TxEnvelope :: decode_2718 ( & mut tx. chunk ( ) ) )
131
- . collect :: < Result < Vec < _ > , _ > > ( ) ;
132
- let txs = match txs {
133
- Ok ( txs) => txs,
134
- Err ( e) => return Err ( trevm. errored ( BundleError :: TransactionDecodingError ( e) ) ) ,
135
- } ;
129
+ let txs = unwrap_or_trevm_err ! (
130
+ self . bundle
131
+ . txs
132
+ . iter( )
133
+ . map( |tx| TxEnvelope :: decode_2718( & mut tx. chunk( ) ) )
134
+ . collect:: <Result <Vec <_>, _>>( ) ,
135
+ trevm
136
+ ) ;
136
137
137
138
// Check that the bundle does not exceed the maximum gas limit for blob transactions
138
- if txs
139
- . iter ( )
140
- . filter_map ( |tx| tx. as_eip4844 ( ) )
141
- . map ( |tx| tx. tx ( ) . tx ( ) . blob_gas ( ) )
142
- . sum :: < u64 > ( )
143
- > MAX_BLOB_GAS_PER_BLOCK
144
- {
145
- return Err ( trevm . errored ( BundleError :: Eip4844BlobGasExceeded ) ) ;
146
- }
139
+ trevm_ensure ! (
140
+ txs . iter( )
141
+ . filter_map( |tx| tx. as_eip4844( ) )
142
+ . map( |tx| tx. tx( ) . tx( ) . blob_gas( ) )
143
+ . sum:: <u64 >( )
144
+ <= MAX_BLOB_GAS_PER_BLOCK ,
145
+ trevm ,
146
+ BundleError :: Eip4844BlobGasExceeded
147
+ ) ;
147
148
148
149
// Cache the pre simulation coinbase balance, so we can use it to calculate the coinbase diff after every tx simulated.
149
150
let initial_coinbase_balance =
@@ -179,27 +180,24 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthCallBundle, EthCallBundleResp
179
180
let gas_used = execution_result. gas_used ( ) ;
180
181
181
182
// Fetch the address and coinbase balance after the transaction, to start calculating and results
182
- let from_address = tx
183
- . recover_signer ( )
184
- . map_err ( |e| BundleError :: TransactionSenderRecoveryError ( e) ) ;
185
- let from_address = match from_address {
186
- Ok ( addr) => addr,
187
- Err ( e) => return Err ( committed_trevm. errored ( e) ) ,
188
- } ;
183
+ let from_address = unwrap_or_trevm_err ! (
184
+ tx. recover_signer( )
185
+ . map_err( |e| BundleError :: TransactionSenderRecoveryError ( e) ) ,
186
+ committed_trevm
187
+ ) ;
189
188
190
189
// Extend the hash bytes with the transaction hash to calculate the bundle hash later
191
190
hash_bytes. extend_from_slice ( tx. tx_hash ( ) . as_slice ( ) ) ;
192
191
193
192
// Get the post simulation coinbase balance
194
- let post_sim_coinbase_balance =
195
- match committed_trevm. try_read_balance ( coinbase) {
196
- Ok ( balance) => balance,
197
- Err ( e) => {
198
- return Err ( committed_trevm. errored ( BundleError :: EVMError {
199
- inner : revm:: primitives:: EVMError :: Database ( e) ,
200
- } ) )
193
+ let post_sim_coinbase_balance = unwrap_or_trevm_err ! (
194
+ committed_trevm. try_read_balance( coinbase) . map_err( |e| {
195
+ BundleError :: EVMError {
196
+ inner: revm:: primitives:: EVMError :: Database ( e) ,
201
197
}
202
- } ;
198
+ } ) ,
199
+ committed_trevm
200
+ ) ;
203
201
204
202
// Calculate the gas fees paid
205
203
let gas_fees = match tx {
@@ -224,8 +222,10 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthCallBundle, EthCallBundleResp
224
222
}
225
223
} ,
226
224
_ => {
227
- return Err ( committed_trevm
228
- . errored ( BundleError :: UnsupportedTransactionType ) )
225
+ trevm_bail ! (
226
+ committed_trevm,
227
+ BundleError :: UnsupportedTransactionType
228
+ )
229
229
}
230
230
} ;
231
231
@@ -245,8 +245,10 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthCallBundle, EthCallBundleResp
245
245
}
246
246
} ,
247
247
_ => {
248
- return Err ( committed_trevm
249
- . errored ( BundleError :: UnsupportedTransactionType ) )
248
+ trevm_bail ! (
249
+ committed_trevm,
250
+ BundleError :: UnsupportedTransactionType
251
+ )
250
252
}
251
253
} ;
252
254
@@ -330,39 +332,41 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthSendBundle, EthBundleHash> {
330
332
) -> DriveBundleResult < ' a , Ext , Db , Self > {
331
333
{
332
334
// Check if the block we're in is valid for this bundle. Both must match
333
- if trevm. inner ( ) . block ( ) . number . to :: < u64 > ( ) != self . bundle . block_number {
334
- return Err ( trevm. errored ( BundleError :: BlockNumberMismatch ) ) ;
335
- }
335
+ trevm_ensure ! (
336
+ trevm. inner( ) . block( ) . number. to:: <u64 >( ) == self . bundle. block_number,
337
+ trevm,
338
+ BundleError :: BlockNumberMismatch
339
+ ) ;
336
340
337
341
// Check for start timestamp range validity
338
342
if let Some ( min_timestamp) = self . bundle . min_timestamp {
339
- if trevm. inner ( ) . block ( ) . timestamp . to :: < u64 > ( ) < min_timestamp {
340
- return Err ( trevm. errored ( BundleError :: TimestampOutOfRange ) ) ;
341
- }
343
+ trevm_ensure ! (
344
+ trevm. inner( ) . block( ) . timestamp. to:: <u64 >( ) >= min_timestamp,
345
+ trevm,
346
+ BundleError :: TimestampOutOfRange
347
+ ) ;
342
348
}
343
349
344
350
// Check for end timestamp range validity
345
351
if let Some ( max_timestamp) = self . bundle . max_timestamp {
346
- if trevm. inner ( ) . block ( ) . timestamp . to :: < u64 > ( ) > max_timestamp {
347
- return Err ( trevm. errored ( BundleError :: TimestampOutOfRange ) ) ;
348
- }
352
+ trevm_ensure ! (
353
+ trevm. inner( ) . block( ) . timestamp. to:: <u64 >( ) <= max_timestamp,
354
+ trevm,
355
+ BundleError :: TimestampOutOfRange
356
+ ) ;
349
357
}
350
358
351
359
// Check if the bundle has any transactions
352
- if self . bundle . txs . is_empty ( ) {
353
- return Err ( trevm. errored ( BundleError :: BundleEmpty ) ) ;
354
- }
360
+ trevm_ensure ! ( !self . bundle. txs. is_empty( ) , trevm, BundleError :: BundleEmpty ) ;
355
361
356
- let txs = self
357
- . bundle
358
- . txs
359
- . iter ( )
360
- . map ( |tx| TxEnvelope :: decode_2718 ( & mut tx. chunk ( ) ) )
361
- . collect :: < Result < Vec < _ > , _ > > ( ) ;
362
- let txs = match txs {
363
- Ok ( txs) => txs,
364
- Err ( e) => return Err ( trevm. errored ( BundleError :: TransactionDecodingError ( e) ) ) ,
365
- } ;
362
+ let txs = unwrap_or_trevm_err ! (
363
+ self . bundle
364
+ . txs
365
+ . iter( )
366
+ . map( |tx| TxEnvelope :: decode_2718( & mut tx. chunk( ) ) )
367
+ . collect:: <Result <Vec <_>, _>>( ) ,
368
+ trevm
369
+ ) ;
366
370
367
371
// Check that the bundle does not exceed the maximum gas limit for blob transactions
368
372
if txs
@@ -399,7 +403,7 @@ impl<Ext> BundleDriver<Ext> for BundleProcessor<EthSendBundle, EthBundleHash> {
399
403
if self . bundle . reverting_tx_hashes . contains ( tx. tx_hash ( ) ) {
400
404
run_result. accept_state ( )
401
405
} else {
402
- return Err ( run_result. errored ( BundleError :: BundleReverted ) ) ;
406
+ trevm_bail ! ( run_result, BundleError :: BundleReverted ) ;
403
407
}
404
408
}
405
409
} ;
@@ -486,48 +490,47 @@ impl<Ext> BundleDriver<Ext> for EthCallBundle {
486
490
& mut self ,
487
491
trevm : crate :: EvmNeedsTx < ' a , Ext , Db > ,
488
492
) -> DriveBundleResult < ' a , Ext , Db , Self > {
489
- // 1. Check if the block we're in is valid for this bundle. Both must match
490
- if trevm. inner ( ) . block ( ) . number . to :: < u64 > ( ) != self . block_number {
491
- return Err ( trevm. errored ( BundleError :: BlockNumberMismatch ) ) ;
492
- }
493
+ // Check if the block we're in is valid for this bundle. Both must match
494
+ trevm_ensure ! (
495
+ trevm. inner( ) . block( ) . number. to:: <u64 >( ) == self . block_number,
496
+ trevm,
497
+ BundleError :: BlockNumberMismatch
498
+ ) ;
493
499
494
500
// Check if the bundle has any transactions
495
- if self . txs . is_empty ( ) {
496
- return Err ( trevm. errored ( BundleError :: BundleEmpty ) ) ;
497
- }
501
+ trevm_ensure ! ( !self . txs. is_empty( ) , trevm, BundleError :: BundleEmpty ) ;
498
502
499
503
// Check if the state block number is valid (not 0, and not a tag)
500
- if !self . state_block_number . is_number ( )
501
- || self . state_block_number . as_number ( ) . unwrap_or ( 0 ) == 0
502
- {
503
- return Err ( trevm. errored ( BundleError :: BlockNumberMismatch ) ) ;
504
- }
504
+ trevm_ensure ! (
505
+ self . state_block_number. is_number( )
506
+ && self . state_block_number. as_number( ) . unwrap_or( 0 ) != 0 ,
507
+ trevm,
508
+ BundleError :: BlockNumberMismatch
509
+ ) ;
505
510
506
511
let bundle_filler = BundleBlockFiller :: from ( self . clone ( ) ) ;
507
512
508
513
let run_result = trevm. try_with_block ( & bundle_filler, |trevm| {
509
514
let mut trevm = trevm;
510
515
511
- let txs = self
512
- . txs
513
- . iter ( )
514
- . map ( |tx| TxEnvelope :: decode_2718 ( & mut tx. chunk ( ) ) )
515
- . collect :: < Result < Vec < _ > , _ > > ( ) ;
516
- let txs = match txs {
517
- Ok ( txs) => txs,
518
- Err ( e) => return Err ( trevm. errored ( BundleError :: TransactionDecodingError ( e) ) ) ,
519
- } ;
516
+ let txs = unwrap_or_trevm_err ! (
517
+ self . txs
518
+ . iter( )
519
+ . map( |tx| TxEnvelope :: decode_2718( & mut tx. chunk( ) ) )
520
+ . collect:: <Result <Vec <_>, _>>( ) ,
521
+ trevm
522
+ ) ;
520
523
521
524
// Check that the bundle does not exceed the maximum gas limit for blob transactions
522
- if txs
523
- . iter ( )
524
- . filter_map ( |tx| tx. as_eip4844 ( ) )
525
- . map ( |tx| tx. tx ( ) . tx ( ) . blob_gas ( ) )
526
- . sum :: < u64 > ( )
527
- > MAX_BLOB_GAS_PER_BLOCK
528
- {
529
- return Err ( trevm . errored ( BundleError :: Eip4844BlobGasExceeded ) ) ;
530
- }
525
+ trevm_ensure ! (
526
+ txs . iter( )
527
+ . filter_map( |tx| tx. as_eip4844( ) )
528
+ . map( |tx| tx. tx( ) . tx( ) . blob_gas( ) )
529
+ . sum:: <u64 >( )
530
+ <= MAX_BLOB_GAS_PER_BLOCK ,
531
+ trevm ,
532
+ BundleError :: Eip4844BlobGasExceeded
533
+ ) ;
531
534
532
535
for tx in txs. iter ( ) {
533
536
let run_result = trevm. run_tx ( tx) ;
@@ -573,49 +576,52 @@ impl<Ext> BundleDriver<Ext> for EthSendBundle {
573
576
trevm : crate :: EvmNeedsTx < ' a , Ext , Db > ,
574
577
) -> DriveBundleResult < ' a , Ext , Db , Self > {
575
578
// Check if the block we're in is valid for this bundle. Both must match
576
- if trevm. inner ( ) . block ( ) . number . to :: < u64 > ( ) != self . block_number {
577
- return Err ( trevm. errored ( BundleError :: BlockNumberMismatch ) ) ;
578
- }
579
+ trevm_ensure ! (
580
+ trevm. inner( ) . block( ) . number. to:: <u64 >( ) == self . block_number,
581
+ trevm,
582
+ BundleError :: BlockNumberMismatch
583
+ ) ;
579
584
580
585
// Check for start timestamp range validity
586
+
581
587
if let Some ( min_timestamp) = self . min_timestamp {
582
- if trevm. inner ( ) . block ( ) . timestamp . to :: < u64 > ( ) < min_timestamp {
583
- return Err ( trevm. errored ( BundleError :: TimestampOutOfRange ) ) ;
584
- }
588
+ trevm_ensure ! (
589
+ trevm. inner( ) . block( ) . timestamp. to:: <u64 >( ) >= min_timestamp,
590
+ trevm,
591
+ BundleError :: TimestampOutOfRange
592
+ ) ;
585
593
}
586
594
587
595
// Check for end timestamp range validity
588
596
if let Some ( max_timestamp) = self . max_timestamp {
589
- if trevm. inner ( ) . block ( ) . timestamp . to :: < u64 > ( ) > max_timestamp {
590
- return Err ( trevm. errored ( BundleError :: TimestampOutOfRange ) ) ;
591
- }
597
+ trevm_ensure ! (
598
+ trevm. inner( ) . block( ) . timestamp. to:: <u64 >( ) <= max_timestamp,
599
+ trevm,
600
+ BundleError :: TimestampOutOfRange
601
+ ) ;
592
602
}
593
603
594
604
// Check if the bundle has any transactions
595
- if self . txs . is_empty ( ) {
596
- return Err ( trevm. errored ( BundleError :: BundleEmpty ) ) ;
597
- }
605
+ trevm_ensure ! ( !self . txs. is_empty( ) , trevm, BundleError :: BundleEmpty ) ;
598
606
599
- let txs = self
600
- . txs
601
- . iter ( )
602
- . map ( |tx| TxEnvelope :: decode_2718 ( & mut tx. chunk ( ) ) )
603
- . collect :: < Result < Vec < _ > , _ > > ( ) ;
604
- let txs = match txs {
605
- Ok ( txs) => txs,
606
- Err ( e) => return Err ( trevm. errored ( BundleError :: TransactionDecodingError ( e) ) ) ,
607
- } ;
607
+ let txs = unwrap_or_trevm_err ! (
608
+ self . txs
609
+ . iter( )
610
+ . map( |tx| TxEnvelope :: decode_2718( & mut tx. chunk( ) ) )
611
+ . collect:: <Result <Vec <_>, _>>( ) ,
612
+ trevm
613
+ ) ;
608
614
609
615
// Check that the bundle does not exceed the maximum gas limit for blob transactions
610
- if txs
611
- . iter ( )
612
- . filter_map ( |tx| tx. as_eip4844 ( ) )
613
- . map ( |tx| tx. tx ( ) . tx ( ) . blob_gas ( ) )
614
- . sum :: < u64 > ( )
615
- > MAX_BLOB_GAS_PER_BLOCK
616
- {
617
- return Err ( trevm . errored ( BundleError :: Eip4844BlobGasExceeded ) ) ;
618
- }
616
+ trevm_ensure ! (
617
+ txs . iter( )
618
+ . filter_map( |tx| tx. as_eip4844( ) )
619
+ . map( |tx| tx. tx( ) . tx( ) . blob_gas( ) )
620
+ . sum:: <u64 >( )
621
+ <= MAX_BLOB_GAS_PER_BLOCK ,
622
+ trevm ,
623
+ BundleError :: Eip4844BlobGasExceeded
624
+ ) ;
619
625
620
626
// Store the current evm state in this mutable variable, so we can continually use the freshest state for each simulation
621
627
let mut t = trevm;
@@ -638,7 +644,7 @@ impl<Ext> BundleDriver<Ext> for EthSendBundle {
638
644
if self . reverting_tx_hashes . contains ( tx. tx_hash ( ) ) {
639
645
run_result. accept_state ( )
640
646
} else {
641
- return Err ( run_result. errored ( BundleError :: BundleReverted ) ) ;
647
+ trevm_bail ! ( run_result, BundleError :: BundleReverted )
642
648
}
643
649
}
644
650
} ;
0 commit comments