Skip to content

feat: rollup mana limit gas validation#21219

Open
mrzeszutko wants to merge 1 commit intomerge-train/spartanfrom
mr/gas-limit-validation-block-limit
Open

feat: rollup mana limit gas validation#21219
mrzeszutko wants to merge 1 commit intomerge-train/spartanfrom
mr/gas-limit-validation-block-limit

Conversation

@mrzeszutko
Copy link
Contributor

Summary

Transactions whose gas limits exceed the block or checkpoint mana limit are currently silently dropped during block building, causing users' .wait() calls to hang indefinitely. This PR adds early rejection at the gossip and RPC entry points by checking min(MAX_PROCESSABLE_L2_GAS, rollupManaLimit, maxBlockL2Gas).

Changes

Promote rollupManaLimit to L1RollupConstants

  • Added rollupManaLimit: number to the L1RollupConstants type, EmptyL1RollupConstants (defaults to Infinity), and the Zod schema
  • Removed the ad-hoc & { rollupManaLimit?: number } extensions from the archiver, sequencer, and block-builder types — they now get it from the base type
  • Updated EpochCache.create() and RollupContract.getRollupConstants() to fetch and include rollupManaLimit from L1

Shared deriveMaxBlockL2Gas utility

  • New function in stdlib/src/gas/block_gas_limit.ts that derives the per-block L2 gas limit from the checkpoint-level rollup mana limit: min(rollupManaLimit, ceil(rollupManaLimit / maxBlocksPerSlot * multiplier)), with an optional explicit limit override (capped at the rollup mana limit)
  • Exported DEFAULT_PER_BLOCK_ALLOCATION_MULTIPLIER = 2 constant from the same module
  • Used by both the sequencer (computeBlockLimits) and the gossip path (createFirstStageMessageValidators), so both compute the same block gas limit from the same shared logic

Validate against all three gas limits

  • GasLimitsValidator now accepts { rollupManaLimit, maxBlockL2Gas?, bindings? } and computes an effective max as min(MAX_PROCESSABLE_L2_GAS, rollupManaLimit, maxBlockL2Gas). Rejection logs include all three individual limits for debuggability.
  • rollupManaLimit is required — it is always available from L1. Only maxBlockL2Gas is optional since it depends on node configuration.
  • GasTxValidator forwards these options when constructing its inner GasLimitsValidator
  • All factory functions (createFirstStageTxValidationsForGossipedTransactions, createTxValidatorForAcceptingTxsOverRPC, createTxValidatorForTransactionsEnteringPendingTxPool) accept and pass through the new limits

Plumb limits to entry points

  • Gossip path (libp2p_service.ts): Fetches rollupManaLimit from archiver.getL1Constants(), computes maxBlockL2Gas via deriveMaxBlockL2Gas using calculateMaxBlocksPerSlot and DEFAULT_PER_BLOCK_ALLOCATION_MULTIPLIER — same derivation as the sequencer
  • RPC path (aztec-node/server.ts): Fetches rollupManaLimit from blockSource.getL1Constants() and maxBlockL2Gas from the sequencer client's already-computed block limit
  • Pending pool migration (client/factory.ts): Fetches rollupManaLimit from archiver.getL1Constants()

Unit tests

Six new tests in gas_validator.test.ts covering:

  • Rejection when exceeding rollupManaLimit
  • Rejection when exceeding maxBlockL2Gas
  • Min-of-all-limits behavior
  • Acceptance at exactly the effective limit
  • Backward compatibility (no params = falls back to MAX_PROCESSABLE_L2_GAS)
  • Forwarding limits through GasTxValidator

Notes

  • No new env vars — the gossip path derives maxBlockL2Gas from existing config (blockDurationMs, slot durations from L1 constants) using the same shared function as the sequencer.
  • ~20 test files updated to include rollupManaLimit in their L1RollupConstants objects

Fixes A-68

@spalladino
Copy link
Contributor

spalladino commented Mar 6, 2026

We shouldn't go the deriveMaxBlockL2Gas route. Instead. we should use the validator block gas limits introduced in #21060 (if set). The derived limit should only be used for proposals.

Also, it'd be good to extend this check to DA limits as well since we're at it.

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