@aztec/foundation 1.2.0 → 2.0.0-nightly.20250813

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 (64) hide show
  1. package/dest/array/array.d.ts +5 -0
  2. package/dest/array/array.d.ts.map +1 -1
  3. package/dest/array/array.js +11 -0
  4. package/dest/async-pool/index.d.ts.map +1 -1
  5. package/dest/async-pool/index.js +1 -0
  6. package/dest/collection/array.d.ts +2 -0
  7. package/dest/collection/array.d.ts.map +1 -1
  8. package/dest/collection/array.js +10 -0
  9. package/dest/collection/object.d.ts +2 -0
  10. package/dest/collection/object.d.ts.map +1 -1
  11. package/dest/collection/object.js +3 -0
  12. package/dest/config/env_var.d.ts +1 -1
  13. package/dest/config/env_var.d.ts.map +1 -1
  14. package/dest/crypto/secp256k1-signer/utils.d.ts.map +1 -1
  15. package/dest/fields/fields.d.ts.map +1 -1
  16. package/dest/fields/fields.js +0 -2
  17. package/dest/log/index.d.ts +1 -0
  18. package/dest/log/index.d.ts.map +1 -1
  19. package/dest/log/index.js +1 -0
  20. package/dest/log/pino-logger.d.ts +1 -0
  21. package/dest/log/pino-logger.d.ts.map +1 -1
  22. package/dest/log/pino-logger.js +4 -2
  23. package/dest/number/index.d.ts +3 -0
  24. package/dest/number/index.d.ts.map +1 -0
  25. package/dest/number/index.js +12 -0
  26. package/dest/promise/running-promise.d.ts.map +1 -1
  27. package/dest/promise/running-promise.js +0 -1
  28. package/dest/schemas/schemas.d.ts +1 -1
  29. package/dest/schemas/schemas.d.ts.map +1 -1
  30. package/dest/serialize/serialize.d.ts +1 -0
  31. package/dest/serialize/serialize.d.ts.map +1 -1
  32. package/dest/timer/timeout.d.ts +16 -6
  33. package/dest/timer/timeout.d.ts.map +1 -1
  34. package/dest/timer/timeout.js +34 -33
  35. package/dest/trees/merkle_tree_calculator.d.ts +10 -0
  36. package/dest/trees/merkle_tree_calculator.d.ts.map +1 -1
  37. package/dest/trees/merkle_tree_calculator.js +31 -1
  38. package/dest/trees/unbalanced_merkle_tree.d.ts +20 -6
  39. package/dest/trees/unbalanced_merkle_tree.d.ts.map +1 -1
  40. package/dest/trees/unbalanced_merkle_tree.js +50 -51
  41. package/dest/trees/unbalanced_merkle_tree_calculator.d.ts +3 -1
  42. package/dest/trees/unbalanced_merkle_tree_calculator.d.ts.map +1 -1
  43. package/dest/trees/unbalanced_merkle_tree_calculator.js +16 -6
  44. package/dest/types/index.d.ts +2 -0
  45. package/dest/types/index.d.ts.map +1 -1
  46. package/package.json +5 -4
  47. package/src/array/array.ts +13 -0
  48. package/src/async-pool/index.ts +1 -0
  49. package/src/collection/array.ts +12 -0
  50. package/src/collection/object.ts +5 -0
  51. package/src/config/env_var.ts +33 -4
  52. package/src/crypto/secp256k1-signer/utils.ts +0 -1
  53. package/src/fields/fields.ts +0 -2
  54. package/src/log/index.ts +1 -0
  55. package/src/log/pino-logger.ts +5 -0
  56. package/src/number/index.ts +14 -0
  57. package/src/promise/running-promise.ts +0 -1
  58. package/src/schemas/schemas.ts +1 -1
  59. package/src/serialize/serialize.ts +2 -0
  60. package/src/timer/timeout.ts +33 -30
  61. package/src/trees/merkle_tree_calculator.ts +34 -1
  62. package/src/trees/unbalanced_merkle_tree.ts +51 -43
  63. package/src/trees/unbalanced_merkle_tree_calculator.ts +22 -8
  64. package/src/types/index.ts +2 -0
@@ -1,13 +1,27 @@
1
1
  import { sha256Trunc } from '../crypto/sha256/index.js';
