@aztec/stdlib 0.82.3 → 0.83.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 (129) hide show
  1. package/dest/avm/avm.d.ts +3889 -382
  2. package/dest/avm/avm.d.ts.map +1 -1
  3. package/dest/avm/avm.js +64 -18
  4. package/dest/avm/avm_proving_request.d.ts +1610 -66
  5. package/dest/avm/avm_proving_request.d.ts.map +1 -1
  6. package/dest/block/l2_block_downloader/l2_block_stream.d.ts +9 -12
  7. package/dest/block/l2_block_downloader/l2_block_stream.d.ts.map +1 -1
  8. package/dest/block/l2_block_downloader/l2_block_stream.js +39 -11
  9. package/dest/config/config.d.ts +2 -2
  10. package/dest/config/config.d.ts.map +1 -1
  11. package/dest/config/config.js +4 -5
  12. package/dest/contract/interfaces/node-info.d.ts +2 -2
  13. package/dest/contract/interfaces/node-info.d.ts.map +1 -1
  14. package/dest/contract/interfaces/node-info.js +1 -1
  15. package/dest/interfaces/prover-client.d.ts +3 -3
  16. package/dest/interfaces/prover-client.d.ts.map +1 -1
  17. package/dest/interfaces/prover-client.js +6 -4
  18. package/dest/interfaces/proving-job.d.ts +1610 -66
  19. package/dest/interfaces/proving-job.d.ts.map +1 -1
  20. package/dest/interfaces/pxe.d.ts +7 -6
  21. package/dest/interfaces/pxe.d.ts.map +1 -1
  22. package/dest/interfaces/pxe.js +1 -1
  23. package/dest/keys/derivation.d.ts +1 -1
  24. package/dest/keys/derivation.d.ts.map +1 -1
  25. package/dest/keys/derivation.js +10 -2
  26. package/dest/logs/index.d.ts +2 -1
  27. package/dest/logs/index.d.ts.map +1 -1
  28. package/dest/logs/index.js +2 -1
  29. package/dest/logs/pending_tagged_log.d.ts +17 -0
  30. package/dest/logs/pending_tagged_log.d.ts.map +1 -0
  31. package/dest/logs/pending_tagged_log.js +45 -0
  32. package/dest/logs/{l1_payload/shared_secret_derivation.d.ts → shared_secret_derivation.d.ts} +4 -3
  33. package/dest/logs/shared_secret_derivation.d.ts.map +1 -0
  34. package/dest/logs/{l1_payload/shared_secret_derivation.js → shared_secret_derivation.js} +3 -5
  35. package/dest/logs/tx_scoped_l2_log.d.ts +6 -1
  36. package/dest/logs/tx_scoped_l2_log.d.ts.map +1 -1
  37. package/dest/logs/tx_scoped_l2_log.js +12 -4
  38. package/dest/note/note.d.ts +45 -4
  39. package/dest/note/note.d.ts.map +1 -1
  40. package/dest/note/note.js +51 -4
  41. package/dest/proofs/proof.d.ts.map +1 -1
  42. package/dest/proofs/proof.js +33 -7
  43. package/dest/snapshots/download.js +1 -1
  44. package/dest/snapshots/types.d.ts +4 -4
  45. package/dest/snapshots/types.d.ts.map +1 -1
  46. package/dest/snapshots/types.js +1 -1
  47. package/dest/snapshots/upload.d.ts +1 -1
  48. package/dest/snapshots/upload.d.ts.map +1 -1
  49. package/dest/snapshots/upload.js +1 -1
  50. package/dest/tests/factories.d.ts +10 -2
  51. package/dest/tests/factories.d.ts.map +1 -1
  52. package/dest/tests/factories.js +42 -6
  53. package/dest/tests/mocks.d.ts +2 -1
  54. package/dest/tests/mocks.d.ts.map +1 -1
  55. package/dest/tests/mocks.js +5 -1
  56. package/dest/trees/nullifier_leaf.d.ts +46 -21
  57. package/dest/trees/nullifier_leaf.d.ts.map +1 -1
  58. package/dest/trees/nullifier_leaf.js +48 -30
  59. package/dest/trees/nullifier_membership_witness.d.ts +28 -12
  60. package/dest/trees/nullifier_membership_witness.d.ts.map +1 -1
  61. package/dest/trees/protocol_contract_leaf.d.ts +0 -1
  62. package/dest/trees/protocol_contract_leaf.d.ts.map +1 -1
  63. package/dest/trees/protocol_contract_leaf.js +0 -3
  64. package/dest/trees/public_data_leaf.d.ts +46 -25
  65. package/dest/trees/public_data_leaf.d.ts.map +1 -1
  66. package/dest/trees/public_data_leaf.js +35 -30
  67. package/dest/trees/public_data_witness.d.ts +36 -18
  68. package/dest/trees/public_data_witness.d.ts.map +1 -1
  69. package/dest/trees/public_data_witness.js +6 -6
  70. package/dest/versioning/versioning.d.ts +1 -1
  71. package/dest/versioning/versioning.d.ts.map +1 -1
  72. package/dest/versioning/versioning.js +6 -6
  73. package/package.json +6 -7
  74. package/src/avm/avm.ts +74 -20
  75. package/src/block/l2_block_downloader/l2_block_stream.ts +58 -29
  76. package/src/config/config.ts +6 -6
  77. package/src/contract/interfaces/node-info.ts +3 -3
  78. package/src/interfaces/prover-client.ts +9 -7
  79. package/src/interfaces/pxe.ts +14 -7
  80. package/src/keys/derivation.ts +12 -6
  81. package/src/logs/index.ts +2 -1
  82. package/src/logs/pending_tagged_log.ts +43 -0
  83. package/src/logs/{l1_payload/shared_secret_derivation.ts → shared_secret_derivation.ts} +4 -11
  84. package/src/logs/tx_scoped_l2_log.ts +13 -4
  85. package/src/note/note.ts +61 -5
  86. package/src/proofs/proof.ts +39 -5
  87. package/src/snapshots/download.ts +1 -1
  88. package/src/snapshots/types.ts +2 -2
  89. package/src/snapshots/upload.ts +5 -3
  90. package/src/tests/factories.ts +72 -8
  91. package/src/tests/mocks.ts +7 -0
  92. package/src/trees/nullifier_leaf.ts +49 -26
  93. package/src/trees/protocol_contract_leaf.ts +0 -4
  94. package/src/trees/public_data_leaf.ts +31 -29
  95. package/src/trees/public_data_witness.ts +6 -6
  96. package/src/versioning/versioning.ts +8 -14
  97. package/dest/event/event.d.ts +0 -24
  98. package/dest/event/event.d.ts.map +0 -1
  99. package/dest/event/event.js +0 -13
  100. package/dest/event/event_metadata.d.ts +0 -38
  101. package/dest/event/event_metadata.d.ts.map +0 -1
  102. package/dest/event/event_metadata.js +0 -45
  103. package/dest/event/index.d.ts +0 -4
  104. package/dest/event/index.d.ts.map +0 -1
  105. package/dest/event/index.js +0 -3
  106. package/dest/event/l1_event_payload.d.ts +0 -52
  107. package/dest/event/l1_event_payload.d.ts.map +0 -1
  108. package/dest/event/l1_event_payload.js +0 -64
  109. package/dest/logs/l1_payload/encrypted_log_payload.d.ts +0 -50
  110. package/dest/logs/l1_payload/encrypted_log_payload.d.ts.map +0 -1
  111. package/dest/logs/l1_payload/encrypted_log_payload.js +0 -140
  112. package/dest/logs/l1_payload/encryption_util.d.ts +0 -24
  113. package/dest/logs/l1_payload/encryption_util.d.ts.map +0 -1
  114. package/dest/logs/l1_payload/encryption_util.js +0 -46
  115. package/dest/logs/l1_payload/index.d.ts +0 -3
  116. package/dest/logs/l1_payload/index.d.ts.map +0 -1
  117. package/dest/logs/l1_payload/index.js +0 -2
  118. package/dest/logs/l1_payload/payload.d.ts +0 -60
  119. package/dest/logs/l1_payload/payload.d.ts.map +0 -1
  120. package/dest/logs/l1_payload/payload.js +0 -61
  121. package/dest/logs/l1_payload/shared_secret_derivation.d.ts.map +0 -1
  122. package/src/event/event.ts +0 -16
  123. package/src/event/event_metadata.ts +0 -56
  124. package/src/event/index.ts +0 -3
  125. package/src/event/l1_event_payload.ts +0 -87
  126. package/src/logs/l1_payload/encrypted_log_payload.ts +0 -202
  127. package/src/logs/l1_payload/encryption_util.ts +0 -54
  128. package/src/logs/l1_payload/index.ts +0 -2
  129. package/src/logs/l1_payload/payload.ts +0 -73
