@aztec/foundation 2.1.0-rc.9 → 3.0.0-devnet.2
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.
- package/dest/config/env_var.d.ts +1 -1
- package/dest/config/env_var.d.ts.map +1 -1
- package/dest/config/network_name.d.ts +1 -1
- package/dest/config/network_name.d.ts.map +1 -1
- package/dest/config/network_name.js +6 -2
- package/dest/crypto/aes128/index.d.ts.map +1 -1
- package/dest/crypto/aes128/index.js +23 -6
- package/dest/crypto/ecdsa/index.d.ts.map +1 -1
- package/dest/crypto/ecdsa/index.js +66 -48
- package/dest/crypto/grumpkin/index.d.ts.map +1 -1
- package/dest/crypto/grumpkin/index.js +64 -43
- package/dest/crypto/keys/index.js +9 -4
- package/dest/crypto/pedersen/pedersen.wasm.d.ts.map +1 -1
- package/dest/crypto/pedersen/pedersen.wasm.js +29 -13
- package/dest/crypto/poseidon/index.d.ts.map +1 -1
- package/dest/crypto/poseidon/index.js +42 -17
- package/dest/crypto/schnorr/index.d.ts.map +1 -1
- package/dest/crypto/schnorr/index.js +35 -37
- package/dest/crypto/secp256k1/index.d.ts.map +1 -1
- package/dest/crypto/secp256k1/index.js +29 -18
- package/dest/crypto/secp256k1-signer/utils.d.ts +8 -0
- package/dest/crypto/secp256k1-signer/utils.d.ts.map +1 -1
- package/dest/crypto/secp256k1-signer/utils.js +14 -0
- package/dest/crypto/sync/index.js +3 -1
- package/dest/crypto/sync/pedersen/index.d.ts.map +1 -1
- package/dest/crypto/sync/pedersen/index.js +17 -10
- package/dest/crypto/sync/poseidon/index.d.ts.map +1 -1
- package/dest/crypto/sync/poseidon/index.js +27 -12
- package/dest/fields/bls12_point.d.ts +7 -7
- package/dest/fields/bls12_point.js +7 -7
- package/dest/fields/fields.d.ts.map +1 -1
- package/dest/fields/fields.js +9 -10
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/json-rpc/client/safe_json_rpc_client.d.ts.map +1 -1
- package/dest/json-rpc/client/safe_json_rpc_client.js +9 -0
- package/dest/log/pino-logger.d.ts.map +1 -1
- package/dest/log/pino-logger.js +0 -1
- package/dest/profiler/index.d.ts +2 -0
- package/dest/profiler/index.d.ts.map +1 -0
- package/dest/profiler/index.js +1 -0
- package/dest/profiler/profiler.d.ts +8 -0
- package/dest/profiler/profiler.d.ts.map +1 -0
- package/dest/profiler/profiler.js +97 -0
- package/dest/testing/formatting.d.ts +4 -0
- package/dest/testing/formatting.d.ts.map +1 -0
- package/dest/testing/formatting.js +3 -0
- package/dest/testing/index.d.ts +1 -0
- package/dest/testing/index.d.ts.map +1 -1
- package/dest/testing/index.js +1 -0
- package/dest/trees/unbalanced_merkle_tree.d.ts +0 -1
- package/dest/trees/unbalanced_merkle_tree.d.ts.map +1 -1
- package/dest/trees/unbalanced_merkle_tree.js +1 -1
- package/dest/trees/unbalanced_merkle_tree_calculator.d.ts +25 -22
- package/dest/trees/unbalanced_merkle_tree_calculator.d.ts.map +1 -1
- package/dest/trees/unbalanced_merkle_tree_calculator.js +124 -94
- package/dest/trees/unbalanced_tree_store.d.ts +1 -0
- package/dest/trees/unbalanced_tree_store.d.ts.map +1 -1
- package/dest/trees/unbalanced_tree_store.js +6 -0
- package/package.json +4 -3
- package/src/config/env_var.ts +2 -1
- package/src/config/network_name.ts +14 -3
- package/src/crypto/aes128/index.ts +19 -10
- package/src/crypto/ecdsa/index.ts +40 -37
- package/src/crypto/grumpkin/index.ts +29 -31
- package/src/crypto/keys/index.ts +5 -5
- package/src/crypto/pedersen/pedersen.wasm.ts +22 -18
- package/src/crypto/poseidon/index.ts +32 -24
- package/src/crypto/schnorr/index.ts +20 -17
- package/src/crypto/secp256k1/index.ts +15 -11
- package/src/crypto/secp256k1-signer/utils.ts +16 -0
- package/src/crypto/sync/index.ts +1 -1
- package/src/crypto/sync/pedersen/index.ts +16 -15
- package/src/crypto/sync/poseidon/index.ts +27 -22
- package/src/fields/bls12_point.ts +7 -7
- package/src/fields/fields.ts +5 -6
- package/src/index.ts +1 -0
- package/src/json-rpc/client/safe_json_rpc_client.ts +9 -0
- package/src/log/pino-logger.ts +0 -1
- package/src/profiler/index.ts +1 -0
- package/src/profiler/profiler.ts +125 -0
- package/src/testing/formatting.ts +3 -0
- package/src/testing/index.ts +1 -0
- package/src/trees/unbalanced_merkle_tree.ts +1 -1
- package/src/trees/unbalanced_merkle_tree_calculator.ts +140 -92
- package/src/trees/unbalanced_tree_store.ts +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/profiler/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './profiler.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare function reset(): void;
|
|
2
|
+
declare function runAsync<ReturnType>(label: string, fn: () => Promise<ReturnType>): Promise<ReturnType>;
|
|
3
|
+
export declare const profiler: {
|
|
4
|
+
reset: typeof reset;
|
|
5
|
+
runAsync: typeof runAsync;
|
|
6
|
+
};
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=profiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiler.d.ts","sourceRoot":"","sources":["../../src/profiler/profiler.ts"],"names":[],"mappings":"AA8BA,iBAAS,KAAK,IAAI,IAAI,CAErB;AAwDD,iBAAe,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAkCrG;AAED,eAAO,MAAM,QAAQ;;;CAAsB,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { performance } from 'node:perf_hooks';
|
|
5
|
+
const als = new AsyncLocalStorage();
|
|
6
|
+
const roots = [];
|
|
7
|
+
function reset() {
|
|
8
|
+
roots.length = 0;
|
|
9
|
+
}
|
|
10
|
+
// Strip out circular references (parent) and unused fields (start) for JSON serialization
|
|
11
|
+
function serializeSpans(spans) {
|
|
12
|
+
return spans.map((span)=>({
|
|
13
|
+
label: span.label,
|
|
14
|
+
dur: span.dur,
|
|
15
|
+
count: span.count,
|
|
16
|
+
children: serializeSpans(span.children)
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
let i = 0;
|
|
20
|
+
function save() {
|
|
21
|
+
if (roots.length === 0) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Find max single execution time across all spans (dur/count since dur is accumulated)
|
|
25
|
+
const findMaxSingleDuration = (spans)=>{
|
|
26
|
+
let max = 0;
|
|
27
|
+
for (const span of spans){
|
|
28
|
+
const singleDur = span.dur / span.count;
|
|
29
|
+
max = Math.max(max, singleDur);
|
|
30
|
+
if (span.children.length > 0) {
|
|
31
|
+
max = Math.max(max, findMaxSingleDuration(span.children));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return max;
|
|
35
|
+
};
|
|
36
|
+
const profileData = {
|
|
37
|
+
spans: serializeSpans(roots),
|
|
38
|
+
timestamp: new Date().toISOString(),
|
|
39
|
+
totalTime: findMaxSingleDuration(roots)
|
|
40
|
+
};
|
|
41
|
+
const profilePath = path.join(process.cwd(), `profile-${i++}.json`);
|
|
42
|
+
process.stdout.write(`Writing profile data to ${profilePath}\n`);
|
|
43
|
+
fs.writeFileSync(profilePath, JSON.stringify(profileData, null, 2));
|
|
44
|
+
}
|
|
45
|
+
// Hook into Jest to save after each test
|
|
46
|
+
if (typeof afterEach === 'function') {
|
|
47
|
+
afterEach(()=>{
|
|
48
|
+
save();
|
|
49
|
+
reset();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// Also save on process exit for non-Jest environments
|
|
53
|
+
process.on('exit', ()=>{
|
|
54
|
+
save();
|
|
55
|
+
});
|
|
56
|
+
// Wrapper for async functions to maintain context properly
|
|
57
|
+
async function runAsync(label, fn) {
|
|
58
|
+
const parent = als.getStore();
|
|
59
|
+
// Check if we already have a span with this label in the current context
|
|
60
|
+
let existingSpan;
|
|
61
|
+
if (parent) {
|
|
62
|
+
existingSpan = parent.children.find((c)=>c.label === label);
|
|
63
|
+
} else {
|
|
64
|
+
existingSpan = roots.find((r)=>r.label === label);
|
|
65
|
+
}
|
|
66
|
+
let span;
|
|
67
|
+
if (existingSpan) {
|
|
68
|
+
// Reuse existing span and increment count
|
|
69
|
+
span = existingSpan;
|
|
70
|
+
span.count++;
|
|
71
|
+
} else {
|
|
72
|
+
// Create new span
|
|
73
|
+
span = {
|
|
74
|
+
label,
|
|
75
|
+
start: performance.now(),
|
|
76
|
+
dur: 0,
|
|
77
|
+
count: 1,
|
|
78
|
+
children: [],
|
|
79
|
+
parent
|
|
80
|
+
};
|
|
81
|
+
if (parent) {
|
|
82
|
+
parent.children.push(span);
|
|
83
|
+
} else {
|
|
84
|
+
roots.push(span);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const startTime = performance.now();
|
|
88
|
+
const result = await als.run(span, fn);
|
|
89
|
+
const elapsed = performance.now() - startTime;
|
|
90
|
+
// Add to total duration (for averaging)
|
|
91
|
+
span.dur += elapsed;
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
export const profiler = {
|
|
95
|
+
reset,
|
|
96
|
+
runAsync
|
|
97
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../src/testing/formatting.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,GAAG,EAAE;IAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAE1E"}
|
package/dest/testing/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
package/dest/testing/index.js
CHANGED
|
@@ -21,7 +21,6 @@ import { sha256Trunc } from '../crypto/sha256/index.js';
|
|
|
21
21
|
* (depth 1), the final tree has a depth of 5.
|
|
22
22
|
*/
|
|
23
23
|
export declare function computeUnbalancedMerkleTreeRoot(leaves: Buffer[], hasher?: typeof sha256Trunc): Buffer;
|
|
24
|
-
export declare function getMaxUnbalancedTreeDepth(numLeaves: number): number;
|
|
25
24
|
export declare function findLeafLevelAndIndex(numLeaves: number, leafIndex: number): {
|
|
26
25
|
level: number;
|
|
27
26
|
indexAtLevel: number;
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAsDD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;WAhC9D,MAAM;kBAAgB,MAAM;EAmCvC"}
|
|
@@ -57,7 +57,7 @@ function getMaxBalancedSubtreeDepth(numLeaves) {
|
|
|
57
57
|
return Math.floor(Math.log2(numLeaves));
|
|
58
58
|
}
|
|
59
59
|
/// Get the maximum depth of an unbalanced tree that can be created with the given number of leaves.
|
|
60
|
-
|
|
60
|
+
function getMaxUnbalancedTreeDepth(numLeaves) {
|
|
61
61
|
return Math.ceil(Math.log2(numLeaves));
|
|
62
62
|
}
|
|
63
63
|
function findPosition(rootLevel, leafLevel, numLeaves, indexOffset, targetIndex) {
|
|
@@ -1,45 +1,48 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import type { Hasher } from './hasher.js';
|
|
2
|
+
import { SiblingPath } from './sibling_path.js';
|
|
3
|
+
import { type TreeNodeLocation } from './unbalanced_tree_store.js';
|
|
4
|
+
export declare function computeCompressedUnbalancedMerkleTreeRoot(leaves: Buffer[], valueToCompress?: Buffer<ArrayBuffer>, hasher?: Hasher['hash']): Buffer;
|
|
4
5
|
/**
|
|
5
6
|
* An ephemeral unbalanced Merkle tree implementation.
|
|
6
7
|
* Follows the rollup implementation which greedily hashes pairs of nodes up the tree.
|
|
7
8
|
* Remaining rightmost nodes are shifted up until they can be paired.
|
|
9
|
+
* The values that match the `valueToCompress` are skipped and the sibling of the compressed leaf are shifted up until
|
|
10
|
+
* they can be paired.
|
|
8
11
|
* If there is only one leaf, the root is the leaf.
|
|
9
12
|
*/
|
|
10
13
|
export declare class UnbalancedMerkleTreeCalculator {
|
|
11
|
-
private
|
|
12
|
-
private
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
static create(height: number, hasher?: (left: Buffer, right: Buffer) => Promise<Buffer<ArrayBuffer>>): UnbalancedMerkleTreeCalculator;
|
|
14
|
+
private readonly leaves;
|
|
15
|
+
private readonly valueToCompress;
|
|
16
|
+
private readonly hasher;
|
|
17
|
+
private store;
|
|
18
|
+
private leafLocations;
|
|
19
|
+
constructor(leaves: Buffer[], valueToCompress: Buffer, hasher: Hasher['hash']);
|
|
20
|
+
static create(leaves: Buffer[], valueToCompress?: Buffer<ArrayBuffer>, hasher?: (left: Buffer, right: Buffer) => Buffer<ArrayBuffer>): UnbalancedMerkleTreeCalculator;
|
|
19
21
|
/**
|
|
20
22
|
* Returns the root of the tree.
|
|
21
23
|
* @returns The root of the tree.
|
|
22
24
|
*/
|
|
23
25
|
getRoot(): Buffer;
|
|
24
26
|
/**
|
|
25
|
-
* Returns a sibling path for the element
|
|
27
|
+
* Returns a sibling path for the element.
|
|
26
28
|
* @param value - The value of the element.
|
|
27
29
|
* @returns A sibling path for the element.
|
|
28
30
|
* Note: The sibling path is an array of sibling hashes, with the lowest hash (leaf hash) first, and the highest hash last.
|
|
29
31
|
*/
|
|
30
|
-
getSiblingPath<N extends number>(value:
|
|
32
|
+
getSiblingPath<N extends number>(value: Buffer): SiblingPath<N>;
|
|
31
33
|
/**
|
|
32
|
-
*
|
|
33
|
-
* @param
|
|
34
|
-
* @returns
|
|
34
|
+
* Returns a sibling path for the leaf at the given index.
|
|
35
|
+
* @param leafIndex - The index of the leaf.
|
|
36
|
+
* @returns A sibling path for the leaf.
|
|
35
37
|
*/
|
|
36
|
-
|
|
38
|
+
getSiblingPathByLeafIndex<N extends number>(leafIndex: number): SiblingPath<N>;
|
|
39
|
+
getLeafLocation(leafIndex: number): TreeNodeLocation;
|
|
37
40
|
/**
|
|
38
|
-
*
|
|
39
|
-
* @param leaves - The leaves
|
|
40
|
-
* @returns Resulting root of the tree.
|
|
41
|
+
* Adds leaves and nodes to the store. Updates the leafLocations.
|
|
42
|
+
* @param leaves - The leaves of the tree.
|
|
41
43
|
*/
|
|
42
|
-
private
|
|
43
|
-
private
|
|
44
|
+
private buildTree;
|
|
45
|
+
private shiftNodeUp;
|
|
46
|
+
private shiftChildrenUp;
|
|
44
47
|
}
|
|
45
48
|
//# sourceMappingURL=unbalanced_merkle_tree_calculator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unbalanced_merkle_tree_calculator.d.ts","sourceRoot":"","sources":["../../src/trees/unbalanced_merkle_tree_calculator.ts"],"names":[],"mappings":"
|
|
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,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,KAAK,gBAAgB,EAAuB,MAAM,4BAA4B,CAAC;AAExF,wBAAgB,yCAAyC,CACvD,MAAM,EAAE,MAAM,EAAE,EAChB,eAAe,sBAAmB,EAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GACtB,MAAM,CAGR;AAOD;;;;;;;GAOG;AACH,qBAAa,8BAA8B;IAKvC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,aAAa,CAA0B;gBAG5B,MAAM,EAAE,MAAM,EAAE,EAChB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;IAUzC,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,MAAM,EAAE,EAChB,eAAe,sBAAkB,EACjC,MAAM,IAAI,MAAM,MAAM,EAAE,OAAO,MAAM,KAAkD,MAAM,CAAC,WAAW,CAAC;IAK5G;;;OAGG;IACI,OAAO,IAAI,MAAM;IAIxB;;;;;OAKG;IACI,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC;IAStE;;;;OAIG;IACI,yBAAyB,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC;IAqB9E,eAAe,CAAC,SAAS,EAAE,MAAM;IAIxC;;;OAGG;IACH,OAAO,CAAC,SAAS;IAkDjB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,eAAe;CAoBxB"}
|
|
@@ -1,132 +1,162 @@
|
|
|
1
|
-
import { serializeToBuffer } from '@aztec/foundation/serialize';
|
|
2
|
-
import { SiblingPath } from '@aztec/foundation/trees';
|
|
3
1
|
import { sha256Trunc } from '../crypto/index.js';
|
|
4
|
-
|
|
2
|
+
import { SiblingPath } from './sibling_path.js';
|
|
3
|
+
import { UnbalancedTreeStore } from './unbalanced_tree_store.js';
|
|
4
|
+
export function computeCompressedUnbalancedMerkleTreeRoot(leaves, valueToCompress = Buffer.alloc(32), hasher) {
|
|
5
|
+
const calculator = UnbalancedMerkleTreeCalculator.create(leaves, valueToCompress, hasher);
|
|
6
|
+
return calculator.getRoot();
|
|
7
|
+
}
|
|
5
8
|
/**
|
|
6
9
|
* An ephemeral unbalanced Merkle tree implementation.
|
|
7
10
|
* Follows the rollup implementation which greedily hashes pairs of nodes up the tree.
|
|
8
11
|
* Remaining rightmost nodes are shifted up until they can be paired.
|
|
12
|
+
* The values that match the `valueToCompress` are skipped and the sibling of the compressed leaf are shifted up until
|
|
13
|
+
* they can be paired.
|
|
9
14
|
* If there is only one leaf, the root is the leaf.
|
|
10
15
|
*/ export class UnbalancedMerkleTreeCalculator {
|
|
11
|
-
|
|
16
|
+
leaves;
|
|
17
|
+
valueToCompress;
|
|
12
18
|
hasher;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
root;
|
|
19
|
-
constructor(maxDepth, hasher){
|
|
20
|
-
this.maxDepth = maxDepth;
|
|
19
|
+
store;
|
|
20
|
+
leafLocations;
|
|
21
|
+
constructor(leaves, valueToCompress, hasher){
|
|
22
|
+
this.leaves = leaves;
|
|
23
|
+
this.valueToCompress = valueToCompress;
|
|
21
24
|
this.hasher = hasher;
|
|
22
|
-
this.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
this.leafLocations = [];
|
|
26
|
+
if (leaves.length === 0) {
|
|
27
|
+
throw Error('Cannot create a compressed unbalanced tree with 0 leaves.');
|
|
28
|
+
}
|
|
29
|
+
this.store = new UnbalancedTreeStore(leaves.length);
|
|
30
|
+
this.buildTree();
|
|
26
31
|
}
|
|
27
|
-
static create(
|
|
32
|
+
static create(leaves, valueToCompress = Buffer.alloc(0), hasher = (left, right)=>sha256Trunc(Buffer.concat([
|
|
28
33
|
left,
|
|
29
34
|
right
|
|
30
|
-
])))
|
|
31
|
-
return new UnbalancedMerkleTreeCalculator(
|
|
35
|
+
]))) {
|
|
36
|
+
return new UnbalancedMerkleTreeCalculator(leaves, valueToCompress, hasher);
|
|
32
37
|
}
|
|
33
38
|
/**
|
|
34
39
|
* Returns the root of the tree.
|
|
35
40
|
* @returns The root of the tree.
|
|
36
41
|
*/ getRoot() {
|
|
37
|
-
return this.
|
|
42
|
+
return this.store.getRoot().value;
|
|
38
43
|
}
|
|
39
44
|
/**
|
|
40
|
-
* Returns a sibling path for the element
|
|
45
|
+
* Returns a sibling path for the element.
|
|
41
46
|
* @param value - The value of the element.
|
|
42
47
|
* @returns A sibling path for the element.
|
|
43
48
|
* Note: The sibling path is an array of sibling hashes, with the lowest hash (leaf hash) first, and the highest hash last.
|
|
44
49
|
*/ getSiblingPath(value) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const path = [];
|
|
49
|
-
const [depth, _index] = this.valueCache[serializeToBuffer(value).toString('hex')].split(':');
|
|
50
|
-
let level = parseInt(depth, 10);
|
|
51
|
-
let index = BigInt(_index);
|
|
52
|
-
while(level > 0){
|
|
53
|
-
const isRight = index & 0x01n;
|
|
54
|
-
const key = indexToKeyHash(level, isRight ? index - 1n : index + 1n);
|
|
55
|
-
const sibling = this.cache[key];
|
|
56
|
-
path.push(sibling);
|
|
57
|
-
level -= 1;
|
|
58
|
-
index >>= 1n;
|
|
50
|
+
const leafIndex = this.leaves.findIndex((leaf)=>leaf.equals(value));
|
|
51
|
+
if (leafIndex === -1) {
|
|
52
|
+
throw Error(`Leaf value ${value.toString('hex')} not found in tree.`);
|
|
59
53
|
}
|
|
60
|
-
return
|
|
54
|
+
return this.getSiblingPathByLeafIndex(leafIndex);
|
|
61
55
|
}
|
|
62
56
|
/**
|
|
63
|
-
*
|
|
64
|
-
* @param
|
|
65
|
-
* @returns
|
|
66
|
-
*/
|
|
67
|
-
if (this.
|
|
68
|
-
throw Error(`
|
|
57
|
+
* Returns a sibling path for the leaf at the given index.
|
|
58
|
+
* @param leafIndex - The index of the leaf.
|
|
59
|
+
* @returns A sibling path for the leaf.
|
|
60
|
+
*/ getSiblingPathByLeafIndex(leafIndex) {
|
|
61
|
+
if (leafIndex >= this.leaves.length) {
|
|
62
|
+
throw Error(`Leaf index ${leafIndex} out of bounds. Tree has ${this.leaves.length} leaves.`);
|
|
69
63
|
}
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
const leaf = this.leaves[leafIndex];
|
|
65
|
+
if (leaf.equals(this.valueToCompress)) {
|
|
66
|
+
throw Error(`Leaf at index ${leafIndex} has been compressed.`);
|
|
72
67
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
const path = [];
|
|
69
|
+
let location = this.leafLocations[leafIndex];
|
|
70
|
+
while(location.level > 0){
|
|
71
|
+
const sibling = this.store.getSibling(location);
|
|
72
|
+
path.push(sibling.value);
|
|
73
|
+
location = this.store.getParentLocation(location);
|
|
77
74
|
}
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
return new SiblingPath(path.length, path);
|
|
76
|
+
}
|
|
77
|
+
getLeafLocation(leafIndex) {
|
|
78
|
+
return this.leafLocations[leafIndex];
|
|
80
79
|
}
|
|
81
80
|
/**
|
|
82
|
-
*
|
|
83
|
-
* @param leaves - The leaves
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
81
|
+
* Adds leaves and nodes to the store. Updates the leafLocations.
|
|
82
|
+
* @param leaves - The leaves of the tree.
|
|
83
|
+
*/ buildTree() {
|
|
84
|
+
this.leafLocations = this.leaves.map((value, i)=>this.store.setLeaf(i, {
|
|
85
|
+
value,
|
|
86
|
+
leafIndex: i
|
|
87
|
+
}));
|
|
88
|
+
// Start with the leaves that are not compressed.
|
|
89
|
+
let toProcess = this.leafLocations.filter((_, i)=>!this.leaves[i].equals(this.valueToCompress));
|
|
90
|
+
if (!toProcess.length) {
|
|
91
|
+
// All leaves are compressed. Set 0 to the root.
|
|
92
|
+
this.store.setNode({
|
|
93
|
+
level: 0,
|
|
94
|
+
index: 0
|
|
95
|
+
}, {
|
|
96
|
+
value: Buffer.alloc(32)
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const level = toProcess[0].level;
|
|
101
|
+
for(let i = level; i > 0; i--){
|
|
102
|
+
const toProcessNext = [];
|
|
103
|
+
for (const location of toProcess){
|
|
104
|
+
if (location.level !== i) {
|
|
105
|
+
toProcessNext.push(location);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const parentLocation = this.store.getParentLocation(location);
|
|
109
|
+
if (this.store.getNode(parentLocation)) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const sibling = this.store.getSibling(location);
|
|
113
|
+
// If sibling is undefined, all its children are compressed.
|
|
114
|
+
const shouldShiftUp = !sibling || sibling.value.equals(this.valueToCompress);
|
|
115
|
+
if (shouldShiftUp) {
|
|
116
|
+
// The node becomes the parent if the sibling is a compressed leaf.
|
|
117
|
+
const isLeaf = this.shiftNodeUp(location, parentLocation);
|
|
118
|
+
if (!isLeaf) {
|
|
119
|
+
this.shiftChildrenUp(location);
|
|
120
|
+
}
|
|
114
121
|
} else {
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
122
|
+
// Hash the value with the (right) sibling and update the parent node.
|
|
123
|
+
const node = this.store.getNode(location);
|
|
124
|
+
const parentValue = this.hasher(node.value, sibling.value);
|
|
125
|
+
this.store.setNode(parentLocation, {
|
|
126
|
+
value: parentValue
|
|
127
|
+
});
|
|
118
128
|
}
|
|
129
|
+
// Add the parent location to be processed next.
|
|
130
|
+
toProcessNext.push(parentLocation);
|
|
119
131
|
}
|
|
120
|
-
|
|
121
|
-
thisLayer = nextLayer;
|
|
122
|
-
nextLayer = [];
|
|
132
|
+
toProcess = toProcessNext;
|
|
123
133
|
}
|
|
124
|
-
// return the root
|
|
125
|
-
return thisLayer[0];
|
|
126
134
|
}
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
this.
|
|
130
|
-
|
|
135
|
+
shiftNodeUp(fromLocation, toLocation) {
|
|
136
|
+
const node = this.store.getNode(fromLocation);
|
|
137
|
+
this.store.setNode(toLocation, node);
|
|
138
|
+
const isLeaf = node.leafIndex !== undefined;
|
|
139
|
+
if (isLeaf) {
|
|
140
|
+
// Update the location if the node is a leaf.
|
|
141
|
+
this.leafLocations[node.leafIndex] = toLocation;
|
|
142
|
+
}
|
|
143
|
+
return isLeaf;
|
|
144
|
+
}
|
|
145
|
+
shiftChildrenUp(parent) {
|
|
146
|
+
const [left, right] = this.store.getChildLocations(parent);
|
|
147
|
+
const level = parent.level;
|
|
148
|
+
const groupSize = 2 ** level;
|
|
149
|
+
const computeNewLocation = (index)=>({
|
|
150
|
+
level,
|
|
151
|
+
index: Math.floor(index / (groupSize * 2)) * groupSize + index % groupSize
|
|
152
|
+
});
|
|
153
|
+
const isLeftLeaf = this.shiftNodeUp(left, computeNewLocation(left.index));
|
|
154
|
+
const isRightLeaf = this.shiftNodeUp(right, computeNewLocation(right.index));
|
|
155
|
+
if (!isLeftLeaf) {
|
|
156
|
+
this.shiftChildrenUp(left);
|
|
157
|
+
}
|
|
158
|
+
if (!isRightLeaf) {
|
|
159
|
+
this.shiftChildrenUp(right);
|
|
160
|
+
}
|
|
131
161
|
}
|
|
132
162
|
}
|
|
@@ -12,6 +12,7 @@ export declare class UnbalancedTreeStore<T> {
|
|
|
12
12
|
getChildLocations({ level, index }: TreeNodeLocation): [TreeNodeLocation, TreeNodeLocation];
|
|
13
13
|
getLeaf(leafIndex: number): T | undefined;
|
|
14
14
|
getNode(location: TreeNodeLocation): T | undefined;
|
|
15
|
+
getRoot(): T | undefined;
|
|
15
16
|
getParent(location: TreeNodeLocation): T | undefined;
|
|
16
17
|
getSibling(location: TreeNodeLocation): T | undefined;
|
|
17
18
|
getChildren(location: TreeNodeLocation): [T | undefined, T | undefined];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unbalanced_tree_store.d.ts","sourceRoot":"","sources":["../../src/trees/unbalanced_tree_store.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,qBAAa,mBAAmB,CAAC,CAAC;;gBAIpB,SAAS,EAAE,MAAM;IAI7B,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,gBAAgB;IAiBtD,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;IAWpD,iBAAiB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,gBAAgB,GAAG,gBAAgB;IAQvE,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,gBAAgB,GAAG,gBAAgB;IAQxE,iBAAiB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,gBAAgB,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAM3F,OAAO,CAAC,SAAS,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"unbalanced_tree_store.d.ts","sourceRoot":"","sources":["../../src/trees/unbalanced_tree_store.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,qBAAa,mBAAmB,CAAC,CAAC;;gBAIpB,SAAS,EAAE,MAAM;IAI7B,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,gBAAgB;IAiBtD,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;IAWpD,iBAAiB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,gBAAgB,GAAG,gBAAgB;IAQvE,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,gBAAgB,GAAG,gBAAgB;IAQxE,iBAAiB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,gBAAgB,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAM3F,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IASzC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,GAAG,CAAC,GAAG,SAAS;IAIlD,OAAO,IAAI,CAAC,GAAG,SAAS;IAIxB,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,CAAC,GAAG,SAAS;IAKpD,UAAU,CAAC,QAAQ,EAAE,gBAAgB,GAAG,CAAC,GAAG,SAAS;IAKrD,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,SAAS,CAAC;CAQxE"}
|
|
@@ -73,6 +73,12 @@ export class UnbalancedTreeStore {
|
|
|
73
73
|
getNode(location) {
|
|
74
74
|
return this.#nodeMapping.get(this.#getKey(location))?.value;
|
|
75
75
|
}
|
|
76
|
+
getRoot() {
|
|
77
|
+
return this.getNode({
|
|
78
|
+
level: 0,
|
|
79
|
+
index: 0
|
|
80
|
+
});
|
|
81
|
+
}
|
|
76
82
|
getParent(location) {
|
|
77
83
|
const parentLocation = this.getParentLocation(location);
|
|
78
84
|
return this.getNode(parentLocation);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/foundation",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-devnet.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dest/index.js",
|
|
6
6
|
"types": "./dest/index.d.ts",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"./noir": "./dest/noir/index.js",
|
|
48
48
|
"./testing": "./dest/testing/index.js",
|
|
49
49
|
"./testing/files": "./dest/testing/files/index.js",
|
|
50
|
+
"./profiler": "./dest/profiler/index.js",
|
|
50
51
|
"./array": "./dest/array/index.js",
|
|
51
52
|
"./validation": "./dest/validation/index.js",
|
|
52
53
|
"./promise": "./dest/promise/index.js",
|
|
@@ -102,7 +103,7 @@
|
|
|
102
103
|
"testEnvironment": "../../foundation/src/jest/env.mjs"
|
|
103
104
|
},
|
|
104
105
|
"dependencies": {
|
|
105
|
-
"@aztec/bb.js": "
|
|
106
|
+
"@aztec/bb.js": "3.0.0-devnet.2",
|
|
106
107
|
"@koa/cors": "^5.0.0",
|
|
107
108
|
"@noble/curves": "=1.7.0",
|
|
108
109
|
"bn.js": "^5.2.1",
|
|
@@ -153,7 +154,7 @@
|
|
|
153
154
|
"ts-node": "^10.9.1",
|
|
154
155
|
"typescript": "^5.3.3",
|
|
155
156
|
"typescript-eslint": "^8.32.1",
|
|
156
|
-
"viem": "2.
|
|
157
|
+
"viem": "npm:@spalladino/viem@2.38.2-eip7594.0"
|
|
157
158
|
},
|
|
158
159
|
"files": [
|
|
159
160
|
"dest",
|
package/src/config/env_var.ts
CHANGED
|
@@ -26,6 +26,7 @@ export type EnvVar =
|
|
|
26
26
|
| 'BLOB_SINK_URL'
|
|
27
27
|
| 'BOT_DA_GAS_LIMIT'
|
|
28
28
|
| 'BOT_FEE_PAYMENT_METHOD'
|
|
29
|
+
| 'BOT_BASE_FEE_PADDING'
|
|
29
30
|
| 'BOT_FLUSH_SETUP_TRANSACTIONS'
|
|
30
31
|
| 'BOT_FOLLOW_CHAIN'
|
|
31
32
|
| 'BOT_L2_GAS_LIMIT'
|
|
@@ -38,7 +39,6 @@ export type EnvVar =
|
|
|
38
39
|
| 'BOT_ACCOUNT_SALT'
|
|
39
40
|
| 'BOT_PRIVATE_TRANSFERS_PER_TX'
|
|
40
41
|
| 'BOT_PUBLIC_TRANSFERS_PER_TX'
|
|
41
|
-
| 'BOT_PXE_URL'
|
|
42
42
|
| 'BOT_RECIPIENT_ENCRYPTION_SECRET'
|
|
43
43
|
| 'BOT_TOKEN_CONTRACT'
|
|
44
44
|
| 'BOT_TOKEN_SALT'
|
|
@@ -173,6 +173,7 @@ export type EnvVar =
|
|
|
173
173
|
| 'RPC_MAX_BATCH_SIZE'
|
|
174
174
|
| 'RPC_MAX_BODY_SIZE'
|
|
175
175
|
| 'RPC_SIMULATE_PUBLIC_MAX_GAS_LIMIT'
|
|
176
|
+
| 'RPC_SIMULATE_PUBLIC_MAX_DEBUG_LOG_MEMORY_READS'
|
|
176
177
|
| 'SENTINEL_ENABLED'
|
|
177
178
|
| 'SENTINEL_HISTORY_LENGTH_IN_EPOCHS'
|
|
178
179
|
| 'SENTINEL_HISTORIC_PROVEN_PERFORMANCE_LENGTH_IN_EPOCHS'
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
export type NetworkNames =
|
|
1
|
+
export type NetworkNames =
|
|
2
|
+
| 'local'
|
|
3
|
+
| 'staging-ignition'
|
|
4
|
+
| 'staging-public'
|
|
5
|
+
| 'testnet'
|
|
6
|
+
| 'mainnet'
|
|
7
|
+
| 'next-net'
|
|
8
|
+
| 'devnet';
|
|
2
9
|
|
|
3
10
|
export function getActiveNetworkName(name?: string): NetworkNames {
|
|
4
11
|
const network = name || process.env.NETWORK;
|
|
@@ -10,8 +17,12 @@ export function getActiveNetworkName(name?: string): NetworkNames {
|
|
|
10
17
|
return network;
|
|
11
18
|
} else if (network === 'testnet' || network === 'alpha-testnet') {
|
|
12
19
|
return 'testnet';
|
|
13
|
-
} else if (network === '
|
|
14
|
-
return '
|
|
20
|
+
} else if (network === 'mainnet') {
|
|
21
|
+
return 'mainnet';
|
|
22
|
+
} else if (network === 'next-net') {
|
|
23
|
+
return 'next-net';
|
|
24
|
+
} else if (network === 'devnet') {
|
|
25
|
+
return 'devnet';
|
|
15
26
|
}
|
|
16
27
|
throw new Error(`Unknown network: ${network}`);
|
|
17
28
|
}
|