2
2
  /**
3
- * Computes the merkle root for an unbalanced tree.
3
+ * Computes the Merkle root of an unbalanced tree.
4
4
  *
5
- * @dev Adapted from unbalanced_tree.ts.
6
- * Calculates the tree upwards layer by layer until we reach the root.
7
- * The L1 calculation instead computes the tree from right to left (slightly cheaper gas).
8
- * TODO: A more thorough investigation of which method is cheaper, then use that method everywhere.
5
+ * Unlike a balanced Merkle tree, which requires the number of leaves to be a power of two, an unbalanced tree can have
6
+ * any number of leaves.
7
+ *
8
+ * The tree is constructed by iteratively extracting the smallest power-of-two-sized subtrees from **right to left**.
9
+ * For each such subtree, it computes the subtree root and then combines all subtree roots (again from right to left)
10
+ * into a single root using the provided hash function.
11
+ *
12
+ * Note: We need the final tree to be as shallow as possible, to minimize the size of the sibling path required to prove
13
+ * membership of a leaf. Therefor, the computation proceeds from right to left - smaller subtrees must always be
14
+ * combined before being merged with a larger sibling on their left.
15
+ *
16
+ * For example, consider an unbalanced tree made of three subtrees of sizes 2, 4, and 8. If we combine the size-2 and
17
+ * size-4 subtrees first (producing a subtree of depth 3), and then merge it with the size-8 subtree (also depth 3), the
18
+ * resulting tree has a maximum depth of 4.
19
+ *
20
+ * But if we instead combine the size-4 and size-8 subtrees first (depth 4), and then merge with the size-2 subtree
21
+ * (depth 1), the final tree has a depth of 5.
9
22
  */
