@aztec/stdlib 2.0.0-rc.8 → 2.0.2-rc.1

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 (91) hide show
  1. package/dest/block/index.d.ts +2 -0
  2. package/dest/block/index.d.ts.map +1 -1
  3. package/dest/block/index.js +2 -0
  4. package/dest/block/l2_block.d.ts +2 -8
  5. package/dest/block/l2_block.d.ts.map +1 -1
  6. package/dest/block/l2_block.js +5 -3
  7. package/dest/block/l2_block_info.d.ts +41 -0
  8. package/dest/block/l2_block_info.d.ts.map +1 -0
  9. package/dest/block/l2_block_info.js +40 -0
  10. package/dest/block/l2_block_source.d.ts +1 -428
  11. package/dest/block/l2_block_source.d.ts.map +1 -1
  12. package/dest/block/l2_block_source.js +0 -28
  13. package/dest/block/published_l2_block.d.ts +25 -1
  14. package/dest/block/published_l2_block.d.ts.map +1 -1
  15. package/dest/block/published_l2_block.js +20 -1
  16. package/dest/block/test/l2_tips_store_test_suite.d.ts.map +1 -1
  17. package/dest/block/test/l2_tips_store_test_suite.js +2 -1
  18. package/dest/block/validate_block_result.d.ts +222 -0
  19. package/dest/block/validate_block_result.d.ts.map +1 -0
  20. package/dest/block/validate_block_result.js +83 -0
  21. package/dest/interfaces/archiver.d.ts +43 -0
  22. package/dest/interfaces/archiver.d.ts.map +1 -1
  23. package/dest/interfaces/archiver.js +10 -1
  24. package/dest/interfaces/aztec-node-admin.d.ts +17 -3
  25. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  26. package/dest/interfaces/aztec-node-admin.js +6 -1
  27. package/dest/interfaces/aztec-node.d.ts +5 -2
  28. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  29. package/dest/interfaces/aztec-node.js +1 -0
  30. package/dest/interfaces/block-builder.d.ts +5 -6
  31. package/dest/interfaces/block-builder.d.ts.map +1 -1
  32. package/dest/interfaces/pxe.d.ts +8 -1
  33. package/dest/interfaces/pxe.d.ts.map +1 -1
  34. package/dest/interfaces/pxe.js +1 -0
  35. package/dest/messaging/inbox_leaf.d.ts +2 -0
  36. package/dest/messaging/inbox_leaf.d.ts.map +1 -1
  37. package/dest/messaging/inbox_leaf.js +3 -0
  38. package/dest/p2p/block_attestation.d.ts +1 -0
  39. package/dest/p2p/block_attestation.d.ts.map +1 -1
  40. package/dest/p2p/block_attestation.js +3 -0
  41. package/dest/p2p/block_proposal.d.ts +2 -2
  42. package/dest/p2p/block_proposal.d.ts.map +1 -1
  43. package/dest/p2p/block_proposal.js +3 -1
  44. package/dest/p2p/consensus_payload.d.ts +1 -0
  45. package/dest/p2p/consensus_payload.d.ts.map +1 -1
  46. package/dest/p2p/consensus_payload.js +6 -4
  47. package/dest/tests/mocks.d.ts +1 -1
  48. package/dest/tests/mocks.d.ts.map +1 -1
  49. package/dest/tests/mocks.js +5 -8
  50. package/dest/tx/content_commitment.d.ts +1 -0
  51. package/dest/tx/content_commitment.d.ts.map +1 -1
  52. package/dest/tx/content_commitment.js +3 -0
  53. package/dest/tx/partial_state_reference.d.ts +1 -0
  54. package/dest/tx/partial_state_reference.d.ts.map +1 -1
  55. package/dest/tx/partial_state_reference.js +3 -0
  56. package/dest/tx/proposed_block_header.d.ts +1 -0
  57. package/dest/tx/proposed_block_header.d.ts.map +1 -1
  58. package/dest/tx/proposed_block_header.js +3 -0
  59. package/dest/tx/state_reference.d.ts +1 -0
  60. package/dest/tx/state_reference.d.ts.map +1 -1
  61. package/dest/tx/state_reference.js +3 -0
  62. package/dest/update-checker/update-checker.d.ts +1 -1
  63. package/dest/update-checker/update-checker.d.ts.map +1 -1
  64. package/dest/update-checker/update-checker.js +1 -1
  65. package/dest/zkpassport/index.d.ts +3 -3
  66. package/dest/zkpassport/index.d.ts.map +1 -1
  67. package/dest/zkpassport/index.js +7 -7
  68. package/package.json +8 -8
  69. package/src/block/index.ts +2 -0
  70. package/src/block/l2_block.ts +6 -11
  71. package/src/block/l2_block_info.ts +63 -0
  72. package/src/block/l2_block_source.ts +1 -51
  73. package/src/block/published_l2_block.ts +38 -5
  74. package/src/block/test/l2_tips_store_test_suite.ts +7 -6
  75. package/src/block/validate_block_result.ts +122 -0
  76. package/src/interfaces/archiver.ts +38 -1
  77. package/src/interfaces/aztec-node-admin.ts +12 -1
  78. package/src/interfaces/aztec-node.ts +8 -2
  79. package/src/interfaces/block-builder.ts +9 -6
  80. package/src/interfaces/pxe.ts +10 -1
  81. package/src/messaging/inbox_leaf.ts +5 -0
  82. package/src/p2p/block_attestation.ts +4 -0
  83. package/src/p2p/block_proposal.ts +5 -3
  84. package/src/p2p/consensus_payload.ts +7 -4
  85. package/src/tests/mocks.ts +5 -5
  86. package/src/tx/content_commitment.ts +4 -0
  87. package/src/tx/partial_state_reference.ts +8 -0
  88. package/src/tx/proposed_block_header.ts +13 -0
  89. package/src/tx/state_reference.ts +4 -0
  90. package/src/update-checker/update-checker.ts +1 -1
  91. package/src/zkpassport/index.ts +6 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/stdlib",
3
- "version": "2.0.0-rc.8",
3
+ "version": "2.0.2-rc.1",
4
4
  "type": "module",
5
5
  "inherits": [
6
6
  "../package.common.json",
@@ -69,13 +69,13 @@
69
69
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
70
70
  },
71
71
  "dependencies": {
72
- "@aztec/bb.js": "2.0.0-rc.8",
73
- "@aztec/blob-lib": "2.0.0-rc.8",
74
- "@aztec/constants": "2.0.0-rc.8",
75
- "@aztec/ethereum": "2.0.0-rc.8",
76
- "@aztec/foundation": "2.0.0-rc.8",
77
- "@aztec/l1-artifacts": "2.0.0-rc.8",
78
- "@aztec/noir-noirc_abi": "2.0.0-rc.8",
72
+ "@aztec/bb.js": "2.0.2-rc.1",
73
+ "@aztec/blob-lib": "2.0.2-rc.1",
74
+ "@aztec/constants": "2.0.2-rc.1",
75
+ "@aztec/ethereum": "2.0.2-rc.1",
76
+ "@aztec/foundation": "2.0.2-rc.1",
77
+ "@aztec/l1-artifacts": "2.0.2-rc.1",
78
+ "@aztec/noir-noirc_abi": "2.0.2-rc.1",
79
79
  "@google-cloud/storage": "^7.15.0",
80
80
  "axios": "^1.9.0",
81
81
  "json-stringify-deterministic": "1.0.12",
@@ -7,3 +7,5 @@ export * from './l2_block_source.js';
7
7
  export * from './block_hash.js';
8
8
  export * from './published_l2_block.js';
9
9
  export * from './proposal/index.js';
10
+ export * from './validate_block_result.js';
11
+ export * from './l2_block_info.js';
@@ -8,6 +8,7 @@ import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
8
8
  import { BlockHeader } from '../tx/block_header.js';
9
9
  import { Body } from './body.js';
10
10
  import { makeAppendOnlyTreeSnapshot, makeHeader } from './l2_block_code_to_purge.js';
11
+ import type { L2BlockInfo } from './l2_block_info.js';
11
12
 
12
13
  /**
13
14
  * The data that makes up the rollup proof, with encoder decoder functions.
@@ -156,13 +157,15 @@ export class L2Block {
156
157
  };
157
158
  }
158
159
 
159
- toBlockInfo(): BlockInfo {
160
+ toBlockInfo(): L2BlockInfo {
160
161
  return {
161
- blockHash: this.blockHash?.toString(),
162
- archive: this.archive.root.toString(),
162
+ blockHash: this.blockHash,
163
+ archive: this.archive.root,
164
+ lastArchive: this.header.lastArchive.root,
163
165
  blockNumber: this.number,
164
166
  slotNumber: Number(this.header.getSlot()),
165
167
  txCount: this.body.txEffects.length,
168
+ timestamp: this.header.globalVariables.timestamp,
166
169
  };
167
170
  }
168
171
 
@@ -170,11 +173,3 @@ export class L2Block {
170
173
  return this.archive.equals(other.archive) && this.header.equals(other.header) && this.body.equals(other.body);
171
174
  }
172
175
  }
173
-
174
- export type BlockInfo = {
175
- blockHash?: string;
176
- archive: string;
177
- blockNumber: number;
178
- slotNumber: number;
179
- txCount: number;
180
- };
@@ -0,0 +1,63 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import { schemas } from '@aztec/foundation/schemas';
3
+ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
4
+
5
+ import { z } from 'zod';
6
+
7
+ export type L2BlockInfo = {
8
+ blockHash?: Fr;
9
+ archive: Fr;
10
+ lastArchive: Fr;
11
+ blockNumber: number;
12
+ slotNumber: number;
13
+ txCount: number;
14
+ timestamp: bigint;
15
+ };
16
+
17
+ export function randomBlockInfo(blockNumber?: number): L2BlockInfo {
18
+ return {
19
+ blockHash: Fr.random(),
20
+ archive: Fr.random(),
21
+ lastArchive: Fr.random(),
22
+ blockNumber: blockNumber ?? Math.floor(Math.random() * 100000) + 1,
23
+ slotNumber: Math.floor(Math.random() * 100000) + 1,
24
+ txCount: Math.floor(Math.random() * 100),
25
+ timestamp: BigInt(Math.floor(Date.now() / 1000)),
26
+ };
27
+ }
28
+
29
+ export const BlockInfoSchema = z.object({
30
+ blockHash: schemas.Fr.optional(),
31
+ archive: schemas.Fr,
32
+ lastArchive: schemas.Fr,
33
+ blockNumber: z.number(),
34
+ slotNumber: z.number(),
35
+ txCount: z.number(),
36
+ timestamp: schemas.BigInt,
37
+ });
38
+
39
+ export function serializeBlockInfo(blockInfo: L2BlockInfo): Buffer {
40
+ return serializeToBuffer(
41
+ blockInfo.blockHash ?? Fr.ZERO,
42
+ blockInfo.archive,
43
+ blockInfo.lastArchive,
44
+ blockInfo.blockNumber,
45
+ blockInfo.slotNumber,
46
+ blockInfo.txCount,
47
+ blockInfo.timestamp,
48
+ );
49
+ }
50
+
51
+ export function deserializeBlockInfo(buffer: Buffer | BufferReader): L2BlockInfo {
52
+ const reader = BufferReader.asReader(buffer);
53
+ const blockHash = reader.readObject(Fr);
54
+ return {
55
+ blockHash: blockHash.equals(Fr.ZERO) ? undefined : blockHash,
56
+ archive: reader.readObject(Fr),
57
+ lastArchive: reader.readObject(Fr),
58
+ blockNumber: reader.readNumber(),
59
+ slotNumber: reader.readNumber(),
60
+ txCount: reader.readNumber(),
61
+ timestamp: reader.readBigInt(),
62
+ };
63
+ }
@@ -1,17 +1,16 @@
1
1
  import type { EthAddress } from '@aztec/foundation/eth-address';
2
- import { type ZodFor, schemas } from '@aztec/foundation/schemas';
3
2
  import type { TypedEventEmitter } from '@aztec/foundation/types';
4
3
 
5
4
  import { z } from 'zod';
6
5
 
7
6
  import type { L1RollupConstants } from '../epoch-helpers/index.js';
8
- import { BlockAttestation } from '../p2p/block_attestation.js';
9
7
  import type { BlockHeader } from '../tx/block_header.js';
10
8
  import type { IndexedTxEffect } from '../tx/indexed_tx_effect.js';
11
9
  import type { TxHash } from '../tx/tx_hash.js';
12
10
  import type { TxReceipt } from '../tx/tx_receipt.js';
13
11
  import type { L2Block } from './l2_block.js';
14
12
  import { PublishedL2Block } from './published_l2_block.js';
13
+ import type { ValidateBlockNegativeResult, ValidateBlockResult } from './validate_block_result.js';
15
14
 
16
15
  /**
17
16
  * Interface of classes allowing for the retrieval of L2 blocks.
@@ -140,59 +139,10 @@ export interface L2BlockSource {
140
139
  syncImmediate(): Promise<void>;
141
140
  }
142
141
 
143
- /** Subtype for invalid block validation results */
144
- export type ValidateBlockNegativeResult =
145
- | {
146
- valid: false;
147
- block: PublishedL2Block;
148
- committee: EthAddress[];
149
- epoch: bigint;
150
- seed: bigint;
151
- attestations: BlockAttestation[];
152
- reason: 'insufficient-attestations';
153
- }
154
- | {
155
- valid: false;
156
- block: PublishedL2Block;
157
- committee: EthAddress[];
158
- epoch: bigint;
159
- seed: bigint;
160
- reason: 'invalid-attestation';
161
- attestations: BlockAttestation[];
162
- invalidIndex: number;
163
- };
164
-
165
- /** Result type for validating a block attestations */
166
- export type ValidateBlockResult = { valid: true } | ValidateBlockNegativeResult;
167
-
168
- export const ValidateBlockResultSchema = z.union([
169
- z.object({ valid: z.literal(true), block: PublishedL2Block.schema.optional() }),
170
- z.object({
171
- valid: z.literal(false),
172
- block: PublishedL2Block.schema,
173
- committee: z.array(schemas.EthAddress),
174
- epoch: schemas.BigInt,
175
- seed: schemas.BigInt,
176
- attestations: z.array(BlockAttestation.schema),
177
- reason: z.literal('insufficient-attestations'),
178
- }),
179
- z.object({
180
- valid: z.literal(false),
181
- block: PublishedL2Block.schema,
182
- committee: z.array(schemas.EthAddress),
183
- epoch: schemas.BigInt,
184
- seed: schemas.BigInt,
185
- attestations: z.array(BlockAttestation.schema),
186
- reason: z.literal('invalid-attestation'),
187
- invalidIndex: z.number(),
188
- }),
189
- ]) satisfies ZodFor<ValidateBlockResult>;
190
-
191
142
  /**
192
143
  * L2BlockSource that emits events upon pending / proven chain changes.
193
144
  * see L2BlockSourceEvents for the events emitted.
194
145
  */
195
-
196
146
  export type ArchiverEmitter = TypedEventEmitter<{
197
147
  [L2BlockSourceEvents.L2PruneDetected]: (args: L2BlockPruneEvent) => void;
198
148
  [L2BlockSourceEvents.L2BlockProven]: (args: L2BlockProvenEvent) => void;
@@ -2,6 +2,8 @@
2
2
  import { Buffer32 } from '@aztec/foundation/buffer';
3
3
  import { randomBigInt } from '@aztec/foundation/crypto';
4
4
  import { schemas } from '@aztec/foundation/schemas';
5
+ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
6
+ import type { FieldsOf } from '@aztec/foundation/types';
5
7
 
6
8
  import { z } from 'zod';
7
9
 
@@ -32,6 +34,10 @@ export class L1PublishedData {
32
34
  Buffer32.random().toString(),
33
35
  );
34
36
  }
37
+
38
+ static fromFields(fields: FieldsOf<L1PublishedData>) {
39
+ return new L1PublishedData(fields.blockNumber, fields.timestamp, fields.blockHash);
40
+ }
35
41
  }
36
42
 
37
43
  export class PublishedL2Block {
@@ -42,11 +48,38 @@ export class PublishedL2Block {
42
48
  ) {}
43
49
 
44
50
  static get schema() {
45
- return z.object({
46
- block: L2Block.schema,
47
- l1: L1PublishedData.schema,
48
- attestations: z.array(CommitteeAttestation.schema),
49
- });
51
+ return z
52
+ .object({
53
+ block: L2Block.schema,
54
+ l1: L1PublishedData.schema,
55
+ attestations: z.array(CommitteeAttestation.schema),
56
+ })
57
+ .transform(obj => PublishedL2Block.fromFields(obj));
58
+ }
59
+
60
+ static fromBuffer(bufferOrReader: Buffer | BufferReader): PublishedL2Block {
61
+ const reader = BufferReader.asReader(bufferOrReader);
62
+ const block = reader.readObject(L2Block);
63
+ const l1BlockNumber = reader.readBigInt();
64
+ const l1BlockHash = reader.readString();
65
+ const l1Timestamp = reader.readBigInt();
66
+ const attestations = reader.readVector(CommitteeAttestation);
67
+ return new PublishedL2Block(block, new L1PublishedData(l1BlockNumber, l1Timestamp, l1BlockHash), attestations);
68
+ }
69
+
70
+ static fromFields(fields: FieldsOf<PublishedL2Block>) {
71
+ return new PublishedL2Block(fields.block, fields.l1, fields.attestations);
72
+ }
73
+
74
+ public toBuffer(): Buffer {
75
+ return serializeToBuffer(
76
+ this.block,
77
+ this.l1.blockNumber,
78
+ this.l1.blockHash,
79
+ this.l1.timestamp,
80
+ this.attestations.length,
81
+ this.attestations,
82
+ );
50
83
  }
51
84
  }
52
85
 
@@ -1,6 +1,6 @@
1
1
  import { times } from '@aztec/foundation/collection';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
- import type { L2Block, L2BlockId, PublishedL2Block } from '@aztec/stdlib/block';
3
+ import { type L2Block, type L2BlockId, PublishedL2Block } from '@aztec/stdlib/block';
4
4
  import type { BlockHeader } from '@aztec/stdlib/tx';
5
5
 
6
6
  import { jestExpect as expect } from '@jest/expect';
@@ -14,11 +14,12 @@ export function testL2TipsStore(makeTipsStore: () => Promise<L2TipsStore>) {
14
14
  tipsStore = await makeTipsStore();
15
15
  });
16
16
 
17
- const makeBlock = (number: number): PublishedL2Block => ({
18
- block: { number, header: { hash: () => Promise.resolve(new Fr(number)) } as BlockHeader } as L2Block,
19
- l1: { blockNumber: BigInt(number), blockHash: `0x${number}`, timestamp: BigInt(number) },
20
- attestations: [],
21
- });
17
+ const makeBlock = (number: number): PublishedL2Block =>
18
+ PublishedL2Block.fromFields({
19
+ block: { number, header: { hash: () => Promise.resolve(new Fr(number)) } as BlockHeader } as L2Block,
20
+ l1: { blockNumber: BigInt(number), blockHash: `0x${number}`, timestamp: BigInt(number) },
21
+ attestations: [],
22
+ });
22
23
 
