Skip to content

feat: implement floor gas + calldata gas and improve gas calculation#825

Merged
roninjin10 merged 1 commit into09-24-spec-runner-small-fixes-and-better-debuggingfrom
09-24-fix-full-gas-with-calldata-and-floor-gas
Sep 30, 2025
Merged

feat: implement floor gas + calldata gas and improve gas calculation#825
roninjin10 merged 1 commit into09-24-spec-runner-small-fixes-and-better-debuggingfrom
09-24-fix-full-gas-with-calldata-and-floor-gas

Conversation

@0xpolarzero
Copy link
Collaborator

@0xpolarzero 0xpolarzero commented Sep 24, 2025

Description

Implements EIP-7623 (Floor Gas) and refactors gas calculation logic for transactions. This PR adds support for calculating the minimum gas a transaction must consume based on calldata tokens, which is required for the Prague hardfork. The implementation includes:

  1. Adding EIP-7623 to the Prague hardfork EIP list
  2. Implementing token-based calldata gas calculation
  3. Adding floor gas cost calculation for Prague
  4. Refactoring intrinsic gas calculation to be more modular
  5. Ensuring transactions consume at least the floor gas amount

The PR also adds comprehensive tests for all the new gas calculation functions, including edge cases and regression tests.

Type of Change

  • 🎉 New feature (non-breaking change which adds functionality)
  • ✅ Test additions or updates

Testing

  • zig build test passes
  • zig build completes successfully
  • All existing tests pass
  • Added new tests for changes (if applicable)

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code where necessary
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@vercel
Copy link

vercel bot commented Sep 24, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
guillotine Error Error Sep 29, 2025 9:12am

Copy link
Collaborator Author

0xpolarzero commented Sep 24, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@0xpolarzero 0xpolarzero changed the title fix: correct and comprehensive gas costs with calldata & floor gas feat: implement EIP-7623 floor gas + calldata gas and improve gas calculation Sep 24, 2025
@0xpolarzero 0xpolarzero self-assigned this Sep 24, 2025
@claude
Copy link
Contributor

claude bot commented Sep 24, 2025

Code Review: Correct and Comprehensive Gas Costs Implementation

Note: This action was performed by Claude AI assistant, not @roninjin10 or @fucory

✅ Overall Assessment

This PR correctly implements gas cost calculations for calldata and floor gas (EIP-7623), addressing critical gaps in the EVM implementation. The changes align well with Ethereum specifications and follow the codebase conventions in CLAUDE.md.

📊 Code Quality & Best Practices

Strengths:

  • Clean, idiomatic Zig code following project conventions
  • Strong typing with explicit u64 for gas calculations
  • Proper separation of concerns between EIP logic and gas constants
  • Follows the minimal else statement principle from CLAUDE.md

Minor improvements:

  • Consider using compile-time assertions for gas constant relationships (e.g., comptime std.debug.assert(TxDataNonZeroGasMultiplier == TxDataNonZeroGas / TxDataZeroGas))

🐛 Potential Issues

  1. Integer Division Precision: In eip_2028_calldata_gas_cost_multiplier(), the constants use integer division which is correct but worth documenting that 68/4 = 17 (not 17.0)
  2. Missing EIP-7623 in PRAGUE hardfork: Good catch adding EIP-7623 to the Prague hardfork list - this was a critical omission

⚡ Performance Considerations

Positive:

  • Token-based calculation is efficient, avoiding redundant byte counting
  • Reusing tokens for both calldata and floor gas calculations is smart
  • No unnecessary allocations or loops

Optimization opportunity:

  • tokens_in_calldata() could potentially use SIMD instructions for counting zero bytes in large calldata, though the current implementation is already O(n) optimal

🔐 Security Analysis

Critical fixes:

  • ✅ Correctly enforces gas limits before execution
  • ✅ Properly applies floor gas cost (EIP-7623) to prevent underpriced transactions
  • ✅ Handles gas refunds correctly with EIP-3529 cap

