@aztec/stdlib 0.79.0 → 0.81.0

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 (121) hide show
  1. package/dest/abi/abi.d.ts +7 -5
  2. package/dest/abi/abi.d.ts.map +1 -1
  3. package/dest/abi/abi.js +8 -3
  4. package/dest/abi/contract_artifact.d.ts +16 -1
  5. package/dest/abi/contract_artifact.d.ts.map +1 -1
  6. package/dest/abi/contract_artifact.js +72 -11
  7. package/dest/avm/avm.d.ts +173 -405
  8. package/dest/avm/avm.d.ts.map +1 -1
  9. package/dest/avm/avm.js +34 -27
  10. package/dest/avm/avm_proving_request.d.ts +84 -186
  11. package/dest/avm/avm_proving_request.d.ts.map +1 -1
  12. package/dest/avm/public_data_write.d.ts +1 -0
  13. package/dest/avm/public_data_write.d.ts.map +1 -1
  14. package/dest/avm/public_data_write.js +3 -0
  15. package/dest/block/body.d.ts +1 -0
  16. package/dest/block/body.d.ts.map +1 -1
  17. package/dest/block/body.js +3 -0
  18. package/dest/block/index.d.ts +1 -0
  19. package/dest/block/index.d.ts.map +1 -1
  20. package/dest/block/index.js +1 -0
  21. package/dest/block/l2_block.d.ts +2 -1
  22. package/dest/block/l2_block.d.ts.map +1 -1
  23. package/dest/block/l2_block.js +3 -0
  24. package/dest/block/l2_block_downloader/l2_block_stream.d.ts +3 -3
  25. package/dest/block/l2_block_downloader/l2_block_stream.d.ts.map +1 -1
  26. package/dest/block/l2_block_downloader/l2_block_stream.js +2 -2
  27. package/dest/block/l2_block_source.d.ts +3 -0
  28. package/dest/block/l2_block_source.d.ts.map +1 -1
  29. package/dest/block/published_l2_block.d.ts +89 -0
  30. package/dest/block/published_l2_block.d.ts.map +1 -0
  31. package/dest/block/published_l2_block.js +32 -0
  32. package/dest/contract/contract_class.d.ts.map +1 -1
  33. package/dest/contract/contract_class.js +2 -0
  34. package/dest/contract/contract_instance.d.ts +2 -2
  35. package/dest/contract/contract_instance.d.ts.map +1 -1
  36. package/dest/contract/contract_instance.js +3 -2
  37. package/dest/contract/interfaces/contract_data_source.d.ts +3 -9
  38. package/dest/contract/interfaces/contract_data_source.d.ts.map +1 -1
  39. package/dest/database-version/version_manager.js +1 -1
  40. package/dest/interfaces/archiver.d.ts.map +1 -1
  41. package/dest/interfaces/archiver.js +4 -3
  42. package/dest/interfaces/aztec-node.d.ts +1 -1
  43. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  44. package/dest/interfaces/aztec-node.js +2 -0
  45. package/dest/interfaces/proving-job.d.ts +106 -208
  46. package/dest/interfaces/proving-job.d.ts.map +1 -1
  47. package/dest/logs/contract_class_log.d.ts +1 -0
  48. package/dest/logs/contract_class_log.d.ts.map +1 -1
  49. package/dest/logs/contract_class_log.js +3 -0
  50. package/dest/logs/l1_payload/index.d.ts +1 -1
  51. package/dest/logs/l1_payload/index.d.ts.map +1 -1
  52. package/dest/logs/l1_payload/index.js +1 -1
  53. package/dest/logs/private_log.d.ts +2 -1
  54. package/dest/logs/private_log.d.ts.map +1 -1
  55. package/dest/logs/private_log.js +14 -3
  56. package/dest/logs/public_log.d.ts.map +1 -1
  57. package/dest/logs/public_log.js +4 -1
  58. package/dest/logs/tx_scoped_l2_log.d.ts +16 -28
  59. package/dest/logs/tx_scoped_l2_log.d.ts.map +1 -1
  60. package/dest/logs/tx_scoped_l2_log.js +28 -19
  61. package/dest/note/extended_note.d.ts +10 -21
  62. package/dest/note/extended_note.d.ts.map +1 -1
  63. package/dest/note/extended_note.js +19 -28
  64. package/dest/note/notes_filter.d.ts +2 -2
  65. package/dest/note/notes_filter.d.ts.map +1 -1
  66. package/dest/note/notes_filter.js +1 -1
  67. package/dest/p2p/consensus_payload.d.ts +3 -1
  68. package/dest/p2p/consensus_payload.d.ts.map +1 -1
  69. package/dest/p2p/consensus_payload.js +3 -0
  70. package/dest/proofs/proof.d.ts +0 -1
  71. package/dest/proofs/proof.d.ts.map +1 -1
  72. package/dest/proofs/proof.js +2 -7
  73. package/dest/rollup/block_root_rollup.d.ts +1 -1
  74. package/dest/tests/factories.d.ts +3 -2
  75. package/dest/tests/factories.d.ts.map +1 -1
  76. package/dest/tests/factories.js +14 -8
  77. package/dest/tests/mocks.d.ts +2 -2
  78. package/dest/tests/mocks.d.ts.map +1 -1
  79. package/dest/tests/mocks.js +5 -5
  80. package/dest/trees/nullifier_membership_witness.d.ts +7 -7
  81. package/dest/trees/public_data_witness.d.ts +7 -7
  82. package/dest/tx/capsule.d.ts +2 -0
  83. package/dest/tx/capsule.d.ts.map +1 -1
  84. package/dest/tx/capsule.js +2 -0
  85. package/dest/tx/tx_effect.d.ts +1 -0
  86. package/dest/tx/tx_effect.d.ts.map +1 -1
  87. package/dest/tx/tx_effect.js +4 -1
  88. package/package.json +6 -6
  89. package/src/abi/abi.ts +16 -9
  90. package/src/abi/contract_artifact.ts +87 -10
  91. package/src/avm/avm.ts +42 -39
  92. package/src/avm/public_data_write.ts +4 -0
  93. package/src/block/body.ts +6 -0
  94. package/src/block/index.ts +1 -0
  95. package/src/block/l2_block.ts +4 -0
  96. package/src/block/l2_block_downloader/l2_block_stream.ts +5 -5
  97. package/src/block/l2_block_source.ts +4 -0
  98. package/src/block/published_l2_block.ts +45 -0
  99. package/src/contract/contract_class.ts +2 -0
  100. package/src/contract/contract_instance.ts +13 -5
  101. package/src/contract/interfaces/contract_data_source.ts +3 -10
  102. package/src/database-version/version_manager.ts +1 -1
  103. package/src/interfaces/archiver.ts +9 -6
  104. package/src/interfaces/aztec-node.ts +4 -1
  105. package/src/logs/contract_class_log.ts +8 -0
  106. package/src/logs/l1_payload/index.ts +1 -1
  107. package/src/logs/private_log.ts +13 -3
  108. package/src/logs/public_log.ts +11 -1
  109. package/src/logs/tx_scoped_l2_log.ts +28 -25
  110. package/src/note/extended_note.ts +17 -36
  111. package/src/note/notes_filter.ts +3 -3
  112. package/src/p2p/consensus_payload.ts +9 -0
  113. package/src/proofs/proof.ts +2 -8
  114. package/src/tests/factories.ts +15 -14
  115. package/src/tests/mocks.ts +5 -9
  116. package/src/tx/capsule.ts +2 -0
  117. package/src/tx/tx_effect.ts +23 -1
  118. package/dest/logs/l1_payload/l1_note_payload.d.ts +0 -82
  119. package/dest/logs/l1_payload/l1_note_payload.d.ts.map +0 -1
  120. package/dest/logs/l1_payload/l1_note_payload.js +0 -129
  121. package/src/logs/l1_payload/l1_note_payload.ts +0 -182
@@ -9,6 +9,7 @@ import {
9
9
  ContractArtifactSchema,
10
10
  type ContractNote,
11
11
  type FieldLayout,
12
+ type FunctionAbi,
12
13
  type FunctionArtifact,
13
14
  FunctionType,
14
15
  type IntegerValue,
@@ -44,6 +45,7 @@ export function contractArtifactFromBuffer(buffer: Buffer): Promise<ContractArti
44
45
 
45
46
  /**
46
47
  * Gets nargo build output and returns a valid contract artifact instance.
48
+ * Does not include public bytecode, apart from the public_dispatch function.
47
49
  * @param input - Input object as generated by nargo compile.
48
50
  * @returns A valid contract artifact instance.
49
51
  */
@@ -54,6 +56,16 @@ export function loadContractArtifact(input: NoirCompiledContract): ContractArtif
54
56
  return generateContractArtifact(input);
55
57
  }
56
58
 
59
+ /**
60
+ * Gets nargo build output and returns a valid contract artifact instance.
61
+ * Differs from loadContractArtifact() by retaining all bytecode.
62
+ * @param input - Input object as generated by nargo compile.
63
+ * @returns A valid contract artifact instance.
64
+ */
65
+ export function loadContractArtifactForPublic(input: NoirCompiledContract): ContractArtifact {
66
+ return generateContractArtifactForPublic(input);
67
+ }
68
+
57
69
  /**
58
70
  * Checks if the given input looks like a valid ContractArtifact. The check is not exhaustive,
59
71
  * and it's just meant to differentiate between nargo raw build artifacts and the ones
@@ -79,6 +91,22 @@ function isContractArtifact(input: any): input is ContractArtifact {
79
91
  if (typeof fn.functionType !== 'string') {
80
92
  return false;
81
93
  }
94
+ if (!retainBytecode(fn) && fn.bytecode.length) {
95
+ // We want to remove the bytecode of public fns (apart from the dispatch fn) to save space
96
+ // If the input is private-only, we don't need to use generateContractArtifact() below
97
+ return false;
98
+ }
99
+ }
100
+ if (!Array.isArray(maybeContractArtifact.nonDispatchPublicFunctions)) {
101
+ return false;
102
+ }
103
+ for (const fn of maybeContractArtifact.nonDispatchPublicFunctions) {
104
+ if (typeof fn.name !== 'string') {
105
+ return false;
106
+ }
107
+ if (typeof fn.functionType !== 'string') {
108
+ return false;
109
+ }
82
110
  }
83
111
  return true;
84
112
  }
@@ -103,15 +131,21 @@ function generateFunctionParameter(param: NoirCompiledContractFunctionParameter)
103
131
  type NoirCompiledContractFunction = NoirCompiledContract['functions'][number];
104
132
 
105
133
  /**
106
- * Generates a function build artifact.
134
+ * Returns true if we should retain bytecode
135
+ */
136
+ export function retainBytecode(input: NoirCompiledContractFunction | FunctionArtifact): boolean {
137
+ const functionType =
138
+ (input as FunctionArtifact).functionType ?? getFunctionType(input as NoirCompiledContractFunction);
139
+ return functionType !== FunctionType.PUBLIC || input.name == 'public_dispatch';
140
+ }
141
+
142
+ /**
143
+ * Generates a function abi.
107
144
  * @param fn - Noir function entry.
108
145
  * @param contract - Parent contract.
109
- * @returns Function artifact.
146
+ * @returns Function abi.
110
147
  */
111
- function generateFunctionArtifact(
112
- fn: NoirCompiledContractFunction,
113
- contract: NoirCompiledContract,
114
- ): Omit<FunctionArtifact, 'bytecode'> & { bytecode: string } {
148
+ function generateFunctionAbi(fn: NoirCompiledContractFunction, contract: NoirCompiledContract): FunctionAbi {
115
149
  if (fn.custom_attributes === undefined) {
116
150
  throw new Error(
117
151
  `No custom attributes found for contract function ${fn.name}. Try rebuilding the contract with the latest nargo version.`,
@@ -156,10 +190,26 @@ function generateFunctionArtifact(
156
190
  isInitializer: fn.custom_attributes.includes(AZTEC_INITIALIZER_ATTRIBUTE),
157
191
  parameters,
158
192
  returnTypes,
159
- bytecode: fn.bytecode,
160
- debugSymbols: fn.debug_symbols,
161
193
  errorTypes: fn.abi.error_types,
162
194
  ...(fn.assert_messages ? { assertMessages: fn.assert_messages } : undefined),
195
+ };
196
+ }
197
+
198
+ /**
199
+ * Generates a function build artifact.
200
+ * @param fn - Noir function entry.
201
+ * @param contract - Parent contract.
202
+ * @returns Function artifact.
203
+ */
204
+ function generateFunctionArtifact(
205
+ fn: NoirCompiledContractFunction,
206
+ contract: NoirCompiledContract,
207
+ ): Omit<FunctionArtifact, 'bytecode'> & { bytecode: string } {
208
+ const abi = generateFunctionAbi(fn, contract);
209
+ return {
210
+ ...abi,
211
+ bytecode: fn.bytecode,
212
+ debugSymbols: fn.debug_symbols,
163
213
  ...(fn.verification_key ? { verificationKey: fn.verification_key } : undefined),
164
214
  };
165
215
  }
@@ -274,19 +324,46 @@ function getNoteTypes(input: NoirCompiledContract) {
274
324
 
275
325
  /**
276
326
  * Given a Nargo output generates an Aztec-compatible contract artifact.
327
+ * Does not include public bytecode, apart from the public_dispatch function.
328
+ * @param compiled - Noir build output.
329
+ * @returns Aztec contract build artifact.
330
+ */
331
+ function generateContractArtifact(contract: NoirCompiledContract): ContractArtifact {
332
+ try {
333
+ return ContractArtifactSchema.parse({
334
+ name: contract.name,
335
+ functions: contract.functions.filter(f => retainBytecode(f)).map(f => generateFunctionArtifact(f, contract)),
336
+ nonDispatchPublicFunctions: contract.functions
337
+ .filter(f => !retainBytecode(f))
338
+ .map(f => generateFunctionAbi(f, contract)),
339
+ outputs: contract.outputs,
340
+ storageLayout: getStorageLayout(contract),
341
+ notes: getNoteTypes(contract),
342
+ fileMap: contract.file_map,
343
+ });
344
+ } catch (err) {
345
+ throw new Error(`Could not generate contract artifact for ${contract.name}: ${err}`);
346
+ }
347
+ }
348
+
349
+ /**
350
+ * Given a Nargo output generates an Aztec-compatible contract artifact.
351
+ * Retains all public bytecode.
277
352
  * @param compiled - Noir build output.
278
353
  * @returns Aztec contract build artifact.
279
354
  */
280
- function generateContractArtifact(contract: NoirCompiledContract, aztecNrVersion?: string): ContractArtifact {
355
+ function generateContractArtifactForPublic(contract: NoirCompiledContract): ContractArtifact {
281
356
  try {
282
357
  return ContractArtifactSchema.parse({
283
358
  name: contract.name,
284
359
  functions: contract.functions.map(f => generateFunctionArtifact(f, contract)),
360
+ nonDispatchPublicFunctions: contract.functions
361
+ .filter(f => !retainBytecode(f))
362
+ .map(f => generateFunctionAbi(f, contract)),
285
363
  outputs: contract.outputs,
286
364
  storageLayout: getStorageLayout(contract),
287
365
  notes: getNoteTypes(contract),
288
366
  fileMap: contract.file_map,
289
- ...(aztecNrVersion ? { aztecNrVersion } : {}),
290
367
  });
291
368
  } catch (err) {
292
369
  throw new Error(`Could not generate contract artifact for ${contract.name}: ${err}`);
package/src/avm/avm.ts CHANGED
@@ -12,25 +12,33 @@ import { AvmCircuitPublicInputs } from './avm_circuit_public_inputs.js';
12
12
  import { serializeWithMessagePack } from './message_pack.js';
13
13
 
14
14
  export class AvmEnqueuedCallHint {
15
- constructor(public readonly contractAddress: AztecAddress, public readonly calldata: Fr[]) {}
15
+ constructor(
16
+ public readonly msgSender: AztecAddress,
17
+ public readonly contractAddress: AztecAddress,
18
+ public readonly calldata: Fr[],
19
+ public isStaticCall: boolean,
20
+ ) {}
16
21
 
17
22
  static get schema() {
18
23
  return z
19
24
  .object({
25
+ msgSender: AztecAddress.schema,
20
26
  contractAddress: AztecAddress.schema,
21
27
  calldata: schemas.Fr.array(),
28
+ isStaticCall: z.boolean(),
22
29
  })
23
- .transform(({ contractAddress, calldata }) => new AvmEnqueuedCallHint(contractAddress, calldata));
30
+ .transform(
31
+ ({ msgSender, contractAddress, calldata, isStaticCall }) =>
32
+ new AvmEnqueuedCallHint(msgSender, contractAddress, calldata, isStaticCall),
33
+ );
24
34
  }
25
35
  }
26
36
 
27
37
  export class AvmContractClassHint {
28
38
  constructor(
29
39
  public readonly classId: Fr,
30
- public readonly exists: boolean,
31
40
  public readonly artifactHash: Fr,
32
41
  public readonly privateFunctionsRoot: Fr,
33
- public readonly publicBytecodeCommitment: Fr,
34
42
  public readonly packedBytecode: Buffer,
35
43
  ) {}
36
44
 
@@ -38,79 +46,70 @@ export class AvmContractClassHint {
38
46
  return z
39
47
  .object({
40
48
  classId: schemas.Fr,
41
- exists: z.boolean(),
42
49
  artifactHash: schemas.Fr,
43
50
  privateFunctionsRoot: schemas.Fr,
44
- publicBytecodeCommitment: schemas.Fr,
45
51
  packedBytecode: schemas.Buffer,
46
52
  })
47
53
  .transform(
48
- ({ classId, exists, artifactHash, privateFunctionsRoot, publicBytecodeCommitment, packedBytecode }) =>
49
- new AvmContractClassHint(
50
- classId,
51
- exists,
52
- artifactHash,
53
- privateFunctionsRoot,
54
- publicBytecodeCommitment,
55
- packedBytecode,
56
- ),
54
+ ({ classId, artifactHash, privateFunctionsRoot, packedBytecode }) =>
55
+ new AvmContractClassHint(classId, artifactHash, privateFunctionsRoot, packedBytecode),
57
56
  );
58
57
  }
59
58
  }
60
59
 
60
+ export class AvmBytecodeCommitmentHint {
61
+ constructor(public readonly classId: Fr, public readonly commitment: Fr) {}
62
+
63
+ static get schema() {
64
+ return z
65
+ .object({
66
+ classId: schemas.Fr,
67
+ commitment: schemas.Fr,
68
+ })
69
+ .transform(({ classId, commitment }) => new AvmBytecodeCommitmentHint(classId, commitment));
70
+ }
71
+ }
72
+
61
73
  export class AvmContractInstanceHint {
62
74
  constructor(
63
75
  public readonly address: AztecAddress,
64
- public readonly exists: boolean,
65
76
  public readonly salt: Fr,
66
77
  public readonly deployer: AztecAddress,
67
78
  public readonly currentContractClassId: Fr,
68
79
  public readonly originalContractClassId: Fr,
69
80
  public readonly initializationHash: Fr,
70
81
  public readonly publicKeys: PublicKeys,
71
- // public readonly updateMembershipHint: AvmPublicDataReadTreeHint = AvmPublicDataReadTreeHint.empty(),
72
- public readonly updateMembershipHint: AvmPublicDataReadTreeHint,
73
- public readonly updatePreimage: Fr[] = [],
74
82
  ) {}
75
83
 
76
84
  static get schema() {
77
85
  return z
78
86
  .object({
79
87
  address: AztecAddress.schema,
80
- exists: z.boolean(),
81
88
  salt: schemas.Fr,
82
89
  deployer: AztecAddress.schema,
83
90
  currentContractClassId: schemas.Fr,
84
91
  originalContractClassId: schemas.Fr,
85
92
  initializationHash: schemas.Fr,
86
93
  publicKeys: PublicKeys.schema,
87
- updateMembershipHint: AvmPublicDataReadTreeHint.schema,
88
- updatePreimage: schemas.Fr.array(),
89
94
  })
90
95
  .transform(
91
96
  ({
92
97
  address,
93
- exists,
94
98
  salt,
95
99
  deployer,
96
100
  currentContractClassId,
97
101
  originalContractClassId,
98
102
  initializationHash,
99
103
  publicKeys,
100
- updateMembershipHint,
101
- updatePreimage,
102
104
  }) =>
103
105
  new AvmContractInstanceHint(
104
106
  address,
105
- exists,
106
107
  salt,
107
108
  deployer,
108
109
  currentContractClassId,
109
110
  originalContractClassId,
110
111
  initializationHash,
111
112
  publicKeys,
112
- updateMembershipHint,
113
- updatePreimage,
114
113
  ),
115
114
  );
116
115
  }
@@ -213,20 +212,21 @@ export class AvmPublicDataWriteTreeHint {
213
212
 
214
213
  export class AvmExecutionHints {
215
214
  constructor(
216
- public readonly enqueuedCalls: AvmEnqueuedCallHint[],
217
- public readonly contractInstances: AvmContractInstanceHint[],
218
- public readonly contractClasses: AvmContractClassHint[],
219
- public readonly publicDataReads: AvmPublicDataReadTreeHint[],
220
- public readonly publicDataWrites: AvmPublicDataWriteTreeHint[],
221
- public readonly nullifierReads: AvmNullifierReadTreeHint[],
222
- public readonly nullifierWrites: AvmNullifierWriteTreeHint[],
223
- public readonly noteHashReads: AvmAppendTreeHint[],
224
- public readonly noteHashWrites: AvmAppendTreeHint[],
225
- public readonly l1ToL2MessageReads: AvmAppendTreeHint[],
215
+ public readonly enqueuedCalls: AvmEnqueuedCallHint[] = [],
216
+ public readonly contractInstances: AvmContractInstanceHint[] = [],
217
+ public readonly contractClasses: AvmContractClassHint[] = [],
218
+ public readonly bytecodeCommitments: AvmBytecodeCommitmentHint[] = [],
219
+ public readonly publicDataReads: AvmPublicDataReadTreeHint[] = [],
220
+ public readonly publicDataWrites: AvmPublicDataWriteTreeHint[] = [],
221
+ public readonly nullifierReads: AvmNullifierReadTreeHint[] = [],
222
+ public readonly nullifierWrites: AvmNullifierWriteTreeHint[] = [],
223
+ public readonly noteHashReads: AvmAppendTreeHint[] = [],
224
+ public readonly noteHashWrites: AvmAppendTreeHint[] = [],
225
+ public readonly l1ToL2MessageReads: AvmAppendTreeHint[] = [],
226
226
  ) {}
227
227
 
228
228
  static empty() {
229
- return new AvmExecutionHints([], [], [], [], [], [], [], [], [], []);
229
+ return new AvmExecutionHints();
230
230
  }
231
231
 
232
232
  static get schema() {
@@ -235,6 +235,7 @@ export class AvmExecutionHints {
235
235
  enqueuedCalls: AvmEnqueuedCallHint.schema.array(),
236
236
  contractInstances: AvmContractInstanceHint.schema.array(),
237
237
  contractClasses: AvmContractClassHint.schema.array(),
238
+ bytecodeCommitments: AvmBytecodeCommitmentHint.schema.array(),
238
239
  publicDataReads: AvmPublicDataReadTreeHint.schema.array(),
239
240
  publicDataWrites: AvmPublicDataWriteTreeHint.schema.array(),
240
241
  nullifierReads: AvmNullifierReadTreeHint.schema.array(),
@@ -248,6 +249,7 @@ export class AvmExecutionHints {
248
249
  enqueuedCalls,
249
250
  contractInstances,
250
251
  contractClasses,
252
+ bytecodeCommitments,
251
253
  publicDataReads,
252
254
  publicDataWrites,
253
255
  nullifierReads,
@@ -260,6 +262,7 @@ export class AvmExecutionHints {
260
262
  enqueuedCalls,
261
263
  contractInstances,
262
264
  contractClasses,
265
+ bytecodeCommitments,
263
266
  publicDataReads,
264
267
  publicDataWrites,
265
268
  nullifierReads,
@@ -77,4 +77,8 @@ export class PublicDataWrite {
77
77
  isEmpty() {
78
78
  return this.leafSlot.isZero() && this.value.isZero();
79
79
  }
80
+
81
+ equals(other: PublicDataWrite): boolean {
82
+ return this.leafSlot.equals(other.leafSlot) && this.value.equals(other.value);
83
+ }
80
84
  }
package/src/block/body.ts CHANGED
@@ -18,6 +18,12 @@ export class Body {
18
18
  });
19
19
  }
20
20
 
21
+ equals(other: Body) {
22
+ return (
23
+ this.txEffects.length === other.txEffects.length && this.txEffects.every((te, i) => te.equals(other.txEffects[i]))
24
+ );
25
+ }
26
+
21
27
  static get schema(): ZodFor<Body> {
22
28
  return z
23
29
  .object({
@@ -6,3 +6,4 @@ export * from './body.js';
6
6
  export * from './l2_block_number.js';
7
7
  export * from './l2_block_source.js';
8
8
  export * from './block_hash.js';
9
+ export * from './published_l2_block.js';
@@ -202,4 +202,8 @@ export class L2Block {
202
202
  ...logsStats,
203
203
  };
204
204
  }
205
+
206
+ equals(other: L2Block) {
207
+ return this.archive.equals(other.archive) && this.header.equals(other.header) && this.body.equals(other.body);
208
+ }
205
209
  }
@@ -2,8 +2,8 @@ import { AbortError } from '@aztec/foundation/error';
2
2
  import { createLogger } from '@aztec/foundation/log';
3
3
  import { RunningPromise } from '@aztec/foundation/running-promise';
4
4
 
5
- import type { L2Block } from '../l2_block.js';
6
5
  import type { L2BlockId, L2BlockSource, L2Tips } from '../l2_block_source.js';
6
+ import type { PublishedL2Block } from '../published_l2_block.js';
7
7
 
8
8
  /** Creates a stream of events for new blocks, chain tips updates, and reorgs, out of polling an archiver or a node. */
9
9
  export class L2BlockStream {
@@ -11,7 +11,7 @@ export class L2BlockStream {
11
11
  private isSyncing = false;
12
12
 
13
13
  constructor(
14
- private l2BlockSource: Pick<L2BlockSource, 'getBlocks' | 'getBlockHeader' | 'getL2Tips'>,
14
+ private l2BlockSource: Pick<L2BlockSource, 'getPublishedBlocks' | 'getBlockHeader' | 'getL2Tips'>,
15
15
  private localData: L2BlockStreamLocalDataProvider,
16
16
  private handler: L2BlockStreamEventHandler,
17
17
  private readonly log = createLogger('types:block_stream'),
@@ -84,12 +84,12 @@ export class L2BlockStream {
84
84
  const from = latestBlockNumber + 1;
85
85
  const limit = Math.min(this.opts.batchSize ?? 20, sourceTips.latest.number - from + 1);
86
86
  this.log.trace(`Requesting blocks from ${from} limit ${limit} proven=${this.opts.proven}`);
87
- const blocks = await this.l2BlockSource.getBlocks(from, limit, this.opts.proven);
87
+ const blocks = await this.l2BlockSource.getPublishedBlocks(from, limit, this.opts.proven);
88
88
  if (blocks.length === 0) {
89
89
  break;
90
90
  }
91
91
  await this.emitEvent({ type: 'blocks-added', blocks });
92
- latestBlockNumber = blocks.at(-1)!.number;
92
+ latestBlockNumber = blocks.at(-1)!.block.number;
93
93
  }
94
94
 
95
95
  // Update the proven and finalized tips.
@@ -160,7 +160,7 @@ export type L2BlockStreamEvent =
160
160
  | {
161
161
  type: 'blocks-added';
162
162
  /** New blocks added to the chain. */
163
- blocks: L2Block[];
163
+ blocks: PublishedL2Block[];
164
164
  }
165
165
  | {
166
166
  type: 'chain-pruned';
@@ -10,6 +10,7 @@ import type { TxHash } from '../tx/tx_hash.js';
10
10
  import type { TxReceipt } from '../tx/tx_receipt.js';
11
11
  import type { InBlock } from './in_block.js';
12
12
  import type { L2Block } from './l2_block.js';
13
+ import type { PublishedL2Block } from './published_l2_block.js';
13
14
 
14
15
  /**
15
16
  * Interface of classes allowing for the retrieval of L2 blocks.
@@ -62,6 +63,9 @@ export interface L2BlockSource {
62
63
  */
63
64
  getBlocks(from: number, limit: number, proven?: boolean): Promise<L2Block[]>;
64
65
 
66
+ /** Equivalent to getBlocks but includes publish data. */
67
+ getPublishedBlocks(from: number, limit: number, proven?: boolean): Promise<PublishedL2Block[]>;
68
+
65
69
  /**
66
70
  * Gets a tx effect.
67
71
  * @param txHash - The hash of a transaction which resulted in the returned tx effect.
@@ -0,0 +1,45 @@
1
+ import { Buffer32 } from '@aztec/foundation/buffer';
2
+ import { times } from '@aztec/foundation/collection';
3
+ import { Secp256k1Signer } from '@aztec/foundation/crypto';
4
+ import { Signature } from '@aztec/foundation/eth-signature';
5
+ import { schemas } from '@aztec/foundation/schemas';
6
+ import { L2Block } from '@aztec/stdlib/block';
7
+
8
+ import { z } from 'zod';
9
+
10
+ export type L1PublishedData = {
11
+ blockNumber: bigint;
12
+ timestamp: bigint;
13
+ blockHash: string;
14
+ };
15
+
16
+ export type PublishedL2Block = {
17
+ block: L2Block;
18
+ l1: L1PublishedData;
19
+ signatures: Signature[];
20
+ };
21
+
22
+ export const PublishedL2BlockSchema = z.object({
23
+ block: L2Block.schema,
24
+ l1: z.object({
25
+ blockNumber: schemas.BigInt,
26
+ timestamp: schemas.BigInt,
27
+ blockHash: z.string(),
28
+ }),
29
+ signatures: z.array(Signature.schema),
30
+ });
31
+
32
+ export async function randomPublishedL2Block(l2BlockNumber: number): Promise<PublishedL2Block> {
33
+ const block = await L2Block.random(l2BlockNumber);
34
+ const l1 = {
35
+ blockNumber: BigInt(block.number),
36
+ timestamp: block.header.globalVariables.timestamp.toBigInt(),
37
+ blockHash: Buffer32.random().toString(),
38
+ };
39
+ // Create valid signatures
40
+ const signers = times(3, () => Secp256k1Signer.random());
41
+ const signatures = await Promise.all(
42
+ times(3, async i => signers[i].signMessage(Buffer32.fromField(await block.hash()))),
43
+ );
44
+ return { block, l1, signatures };
45
+ }
@@ -20,6 +20,8 @@ export async function getContractClassFromArtifact(
20
20
  ): Promise<ContractClassWithId & ContractClassIdPreimage> {
21
21
  const artifactHash = 'artifactHash' in artifact ? artifact.artifactHash : await computeArtifactHash(artifact);
22
22
  const publicFunctions = artifact.functions.filter(f => f.functionType === FunctionType.PUBLIC);
23
+ // TODO(#8985): ContractArtifact.functions should ensure that the below only contains the public dispatch function
24
+ // So we can likely remove this and just use the below to assign the dispatch.
23
25
  const artifactPublicFunctions: ContractClass['publicFunctions'] = await Promise.all(
24
26
  publicFunctions.map(async f => ({
25
27
  selector: await FunctionSelector.fromNameAndParameters(f.name, f.parameters),
@@ -2,7 +2,14 @@ import { Fr } from '@aztec/foundation/fields';
2
2
  import { BufferReader, numToUInt8, serializeToBuffer } from '@aztec/foundation/serialize';
3
3
  import type { FieldsOf } from '@aztec/foundation/types';
4
4
 
5
- import { type ContractArtifact, type FunctionArtifact, FunctionSelector, getDefaultInitializer } from '../abi/index.js';
5
+ import {
6
+ type ContractArtifact,
7
+ type FunctionAbi,
8
+ type FunctionArtifact,
9
+ FunctionSelector,
10
+ getAllFunctionAbis,
11
+ getDefaultInitializer,
12
+ } from '../abi/index.js';
6
13
  import { AztecAddress } from '../aztec-address/index.js';
7
14
  import { getContractClassFromArtifact } from '../contract/contract_class.js';
8
15
  import { PublicKeys } from '../keys/public_keys.js';
@@ -101,7 +108,7 @@ export class SerializableContractInstance {
101
108
  export async function getContractInstanceFromDeployParams(
102
109
  artifact: ContractArtifact,
103
110
  opts: {
104
- constructorArtifact?: FunctionArtifact | string;
111
+ constructorArtifact?: FunctionAbi | string;
105
112
  constructorArgs?: any[];
106
113
  skipArgsDecoding?: boolean;
107
114
  salt?: Fr;
@@ -138,14 +145,15 @@ export async function getContractInstanceFromDeployParams(
138
145
 
139
146
  function getConstructorArtifact(
140
147
  artifact: ContractArtifact,
141
- requestedConstructorArtifact: FunctionArtifact | string | undefined,
142
- ): FunctionArtifact | undefined {
148
+ requestedConstructorArtifact: FunctionArtifact | FunctionAbi | string | undefined,
149
+ ): FunctionAbi | undefined {
143
150
  if (typeof requestedConstructorArtifact === 'string') {
144
- const found = artifact.functions.find(fn => fn.name === requestedConstructorArtifact);
151
+ const found = getAllFunctionAbis(artifact).find(fn => fn.name === requestedConstructorArtifact);
145
152
  if (!found) {
146
153
  throw new Error(`No constructor found with name ${requestedConstructorArtifact}`);
147
154
  }
148
155
  return found;
149
156
  }
157
+ // TODO: shouldn't we check that requestedConstructorArtifact exists on artifact before returning?
150
158
  return requestedConstructorArtifact ?? getDefaultInitializer(artifact);
151
159
  }
@@ -2,18 +2,10 @@ import type { Fr } from '@aztec/foundation/fields';
2
2
 
3
3
  import { FunctionSelector } from '../../abi/index.js';
4
4
  import type { AztecAddress } from '../../aztec-address/index.js';
5
- import type { ContractClassPublic, PublicFunction } from './contract_class.js';
5
+ import type { ContractClassPublic } from './contract_class.js';
6
6
  import type { ContractInstanceWithAddress } from './contract_instance.js';
7
7
 
8
8
  export interface ContractDataSource {
9
- /**
10
- * Returns a contract's encoded public function, given its function selector.
11
- * @param address - The contract aztec address.
12
- * @param selector - The function's selector.
13
- * @returns The function's data.
14
- */
15
- getPublicFunction(address: AztecAddress, selector: FunctionSelector): Promise<PublicFunction | undefined>;
16
-
17
9
  /**
18
10
  * Gets the number of the latest L2 block processed by the implementation.
19
11
  * @returns The number of the latest L2 block processed by the implementation.
@@ -37,8 +29,9 @@ export interface ContractDataSource {
37
29
  /**
38
30
  * Returns a publicly deployed contract instance given its address.
39
31
  * @param address - Address of the deployed contract.
32
+ * @param blockNumber - Block number at which to retrieve the contract instance. If not provided, the latest block should be used.
40
33
  */
41
- getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined>;
34
+ getContract(address: AztecAddress, blockNumber?: number): Promise<ContractInstanceWithAddress | undefined>;
42
35
 
43
36
  /**
44
37
  * Returns the list of all class ids known.
@@ -148,7 +148,7 @@ export class DatabaseVersionManager<T> {
148
148
  }
149
149
  } else if (cmp !== 0) {
150
150
  this.log.info(
151
- `Can't upgrade from version ${storedVersion.schemaVersion} to ${this.currentVersion}. Resetting database at ${this.dataDirectory}`,
151
+ `Can't upgrade from version ${storedVersion.schemaVersion} to ${this.currentVersion.schemaVersion}. Resetting database at ${this.dataDirectory}`,
152
152
  );
153
153
  needsReset = true;
154
154
  }
@@ -6,11 +6,11 @@ import { inBlockSchemaFor } from '../block/in_block.js';
6
6
  import { L2Block } from '../block/l2_block.js';
7
7
  import { type L2BlockSource, L2TipsSchema } from '../block/l2_block_source.js';
8
8
  import type { NullifierWithBlockSource } from '../block/nullifier_with_block_source.js';
9
+ import { PublishedL2BlockSchema } from '../block/published_l2_block.js';
9
10
  import {
10
11
  ContractClassPublicSchema,
11
12
  type ContractDataSource,
12
13
  ContractInstanceWithAddressSchema,
13
- PublicFunctionSchema,
14
14
  } from '../contract/index.js';
15
15
  import { L1RollupConstantsSchema } from '../epoch-helpers/index.js';
16
16
  import { LogFilterSchema } from '../logs/log_filter.js';
@@ -44,6 +44,10 @@ export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
44
44
  .function()
45
45
  .args(schemas.Integer, schemas.Integer, optional(z.boolean()))
46
46
  .returns(z.array(L2Block.schema)),
47
+ getPublishedBlocks: z
48
+ .function()
49
+ .args(schemas.Integer, schemas.Integer, optional(z.boolean()))
50
+ .returns(z.array(PublishedL2BlockSchema)),
47
51
  getTxEffect: z.function().args(TxHash.schema).returns(inBlockSchemaFor(TxEffect.schema).optional()),
48
52
  getSettledTxReceipt: z.function().args(TxHash.schema).returns(TxReceipt.schema.optional()),
49
53
  getL2SlotNumber: z.function().args().returns(schemas.BigInt),
@@ -62,13 +66,12 @@ export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
62
66
  .returns(z.array(optional(inBlockSchemaFor(schemas.BigInt)))),
63
67
  getPublicLogs: z.function().args(LogFilterSchema).returns(GetPublicLogsResponseSchema),
64
68
  getContractClassLogs: z.function().args(LogFilterSchema).returns(GetContractClassLogsResponseSchema),
65
- getPublicFunction: z
66
- .function()
67
- .args(schemas.AztecAddress, schemas.FunctionSelector)
68
- .returns(PublicFunctionSchema.optional()),
69
69
  getContractClass: z.function().args(schemas.Fr).returns(ContractClassPublicSchema.optional()),
70
70
  getBytecodeCommitment: z.function().args(schemas.Fr).returns(schemas.Fr),
71
- getContract: z.function().args(schemas.AztecAddress).returns(ContractInstanceWithAddressSchema.optional()),
71
+ getContract: z
72
+ .function()
73
+ .args(schemas.AztecAddress, optional(schemas.Integer))
74
+ .returns(ContractInstanceWithAddressSchema.optional()),
72
75
  getContractClassIds: z.function().args().returns(z.array(schemas.Fr)),
73
76
  registerContractFunctionSignatures: z.function().args(schemas.AztecAddress, z.array(z.string())).returns(z.void()),
74
77
  getL1ToL2Messages: z.function().args(schemas.BigInt).returns(z.array(schemas.Fr)),
@@ -17,6 +17,7 @@ import { type InBlock, inBlockSchemaFor } from '../block/in_block.js';
17
17
  import { L2Block } from '../block/l2_block.js';
18
18
  import { type L2BlockNumber, L2BlockNumberSchema } from '../block/l2_block_number.js';
19
19
  import { type L2BlockSource, type L2Tips, L2TipsSchema } from '../block/l2_block_source.js';
20
+ import { PublishedL2BlockSchema } from '../block/published_l2_block.js';
20
21
  import {
21
22
  type ContractClassPublic,
22
23
  ContractClassPublicSchema,
@@ -63,7 +64,7 @@ import { type WorldStateSyncStatus, WorldStateSyncStatusSchema } from './world_s
63
64
  */
64
65
  export interface AztecNode
65
66
  extends ProverCoordination,
66
- Pick<L2BlockSource, 'getBlocks' | 'getBlockHeader' | 'getL2Tips'> {
67
+ Pick<L2BlockSource, 'getBlocks' | 'getPublishedBlocks' | 'getBlockHeader' | 'getL2Tips'> {
67
68
  /**
68
69
  * Returns the tips of the L2 chain.
69
70
  */
@@ -534,6 +535,8 @@ export const AztecNodeApiSchema: ApiSchemaFor<AztecNode> = {
534
535
 
535
536
  getBlocks: z.function().args(z.number(), z.number()).returns(z.array(L2Block.schema)),
536
537
 
538
+ getPublishedBlocks: z.function().args(z.number(), z.number()).returns(z.array(PublishedL2BlockSchema)),
539
+
537
540
  getCurrentBaseFees: z.function().returns(GasFees.schema),
538
541
 
539
542
  getNodeVersion: z.function().returns(z.string()),