@@ -1,8 +1,7 @@
1
1
  import { Grumpkin } from '@aztec/foundation/crypto';
2
2
  import type { GrumpkinScalar, Point } from '@aztec/foundation/fields';
3
3
 
4
- import type { AztecAddress } from '../../aztec-address/index.js';
5
- import type { PublicKey } from '../../keys/public_key.js';
4
+ import type { PublicKey } from '../keys/public_key.js';
6
5
 
7
6
  /**
8
7
  * Derive an Elliptic Curve Diffie-Hellman (ECDH) Shared Secret.
@@ -13,6 +12,9 @@ import type { PublicKey } from '../../keys/public_key.js';
13
12
  * @param publicKey - The public key used to derive shared secret.
14
13
  * @returns A derived shared secret.
15
14
  * @throws If the publicKey is zero.
15
+ *
16
+ * TODO(#12656): This function is kept around because of the getSharedSecret oracle. Nuke this once returning
17
+ * the app-siloed secret.
16
18
  */
17
19
  export async function deriveEcdhSharedSecret(secretKey: GrumpkinScalar, publicKey: PublicKey): Promise<Point> {
18
20
  if (publicKey.isZero()) {
@@ -24,12 +26,3 @@ export async function deriveEcdhSharedSecret(secretKey: GrumpkinScalar, publicKe
24
26
  const sharedSecret = await curve.mul(publicKey, secretKey);
25
27
  return sharedSecret;
26
28
  }
27
-
28
- export async function deriveEcdhSharedSecretUsingAztecAddress(
29
- secretKey: GrumpkinScalar,
30
- address: AztecAddress,
31
- ): Promise<Point> {
32
- const addressPoint = await address.toAddressPoint();
33
- const sharedSecret = await deriveEcdhSharedSecret(secretKey, addressPoint);
34
- return sharedSecret;
35
- }
@@ -17,6 +17,11 @@ export class TxScopedL2Log {
17
17
  * with the log so the noteHashIndex can be reconstructed after decryption.
18
18
  */
19
19
  public dataStartIndexForTx: number,
20
+ /*
21
+ * The index of the log in the transaction. Note that public and private logs are in separate arrays in the tx
22
+ * effect and for this reason these indices are independent (a private and public log can have the same index).
23
+ */
24
+ public logIndexInTx: number,
20
25
  /*
21
26
  * The block this log is included in
22
27
  */
@@ -36,12 +41,13 @@ export class TxScopedL2Log {
36
41
  .object({
37
42
  txHash: TxHash.schema,
38
43
  dataStartIndexForTx: z.number(),
44
+ logIndexInTx: z.number(),
39
45
  blockNumber: z.number(),
40
46
  log: z.union([PrivateLog.schema, PublicLog.schema]),
41
47
  })
42
48
  .transform(
43
- ({ txHash, dataStartIndexForTx, blockNumber, log }) =>
44
- new TxScopedL2Log(txHash, dataStartIndexForTx, blockNumber, log),
49
+ ({ txHash, dataStartIndexForTx, logIndexInTx, blockNumber, log }) =>
50
+ new TxScopedL2Log(txHash, dataStartIndexForTx, logIndexInTx, blockNumber, log),
45
51
  );
46
52
  }
47
53
 
@@ -50,6 +56,7 @@ export class TxScopedL2Log {
50
56
  return Buffer.concat([
51
57
  this.txHash.toBuffer(),
52
58
  numToUInt32BE(this.dataStartIndexForTx),
59
+ numToUInt32BE(this.logIndexInTx),
53
60
  numToUInt32BE(this.blockNumber),
54
61
  boolToBuffer(isFromPublic),
55
62
  this.log.toBuffer(),
@@ -60,23 +67,25 @@ export class TxScopedL2Log {
60
67
  const reader = BufferReader.asReader(buffer);
61
68
  const txHash = reader.readObject(TxHash);
62
69
  const dataStartIndexForTx = reader.readNumber();
70
+ const logIndexInTx = reader.readNumber();
63
71
  const blockNumber = reader.readNumber();
64
72
  const isFromPublic = reader.readBoolean();
65
73
  const log = isFromPublic ? PublicLog.fromBuffer(reader) : PrivateLog.fromBuffer(reader);
66
74
 
67
- return new TxScopedL2Log(txHash, dataStartIndexForTx, blockNumber, log);
75
+ return new TxScopedL2Log(txHash, dataStartIndexForTx, logIndexInTx, blockNumber, log);
68
76
  }
69
77
 
70
78
  static async random() {
71
79
  const isFromPublic = Math.random() < 0.5;
72
80
  const log = isFromPublic ? await PublicLog.random() : PrivateLog.random();
73
- return new TxScopedL2Log(TxHash.random(), 1, 1, log);
81
+ return new TxScopedL2Log(TxHash.random(), 1, 1, 1, log);
74
82
  }
75
83
 
76
84
  equals(other: TxScopedL2Log) {
77
85
  return (
78
86
  this.txHash.equals(other.txHash) &&
79
87
  this.dataStartIndexForTx === other.dataStartIndexForTx &&
88
+ this.logIndexInTx === other.logIndexInTx &&
80
89
  this.blockNumber === other.blockNumber &&
81
90
  ((this.log instanceof PublicLog && other.log instanceof PublicLog) ||
82
91
  (this.log instanceof PrivateLog && other.log instanceof PrivateLog)) &&
package/src/note/note.ts CHANGED
@@ -1,16 +1,72 @@
1
+ import { randomInt } from '@aztec/foundation/crypto';
1
2
  import { Fr } from '@aztec/foundation/fields';
2
- import { schemas } from '@aztec/foundation/schemas';
3
3
  import { BufferReader } from '@aztec/foundation/serialize';
4
+ import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
4
5
 
5
- import { Payload } from '../logs/l1_payload/payload.js';
6
+ import { schemas } from '../schemas/index.js';
7
+ import { Vector } from '../types/shared.js';
6
8
 
7
- export class Note extends Payload {
8
- static override get schema() {
9
+ /**
10
+ * The Note class represents a Note emitted from a Noir contract as a vector of Fr (finite field) elements.
11
+ * This data also represents a preimage to a note hash.
12
+ */
13
+ export class Note extends Vector<Fr> {
14
+ toJSON() {
15
+ return this.toBuffer();
16
+ }
17
+
18
+ static get schema() {
9
19
  return schemas.Buffer.transform(Note.fromBuffer);
10
20
  }
11
21
 
12
- static override fromBuffer(buffer: Buffer | BufferReader) {
22
+ /**
23
+ * Create a Note instance from a Buffer or BufferReader.
24
+ * The input 'buffer' can be either a Buffer containing the serialized Fr elements or a BufferReader instance.
25
+ * This function reads the Fr elements in the buffer and constructs a Note with them.
26
+ *
27
+ * @param buffer - The Buffer or BufferReader containing the serialized Fr elements.
28
+ * @returns A Note instance containing the deserialized Fr elements.
29
+ */
30
+ static fromBuffer(buffer: Buffer | BufferReader) {
13
31
  const reader = BufferReader.asReader(buffer);
14
32
  return new Note(reader.readVector(Fr));
15
33
  }
34
+
35
+ /**
36
+ * Generates a random Note instance with a variable number of items.
37
+ * The number of items is determined by a random value between 1 and 10 (inclusive).
38
+ * Each item in the Note is generated using the Fr.random() method.
39
+ *
40
+ * @returns A randomly generated Note instance.
41
+ */
42
+ static random() {
43
+ const numItems = randomInt(10) + 1;
44
+ const items = Array.from({ length: numItems }, () => Fr.random());
45
+ return new Note(items);
46
+ }
47
+
48
+ /**
49
+ * Returns a hex representation of the note.
50
+ * @returns A hex string with the vector length as first element.
51
+ */
52
+ override toString() {
53
+ return bufferToHex(this.toBuffer());
54
+ }
55
+
56
+ /**
57
+ * Creates a new Note instance from a hex string.
58
+ * @param str - Hex representation.
59
+ * @returns A Note instance.
60
+ */
61
+ static fromString(str: string) {
62
+ return Note.fromBuffer(hexToBuffer(str));
63
+ }
64
+
65
+ get length() {
66
+ return this.items.length;
67
+ }
68
+
69
+ equals(other: Note) {
70
+ return this.items.every((item, index) => item.equals(other.items[index]));
71
+ }
16
72
  }
@@ -3,6 +3,8 @@ import { Fr } from '@aztec/foundation/fields';
3
3
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
4
4
  import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
5
5
 
6
+ import { strict as assert } from 'assert';
7
+
6
8
  const EMPTY_PROOF_SIZE = 42;
7
9
 
8
10
  /**
@@ -17,6 +19,7 @@ export class Proof {
17
19
 
18
20
  // Honk proofs start with a 4 byte length prefix
19
21
  // the proof metadata starts immediately after
22
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/1312): Get rid of if possible.
20
23
  private readonly metadataOffset = 4;
21
24
 
22
25
  constructor(
@@ -62,19 +65,50 @@ export class Proof {
62
65
  }
63
66
 
64
67
  public withoutPublicInputs(): Buffer {
65
- return Buffer.concat([this.buffer.subarray(this.metadataOffset + Fr.SIZE_IN_BYTES * this.numPublicInputs)]);
68
+ if (this.isEmpty()) {
69
+ return this.buffer;
70
+ }
71
+ // We are indexing to this particular size because we are assuming the proof buffer looks like:
72
+ // [4 bytes of metadata for public inputs, binary public inputs, 4 bytes of metadata for proof, binary proof]
73
+ const proofStart = this.metadataOffset + Fr.SIZE_IN_BYTES * this.numPublicInputs + this.metadataOffset;
74
+ assert(this.buffer.length >= proofStart, 'Proof buffer is not appropriately sized to call withoutPublicInputs()');
75
+ return this.buffer.subarray(proofStart);
66
76
  }
67
77
 
78
+ // This function assumes that the proof will contain an aggregation object and look something like:
79
+ // [4 bytes of metadata for public inputs, binary public inputs, 4 bytes of metadata for proof, aggregation object, rest of proof]
80
+ // We are extracting the binary public inputs and reading them as Frs, and also extracting the aggregation object.
68
81
  public extractPublicInputs(): Fr[] {
82
+ if (this.isEmpty()) {
83
+ // return array of this.numPublicInputs 0s
84
+ return new Array(this.numPublicInputs).fill(Fr.zero());
85
+ }
86
+ assert(this.numPublicInputs >= AGGREGATION_OBJECT_LENGTH, 'Proof does not contain an aggregation object');
87
+ const numInnerPublicInputs = this.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
69
88
  const reader = BufferReader.asReader(
70
- this.buffer.subarray(this.metadataOffset, this.metadataOffset + Fr.SIZE_IN_BYTES * this.numPublicInputs),
89
+ this.buffer.subarray(this.metadataOffset, this.metadataOffset + Fr.SIZE_IN_BYTES * numInnerPublicInputs),
71
90
  );
72
- return reader.readArray(this.numPublicInputs, Fr);
91
+ let publicInputs = reader.readArray(numInnerPublicInputs, Fr);
92
+ // concatenate Fr[] with aggregation object
93
+ publicInputs = publicInputs.concat(this.extractAggregationObject());
94
+ return publicInputs;
73
95
  }
74
96
 
75
97
  public extractAggregationObject(): Fr[] {
76
- const publicInputs = this.extractPublicInputs();
77
- return publicInputs.slice(-1 * AGGREGATION_OBJECT_LENGTH);
98
+ if (this.isEmpty()) {
99
+ // return array of 16 0s
100
+ return new Array(16).fill(Fr.zero());
101
+ }
102
+ assert(this.numPublicInputs >= AGGREGATION_OBJECT_LENGTH, 'Proof does not contain an aggregation object');
103
+ const numInnerPublicInputs = this.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
104
+ // The aggregation object is currently stored after the initial inner public inputs and after the 4 byte proof metadata.
105
+ const reader = BufferReader.asReader(
106
+ this.buffer.subarray(
107
+ this.metadataOffset + Fr.SIZE_IN_BYTES * numInnerPublicInputs + this.metadataOffset,
108
+ this.metadataOffset + Fr.SIZE_IN_BYTES * this.numPublicInputs + this.metadataOffset,
109
+ ),
110
+ );
111
+ return reader.readArray(AGGREGATION_OBJECT_LENGTH, Fr);
78
112
  }
79
113
 
80
114
  /**
@@ -40,7 +40,7 @@ export async function getLatestSnapshotMetadata(
40
40
  }
41
41
 
42
42
  export function getBasePath(metadata: SnapshotsIndexMetadata): string {
43
- return `aztec-${metadata.l1ChainId}-${metadata.l2Version}-${metadata.rollupAddress}`;
43
+ return `aztec-${metadata.l1ChainId}-${metadata.rollupVersion}-${metadata.rollupAddress}`;
44
44
  }
45
45
 
46
46
  export function getSnapshotIndexPath(metadata: SnapshotsIndexMetadata): string {
@@ -27,7 +27,7 @@ export type SnapshotMetadata = {
27
27
 
28
28
  export type SnapshotsIndexMetadata = {
29
29
  l1ChainId: number;
30
- l2Version: number;
30
+ rollupVersion: number;
31
31
  rollupAddress: EthAddress;
32
32
  };
33
33
 
@@ -37,7 +37,7 @@ export type SnapshotsIndex = SnapshotsIndexMetadata & {
37
37
 
38
38
  export const SnapshotsIndexSchema = z.object({
39
39
  l1ChainId: z.number(),
40
- l2Version: z.number(),
40
+ rollupVersion: z.number(),
41
41
  rollupAddress: schemas.EthAddress,
42
42
  snapshots: z.array(
43
43
  z.object({
@@ -6,7 +6,7 @@ import { getBasePath, getSnapshotIndex, getSnapshotIndexPath } from './download.
6
6
  import type { SnapshotDataKeys, SnapshotMetadata, SnapshotsIndex } from './types.js';
7
7
 
8
8
  export type UploadSnapshotMetadata = Pick<SnapshotMetadata, 'l2BlockNumber' | 'l2BlockHash' | 'l1BlockNumber'> &
9
- Pick<SnapshotsIndex, 'l1ChainId' | 'l2Version' | 'rollupAddress'>;
9
+ Pick<SnapshotsIndex, 'l1ChainId' | 'rollupVersion' | 'rollupAddress'>;
10
10
 
11
11
  export async function uploadSnapshot(
12
12
  localPaths: Record<SnapshotDataKeys, string>,
@@ -45,9 +45,11 @@ export async function uploadSnapshot(
45
45
  return newSnapshotMetadata;
46
46
  }
47
47
 
48
- function createEmptyIndex(metadata: Pick<SnapshotsIndex, 'l1ChainId' | 'l2Version' | 'rollupAddress'>): SnapshotsIndex {
48
+ function createEmptyIndex(
49
+ metadata: Pick<SnapshotsIndex, 'l1ChainId' | 'rollupVersion' | 'rollupAddress'>,
50
+ ): SnapshotsIndex {
49
51
  return {
50
- ...pick(metadata, 'l1ChainId', 'l2Version', 'rollupAddress'),
52
+ ...pick(metadata, 'l1ChainId', 'rollupVersion', 'rollupAddress'),
51
53
  snapshots: [],
52
54
  };
53
55
  }
@@ -67,6 +67,8 @@ import {
67
67
  AvmGetLeafValueHint,
68
68
  AvmGetPreviousValueIndexHint,
69
69
  AvmGetSiblingPathHint,
70
+ AvmSequentialInsertHintNullifierTree,
71
+ AvmSequentialInsertHintPublicDataTree,
70
72
  RevertCode,
71
73
  } from '../avm/index.js';
72
74
  import { PublicDataHint } from '../avm/public_data_hint.js';
@@ -144,6 +146,7 @@ import { PublicTubeData } from '../rollup/public_tube_data.js';
144
146
  import { RootRollupInputs, RootRollupPublicInputs } from '../rollup/root_rollup.js';
145
147
  import { PrivateBaseStateDiffHints } from '../rollup/state_diff_hints.js';
146
148
  import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
149
+ import { MerkleTreeId } from '../trees/merkle_tree_id.js';
147
150
  import { NullifierLeaf, NullifierLeafPreimage } from '../trees/nullifier_leaf.js';
148
151
  import { PublicDataTreeLeaf, PublicDataTreeLeafPreimage } from '../trees/public_data_leaf.js';
149
152
  import { BlockHeader } from '../tx/block_header.js';
@@ -999,13 +1002,22 @@ export function makeNullifierLeaf(seed = 0): NullifierLeaf {
999
1002
  return new NullifierLeaf(new Fr(seed));
1000
1003
  }
1001
1004
 
1005
+ /**
1006
+ * Makes arbitrary nullifier leaf preimages.
1007
+ * @param seed - The seed to use for generating the nullifier leaf preimage.
1008
+ * @returns A nullifier leaf preimage.
1009
+ */
1010
+ export function makeNullifierLeafPreimage(seed = 0): NullifierLeafPreimage {
1011
+ return new NullifierLeafPreimage(makeNullifierLeaf(seed), new Fr(seed + 1), BigInt(seed + 2));
1012
+ }
1013
+
1002
1014
  /**
1003
1015
  * Makes arbitrary public data tree leaf preimages.
1004
1016
  * @param seed - The seed to use for generating the public data tree leaf preimage.
1005
1017
  * @returns A public data tree leaf preimage.
1006
1018
  */
1007
1019
  export function makePublicDataTreeLeafPreimage(seed = 0): PublicDataTreeLeafPreimage {
1008
- return new PublicDataTreeLeafPreimage(new Fr(seed), new Fr(seed + 1), new Fr(seed + 2), BigInt(seed + 3));
1020
+ return new PublicDataTreeLeafPreimage(makePublicDataTreeLeaf(seed), new Fr(seed + 2), BigInt(seed + 3));
1009
1021
  }
1010
1022
 
1011
1023
  /**
@@ -1016,7 +1028,7 @@ export function makePublicDataTreeLeafPreimage(seed = 0): PublicDataTreeLeafPrei
1016
1028
  export function makePrivateBaseStateDiffHints(seed = 1): PrivateBaseStateDiffHints {
1017
1029
  const nullifierPredecessorPreimages = makeTuple(
1018
1030
  MAX_NULLIFIERS_PER_TX,
1019
- x => new NullifierLeafPreimage(fr(x), fr(x + 0x100), BigInt(x + 0x200)),
1031
+ x => makeNullifierLeafPreimage(x),
1020
1032
  seed + 0x1000,
1021
1033
  );
1022
1034
 
@@ -1300,9 +1312,7 @@ export function makeAvmGetLeafPreimageHintPublicDataTree(seed = 0): AvmGetLeafPr
1300
1312
  return new AvmGetLeafPreimageHintPublicDataTree(
1301
1313
  makeAppendOnlyTreeSnapshot(seed),
1302
1314
  /*index=*/ index,
1303
- /*leaf=*/ makePublicDataTreeLeaf(seed + 3),
1304
- /*nextIndex=*/ index + 1n,
1305
- /*nextValue*/ new Fr(seed + 0x500),
1315
+ /*leafPreimage=*/ makePublicDataTreeLeafPreimage(seed + 3),
1306
1316
  );
1307
1317
  }
1308
1318
 
@@ -1312,9 +1322,7 @@ export function makeAvmGetLeafPreimageHintNullifierTree(seed = 0): AvmGetLeafPre
1312
1322
  return new AvmGetLeafPreimageHintNullifierTree(
1313
1323
  makeAppendOnlyTreeSnapshot(seed),
1314
1324
  /*index=*/ index,
1315
- /*leaf=*/ makeNullifierLeaf(seed + 3),
1316
- /*nextIndex=*/ index + 1n,
1317
- /*nextValue*/ new Fr(seed + 0x500),
1325
+ /*leafPreimage=*/ makeNullifierLeafPreimage(seed + 3),
1318
1326
  );
1319
1327
  }
1320
1328
 
@@ -1329,6 +1337,50 @@ export function makeAvmGetLeafValueHint(seed = 0): AvmGetLeafValueHint {
1329
1337
  );
1330
1338
  }
1331
1339
 
1340
+ export function makeAvmSequentialInsertHintPublicDataTree(seed = 0): AvmSequentialInsertHintPublicDataTree {
1341
+ const lowLeavesWitnessData = {
1342
+ leaf: makePublicDataTreeLeafPreimage(seed + 3),
1343
+ index: BigInt(seed + 4),
1344
+ path: makeArray(seed % 64, i => new Fr(i), seed + 5),
1345
+ };
1346
+ const insertionWitnessData = {
1347
+ leaf: makePublicDataTreeLeafPreimage(seed + 6),
1348
+ index: BigInt(seed + 7),
1349
+ path: makeArray(seed % 64, i => new Fr(i), seed + 8),
1350
+ };
1351
+
1352
+ return new AvmSequentialInsertHintPublicDataTree(
1353
+ makeAppendOnlyTreeSnapshot(seed),
1354
+ makeAppendOnlyTreeSnapshot(seed + 1),
1355
+ MerkleTreeId.PUBLIC_DATA_TREE,
1356
+ makePublicDataTreeLeaf(seed + 2),
1357
+ lowLeavesWitnessData,
1358
+ insertionWitnessData,
1359
+ );
1360
+ }
1361
+
1362
+ export function makeAvmSequentialInsertHintNullifierTree(seed = 0): AvmSequentialInsertHintNullifierTree {
1363
+ const lowLeavesWitnessData = {
1364
+ leaf: makeNullifierLeafPreimage(seed + 3),
1365
+ index: BigInt(seed + 4),
1366
+ path: makeArray(seed % 64, i => new Fr(i), seed + 5),
1367
+ };
1368
+ const insertionWitnessData = {
1369
+ leaf: makeNullifierLeafPreimage(seed + 6),
1370
+ index: BigInt(seed + 7),
1371
+ path: makeArray(seed % 64, i => new Fr(i), seed + 8),
1372
+ };
1373
+
1374
+ return new AvmSequentialInsertHintNullifierTree(
1375
+ makeAppendOnlyTreeSnapshot(seed),
1376
+ makeAppendOnlyTreeSnapshot(seed + 1),
1377
+ MerkleTreeId.NULLIFIER_TREE,
1378
+ makeNullifierLeaf(seed + 2),
1379
+ lowLeavesWitnessData,
1380
+ insertionWitnessData,
1381
+ );
1382
+ }
1383
+
1332
1384
  /**
1333
1385
  * Makes arbitrary AvmContractInstanceHint.
1334
1386
  * @param seed - The seed to use for generating the state reference.
@@ -1402,6 +1454,16 @@ export async function makeAvmExecutionHints(
1402
1454
  ),
1403
1455
  getLeafPreimageHintNullifierTree: makeArray(baseLength + 5, makeAvmGetLeafPreimageHintNullifierTree, seed + 0x5100),
1404
1456
  getLeafValueHints: makeArray(baseLength + 5, makeAvmGetLeafValueHint, seed + 0x5300),
1457
+ sequentialInsertHintsPublicDataTree: makeArray(
1458
+ baseLength + 5,
1459
+ makeAvmSequentialInsertHintPublicDataTree,
1460
+ seed + 0x5500,
1461
+ ),
1462
+ sequentialInsertHintsNullifierTree: makeArray(
1463
+ baseLength + 5,
1464
+ makeAvmSequentialInsertHintNullifierTree,
1465
+ seed + 0x5700,
1466
+ ),
1405
1467
  ...overrides,
1406
1468
  };
1407
1469
 
@@ -1415,6 +1477,8 @@ export async function makeAvmExecutionHints(
1415
1477
  fields.getLeafPreimageHintPublicDataTree,
1416
1478
  fields.getLeafPreimageHintNullifierTree,
1417
1479
  fields.getLeafValueHints,
1480
+ fields.sequentialInsertHintsPublicDataTree,
1481
+ fields.sequentialInsertHintsNullifierTree,
1418
1482
  );
1419
1483
  }
1420
1484
 
@@ -73,6 +73,7 @@ export const mockTx = async (
73
73
  {
74
74
  numberOfNonRevertiblePublicCallRequests = MAX_ENQUEUED_CALLS_PER_TX / 2,
75
75
  numberOfRevertiblePublicCallRequests = MAX_ENQUEUED_CALLS_PER_TX / 2,
76
+ numberOfRevertibleNullifiers = 0,
76
77
  hasPublicTeardownCallRequest = false,
77
78
  publicCalldataSize = 2,
78
79
  feePayer,
@@ -80,6 +81,7 @@ export const mockTx = async (
80
81
  }: {
81
82
  numberOfNonRevertiblePublicCallRequests?: number;
82
83
  numberOfRevertiblePublicCallRequests?: number;
84
+ numberOfRevertibleNullifiers?: number;
83
85
  hasPublicTeardownCallRequest?: boolean;
84
86
  publicCalldataSize?: number;
85
87
  feePayer?: AztecAddress;
@@ -123,6 +125,11 @@ export const mockTx = async (
123
125
  .withPublicCallRequests(publicCallRequests.slice(numberOfRevertiblePublicCallRequests))
124
126
  .build();
125
127
 
128
+ for (let i = 0; i < numberOfRevertibleNullifiers; i++) {
129
+ const revertibleNullifier = new Nullifier(new Fr(seed + 2 + i), 0, Fr.ZERO);
130
+ revertibleBuilder.pushNullifier(revertibleNullifier.value);
131
+ }
132
+
126
133
  data.forPublic.revertibleAccumulatedData = revertibleBuilder
127
134
  .withPublicCallRequests(publicCallRequests.slice(0, numberOfRevertiblePublicCallRequests))
128
135
  .build();
@@ -15,11 +15,11 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage {
15
15
  /**
16
16
  * Leaf value inside the indexed tree's linked list.
17
17
  */
18
- public nullifier: Fr,
18
+ public leaf: NullifierLeaf,
19
19
  /**
20
- * Next value inside the indexed tree's linked list.
20
+ * Next nullifier inside the indexed tree's linked list.
21
21
  */
22
- public nextNullifier: Fr,
22
+ public nextKey: Fr,
23
23
  /**
24
24
  * Index of the next leaf in the indexed tree's linked list.
25
25
  */
@@ -29,21 +29,23 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage {
29
29
  static get schema() {
30
30
  return z
31
31
  .object({
32
- nullifier: schemas.Fr,
33
- nextNullifier: schemas.Fr,
32
+ leaf: NullifierLeaf.schema,
33
+ nextKey: schemas.Fr,
34
34
  nextIndex: schemas.BigInt,
35
35
  })
36
- .transform(
37
- ({ nullifier, nextNullifier, nextIndex }) => new NullifierLeafPreimage(nullifier, nextNullifier, nextIndex),
38
- );
36
+ .transform(({ leaf, nextKey, nextIndex }) => new NullifierLeafPreimage(leaf, nextKey, nextIndex));
37
+ }
38
+
39
+ static get leafSchema() {
40
+ return NullifierLeaf.schema;
39
41
  }
40
42
 
41
43
  getKey(): bigint {
42
- return this.nullifier.toBigInt();
44
+ return this.leaf.getKey();
43
45
  }
44
46
 
45
47
  getNextKey(): bigint {
46
- return this.nextNullifier.toBigInt();
48
+ return this.nextKey.toBigInt();
47
49
  }
48
50
 
49
51
  getNextIndex(): bigint {
@@ -51,7 +53,7 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage {
51
53
  }
52
54
 
53
55
  asLeaf(): NullifierLeaf {
54
- return new NullifierLeaf(this.nullifier);
56
+ return this.leaf;
55
57
  }
56
58
 
57
59
  toBuffer(): Buffer {
@@ -60,8 +62,8 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage {
60
62
 
61
63
  toHashInputs(): Buffer[] {
62
64
  return [
63
- Buffer.from(this.nullifier.toBuffer()),
64
- Buffer.from(this.nextNullifier.toBuffer()),
65
+ ...this.leaf.toHashInputs(),
66
+ Buffer.from(this.nextKey.toBuffer()),
65
67
  Buffer.from(toBufferBE(this.nextIndex, 32)),
66
68
  ];
67
69
  }
@@ -71,28 +73,32 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage {
71
73
  }
72
74
 
73
75
  clone(): NullifierLeafPreimage {
74
- return new NullifierLeafPreimage(this.nullifier, this.nextNullifier, this.nextIndex);
76
+ return new NullifierLeafPreimage(this.leaf.clone(), this.nextKey, this.nextIndex);
75
77
  }
76
78
 
77
79
  static random() {
78
- return new NullifierLeafPreimage(Fr.random(), Fr.random(), BigInt(Math.floor(Math.random() * 1000)));
80
+ return new NullifierLeafPreimage(NullifierLeaf.random(), Fr.random(), BigInt(Math.floor(Math.random() * 1000)));
79
81
  }
80
82
 
81
83
  static empty(): NullifierLeafPreimage {
82
- return new NullifierLeafPreimage(Fr.ZERO, Fr.ZERO, 0n);
84
+ return new NullifierLeafPreimage(NullifierLeaf.empty(), Fr.zero(), 0n);
83
85
  }
84
86
 
85
87
  static fromBuffer(buffer: Buffer | BufferReader): NullifierLeafPreimage {
86
88
  const reader = BufferReader.asReader(buffer);
87
- return new NullifierLeafPreimage(reader.readObject(Fr), reader.readObject(Fr), toBigIntBE(reader.readBytes(32)));
89
+ return new NullifierLeafPreimage(
90
+ NullifierLeaf.fromBuffer(reader),
91
+ reader.readObject(Fr),
92
+ toBigIntBE(reader.readBytes(32)),
93
+ );
88
94
  }
89
95
 
90
96
  static fromLeaf(leaf: NullifierLeaf, nextKey: bigint, nextIndex: bigint): NullifierLeafPreimage {
91
- return new NullifierLeafPreimage(leaf.value, new Fr(nextKey), nextIndex);
97
+ return new NullifierLeafPreimage(leaf, new Fr(nextKey), nextIndex);
92
98
  }
93
99
 
94
100
  static clone(preimage: NullifierLeafPreimage): NullifierLeafPreimage {
95
- return new NullifierLeafPreimage(preimage.nullifier, preimage.nextNullifier, preimage.nextIndex);
101
+ return preimage.clone();
96
102
  }
97
103
  }
98
104
 
@@ -104,19 +110,35 @@ export class NullifierLeaf implements IndexedTreeLeaf {
104
110
  /**
105
111
  * Nullifier value.
106
112
  */
107
- public value: Fr,
113
+ public nullifier: Fr,
108
114
  ) {}
109
115
 
110
116
  getKey(): bigint {
111
- return this.value.toBigInt();
117
+ return this.nullifier.toBigInt();
112
118
  }
113
119
 
114
120
  toBuffer(): Buffer {
115
- return this.value.toBuffer();
121
+ return this.nullifier.toBuffer();
122
+ }
123
+
124
+ clone(): NullifierLeaf {
125
+ return new NullifierLeaf(new Fr(this.nullifier));
126
+ }
127
+
128
+ toHashInputs(): Buffer[] {
129
+ return [Buffer.from(this.nullifier.toBuffer())];
130
+ }
131
+
132
+ static empty(): NullifierLeaf {
133
+ return new NullifierLeaf(Fr.ZERO);
134
+ }
135
+
136
+ static random(): NullifierLeaf {
137
+ return new NullifierLeaf(Fr.random());
116
138
  }
117
139
 
118
140
  isEmpty(): boolean {
119
- return this.value.isZero();
141
+ return this.nullifier.isZero();
120
142
  }
121
143
 
122
144
  updateTo(_another: NullifierLeaf): NullifierLeaf {
@@ -127,11 +149,12 @@ export class NullifierLeaf implements IndexedTreeLeaf {
127
149
  return new NullifierLeaf(new Fr(key));
128
150
  }
129
151
 
130
- static fromBuffer(buf: Buffer): NullifierLeaf {
131
- return new NullifierLeaf(Fr.fromBuffer(buf));
152
+ static fromBuffer(buf: Buffer | BufferReader): NullifierLeaf {
153
+ const reader = BufferReader.asReader(buf);
154
+ return new NullifierLeaf(reader.readObject(Fr));
132
155
  }
133
156
 
134
157
  static get schema() {
135
- return z.object({ value: schemas.Fr }).transform(({ value }) => new NullifierLeaf(value));
158
+ return z.object({ nullifier: schemas.Fr }).transform(({ nullifier }) => new NullifierLeaf(nullifier));
136
159
  }
137
160
  }
@@ -89,10 +89,6 @@ export class ProtocolContractLeafPreimage implements IndexedTreeLeafPreimage {
89
89
  toBigIntBE(reader.readBytes(32)),
90
90
  );
91
91
  }
92
-
93
- static fromLeaf(leaf: ProtocolContractLeaf, nextKey: bigint, nextIndex: bigint): ProtocolContractLeafPreimage {
94
- return new ProtocolContractLeafPreimage(leaf.address, new Fr(nextKey), nextIndex);
95
- }
96
92
  }
97
93
 
98
94
  /**