Skip to content

fix(manifest): raise MAX_LOGS_PER_MANIFEST to 32768 - #215

Open
prajwolrg wants to merge 1 commit into
mainfrom
fix/manifest-log-cap
Open

fix(manifest): raise MAX_LOGS_PER_MANIFEST to 32768#215
prajwolrg wants to merge 1 commit into
mainfrom
fix/manifest-log-cap

Conversation

@prajwolrg

@prajwolrg prajwolrg commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Description

MAX_LOGS_PER_MANIFEST was 1024, and today's deposit traffic alone can go past it. One deposit transaction produces one ASM log, and a deposit transaction is small:

part bytes
version, locktime, input and output counts 10
one input 41
SPS-50 OP_RETURN output (magic 4 + subproto 1 + tx type 1 + deposit idx 4) 21
N/N P2TR output 43
segwit marker/flag and witness 68
total 183

The 115 non-witness bytes count 4x toward weight and the 68 witness bytes count 1x, giving 528 WU, or 132 vbytes. Against Bitcoin's 4,000,000 WU block limit that is about 7,575 deposits in one block — more than seven times the old cap, with no other subprotocol involved.

Going over the cap is unrecoverable rather than merely noisy. Manifest construction fails, that fails the whole state transition, and the guest panics, so no proof can ever be produced for that block and the ASM cannot advance past it. That makes this a cap worth setting with room to spare rather than tightly.

This raises it to 32768.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Proving Cost

Measured against main at 4829393:

cycles gas
main 136,414,202 134,127,867
this PR 136,427,682 134,144,064
delta +13,480 (+0.010%) +16,197 (+0.012%)

Capacity only affects merkleization depth. The list serializes and decodes identically, and padding comes from precomputed zero hashes rather than being hashed out, so the tree is simply 5 levels deeper. That is 5 extra sha256 compressions per manifest.

The count is flat: it does not grow with the number of logs, because the added levels sit above where the real data ends and each one just folds the accumulated root against a cached zero hash. I checked by counting compressions for 0 through 1024 logs, and the delta is exactly 5 in every case. So this is a fixed ~13.5k cycles per block, not a cost that scales with traffic.

One thing does get more expensive, though only if we start using it. An SSZ inclusion proof for a single log entry now needs 15 sibling hashes instead of 10, so 160 more bytes on the wire and 5 more compressions to verify. Nothing proves log inclusion today, but AsmManifest::compute_hash uses SSZ partly to keep that option open, so it is worth knowing the branch got longer.

Notes to Reviewers

Changing an SSZ list capacity changes the merkleization depth, so every manifest tree hash root changes, and with it the history accumulator.

Checklist

  • I have performed a self-review of my code.
  • I have commented my code where necessary.
  • I have updated the documentation if needed.
  • My changes do not introduce new warnings.
  • I have added tests that prove my changes are effective or that my feature works.
  • New and existing tests pass with my changes.

A single L1 block can produce more than 1024 logs, and going over the cap
is unrecoverable: `AsmManifest::new` fails, the transition fails, and the
guest panics, so no proof can ever be produced for that block.

Most logs are emitted while handling a transaction, roughly one each. The
smallest protocol transaction is a deposit at 528 WU, so a 4M WU block
fits about 7.5k of them - over 7x the old cap. The admin subprotocol adds
to that from a second direction: it drains queued updates when they reach
their activation height, and those were queued in earlier blocks, so they
are not bounded by the current block's weight.

32768 covers a Bitcoin block made up entirely of protocol transactions
with about 2x to spare. A block holds at most ~16.6k transactions of any
kind, since the smallest one that can serialize with an input and an
output is 60 bytes, or 240 WU against the 4M WU limit. The margin on top
covers the admin queue drain. The bound is deliberately loose because it
is a sanity limit, not a tight one, and the only cost of a larger cap is
SSZ merkleization depth - a few cached zero hashes per manifest.

This changes the tree hash root of every manifest, and with it the history
accumulator.
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Commit: eceb8dc
SP1 Execution Results

program cycles gas
asm-stf 136,427,682 134,144,064
moho 5,223,687 5,525,436

@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
see 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@prajwolrg
prajwolrg marked this pull request as ready for review August 7, 2026 10:05
@prajwolrg
prajwolrg requested review from delbonis and irnb August 7, 2026 10:11

@storopoli storopoli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK a7ef74b

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

This is good reasoning! Thank you!

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