Skip to content

feat: merge-train/spartan#22177

Merged
AztecBot merged 10 commits into
nextfrom
merge-train/spartan
Apr 1, 2026
Merged

feat: merge-train/spartan#22177
AztecBot merged 10 commits into
nextfrom
merge-train/spartan

Conversation

@AztecBot

@AztecBot AztecBot commented Mar 31, 2026

Copy link
Copy Markdown
Collaborator

BEGIN_COMMIT_OVERRIDE
chore: (A-771) remove dead code, verify keypair (#22167)
fix(aes128): validate PKCS#7 padding in decryptBufferCBC (#22179)
chore: (A-815) fix l1 tx utils fallback id logic (#22187)
fix(archiver): always advance L1-to-L2 messages syncpoint to current L1 block (#22154)
chore: (A-832) fix defaultFetch double consuming response on JSON parse failure (#22194)
fix: indefinite retry for prover node and agent broker communication (#22202)
fix: remove unused createDispatchFn with no method allowlist (#22219)
chore: fix wallet setup to use NO_FROM instead of ZERO address (#22222)
fix: update aes128 bad-key test for PKCS#7 padding validation (#22190)
END_COMMIT_OVERRIDE

During decryption `decryptBn254KeystoreFromObject` recomputes and
validates that the checksum is correct, which is the key pair
verification that makes this `verifyBn254Keypair` function obsolete.

Co-authored-by: danielntmd <danielntmd@nethermind.io>

@ludamad ludamad left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 Auto-approved

@AztecBot AztecBot enabled auto-merge March 31, 2026 14:29
@AztecBot

Copy link
Copy Markdown
Collaborator Author

🤖 Auto-merge enabled after 4 hours of inactivity. This PR will be merged automatically once all checks pass.

spypsy and others added 8 commits March 31, 2026 16:06
## Summary

- `decryptBufferCBC` previously stripped padding by blindly trusting the
last byte value with no validation
- A corrupt or maliciously crafted ciphertext could silently produce
wrong plaintext (wrong number of bytes stripped) instead of an error
- Adds full PKCS#7 validation: padding length must be in [1, 16] and all
padding bytes must equal the declared length

Fixes
[A-767](https://linear.app/aztec-labs/issue/A-767/audit-101-aes-128-decryption-has-no-pkcs7-padding-validation-padding)

Made with [Cursor](https://cursor.com)
This is purely a correctness fix, no behavioral changes as the id is
only used for store operations and when there is no store, this fallback
is never hit.

**Fallback logic previous:** 
If `txs.map` is empty then `this.txs.map(tx => tx.id)` resolves to
nothing and `Math.max(0)` resolves to 0.
Next iteration, `this.txs.map(tx => tx.id)` resolves to 0 and
`Math.max(0, 0)` resolves to 0 again. Collision!

**Fallback logic fixed:**
If `txs.map` is empty then `this.txs.map(tx => tx.id)` resolves to empty
and `Math.max(-1) + 1` resolves to 0.
Next iteration, `this.txs.map(tx => tx.id)` resolves to 0 and
`Math.max(0, -1) + 1` resolves to 1, a unique id.

Co-authored-by: danielntmd <danielntmd@nethermind.io>
…L1 block (#22154)

## Motivation

The L1-to-L2 messages syncpoint tracked the L1 block of the last
downloaded message. If no messages were sent for a long time, the
syncpoint got stuck and the next non-empty sync iteration re-scanned old
block ranges. The rolling hash check and rollback logic already handle
L1 reorgs, making this conservative syncpoint advancement redundant.

## Approach

The syncpoint now always advances to `currentL1BlockNumber` on success.
After downloading, local state is verified against L1; on mismatch the
syncpoint rolls back and the operation retries (up to 3 times within the
same L1 sync iteration).

## Extras

Method `setInboxTreeInProgress` was called before messages were
downloaded, allowing concurrent RPC reads to see a checkpoint as sealed
before its messages were available. Also, `retrieveL1ToL2Message` would
scan a large block range, as opposed to just using the L1 sync data
already stored in the archiver.

## Changes

- **archiver**: Refactored `handleL1ToL2Messages` to always advance the
syncpoint on success, with rollback-and-retry on mismatch. Merged
`setInboxTreeInProgress` and `setMessageSynchedL1Block` into a single
atomic `setMessageSyncState`. Re-throws unexpected
(non-`MessageStoreError`) exceptions instead of swallowing them. Updated
README to document the new sync logic.
- **archiver (tests)**: Updated store tests for `setMessageSyncState`.
Improved `fake_l1_state` to correctly filter messages by block number in
`getState` and support `getMessageSentEventByHash`.
- **ethereum**: Updated `InboxContract.getMessageSentEventByHash`
signature to take `(msgHash, l1BlockHash)` instead of `(hash, fromBlock,
toBlock)`.
- **foundation**: Added `retryTimes` utility function (like `retryUntil`
but with a retry count instead of a timeout).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…se failure (#22194)

When the json() call fails and the response was OK (2xx), the code
called resp.tex() to include the body in the error. The error message
never contains the actual body content since we have already consumed
the response body. Now we read the body as text first, then parse as
JSON.

Co-authored-by: danielntmd <danielntmd@nethermind.io>
…22202)

## Summary

Changes the HTTP-level retry mechanism for prover node and agent
communication with the prover broker from limited retries to indefinite
backoff:

- **Prover node → broker** (`start_node.ts`): Changed from finite retry
array `[1, 2, 3, 3, ...]` (~30s) to indefinite backoff `[1, 1, 1, 2, 4,
4, 4, ...]`
- **Prover agent → broker** (`start_prover_agent.ts`): Same change
- **Default broker RPC clients** (`rpc.ts`): Updated defaults to use the
new `proverBrokerBackoff` generator
- **`makeTracedFetch`** (`fetch.ts`): Now accepts either a `number[]`
for finite backoff or a `() => Generator<number>` factory for indefinite
backoff

The rationale is that the epoch proving has its own timeout — when it
expires, the chain reorgs and jobs can be safely cancelled. There's no
reason for the HTTP communication layer to give up before that happens.

## Test plan

- [x] All 98 proving broker tests pass
- [x] Build succeeds
- [ ] Verify in spartan that prover node and agent reconnect to broker
after transient failures"
## Summary
- Removes dead `createDispatchFn` which allowed arbitrary method
dispatch without a method allowlist
- The function had zero callsites — the only `TransportServer` usage
already validates via `schemaHasMethod`
- Moves the `DispatchMsg` type into `create_dispatch_proxy.ts` where
it's actually used

Fixes A-745

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This fixes the `mempool_limit` test that the scenario deployment tests.

Fixing a malformed merge.

Co-authored-by: danielntmd <danielntmd@nethermind.io>
## Summary
PR #22179 added PKCS#7 padding validation to `decryptBufferCBC`, which
causes the AES oracle to return `None` (instead of `Some(garbage)`) when
decrypting with the wrong key. This broke the
`aes_encrypt_then_decrypt_with_bad_sym_key_is_caught` test which
expected `Some`.

Updated the test to assert `None` is returned, updated the doc comment
on `try_aes128_decrypt`, and removed unused imports.

## Details
- [Full
analysis](https://gist.github.com/AztecBot/0ba88957f8a4e11ac07afee832905d58)

ClaudeBox log: https://claudebox.work/s/75f04c49a604e884?run=1
@spypsy spypsy requested a review from nventuro as a code owner April 1, 2026 13:53
@AztecBot AztecBot added this pull request to the merge queue Apr 1, 2026
Merged via the queue into next with commit 94251f5 Apr 1, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants