Enforce EIP-7825 per-tx gas cap on settlement#4371
Enforce EIP-7825 per-tx gas cap on settlement#43710xDevNinja wants to merge 5 commits intocowprotocol:mainfrom
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
recheck |
There was a problem hiding this comment.
Code Review
This pull request implements the EIP-7825 per-transaction gas cap (2^24 - 1) within the settlement domain. The Gas::new function now caps the maximum gas by taking the minimum of half the block limit and this new constant, preventing the creation of solutions that would be rejected by the mempool. Unit tests have been added to verify the cap's behavior in both large and small block limit scenarios. I have no feedback to provide.
AryanGodara
left a comment
There was a problem hiding this comment.
I think the PR is good to merge, just left some small follow-up questions
|
|
||
| #[test] | ||
| fn rejects_solution_above_eip_7825_cap() { | ||
| // 120M block (well above the EIP-7825 cap of 16,777,215). Half the |
There was a problem hiding this comment.
nit: can we rewrite this comment, so it reads more clearly.
it can be structured a little bit better 😅
- Make EIP_7825_TX_GAS_CAP private; no external callers. - Reword test comment for clarity.
Replace the hardcoded EIP-7825 constant in Gas::new with the existing per-driver tx_gas_limit config knob. Operators set the cap per chain (EIP-7825's 16,777,215 on Fusaka chains, higher elsewhere) so non-Fusaka chains aren't over-restricted by an L1-only fork rule.
EIP-7825 chose 2^24-1 for Mainnet's Fusaka hardfork; other chains pick their own per-tx limits (e.g. Arbitrum One uses 32M). Reword comments and rename the test const to make the Mainnet scope explicit.
|
@jmg-duarte, Addressed all three suggestions in 20dba82:
Good to know about Arb1 picking 32M — that's exactly why the cap is now driven by the per-chain |
AryanGodara
left a comment
There was a problem hiding this comment.
Nit: description claims hardcoded const EIP_7825_TX_GAS_CAP but that is no longer true, as it uses tx_gas_limit plumbing.
Update body to reflect the pivot.
squadgazzz
left a comment
There was a problem hiding this comment.
Two minor follow-ups, neither blocking.
PR description note: the Changes list still says the cap is exposed as Gas::EIP_7825_TX_GAS_CAP for callers and tests to share, but the final code keeps the constant private to the test module and the per-tx ceiling now comes from the existing tx_gas_limit config knob, not a hardcoded constant. Worth tightening before squash so the commit message reflects what shipped.
| let block_limit = gas(120_000_000); | ||
| let tx_gas_limit = gas(EIP_7825_MAINNET_TX_GAS_CAP); | ||
| let result = Gas::new(tx_gas_limit, block_limit, tx_gas_limit).unwrap(); | ||
| assert_eq!(result.estimate, tx_gas_limit); |
There was a problem hiding this comment.
The boundary test only asserts estimate, but limit is what flows downstream into required_balance and the submitted tx's gas field. With estimate == tx_gas_limit, the 2.0× buffer would compute estimate_with_buffer = 2 * tx_gas_limit, and the min(max_gas, ...) clamp is what keeps the limit at the cap. Worth locking that in.
| assert_eq!(result.estimate, tx_gas_limit); | |
| assert_eq!(result.estimate, tx_gas_limit); | |
| assert_eq!(result.limit, tx_gas_limit); |
There was a problem hiding this comment.
Good catch — applied in 78cbd3b. Locks in that the 2x estimate buffer can't leak past the configured cap.
When estimate == tx_gas_limit, the 2x estimate buffer would otherwise set limit to 2 * tx_gas_limit; the min(max_gas, ...) clamp pins it back to the configured cap. Lock that contract in.
|
Updated the PR description to reflect the pivot — the cap now reads from the existing |
Description
The driver caps a settlement's gas estimate at half the block gas limit (e.g. 60M on a 120M block). Fusaka introduced the EIP-7825 per-transaction gas cap of
2^24 - 1 = 16,777,215on Mainnet; any tx exceeding this is rejected by the mempool. Without this check a solution above the cap can still be returned by/solveand forwarded to/settle, where it could never be mined. The cap is already enforced on the quote-verification path (#4261) but was never ported to settlement submission.Note: EIP-7825 is L1 Fusaka-only and other chains pick their own per-tx limits (e.g. Arbitrum One uses 32M), so the driver reuses the existing
tx_gas_limitconfig knob (#3780) rather than hardcoding a single value. Operators set the per-chain ceiling —16,777,215on Mainnet Fusaka, higher elsewhere — andGas::newenforcesmin(block_limit / 2, tx_gas_limit).Changes
tx_gas_limitconfig value throughinfra::blockchain::Ethereum(newtx_gas_limit()accessor).Gas::new, cap the per-settlement maximum atmin(block_limit / 2, tx_gas_limit)so over-sized solutions fail fast through the existingGasLimitExceedederror.2 * tx_gas_limitkeep the tighter half-block behaviour.estimateand the clampedlimit), the small-block-limit path, and the non-Fusaka case where the half-block cap binds.How to test
All four new tests pass; existing driver tests are unchanged.
Fixes #4368