feat(sequencer): set block building limits from checkpoint limits#20974
Open
spalladino wants to merge 6 commits intomerge-train/spartanfrom
Open
feat(sequencer): set block building limits from checkpoint limits#20974spalladino wants to merge 6 commits intomerge-train/spartanfrom
spalladino wants to merge 6 commits intomerge-train/spartanfrom
Conversation
spalladino
commented
Feb 27, 2026
Comment on lines
+166
to
+200
| // Remaining L2 gas (mana) | ||
| // IMPORTANT: This assumes mana is computed solely based on L2 gas used in transactions. | ||
| // This may change in the future. | ||
| const usedMana = sum(existingBlocks.map(b => b.header.totalManaUsed.toNumber())); | ||
| const remainingMana = this.config.rollupManaLimit - usedMana; | ||
|
|
||
| // Remaining DA gas: DA gas = tx blob fields * DA_GAS_PER_FIELD | ||
| // IMPORTANT: This assumes DA gas is computed solely based on the number of blob fields in transactions | ||
| // This may change in the future, but we cannot access the actual DA gas used in a block since it's not exposed | ||
| // in the L2BlockHeader, so we have to rely on recomputing it here. | ||
| const usedDAGas = | ||
| sum(existingBlocks.map(b => sum(b.body.txEffects.map(tx => tx.getNumBlobFields())))) * DA_GAS_PER_FIELD; | ||
| const remainingDAGas = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT - usedDAGas; | ||
|
|
||
| // Remaining blob fields (block blob fields include both tx data and block-end overhead) | ||
| const usedBlobFields = sum(existingBlocks.map(b => b.toBlobFields().length)); | ||
| const totalBlobCapacity = BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB - NUM_CHECKPOINT_END_MARKER_FIELDS; | ||
| const isFirstBlock = existingBlocks.length === 0; | ||
| const blockEndOverhead = getNumBlockEndBlobFields(isFirstBlock); | ||
| const maxBlobFieldsForTxs = totalBlobCapacity - usedBlobFields - blockEndOverhead; | ||
|
|
||
| // Cap L2 gas by remaining checkpoint mana | ||
| const cappedL2Gas = Math.min(opts.maxBlockGas?.l2Gas ?? remainingMana, remainingMana); | ||
|
|
||
| // Cap DA gas by remaining checkpoint DA gas budget | ||
| const cappedDAGas = Math.min(opts.maxBlockGas?.daGas ?? remainingDAGas, remainingDAGas); | ||
|
|
||
| // Cap blob fields by remaining checkpoint blob capacity | ||
| const cappedBlobFields = | ||
| opts.maxBlobFields !== undefined ? Math.min(opts.maxBlobFields, maxBlobFieldsForTxs) : maxBlobFieldsForTxs; | ||
|
|
||
| return { | ||
| maxBlockGas: new Gas(cappedDAGas, cappedL2Gas), | ||
| maxBlobFields: cappedBlobFields, | ||
| }; |
Contributor
Author
There was a problem hiding this comment.
@sirasistant can I ask you to review this part of the code?
… building During re-execution (validation/proving), the public processor must process the exact txs from the proposal. Pre-processing skip checks for estimated blob fields and gas limits are now gated behind a new `isBuildingProposal` flag on PublicProcessorLimits, which is only set by the sequencer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
spalladino
commented
Feb 27, 2026
Contributor
Author
There was a problem hiding this comment.
@sirasistant also the changes on this file
spalladino
commented
Feb 27, 2026
|
|
||
| // Default gas limits. Users should use gas estimation, or they will overpay gas fees. | ||
| // TODO: consider moving to typescript | ||
| // TODO: These are overridden in typescript-land. Remove them from here. |
Contributor
Author
There was a problem hiding this comment.
I didn't delete them in this PR because I was scared of triggering a change in a vk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The checkpoint builder now tracks remaining L2 gas, DA gas, and blob fields in a checkpoint while building each block, and forwards them to the public processor. This means that a proposer will not propose blocks that overall exceed checkpoint limits, and validators will properly reject them.
In addition, the proposer defaults the L2 and DA gas limits per block to the checkpoint limits divided by expected number of blocks, times two. This value is still capped by the remaining gas in the checkpoint builder, but means that a proposer will not waste the entire checkpoint gas allocation on the first block.
Fixes A-528
Changes
As described by Claude
rollupManaLimit,MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT) using the timetable'smaxNumberOfBlocksand a configurable multiplier (default: 2) for creating proposals only (not for validation)CheckpointBuilder.capLimitsByCheckpointBudgets(), which caps per-block limits by remaining checkpoint budgets for both proposer and validator pathsmaxTxsPerBlock,maxL2BlockGas,maxDABlockGas, androllupManaLimitthrough to validator re-execution so limits are enforced during block validationmaxBlockSizeInByteswith field-based blob limits and a pre-processing blob field estimation (getPrivateTxEffectsSizeInFields)gasPerBlockAllocationMultiplierconfig (SEQ_GAS_PER_BLOCK_ALLOCATION_MULTIPLIER, default: 2)maxL2BlockGasandmaxDABlockGasoptional (auto-computed from checkpoint limits when not set)🤖 Generated with Claude Code