23
24
  const makeBlockId = (number: number): L2BlockId => ({
24
25
  number,
@@ -0,0 +1,122 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { type ZodFor, schemas } from '@aztec/foundation/schemas';
3
+ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
4
+
5
+ import { z } from 'zod';
6
+
7
+ import { BlockInfoSchema, type L2BlockInfo, deserializeBlockInfo, serializeBlockInfo } from './l2_block_info.js';
8
+ import { CommitteeAttestation } from './proposal/committee_attestation.js';
9
+
10
+ /** Subtype for invalid block validation results */
11
+ export type ValidateBlockNegativeResult =
12
+ | {
13
+ valid: false;
14
+ /** Identifiers from the invalid block */
15
+ block: L2BlockInfo;
16
+ /** Committee members at the epoch this block was proposed */
17
+ committee: EthAddress[];
18
+ /** Epoch in which this block was proposed */
19
+ epoch: bigint;
20
+ /** Proposer selection seed for the epoch */
21
+ seed: bigint;
22
+ /** List of committee members who signed this block proposal */
23
+ attestors: EthAddress[];
24
+ /** Committee attestations for this block as they were posted to L1 */
25
+ attestations: CommitteeAttestation[];
26
+ /** Reason for the block being invalid: not enough attestations were posted */
27
+ reason: 'insufficient-attestations';
28
+ }
29
+ | {
30
+ valid: false;
31
+ /** Identifiers from the invalid block */
32
+ block: L2BlockInfo;
33
+ /** Committee members at the epoch this block was proposed */
34
+ committee: EthAddress[];
35
+ /** Epoch in which this block was proposed */
36
+ epoch: bigint;
37
+ /** Proposer selection seed for the epoch */
38
+ seed: bigint;
39
+ /** List of committee members who signed this block proposal */
40
+ attestors: EthAddress[];
41
+ /** Committee attestations for this block as they were posted to L1 */
42
+ attestations: CommitteeAttestation[];
43
+ /** Reason for the block being invalid: an invalid attestation was posted */
44
+ reason: 'invalid-attestation';
45
+ /** Index in the attestations array of the invalid attestation posted */
46
+ invalidIndex: number;
47
+ };
48
+
49
+ /** Result type for validating a block attestations */
50
+ export type ValidateBlockResult = { valid: true } | ValidateBlockNegativeResult;
51
+
52
+ export const ValidateBlockResultSchema = z.union([
53
+ z.object({ valid: z.literal(true) }),
54
+ z.object({
55
+ valid: z.literal(false),
56
+ block: BlockInfoSchema,
57
+ committee: z.array(schemas.EthAddress),
58
+ epoch: schemas.BigInt,
59
+ seed: schemas.BigInt,
60
+ attestors: z.array(schemas.EthAddress),
61
+ attestations: z.array(CommitteeAttestation.schema),
62
+ reason: z.literal('insufficient-attestations'),
63
+ }),
64
+ z.object({
65
+ valid: z.literal(false),
66
+ block: BlockInfoSchema,
67
+ committee: z.array(schemas.EthAddress),
68
+ epoch: schemas.BigInt,
69
+ seed: schemas.BigInt,
70
+ attestors: z.array(schemas.EthAddress),
71
+ attestations: z.array(CommitteeAttestation.schema),
72
+ reason: z.literal('invalid-attestation'),
73
+ invalidIndex: z.number(),
74
+ }),
75
+ ]) satisfies ZodFor<ValidateBlockResult>;
76
+
77
+ export function serializeValidateBlockResult(result: ValidateBlockResult): Buffer {
78
+ if (result.valid) {
79
+ return serializeToBuffer(true);
80
+ }
81
+
82
+ const l2Block = serializeBlockInfo(result.block);
83
+ return serializeToBuffer(
84
+ result.valid,
85
+ result.reason,
86
+ l2Block.length,
87
+ l2Block,
88
+ result.committee.length,
89
+ result.committee,
90
+ result.epoch,
91
+ result.seed ?? 0n,
92
+ result.attestors.length,
93
+ result.attestors,
94
+ result.attestations.length,
95
+ result.attestations,
96
+ result.reason === 'invalid-attestation' ? result.invalidIndex : 0,
97
+ );
98
+ }
99
+
100
+ export function deserializeValidateBlockResult(bufferOrReader: Buffer | BufferReader): ValidateBlockResult {
101
+ const reader = BufferReader.asReader(bufferOrReader);
102
+ const valid = reader.readBoolean();
103
+ if (valid) {
104
+ return { valid };
105
+ }
106
+ const reason = reader.readString() as 'insufficient-attestations' | 'invalid-attestation';
107
+ const block = deserializeBlockInfo(reader.readBuffer());
108
+ const committee = reader.readVector(EthAddress);
109
+ const epoch = reader.readBigInt();
110
+ const seed = reader.readBigInt();
111
+ const attestors = reader.readVector(EthAddress);
112
+ const attestations = reader.readVector(CommitteeAttestation);
113
+ const invalidIndex = reader.readNumber();
114
+ if (reason === 'insufficient-attestations') {
115
+ return { valid, reason, block, committee, epoch, seed, attestors, attestations: attestations };
116
+ } else if (reason === 'invalid-attestation') {
117
+ return { valid, reason, block, committee, epoch, seed, attestors, invalidIndex, attestations: attestations };
118
+ } else {
119
+ const _: never = reason;
120
+ throw new Error(`Unknown reason: ${reason}`);
121
+ }
122
+ }
@@ -1,10 +1,12 @@
1
+ import type { L1ContractAddresses } from '@aztec/ethereum';
1
2
  import type { ApiSchemaFor } from '@aztec/foundation/schemas';
2
3
 
3
4
  import { z } from 'zod';
4
5
 
5
6
  import { L2Block } from '../block/l2_block.js';
6
- import { type L2BlockSource, L2TipsSchema, ValidateBlockResultSchema } from '../block/l2_block_source.js';
7
+ import { type L2BlockSource, L2TipsSchema } from '../block/l2_block_source.js';
7
8
  import { PublishedL2Block } from '../block/published_l2_block.js';
9
+ import { ValidateBlockResultSchema } from '../block/validate_block_result.js';
8
10
  import {
9
11
  ContractClassPublicSchema,
10
12
  type ContractDataSource,
@@ -23,6 +25,41 @@ import { TxReceipt } from '../tx/tx_receipt.js';
23
25
  import { GetContractClassLogsResponseSchema, GetPublicLogsResponseSchema } from './get_logs_response.js';
24
26
  import type { L2LogsSource } from './l2_logs_source.js';
25
27
 
28
+ /**
29
+ * The archiver configuration.
30
+ */
31
+ export type ArchiverSpecificConfig = {
32
+ /** The polling interval in ms for retrieving new L2 blocks and encrypted logs. */
33
+ archiverPollingIntervalMS?: number;
34
+
35
+ /** The number of L2 blocks the archiver will attempt to download at a time. */
36
+ archiverBatchSize?: number;
37
+
38
+ /** The polling interval viem uses in ms */
39
+ viemPollingIntervalMS?: number;
40
+
41
+ /** The deployed L1 contract addresses */
42
+ l1Contracts: L1ContractAddresses;
43
+
44
+ /** The max number of logs that can be obtained in 1 "getPublicLogs" call. */
45
+ maxLogs?: number;
46
+
47
+ /** The maximum possible size of the archiver DB in KB. Overwrites the general dataStoreMapSizeKB. */
48
+ archiverStoreMapSizeKb?: number;
49
+
50
+ /** Whether to skip validating block attestations (use only for testing). */
51
+ skipValidateBlockAttestations?: boolean;
52
+ };
53
+
54
+ export const ArchiverSpecificConfigSchema = z.object({
55
+ archiverPollingIntervalMS: schemas.Integer.optional(),
56
+ archiverBatchSize: schemas.Integer.optional(),
57
+ viemPollingIntervalMS: schemas.Integer.optional(),
58
+ maxLogs: schemas.Integer.optional(),
59
+ archiverStoreMapSizeKb: schemas.Integer.optional(),
60
+ skipValidateBlockAttestations: z.boolean().optional(),
61
+ });
62
+
26
63
  export type ArchiverApi = Omit<
27
64
  L2BlockSource & L2LogsSource & ContractDataSource & L1ToL2MessageSource,
28
65
  'start' | 'stop'
@@ -5,6 +5,7 @@ import { z } from 'zod';
5
5
  import type { ApiSchemaFor } from '../schemas/schemas.js';
6
6
  import { type Offense, OffenseSchema, type SlashPayloadRound, SlashPayloadRoundSchema } from '../slashing/index.js';
7
7
  import { type ComponentsVersions, getVersioningResponseHandler } from '../versioning/index.js';
8
+ import { type ArchiverSpecificConfig, ArchiverSpecificConfigSchema } from './archiver.js';
8
9
  import { type SequencerConfig, SequencerConfigSchema } from './configs.js';
9
10
  import { type ProverConfig, ProverConfigSchema } from './prover-client.js';
10
11
  import { type SlasherConfig, SlasherConfigSchema } from './slasher.js';
@@ -54,11 +55,21 @@ export interface AztecNodeAdmin {
54
55
  export type AztecNodeAdminConfig = ValidatorClientFullConfig &
55
56
  SequencerConfig &
56
57
  ProverConfig &
57
- SlasherConfig & { maxTxPoolSize: number };
58
+ SlasherConfig &
59
+ Pick<ArchiverSpecificConfig, 'archiverPollingIntervalMS' | 'skipValidateBlockAttestations' | 'archiverBatchSize'> & {
60
+ maxTxPoolSize: number;
61
+ };
58
62
 
59
63
  export const AztecNodeAdminConfigSchema = SequencerConfigSchema.merge(ProverConfigSchema)
60
64
  .merge(SlasherConfigSchema)
61
65
  .merge(ValidatorClientConfigSchema)
66
+ .merge(
67
+ ArchiverSpecificConfigSchema.pick({
68
+ archiverPollingIntervalMS: true,
69
+ skipValidateBlockAttestations: true,
70
+ archiverBatchSize: true,
71
+ }),
72
+ )
62
73
  .merge(z.object({ maxTxPoolSize: z.number() }));
63
74
 
64
75
  export const AztecNodeAdminApiSchema: ApiSchemaFor<AztecNodeAdmin> = {
@@ -199,10 +199,14 @@ export interface AztecNode
199
199
  l1ToL2Message: Fr,
200
200
  ): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined>;
201
201
 
202
+ /** Returns the L2 block number in which this L1 to L2 message becomes available, or undefined if not found. */
203
+ getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<number | undefined>;
204
+
202
205
  /**
203
- * Returns whether an L1 to L2 message is synced by archiver and if it's ready to be included in a block.
206
+ * Returns whether an L1 to L2 message is synced by archiver.
204
207
  * @param l1ToL2Message - The L1 to L2 message to check.
205
- * @returns Whether the message is synced and ready to be included in a block.
208
+ * @returns Whether the message is synced.
209
+ * @deprecated Use `getL1ToL2MessageBlock` instead. This method may return true even if the message is not ready to use.
206
210
  */
207
211
  isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean>;
208
212
 
@@ -501,6 +505,8 @@ export const AztecNodeApiSchema: ApiSchemaFor<AztecNode> = {
501
505
  .args(L2BlockNumberSchema, schemas.Fr)
502
506
  .returns(z.tuple([schemas.BigInt, SiblingPath.schemaFor(L1_TO_L2_MSG_TREE_HEIGHT)]).optional()),
503
507
 
508
+ getL1ToL2MessageBlock: z.function().args(schemas.Fr).returns(z.number().optional()),
509
+
504
510
  isL1ToL2MessageSynced: z.function().args(schemas.Fr).returns(z.boolean()),
505
511
 
506
512
  getL2ToL1Messages: z
@@ -2,6 +2,8 @@ import type { Fr } from '@aztec/foundation/fields';
2
2
  import type { Timer } from '@aztec/foundation/timer';
3
3
 
4
4
  import type { L2Block } from '../block/l2_block.js';
5
+ import type { ChainConfig, SequencerConfig } from '../config/chain-config.js';
6
+ import type { L1RollupConstants } from '../epoch-helpers/index.js';
5
7
  import type { Gas } from '../gas/gas.js';
6
8
  import type { MerkleTreeWriteOperations } from '../trees/index.js';
7
9
  import type { BlockHeader } from '../tx/block_header.js';
@@ -59,13 +61,14 @@ export interface BuildBlockResult {
59
61
  usedTxs: Tx[];
60
62
  }
61
63
 
64
+ export type FullNodeBlockBuilderConfig = Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'> &
65
+ Pick<ChainConfig, 'l1ChainId' | 'rollupVersion'> &
66
+ Pick<SequencerConfig, 'txPublicSetupAllowList' | 'fakeProcessingDelayPerTxMs'>;
67
+
62
68
  export interface IFullNodeBlockBuilder {
63
- getConfig(): {
64
- l1GenesisTime: bigint;
65
- slotDuration: number;
66
- l1ChainId: number;
67
- rollupVersion: number;
68
- };
69
+ getConfig(): FullNodeBlockBuilderConfig;
70
+
71
+ updateConfig(config: Partial<FullNodeBlockBuilderConfig>): void;
69
72
 
70
73
  buildBlock(
71
74
  txs: Iterable<Tx> | AsyncIterable<Tx>,
@@ -56,12 +56,20 @@ import {
56
56
  */
57
57
  export interface PXE {
58
58
  /**
59
- * Returns whether an L1 to L2 message is synced by archiver and if it's ready to be included in a block.
59
+ * Returns whether an L1 to L2 message is synced by archiver.
60
60
  * @param l1ToL2Message - The L1 to L2 message to check.
61
61
  * @returns Whether the message is synced and ready to be included in a block.
62
+ * @deprecated Use `waitForL1ToL2MessageReady` and `isL1ToL2MessageReady` instead.
62
63
  */
63
64
  isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean>;
64
65
 
66
+ /**
67
+ * Returns the L2 block number in which this L1 to L2 message becomes available, or undefined if not found.
68
+ * @param l1ToL2Message - The L1 to L2 message to check.
69
+ * @returns The L2 block number or undefined if not synced yet.
70
+ */
71
+ getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<number | undefined>;
72
+
65
73
  /**
66
74
  * Registers a user account in PXE given its master encryption private key.
67
75
  * Once a new account is registered, the PXE Service will trial-decrypt all published notes on
@@ -447,6 +455,7 @@ const PXEInfoSchema = z.object({
447
455
 
448
456
  export const PXESchema: ApiSchemaFor<PXE> = {
449
457
  isL1ToL2MessageSynced: z.function().args(schemas.Fr).returns(z.boolean()),
458
+ getL1ToL2MessageBlock: z.function().args(schemas.Fr).returns(z.number().optional()),
450
459
  registerAccount: z.function().args(schemas.Fr, schemas.Fr).returns(CompleteAddress.schema),
451
460
  getRegisteredAccounts: z.function().returns(z.array(CompleteAddress.schema)),
452
461
  registerSender: z.function().args(schemas.AztecAddress).returns(schemas.AztecAddress),
@@ -35,4 +35,9 @@ export class InboxLeaf {
35
35
  const end = start + BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
36
36
  return [start, end];
37
37
  }
38
+
39
+ /** Returns the L2 block number for a given leaf index */
40
+ static l2BlockFromIndex(index: bigint): number {
41
+ return Number(index / BigInt(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP)) + INITIAL_L2_BLOCK_NUM;
42
+ }
38
43
  }
@@ -98,6 +98,10 @@ export class BlockAttestation extends Gossipable {
98
98
  return new BlockAttestation(0, ConsensusPayload.empty(), Signature.empty());
99
99
  }
100
100
 
101
+ static random(): BlockAttestation {
102
+ return new BlockAttestation(Math.floor(Math.random() * 1000) + 1, ConsensusPayload.random(), Signature.random());
103
+ }
104
+
101
105
  getSize(): number {
102
106
  return 4 /* blockNumber */ + this.payload.getSize() + this.signature.getSize();
103
107
  }
@@ -5,7 +5,7 @@ import { Signature } from '@aztec/foundation/eth-signature';
5
5
  import { Fr } from '@aztec/foundation/fields';
6
6
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
7
7
 
8
- import type { BlockInfo } from '../block/l2_block.js';
8
+ import type { L2BlockInfo } from '../block/l2_block_info.js';
9
9
  import { TxHash } from '../tx/index.js';
10
10
  import { Tx } from '../tx/tx.js';
11
11
  import type { UInt32 } from '../types/index.js';
@@ -71,11 +71,13 @@ export class BlockProposal extends Gossipable {
71
71
  return this.payload.header.slotNumber;
72
72
  }
73
73
 
74
- toBlockInfo(): BlockInfo {
74
+ toBlockInfo(): L2BlockInfo {
75
75
  return {
76
76
  blockNumber: this.blockNumber,
77
77
  slotNumber: this.slotNumber.toNumber(),
78
- archive: this.archive.toString(),
78
+ lastArchive: this.payload.header.lastArchiveRoot,
79
+ timestamp: this.payload.header.timestamp,
80
+ archive: this.archive,
79
81
  txCount: this.txHashes.length,
80
82
  };
81
83
  }