@aztec/archiver 0.0.1-commit.d431d1c → 0.0.1-commit.db765a8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +9 -0
  2. package/dest/archiver.d.ts +10 -6
  3. package/dest/archiver.d.ts.map +1 -1
  4. package/dest/archiver.js +50 -111
  5. package/dest/errors.d.ts +6 -1
  6. package/dest/errors.d.ts.map +1 -1
  7. package/dest/errors.js +8 -0
  8. package/dest/factory.d.ts +5 -2
  9. package/dest/factory.d.ts.map +1 -1
  10. package/dest/factory.js +16 -13
  11. package/dest/index.d.ts +2 -1
  12. package/dest/index.d.ts.map +1 -1
  13. package/dest/index.js +1 -0
  14. package/dest/l1/bin/retrieve-calldata.js +35 -32
  15. package/dest/l1/calldata_retriever.d.ts +73 -50
  16. package/dest/l1/calldata_retriever.d.ts.map +1 -1
  17. package/dest/l1/calldata_retriever.js +190 -259
  18. package/dest/l1/data_retrieval.d.ts +9 -9
  19. package/dest/l1/data_retrieval.d.ts.map +1 -1
  20. package/dest/l1/data_retrieval.js +24 -22
  21. package/dest/l1/spire_proposer.d.ts +5 -5
  22. package/dest/l1/spire_proposer.d.ts.map +1 -1
  23. package/dest/l1/spire_proposer.js +9 -17
  24. package/dest/l1/validate_trace.d.ts +6 -3
  25. package/dest/l1/validate_trace.d.ts.map +1 -1
  26. package/dest/l1/validate_trace.js +13 -9
  27. package/dest/modules/data_source_base.d.ts +23 -19
  28. package/dest/modules/data_source_base.d.ts.map +1 -1
  29. package/dest/modules/data_source_base.js +44 -119
  30. package/dest/modules/data_store_updater.d.ts +31 -20
  31. package/dest/modules/data_store_updater.d.ts.map +1 -1
  32. package/dest/modules/data_store_updater.js +79 -60
  33. package/dest/modules/instrumentation.d.ts +17 -4
  34. package/dest/modules/instrumentation.d.ts.map +1 -1
  35. package/dest/modules/instrumentation.js +36 -12
  36. package/dest/modules/l1_synchronizer.d.ts +4 -8
  37. package/dest/modules/l1_synchronizer.d.ts.map +1 -1
  38. package/dest/modules/l1_synchronizer.js +23 -19
  39. package/dest/store/block_store.d.ts +50 -32
  40. package/dest/store/block_store.d.ts.map +1 -1
  41. package/dest/store/block_store.js +147 -54
  42. package/dest/store/contract_class_store.d.ts +1 -1
  43. package/dest/store/contract_class_store.d.ts.map +1 -1
  44. package/dest/store/contract_class_store.js +11 -7
  45. package/dest/store/kv_archiver_store.d.ts +43 -25
  46. package/dest/store/kv_archiver_store.d.ts.map +1 -1
  47. package/dest/store/kv_archiver_store.js +38 -17
  48. package/dest/store/l2_tips_cache.d.ts +19 -0
  49. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  50. package/dest/store/l2_tips_cache.js +89 -0
  51. package/dest/store/log_store.d.ts +4 -4
  52. package/dest/store/log_store.d.ts.map +1 -1
  53. package/dest/store/log_store.js +57 -37
  54. package/dest/test/fake_l1_state.d.ts +9 -4
  55. package/dest/test/fake_l1_state.d.ts.map +1 -1
  56. package/dest/test/fake_l1_state.js +56 -18
  57. package/dest/test/index.js +3 -1
  58. package/dest/test/mock_archiver.d.ts +1 -1
  59. package/dest/test/mock_archiver.d.ts.map +1 -1
  60. package/dest/test/mock_archiver.js +3 -2
  61. package/dest/test/mock_l2_block_source.d.ts +36 -21
  62. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  63. package/dest/test/mock_l2_block_source.js +151 -109
  64. package/dest/test/mock_structs.d.ts +3 -2
  65. package/dest/test/mock_structs.d.ts.map +1 -1
  66. package/dest/test/mock_structs.js +11 -9
  67. package/dest/test/noop_l1_archiver.d.ts +23 -0
  68. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  69. package/dest/test/noop_l1_archiver.js +68 -0
  70. package/package.json +14 -13
  71. package/src/archiver.ts +71 -136
  72. package/src/errors.ts +12 -0
  73. package/src/factory.ts +30 -14
  74. package/src/index.ts +1 -0
  75. package/src/l1/README.md +25 -68
  76. package/src/l1/bin/retrieve-calldata.ts +45 -33
  77. package/src/l1/calldata_retriever.ts +249 -379
  78. package/src/l1/data_retrieval.ts +27 -29
  79. package/src/l1/spire_proposer.ts +7 -15
  80. package/src/l1/validate_trace.ts +24 -6
  81. package/src/modules/data_source_base.ts +73 -163
  82. package/src/modules/data_store_updater.ts +92 -63
  83. package/src/modules/instrumentation.ts +46 -14
  84. package/src/modules/l1_synchronizer.ts +26 -24
  85. package/src/store/block_store.ts +188 -92
  86. package/src/store/contract_class_store.ts +11 -7
  87. package/src/store/kv_archiver_store.ts +69 -29
  88. package/src/store/l2_tips_cache.ts +89 -0
  89. package/src/store/log_store.ts +105 -43
  90. package/src/test/fake_l1_state.ts +77 -19
  91. package/src/test/index.ts +3 -0
  92. package/src/test/mock_archiver.ts +3 -2
  93. package/src/test/mock_l2_block_source.ts +196 -126
  94. package/src/test/mock_structs.ts +26 -10
  95. package/src/test/noop_l1_archiver.ts +109 -0
