Skip to content

(feat): reserved blockspace block building#2302

Open
manav2401 wants to merge 15 commits into
developfrom
reserved-blockspace-block-building
Open

(feat): reserved blockspace block building#2302
manav2401 wants to merge 15 commits into
developfrom
reserved-blockspace-block-building

Conversation

@manav2401

@manav2401 manav2401 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR implements the sequencing changes needed for reserved blockspace implementation. It partitions each block into reserved and normal transactions during the block building phase.

Here's the spec for more details: https://primer-polygon.up.railway.app/d/019f3716-b491-77ea-8c67-519245e075a9

This PR is It is one slice of the larger feature. Other changes around the feature will be included in a separate PR. Note that the PR doesn't activate the feature. More details below.

What this PR adds, per package

miner — the sequencing pipeline and its inputs:

  • sequencing.go (new): sequenceTxs orders pending transactions into commit batches —
    priority senders → one batch per reserved client → normal. Reserved selection charges each
    client's quota against declared gas limits (tx.Gas, not actual gas used) so the whole
    set is decidable without executing anything — this keeps it compatible with future parallel
    (BlockSTM) building and makes validation pre-execution-checkable. A global ceiling bounds the
    sum across clients. Quota/ceiling overflow falls back to the normal pass under standard
    EIP-1559 rules. Client visit order rotates deterministically per block
    (keccak(clientID ‖ parentHash)) so no client is systematically favored.
  • reserved_registry.go (new): the reservedRegistry interface the miner consumes (lookup,
    quotas, ceiling, per-build snapshot pinned to the parent block) plus an in-memory
    MockRegistry used by tests. The contract-backed registry lands behind this same interface
    in its own PR — swap happens at one setter (Miner.SetReservedRegistry).
  • ordering.go: a second, reserved-only mode for the existing price/nonce heap — pops
    ascending effective tip (zero-fee first) and never drops below-base-fee transactions,
    the opposite of the normal market on both counts. The normal mode is byte-identical to before.
  • worker.go: fillTransactions now commits the sequenced batches in order; the build
    accumulates actual gas used by reserved batches and records it in the header
    (writeReservedGasUsed, written even for interrupt-truncated blocks since those still seal).
    Two producer-side metrics (worker/reserved/{gasused,overflow}).

core/types — the header surface:

  • BlockExtraData gains a fifth field, ReservedGasUsed *uint64 (rlp:"optional"), following
    the Giugliano GasTarget/BaseFeeChangeDenominator precedent. Pointer on purpose: an explicit
    zero ("reserved active, none used") stays distinct from the field being absent on the wire.
  • GetReservedGasUsed / SetReservedGasUsed helpers. The setter rewrites Header.Extra via the
    raw-TxDependency mirror, so it never expands TxDependency just to append one integer.

Worth knowing while reviewing

  • Reserved-first placement is a builder preference, not a consensus rule (per spec) — future
    mini-block sequencing may interleave; only quota/accounting are meant for consensus (validation PR).
  • On a quota breach, the sender's remaining nonce sequence diverts to the normal pass (not just
    the breaching tx) — reserved batches commit before normal ones, so anything else would break
    per-sender nonce order.
  • Zero-fee transactions cannot yet flow end-to-end: pool admission (25 gwei floor) and execution
    (base-fee check) still reject them until the txpool and EVM slices land. Tests therefore
    exercise sequencing with fee-carrying transactions, which works today.

Executed tests

  • Unit: sequencing/selection/quota/ceiling, reserved ordering (ascending pop, never-drop,
    time tie-break, Shift re-wrap, clone, interrupt), RLP encode/decode compatibility.
  • Wire-neutrality is test-pinned: with the field unset, BlockExtraData encodes as the same
    4-element list as before this PR — headers are byte-identical.
  • e2e (test worker): nil-registry regression, reserved inclusion, quota overflow, header field
    present/absent, and a positional test where a reserved sender's 26 gwei tx is included ahead
    of a normal sender's 100 gwei tx.
  • Full miner suite under -race: green. Diffguard mutation score on the diff: 99.3 %
    (147/148; the lone survivor is an equivalent mutant — boundary case where both variants
    return nil).

Rollout notes

Safe to merge and deploy now; the feature is dormant. There is no hardfork in this PR and no
production code sets a registry (Miner.SetReservedRegistry has no production caller), so:

  • every reserved code path exits at its nil-registry check before touching anything;
  • block building is behaviorally identical to develop, and produced headers are
    byte-identical (no ReservedGasUsed is ever written — test-pinned);
  • validation/execution paths are untouched, so validators, sentries, and RPC nodes are unaffected.

Backwards-compatible, no coordination or operator action needed. Activation happens in a later
slice: the contract-backed registry plus a hardfork gate on the header write
(TODO(reserved-blockspace) marks the spot, following the Giugliano gating pattern).

@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.52941% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 54.16%. Comparing base (ccc20e9) to head (c069dbb).

Files with missing lines Patch % Lines
core/types/block.go 84.61% 4 Missing and 2 partials ⚠️
miner/ordering.go 92.18% 4 Missing and 1 partial ⚠️
miner/worker.go 91.37% 3 Missing and 2 partials ⚠️
miner/miner.go 0.00% 2 Missing ⚠️
miner/reserved_registry.go 95.45% 1 Missing and 1 partial ⚠️
miner/sequencing.go 98.49% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #2302      +/-   ##
===========================================
+ Coverage    54.05%   54.16%   +0.10%     
===========================================
  Files          907      909       +2     
  Lines       161982   162243     +261     
===========================================
+ Hits         87564    87882     +318     
+ Misses       69000    68939      -61     
- Partials      5418     5422       +4     
Files with missing lines Coverage Δ
miner/miner.go 71.20% <0.00%> (-1.16%) ⬇️
miner/reserved_registry.go 95.45% <95.45%> (ø)
miner/sequencing.go 98.49% <98.49%> (ø)
miner/ordering.go 93.61% <92.18%> (-0.93%) ⬇️
miner/worker.go 81.98% <91.37%> (+4.06%) ⬆️
core/types/block.go 47.03% <84.61%> (+3.83%) ⬆️

... and 20 files with indirect coverage changes

Files with missing lines Coverage Δ
miner/miner.go 71.20% <0.00%> (-1.16%) ⬇️
miner/reserved_registry.go 95.45% <95.45%> (ø)
miner/sequencing.go 98.49% <98.49%> (ø)
miner/ordering.go 93.61% <92.18%> (-0.93%) ⬇️
miner/worker.go 81.98% <91.37%> (+4.06%) ⬆️
core/types/block.go 47.03% <84.61%> (+3.83%) ⬆️

... and 20 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@manav2401 manav2401 changed the title (feat): sequencing rules for reserved blockspace (feat): reserved blockspace block building Jul 15, 2026
@manav2401
manav2401 marked this pull request as ready for review July 15, 2026 10:49
Copilot AI review requested due to automatic review settings July 15, 2026 10:49

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@manav2401

Copy link
Copy Markdown
Contributor Author

@claude review

lucca30
lucca30 previously approved these changes Jul 15, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Implements the miner-side sequencing and header plumbing needed to support “reserved blockspace” block building, by splitting block filling into ordered commit batches (priority → per-reserved-client → normal) and optionally recording reserved-region gas usage into Header.Extra (post-Cancun) for future validation work.

Changes:

  • Adds a sequencing stage to partition pending transactions into prioritized, reserved-per-client (quota/ceiling), and normal batches, and commits them in order.
  • Extends the miner’s ordering heap with a reserved mode (ascending effective tip, never dropping below-base-fee txs) and introduces a registry interface + test mock.
  • Extends core/types.BlockExtraData with an optional ReservedGasUsed field plus getter/setter and RLP compatibility tests.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
miner/worker.go Integrates batch sequencing into block filling and writes ReservedGasUsed into header extra data when the reserved pass is active.
miner/sequencing.go Implements batch formation logic (priority extraction, reserved selection by quota/ceiling, deterministic per-block client rotation) and adds producer metrics.
miner/reserved_test.go Adds unit/e2e-style tests for sequencing/quota/ceiling behavior, registry snapshotting, and header field presence/absence.
miner/reserved_registry.go Adds the reserved registry interface plus an in-memory mock registry for tests.
miner/ordering.go Adds reserved-mode ordering (ascending effective tip, clamped below-base-fee) and threads a reserved flag through the heap implementation.
miner/ordering_test.go Adds focused tests for reserved ordering semantics and interrupt/clone behavior.
miner/miner.go Exposes Miner.SetReservedRegistry to wire a registry into the worker.
core/types/block.go Adds ReservedGasUsed to BlockExtraData and implements GetReservedGasUsed / SetReservedGasUsed.
core/types/block_test.go Adds RLP backward-compatibility and getter/setter tests for the new extra-data field.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread miner/sequencing.go
Comment thread miner/worker.go

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Beyond the inline findings, this run also examined and ruled out a few adjacent concerns: blob transactions being silently dropped by the new fillTransactions (bor's txpool filter already excludes blob txs, so none are dropped by this change), SetReservedGasUsed corrupting a nil GasTarget/BaseFeeChangeDenominator into an explicit zero (the RLP optional-pointer round-trip preserves the existing nil/zero distinction), and an empty pre-seal commit bypassing writeReservedGasUsed (the write happens unconditionally at the end of fillTransactions, including for empty/interrupted builds).

Extended reasoning...

This is a record of additional areas checked beyond the two inline findings (the dead fillTransactionsOld duplication and the multi-batch BlockSTM TxDependency reset bug), not a guarantee of correctness or an instruction to skip these in future review.

Comment thread miner/worker.go
Comment thread miner/worker.go Outdated
Copilot AI review requested due to automatic review settings July 15, 2026 13:00
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
3.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@manav2401

Copy link
Copy Markdown
Contributor Author

@claude review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comment thread miner/worker.go
@manav2401
manav2401 requested a review from a team July 15, 2026 14:07
Copilot AI review requested due to automatic review settings July 16, 2026 08:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread miner/sequencing.go
Comment on lines +68 to +81
type ranked struct {
id uint64
digest []byte
}
var buf [40]byte
copy(buf[8:], parentHash[:])
ranks := make([]ranked, len(ids))
for i, id := range ids {
binary.BigEndian.PutUint64(buf[:8], id)
ranks[i] = ranked{id: id, digest: crypto.Keccak256(buf[:])}
}
sort.Slice(ranks, func(i, j int) bool {
return bytes.Compare(ranks[i].digest, ranks[j].digest) < 0
})
Comment thread miner/sequencing.go
Comment on lines +158 to +172
if registry == nil || len(registry.Clients()) == 0 {
return nil
}
reservedTxs := filterReservedTxs(pendingTxs, registry)
if len(reservedTxs) == 0 {
return nil
}

// The global ceiling bounds the summed declared gas selected across all
// clients. Like per-client quota, it is charged against declared gas
// limits, not actual gas used.
ceilingLeft := effectiveCeilingGas(registry)

clientOrder := orderClients(parentHash, registry.Clients())
var clientGroups = make([]*transactionsByPriceAndNonce, 0, len(clientOrder))
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.

3 participants