Skip to content

fix(pricing): storage model native resources charging issues#679

Draft
vibelyova wants to merge 1 commit into
matter-labs:draft-0.4.0from
vibelyova:storage-native-resources
Draft

fix(pricing): storage model native resources charging issues#679
vibelyova wants to merge 1 commit into
matter-labs:draft-0.4.0from
vibelyova:storage-native-resources

Conversation

@vibelyova
Copy link
Copy Markdown

What ❔

Fixes four native resource charging bugs in the storage model (EVM-1363), corrects keccak256 native cost to the delegation model, and fixes a missing warm storage read in the access list intrinsic formula.

Storage charging fixes:

  1. Storage write extra constants under-charged — derived all cold storage costs from SINGLE_MERKLE_PATH_NATIVE_COST based on docs/system/io/tree.md. Existing write extra was 2x under-charged, new write extra was 3x under-charged.
  2. Repeated writes overcharged — warm storage writes now pay WARM_STORAGE_WRITE_EXTRA_NATIVE_COST (1k) instead of the full cold price.
  3. Account persist writes uncharged — proactive native charge for the deferred 0x8003 storage write + blake2s preimage hash, per distinct account per tx. Only fires when the value actually changes (no-op balance updates are skipped). Tree insertion cost (NEW) is charged only once per account per block; subsequent txs pay EXISTING.
  4. Preimage hashing uncharged — blake2s hash cost for AccountProperties is included in the persist charge.

Keccak256 native cost correction:

  1. Keccak round cost updated to delegation model — each keccak f1600 permutation = 649 delegations with coefficient 4. KECCAK256_ROUND_NATIVE_COST: 17500 → 2596. Base cost measured at 1908 RISC-V cycles, kept at 2500 for ~30% headroom.
  2. Missing WARM_STORAGE_READ in per-key access list formulamaterialize_element always charges a warm storage read, but it was not included in L2_TX_INTRINSIC_COMPUTATIONAL_NATIVE_ACCESS_LIST_PER_STORAGE_KEY. Previously masked by keccak surplus.

Also updates intrinsic cost formulas (L2, service, L1, EIP-7702), re-measures L1 AssetTracker notification costs, and adds test infrastructure (coinbase pre-creation in the state tree).

Supersedes #676 (closed due to base branch deletion).

Why ❔

The native resource pricing must accurately reflect the actual ZK prover cost of storage operations. Under-charging means the prover does more work than was paid for; over-charging wastes user gas. These fixes align the charging model with the Merkle tree cost model documented in docs/system/io/tree.md and the delegation-based proving model for keccak.

Is this a breaking change?

  • Yes
  • No

Effective native cost of transactions changes — intrinsic costs increase (storage writes, persist charges), keccak costs decrease. This affects minimum gas requirements for transactions.

Checklist

  • PR title corresponds to the body of PR (we generate changelog entries from PRs).
  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.
  • Code has been formatted.

Fixes four native resource charging bugs, corrects keccak256 cost to
the delegation model, and fixes a missing warm storage read in the
access list intrinsic formula.

Storage charging fixes:
- Derive all cold storage costs from SINGLE_MERKLE_PATH_NATIVE_COST
  based on docs/system/io/tree.md. Existing write extra was 2x
  under-charged, new write extra was 3x under-charged.
- Warm storage writes now pay WARM_STORAGE_WRITE_EXTRA (1k) instead
  of the full cold price.
- Proactive native charge for the deferred 0x8003 storage write +
  blake2s preimage hash per distinct account per tx. Only fires when
  the value actually changes. Tree insertion cost (NEW) charged only
  once per account per block; subsequent txs pay EXISTING.
- Skip persist charge and cache_write on no-op balance updates.

Keccak256 native cost correction:
- Round cost derived from delegation model: 649 delegations * coeff 4.
  Base cost measured at 1908 RISC-V cycles, rounded to 2500 (~30%
  headroom). Add KECCAK_DELEGATION_COEFFICIENT to zk_ee constants.
- Add missing WARM_STORAGE_READ to per-key access list formula
  (previously masked by keccak surplus).

Intrinsic formula updates:
- L2 tx: 2*PERSIST_EXISTING for sender + coinbase. No coinbase cold
  read (pre-warmed by tx_loop).
- Service tx: no persist (gas_price=0, all balance updates are no-ops).
- L1 tx: decomposed into symbolic + measured parts. AssetTracker
  notification costs measured directly via cycle instrumentation.
  Refund recipient uses PERSIST_NEW (may be new, set by L1 sender).
- EIP-7702 auth: +PERSIST_NEW per delegatee.

Test infrastructure:
- Chain::ensure_account_exists + coinbase pre-creation in run_inner.
- 4 new integration tests for storage charging correctness.
- Pre-create sender in simulation balance check test.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant