@aztec/stdlib 3.0.0-nightly.20250919 → 3.0.0-nightly.20250921

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 (36) hide show
  1. package/dest/avm/avm.d.ts +8 -16
  2. package/dest/avm/avm.d.ts.map +1 -1
  3. package/dest/avm/avm_accumulated_data.d.ts +9 -21
  4. package/dest/avm/avm_accumulated_data.d.ts.map +1 -1
  5. package/dest/avm/avm_accumulated_data.js +15 -22
  6. package/dest/avm/avm_circuit_public_inputs.d.ts +6 -12
  7. package/dest/avm/avm_circuit_public_inputs.d.ts.map +1 -1
  8. package/dest/avm/avm_proving_request.d.ts +9 -18
  9. package/dest/avm/avm_proving_request.d.ts.map +1 -1
  10. package/dest/interfaces/epoch-prover.d.ts +3 -3
  11. package/dest/interfaces/epoch-prover.d.ts.map +1 -1
  12. package/dest/interfaces/proving-job.d.ts +9 -18
  13. package/dest/interfaces/proving-job.d.ts.map +1 -1
  14. package/dest/interfaces/pxe.d.ts +2 -29
  15. package/dest/interfaces/pxe.d.ts.map +1 -1
  16. package/dest/interfaces/pxe.js +2 -7
  17. package/dest/logs/log_with_tx_data.d.ts +9 -12
  18. package/dest/logs/log_with_tx_data.d.ts.map +1 -1
  19. package/dest/logs/log_with_tx_data.js +18 -23
  20. package/dest/logs/public_log.d.ts +23 -10
  21. package/dest/logs/public_log.d.ts.map +1 -1
  22. package/dest/logs/public_log.js +117 -42
  23. package/dest/tests/factories.d.ts.map +1 -1
  24. package/dest/tests/factories.js +5 -5
  25. package/dest/tx/processed_tx.js +1 -1
  26. package/dest/tx/tx_effect.d.ts.map +1 -1
  27. package/dest/tx/tx_effect.js +9 -10
  28. package/package.json +8 -8
  29. package/src/avm/avm_accumulated_data.ts +15 -29
  30. package/src/interfaces/epoch-prover.ts +2 -2
  31. package/src/interfaces/pxe.ts +1 -46
  32. package/src/logs/log_with_tx_data.ts +14 -24
  33. package/src/logs/public_log.ts +120 -58
  34. package/src/tests/factories.ts +4 -7
  35. package/src/tx/processed_tx.ts +1 -1
  36. package/src/tx/tx_effect.ts +9 -8
@@ -3,7 +3,6 @@ import {
3
3
  MAX_L2_TO_L1_MSGS_PER_TX,
4
4
  MAX_NOTE_HASHES_PER_TX,
5
5
  MAX_NULLIFIERS_PER_TX,
6
- MAX_PUBLIC_LOGS_PER_TX,
7
6
  MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
8
7
  } from '@aztec/constants';
9
8
  import { type FieldsOf, makeTuple } from '@aztec/foundation/array';
@@ -23,7 +22,7 @@ import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
23
22
  import { inspect } from 'util';
24
23
  import { z } from 'zod';
25
24
 
26
- import { PublicLog } from '../logs/public_log.js';
25
+ import { FlatPublicLogs } from '../logs/public_log.js';
27
26
  import { ScopedL2ToL1Message } from '../messaging/l2_to_l1_message.js';
28
27
  import { PublicDataWrite } from './public_data_write.js';
29
28
 
@@ -44,7 +43,7 @@ export class AvmAccumulatedData {
44
43
  /**
45
44
  * The public logs emitted from the AVM execution.
46
45
  */
47
- public publicLogs: Tuple<PublicLog, typeof MAX_PUBLIC_LOGS_PER_TX>,
46
+ public publicLogs: FlatPublicLogs,
48
47
  /**
49
48
  * The public data writes made in the AVM execution.
50
49
  */
@@ -57,7 +56,7 @@ export class AvmAccumulatedData {
57
56
  noteHashes: schemas.Fr.array().min(MAX_NOTE_HASHES_PER_TX).max(MAX_NOTE_HASHES_PER_TX),
58
57
  nullifiers: schemas.Fr.array().min(MAX_NULLIFIERS_PER_TX).max(MAX_NULLIFIERS_PER_TX),
59
58
  l2ToL1Msgs: ScopedL2ToL1Message.schema.array().min(MAX_L2_TO_L1_MSGS_PER_TX).max(MAX_L2_TO_L1_MSGS_PER_TX),
60
- publicLogs: PublicLog.schema.array().min(MAX_PUBLIC_LOGS_PER_TX).max(MAX_PUBLIC_LOGS_PER_TX),
59
+ publicLogs: FlatPublicLogs.schema,
61
60
  publicDataWrites: PublicDataWrite.schema
62
61
  .array()
63
62
  .min(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX)
@@ -69,7 +68,7 @@ export class AvmAccumulatedData {
69
68
  assertLength(noteHashes, MAX_NOTE_HASHES_PER_TX),
70
69
  assertLength(nullifiers, MAX_NULLIFIERS_PER_TX),
71
70
  assertLength(l2ToL1Msgs, MAX_L2_TO_L1_MSGS_PER_TX),
72
- assertLength(publicLogs, MAX_PUBLIC_LOGS_PER_TX),
71
+ publicLogs,
73
72
  assertLength(publicDataWrites, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX),
74
73
  ),
75
74
  );
@@ -80,7 +79,7 @@ export class AvmAccumulatedData {
80
79
  arraySerializedSizeOfNonEmpty(this.noteHashes) +
81
80
  arraySerializedSizeOfNonEmpty(this.nullifiers) +
82
81
  arraySerializedSizeOfNonEmpty(this.l2ToL1Msgs) +
83
- arraySerializedSizeOfNonEmpty(this.publicLogs) +
82
+ this.publicLogs.toBuffer().length +
84
83
  arraySerializedSizeOfNonEmpty(this.publicDataWrites)
85
84
  );
86
85
  }
@@ -91,7 +90,7 @@ export class AvmAccumulatedData {
91
90
  reader.readArray(MAX_NOTE_HASHES_PER_TX, Fr),
92
91
  reader.readArray(MAX_NULLIFIERS_PER_TX, Fr),
93
92
  reader.readArray(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
94
- reader.readArray(MAX_PUBLIC_LOGS_PER_TX, PublicLog),
93
+ reader.readObject(FlatPublicLogs),
95
94
  reader.readArray(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite),
96
95
  );
97
96
  }
@@ -116,7 +115,7 @@ export class AvmAccumulatedData {
116
115
  reader.readFieldArray(MAX_NOTE_HASHES_PER_TX),
117
116
  reader.readFieldArray(MAX_NULLIFIERS_PER_TX),
118
117
  reader.readArray(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message),
119
- reader.readArray(MAX_PUBLIC_LOGS_PER_TX, PublicLog),
118
+ reader.readObject(FlatPublicLogs),
120
119
  reader.readArray(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite),
121
120
  );
122
121
  }
@@ -144,7 +143,7 @@ export class AvmAccumulatedData {
144
143
  makeTuple(MAX_NOTE_HASHES_PER_TX, Fr.zero),
145
144
  makeTuple(MAX_NULLIFIERS_PER_TX, Fr.zero),
146
145
  makeTuple(MAX_L2_TO_L1_MSGS_PER_TX, ScopedL2ToL1Message.empty),
147
- makeTuple(MAX_PUBLIC_LOGS_PER_TX, PublicLog.empty),
146
+ FlatPublicLogs.empty(),
148
147
  makeTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite.empty),
149
148
  );
150
149
  }
@@ -154,7 +153,7 @@ export class AvmAccumulatedData {
154
153
  this.noteHashes.every(x => x.isZero()) &&
155
154
  this.nullifiers.every(x => x.isZero()) &&
156
155
  this.l2ToL1Msgs.every(x => x.isEmpty()) &&
157
- this.publicLogs.every(x => x.isEmpty()) &&
156
+ this.publicLogs.isEmpty() &&
158
157
  this.publicDataWrites.every(x => x.isEmpty())
159
158
  );
160
159
  }
@@ -175,6 +174,7 @@ export class AvmAccumulatedData {
175
174
  .map(h => inspect(h))
176
175
  .join(', ')}],
177
176
  publicLogs: [${this.publicLogs
177
+ .toLogs()
178
178
  .filter(x => !x.isEmpty())
179
179
  .map(h => inspect(h))
180
180
  .join(', ')}],
@@ -203,10 +203,6 @@ export class AvmAccumulatedDataArrayLengths {
203
203
  * Number of L2 to L1 messages
204
204
  */
205
205
  public l2ToL1Msgs: number,
206
- /**
207
- * Number of public logs
208
- */
209
- public publicLogs: number,
210
206
  /**
211
207
  * Number of public data writes
212
208
  */
@@ -219,12 +215,11 @@ export class AvmAccumulatedDataArrayLengths {
219
215
  noteHashes: z.number(),
220
216
  nullifiers: z.number(),
221
217
  l2ToL1Msgs: z.number(),
222
- publicLogs: z.number(),
223
218
  publicDataWrites: z.number(),
224
219
  })
225
220
  .transform(
226
- ({ noteHashes, nullifiers, l2ToL1Msgs, publicLogs, publicDataWrites }) =>
227
- new AvmAccumulatedDataArrayLengths(noteHashes, nullifiers, l2ToL1Msgs, publicLogs, publicDataWrites),
221
+ ({ noteHashes, nullifiers, l2ToL1Msgs, publicDataWrites }) =>
222
+ new AvmAccumulatedDataArrayLengths(noteHashes, nullifiers, l2ToL1Msgs, publicDataWrites),
228
223
  );
229
224
  }
230
225
 
@@ -235,12 +230,11 @@ export class AvmAccumulatedDataArrayLengths {
235
230
  reader.readNumber(),
236
231
  reader.readNumber(),
237
232
  reader.readNumber(),
238
- reader.readNumber(),
239
233
  );
240
234
  }
241
235
 
242
236
  toBuffer() {
243
- return serializeToBuffer(this.noteHashes, this.nullifiers, this.l2ToL1Msgs, this.publicLogs, this.publicDataWrites);
237
+ return serializeToBuffer(this.noteHashes, this.nullifiers, this.l2ToL1Msgs, this.publicDataWrites);
244
238
  }
245
239
 
246
240
  static fromFields(fields: Fr[] | FieldReader) {
@@ -250,22 +244,15 @@ export class AvmAccumulatedDataArrayLengths {
250
244
  Number(reader.readField()),
251
245
  Number(reader.readField()),
252
246
  Number(reader.readField()),
253
- Number(reader.readField()),
254
247
  );
255
248
  }
256
249
 
257
250
  toFields(): Fr[] {
258
- return [
259
- new Fr(this.noteHashes),
260
- new Fr(this.nullifiers),
261
- new Fr(this.l2ToL1Msgs),
262
- new Fr(this.publicLogs),
263
- new Fr(this.publicDataWrites),
264
- ];
251
+ return [new Fr(this.noteHashes), new Fr(this.nullifiers), new Fr(this.l2ToL1Msgs), new Fr(this.publicDataWrites)];
265
252
  }
266
253
 
267
254
  static empty() {
268
- return new AvmAccumulatedDataArrayLengths(0, 0, 0, 0, 0);
255
+ return new AvmAccumulatedDataArrayLengths(0, 0, 0, 0);
269
256
  }
270
257
 
271
258
  [inspect.custom]() {
@@ -273,7 +260,6 @@ export class AvmAccumulatedDataArrayLengths {
273
260
  noteHashes: ${this.noteHashes},
274
261
  nullifiers: ${this.nullifiers},
275
262
  l2ToL1Msgs: ${this.l2ToL1Msgs},
276
- publicLogs: ${this.publicLogs},
277
263
  publicDataWrites: ${this.publicDataWrites},
278
264
  }`;
279
265
  }
@@ -15,19 +15,18 @@ export interface EpochProver extends Omit<IBlockFactory, 'setBlockCompleted' | '
15
15
  /**
16
16
  * Starts a new epoch. Must be the first method to be called.
17
17
  * @param epochNumber - The epoch number.
18
- * @param firstCheckpointNumber - The number of the first checkpoint in the epoch. Used to determine the correct order when checkpoints are added.
19
18
  * @param totalNumCheckpoints - The total number of checkpoints expected in the epoch (must be at least one).
20
19
  * @param finalBlobBatchingChallenges - The final blob batching challenges for the epoch.
21
20
  **/
22
21
  startNewEpoch(
23
22
  epochNumber: number,
24
- firstCheckpointNumber: Fr,
25
23
  totalNumCheckpoints: number,
26
24
  finalBlobBatchingChallenges: FinalBlobBatchingChallenges,
27
25
  ): void;
28
26
 
29
27
  /**
30
28
  * Starts a new checkpoint.
29
+ * @param checkpointIndex - The index of the checkpoint in the epoch.
31
30
  * @param constants - The constants for this checkpoint.
32
31
  * @param l1ToL2Messages - The set of L1 to L2 messages to be included in this checkpoint.
33
32
  * @param totalNumBlocks - The total number of blocks expected in the checkpoint (must be at least one).
@@ -35,6 +34,7 @@ export interface EpochProver extends Omit<IBlockFactory, 'setBlockCompleted' | '
35
34
  * @param headerOfLastBlockInPreviousCheckpoint - The header of the last block in the previous checkpoint.
36
35
  */
37
36
  startNewCheckpoint(
37
+ checkpointIndex: number,
38
38
  constants: CheckpointConstantData,
39
39
  l1ToL2Messages: Fr[],
40
40
  totalNumBlocks: number,
@@ -13,25 +13,14 @@ import {
13
13
  ContractClassWithIdSchema,
14
14
  type ContractInstanceWithAddress,
15
15
  ContractInstanceWithAddressSchema,
16
- type NodeInfo,
17
- NodeInfoSchema,
18
16
  type PartialAddress,
19
17
  type ProtocolContractAddresses,
20
18
  ProtocolContractAddressesSchema,
21
19
  } from '../contract/index.js';
22
- import { GasFees } from '../gas/gas_fees.js';
23
20
  import { UniqueNote } from '../note/extended_note.js';
24
21
  import { type NotesFilter, NotesFilterSchema } from '../note/notes_filter.js';
25
22
  import { AbiDecodedSchema, optional, schemas } from '../schemas/schemas.js';
26
- import {
27
- PrivateExecutionResult,
28
- SimulationOverrides,
29
- Tx,
30
- TxExecutionRequest,
31
- TxHash,
32
- TxReceipt,
33
- TxSimulationResult,
34
- } from '../tx/index.js';
23
+ import { PrivateExecutionResult, SimulationOverrides, TxExecutionRequest, TxSimulationResult } from '../tx/index.js';
35
24
  import { TxProfileResult, UtilitySimulationResult } from '../tx/profiling.js';
36
25
  import { TxProvingResult } from '../tx/proven_tx.js';
37
26
 
@@ -176,23 +165,6 @@ export interface PXE {
176
165
  msgSender?: AztecAddress,
177
166
  ): Promise<TxProfileResult>;
178
167
 
179
- /**
180
- * Sends a transaction to an Aztec node to be broadcasted to the network and mined.
181
- * @param tx - The transaction as created via `proveTx`.
182
- * @returns A hash of the transaction, used to identify it.
183
- */
184
- sendTx(tx: Tx): Promise<TxHash>;
185
-
186
- /**
187
- * Fetches a transaction receipt for a given transaction hash. Returns a mined receipt if it was added
188
- * to the chain, a pending receipt if it's still in the mempool of the connected Aztec node, or a dropped
189
- * receipt if not found in the connected Aztec node.
190
- *
191
- * @param txHash - The transaction hash.
192
- * @returns A receipt of the transaction.
193
- */
194
- getTxReceipt(txHash: TxHash): Promise<TxReceipt>;
195
-
196
168
  /**
197
169
  * Gets notes registered in this PXE based on the provided filter.
198
170
  * @param filter - The filter to apply to the notes.
@@ -200,12 +172,6 @@ export interface PXE {
200
172
  */
201
173
  getNotes(filter: NotesFilter): Promise<UniqueNote[]>;
202
174
 
203
- /**
204
- * Method to fetch the current base fees.
205
- * @returns The current base fees.
206
- */
207
- getCurrentBaseFees(): Promise<GasFees>;
208
-
209
175
  /**
210
176
  * Simulate the execution of a contract utility function.
211
177
  *
@@ -227,13 +193,6 @@ export interface PXE {
227
193
  scopes?: AztecAddress[],
228
194
  ): Promise<UtilitySimulationResult>;
229
195
 
230
- /**
231
- * Returns the information about the server's node. Includes current Node version, compatible Noir version,
232
- * L1 chain identifier, rollup version, and L1 address of the rollup contract.
233
- * @returns - The node information.
234
- */
235
- getNodeInfo(): Promise<NodeInfo>;
236
-
237
196
  /**
238
197
  * Returns information about this PXE.
239
198
  */
@@ -379,10 +338,7 @@ export const PXESchema: ApiSchemaFor<PXE> = {
379
338
  optional(z.array(schemas.AztecAddress)),
380
339
  )
381
340
  .returns(TxSimulationResult.schema),
382
- sendTx: z.function().args(Tx.schema).returns(TxHash.schema),
383
- getTxReceipt: z.function().args(TxHash.schema).returns(TxReceipt.schema),
384
341
  getNotes: z.function().args(NotesFilterSchema).returns(z.array(UniqueNote.schema)),
385
- getCurrentBaseFees: z.function().returns(GasFees.schema),
386
342
 
387
343
  simulateUtility: z
388
344
  .function()
@@ -395,7 +351,6 @@ export const PXESchema: ApiSchemaFor<PXE> = {
395
351
  optional(z.array(schemas.AztecAddress)),
396
352
  )
397
353
  .returns(UtilitySimulationResult.schema),
398
- getNodeInfo: z.function().returns(NodeInfoSchema),
399
354
  getPXEInfo: z.function().returns(PXEInfoSchema),
400
355
  getContractMetadata: z.function().args(schemas.AztecAddress).returns(ContractMetadataSchema),
401
356
  getContractClassMetadata: z.function().args(schemas.Fr, optional(z.boolean())).returns(ContractClassMetadataSchema),
@@ -1,44 +1,34 @@
1
- import { MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_CIPHERTEXT_LEN, PUBLIC_LOG_PLAINTEXT_LEN } from '@aztec/constants';
1
+ import { MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_CIPHERTEXT_LEN } from '@aztec/constants';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
3
  import { TxHash } from '@aztec/stdlib/tx';
4
4
 
5
- // TypeScript representation of the Noir aztec::oracle::message_processing::LogWithTxData<N> struct. This is used as a
6
- // response for PXE's custom getPublicLogByTag and getPrivateLogByTag oracles.
7
- class LogWithTxData<N extends number> {
5
+ // This is used as a response for PXE's custom getPublicLogByTag oracle.
6
+ export class PublicLogWithTxData {
7
+ constructor(
8
+ public logPayload: Fr[],
9
+ public txHash: TxHash,
10
+ public uniqueNoteHashesInTx: Fr[],
11
+ public firstNullifierInTx: Fr,
12
+ ) {}
13
+ }
14
+
15
+ // This is used as a response for PXE's custom getPrivateLogByTag oracle.
16
+ export class PrivateLogWithTxData {
8
17
  constructor(
9
18
  public logPayload: Fr[],
10
19
  public txHash: TxHash,
11
20
  public uniqueNoteHashesInTx: Fr[],
12
21
  public firstNullifierInTx: Fr,
13
- private maxLogContentLength: N,
14
22
  ) {}
15
23
 
16
24
  toNoirSerialization(): (Fr | Fr[])[] {
17
25
  return [
18
- ...toBoundedVecSerialization(this.logPayload, this.maxLogContentLength),
26
+ ...toBoundedVecSerialization(this.logPayload, PRIVATE_LOG_CIPHERTEXT_LEN),
19
27
  this.txHash.hash,
20
28
  ...toBoundedVecSerialization(this.uniqueNoteHashesInTx, MAX_NOTE_HASHES_PER_TX),
21
29
  this.firstNullifierInTx,
22
30
  ];
23
31
  }
24
- }
25
-
26
- // This is used as a response for PXE's custom getPublicLogByTag oracle.
27
- export class PublicLogWithTxData extends LogWithTxData<typeof PUBLIC_LOG_PLAINTEXT_LEN> {
28
- constructor(logContent: Fr[], txHash: TxHash, uniqueNoteHashesInTx: Fr[], firstNullifierInTx: Fr) {
29
- super(logContent, txHash, uniqueNoteHashesInTx, firstNullifierInTx, PUBLIC_LOG_PLAINTEXT_LEN);
30
- }
31
-
32
- static noirSerializationOfEmpty(): (Fr | Fr[])[] {
33
- return new PublicLogWithTxData([], TxHash.zero(), [], new Fr(0)).toNoirSerialization();
34
- }
35
- }
36
-
37
- // This is used as a response for PXE's custom getPrivateLogByTag oracle.
38
- export class PrivateLogWithTxData extends LogWithTxData<typeof PRIVATE_LOG_CIPHERTEXT_LEN> {
39
- constructor(logContent: Fr[], txHash: TxHash, uniqueNoteHashesInTx: Fr[], firstNullifierInTx: Fr) {
40
- super(logContent, txHash, uniqueNoteHashesInTx, firstNullifierInTx, PRIVATE_LOG_CIPHERTEXT_LEN);
41
- }
42
32
 
43
33
  static noirSerializationOfEmpty(): (Fr | Fr[])[] {
44
34
  return new PrivateLogWithTxData([], TxHash.zero(), [], new Fr(0)).toNoirSerialization();
@@ -1,28 +1,113 @@
1
- import { PUBLIC_LOG_LENGTH, PUBLIC_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
2
- import { type FieldsOf, makeTuple } from '@aztec/foundation/array';
3
- import { padArrayEnd } from '@aztec/foundation/collection';
1
+ import { FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH, PUBLIC_LOG_HEADER_LENGTH } from '@aztec/constants';
2
+ import type { FieldsOf } from '@aztec/foundation/array';
4
3
  import { Fr } from '@aztec/foundation/fields';
5
4
  import { type ZodFor, schemas } from '@aztec/foundation/schemas';
6
- import {
7
- BufferReader,
8
- FieldReader,
9
- type Tuple,
10
- serializeToBuffer,
11
- serializeToFields,
12
- } from '@aztec/foundation/serialize';
5
+ import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
13
6
 
14
7
  import { inspect } from 'util';
15
8
  import { z } from 'zod';
16
9
 
17
10
  import { AztecAddress } from '../aztec-address/index.js';
18
11
 
19
- export class PublicLog {
20
- static SIZE_IN_BYTES = Fr.SIZE_IN_BYTES * PUBLIC_LOG_LENGTH;
12
+ function totalSizeInFields(logs: PublicLog[]) {
13
+ return logs.reduce((acc, log) => acc + log.sizeInFields(), 0);
14
+ }
15
+
16
+ // This class represents logs in the same format as noir does, with a bounded maximum length.
17
+ export class FlatPublicLogs {
18
+ // We don't use tuple here because FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH is too large
19
+ constructor(
20
+ public length: number,
21
+ public payload: Fr[],
22
+ ) {
23
+ if (payload.length !== FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH) {
24
+ throw new Error('Invalid payload given to FlatPublicLogs');
25
+ }
26
+ if (length > payload.length) {
27
+ throw new Error('Invalid length given to FlatPublicLogs');
28
+ }
29
+ }
30
+
31
+ private static fromUnpaddedPayload(payload: Fr[]) {
32
+ const length = payload.length;
33
+ return new FlatPublicLogs(length, [...payload, ...Array(FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH - length).fill(Fr.ZERO)]);
34
+ }
35
+
36
+ // In blobs, the actual nonempty length of the logs is encoded with the prefix, and then we have the non-padded payload.
37
+ static fromBlobFields(length: number, fields: Fr[] | FieldReader) {
38
+ const reader = FieldReader.asReader(fields);
39
+ const payload = reader.readFieldArray(length);
40
+ return this.fromUnpaddedPayload(payload);
41
+ }
42
+
43
+ toBlobFields() {
44
+ return this.payload.slice(0, this.length);
45
+ }
46
+
47
+ static fromLogs(logs: PublicLog[]) {
48
+ return this.fromUnpaddedPayload(logs.flatMap(log => log.toFields()));
49
+ }
50
+
51
+ toLogs() {
52
+ const reader = FieldReader.asReader(this.payload);
53
+ const logs = [];
54
+ while (totalSizeInFields(logs) < this.length) {
55
+ logs.push(PublicLog.fromFields(reader));
56
+ }
57
+ if (totalSizeInFields(logs) !== this.length) {
58
+ throw new Error('Wrong length in FlatPublicLogs');
59
+ }
60
+ return logs;
61
+ }
62
+
63
+ static get schema(): ZodFor<FlatPublicLogs> {
64
+ return z
65
+ .object({
66
+ length: z.number(),
67
+ payload: z.array(schemas.Fr).min(FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH).max(FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH),
68
+ })
69
+ .transform(({ length, payload }) => new FlatPublicLogs(length, payload));
70
+ }
71
+
72
+ toBuffer(): Buffer {
73
+ return serializeToBuffer(this.length, this.payload.slice(0, this.length));
74
+ }
75
+
76
+ static fromBuffer(buffer: Buffer | BufferReader) {
77
+ const reader = BufferReader.asReader(buffer);
78
+ const length = reader.readNumber();
79
+ return this.fromUnpaddedPayload(reader.readArray(length, Fr));
80
+ }
21
81
 
82
+ // ToFields and fromFields expect the noir style representation, with constant length payload.
83
+ toFields(): Fr[] {
84
+ return [new Fr(this.length), ...this.payload];
85
+ }
86
+
87
+ static fromFields(fields: Fr[] | FieldReader) {
88
+ const reader = FieldReader.asReader(fields);
89
+ // We need to do this because field reader returns tuples, which break the type system on these sizes.
90
+ const length = reader.readU32();
91
+ const payload: Fr[] = [];
92
+ for (let i = 0; i < FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH; ++i) {
93
+ payload.push(reader.readField());
94
+ }
95
+ return new FlatPublicLogs(length, payload);
96
+ }
97
+
98
+ static empty() {
99
+ return new FlatPublicLogs(0, Array(FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH).fill(Fr.ZERO));
100
+ }
101
+
102
+ isEmpty() {
103
+ return this.length === 0;
104
+ }
105
+ }
106
+
107
+ export class PublicLog {
22
108
  constructor(
23
109
  public contractAddress: AztecAddress,
24
- public fields: Tuple<Fr, typeof PUBLIC_LOG_SIZE_IN_FIELDS>,
25
- public emittedLength: number,
110
+ public fields: Fr[],
26
111
  ) {}
27
112
 
28
113
  static from(fields: FieldsOf<PublicLog>) {
@@ -30,104 +115,81 @@ export class PublicLog {
30
115
  }
31
116
 
32
117
  static getFields(fields: FieldsOf<PublicLog>) {
33
- return [fields.contractAddress, fields.fields, fields.emittedLength] as const;
118
+ return [fields.contractAddress, fields.fields] as const;
34
119
  }
35
120
 
36
121
  toFields(): Fr[] {
37
- return serializeToFields(...PublicLog.getFields(this));
122
+ return [new Fr(this.fields.length), this.contractAddress.toField(), ...this.fields];
38
123
  }
39
124
 
40
125
  static fromFields(fields: Fr[] | FieldReader) {
41
126
  const reader = FieldReader.asReader(fields);
42
- return new PublicLog(
43
- reader.readObject(AztecAddress),
44
- reader.readFieldArray(PUBLIC_LOG_SIZE_IN_FIELDS),
45
- reader.readU32(),
46
- );
127
+ const fieldsLength = reader.readU32();
128
+ return new PublicLog(reader.readObject(AztecAddress), reader.readFieldArray(fieldsLength));
47
129
  }
48
130
 
49
- getEmittedFields() {
50
- return this.fields.slice(0, this.emittedLength);
51
- }
52
-
53
- getEmittedFieldsWithoutTag() {
54
- return this.fields.slice(1, this.emittedLength);
131
+ sizeInFields() {
132
+ return this.fields.length + PUBLIC_LOG_HEADER_LENGTH;
55
133
  }
56
134
 
57
- toBlobFields(): Fr[] {
58
- return [new Fr(this.emittedLength), this.contractAddress.toField()].concat(this.getEmittedFields());
135
+ getEmittedFields() {
136
+ return this.fields.slice(0);
59
137
  }
60
138
 
61
- static fromBlobFields(fields: Fr[] | FieldReader) {
62
- const reader = FieldReader.asReader(fields);
63
- const emittedLength = reader.readU32();
64
- const contractAddress = reader.readObject(AztecAddress);
65
- const emittedFields = reader.readFieldArray(emittedLength);
66
- return new PublicLog(
67
- contractAddress,
68
- padArrayEnd(emittedFields, Fr.ZERO, PUBLIC_LOG_SIZE_IN_FIELDS),
69
- emittedLength,
70
- );
139
+ getEmittedFieldsWithoutTag() {
140
+ return this.fields.slice(1);
71
141
  }
72
142
 
73
143
  isEmpty() {
74
- return this.contractAddress.isZero() && this.fields.every(f => f.isZero()) && this.emittedLength === 0;
144
+ return this.contractAddress.isZero() && this.fields.length === 0;
75
145
  }
76
146
 
77
147
  static empty() {
78
- return new PublicLog(AztecAddress.ZERO, makeTuple(PUBLIC_LOG_SIZE_IN_FIELDS, Fr.zero), 0);
148
+ return new PublicLog(AztecAddress.ZERO, []);
79
149
  }
80
150
 
81
151
  toBuffer(): Buffer {
82
- return serializeToBuffer(...PublicLog.getFields(this));
152
+ return serializeToBuffer(this.fields.length, this.contractAddress, this.fields);
83
153
  }
84
154
 
85
155
  static fromBuffer(buffer: Buffer | BufferReader) {
86
156
  const reader = BufferReader.asReader(buffer);
87
- return new PublicLog(
88
- reader.readObject(AztecAddress),
89
- reader.readArray(PUBLIC_LOG_SIZE_IN_FIELDS, Fr),
90
- reader.readNumber(),
91
- );
157
+ const fieldsLength = reader.readNumber();
158
+ return new PublicLog(reader.readObject(AztecAddress), reader.readArray(fieldsLength, Fr));
92
159
  }
93
160
 
94
161
  static async random() {
95
162
  return new PublicLog(
96
163
  await AztecAddress.random(),
97
- makeTuple(PUBLIC_LOG_SIZE_IN_FIELDS, Fr.random),
98
- PUBLIC_LOG_SIZE_IN_FIELDS,
164
+ Array.from({ length: 10 }, () => Fr.random()),
99
165
  );
100
166
  }
101
167
 
102
168
  equals(other: this) {
103
169
  return (
170
+ this.fields.length === other.fields.length &&
104
171
  this.contractAddress.equals(other.contractAddress) &&
105
- this.fields.every((field, i) => field.equals(other.fields[i])) &&
106
- this.emittedLength === other.emittedLength
172
+ this.fields.every((field, i) => field.equals(other.fields[i]))
107
173
  );
108
174
  }
109
175
 
110
176
  toHumanReadable(): string {
111
- return `PublicLog: (contractAddress: ${this.contractAddress} fields: ${this.fields}) emittedLength: ${this.emittedLength}`;
177
+ return `PublicLog: (contractAddress: ${this.contractAddress} fields: ${this.fields})`;
112
178
  }
113
179
 
114
180
  static get schema(): ZodFor<PublicLog> {
115
181
  return z
116
182
  .object({
117
183
  contractAddress: AztecAddress.schema,
118
- fields: z.array(schemas.Fr).refine(arr => arr.length === PUBLIC_LOG_SIZE_IN_FIELDS),
119
- emittedLength: z.number(),
184
+ fields: z.array(schemas.Fr),
120
185
  })
121
- .transform(({ contractAddress, fields, emittedLength }) =>
122
- PublicLog.fromFields([contractAddress.toField(), ...fields, new Fr(emittedLength)]),
123
- );
186
+ .transform(({ contractAddress, fields }) => PublicLog.from({ contractAddress, fields }));
124
187
  }
125
188
 
126
189
  [inspect.custom](): string {
127
190
  return `PublicLog {
128
191
  contractAddress: ${inspect(this.contractAddress)},
129
192
  fields: [${this.fields.map(x => inspect(x)).join(', ')}],
130
- emittedLength: ${this.emittedLength},
131
193
  }`;
132
194
  }
133
195
  }
@@ -27,7 +27,6 @@ import {
27
27
  MAX_PRIVATE_LOGS_PER_TX,
28
28
  MAX_PROTOCOL_CONTRACTS,
29
29
  MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
30
- MAX_PUBLIC_LOGS_PER_TX,
31
30
  MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
32
31
  NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
33
32
  NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH,
@@ -38,7 +37,6 @@ import {
38
37
  NUM_MSGS_PER_BASE_PARITY,
39
38
  PRIVATE_LOG_SIZE_IN_FIELDS,
40
39
  PUBLIC_DATA_TREE_HEIGHT,
41
- PUBLIC_LOG_SIZE_IN_FIELDS,
42
40
  RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
43
41
  VK_TREE_HEIGHT,
44
42
  } from '@aztec/constants';
@@ -124,7 +122,7 @@ import {
124
122
  import { PublicKeys, computeAddress } from '../keys/index.js';
125
123
  import { ContractClassLogFields } from '../logs/index.js';
126
124
  import { PrivateLog } from '../logs/private_log.js';
127
- import { PublicLog } from '../logs/public_log.js';
125
+ import { FlatPublicLogs, PublicLog } from '../logs/public_log.js';
128
126
  import { CountedL2ToL1Message, L2ToL1Message, ScopedL2ToL1Message } from '../messaging/l2_to_l1_message.js';
129
127
  import { ParityBasePrivateInputs } from '../parity/parity_base_private_inputs.js';
130
128
  import { ParityPublicInputs } from '../parity/parity_public_inputs.js';
@@ -210,8 +208,7 @@ function makePrivateLogData(seed: number) {
210
208
  function makePublicLog(seed: number) {
211
209
  return new PublicLog(
212
210
  makeAztecAddress(seed),
213
- makeTuple(PUBLIC_LOG_SIZE_IN_FIELDS, fr, seed + 1),
214
- PUBLIC_LOG_SIZE_IN_FIELDS,
211
+ new Array(10).fill(null).map((_, i) => new Fr(seed + i)),
215
212
  );
216
213
  }
217
214
 
@@ -351,13 +348,13 @@ function makeAvmAccumulatedData(seed = 1) {
351
348
  makeTuple(MAX_NOTE_HASHES_PER_TX, fr, seed),
352
349
  makeTuple(MAX_NULLIFIERS_PER_TX, fr, seed + 0x100),
353
350
  makeTuple(MAX_L2_TO_L1_MSGS_PER_TX, makeScopedL2ToL1Message, seed + 0x200),
354
- makeTuple(MAX_PUBLIC_LOGS_PER_TX, makePublicLog, seed + 0x300),
351
+ FlatPublicLogs.fromLogs(new Array(20).fill(null).map((_, i) => makePublicLog(seed + i * 256))),
355
352
  makeTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataWrite, seed + 0x400),
356
353
  );
357
354
  }
358
355
 
359
356
  function makeAvmAccumulatedDataArrayLengths(seed = 1) {
360
- return new AvmAccumulatedDataArrayLengths(seed, seed + 1, seed + 2, seed + 3, seed + 4);
357
+ return new AvmAccumulatedDataArrayLengths(seed, seed + 1, seed + 2, seed + 3);
361
358
  }
362
359
 
363
360
  export function makeGas(seed = 1) {
@@ -175,7 +175,7 @@ export function makeProcessedTxFromTxWithPublicCalls(
175
175
  ),
176
176
  publicDataWrites,
177
177
  privateLogs,
178
- avmPublicInputs.accumulatedData.publicLogs.filter(l => !l.isEmpty()),
178
+ avmPublicInputs.accumulatedData.publicLogs.toLogs(),
179
179
  contractClassLogs,
180
180
  );
181
181