fix(devnet-7): reject txs exceeding EIP-8037 intrinsic gas cap; skip BAL no-op code#11635
fix(devnet-7): reject txs exceeding EIP-8037 intrinsic gas cap; skip BAL no-op code#11635benaadams wants to merge 5 commits into
Conversation
…BAL no-op code changes Reject transactions at both validation (TxValidator) and execution (TransactionProcessor) when the EIP-8037 intrinsic regular or floor gas exceeds the EIP-7825 per-tx cap. A calldata-heavy tx (e.g. 262k 0xff bytes) can push floor pricing over the cap even when the declared GasLimit is well below it, and must be rejected before execution. Shared check lives on IntrinsicGas<TGasPolicy>.ExceedsCap. BlockAccessList.AddCodeChange short-circuits before invalidating the cached item count and allocating an AccountChanges entry when before equals after, so EIP-7702 authorizations that resolve to no code change (e.g. null-address delegation) no longer create empty AccountChanges entries in the BAL. Regression tests added for both behaviors.
|
Claude finished @benaadams's task in 7m 13s —— View job PR Review
SummaryTwo distinct fixes in this PR — the EIP-8037 intrinsic gas cap rejection and the BAL no-op short-circuit — are both logically correct. The tests are well-targeted. One medium finding in the refactored validator path, one low. FindingsMedium —
|
There was a problem hiding this comment.
Pull request overview
This PR tightens EIP-8037 transaction validation by rejecting transactions whose intrinsic regular or floor gas exceeds the EIP-7825 cap, and avoids creating empty block access list code-change entries for no-op code updates.
Changes:
- Adds an
IntrinsicGas<TGasPolicy>.ExceedsCaphelper and uses it in transaction validation/execution. - Skips
BlockAccessList.AddCodeChangework when code bytes are unchanged. - Adds regression tests for EIP-8037 intrinsic gas cap rejection and BAL no-op code changes.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs |
Adds execution-time intrinsic cap rejection and adjusts intrinsic-gas error return. |
src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs |
Adds shared intrinsic gas cap helper. |
src/Nethermind/Nethermind.Evm.Test/Eip8037RegressionTests.cs |
Adds execution regression test for calldata floor gas exceeding the cap. |
src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs |
Adds BAL regression coverage for null-address delegation with no code change. |
src/Nethermind/Nethermind.Core/BlockAccessLists/BlockAccessList.cs |
Avoids creating account changes for no-op code changes. |
src/Nethermind/Nethermind.Core.Test/BlockAccessLists/BlockAccessListJournalTests.cs |
Adds unit coverage for no-op code changes not creating account changes. |
src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs |
Adds validation-time intrinsic cap rejection. |
src/Nethermind/Nethermind.Blockchain.Test/Validators/TxValidatorTests.cs |
Adds validator regression coverage for EIP-8037 floor gas cap rejection. |
Comments suppressed due to low confidence (2)
src/Nethermind/Nethermind.Consensus/Validators/TxValidator.cs:143
- This now compares the transaction gas limit only against
MinimalGas.Value, which ignores EIP-8037 intrinsic state gas stored onintrinsicGas.Standard.StateReservoir. The previousEthereumIntrinsicGasconversion includedStandard.Value + StateReservoir, andTransactionProcessor.ValidateStaticstill requiresMath.Max(standard.Value + stateReservoir, minimal.Value), so set-code/contract-creation transactions with gas betweenmax(regular, floor)andregular + intrinsic statewill be accepted byTxValidatorbut rejected during execution.
return transaction.GasLimit < intrinsicGas.MinimalGas.Value
? TxErrorMessages.IntrinsicGasTooLow
src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs:645
- This drops the detailed error text that included both the supplied gas limit and the required intrinsic gas.
TransactionResult.ErrorDescriptionis surfaced in block production/validation and JSON-RPC errors, so under-intrinsic transactions will now only report the generic “intrinsic gas too low” message even though the exacthave/wantvalues are available here.
if (tx.GasLimit < minGasRequired)
{
TraceLogInvalidTx(tx, $"GAS_LIMIT_BELOW_INTRINSIC_GAS {tx.GasLimit} < {minGasRequired}");
return TransactionResult.ErrorType.GasLimitBelowIntrinsicGas;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@claude re-review |
|
Claude finished @benaadams's task in 4m 23s —— View job PR Re-review
|
The EIP-8037 per-tx cap rejection is semantically "a per-tx maximum was exceeded", not "intrinsic gas too low" - the failing tx's GasLimit may be well within the cap; what overflows is the intrinsic regular or floor dimension vs the cap. Use the existing TxGasLimitCapExceeded: prefix (already mapped to GAS_LIMIT_EXCEEDS_MAXIMUM for EIP-7825) so both EIP-7825 and EIP-8037 cap-overflow share a single semantically accurate exception type. Upstream EEST fixtures still expect INTRINSIC_GAS_TOO_LOW for these test cases; bridge the mapping in BlockchainTestBase until those fixtures are updated.
|
@claude re-review |
|
Claude finished @benaadams's task in 3m 45s —— View job PR Re-review
SummaryAll findings from prior reviews have been addressed. The latest commit ( Prior findings — statusMedium (resolved) —
|

Changes
Reject transactions at both validation (TxValidator) and execution (TransactionProcessor) when the EIP-8037 intrinsic regular or floor gas exceeds the EIP-7825 per-tx cap. A calldata-heavy tx (e.g. 262k 0xff bytes) can push floor pricing over the cap even when the declared GasLimit is well below it, and must be rejected before execution. Shared check lives on IntrinsicGas.ExceedsCap.
BlockAccessList.AddCodeChange short-circuits before invalidating the cached item count and allocating an AccountChanges entry when before equals after, so EIP-7702 authorizations that resolve to no code change (e.g. null-address delegation) no longer create empty AccountChanges entries in the BAL.
Regression tests added for both behaviors.
Types of changes
What types of changes does your code introduce?
Testing
Requires testing
If yes, did you write tests?