Skip to content

Commit 69e967d

Browse files
spalladinoclaude
andcommitted
feat(fast-inbox): drop archiver inHash cross-check and TXE message padding (A-1384)
- Archiver l1_synchronizer stops cross-checking the (now-zero) checkpoint inHash; the consensus Inbox rolling hash is verified on L1 at propose (AZIP-22 Fast Inbox). - TXE appends real message leaves unpadded at compact indices (synchronizer, block_creation) and stops padding empty blocks to a full subtree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 4dbb889 commit 69e967d

4 files changed

Lines changed: 10 additions & 49 deletions

File tree

yarn-project/archiver/src/modules/l1_synchronizer.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
PublishedCheckpoint,
3131
} from '@aztec/stdlib/checkpoint';
3232
import { type L1RollupConstants, getEpochAtSlot, getSlotAtNextL1Block } from '@aztec/stdlib/epoch-helpers';
33-
import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
3433
import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p';
3534
import { type Traceable, type Tracer, execInSpan, trackSpan } from '@aztec/telemetry-client';
3635

@@ -1013,25 +1012,8 @@ export class ArchiverL1Synchronizer implements Traceable {
10131012
for (const calldataCheckpoint of checkpointsToIngest) {
10141013
const published = publishedByNumber.get(calldataCheckpoint.checkpointNumber)!;
10151014

1016-
// Check the inHash of the checkpoint against the l1->l2 messages.
1017-
// The messages should've been synced up to the currentL1BlockNumber and must be available for the published
1018-
// checkpoints we just retrieved.
1019-
const l1ToL2Messages = await this.stores.messages.getL1ToL2Messages(published.checkpoint.number);
1020-
const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
1021-
const publishedInHash = published.checkpoint.header.inHash;
1022-
if (!computedInHash.equals(publishedInHash)) {
1023-
this.log.fatal(`Mismatch inHash for checkpoint ${published.checkpoint.number}`, {
1024-
checkpointHash: published.checkpoint.hash(),
1025-
l1BlockNumber: published.l1.blockNumber,
1026-
computedInHash,
1027-
publishedInHash,
1028-
});
1029-
// Throwing an error since this is most likely caused by a bug.
1030-
throw new Error(
1031-
`Mismatch inHash for checkpoint ${published.checkpoint.number}. Expected ${computedInHash} but got ${publishedInHash}`,
1032-
);
1033-
}
1034-
1015+
// The legacy inHash cross-check is dead post-flip (the header carries zero): the consensus Inbox rolling hash
1016+
// is verified on L1 at propose, so no equivalent check is needed here (AZIP-22 Fast Inbox).
10351017
validCheckpoints.push(published);
10361018
this.log.debug(
10371019
`Ingesting new checkpoint ${published.checkpoint.number} with ${published.checkpoint.blocks.length} blocks`,

yarn-project/txe/src/oracle/txe_oracle_top_level_context.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
3-
MAX_PRIVATE_LOGS_PER_TX,
4-
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
5-
} from '@aztec/constants';
1+
import { CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, MAX_PRIVATE_LOGS_PER_TX } from '@aztec/constants';
62
import { BlockNumber } from '@aztec/foundation/branded-types';
73
import { Schnorr } from '@aztec/foundation/crypto/schnorr';
84
import { Fr } from '@aztec/foundation/curves/bn254';
@@ -658,8 +654,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
658654

659655
txEffect.txHash = new TxHash(new Fr(blockNumber));
660656

661-
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
662-
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
657+
// Post-flip TXE blocks carry no L1-to-L2 messages, so the message tree is left unadvanced (AZIP-22 Fast Inbox).
663658

664659
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
665660

@@ -823,8 +818,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
823818

824819
txEffect.txHash = new TxHash(new Fr(blockNumber));
825820

826-
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
827-
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
821+
// Post-flip TXE blocks carry no L1-to-L2 messages, so the message tree is left unadvanced (AZIP-22 Fast Inbox).
828822

829823
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
830824

yarn-project/txe/src/state_machine/synchronizer.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
21
import { BlockNumber } from '@aztec/foundation/branded-types';
3-
import { padArrayEnd } from '@aztec/foundation/collection';
42
import { Fr } from '@aztec/foundation/curves/bn254';
53
import { AvmSimulatorPool } from '@aztec/simulator/server';
64
import type { BlockHash, L2Block } from '@aztec/stdlib/block';
@@ -35,14 +33,8 @@ export class TXESynchronizer implements WorldStateSynchronizer {
3533
}
3634

3735
public async handleL2Block(block: L2Block, l1ToL2Messages: Fr[] = []) {
38-
// Pad the bundle only for a first-in-checkpoint block, matching how the circuits (and native world state) build the
39-
// message tree. TXE mines one block per checkpoint, so this is always the first block, but keep the condition
40-
// explicit so the caller matches the per-block message-insertion semantics of handleL2BlockAndMessages.
41-
const messages =
42-
block.indexWithinCheckpoint === 0
43-
? padArrayEnd<Fr, number>(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP)
44-
: l1ToL2Messages;
45-
await this.nativeWorldStateService.handleL2BlockAndMessages(block, messages);
36+
// Append the block's real message leaves unpadded at compact indices (AZIP-22 Fast Inbox).
37+
await this.nativeWorldStateService.handleL2BlockAndMessages(block, l1ToL2Messages);
4638

4739
this.blockNumber = block.header.globalVariables.blockNumber;
4840
}

yarn-project/txe/src/utils/block_creation.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import {
2-
MAX_NOTE_HASHES_PER_TX,
3-
MAX_NULLIFIERS_PER_TX,
4-
NULLIFIER_SUBTREE_HEIGHT,
5-
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
6-
} from '@aztec/constants';
1+
import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT } from '@aztec/constants';
72
import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
83
import { padArrayEnd } from '@aztec/foundation/collection';
94
import { Fr } from '@aztec/foundation/curves/bn254';
@@ -36,10 +31,8 @@ export async function insertTxEffectIntoWorldTrees(
3631
NULLIFIER_SUBTREE_HEIGHT,
3732
);
3833

39-
await worldTrees.appendLeaves(
40-
MerkleTreeId.L1_TO_L2_MESSAGE_TREE,
41-
padArrayEnd<Fr, number>(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP),
42-
);
34+
// Append the block's real message leaves unpadded at compact indices (AZIP-22 Fast Inbox).
35+
await worldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
4336

4437
// We do not need to add public data writes because we apply them as we go.
4538
}

0 commit comments

Comments
 (0)