Security considerations verified:

  • Gas underflow protection with proper checks
  • No arithmetic overflow risks (using checked operations)
  • Correct ordering of gas deductions and balance transfers

✅ Test Coverage

Excellent test coverage including:

  • Unit tests for each new function
  • Edge cases (empty data, word boundaries, large calldata)
  • Hardfork transition tests
  • Integration tests showing full gas calculation flow
  • Regression tests ensuring EIP ordering

Test quality:

  • Clear test names and documentation
  • Good use of data-driven tests for word boundaries
  • Comprehensive hardfork ordering verification

📝 Additional Notes

  1. The PR correctly implements the complex interaction between:

    • Base intrinsic gas (21,000 for calls, 53,000 for creates)
    • Calldata gas costs (with Istanbul reduction from 68 to 16 gas)
    • Init code word cost (EIP-3860)
    • Floor gas enforcement (EIP-7623)
  2. The token-based approach elegantly handles the multiplier difference between pre/post-Istanbul hardforks

  3. Gas refund handling properly respects the EIP-3529 cap

🎯 Recommendation

APPROVE - This is a well-implemented, thoroughly tested fix for critical gas calculation issues. The code is production-ready pending successful CI/CD validation.

🔧 Pre-merge checklist:

  • Verify zig build test passes
  • Verify zig build test-opcodes passes
  • Consider adding a differential test against revm for these gas calculations
  • Update any documentation referencing gas costs

Great work on this comprehensive fix! The attention to detail in handling hardfork transitions and edge cases is commendable.

@0xpolarzero 0xpolarzero changed the title feat: implement EIP-7623 floor gas + calldata gas and improve gas calculation feat: implement floor gas + calldata gas and improve gas calculation Sep 24, 2025
@0xpolarzero 0xpolarzero marked this pull request as ready for review September 24, 2025 11:49
@0xpolarzero 0xpolarzero changed the base branch from main to graphite-base/825 September 24, 2025 14:20
@0xpolarzero 0xpolarzero force-pushed the 09-24-fix-full-gas-with-calldata-and-floor-gas branch from 07b77de to 7bc9d17 Compare September 24, 2025 14:20
@0xpolarzero 0xpolarzero changed the base branch from graphite-base/825 to 09-24-spec-runner-small-fixes-and-better-debugging September 24, 2025 14:20
@claude
Copy link
Contributor

claude bot commented Sep 24, 2025

Code Review

This PR implements EIP-7623 (Floor Gas) and improves the gas calculation logic. Here's my detailed review:

✅ Strengths

  1. Well-structured implementation: The gas calculation refactor nicely separates concerns into discrete functions (intrinsic_gas_cost, calldata_gas_cost, floor_gas_cost)

  2. Comprehensive test coverage: Excellent test suite covering:

    • Pre/post hardfork behavior
    • Edge cases (word boundaries, empty data, large calldata)
    • Integration scenarios
    • Regression tests for hardfork ordering
  3. Follows CLAUDE.md conventions:

    • Single-word variables (tokens, gas)
    • Direct error propagation
    • No stub implementations
    • Evidence-based testing

🔍 Observations & Suggestions

  1. Gas constant usage: Good use of centralized GasConstants from primitives module. The new constants (TxDataFloorTokenGas, multipliers) are well-documented.

  2. Token calculation optimization: The tokens_in_calldata function efficiently counts zero bytes and calculates non-zero multiplier in a single pass.

  3. EIP activation: EIP-7623 is correctly added to Prague hardfork list, maintaining chronological order.

⚠️ Minor Issues

  1. Comment clarity in evm.zig:321: The comment says "non-zero being more expensive" but should clarify this refers to gas cost (4 gas for zero bytes vs 16/68 gas for non-zero bytes depending on hardfork).

  2. Potential optimization in calldata_gas_cost: Consider simplifying the init code cost calculation:

    const init_code_cost = if (is_create and self.is_eip_active(3860))
        self.eip_3860_initcode_word_cost(input_len)
    else 0;
  3. Documentation: Consider adding a comment explaining the token concept - that tokens represent a weighted count of calldata bytes used for both regular gas and floor gas calculations.

✅ Security & Correctness

  • No fund loss risks: Gas calculations properly prevent underflows and enforce minimum requirements
  • Backward compatibility: Pre-Prague behavior is preserved with floor gas returning 0
  • Proper gas ordering: Initial gas checks happen before execution, floor gas enforcement after

📊 Performance

  • Token calculation is O(n) with single pass through calldata
  • No unnecessary allocations
  • Efficient hardfork checks using compile-time configuration where possible

Conclusion

This is a solid implementation that correctly handles the complexity of Ethereum's evolving gas calculation rules. The code is clean, well-tested, and follows project conventions. The refactoring makes the gas calculation logic more maintainable and easier to understand.

Recommendation: APPROVE

The minor suggestions above are non-blocking improvements that could be addressed in a follow-up if desired.

Note: This review was performed by Claude AI assistant, not @roninjin10 or @fucory

@0xpolarzero 0xpolarzero force-pushed the 09-24-spec-runner-small-fixes-and-better-debugging branch from bab9c6c to 692f787 Compare September 29, 2025 08:58
@0xpolarzero 0xpolarzero force-pushed the 09-24-fix-full-gas-with-calldata-and-floor-gas branch from 7bc9d17 to 7d35df5 Compare September 29, 2025 08:58
Copy link
Contributor

@roninjin10 roninjin10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the places where it looks like a bug to me a bug? What test is this pr making pass or should this be adding a test?

Comment on lines +521 to +523
if (!comptime config.disable_gas_checks) {
result.gas_left = gas_limit - floor_gas_cost;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't look right to me

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the issue here? purpose is if we didn't consume at least floor_gas we deduct it from the original gas

Comment on lines +518 to +519
// EIP-7623 (Prague): Ensure at least floor_gas_cost is consumed
if (gas_consumed < floor_gas_cost) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit using std.math.max would be more readable

Comment on lines +473 to +474
if (gas_limit < initial_gas_cost) return CallResult.failure(self.getCallArenaAllocator(), 0) catch unreachable;
if (gas_limit < floor_gas_cost) return CallResult.failure(self.getCallArenaAllocator(), 0) catch unreachable;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right to me we still need to deal with not underflowing. Might be a good idea to remove disable gas cost as an option right now seems to be randomly implemented without much thought and too much vibes everywhere

@0xpolarzero
Copy link
Collaborator Author

Is the places where it looks like a bug to me a bug? What test is this pr making pass or should this be adding a test?

This makes some execution specs correctly deduct balance, I don't remember which ones but some cancun state tests

@roninjin10 roninjin10 merged commit 1dc65d4 into 09-24-spec-runner-small-fixes-and-better-debugging Sep 30, 2025
8 of 13 checks passed
@roninjin10 roninjin10 deleted the 09-24-fix-full-gas-with-calldata-and-floor-gas branch September 30, 2025 18:50
0xpolarzero added a commit that referenced this pull request Oct 5, 2025
…825)

## Description
Implements EIP-7623 (Floor Gas) and refactors gas calculation logic for
transactions. This PR adds support for calculating the minimum gas a
transaction must consume based on calldata tokens, which is required for
the Prague hardfork. The implementation includes:

1. Adding EIP-7623 to the Prague hardfork EIP list
2. Implementing token-based calldata gas calculation
3. Adding floor gas cost calculation for Prague
4. Refactoring intrinsic gas calculation to be more modular
5. Ensuring transactions consume at least the floor gas amount

The PR also adds comprehensive tests for all the new gas calculation
functions, including edge cases and regression tests.

## Type of Change
- [x] 🎉 New feature (non-breaking change which adds functionality)
- [ ] ✅ Test additions or updates

## Testing
- [x] `zig build test` passes
- [x] `zig build` completes successfully
- [x] All existing tests pass
- [x] Added new tests for changes (if applicable)

## Checklist
- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my own code
- [x] I have commented my code where necessary
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments