@@ -174,10 +174,13 @@ where
174174 . cfg_env
175175 . tx_gas_limit_cap
176176 . unwrap_or ( ctx. evm_env . block_env . gas_limit ) ;
177- let gas_left = max_tx_gas_limit
178- . checked_sub ( space_used. gas )
179- . unwrap_or_default ( ) ;
180- let estimation = insert_test_payout_tx ( to, ctx, state, gas_left) ?
177+ let max_payout_gas_limit = max_tx_gas_limit. min (
178+ ctx. evm_env
179+ . block_env
180+ . gas_limit
181+ . saturating_sub ( space_used. gas ) ,
182+ ) ;
183+ let estimation = insert_test_payout_tx ( to, ctx, state, max_payout_gas_limit) ?
181184 . ok_or ( EstimatePayoutGasErr :: FailedToEstimate ) ?;
182185
183186 if insert_test_payout_tx ( to, ctx, state, estimation) ?. is_some ( ) {
@@ -189,7 +192,7 @@ where
189192 }
190193
191194 let mut left = estimation;
192- let mut right = gas_left ;
195+ let mut right = max_payout_gas_limit ;
193196
194197 // binary search for perfect gas limit
195198 loop {
@@ -227,8 +230,9 @@ mod tests {
227230 use revm:: primitives:: hardfork:: SpecId ;
228231 use std:: sync:: Arc ;
229232
230- #[ test]
231- fn estimate_payout_tx_gas_limit ( ) {
233+ fn setup (
234+ tx_gas_limit_cap : Option < u64 > ,
235+ ) -> ( Address , BlockBuildingContext , BlockState < CachedDB > ) {
232236 let signer = Signer :: random ( ) ;
233237 let proposer = Address :: random ( ) ;
234238 let chain_spec = MAINNET . clone ( ) ;
@@ -261,7 +265,7 @@ mod tests {
261265 block. header . mix_hash = B256 :: random ( ) ;
262266 block. header . number = EthereumHardfork :: Prague . mainnet_activation_block ( ) . unwrap ( ) ;
263267 block. header . excess_blob_gas = Some ( 1000 ) ;
264- let ctx = BlockBuildingContext :: from_onchain_block (
268+ let mut ctx = BlockBuildingContext :: from_onchain_block (
265269 block,
266270 chain_spec,
267271 Some ( spec_id) ,
@@ -273,15 +277,59 @@ mod tests {
273277 false ,
274278 U256 :: ZERO ,
275279 ) ;
280+ ctx. evm_env . cfg_env . tx_gas_limit_cap = tx_gas_limit_cap;
281+
276282 let cached = CachedDB :: new (
277283 provider_factory. latest ( ) . unwrap ( ) ,
278284 Arc :: new ( SharedCachedReads :: default ( ) ) ,
279285 ) ;
280- let mut state = BlockState :: new ( cached) ;
286+ let state = BlockState :: new ( cached) ;
287+ ( proposer, ctx, state)
288+ }
289+
290+ #[ test]
291+ fn estimate_payout_tx_gas_limit ( ) {
292+ // Pre Fusaka block: no per-tx cap.
293+ let ( proposer, ctx, mut state) = setup ( None ) ;
294+
295+ let empty_block = estimate_payout_gas_limit ( proposer, & ctx, & mut state, BlockSpace :: ZERO ) ;
296+ assert_matches ! ( empty_block, Ok ( _) ) ;
297+ assert_eq ! ( empty_block. unwrap( ) . gas, 21_000 ) ;
298+
299+ // Only 10k gas left in the block.
300+ let full_block = estimate_payout_gas_limit (
301+ proposer,
302+ & ctx,
303+ & mut state,
304+ BlockSpace :: new ( 29_990_000 , 0 , 0 ) ,
305+ ) ;
306+ assert_matches ! ( full_block, Err ( _) ) ;
307+
308+ // Post Fusaka block: EIP-7825 caps one tx at 16,777,216 gas
309+ let ( proposer, ctx, mut state) = setup ( Some ( 16_777_216 ) ) ;
281310
282- let estimate_result =
283- estimate_payout_gas_limit ( proposer, & ctx, & mut state, BlockSpace :: ZERO ) ;
284- assert_matches ! ( estimate_result, Ok ( _) ) ;
285- assert_eq ! ( estimate_result. unwrap( ) . gas, 21_000 ) ;
311+ let empty_block = estimate_payout_gas_limit ( proposer, & ctx, & mut state, BlockSpace :: ZERO ) ;
312+ assert_matches ! ( empty_block, Ok ( _) ) ;
313+ assert_eq ! ( empty_block. unwrap( ) . gas, 21_000 ) ;
314+
315+ // 20M gas is already used. This is more than the single-transaction limit,
316+ // but 10M of block space is still available.
317+ let past_cap = estimate_payout_gas_limit (
318+ proposer,
319+ & ctx,
320+ & mut state,
321+ BlockSpace :: new ( 20_000_000 , 0 , 0 ) ,
322+ ) ;
323+ assert_matches ! ( past_cap, Ok ( _) ) ;
324+ assert_eq ! ( past_cap. unwrap( ) . gas, 21_000 ) ;
325+
326+ // Only 10k gas left in the block.
327+ let full_block = estimate_payout_gas_limit (
328+ proposer,
329+ & ctx,
330+ & mut state,
331+ BlockSpace :: new ( 29_990_000 , 0 , 0 ) ,
332+ ) ;
333+ assert_matches ! ( full_block, Err ( _) ) ;
286334 }
287335}
0 commit comments