From a7ef74b8f2762646c37c9a3c51c8f767904d68bd Mon Sep 17 00:00:00 2001 From: Prajwol Gyawali Date: Fri, 7 Aug 2026 13:39:02 +0545 Subject: [PATCH] fix(manifest): raise MAX_LOGS_PER_MANIFEST to 32768 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. --- crates/manifest-types/ssz/manifest.ssz | 30 +++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/crates/manifest-types/ssz/manifest.ssz b/crates/manifest-types/ssz/manifest.ssz index f1dfca6c..3c9d23ee 100644 --- a/crates/manifest-types/ssz/manifest.ssz +++ b/crates/manifest-types/ssz/manifest.ssz @@ -1,7 +1,35 @@ import strata_identifiers import log -MAX_LOGS_PER_MANIFEST = 1 << 10 +### Maximum number of log entries a single manifest can hold. +### +### Most logs are emitted while handling a transaction, roughly one each, so +### their count tracks how many protocol transactions land in one L1 block. A +### Bitcoin block holds at most ~16.6k transactions of any kind, so the cap +### covers a block made up entirely of protocol transactions with about 2x to +### spare. +### +### That ~16.6k is the block weight limit divided by the smallest a transaction +### can serialize to and still have one input and one output: +### +### - version: 4 bytes +### - input count: 1 +### - input: 41 (32 txid + 4 index + 1 empty scriptSig + 4 sequence) +### - output count: 1 +### - output: 9 (8 value + 1 empty scriptPubKey) +### - locktime: 4 +### +### That is 60 bytes. Non-witness bytes count 4x, so 240 WU, and the block +### limit of 4M WU divided by 240 gives ~16.6k. +### +### The margin on top covers logs that are not tied to this block's own +### transactions. Some are emitted later than the transaction that caused them, +### once a deferred action reaches the height it takes effect at, so they land +### in a block whose weight says nothing about how many of them there are. +### +### Overflowing the cap fails the whole state transition, so the bound is +### deliberately loose: it is a sanity limit, not a tight one. +MAX_LOGS_PER_MANIFEST = 1 << 15 ### The manifest output produced after processing an L1 block. ###