Skip to content

eth/sequencer: cap coalesced published records at the store message limit - #2400

Merged
cffls merged 1 commit into
cffls/sequence-publisherfrom
cffls/preconf-record-size-cap
Sep 10, 2026
Merged

eth/sequencer: cap coalesced published records at the store message limit#2400
cffls merged 1 commit into
cffls/sequence-publisherfrom
cffls/preconf-record-size-cap

Conversation

@cffls

@cffls cffls commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

The send path coalesces up to 64 transactions into one published record (commit 89143d7), bounded only by that count and a 32 MB pending-input limit — never by the store's Redpanda max.message.bytes. A run of large transactions (e.g. 64 × 32 KiB) produced a >1 MiB record, which draws a permanent MESSAGE_TOO_LARGE on produce. The ingress treats a produce failure as a fence and takeover replays the same record, so one oversized record wedges the writer and starves every preconfirmation behind it — the "nothing gets preconfirmed under load" report from the Amoy stress test.

This caps a coalesced record at maxRecordBytes = maxMessageBytes (1 MiB) less a 4 KiB reserve for per-transaction protobuf framing, the prefix commitment, and the ingress's own recordFraming allowance — so bor never builds a record the ingress would reject. A lone transaction over the cap is still emitted and left for the store to judge, not silently dropped. The limit is a package constant (maxMessageBytes), matched to the store side.

The store-side half (reject oversized instead of self-fencing) is 0xPolygon/sequence-store#12.

Executed tests

  • New unit tests in stream_test.go: TestCoalesceRecordByteCap (40 × 32 KiB → byte-capped prefix, proto.Size under the ingress limit, fold commitment preserved), TestCoalesceRecordByteCapBoundary (exact-fill is inclusive), TestCoalesceRecordCountCap (the 64-tx count cap still binds below the byte cap).
  • go test ./eth/sequencer/ green; diffguard clean with mutation testing.
  • Kurtosis (3 producers + 3-broker Redpanda + gateways, both fixes deployed): under a 32 KiB-calldata load, records coalesce to ~23.6 tx each; across 6,550 oversized-calldata txs there were 0 self-fences, 0 MALFORMED, 0 MESSAGE_TOO_LARGE, with preconf serving throughout — versus the wedge this reproduces without the cap.

Rollout notes

Producer-side only; not consensus-affecting (changes what a producer batches into a store record, not block content). Backwards-compatible. Pairs with sequence-store#12 — either side alone prevents the wedge; together they keep bor's records provably under the store limit.

🤖 Generated with Claude Code

…imit

The send path coalesces up to 64 transactions into one published record
(commit 89143d7). It bounded a record only by that count and the 32 MB
pending-input limit, never by the store's Redpanda max.message.bytes, so a
run of large transactions (e.g. 64 x 32 KiB) produced a >1 MiB record. That
draws a permanent MESSAGE_TOO_LARGE on produce; the ingress treats a produce
failure as a fence and takeover replays the same record, so one oversized
record wedges the writer and nothing behind it is preconfirmed.

Cap a coalesced record at maxRecordBytes (max.message.bytes less a 4 KiB
reserve for per-transaction protobuf framing, the prefix commitment, and the
ingress's own recordFraming allowance), so bor never builds a record the
ingress would reject. A lone transaction over the cap is still emitted and
left for the store to judge, not dropped.

Also give the terminal MALFORMED ack path a clearer message: with the cap in
place a MALFORMED means the store's max.message.bytes is below this build's
record cap, not an oversized record.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cffls
cffls force-pushed the cffls/preconf-record-size-cap branch from 1d91d1c to cd7ea97 Compare September 10, 2026 05:57
@cffls
cffls marked this pull request as ready for review September 10, 2026 06:17

@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.

@vbhattaccmu
vbhattaccmu self-requested a review September 10, 2026 06:25
@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.99%. Comparing base (1e20c79) to head (cd7ea97).

Additional details and impacted files

Impacted file tree graph

@@                     Coverage Diff                      @@
##           cffls/sequence-publisher    #2400      +/-   ##
============================================================
+ Coverage                     56.97%   56.99%   +0.01%     
============================================================
  Files                           951      951              
  Lines                        174328   174330       +2     
============================================================
+ Hits                          99328    99351      +23     
+ Misses                        69320    69309      -11     
+ Partials                       5680     5670      -10     
Files with missing lines Coverage Δ
eth/sequencer/stream.go 92.82% <100.00%> (+0.49%) ⬆️

... and 24 files with indirect coverage changes

Files with missing lines Coverage Δ
eth/sequencer/stream.go 92.82% <100.00%> (+0.49%) ⬆️

... and 24 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.

@cffls
cffls merged commit b56ff74 into cffls/sequence-publisher Sep 10, 2026
19 checks passed
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