@@ -10,10 +10,11 @@ import { Fr } from '@aztec/foundation/curves/bn254';
10
10
  import { EthAddress } from '@aztec/foundation/eth-address';
11
11
  import { createLogger } from '@aztec/foundation/log';
12
12
  import { RollupAbi } from '@aztec/l1-artifacts';
13
- import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2BlockNew } from '@aztec/stdlib/block';
13
+ import { CommitteeAttestation, CommitteeAttestationsAndSigners, L2Block } from '@aztec/stdlib/block';
14
14
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
15
15
  import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
16
16
  import { InboxLeaf } from '@aztec/stdlib/messaging';
17
+ import { ConsensusPayload, SignatureDomainSeparator } from '@aztec/stdlib/p2p';
17
18
  import {
18
19
  makeAndSignCommitteeAttestationsAndSigners,
19
20
  makeCheckpointAttestationFromCheckpoint,
@@ -22,7 +23,16 @@ import {
22
23
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
23
24
 
24
25
  import { type MockProxy, mock } from 'jest-mock-extended';
25
- import { type FormattedBlock, type Transaction, encodeFunctionData, multicall3Abi, toHex } from 'viem';
26
+ import {
27
+ type AbiParameter,
28
+ type FormattedBlock,
29
+ type Transaction,
30
+ encodeAbiParameters,
31
+ encodeFunctionData,
32
+ keccak256,
33
+ multicall3Abi,
34
+ toHex,
35
+ } from 'viem';
26
36
 
27
37
  import { updateRollingHash } from '../structs/inbox_message.js';
28
38
 
@@ -51,7 +61,7 @@ type AddCheckpointOptions = {
51
61
  /** Number of L2 blocks in the checkpoint. Default: 1 */
52
62
  numBlocks?: number;
53
63
  /** Or the actual blocks for the checkpoint */
54
- blocks?: L2BlockNew[];
64
+ blocks?: L2Block[];
55
65
  /** Number of transactions per block. Default: 4 */
56
66
  txsPerBlock?: number;
57
67
  /** Max number of effects per tx (for generating large blobs). Default: undefined */
@@ -87,6 +97,10 @@ type CheckpointData = {
87
97
  blobHashes: `0x${string}`[];
88
98
  blobs: Blob[];
89
99
  signers: Secp256k1Signer[];
100
+ /** Hash of the packed attestations, matching what the L1 event emits. */
101
+ attestationsHash: Buffer32;
102
+ /** Payload digest, matching what the L1 event emits. */
103
+ payloadDigest: Buffer32;
90
104
  /** If true, archiveAt will ignore it */
91
105
  pruned?: boolean;
92
106
  };
@@ -131,6 +145,7 @@ export class FakeL1State {
131
145
  private provenCheckpointNumber: CheckpointNumber = CheckpointNumber(0);
132
146
  private targetCommitteeSize: number = 0;
133
147
  private version: bigint = 1n;
148
+ private canPruneResult: boolean = false;
134
149
 
135
150
  // Computed from checkpoints based on L1 block visibility
136
151
  private pendingCheckpointNumber: CheckpointNumber = CheckpointNumber(0);
@@ -193,10 +208,10 @@ export class FakeL1State {
193
208
  // Store the messages internally so they match the checkpoint's inHash
194
209
  this.addMessages(checkpointNumber, messagesL1BlockNumber, messages);
195
210
 
196
- // Create the transaction and blobs
197
- const tx = this.makeRollupTx(checkpoint, signers);
198
- const blobHashes = this.makeVersionedBlobHashes(checkpoint);
199
- const blobs = this.makeBlobsFromCheckpoint(checkpoint);
211
+ // Create the transaction, blobs, and event hashes
212
+ const { tx, attestationsHash, payloadDigest } = await this.makeRollupTx(checkpoint, signers);
213
+ const blobHashes = await this.makeVersionedBlobHashes(checkpoint);
214
+ const blobs = await this.makeBlobsFromCheckpoint(checkpoint);
200
215
 
201
216
  // Store the checkpoint data
202
217
  this.checkpoints.push({
@@ -207,6 +222,8 @@ export class FakeL1State {
207
222
  blobHashes,
208
223
  blobs,
209
224
  signers,
225
+ attestationsHash,
226
+ payloadDigest,
210
227
  });
211
228
 
212
229
  // Update last archive for auto-chaining
@@ -276,6 +293,11 @@ export class FakeL1State {
276
293
  this.targetCommitteeSize = size;
277
294
  }
278
295
 
296
+ /** Sets whether the rollup contract would allow pruning at the next block. */
297
+ setCanPrune(value: boolean): void {
298
+ this.canPruneResult = value;
299
+ }
300
+
279
301
  /**
280
302
  * Removes all entries for a checkpoint number (simulates L1 reorg or prune).
281
303
  * Note: Does NOT remove messages for this checkpoint (use numL1ToL2Messages: 0 when re-adding).
@@ -384,6 +406,8 @@ export class FakeL1State {
384
406
  });
385
407
  });
386
408
 
409
+ mockRollup.canPruneAtTime.mockImplementation(() => Promise.resolve(this.canPruneResult));
410
+
387
411
  // Mock the wrapper method for fetching checkpoint events
388
412
  mockRollup.getCheckpointProposedEvents.mockImplementation((fromBlock: bigint, toBlock: bigint) =>
389
413
  Promise.resolve(this.getCheckpointProposedLogs(fromBlock, toBlock)),
@@ -502,10 +526,8 @@ export class FakeL1State {
502
526
  checkpointNumber: cpData.checkpointNumber,
503
527
  archive: cpData.checkpoint.archive.root,
504
528
  versionedBlobHashes: cpData.blobHashes.map(h => Buffer.from(h.slice(2), 'hex')),
505
- // These are intentionally undefined to skip hash validation in the archiver
506
- // (validation is skipped when these fields are falsy)
507
- payloadDigest: undefined,
508
- attestationsHash: undefined,
529
+ attestationsHash: cpData.attestationsHash,
530
+ payloadDigest: cpData.payloadDigest,
509
531
  },
510
532
  }));
511
533
  }
@@ -531,14 +553,17 @@ export class FakeL1State {
531
553
  }));
532
554
  }
533
555
 
534
- private makeRollupTx(checkpoint: Checkpoint, signers: Secp256k1Signer[]): Transaction {
556
+ private async makeRollupTx(
557
+ checkpoint: Checkpoint,
558
+ signers: Secp256k1Signer[],
559
+ ): Promise<{ tx: Transaction; attestationsHash: Buffer32; payloadDigest: Buffer32 }> {
535
560
  const attestations = signers
536
561
  .map(signer => makeCheckpointAttestationFromCheckpoint(checkpoint, signer))
537
562
  .map(attestation => CommitteeAttestation.fromSignature(attestation.signature))
538
563
  .map(committeeAttestation => committeeAttestation.toViem());
539
564
 
540
565
  const header = checkpoint.header.toViem();
541
- const blobInput = getPrefixedEthBlobCommitments(getBlobsPerL1Block(checkpoint.toBlobFields()));
566
+ const blobInput = getPrefixedEthBlobCommitments(await getBlobsPerL1Block(checkpoint.toBlobFields()));
542
567
  const archive = toHex(checkpoint.archive.root.toBuffer());
543
568
  const attestationsAndSigners = new CommitteeAttestationsAndSigners(
544
569
  attestations.map(attestation => CommitteeAttestation.fromViem(attestation)),
@@ -549,6 +574,8 @@ export class FakeL1State {
549
574
  signers[0],
550
575
  );
551
576
 
577
+ const packedAttestations = attestationsAndSigners.getPackedAttestations();
578
+
552
579
  const rollupInput = encodeFunctionData({
553
580
  abi: RollupAbi,
554
581
  functionName: 'propose',
@@ -558,7 +585,7 @@ export class FakeL1State {
558
585
  archive,
559
586
  oracleInput: { feeAssetPriceModifier: 0n },
560
587
  },
561
- attestationsAndSigners.getPackedAttestations(),
588
+ packedAttestations,
562
589
  attestationsAndSigners.getSigners().map(signer => signer.toString()),
563
590
  attestationsAndSignersSignature.toViemSignature(),
564
591
  blobInput,
@@ -579,21 +606,52 @@ export class FakeL1State {
579
606
  ],
580
607
  });
581
608
 
582
- return {
609
+ // Compute attestationsHash (same logic as CalldataRetriever)
610
+ const attestationsHash = Buffer32.fromString(
611
+ keccak256(encodeAbiParameters([this.getCommitteeAttestationsStructDef()], [packedAttestations])),
612
+ );
613
+
614
+ // Compute payloadDigest (same logic as CalldataRetriever)
615
+ const consensusPayload = ConsensusPayload.fromCheckpoint(checkpoint);
616
+ const payloadToSign = consensusPayload.getPayloadToSign(SignatureDomainSeparator.checkpointAttestation);
617
+ const payloadDigest = Buffer32.fromString(keccak256(payloadToSign));
618
+
619
+ const tx = {
583
620
  input: multiCallInput,
584
621
  hash: archive,
585
622
  blockHash: archive,
586
623
  to: MULTI_CALL_3_ADDRESS as `0x${string}`,
587
624
  } as Transaction<bigint, number>;
625
+
626
+ return { tx, attestationsHash, payloadDigest };
627
+ }
628
+
629
+ /** Extracts the CommitteeAttestations struct definition from RollupAbi for hash computation. */
630
+ private getCommitteeAttestationsStructDef(): AbiParameter {
631
+ const proposeFunction = RollupAbi.find(item => item.type === 'function' && item.name === 'propose') as
632
+ | { type: 'function'; name: string; inputs: readonly AbiParameter[] }
633
+ | undefined;
634
+
635
+ if (!proposeFunction) {
636
+ throw new Error('propose function not found in RollupAbi');
637
+ }
638
+
639
+ const attestationsParam = proposeFunction.inputs.find(param => param.name === '_attestations');
640
+ if (!attestationsParam) {
641
+ throw new Error('_attestations parameter not found in propose function');
642
+ }
643
+
644
+ const tupleParam = attestationsParam as unknown as { type: 'tuple'; components?: readonly AbiParameter[] };
645
+ return { type: 'tuple', components: tupleParam.components || [] } as AbiParameter;
588
646
  }
589
647
 
590
- private makeVersionedBlobHashes(checkpoint: Checkpoint): `0x${string}`[] {
591
- return getBlobsPerL1Block(checkpoint.toBlobFields()).map(
648
+ private async makeVersionedBlobHashes(checkpoint: Checkpoint): Promise<`0x${string}`[]> {
649
+ return (await getBlobsPerL1Block(checkpoint.toBlobFields())).map(
592
650
  b => `0x${b.getEthVersionedBlobHash().toString('hex')}` as `0x${string}`,
593
651
  );
594
652
  }
595
653
 
596
- private makeBlobsFromCheckpoint(checkpoint: Checkpoint): Blob[] {
597
- return getBlobsPerL1Block(checkpoint.toBlobFields());
654
+ private async makeBlobsFromCheckpoint(checkpoint: Checkpoint): Promise<Blob[]> {
655
+ return await getBlobsPerL1Block(checkpoint.toBlobFields());
598
656
  }
599
657
  }
package/src/test/index.ts CHANGED
@@ -2,3 +2,6 @@ export * from './mock_structs.js';
2
2
  export * from './mock_l2_block_source.js';
3
3
  export * from './mock_l1_to_l2_message_source.js';
4
4
  export * from './mock_archiver.js';
5
+ // NOTE: noop_l1_archiver.js is intentionally NOT exported here because it imports
6
+ // jest-mock-extended, which depends on @jest/globals and can only run inside Jest.
7
+ // Import it directly: import { NoopL1Archiver } from '@aztec/archiver/test/noop-l1';
@@ -56,8 +56,9 @@ export class MockPrefilledArchiver extends MockArchiver {
56
56
  }
57
57
 
58
58
  const fromBlock = this.l2Blocks.length;
59
- // TODO: Add L2 blocks and checkpoints separately once archiver has the apis for that.
60
- this.addBlocks(this.prefilled.slice(fromBlock, fromBlock + numBlocks).flatMap(c => c.blocks));
59
+ const checkpointsToAdd = this.prefilled.slice(fromBlock, fromBlock + numBlocks);
60
+ this.addProposedBlocks(checkpointsToAdd.flatMap(c => c.blocks));
61
+ this.checkpointList.push(...checkpointsToAdd);
61
62
  return Promise.resolve();
62
63
  }
63
64
  }