Update EIP-8037: clarify regular gas must be charged before state gas#11421
Conversation
When an opcode requires both regular and state gas, the regular gas charge must be applied first. If regular gas OOGs, state gas is not consumed. This prevents the parent's reservoir from being inflated on child frame failure.
|
✅ All reviewers have approved. |
misilva73
left a comment
There was a problem hiding this comment.
This look good to me. Thanks for updating. We can move out of draft.
|
|
||
| - **Regular gas** charges deduct from `gas_left` only. | ||
| - **State gas** charges deduct from `state_gas_reservoir` first; when the reservoir is exhausted, from `gas_left`. | ||
| - When an opcode requires both regular and state gas, the regular gas charge MUST be applied first. If the regular gas charge triggers an out-of-gas error, the state gas charge is not applied. |
There was a problem hiding this comment.
nit: It might help to further clarify some reasoning for this. Maybe:
| - When an opcode requires both regular and state gas, the regular gas charge MUST be applied first. If the regular gas charge triggers an out-of-gas error, the state gas charge is not applied. | |
| - When an opcode requires both regular and state gas, the regular gas charge MUST be applied first. If the regular gas charge triggers an out-of-gas error, the state gas charge is not applied. This prevents a regular-gas OOG from consuming state gas that would otherwise be returned to the parent frame's reservoir on exceptional halt. |
Which is a bit awkward since the On **exception halt** line defined below is where this is return to the parent frame is explained. Maybe this isn't necessary or maybe this last clarifying line could be simpler:
This ensures state gas in the reservoir is not consumed for frames that fail before growing any state.
There was a problem hiding this comment.
I see this was already merged. I'm good with it as is :)
eth-bot
left a comment
There was a problem hiding this comment.
All Reviewers Have Approved; Performing Automatic Merge...
…#6389) Bump execution-spec-tests fixtures from `bal@v5.4.0` to `bal@v5.5.1`. Updates fixture URLs in CI workflows, Makefile, docs, and `.fixtures_url_amsterdam` files. Fix EIP-8037 state gas charging order per [EIPs#11421](ethereum/EIPs#11421): regular gas must be charged before state gas for SSTORE and CALL. Previously state gas was charged first, which let spilled state gas inflate the parent's reservoir via `incorporate_child_on_error` on regular gas OOG. - `stack_memory_storage_flow.rs` (SSTORE): defer state gas charge until after regular gas succeeds - `system.rs` (CALL): peek reservoir to compute expected spill for child gas computation, charge regular gas first, then charge state gas - SELFDESTRUCT already had correct order, no change
Per EIP-8037 and ethereum/EIPs#11421, regular gas must be charged before state gas. If regular gas OOGs, state gas is not consumed, preventing parent reservoir inflation on frame failure. Fixes: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: remove direct state gas charging before 63/64 allocation; include in returned GasCosts instead - CREATE/CREATE2 collision: undo account creation state gas charge (both tracking and budget) since EELS generic_create does not charge state gas on collision Found by reservoir inflation detection tests in bal@v5.5.1.
Per EIP-8037 and ethereum/EIPs#11421, regular gas must be charged before state gas. If regular gas OOGs, state gas is not consumed, preventing parent reservoir inflation on frame failure. Fixes: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: remove direct state gas charging before 63/64 allocation; include in returned GasCosts instead - CREATE/CREATE2 collision: undo account creation state gas charge (both tracking and budget) since EELS generic_create does not charge state gas on collision Found by reservoir inflation detection tests in bal@v5.5.1.
Per EIP-8037 and ethereum/EIPs#11421, regular gas must be charged before state gas. If regular gas OOGs, state gas is not consumed, preventing parent reservoir inflation on frame failure. Fixes: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - State transition: separate intrinsic gas and floor gas checks for Amsterdam, returning the correct error type for each Found by reservoir inflation detection tests in bal@v5.5.1.
Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) CREATE2 collision — track burned regular gas: - On address collision, record the burned child regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas (cumulativeRegular) - Without this, gp.Used() = max(txRegular, txState) vastly underestimates block gas for collision scenarios
Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) Pre-Amsterdam Prague floor check moved to else branch. CREATE2 collision — track burned regular gas: - On address collision, record the burned child regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas (cumulativeRegular)
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
…tion Per EIP-8037 and ethereum/EIPs#11421: Gas ordering — regular gas must be charged before state gas: - SSTORE: return both regular and state gas in GasCosts; the interpreter charges regular first via Underflow check - Code deposit: charge regular gas (keccak256 words) before state gas (storage bytes) - CALL: compute state gas spillover for 63/64 calculation WITHOUT charging state gas directly. Include state gas in returned GasCosts so the interpreter charges atomically (regular first). Prevents parent reservoir inflation when child regular gas OOGs. Gas validation ordering for Amsterdam: 1. Total intrinsic must fit in tx gas limit (ErrIntrinsicGas) 2. max(regular, floor) must fit in MaxTxGas (ErrIntrinsicGas) 3. Calldata floor must fit in tx gas limit (ErrFloorDataGas) CREATE2 collision — track burned regular gas in GasUsed.RegularGasUsed so txRegular properly accounts for it in 2D block gas accounting.
Following the gas repricing call, cc-ing @misilva73
When an opcode requires both regular and state gas, the regular gas charge must be applied first. If regular gas OOGs, state gas is not consumed. This prevents the parent's reservoir from being inflated on child frame failure.