@aztec/aztec 0.0.1-commit.cb6bed7c2 → 0.0.1-commit.cbf2c2d5d
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/cli/aztec_start_action.d.ts +1 -1
- package/dest/cli/aztec_start_action.d.ts.map +1 -1
- package/dest/cli/aztec_start_action.js +12 -5
- package/dest/cli/cmds/compile.d.ts +1 -1
- package/dest/cli/cmds/compile.d.ts.map +1 -1
- package/dest/cli/cmds/compile.js +7 -1
- package/dest/cli/cmds/profile_flamegraph.d.ts +1 -1
- package/dest/cli/cmds/profile_flamegraph.d.ts.map +1 -1
- package/dest/cli/cmds/profile_flamegraph.js +2 -1
- package/dest/cli/cmds/profile_gates.d.ts +1 -1
- package/dest/cli/cmds/profile_gates.d.ts.map +1 -1
- package/dest/cli/cmds/profile_gates.js +2 -1
- package/dest/cli/cmds/standby.d.ts +10 -5
- package/dest/cli/cmds/standby.d.ts.map +1 -1
- package/dest/cli/cmds/standby.js +33 -14
- package/dest/cli/cmds/start_node.d.ts +1 -1
- package/dest/cli/cmds/start_node.d.ts.map +1 -1
- package/dest/cli/cmds/start_node.js +7 -1
- package/dest/cli/cmds/start_prover_broker.d.ts +1 -1
- package/dest/cli/cmds/start_prover_broker.d.ts.map +1 -1
- package/dest/cli/cmds/start_prover_broker.js +7 -1
- package/dest/cli/cmds/utils/needs_recompile.d.ts +10 -0
- package/dest/cli/cmds/utils/needs_recompile.d.ts.map +1 -0
- package/dest/cli/cmds/utils/needs_recompile.js +134 -0
- package/dest/testing/anvil_test_watcher.js +1 -1
- package/dest/testing/cheat_codes.js +1 -1
- package/dest/testing/epoch_test_settler.d.ts +1 -1
- package/dest/testing/epoch_test_settler.d.ts.map +1 -1
- package/dest/testing/epoch_test_settler.js +3 -4
- package/package.json +34 -34
- package/scripts/aztec.sh +3 -0
- package/src/cli/aztec_start_action.ts +7 -5
- package/src/cli/cmds/compile.ts +8 -1
- package/src/cli/cmds/profile_flamegraph.ts +2 -1
- package/src/cli/cmds/profile_gates.ts +2 -1
- package/src/cli/cmds/standby.ts +37 -16
- package/src/cli/cmds/start_node.ts +8 -1
- package/src/cli/cmds/start_prover_broker.ts +8 -1
- package/src/cli/cmds/utils/needs_recompile.ts +151 -0
- package/src/testing/anvil_test_watcher.ts +1 -1
- package/src/testing/cheat_codes.ts +1 -1
- package/src/testing/epoch_test_settler.ts +3 -4
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { LogFn, Logger } from '@aztec/foundation/log';
|
|
2
2
|
export declare function aztecStart(options: any, userLog: LogFn, debugLogger: Logger): Promise<void>;
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXp0ZWNfc3RhcnRfYWN0aW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2xpL2F6dGVjX3N0YXJ0X2FjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFPQSxPQUFPLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFhM0Qsd0JBQXNCLFVBQVUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0saUJBMklqRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aztec_start_action.d.ts","sourceRoot":"","sources":["../../src/cli/aztec_start_action.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAa3D,wBAAsB,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"aztec_start_action.d.ts","sourceRoot":"","sources":["../../src/cli/aztec_start_action.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAa3D,wBAAsB,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBA2IjF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getActiveNetworkName } from '@aztec/foundation/config';
|
|
2
2
|
import { createNamespacedSafeJsonRpcServer, getApiKeyAuthMiddleware, startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
3
|
-
import { AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
|
|
3
|
+
import { AztecNodeAdminApiSchema, AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
|
|
4
4
|
import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
5
5
|
import { getVersioningMiddleware } from '@aztec/stdlib/versioning';
|
|
6
6
|
import { getOtelJsonRpcPropagationMiddleware } from '@aztec/telemetry-client';
|
|
@@ -14,13 +14,13 @@ export async function aztecStart(options, userLog, debugLogger) {
|
|
|
14
14
|
const signalHandlers = [];
|
|
15
15
|
const services = {};
|
|
16
16
|
const adminServices = {};
|
|
17
|
+
const packageVersion = getPackageVersion();
|
|
17
18
|
let config = undefined;
|
|
18
19
|
if (options.localNetwork) {
|
|
19
|
-
const cliVersion = getPackageVersion() ?? 'unknown';
|
|
20
20
|
const localNetwork = extractNamespacedOptions(options, 'local-network');
|
|
21
21
|
localNetwork.testAccounts = true;
|
|
22
22
|
userLog(`${splash}\n${github}\n\n`);
|
|
23
|
-
userLog(`Setting up Aztec local network ${
|
|
23
|
+
userLog(`Setting up Aztec local network ${packageVersion ?? 'unknown'}, please stand by...`);
|
|
24
24
|
const { node, stop } = await createLocalNetwork({
|
|
25
25
|
l1Mnemonic: localNetwork.l1Mnemonic,
|
|
26
26
|
l1RpcUrls: options.l1RpcUrls,
|
|
@@ -38,6 +38,10 @@ export async function aztecStart(options, userLog, debugLogger) {
|
|
|
38
38
|
node,
|
|
39
39
|
AztecNodeApiSchema
|
|
40
40
|
];
|
|
41
|
+
adminServices.node = [
|
|
42
|
+
node,
|
|
43
|
+
AztecNodeAdminApiSchema
|
|
44
|
+
];
|
|
41
45
|
} else {
|
|
42
46
|
// Route --prover-node through startNode
|
|
43
47
|
if (options.proverNode && !options.node) {
|
|
@@ -75,6 +79,9 @@ export async function aztecStart(options, userLog, debugLogger) {
|
|
|
75
79
|
}
|
|
76
80
|
installSignalHandlers(debugLogger.info, signalHandlers);
|
|
77
81
|
const versions = getVersions(config);
|
|
82
|
+
const versioningOpts = {
|
|
83
|
+
packageVersion
|
|
84
|
+
};
|
|
78
85
|
// Start the main JSON-RPC server
|
|
79
86
|
if (Object.entries(services).length > 0) {
|
|
80
87
|
const rpcServer = createNamespacedSafeJsonRpcServer(services, {
|
|
@@ -82,7 +89,7 @@ export async function aztecStart(options, userLog, debugLogger) {
|
|
|
82
89
|
log: debugLogger,
|
|
83
90
|
middlewares: [
|
|
84
91
|
getOtelJsonRpcPropagationMiddleware(),
|
|
85
|
-
getVersioningMiddleware(versions)
|
|
92
|
+
getVersioningMiddleware(versions, versioningOpts)
|
|
86
93
|
],
|
|
87
94
|
maxBatchSize: options.rpcMaxBatchSize,
|
|
88
95
|
maxBodySizeBytes: options.rpcMaxBodySize
|
|
@@ -96,7 +103,7 @@ export async function aztecStart(options, userLog, debugLogger) {
|
|
|
96
103
|
if (Object.entries(adminServices).length > 0) {
|
|
97
104
|
const adminMiddlewares = [
|
|
98
105
|
getOtelJsonRpcPropagationMiddleware(),
|
|
99
|
-
getVersioningMiddleware(versions)
|
|
106
|
+
getVersioningMiddleware(versions, versioningOpts)
|
|
100
107
|
];
|
|
101
108
|
// Resolve the admin API key (auto-generated and persisted, or opt-out)
|
|
102
109
|
const apiKeyResolution = await resolveAdminApiKey({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
2
|
import type { Command } from 'commander';
|
|
3
3
|
export declare function injectCompileCommand(program: Command, log: LogFn): Command;
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jbWRzL2NvbXBpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHbkQsT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBb0t6Qyx3QkFBZ0Isb0JBQW9CLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxHQUFHLE9BQU8sQ0FzQjFFIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/compile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/compile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoKzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAsB1E"}
|
package/dest/cli/cmds/compile.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { findBbBinary } from '@aztec/bb.js';
|
|
1
2
|
import { execFileSync } from 'child_process';
|
|
2
3
|
import { readFile, writeFile } from 'fs/promises';
|
|
3
4
|
import { join } from 'path';
|
|
4
5
|
import { readArtifactFiles } from './utils/artifacts.js';
|
|
6
|
+
import { needsRecompile } from './utils/needs_recompile.js';
|
|
5
7
|
import { run } from './utils/spawn.js';
|
|
6
8
|
/** Returns paths to contract artifacts in the target directory. */ async function collectContractArtifacts() {
|
|
7
9
|
let files;
|
|
@@ -116,8 +118,12 @@ import { run } from './utils/spawn.js';
|
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
/** Compiles Aztec Noir contracts and postprocesses artifacts. */ async function compileAztecContract(nargoArgs, log) {
|
|
121
|
+
if (!await needsRecompile()) {
|
|
122
|
+
log('No source changes detected, skipping compilation.');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
119
125
|
const nargo = process.env.NARGO ?? 'nargo';
|
|
120
|
-
const bb = process.env.BB ?? 'bb';
|
|
126
|
+
const bb = process.env.BB ?? findBbBinary() ?? 'bb';
|
|
121
127
|
await run(nargo, [
|
|
122
128
|
'compile',
|
|
123
129
|
...nargoArgs
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
2
|
/** Generates a gate count flamegraph SVG for a single contract function. */
|
|
3
3
|
export declare function profileFlamegraph(artifactPath: string, functionName: string, log: LogFn): Promise<void>;
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZmlsZV9mbGFtZWdyYXBoLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NtZHMvcHJvZmlsZV9mbGFtZWdyYXBoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBU25ELDRFQUE0RTtBQUM1RSx3QkFBc0IsaUJBQWlCLENBQUMsWUFBWSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQW9EN0cifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile_flamegraph.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/profile_flamegraph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"profile_flamegraph.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/profile_flamegraph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AASnD,4EAA4E;AAC5E,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAoD7G"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findBbBinary } from '@aztec/bb.js';
|
|
1
2
|
import { readFile, rename, rm, writeFile } from 'fs/promises';
|
|
2
3
|
import { basename, dirname, join } from 'path';
|
|
3
4
|
import { makeFunctionArtifact } from './profile_utils.js';
|
|
@@ -22,7 +23,7 @@ import { run } from './utils/spawn.js';
|
|
|
22
23
|
try {
|
|
23
24
|
await writeFile(functionArtifact, makeFunctionArtifact(artifact, func));
|
|
24
25
|
const profiler = process.env.PROFILER_PATH ?? 'noir-profiler';
|
|
25
|
-
const bb = process.env.BB ?? 'bb';
|
|
26
|
+
const bb = process.env.BB ?? findBbBinary() ?? 'bb';
|
|
26
27
|
await run(profiler, [
|
|
27
28
|
'gates',
|
|
28
29
|
'--artifact-path',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
2
|
/** Profiles all compiled artifacts in a target directory and prints gate counts. */
|
|
3
3
|
export declare function profileGates(targetDir: string, log: LogFn): Promise<void>;
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZmlsZV9nYXRlcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jbWRzL3Byb2ZpbGVfZ2F0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUErQm5ELG9GQUFvRjtBQUNwRix3QkFBc0IsWUFBWSxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBaUMvRSJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile_gates.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/profile_gates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"profile_gates.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/profile_gates.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AA+BnD,oFAAoF;AACpF,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC/E"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findBbBinary } from '@aztec/bb.js';
|
|
1
2
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
2
3
|
import { execFile as execFileCb } from 'child_process';
|
|
3
4
|
import { rm } from 'fs/promises';
|
|
@@ -23,7 +24,7 @@ const execFile = promisify(execFileCb);
|
|
|
23
24
|
return parseGateCount(stdout);
|
|
24
25
|
}
|
|
25
26
|
/** Profiles all compiled artifacts in a target directory and prints gate counts. */ export async function profileGates(targetDir, log) {
|
|
26
|
-
const bb = process.env.BB ?? 'bb';
|
|
27
|
+
const bb = process.env.BB ?? findBbBinary() ?? 'bb';
|
|
27
28
|
const { artifacts, tmpDir } = await discoverArtifacts(targetDir);
|
|
28
29
|
if (artifacts.length === 0) {
|
|
29
30
|
log('No artifacts found in target directory.');
|
|
@@ -12,9 +12,10 @@ export declare function computeExpectedGenesisRoot(config: GenesisStateConfig, u
|
|
|
12
12
|
prefilledPublicData: import("@aztec/stdlib/trees").PublicDataTreeLeaf[];
|
|
13
13
|
}>;
|
|
14
14
|
/**
|
|
15
|
-
* Waits until the canonical rollup's genesis archive root
|
|
16
|
-
* If the rollup is not yet compatible (e.g. during L1 contract upgrades),
|
|
17
|
-
* starts a lightweight HTTP server for K8s liveness probes and polls every 60s
|
|
15
|
+
* Waits until the canonical rollup's genesis archive root, VK tree root, and protocol contracts hash
|
|
16
|
+
* all match the expected local values. If the rollup is not yet compatible (e.g. during L1 contract upgrades),
|
|
17
|
+
* enters standby mode: starts a lightweight HTTP server for K8s liveness probes and polls every 60s
|
|
18
|
+
* until a compatible rollup appears.
|
|
18
19
|
*/
|
|
19
20
|
export declare function waitForCompatibleRollup(config: {
|
|
20
21
|
l1RpcUrls: string[];
|
|
@@ -23,5 +24,9 @@ export declare function waitForCompatibleRollup(config: {
|
|
|
23
24
|
registryAddress: EthAddress;
|
|
24
25
|
};
|
|
25
26
|
rollupVersion?: number;
|
|
26
|
-
},
|
|
27
|
-
|
|
27
|
+
}, expected: {
|
|
28
|
+
genesisArchiveRoot: Fr;
|
|
29
|
+
vkTreeRoot: Fr;
|
|
30
|
+
protocolContractsHash: Fr;
|
|
31
|
+
}, port: number | undefined, userLog: LogFn): Promise<void>;
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRieS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jbWRzL3N0YW5kYnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHakQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUVqRSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUVoRSxPQUFPLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVNuRDs7OztHQUlHO0FBQ0gsd0JBQXNCLDBCQUEwQixDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsS0FBSzs7O0dBYTFGO0FBd0JEOzs7OztHQUtHO0FBQ0gsd0JBQXNCLHVCQUF1QixDQUMzQyxNQUFNLEVBQUU7SUFDTixTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDcEIsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixXQUFXLEVBQUU7UUFBRSxlQUFlLEVBQUUsVUFBVSxDQUFBO0tBQUUsQ0FBQztJQUM3QyxhQUFhLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDeEIsRUFDRCxRQUFRLEVBQUU7SUFBRSxrQkFBa0IsRUFBRSxFQUFFLENBQUM7SUFBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO0lBQUMscUJBQXFCLEVBQUUsRUFBRSxDQUFBO0NBQUUsRUFDL0UsSUFBSSxFQUFFLE1BQU0sR0FBRyxTQUFTLEVBQ3hCLE9BQU8sRUFBRSxLQUFLLEdBQ2IsT0FBTyxDQUFDLElBQUksQ0FBQyxDQXdEZiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standby.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/standby.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AASnD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,KAAK;;;GAa1F;
|
|
1
|
+
{"version":3,"file":"standby.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/standby.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AASnD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,KAAK;;;GAa1F;AAwBD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE;IACN,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE;QAAE,eAAe,EAAE,UAAU,CAAA;KAAE,CAAC;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,EACD,QAAQ,EAAE;IAAE,kBAAkB,EAAE,EAAE,CAAC;IAAC,UAAU,EAAE,EAAE,CAAC;IAAC,qBAAqB,EAAE,EAAE,CAAA;CAAE,EAC/E,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,KAAK,GACb,OAAO,CAAC,IAAI,CAAC,CAwDf"}
|
package/dest/cli/cmds/standby.js
CHANGED
|
@@ -27,26 +27,45 @@ const ROLLUP_POLL_INTERVAL_S = 60;
|
|
|
27
27
|
prefilledPublicData
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
|
+
async function checkRollupCompatibility(rollup, expected) {
|
|
31
|
+
const mismatches = [];
|
|
32
|
+
const [l1Genesis, l1Vk, l1Protocol] = await Promise.all([
|
|
33
|
+
rollup.getGenesisArchiveTreeRoot(),
|
|
34
|
+
rollup.getVkTreeRoot(),
|
|
35
|
+
rollup.getProtocolContractsHash()
|
|
36
|
+
]);
|
|
37
|
+
if (!l1Genesis.equals(expected.genesisArchiveRoot)) {
|
|
38
|
+
mismatches.push(`genesis archive root (expected ${expected.genesisArchiveRoot}, got ${l1Genesis})`);
|
|
39
|
+
}
|
|
40
|
+
if (!l1Vk.equals(expected.vkTreeRoot)) {
|
|
41
|
+
mismatches.push(`VK tree root (expected ${expected.vkTreeRoot}, got ${l1Vk})`);
|
|
42
|
+
}
|
|
43
|
+
if (!l1Protocol.equals(expected.protocolContractsHash)) {
|
|
44
|
+
mismatches.push(`protocol contracts hash (expected ${expected.protocolContractsHash}, got ${l1Protocol})`);
|
|
45
|
+
}
|
|
46
|
+
return mismatches;
|
|
47
|
+
}
|
|
30
48
|
/**
|
|
31
|
-
* Waits until the canonical rollup's genesis archive root
|
|
32
|
-
* If the rollup is not yet compatible (e.g. during L1 contract upgrades),
|
|
33
|
-
* starts a lightweight HTTP server for K8s liveness probes and polls every 60s
|
|
34
|
-
|
|
49
|
+
* Waits until the canonical rollup's genesis archive root, VK tree root, and protocol contracts hash
|
|
50
|
+
* all match the expected local values. If the rollup is not yet compatible (e.g. during L1 contract upgrades),
|
|
51
|
+
* enters standby mode: starts a lightweight HTTP server for K8s liveness probes and polls every 60s
|
|
52
|
+
* until a compatible rollup appears.
|
|
53
|
+
*/ export async function waitForCompatibleRollup(config, expected, port, userLog) {
|
|
35
54
|
const publicClient = getPublicClient(config);
|
|
36
55
|
const rollupVersion = config.rollupVersion ?? 'canonical';
|
|
37
56
|
const registry = new RegistryContract(publicClient, config.l1Contracts.registryAddress);
|
|
38
57
|
const rollupAddress = await registry.getRollupAddress(rollupVersion);
|
|
39
58
|
const rollup = new RollupContract(publicClient, rollupAddress.toString());
|
|
40
|
-
let
|
|
59
|
+
let mismatches;
|
|
41
60
|
try {
|
|
42
|
-
|
|
61
|
+
mismatches = await checkRollupCompatibility(rollup, expected);
|
|
43
62
|
} catch (err) {
|
|
44
|
-
throw new Error(`Could not retrieve
|
|
63
|
+
throw new Error(`Could not retrieve rollup config from canonical rollup at ${rollupAddress}: ${err.message}`);
|
|
45
64
|
}
|
|
46
|
-
if (
|
|
65
|
+
if (mismatches.length === 0) {
|
|
47
66
|
return;
|
|
48
67
|
}
|
|
49
|
-
userLog(`
|
|
68
|
+
userLog(`Rollup at ${rollupAddress} is incompatible: ${mismatches.join('; ')}. ` + `Entering standby mode. Will poll every ${ROLLUP_POLL_INTERVAL_S}s for a compatible rollup...`);
|
|
50
69
|
const standbyServer = await startHttpRpcServer({
|
|
51
70
|
getApp: ()=>new Koa(),
|
|
52
71
|
isHealthy: ()=>true
|
|
@@ -58,18 +77,18 @@ const ROLLUP_POLL_INTERVAL_S = 60;
|
|
|
58
77
|
await retryUntil(async ()=>{
|
|
59
78
|
const currentRollupAddress = await registry.getRollupAddress(rollupVersion);
|
|
60
79
|
const currentRollup = new RollupContract(publicClient, currentRollupAddress.toString());
|
|
61
|
-
let
|
|
80
|
+
let currentMismatches;
|
|
62
81
|
try {
|
|
63
|
-
|
|
82
|
+
currentMismatches = await checkRollupCompatibility(currentRollup, expected);
|
|
64
83
|
} catch {
|
|
65
|
-
userLog(`Failed to fetch
|
|
84
|
+
userLog(`Failed to fetch rollup config from rollup at ${currentRollupAddress}. Retrying...`);
|
|
66
85
|
return undefined;
|
|
67
86
|
}
|
|
68
|
-
if (
|
|
87
|
+
if (currentMismatches.length === 0) {
|
|
69
88
|
userLog(`Compatible rollup found at ${currentRollupAddress}. Exiting standby mode.`);
|
|
70
89
|
return true;
|
|
71
90
|
}
|
|
72
|
-
userLog(`Still waiting. Rollup at ${currentRollupAddress}
|
|
91
|
+
userLog(`Still waiting. Rollup at ${currentRollupAddress}: ${currentMismatches.join('; ')}.`);
|
|
73
92
|
return undefined;
|
|
74
93
|
}, 'compatible rollup', 0, ROLLUP_POLL_INTERVAL_S);
|
|
75
94
|
} finally{
|
|
@@ -5,4 +5,4 @@ import type { LogFn } from '@aztec/foundation/log';
|
|
|
5
5
|
export declare function startNode(options: any, signalHandlers: (() => Promise<void>)[], services: NamespacedApiHandlers, adminServices: NamespacedApiHandlers, userLog: LogFn, networkName: NetworkNames): Promise<{
|
|
6
6
|
config: AztecNodeConfig;
|
|
7
7
|
}>;
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnRfbm9kZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jbWRzL3N0YXJ0X25vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUE2QyxNQUFNLG1CQUFtQixDQUFDO0FBS3BHLE9BQU8sRUFBRSxLQUFLLFlBQVksRUFBZSxNQUFNLDBCQUEwQixDQUFDO0FBQzFFLE9BQU8sS0FBSyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFL0UsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUEwQm5ELHdCQUFzQixTQUFTLENBQzdCLE9BQU8sRUFBRSxHQUFHLEVBQ1osY0FBYyxFQUFFLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUN2QyxRQUFRLEVBQUUscUJBQXFCLEVBQy9CLGFBQWEsRUFBRSxxQkFBcUIsRUFDcEMsT0FBTyxFQUFFLEtBQUssRUFDZCxXQUFXLEVBQUUsWUFBWSxHQUN4QixPQUFPLENBQUM7SUFBRSxNQUFNLEVBQUUsZUFBZSxDQUFBO0NBQUUsQ0FBQyxDQW9LdEMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start_node.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/start_node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAA6C,MAAM,mBAAmB,CAAC;AAKpG,OAAO,EAAE,KAAK,YAAY,EAAe,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"start_node.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/start_node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAA6C,MAAM,mBAAmB,CAAC;AAKpG,OAAO,EAAE,KAAK,YAAY,EAAe,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AA0BnD,wBAAsB,SAAS,CAC7B,OAAO,EAAE,GAAG,EACZ,cAAc,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EACvC,QAAQ,EAAE,qBAAqB,EAC/B,aAAa,EAAE,qBAAqB,EACpC,OAAO,EAAE,KAAK,EACd,WAAW,EAAE,YAAY,GACxB,OAAO,CAAC;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC,CAoKtC"}
|
|
@@ -5,6 +5,8 @@ import { getPublicClient } from '@aztec/ethereum/client';
|
|
|
5
5
|
import { getGenesisStateConfigEnvVars } from '@aztec/ethereum/config';
|
|
6
6
|
import { SecretValue } from '@aztec/foundation/config';
|
|
7
7
|
import { Agent, makeUndiciFetch } from '@aztec/foundation/json-rpc/undici';
|
|
8
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
9
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
8
10
|
import { ProvingJobConsumerSchema, createProvingJobBrokerClient } from '@aztec/prover-client/broker';
|
|
9
11
|
import { allPxeConfigMappings } from '@aztec/pxe/config';
|
|
10
12
|
import { AztecNodeAdminApiSchema, AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
|
|
@@ -70,7 +72,11 @@ export async function startNode(options, signalHandlers, services, adminServices
|
|
|
70
72
|
}
|
|
71
73
|
// Wait for a compatible rollup before proceeding with full L1 config fetch.
|
|
72
74
|
// This prevents crashes when the canonical rollup hasn't been upgraded yet.
|
|
73
|
-
await waitForCompatibleRollup(nodeConfig,
|
|
75
|
+
await waitForCompatibleRollup(nodeConfig, {
|
|
76
|
+
genesisArchiveRoot,
|
|
77
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
78
|
+
protocolContractsHash
|
|
79
|
+
}, options.port, userLog);
|
|
74
80
|
const { addresses, config } = await getL1Config(nodeConfig.l1Contracts.registryAddress, nodeConfig.l1RpcUrls, nodeConfig.l1ChainId, nodeConfig.rollupVersion);
|
|
75
81
|
process.env.ROLLUP_CONTRACT_ADDRESS ??= addresses.rollupAddress.toString();
|
|
76
82
|
if (!Fr.fromHexString(config.genesisArchiveTreeRoot).equals(genesisArchiveRoot)) {
|
|
@@ -6,4 +6,4 @@ export declare function startProverBroker(options: any, signalHandlers: (() => P
|
|
|
6
6
|
broker: ProvingJobBroker;
|
|
7
7
|
config: ProverBrokerConfig;
|
|
8
8
|
}>;
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnRfcHJvdmVyX2Jyb2tlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jbWRzL3N0YXJ0X3Byb3Zlcl9icm9rZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxLQUFLLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUMvRSxPQUFPLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUduRCxPQUFPLEVBQ0wsS0FBSyxrQkFBa0IsRUFLeEIsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBTXhFLHdCQUFzQixpQkFBaUIsQ0FDckMsT0FBTyxFQUFFLEdBQUcsRUFDWixjQUFjLEVBQUUsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQ3ZDLFFBQVEsRUFBRSxxQkFBcUIsRUFDL0IsT0FBTyxFQUFFLEtBQUssR0FDYixPQUFPLENBQUM7SUFBRSxNQUFNLEVBQUUsZ0JBQWdCLENBQUM7SUFBQyxNQUFNLEVBQUUsa0JBQWtCLENBQUE7Q0FBRSxDQUFDLENBNENuRSJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start_prover_broker.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/start_prover_broker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"start_prover_broker.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/start_prover_broker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAMxE,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,GAAG,EACZ,cAAc,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EACvC,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,KAAK,GACb,OAAO,CAAC;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAC,CA4CnE"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getL1Config } from '@aztec/cli/config';
|
|
2
2
|
import { getGenesisStateConfigEnvVars } from '@aztec/ethereum/config';
|
|
3
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
4
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
3
5
|
import { ProvingJobBrokerSchema, ProvingJobBrokerSchemaWithDebug, createAndStartProvingBroker, proverBrokerConfigMappings } from '@aztec/prover-client/broker';
|
|
4
6
|
import { getProverNodeBrokerConfigFromEnv } from '@aztec/prover-node';
|
|
5
7
|
import { getConfigEnvVars as getTelemetryClientConfig, initTelemetryClient } from '@aztec/telemetry-client';
|
|
@@ -19,7 +21,11 @@ export async function startProverBroker(options, signalHandlers, services, userL
|
|
|
19
21
|
}
|
|
20
22
|
const genesisConfig = getGenesisStateConfigEnvVars();
|
|
21
23
|
const { genesisArchiveRoot } = await computeExpectedGenesisRoot(genesisConfig, userLog);
|
|
22
|
-
await waitForCompatibleRollup(config,
|
|
24
|
+
await waitForCompatibleRollup(config, {
|
|
25
|
+
genesisArchiveRoot,
|
|
26
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
27
|
+
protocolContractsHash
|
|
28
|
+
}, options.port, userLog);
|
|
23
29
|
const { addresses, config: rollupConfig } = await getL1Config(config.l1Contracts.registryAddress, config.l1RpcUrls, config.l1ChainId, config.rollupVersion);
|
|
24
30
|
config.l1Contracts = addresses;
|
|
25
31
|
config.rollupVersion = rollupConfig.rollupVersion;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if recompilation is needed: either no artifacts exist in target/ or any .nr or Nargo.toml source file
|
|
3
|
+
* (including path-based dependencies) is newer than the oldest artifact. We compare against the oldest artifact so
|
|
4
|
+
* that a source change between the oldest and newest compilation (e.g. in a multi-contract workspace) still triggers
|
|
5
|
+
* a recompile.
|
|
6
|
+
*
|
|
7
|
+
* Note: The above implies that if there is a random json file in the target dir we would be always recompiling.
|
|
8
|
+
*/
|
|
9
|
+
export declare function needsRecompile(): Promise<boolean>;
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVlZHNfcmVjb21waWxlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2xpL2NtZHMvdXRpbHMvbmVlZHNfcmVjb21waWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlBOzs7Ozs7O0dBT0c7QUFDSCx3QkFBc0IsY0FBYyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FRdkQifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"needs_recompile.d.ts","sourceRoot":"","sources":["../../../../src/cli/cmds/utils/needs_recompile.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAQvD"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import TOML from '@iarna/toml';
|
|
2
|
+
import { readFile, readdir, stat } from 'fs/promises';
|
|
3
|
+
import { join, resolve } from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Returns true if recompilation is needed: either no artifacts exist in target/ or any .nr or Nargo.toml source file
|
|
6
|
+
* (including path-based dependencies) is newer than the oldest artifact. We compare against the oldest artifact so
|
|
7
|
+
* that a source change between the oldest and newest compilation (e.g. in a multi-contract workspace) still triggers
|
|
8
|
+
* a recompile.
|
|
9
|
+
*
|
|
10
|
+
* Note: The above implies that if there is a random json file in the target dir we would be always recompiling.
|
|
11
|
+
*/ export async function needsRecompile() {
|
|
12
|
+
const oldestArtifactMs = await getOldestArtifactModificationTime('target');
|
|
13
|
+
if (oldestArtifactMs === undefined) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
const crateDirs = await collectCrateDirs('.');
|
|
17
|
+
return hasNewerSourceFile(crateDirs, oldestArtifactMs);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns the last modification time (timestamp in ms) of the oldest .json artifact in targetDir, or undefined if
|
|
21
|
+
* none exist.
|
|
22
|
+
*/ async function getOldestArtifactModificationTime(targetDir) {
|
|
23
|
+
let entries;
|
|
24
|
+
try {
|
|
25
|
+
entries = (await readdir(targetDir)).filter((f)=>f.endsWith('.json'));
|
|
26
|
+
} catch (err) {
|
|
27
|
+
if (err?.code === 'ENOENT') {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
if (entries.length === 0) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
let oldest = Infinity;
|
|
36
|
+
for (const entry of entries){
|
|
37
|
+
const s = await stat(join(targetDir, entry));
|
|
38
|
+
if (s.mtimeMs < oldest) {
|
|
39
|
+
oldest = s.mtimeMs;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return oldest;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Recursively collects crate directories starting from startCrateDir by following path-based dependencies declared in
|
|
46
|
+
* Nargo.toml files. Git-based deps are ignored (they only change when Nargo.toml itself is modified since the deps are
|
|
47
|
+
* tagged).
|
|
48
|
+
*/ async function collectCrateDirs(startCrateDir) {
|
|
49
|
+
// We have a set of visited dirs we check against when entering a new dir because we could stumble upon a directory
|
|
50
|
+
// multiple times in case multiple deps shared a dep (e.g. dep A and dep B both sharing dep C).
|
|
51
|
+
const visited = new Set();
|
|
52
|
+
async function visit(crateDir) {
|
|
53
|
+
const absDir = resolve(crateDir);
|
|
54
|
+
if (visited.has(absDir)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
visited.add(absDir);
|
|
58
|
+
// Every dep is its own crate and every crate needs to have Nargo.toml defined in the root so we try to load it and
|
|
59
|
+
// error out if it's not the case.
|
|
60
|
+
const tomlPath = join(absDir, 'Nargo.toml');
|
|
61
|
+
const content = await readFile(tomlPath, 'utf-8').catch(()=>{
|
|
62
|
+
throw new Error(`Incorrectly defined dependency. Nargo.toml not found in ${absDir}`);
|
|
63
|
+
});
|
|
64
|
+
const parsed = TOML.parse(content);
|
|
65
|
+
const members = parsed.workspace?.members;
|
|
66
|
+
// A Nargo.toml is either a workspace root (has workspace.members) or a single crate (has dependencies).
|
|
67
|
+
if (Array.isArray(members)) {
|
|
68
|
+
// The crate is a workspace root and has members defined so we visit the members
|
|
69
|
+
for (const member of members){
|
|
70
|
+
const memberPath = resolve(absDir, member);
|
|
71
|
+
await visit(memberPath);
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
// The crate is not a workspace root so we check for dependencies
|
|
75
|
+
const deps = parsed.dependencies ?? {};
|
|
76
|
+
for (const dep of Object.values(deps)){
|
|
77
|
+
if (dep && typeof dep === 'object' && typeof dep.path === 'string') {
|
|
78
|
+
const depPath = resolve(absDir, dep.path);
|
|
79
|
+
const s = await stat(depPath);
|
|
80
|
+
if (!s.isDirectory()) {
|
|
81
|
+
throw new Error(`Dependency path "${dep.path}" in ${tomlPath} resolves to ${depPath} which is not a directory`);
|
|
82
|
+
}
|
|
83
|
+
await visit(depPath);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
await visit(startCrateDir);
|
|
89
|
+
return [
|
|
90
|
+
...visited
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Walks crate dirs looking for .nr and Nargo.toml files newer than thresholdMs. Short-circuits on the first match.
|
|
95
|
+
*/ async function hasNewerSourceFile(crateDirs, thresholdMs) {
|
|
96
|
+
// Returns true if it find a new file than thresholdMs, false otherwise
|
|
97
|
+
async function walkForNewer(dir) {
|
|
98
|
+
let entries;
|
|
99
|
+
try {
|
|
100
|
+
entries = await readdir(dir, {
|
|
101
|
+
withFileTypes: true
|
|
102
|
+
});
|
|
103
|
+
} catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
// We iterate over the entries in the dir
|
|
107
|
+
for (const entry of entries){
|
|
108
|
+
const fullPath = join(dir, entry.name);
|
|
109
|
+
if (entry.isDirectory()) {
|
|
110
|
+
// If the entry is a dir and it's not called `target` we recursively enter it
|
|
111
|
+
if (entry.name === 'target') {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (await walkForNewer(fullPath)) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
} else if (entry.name === 'Nargo.toml' || entry.name.endsWith('.nr')) {
|
|
118
|
+
// The entry is a Nargo.toml file or *.nr file so we check the timestamp
|
|
119
|
+
const s = await stat(fullPath);
|
|
120
|
+
if (s.mtimeMs > thresholdMs) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
// We search through the crate dirs
|
|
128
|
+
for (const dir of crateDirs){
|
|
129
|
+
if (await walkForNewer(dir)) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
@@ -101,7 +101,7 @@ import { getAddress, getContract } from 'viem';
|
|
|
101
101
|
if (!this.dateProvider) {
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
|
-
const l1Time = await this.cheatcodes.
|
|
104
|
+
const l1Time = await this.cheatcodes.lastBlockTimestamp() * 1000;
|
|
105
105
|
const wallTime = this.dateProvider.now();
|
|
106
106
|
if (l1Time > wallTime) {
|
|
107
107
|
this.logger.warn(`L1 is ahead of wall time. Syncing wall time to L1 time`);
|
|
@@ -55,7 +55,7 @@ import { retryUntil } from '@aztec/foundation/retry';
|
|
|
55
55
|
* @param node - The Aztec node used to query if a new block has been mined.
|
|
56
56
|
* @param duration - The duration to advance time by (in seconds)
|
|
57
57
|
*/ async warpL2TimeAtLeastBy(sequencerClient, node, duration) {
|
|
58
|
-
const currentTimestamp = await this.eth.
|
|
58
|
+
const currentTimestamp = await this.eth.lastBlockTimestamp();
|
|
59
59
|
const targetTimestamp = BigInt(currentTimestamp) + BigInt(duration);
|
|
60
60
|
await this.warpL2TimeAtLeastTo(sequencerClient, node, targetTimestamp);
|
|
61
61
|
}
|
|
@@ -16,4 +16,4 @@ export declare class EpochTestSettler {
|
|
|
16
16
|
stop(): Promise<void>;
|
|
17
17
|
handleEpochReadyToProve(epoch: EpochNumber): Promise<boolean>;
|
|
18
18
|
}
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfdGVzdF9zZXR0bGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdGluZy9lcG9jaF90ZXN0X3NldHRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLEtBQUssYUFBYSxFQUFvQixNQUFNLHNCQUFzQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxLQUFLLFdBQVcsRUFBYyxNQUFNLGlDQUFpQyxDQUFDO0FBQy9FLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXBELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUdyRSxxQkFBYSxnQkFBZ0I7SUFPekIsT0FBTyxDQUFDLGFBQWE7SUFDckIsT0FBTyxDQUFDLEdBQUc7SUFDWCxPQUFPLENBQUMsT0FBTztJQVJqQixPQUFPLENBQUMsZ0JBQWdCLENBQW1CO0lBQzNDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBZTtJQUVwQyxZQUNFLFVBQVUsRUFBRSxhQUFhLEVBQ3pCLGFBQWEsRUFBRSxVQUFVLEVBQ2pCLGFBQWEsRUFBRSxhQUFhLEVBQzVCLEdBQUcsRUFBRSxNQUFNLEVBQ1gsT0FBTyxFQUFFO1FBQUUsaUJBQWlCLEVBQUUsTUFBTSxDQUFDO1FBQUMsY0FBYyxDQUFDLEVBQUUsTUFBTSxDQUFBO0tBQUUsRUFHeEU7SUFFSyxLQUFLLGtCQUlWO0lBRUssSUFBSSxrQkFFVDtJQUVLLHVCQUF1QixDQUFDLEtBQUssRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQW9DbEU7Q0FDRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epoch_test_settler.d.ts","sourceRoot":"","sources":["../../src/testing/epoch_test_settler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,iCAAiC,CAAC;AAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGrE,qBAAa,gBAAgB;IAOzB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,OAAO;IARjB,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,YAAY,CAAC,CAAe;IAEpC,YACE,UAAU,EAAE,aAAa,EACzB,aAAa,EAAE,UAAU,EACjB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,EAGxE;IAEK,KAAK,kBAIV;IAEK,IAAI,kBAET;IAEK,uBAAuB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"epoch_test_settler.d.ts","sourceRoot":"","sources":["../../src/testing/epoch_test_settler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,iCAAiC,CAAC;AAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGrE,qBAAa,gBAAgB;IAOzB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,OAAO;IARjB,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,YAAY,CAAC,CAAe;IAEpC,YACE,UAAU,EAAE,aAAa,EACzB,aAAa,EAAE,UAAU,EACjB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,EAGxE;IAEK,KAAK,kBAIV;IAEK,IAAI,kBAET;IAEK,uBAAuB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAoClE;CACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RollupCheatCodes } from '@aztec/ethereum/test';
|
|
2
2
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { EpochMonitor } from '@aztec/prover-node';
|
|
4
|
-
import {
|
|
4
|
+
import { computeEpochOutHash } from '@aztec/stdlib/messaging';
|
|
5
5
|
export class EpochTestSettler {
|
|
6
6
|
l2BlockSource;
|
|
7
7
|
log;
|
|
@@ -44,9 +44,8 @@ export class EpochTestSettler {
|
|
|
44
44
|
}
|
|
45
45
|
messagesInEpoch[checkpointIndex].push(block.body.txEffects.map((txEffect)=>txEffect.l2ToL1Msgs));
|
|
46
46
|
}
|
|
47
|
-
const
|
|
48
|
-
if (
|
|
49
|
-
const { root: outHash } = computeL2ToL1MembershipWitnessFromMessagesInEpoch(messagesInEpoch, firstMessage);
|
|
47
|
+
const outHash = computeEpochOutHash(messagesInEpoch);
|
|
48
|
+
if (!outHash.isZero()) {
|
|
50
49
|
await this.rollupCheatCodes.insertOutbox(epoch, outHash.toBigInt());
|
|
51
50
|
} else {
|
|
52
51
|
this.log.info(`No L2 to L1 messages in epoch ${epoch}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/aztec",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.cbf2c2d5d",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -28,39 +28,39 @@
|
|
|
28
28
|
"../package.common.json"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@aztec/accounts": "0.0.1-commit.
|
|
32
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
33
|
-
"@aztec/aztec-
|
|
34
|
-
"@aztec/aztec
|
|
35
|
-
"@aztec/
|
|
36
|
-
"@aztec/bb
|
|
37
|
-
"@aztec/
|
|
38
|
-
"@aztec/
|
|
39
|
-
"@aztec/
|
|
40
|
-
"@aztec/
|
|
41
|
-
"@aztec/
|
|
42
|
-
"@aztec/
|
|
43
|
-
"@aztec/
|
|
44
|
-
"@aztec/
|
|
45
|
-
"@aztec/
|
|
46
|
-
"@aztec/
|
|
47
|
-
"@aztec/
|
|
48
|
-
"@aztec/
|
|
49
|
-
"@aztec/noir-
|
|
50
|
-
"@aztec/
|
|
51
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
52
|
-
"@aztec/
|
|
53
|
-
"@aztec/
|
|
54
|
-
"@aztec/prover-
|
|
55
|
-
"@aztec/
|
|
56
|
-
"@aztec/
|
|
57
|
-
"@aztec/
|
|
58
|
-
"@aztec/
|
|
59
|
-
"@aztec/
|
|
60
|
-
"@aztec/
|
|
61
|
-
"@aztec/
|
|
62
|
-
"@aztec/
|
|
63
|
-
"@
|
|
31
|
+
"@aztec/accounts": "0.0.1-commit.cbf2c2d5d",
|
|
32
|
+
"@aztec/archiver": "0.0.1-commit.cbf2c2d5d",
|
|
33
|
+
"@aztec/aztec-node": "0.0.1-commit.cbf2c2d5d",
|
|
34
|
+
"@aztec/aztec.js": "0.0.1-commit.cbf2c2d5d",
|
|
35
|
+
"@aztec/bb-prover": "0.0.1-commit.cbf2c2d5d",
|
|
36
|
+
"@aztec/bb.js": "0.0.1-commit.cbf2c2d5d",
|
|
37
|
+
"@aztec/blob-client": "0.0.1-commit.cbf2c2d5d",
|
|
38
|
+
"@aztec/bot": "0.0.1-commit.cbf2c2d5d",
|
|
39
|
+
"@aztec/builder": "0.0.1-commit.cbf2c2d5d",
|
|
40
|
+
"@aztec/cli": "0.0.1-commit.cbf2c2d5d",
|
|
41
|
+
"@aztec/constants": "0.0.1-commit.cbf2c2d5d",
|
|
42
|
+
"@aztec/entrypoints": "0.0.1-commit.cbf2c2d5d",
|
|
43
|
+
"@aztec/ethereum": "0.0.1-commit.cbf2c2d5d",
|
|
44
|
+
"@aztec/foundation": "0.0.1-commit.cbf2c2d5d",
|
|
45
|
+
"@aztec/kv-store": "0.0.1-commit.cbf2c2d5d",
|
|
46
|
+
"@aztec/l1-artifacts": "0.0.1-commit.cbf2c2d5d",
|
|
47
|
+
"@aztec/node-lib": "0.0.1-commit.cbf2c2d5d",
|
|
48
|
+
"@aztec/noir-contracts.js": "0.0.1-commit.cbf2c2d5d",
|
|
49
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.cbf2c2d5d",
|
|
50
|
+
"@aztec/p2p": "0.0.1-commit.cbf2c2d5d",
|
|
51
|
+
"@aztec/p2p-bootstrap": "0.0.1-commit.cbf2c2d5d",
|
|
52
|
+
"@aztec/protocol-contracts": "0.0.1-commit.cbf2c2d5d",
|
|
53
|
+
"@aztec/prover-client": "0.0.1-commit.cbf2c2d5d",
|
|
54
|
+
"@aztec/prover-node": "0.0.1-commit.cbf2c2d5d",
|
|
55
|
+
"@aztec/pxe": "0.0.1-commit.cbf2c2d5d",
|
|
56
|
+
"@aztec/sequencer-client": "0.0.1-commit.cbf2c2d5d",
|
|
57
|
+
"@aztec/stdlib": "0.0.1-commit.cbf2c2d5d",
|
|
58
|
+
"@aztec/telemetry-client": "0.0.1-commit.cbf2c2d5d",
|
|
59
|
+
"@aztec/txe": "0.0.1-commit.cbf2c2d5d",
|
|
60
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.cbf2c2d5d",
|
|
61
|
+
"@aztec/wallets": "0.0.1-commit.cbf2c2d5d",
|
|
62
|
+
"@aztec/world-state": "0.0.1-commit.cbf2c2d5d",
|
|
63
|
+
"@iarna/toml": "^2.2.5",
|
|
64
64
|
"@types/chalk": "^2.2.0",
|
|
65
65
|
"abitype": "^0.8.11",
|
|
66
66
|
"chalk": "^5.3.0",
|
package/scripts/aztec.sh
CHANGED
|
@@ -20,6 +20,9 @@ function aztec {
|
|
|
20
20
|
|
|
21
21
|
case $cmd in
|
|
22
22
|
test)
|
|
23
|
+
# Attempt to compile, no-op if there are no changes
|
|
24
|
+
node --no-warnings "$script_dir/../dest/bin/index.js" compile
|
|
25
|
+
|
|
23
26
|
export LOG_LEVEL="${LOG_LEVEL:-"error;trace:contract_log"}"
|
|
24
27
|
aztec start --txe --port 8081 &
|
|
25
28
|
server_pid=$!
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '@aztec/foundation/json-rpc/server';
|
|
8
8
|
import type { LogFn, Logger } from '@aztec/foundation/log';
|
|
9
9
|
import type { ChainConfig } from '@aztec/stdlib/config';
|
|
10
|
-
import { AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
|
|
10
|
+
import { AztecNodeAdminApiSchema, AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
|
|
11
11
|
import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
12
12
|
import { getVersioningMiddleware } from '@aztec/stdlib/versioning';
|
|
13
13
|
import { getOtelJsonRpcPropagationMiddleware } from '@aztec/telemetry-client';
|
|
@@ -23,14 +23,14 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
|
|
|
23
23
|
const signalHandlers: Array<() => Promise<void>> = [];
|
|
24
24
|
const services: NamespacedApiHandlers = {};
|
|
25
25
|
const adminServices: NamespacedApiHandlers = {};
|
|
26
|
+
const packageVersion = getPackageVersion();
|
|
26
27
|
let config: ChainConfig | undefined = undefined;
|
|
27
28
|
|
|
28
29
|
if (options.localNetwork) {
|
|
29
|
-
const cliVersion = getPackageVersion() ?? 'unknown';
|
|
30
30
|
const localNetwork = extractNamespacedOptions(options, 'local-network');
|
|
31
31
|
localNetwork.testAccounts = true;
|
|
32
32
|
userLog(`${splash}\n${github}\n\n`);
|
|
33
|
-
userLog(`Setting up Aztec local network ${
|
|
33
|
+
userLog(`Setting up Aztec local network ${packageVersion ?? 'unknown'}, please stand by...`);
|
|
34
34
|
|
|
35
35
|
const { node, stop } = await createLocalNetwork(
|
|
36
36
|
{
|
|
@@ -50,6 +50,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
|
|
|
50
50
|
// Start Node and PXE JSON-RPC server
|
|
51
51
|
signalHandlers.push(stop);
|
|
52
52
|
services.node = [node, AztecNodeApiSchema];
|
|
53
|
+
adminServices.node = [node, AztecNodeAdminApiSchema];
|
|
53
54
|
} else {
|
|
54
55
|
// Route --prover-node through startNode
|
|
55
56
|
if (options.proverNode && !options.node) {
|
|
@@ -89,13 +90,14 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
|
|
|
89
90
|
|
|
90
91
|
installSignalHandlers(debugLogger.info, signalHandlers);
|
|
91
92
|
const versions = getVersions(config);
|
|
93
|
+
const versioningOpts = { packageVersion };
|
|
92
94
|
|
|
93
95
|
// Start the main JSON-RPC server
|
|
94
96
|
if (Object.entries(services).length > 0) {
|
|
95
97
|
const rpcServer = createNamespacedSafeJsonRpcServer(services, {
|
|
96
98
|
http200OnError: false,
|
|
97
99
|
log: debugLogger,
|
|
98
|
-
middlewares: [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions)],
|
|
100
|
+
middlewares: [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions, versioningOpts)],
|
|
99
101
|
maxBatchSize: options.rpcMaxBatchSize,
|
|
100
102
|
maxBodySizeBytes: options.rpcMaxBodySize,
|
|
101
103
|
});
|
|
@@ -105,7 +107,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
|
|
|
105
107
|
|
|
106
108
|
// If there are any admin services, start a separate JSON-RPC server for them
|
|
107
109
|
if (Object.entries(adminServices).length > 0) {
|
|
108
|
-
const adminMiddlewares = [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions)];
|
|
110
|
+
const adminMiddlewares = [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions, versioningOpts)];
|
|
109
111
|
|
|
110
112
|
// Resolve the admin API key (auto-generated and persisted, or opt-out)
|
|
111
113
|
const apiKeyResolution = await resolveAdminApiKey(
|
package/src/cli/cmds/compile.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findBbBinary } from '@aztec/bb.js';
|
|
1
2
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
3
|
|
|
3
4
|
import { execFileSync } from 'child_process';
|
|
@@ -6,6 +7,7 @@ import { readFile, writeFile } from 'fs/promises';
|
|
|
6
7
|
import { join } from 'path';
|
|
7
8
|
|
|
8
9
|
import { readArtifactFiles } from './utils/artifacts.js';
|
|
10
|
+
import { needsRecompile } from './utils/needs_recompile.js';
|
|
9
11
|
import { run } from './utils/spawn.js';
|
|
10
12
|
|
|
11
13
|
/** Returns paths to contract artifacts in the target directory. */
|
|
@@ -137,8 +139,13 @@ async function checkNoTestsInContracts(nargo: string, log: LogFn): Promise<void>
|
|
|
137
139
|
|
|
138
140
|
/** Compiles Aztec Noir contracts and postprocesses artifacts. */
|
|
139
141
|
async function compileAztecContract(nargoArgs: string[], log: LogFn): Promise<void> {
|
|
142
|
+
if (!(await needsRecompile())) {
|
|
143
|
+
log('No source changes detected, skipping compilation.');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
140
147
|
const nargo = process.env.NARGO ?? 'nargo';
|
|
141
|
-
const bb = process.env.BB ?? 'bb';
|
|
148
|
+
const bb = process.env.BB ?? findBbBinary() ?? 'bb';
|
|
142
149
|
|
|
143
150
|
await run(nargo, ['compile', ...nargoArgs]);
|
|
144
151
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findBbBinary } from '@aztec/bb.js';
|
|
1
2
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
3
|
|
|
3
4
|
import { readFile, rename, rm, writeFile } from 'fs/promises';
|
|
@@ -33,7 +34,7 @@ export async function profileFlamegraph(artifactPath: string, functionName: stri
|
|
|
33
34
|
await writeFile(functionArtifact, makeFunctionArtifact(artifact, func));
|
|
34
35
|
|
|
35
36
|
const profiler = process.env.PROFILER_PATH ?? 'noir-profiler';
|
|
36
|
-
const bb = process.env.BB ?? 'bb';
|
|
37
|
+
const bb = process.env.BB ?? findBbBinary() ?? 'bb';
|
|
37
38
|
|
|
38
39
|
await run(profiler, [
|
|
39
40
|
'gates',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findBbBinary } from '@aztec/bb.js';
|
|
1
2
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
2
3
|
import type { LogFn } from '@aztec/foundation/log';
|
|
3
4
|
|
|
@@ -32,7 +33,7 @@ async function getGateCount(bb: string, artifactPath: string): Promise<number> {
|
|
|
32
33
|
|
|
33
34
|
/** Profiles all compiled artifacts in a target directory and prints gate counts. */
|
|
34
35
|
export async function profileGates(targetDir: string, log: LogFn): Promise<void> {
|
|
35
|
-
const bb = process.env.BB ?? 'bb';
|
|
36
|
+
const bb = process.env.BB ?? findBbBinary() ?? 'bb';
|
|
36
37
|
const { artifacts, tmpDir } = await discoverArtifacts(targetDir);
|
|
37
38
|
|
|
38
39
|
if (artifacts.length === 0) {
|
package/src/cli/cmds/standby.ts
CHANGED
|
@@ -35,10 +35,33 @@ export async function computeExpectedGenesisRoot(config: GenesisStateConfig, use
|
|
|
35
35
|
return { genesisArchiveRoot, prefilledPublicData };
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
async function checkRollupCompatibility(
|
|
39
|
+
rollup: RollupContract,
|
|
40
|
+
expected: { genesisArchiveRoot: Fr; vkTreeRoot: Fr; protocolContractsHash: Fr },
|
|
41
|
+
): Promise<string[]> {
|
|
42
|
+
const mismatches: string[] = [];
|
|
43
|
+
const [l1Genesis, l1Vk, l1Protocol] = await Promise.all([
|
|
44
|
+
rollup.getGenesisArchiveTreeRoot(),
|
|
45
|
+
rollup.getVkTreeRoot(),
|
|
46
|
+
rollup.getProtocolContractsHash(),
|
|
47
|
+
]);
|
|
48
|
+
if (!l1Genesis.equals(expected.genesisArchiveRoot)) {
|
|
49
|
+
mismatches.push(`genesis archive root (expected ${expected.genesisArchiveRoot}, got ${l1Genesis})`);
|
|
50
|
+
}
|
|
51
|
+
if (!l1Vk.equals(expected.vkTreeRoot)) {
|
|
52
|
+
mismatches.push(`VK tree root (expected ${expected.vkTreeRoot}, got ${l1Vk})`);
|
|
53
|
+
}
|
|
54
|
+
if (!l1Protocol.equals(expected.protocolContractsHash)) {
|
|
55
|
+
mismatches.push(`protocol contracts hash (expected ${expected.protocolContractsHash}, got ${l1Protocol})`);
|
|
56
|
+
}
|
|
57
|
+
return mismatches;
|
|
58
|
+
}
|
|
59
|
+
|
|
38
60
|
/**
|
|
39
|
-
* Waits until the canonical rollup's genesis archive root
|
|
40
|
-
* If the rollup is not yet compatible (e.g. during L1 contract upgrades),
|
|
41
|
-
* starts a lightweight HTTP server for K8s liveness probes and polls every 60s
|
|
61
|
+
* Waits until the canonical rollup's genesis archive root, VK tree root, and protocol contracts hash
|
|
62
|
+
* all match the expected local values. If the rollup is not yet compatible (e.g. during L1 contract upgrades),
|
|
63
|
+
* enters standby mode: starts a lightweight HTTP server for K8s liveness probes and polls every 60s
|
|
64
|
+
* until a compatible rollup appears.
|
|
42
65
|
*/
|
|
43
66
|
export async function waitForCompatibleRollup(
|
|
44
67
|
config: {
|
|
@@ -47,7 +70,7 @@ export async function waitForCompatibleRollup(
|
|
|
47
70
|
l1Contracts: { registryAddress: EthAddress };
|
|
48
71
|
rollupVersion?: number;
|
|
49
72
|
},
|
|
50
|
-
|
|
73
|
+
expected: { genesisArchiveRoot: Fr; vkTreeRoot: Fr; protocolContractsHash: Fr },
|
|
51
74
|
port: number | undefined,
|
|
52
75
|
userLog: LogFn,
|
|
53
76
|
): Promise<void> {
|
|
@@ -58,21 +81,19 @@ export async function waitForCompatibleRollup(
|
|
|
58
81
|
const rollupAddress = await registry.getRollupAddress(rollupVersion);
|
|
59
82
|
const rollup = new RollupContract(publicClient, rollupAddress.toString());
|
|
60
83
|
|
|
61
|
-
let
|
|
84
|
+
let mismatches: string[];
|
|
62
85
|
try {
|
|
63
|
-
|
|
86
|
+
mismatches = await checkRollupCompatibility(rollup, expected);
|
|
64
87
|
} catch (err: any) {
|
|
65
|
-
throw new Error(
|
|
66
|
-
`Could not retrieve genesis archive root from canonical rollup at ${rollupAddress}: ${err.message}`,
|
|
67
|
-
);
|
|
88
|
+
throw new Error(`Could not retrieve rollup config from canonical rollup at ${rollupAddress}: ${err.message}`);
|
|
68
89
|
}
|
|
69
90
|
|
|
70
|
-
if (
|
|
91
|
+
if (mismatches.length === 0) {
|
|
71
92
|
return;
|
|
72
93
|
}
|
|
73
94
|
|
|
74
95
|
userLog(
|
|
75
|
-
`
|
|
96
|
+
`Rollup at ${rollupAddress} is incompatible: ${mismatches.join('; ')}. ` +
|
|
76
97
|
`Entering standby mode. Will poll every ${ROLLUP_POLL_INTERVAL_S}s for a compatible rollup...`,
|
|
77
98
|
);
|
|
78
99
|
|
|
@@ -85,20 +106,20 @@ export async function waitForCompatibleRollup(
|
|
|
85
106
|
const currentRollupAddress = await registry.getRollupAddress(rollupVersion);
|
|
86
107
|
const currentRollup = new RollupContract(publicClient, currentRollupAddress.toString());
|
|
87
108
|
|
|
88
|
-
let
|
|
109
|
+
let currentMismatches: string[];
|
|
89
110
|
try {
|
|
90
|
-
|
|
111
|
+
currentMismatches = await checkRollupCompatibility(currentRollup, expected);
|
|
91
112
|
} catch {
|
|
92
|
-
userLog(`Failed to fetch
|
|
113
|
+
userLog(`Failed to fetch rollup config from rollup at ${currentRollupAddress}. Retrying...`);
|
|
93
114
|
return undefined;
|
|
94
115
|
}
|
|
95
116
|
|
|
96
|
-
if (
|
|
117
|
+
if (currentMismatches.length === 0) {
|
|
97
118
|
userLog(`Compatible rollup found at ${currentRollupAddress}. Exiting standby mode.`);
|
|
98
119
|
return true;
|
|
99
120
|
}
|
|
100
121
|
|
|
101
|
-
userLog(`Still waiting. Rollup at ${currentRollupAddress}
|
|
122
|
+
userLog(`Still waiting. Rollup at ${currentRollupAddress}: ${currentMismatches.join('; ')}.`);
|
|
102
123
|
return undefined;
|
|
103
124
|
},
|
|
104
125
|
'compatible rollup',
|
|
@@ -7,6 +7,8 @@ import { type NetworkNames, SecretValue } from '@aztec/foundation/config';
|
|
|
7
7
|
import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
8
8
|
import { Agent, makeUndiciFetch } from '@aztec/foundation/json-rpc/undici';
|
|
9
9
|
import type { LogFn } from '@aztec/foundation/log';
|
|
10
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
11
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
10
12
|
import { ProvingJobConsumerSchema, createProvingJobBrokerClient } from '@aztec/prover-client/broker';
|
|
11
13
|
import { type CliPXEOptions, type PXEConfig, allPxeConfigMappings } from '@aztec/pxe/config';
|
|
12
14
|
import { AztecNodeAdminApiSchema, AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
|
|
@@ -92,7 +94,12 @@ export async function startNode(
|
|
|
92
94
|
|
|
93
95
|
// Wait for a compatible rollup before proceeding with full L1 config fetch.
|
|
94
96
|
// This prevents crashes when the canonical rollup hasn't been upgraded yet.
|
|
95
|
-
await waitForCompatibleRollup(
|
|
97
|
+
await waitForCompatibleRollup(
|
|
98
|
+
nodeConfig,
|
|
99
|
+
{ genesisArchiveRoot, vkTreeRoot: getVKTreeRoot(), protocolContractsHash },
|
|
100
|
+
options.port,
|
|
101
|
+
userLog,
|
|
102
|
+
);
|
|
96
103
|
|
|
97
104
|
const { addresses, config } = await getL1Config(
|
|
98
105
|
nodeConfig.l1Contracts.registryAddress,
|
|
@@ -2,6 +2,8 @@ import { getL1Config } from '@aztec/cli/config';
|
|
|
2
2
|
import { getGenesisStateConfigEnvVars } from '@aztec/ethereum/config';
|
|
3
3
|
import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
4
4
|
import type { LogFn } from '@aztec/foundation/log';
|
|
5
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
6
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
5
7
|
import {
|
|
6
8
|
type ProverBrokerConfig,
|
|
7
9
|
ProvingJobBrokerSchema,
|
|
@@ -38,7 +40,12 @@ export async function startProverBroker(
|
|
|
38
40
|
|
|
39
41
|
const genesisConfig = getGenesisStateConfigEnvVars();
|
|
40
42
|
const { genesisArchiveRoot } = await computeExpectedGenesisRoot(genesisConfig, userLog);
|
|
41
|
-
await waitForCompatibleRollup(
|
|
43
|
+
await waitForCompatibleRollup(
|
|
44
|
+
config,
|
|
45
|
+
{ genesisArchiveRoot, vkTreeRoot: getVKTreeRoot(), protocolContractsHash },
|
|
46
|
+
options.port,
|
|
47
|
+
userLog,
|
|
48
|
+
);
|
|
42
49
|
|
|
43
50
|
const { addresses, config: rollupConfig } = await getL1Config(
|
|
44
51
|
config.l1Contracts.registryAddress,
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import TOML from '@iarna/toml';
|
|
2
|
+
import { readFile, readdir, stat } from 'fs/promises';
|
|
3
|
+
import { join, resolve } from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns true if recompilation is needed: either no artifacts exist in target/ or any .nr or Nargo.toml source file
|
|
7
|
+
* (including path-based dependencies) is newer than the oldest artifact. We compare against the oldest artifact so
|
|
8
|
+
* that a source change between the oldest and newest compilation (e.g. in a multi-contract workspace) still triggers
|
|
9
|
+
* a recompile.
|
|
10
|
+
*
|
|
11
|
+
* Note: The above implies that if there is a random json file in the target dir we would be always recompiling.
|
|
12
|
+
*/
|
|
13
|
+
export async function needsRecompile(): Promise<boolean> {
|
|
14
|
+
const oldestArtifactMs = await getOldestArtifactModificationTime('target');
|
|
15
|
+
if (oldestArtifactMs === undefined) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const crateDirs = await collectCrateDirs('.');
|
|
20
|
+
return hasNewerSourceFile(crateDirs, oldestArtifactMs);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns the last modification time (timestamp in ms) of the oldest .json artifact in targetDir, or undefined if
|
|
25
|
+
* none exist.
|
|
26
|
+
*/
|
|
27
|
+
async function getOldestArtifactModificationTime(targetDir: string): Promise<number | undefined> {
|
|
28
|
+
let entries: string[];
|
|
29
|
+
try {
|
|
30
|
+
entries = (await readdir(targetDir)).filter(f => f.endsWith('.json'));
|
|
31
|
+
} catch (err: any) {
|
|
32
|
+
if (err?.code === 'ENOENT') {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (entries.length === 0) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let oldest = Infinity;
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
const s = await stat(join(targetDir, entry));
|
|
45
|
+
if (s.mtimeMs < oldest) {
|
|
46
|
+
oldest = s.mtimeMs;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return oldest;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Recursively collects crate directories starting from startCrateDir by following path-based dependencies declared in
|
|
54
|
+
* Nargo.toml files. Git-based deps are ignored (they only change when Nargo.toml itself is modified since the deps are
|
|
55
|
+
* tagged).
|
|
56
|
+
*/
|
|
57
|
+
async function collectCrateDirs(startCrateDir: string): Promise<string[]> {
|
|
58
|
+
// We have a set of visited dirs we check against when entering a new dir because we could stumble upon a directory
|
|
59
|
+
// multiple times in case multiple deps shared a dep (e.g. dep A and dep B both sharing dep C).
|
|
60
|
+
const visited = new Set<string>();
|
|
61
|
+
|
|
62
|
+
async function visit(crateDir: string): Promise<void> {
|
|
63
|
+
const absDir = resolve(crateDir);
|
|
64
|
+
if (visited.has(absDir)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
visited.add(absDir);
|
|
68
|
+
|
|
69
|
+
// Every dep is its own crate and every crate needs to have Nargo.toml defined in the root so we try to load it and
|
|
70
|
+
// error out if it's not the case.
|
|
71
|
+
const tomlPath = join(absDir, 'Nargo.toml');
|
|
72
|
+
const content = await readFile(tomlPath, 'utf-8').catch(() => {
|
|
73
|
+
throw new Error(`Incorrectly defined dependency. Nargo.toml not found in ${absDir}`);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const parsed = TOML.parse(content) as Record<string, any>;
|
|
77
|
+
|
|
78
|
+
const members = (parsed.workspace as Record<string, any>)?.members as string[] | undefined;
|
|
79
|
+
|
|
80
|
+
// A Nargo.toml is either a workspace root (has workspace.members) or a single crate (has dependencies).
|
|
81
|
+
if (Array.isArray(members)) {
|
|
82
|
+
// The crate is a workspace root and has members defined so we visit the members
|
|
83
|
+
for (const member of members) {
|
|
84
|
+
const memberPath = resolve(absDir, member);
|
|
85
|
+
await visit(memberPath);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
// The crate is not a workspace root so we check for dependencies
|
|
89
|
+
const deps = (parsed.dependencies as Record<string, any>) ?? {};
|
|
90
|
+
for (const dep of Object.values(deps)) {
|
|
91
|
+
if (dep && typeof dep === 'object' && typeof dep.path === 'string') {
|
|
92
|
+
const depPath = resolve(absDir, dep.path);
|
|
93
|
+
const s = await stat(depPath);
|
|
94
|
+
if (!s.isDirectory()) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Dependency path "${dep.path}" in ${tomlPath} resolves to ${depPath} which is not a directory`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
await visit(depPath);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
await visit(startCrateDir);
|
|
106
|
+
return [...visited];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Walks crate dirs looking for .nr and Nargo.toml files newer than thresholdMs. Short-circuits on the first match.
|
|
111
|
+
*/
|
|
112
|
+
async function hasNewerSourceFile(crateDirs: string[], thresholdMs: number): Promise<boolean> {
|
|
113
|
+
// Returns true if it find a new file than thresholdMs, false otherwise
|
|
114
|
+
async function walkForNewer(dir: string): Promise<boolean> {
|
|
115
|
+
let entries;
|
|
116
|
+
try {
|
|
117
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
118
|
+
} catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// We iterate over the entries in the dir
|
|
123
|
+
for (const entry of entries) {
|
|
124
|
+
const fullPath = join(dir, entry.name);
|
|
125
|
+
if (entry.isDirectory()) {
|
|
126
|
+
// If the entry is a dir and it's not called `target` we recursively enter it
|
|
127
|
+
if (entry.name === 'target') {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (await walkForNewer(fullPath)) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
} else if (entry.name === 'Nargo.toml' || entry.name.endsWith('.nr')) {
|
|
134
|
+
// The entry is a Nargo.toml file or *.nr file so we check the timestamp
|
|
135
|
+
const s = await stat(fullPath);
|
|
136
|
+
if (s.mtimeMs > thresholdMs) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// We search through the crate dirs
|
|
145
|
+
for (const dir of crateDirs) {
|
|
146
|
+
if (await walkForNewer(dir)) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
@@ -130,7 +130,7 @@ export class AnvilTestWatcher {
|
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
const l1Time = (await this.cheatcodes.
|
|
133
|
+
const l1Time = (await this.cheatcodes.lastBlockTimestamp()) * 1000;
|
|
134
134
|
const wallTime = this.dateProvider.now();
|
|
135
135
|
if (l1Time > wallTime) {
|
|
136
136
|
this.logger.warn(`L1 is ahead of wall time. Syncing wall time to L1 time`);
|
|
@@ -72,7 +72,7 @@ export class CheatCodes {
|
|
|
72
72
|
* @param duration - The duration to advance time by (in seconds)
|
|
73
73
|
*/
|
|
74
74
|
async warpL2TimeAtLeastBy(sequencerClient: SequencerClient, node: AztecNode, duration: bigint | number) {
|
|
75
|
-
const currentTimestamp = await this.eth.
|
|
75
|
+
const currentTimestamp = await this.eth.lastBlockTimestamp();
|
|
76
76
|
const targetTimestamp = BigInt(currentTimestamp) + BigInt(duration);
|
|
77
77
|
await this.warpL2TimeAtLeastTo(sequencerClient, node, targetTimestamp);
|
|
78
78
|
}
|
|
@@ -4,7 +4,7 @@ import { type EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
|
4
4
|
import type { Logger } from '@aztec/foundation/log';
|
|
5
5
|
import { EpochMonitor } from '@aztec/prover-node';
|
|
6
6
|
import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
|
|
7
|
-
import {
|
|
7
|
+
import { computeEpochOutHash } from '@aztec/stdlib/messaging';
|
|
8
8
|
|
|
9
9
|
export class EpochTestSettler {
|
|
10
10
|
private rollupCheatCodes: RollupCheatCodes;
|
|
@@ -51,9 +51,8 @@ export class EpochTestSettler {
|
|
|
51
51
|
messagesInEpoch[checkpointIndex].push(block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs));
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
const { root: outHash } = computeL2ToL1MembershipWitnessFromMessagesInEpoch(messagesInEpoch, firstMessage);
|
|
54
|
+
const outHash = computeEpochOutHash(messagesInEpoch);
|
|
55
|
+
if (!outHash.isZero()) {
|
|
57
56
|
await this.rollupCheatCodes.insertOutbox(epoch, outHash.toBigInt());
|
|
58
57
|
} else {
|
|
59
58
|
this.log.info(`No L2 to L1 messages in epoch ${epoch}`);
|