10
- export declare function computeUnbalancedMerkleRoot(leaves: Buffer[], emptyLeaf?: Buffer, hasher?: typeof sha256Trunc): Buffer;
23
+ export declare function computeUnbalancedMerkleTreeRoot(leaves: Buffer[], hasher?: typeof sha256Trunc): Buffer;
24
+ export declare function getMaxUnbalancedTreeDepth(numLeaves: number): number;
11
25
  export declare function findLeafLevelAndIndex(numLeaves: number, leafIndex: number): {
12
26
  level: number;
13
27
  indexAtLevel: number;
@@ -1 +1 @@
1
- {"version":3,"file":"unbalanced_merkle_tree.d.ts","sourceRoot":"","sources":["../../src/trees/unbalanced_merkle_tree.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,qBAAc,GAAG,MAAM,CAwC9G;AAgDD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;WAhC9D,MAAM;kBAAgB,MAAM;EAmCvC"}
1
+ {"version":3,"file":"unbalanced_merkle_tree.d.ts","sourceRoot":"","sources":["../../src/trees/unbalanced_merkle_tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,qBAAc,GAAG,MAAM,CA6B9F;AAYD,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,UAE1D;AAwCD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;WAhC9D,MAAM;kBAAgB,MAAM;EAmCvC"}
@@ -1,64 +1,63 @@
1
- import { padArrayEnd } from '../collection/array.js';
2
1
  import { sha256Trunc } from '../crypto/sha256/index.js';
2
+ import { MerkleTreeCalculator } from './merkle_tree_calculator.js';
3
3
  /**
4
- * Computes the merkle root for an unbalanced tree.
4
+ * Computes the Merkle root of an unbalanced tree.
5
5
  *
6
- * @dev Adapted from unbalanced_tree.ts.
7
- * Calculates the tree upwards layer by layer until we reach the root.
8
- * The L1 calculation instead computes the tree from right to left (slightly cheaper gas).
9
- * TODO: A more thorough investigation of which method is cheaper, then use that method everywhere.
10
- */ export function computeUnbalancedMerkleRoot(leaves, emptyLeaf, hasher = sha256Trunc) {
11
- // Pad leaves to 2
12
- if (leaves.length < 2) {
13
- if (emptyLeaf === undefined) {
14
- throw new Error('Cannot compute a Merkle root with less than 2 leaves');
15
- } else {
16
- leaves = padArrayEnd(leaves, emptyLeaf, 2);
17
- }
6
+ * Unlike a balanced Merkle tree, which requires the number of leaves to be a power of two, an unbalanced tree can have
7
+ * any number of leaves.
8
+ *
9
+ * The tree is constructed by iteratively extracting the smallest power-of-two-sized subtrees from **right to left**.
10
+ * For each such subtree, it computes the subtree root and then combines all subtree roots (again from right to left)
11
+ * into a single root using the provided hash function.
12
+ *
13
+ * Note: We need the final tree to be as shallow as possible, to minimize the size of the sibling path required to prove
14
+ * membership of a leaf. Therefor, the computation proceeds from right to left - smaller subtrees must always be
15
+ * combined before being merged with a larger sibling on their left.
16
+ *
17
+ * For example, consider an unbalanced tree made of three subtrees of sizes 2, 4, and 8. If we combine the size-2 and
18
+ * size-4 subtrees first (producing a subtree of depth 3), and then merge it with the size-8 subtree (also depth 3), the
19
+ * resulting tree has a maximum depth of 4.
20
+ *
21
+ * But if we instead combine the size-4 and size-8 subtrees first (depth 4), and then merge with the size-2 subtree
22
+ * (depth 1), the final tree has a depth of 5.
23
+ */ export function computeUnbalancedMerkleTreeRoot(leaves, hasher = sha256Trunc) {
24
+ if (!leaves.length) {
25
+ throw new Error('Cannot compute a Merkle root with no leaves');
18
26
  }
19
- const depth = Math.ceil(Math.log2(leaves.length));
20
- let [layerWidth, nodeToShift] = leaves.length & 1 ? [
21
- leaves.length - 1,
22
- leaves[leaves.length - 1]
23
- ] : [
24
- leaves.length,
25
- Buffer.alloc(0)
26
- ];
27
- // Allocate this layer's leaves and init the next layer up
28
- let thisLayer = leaves.slice(0, layerWidth);
29
- let nextLayer = [];
30
- for(let i = 0; i < depth; i++){
31
- for(let j = 0; j < layerWidth; j += 2){
32
- // Store the hash of each pair one layer up
33
- nextLayer[j / 2] = hasher(Buffer.concat([
34
- thisLayer[j],
35
- thisLayer[j + 1]
36
- ]));
37
- }
38
- layerWidth /= 2;
39
- if (layerWidth & 1) {
40
- if (nodeToShift.length) {
41
- // If the next layer has odd length, and we have a node that needs to be shifted up, add it here
42
- nextLayer.push(nodeToShift);
43
- layerWidth += 1;
44
- nodeToShift = Buffer.alloc(0);
27
+ if (leaves.length === 1) {
28
+ return leaves[0];
29
+ }
30
+ let numRemainingLeaves = leaves.length;
31
+ let subtreeSize = 1;
32
+ let root;
33
+ while(numRemainingLeaves > 1){
34
+ if ((numRemainingLeaves & subtreeSize) !== 0) {
35
+ const subtreeLeaves = leaves.slice(numRemainingLeaves - subtreeSize, numRemainingLeaves);
36
+ const subtreeRoot = MerkleTreeCalculator.computeTreeRootSync(subtreeLeaves, hasher);
37
+ if (!root) {
38
+ root = subtreeRoot;
45
39
  } else {
46
- // If we don't have a node waiting to be shifted, store the next layer's final node to be shifted
47
- layerWidth -= 1;
48
- nodeToShift = nextLayer[layerWidth];
40
+ root = hasher(Buffer.concat([
41
+ subtreeRoot,
42
+ root
43
+ ]));
49
44
  }
45
+ numRemainingLeaves -= subtreeSize;
50
46
  }
51
- // reset the layers
52
- thisLayer = nextLayer;
53
- nextLayer = [];
47
+ subtreeSize *= 2;
54
48
  }
55
- // return the root
56
- return thisLayer[0];
49
+ return root;
57
50
  }
58
- function getMaxBalancedTreeDepth(numLeaves) {
51
+ /// Get the depth of the maximum balanced tree that can be created with the given number of leaves. The subtree will be
52
+ /// the left most subtree of the wonky tree with a total of `numLeaves` leaves.
53
+ ///
54
+ /// Note: All the leaves may not be used to form the tree. For example, if there are 5 leaves, the maximum depth is 2,
55
+ /// only 4 leaves are used to form a balanced tree.
56
+ function getMaxBalancedSubtreeDepth(numLeaves) {
59
57
  return Math.floor(Math.log2(numLeaves));
60
58
  }
61
- function getMaxUnbalancedTreeDepth(numLeaves) {
59
+ /// Get the maximum depth of an unbalanced tree that can be created with the given number of leaves.
60
+ export function getMaxUnbalancedTreeDepth(numLeaves) {
62
61
  return Math.ceil(Math.log2(numLeaves));
63
62
  }
64
63
  function findPosition(rootLevel, leafLevel, numLeaves, indexOffset, targetIndex) {
@@ -70,7 +69,7 @@ function findPosition(rootLevel, leafLevel, numLeaves, indexOffset, targetIndex)
70
69
  };
71
70
  }
72
71
  // The largest balanced tree that can be created with the given number of leaves.
73
- const maxBalancedTreeDepth = getMaxBalancedTreeDepth(numLeaves);
72
+ const maxBalancedTreeDepth = getMaxBalancedSubtreeDepth(numLeaves);
74
73
  const numBalancedLeaves = 2 ** maxBalancedTreeDepth;
75
74
  const numRemainingLeaves = numLeaves - numBalancedLeaves;
76
75
  if (targetIndex < numBalancedLeaves) {
@@ -1,9 +1,11 @@
1
+ import { type Bufferable } from '@aztec/foundation/serialize';
1
2
  import type { AsyncHasher } from '@aztec/foundation/trees';
2
3
  import { SiblingPath } from '@aztec/foundation/trees';
3
4
  /**
4
5
  * An ephemeral unbalanced Merkle tree implementation.
5
6
  * Follows the rollup implementation which greedily hashes pairs of nodes up the tree.
6
7
  * Remaining rightmost nodes are shifted up until they can be paired.
8
+ * If there is only one leaf, the root is the leaf.
7
9
  */
8
10
  export declare class UnbalancedMerkleTreeCalculator {
9
11
  private maxDepth;
@@ -25,7 +27,7 @@ export declare class UnbalancedMerkleTreeCalculator {
25
27
  * @returns A sibling path for the element.
26
28
  * Note: The sibling path is an array of sibling hashes, with the lowest hash (leaf hash) first, and the highest hash last.
27
29
  */
28
- getSiblingPath<N extends number>(value: bigint): Promise<SiblingPath<N>>;
30
+ getSiblingPath<N extends number>(value: Bufferable): Promise<SiblingPath<N>>;
29
31
  /**
30
32
  * Appends the given leaves to the tree.
31
33
  * @param leaves - The leaves to append.
@@ -1 +1 @@
1
- {"version":3,"file":"unbalanced_merkle_tree_calculator.d.ts","sourceRoot":"","sources":["../../src/trees/unbalanced_merkle_tree_calculator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD;;;;GAIG;AACH,qBAAa,8BAA8B;IAUvC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IAThB,OAAO,CAAC,KAAK,CAAiC;IAE9C,OAAO,CAAC,UAAU,CAAiC;IACnD,SAAS,CAAC,IAAI,EAAE,MAAM,CAAM;IAE5B,IAAI,EAAE,MAAM,CAAoB;gBAGtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;IAGrC,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,MAAM,EACd,MAAM,IAAU,MAAM,MAAM,EAAE,OAAO,MAAM,iCAC4B;IAKzE;;;OAGG;IACI,OAAO,IAAI,MAAM;IAIxB;;;;;OAKG;IACI,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAgB/E;;;;OAIG;IACU,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAU1D;;;;OAIG;YACW,WAAW;IAyCzB,OAAO,CAAC,SAAS;CAKlB"}
1
+ {"version":3,"file":"unbalanced_merkle_tree_calculator.d.ts","sourceRoot":"","sources":["../../src/trees/unbalanced_merkle_tree_calculator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD;;;;;GAKG;AACH,qBAAa,8BAA8B;IAUvC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IAThB,OAAO,CAAC,KAAK,CAAiC;IAE9C,OAAO,CAAC,UAAU,CAAiC;IACnD,SAAS,CAAC,IAAI,EAAE,MAAM,CAAM;IAE5B,IAAI,EAAE,MAAM,CAAoB;gBAGtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;IAGrC,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,MAAM,EACd,MAAM,IAAI,MAAM,MAAM,EAAE,OAAO,MAAM,iCAC8C;IAKrF;;;OAGG;IACI,OAAO,IAAI,MAAM;IAIxB;;;;;OAKG;IACI,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAoBnF;;;;OAIG;IACU,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB1D;;;;OAIG;YACW,WAAW;IAyCzB,OAAO,CAAC,SAAS;CAKlB"}
@@ -1,11 +1,12 @@
1
1
  import { serializeToBuffer } from '@aztec/foundation/serialize';
2
2
  import { SiblingPath } from '@aztec/foundation/trees';
3
- import { pedersenHash } from '../crypto/pedersen/index.js';
3
+ import { sha256Trunc } from '../crypto/index.js';
4
4
  const indexToKeyHash = (level, index)=>`${level}:${index}`;
5
5
  /**
6
6
  * An ephemeral unbalanced Merkle tree implementation.
7
7
  * Follows the rollup implementation which greedily hashes pairs of nodes up the tree.
8
8
  * Remaining rightmost nodes are shifted up until they can be paired.
9
+ * If there is only one leaf, the root is the leaf.
9
10
  */ export class UnbalancedMerkleTreeCalculator {
10
11
  maxDepth;
11
12
  hasher;
@@ -23,10 +24,10 @@ const indexToKeyHash = (level, index)=>`${level}:${index}`;
23
24
  this.size = 0n;
24
25
  this.root = Buffer.alloc(32);
25
26
  }
26
- static create(height, hasher = async (left, right)=>(await pedersenHash([
27
+ static create(height, hasher = (left, right)=>Promise.resolve(sha256Trunc(Buffer.concat([
27
28
  left,
28
29
  right
29
- ])).toBuffer()) {
30
+ ])))) {
30
31
  return new UnbalancedMerkleTreeCalculator(height, hasher);
31
32
  }
32
33
  /**
@@ -41,6 +42,9 @@ const indexToKeyHash = (level, index)=>`${level}:${index}`;
41
42
  * @returns A sibling path for the element.
42
43
  * Note: The sibling path is an array of sibling hashes, with the lowest hash (leaf hash) first, and the highest hash last.
43
44
  */ getSiblingPath(value) {
45
+ if (this.size === 1n) {
46
+ return Promise.resolve(new SiblingPath(0, []));
47
+ }
44
48
  const path = [];
45
49
  const [depth, _index] = this.valueCache[serializeToBuffer(value).toString('hex')].split(':');
46
50
  let level = parseInt(depth, 10);
@@ -63,8 +67,15 @@ const indexToKeyHash = (level, index)=>`${level}:${index}`;
63
67
  if (this.size != BigInt(0)) {
64
68
  throw Error(`Can't re-append to an unbalanced tree. Current has ${this.size} leaves.`);
65
69
  }
66
- const root = await this.batchInsert(leaves);
67
- this.root = root;
70
+ if (leaves.length === 0) {
71
+ throw Error(`Can't append 0 leaves to an unbalanced tree.`);
72
+ }
73
+ if (leaves.length === 1) {
74
+ this.root = leaves[0];
75
+ } else {
76
+ this.root = await this.batchInsert(leaves);
77
+ }
78
+ this.size = BigInt(leaves.length);
68
79
  return Promise.resolve();
69
80
  }
70
81
  /**
@@ -110,7 +121,6 @@ const indexToKeyHash = (level, index)=>`${level}:${index}`;
110
121
  thisLayer = nextLayer;
111
122
  nextLayer = [];
112
123
  }
113
- this.size += BigInt(_leaves.length);
114
124
  // return the root
115
125
  return thisLayer[0];
116
126
  }
@@ -28,9 +28,11 @@ export declare function unfreeze<T>(obj: T): Writeable<T>;
28
28
  export interface TypedEventEmitter<TEventMap extends {
29
29
  [key in keyof TEventMap]: (...args: any[]) => void;
30
30
  }> {
31
+ once<K extends keyof TEventMap>(event: K, listener: TEventMap[K]): this;
31
32
  on<K extends keyof TEventMap>(event: K, listener: TEventMap[K]): this;
32
33
  off<K extends keyof TEventMap>(event: K, listener: TEventMap[K]): this;
33
34
  emit<K extends keyof TEventMap>(event: K, ...args: Parameters<TEventMap[K]>): boolean;
34
35
  removeListener<K extends keyof TEventMap>(event: K, listener: TEventMap[K]): this;
36
+ removeAllListeners<K extends keyof TEventMap>(event: K): this;
35
37
  }
36
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,kCAAkC;AAClC,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,uDAAuD;AACvD,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE/E,6CAA6C;AAC7C,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;IAAE,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAE9D,gDAAgD;AAChD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAEhD;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB,CAAC,SAAS,SAAS;KAAG,GAAG,IAAI,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;CAAE;IACzG,EAAE,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACtE,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACvE,IAAI,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IACtF,cAAc,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAEnF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,kCAAkC;AAClC,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,uDAAuD;AACvD,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE/E,6CAA6C;AAC7C,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;IAAE,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAE9D,gDAAgD;AAChD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAEhD;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB,CAAC,SAAS,SAAS;KAAG,GAAG,IAAI,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;CAAE;IACzG,IAAI,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACxE,EAAE,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACtE,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACvE,IAAI,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IACtF,cAAc,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAClF,kBAAkB,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CAE/D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/foundation",
3
- "version": "1.2.0",
3
+ "version": "2.0.0-nightly.20250813",
4
4
  "type": "module",
5
5
  "main": "./dest/index.js",
6
6
  "types": "./dest/index.d.ts",
@@ -51,7 +51,8 @@
51
51
  "./validation": "./dest/validation/index.js",
52
52
  "./promise": "./dest/promise/index.js",
53
53
  "./string": "./dest/string/index.js",
54
- "./message": "./dest/message/index.js"
54
+ "./message": "./dest/message/index.js",
55
+ "./number": "./dest/number/index.js"
55
56
  },
56
57
  "scripts": {
57
58
  "build": "yarn clean && tsc -b",
@@ -101,9 +102,9 @@
101
102
  "testEnvironment": "../../foundation/src/jest/env.mjs"
102
103
  },
103
104
  "dependencies": {
104
- "@aztec/bb.js": "1.2.0",
105
+ "@aztec/bb.js": "2.0.0-nightly.20250813",
105
106
  "@koa/cors": "^5.0.0",
106
- "@noble/curves": "^1.2.0",
107
+ "@noble/curves": "=1.7.0",
107
108
  "bn.js": "^5.2.1",
108
109
  "colorette": "^2.0.20",
109
110
  "detect-node": "^2.1.0",
@@ -148,3 +148,16 @@ export function assertRightPadded<T>(arr: T[], isEmpty: (item: T) => boolean) {
148
148
  }
149
149
  }
150
150
  }
151
+
152
+ /**
153
+ * Shuffles an array in-place using the Fisher-Yates algorith,
154
+ * @param arr - The array to shuffle
155
+ */
156
+ export function shuffle<T>(arr: T[]): void {
157
+ for (let i = arr.length - 1; i > 0; i--) {
158
+ const j = (Math.random() * (i + 1)) | 0;
159
+ const temp = arr[i];
160
+ arr[i] = arr[j];
161
+ arr[j] = temp;
162
+ }
163
+ }
@@ -29,6 +29,7 @@
29
29
  export function asyncPool<T, R>(poolLimit: number, iterable: T[], iteratorFn: (item: T, iterable: T[]) => Promise<R>) {
30
30
  let i = 0;
31
31
  const ret: Promise<R>[] = [];
32
+ // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
32
33
  const executing: Set<Promise<R>> = new Set();
33
34
  const enqueue = (): Promise<any> => {
34
35
  if (i === iterable.length) {
@@ -214,3 +214,15 @@ export function countWhile<T>(collection: T[], predicate: (x: T) => boolean): nu
214
214
  }
215
215
  return count;
216
216
  }
217
+
218
+ /** Splits the given iterable into chunks of the given size. Last chunk may be of smaller than the requested size. */
219
+ export function chunk<T>(items: T[], chunkSize: number): T[][] {
220
+ if (chunkSize <= 0) {
221
+ throw new Error('Chunk size must be greater than 0');
222
+ }
223
+ const chunks: T[][] = [];
224
+ for (let i = 0; i < items.length; i += chunkSize) {
225
+ chunks.push(items.slice(i, i + chunkSize));
226
+ }
227
+ return chunks;
228
+ }
@@ -51,6 +51,11 @@ export function omit<T extends object>(object: T, ...props: string[]): Partial<T
51
51
  return obj;
52
52
  }
53
53
 
54
+ /** Equivalent to Object.keys but preserves types. */
55
+ export function getKeys<T extends object>(obj: T): (keyof T)[] {
56
+ return Object.keys(obj) as (keyof T)[];
57
+ }
58
+
54
59
  /** Equivalent to Object.entries but preserves types. */
55
60
  export function getEntries<T extends Record<PropertyKey, unknown>>(obj: T): { [K in keyof T]: [K, T[K]] }[keyof T][] {
56
61
  // See https://stackoverflow.com/a/76176570
@@ -84,7 +84,6 @@ export type EnvVar =
84
84
  | 'LOG_MULTILINE'
85
85
  | 'LOG_LEVEL'
86
86
  | 'MNEMONIC'
87
- | 'NETWORK_NAME'
88
87
  | 'NETWORK'
89
88
  | 'NO_PXE'
90
89
  | 'COIN_ISSUER_CONTRACT_ADDRESS'
@@ -105,6 +104,7 @@ export type EnvVar =
105
104
  | 'P2P_BOOTSTRAP_NODE_ENR_VERSION_CHECK'
106
105
  | 'P2P_BOOTSTRAP_NODES_AS_FULL_PEERS'
107
106
  | 'P2P_ENABLED'
107
+ | 'P2P_DISCOVERY_DISABLED'
108
108
  | 'P2P_GOSSIPSUB_D'
109
109
  | 'P2P_GOSSIPSUB_DHI'
110
110
  | 'P2P_GOSSIPSUB_DLO'
@@ -126,6 +126,8 @@ export type EnvVar =
126
126
  | 'P2P_REQRESP_DIAL_TIMEOUT_MS'
127
127
  | 'P2P_REQRESP_OVERALL_REQUEST_TIMEOUT_MS'
128
128
  | 'P2P_DISABLE_STATUS_HANDSHAKE'
129
+ | 'P2P_ALLOW_ONLY_VALIDATORS'
130
+ | 'P2P_MAX_AUTH_FAILED_ATTEMPTS_ALLOWED'
129
131
  | 'P2P_REQRESP_OPTIMISTIC_NEGOTIATION'
130
132
  | 'P2P_DOUBLE_SPEND_SEVERE_PEER_PENALTY_WINDOW'
131
133
  | 'P2P_LISTEN_ADDR'
@@ -135,9 +137,12 @@ export type EnvVar =
135
137
  | 'P2P_ARCHIVED_TX_LIMIT'
136
138
  | 'P2P_TRUSTED_PEERS'
137
139
  | 'P2P_PRIVATE_PEERS'
140
+ | 'P2P_PREFERRED_PEERS'
138
141
  | 'P2P_MAX_TX_POOL_SIZE'
139
142
  | 'P2P_TX_POOL_OVERFLOW_FACTOR'
140
143
  | 'P2P_SEEN_MSG_CACHE_SIZE'
144
+ | 'P2P_DROP_TX'
145
+ | 'P2P_DROP_TX_CHANCE'
141
146
  | 'PEER_ID_PRIVATE_KEY'
142
147
  | 'PEER_ID_PRIVATE_KEY_PATH'
143
148
  | 'PROVER_AGENT_COUNT'
@@ -160,6 +165,7 @@ export type EnvVar =
160
165
  | 'PROVER_NODE_TX_GATHERING_INTERVAL_MS'
161
166
  | 'PROVER_NODE_TX_GATHERING_BATCH_SIZE'
162
167
  | 'PROVER_NODE_TX_GATHERING_MAX_PARALLEL_REQUESTS_PER_NODE'
168
+ | 'PROVER_NODE_TX_GATHERING_TIMEOUT_MS'
163
169
  | 'PROVER_PUBLISH_RETRY_INTERVAL_MS'
164
170
  | 'PROVER_PUBLISHER_PRIVATE_KEY'
165
171
  | 'PROVER_REAL_PROOFS'
@@ -186,6 +192,9 @@ export type EnvVar =
186
192
  | 'SEQ_TX_POLLING_INTERVAL_MS'
187
193
  | 'SEQ_ENFORCE_TIME_TABLE'
188
194
  | 'SEQ_MAX_L1_TX_INCLUSION_TIME_INTO_SLOT'
195
+ | 'SEQ_ATTESTATION_PROPAGATION_TIME'
196
+ | 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_COMMITTEE_MEMBER'
197
+ | 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_NON_COMMITTEE_MEMBER'
189
198
  | 'SLASH_FACTORY_CONTRACT_ADDRESS'
190
199
  | 'SLASH_PRUNE_ENABLED'
191
200
  | 'SLASH_PRUNE_PENALTY'
@@ -200,6 +209,11 @@ export type EnvVar =
200
209
  | 'SLASH_INACTIVITY_SIGNAL_TARGET_PERCENTAGE'
201
210
  | 'SLASH_OVERRIDE_PAYLOAD'
202
211
  | 'SLASH_PAYLOAD_TTL_SECONDS'
212
+ | 'SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY'
213
+ | 'SLASH_PROPOSE_INVALID_ATTESTATIONS_MAX_PENALTY'
214
+ | 'SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY'
215
+ | 'SLASH_ATTEST_DESCENDANT_OF_INVALID_MAX_PENALTY'
216
+ | 'SLASHER_PRIVATE_KEY'
203
217
  | 'STAKING_ASSET_CONTRACT_ADDRESS'
204
218
  | 'STAKING_ASSET_HANDLER_CONTRACT_ADDRESS'
205
219
  | 'SYNC_MODE'
@@ -208,6 +222,16 @@ export type EnvVar =
208
222
  | 'TELEMETRY'
209
223
  | 'TEST_ACCOUNTS'
210
224
  | 'SPONSORED_FPC'
225
+ | 'TX_COLLECTION_FAST_NODES_TIMEOUT_BEFORE_REQ_RESP_MS'
226
+ | 'TX_COLLECTION_SLOW_NODES_INTERVAL_MS'
227
+ | 'TX_COLLECTION_SLOW_REQ_RESP_INTERVAL_MS'
228
+ | 'TX_COLLECTION_SLOW_REQ_RESP_TIMEOUT_MS'
229
+ | 'TX_COLLECTION_RECONCILE_INTERVAL_MS'
230
+ | 'TX_COLLECTION_DISABLE_SLOW_DURING_FAST_REQUESTS'
231
+ | 'TX_COLLECTION_FAST_NODE_INTERVAL_MS'
232
+ | 'TX_COLLECTION_FAST_MAX_PARALLEL_REQUESTS_PER_NODE'
233
+ | 'TX_COLLECTION_NODE_RPC_MAX_BATCH_SIZE'
234
+ | 'TX_COLLECTION_NODE_RPC_URLS'
211
235
  | 'TX_GOSSIP_VERSION'
212
236
  | 'TX_PUBLIC_SETUP_ALLOWLIST'
213
237
  | 'TXE_PORT'
@@ -231,12 +255,15 @@ export type EnvVar =
231
255
  | 'AZTEC_EPOCH_DURATION'
232
256
  | 'AZTEC_TARGET_COMMITTEE_SIZE'
233
257
  | 'AZTEC_PROOF_SUBMISSION_EPOCHS'
234
- | 'AZTEC_DEPOSIT_AMOUNT'
235
- | 'AZTEC_MINIMUM_STAKE'
258
+ | 'AZTEC_ACTIVATION_THRESHOLD'
259
+ | 'AZTEC_EJECTION_THRESHOLD'
236
260
  | 'AZTEC_MANA_TARGET'
237
261
  | 'AZTEC_PROVING_COST_PER_MANA'
238
262
  | 'AZTEC_SLASHING_QUORUM'
239
263
  | 'AZTEC_SLASHING_ROUND_SIZE'
264
+ | 'AZTEC_SLASHING_LIFETIME_IN_ROUNDS'
265
+ | 'AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS'
266
+ | 'AZTEC_SLASHING_VETOER'
240
267
  | 'AZTEC_GOVERNANCE_PROPOSER_QUORUM'
241
268
  | 'AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE'
242
269
  | 'AZTEC_EXIT_DELAY_SECONDS'
@@ -264,4 +291,6 @@ export type EnvVar =
264
291
  | 'FEE_ASSET_HANDLER_CONTRACT_ADDRESS'
265
292
  | 'VALIDATOR_REEXECUTE_DEADLINE_MS'
266
293
  | 'AUTO_UPDATE'
267
- | 'AUTO_UPDATE_URL';
294
+ | 'AUTO_UPDATE_URL'
295
+ | 'WEB3_SIGNER_URL'
296
+ | 'WEB3_SIGNER_ADDRESSES';
@@ -99,7 +99,6 @@ export function recoverPublicKey(hash: Buffer32, signature: Signature): Buffer {
99
99
  const { r, s, v } = signature;
100
100
  const recoveryBit = toRecoveryBit(v);
101
101
  const sig = new secp256k1.Signature(r.toBigInt(), s.toBigInt()).addRecoveryBit(recoveryBit);
102
-
103
102
  const publicKey = sig.recoverPublicKey(hash.buffer).toHex(false);
104
103
  return Buffer.from(publicKey, 'hex');
105
104
  }
@@ -60,8 +60,6 @@ abstract class BaseField {
60
60
  this.asBigInt = BigInt(value);
61
61
  if (this.asBigInt >= this.modulus()) {
62
62
  throw new Error(`Value 0x${this.asBigInt.toString(16)} is greater or equal to field modulus.`);
63
- } else if (this.asBigInt < 0n) {
64
- throw new Error(`Value 0x${this.asBigInt.toString(16)} is negative.`);
65
63
  }
66
64
  } else if (value instanceof BaseField) {
67
65
  this.asBuffer = value.asBuffer;
package/src/log/index.ts CHANGED
@@ -3,3 +3,4 @@ export * from './libp2p_logger.js';
3
3
  export * from './log_fn.js';
4
4
  export * from './noir_debug_log_util.js';
5
5
  export * from './pino-logger.js';
6
+ export * from './log-levels.js';
@@ -37,11 +37,14 @@ export function createLogger(module: string): Logger {
37
37
  debug: (msg: string, data?: unknown) => logFn('debug', msg, data),
38
38
  /** Log as trace. Use for when we want to denial-of-service any recipient of the logs. */
39
39
  trace: (msg: string, data?: unknown) => logFn('trace', msg, data),
40
+ /** Level of the logger */
40
41
  level: pinoLogger.level as LogLevel,
41
42
  /** Whether the given level is enabled for this logger. */
42
43
  isLevelEnabled: (level: LogLevel) => isLevelEnabled(pinoLogger, level),
43
44
  /** Module name for the logger. */
44
45
  module,
46
+ /** Creates another logger by extending this logger module name. */
47
+ createChild: (childModule: string) => createLogger(`${module}:${childModule}`),
45
48
  };
46
49
  }
47
50
 
@@ -102,6 +105,7 @@ const useGcloudLogging = parseBooleanEnv(process.env['USE_GCLOUD_LOGGING' satisf
102
105
 
103
106
  const redactedPaths = [
104
107
  'validatorPrivateKeys',
108
+ 'slasherPrivateKey',
105
109
  // for both the validator and the prover
106
110
  'publisherPrivateKey',
107
111
  'peerIdPrivateKey',
@@ -258,6 +262,7 @@ export type Logger = { [K in LogLevel]: LogFn } & { /** Error log function */ er
258
262
  level: LogLevel;
259
263
  isLevelEnabled: (level: LogLevel) => boolean;
260
264
  module: string;
265
+ createChild: (childModule: string) => Logger;
261
266
  };
262
267
 
263
268
  /**
@@ -0,0 +1,14 @@
1
+ /** Bounds the given value between the min and max provided (both inclusive) */
2
+ export function boundInclusive(value: number, min: number, max: number): number {
3
+ if (min > max) {
4
+ throw new Error('Minimum bound cannot be greater than maximum bound');
5
+ }
6
+
7
+ if (value < min) {
8
+ return min;
9
+ } else if (value > max) {
10
+ return max;
11
+ } else {
12
+ return value;
13
+ }
14
+ }
@@ -82,7 +82,6 @@ export class RunningPromise {
82
82
  */
83
83
  async stop(): Promise<void> {
84
84
  if (!this.running) {
85
- this.logger.warn(`Running promise was not started`);
86
85
  return;
87
86
  }
88
87
  this.running = false;
@@ -65,4 +65,4 @@ export const schemas = {
65
65
  };
66
66
 
67
67
  // These are needed to avoid errors such as: "The inferred type of 'YourClassSchema' cannot be named without a reference to..."
68
- export type { EthAddress, Point, Fr, Fq };
68
+ export type { EthAddress, Fq, Fr, Point };
@@ -145,6 +145,8 @@ export type Fieldable =
145
145
  }
146
146
  | Fieldable[];
147
147
 
148
+ export type Serializable = Bufferable & Fieldable;
149
+
148
150
  /**
149
151
  * Serializes a list of objects contiguously.
150
152
  * @param objs - Objects to serialize.