Repository navigation
feat(core): apply EIP-2028 calldata pricing at Prague - #2710
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
0bce37e to
446980f
Compare
…not met Gas estimation gives up when the transaction is rejected for not covering the EIP-7623 data floor. The floor is a cost a higher gas limit still covers, just like the intrinsic gas handled here already. The data heavy case in TestEstimateGas pins the retry: its EIP-7623 floor prices it above the intrinsic gas, so the estimate must land on the floor.
XDC keeps the pre-EIP-2028 price of 68 gas per non-zero calldata byte, so the canonical Multicall3 creation transaction runs out of its fixed 1,000,000 gas limit and the address stays without code (issue XinFinOrg#2706). Charge the EIP-2028 price of 16 gas from the Prague fork instead, where the EIP-7623 data floor activated by the same fork governs data heavy transactions. The EIP-3860 initcode word cost keeps its current gate on EIP-1559, which the gas charged for historical blocks depends on. The pre-Prague non-zero byte price now reads params.TxDataNonZeroGasFrontier, the name geth uses for the pre-EIP-2028 rate, and the isEIP2028 doc comment records the Prague activation.
446980f to
e6ed0a9
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
Consensus gas-pricing changes warrant final human validation despite consistent implementation and coverage.
0 open findings
What changed in this PR
Applies EIP-2028 calldata pricing at Prague while preserving existing network activation and EIP-3860 behavior.
Changes:
- Gates 16-gas non-zero calldata pricing on Prague.
- Fixes simulated gas estimation for EIP-7623 floor errors.
- Updates and adds gas-pricing tests.
| File | Description |
|---|---|
core/state_transition.go |
Implements fork-aware calldata pricing. |
core/txpool/validation.go |
Aligns pool validation with consensus pricing. |
core/intrinsic_gas_test.go |
Tests fork boundaries and gas calculations. |
core/state_processor_test.go |
Updates intrinsic-gas invocation. |
core/bench_test.go |
Updates benchmark invocation. |
ethclient/simulated/backend.go |
Handles data-floor errors during estimation. |
ethclient/simulated/backend_test.go |
Tests floor-aware estimation. |
ethclient/gethclient/gethclient_test.go |
Updates expected creation gas. |
eth/tracers/api_test.go |
Updates trace gas expectations. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Proposed changes
XDC keeps the pre-EIP-2028 calldata price of 68 gas per non-zero byte. The canonical Multicall3 creation transaction (3,840 bytes of initcode in a transaction with a fixed 1,000,000 gas limit) therefore needs 1,055,120 gas on XDC and runs out of gas, which is why
0xcA11bde05977b3631167028862bE2a173976CA11has no code (issue #2706).This PR charges the EIP-2028 price of 16 gas per non-zero calldata byte from the Prague fork on. Zero bytes stay at 4 gas, the contract creation base cost stays at 53,000, and the EIP-3860 initcode word cost keeps its current EIP-1559 gate, which the gas charged for historical blocks depends on.
Prague is not scheduled on mainnet or Apothem in this PR (
PragueBlockstays unset), so no live network changes behaviour until the fork is scheduled. Devnet, localnet and the test configs havePragueBlockset (50,000and0), so they already run the new pricing.Note that the EIP-7623 data floor, implemented and activated by the same Prague fork, then governs data heavy transactions: for the initcode above the floor is 164,460 gas, so the transaction needs 927,092 gas instead of the 1,055,120 it needs today, which fits in the fixed 1,000,000 gas limit.
The gas expectations that encode the old price are updated:
eth/tracers/api_test.go(73,812 -> 72,668 with 22 non-zero calldata bytes, 59,903 -> 59,539 with 7, 23,555 -> 23,347 with 4, and 53,072 -> 53,020 with 1),ethclient/gethclient/gethclient_test.go(78,018 -> 77,498 with 10) andethclient/simulated/backend_test.go(21,483 -> 21,275 with 4). Every delta is exactly 52 gas per non-zero calldata byte.The first commit fixes gas estimation in the simulated backend, which gave up instead of raising the gas limit when a transaction was rejected for not covering the EIP-7623 data floor; without it
contracts/tests/TestPriceFeedfails once Prague is active.Part of #2706.
Types of changes
Impacted Components
Checklist
Test coverage:
core/intrinsic_gas_test.gopins the calldata price before and at the Prague block for the mainnet and test configs, including the byte mix of the Multicall3 initcode (292,488 before, 110,624 at Prague with the EIP-3860 word cost), the zero byte price and the contract creation base cost. Reverting the fork gate in either direction makes it fail.Manual test plan on devnet/testnet with Prague scheduled: deploy Multicall3 with a 1,000,000 gas limit, which must succeed instead of running out of gas, and compare
eth_estimateGasfor a calldata heavy creation transaction before and after the fork block.Backwards compatibility: no live network has Prague scheduled, so the gas charged there is unchanged; the EIP-3860 gate that historical blocks depend on is untouched, and both commits pass
make allandmake quick-test.The remaining checklist items are not applicable: no private network run was possible because the fork is not scheduled on any live network, the change cannot be exercised by a node running the previous version until that schedule exists, and the documentation only needs updating when the fork block is decided.