@aztec/aztec 4.4.0-nightly.20260618 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/cli/aztec_start_options.js +1 -1
- package/dest/cli/cmds/standby.d.ts +28 -2
- package/dest/cli/cmds/standby.d.ts.map +1 -1
- package/dest/cli/cmds/standby.js +44 -1
- 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 +8 -6
- package/dest/cli/util.d.ts +10 -5
- package/dest/cli/util.d.ts.map +1 -1
- package/dest/cli/util.js +19 -48
- package/package.json +34 -34
- package/src/cli/aztec_start_options.ts +1 -1
- package/src/cli/cmds/standby.ts +54 -2
- package/src/cli/cmds/start_node.ts +8 -15
- package/src/cli/util.ts +20 -61
|
@@ -76,7 +76,7 @@ export const aztecStartOptions = {
|
|
|
76
76
|
defaultValue: undefined,
|
|
77
77
|
env: 'NETWORK'
|
|
78
78
|
},
|
|
79
|
-
configToFlag('--enable-
|
|
79
|
+
configToFlag('--enable-auto-shutdown', sharedNodeConfigMappings.enableAutoShutdown),
|
|
80
80
|
configToFlag('--sync-mode', sharedNodeConfigMappings.syncMode),
|
|
81
81
|
configToFlag('--snapshots-urls', sharedNodeConfigMappings.snapshotsUrls),
|
|
82
82
|
configToFlag('--fisherman-mode', sharedNodeConfigMappings.fishermanMode)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Fr } from '@aztec/aztec.js/fields';
|
|
2
2
|
import type { GenesisStateConfig } from '@aztec/ethereum/config';
|
|
3
|
+
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
3
4
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
-
import type
|
|
5
|
+
import { type LogFn } from '@aztec/foundation/log';
|
|
5
6
|
/**
|
|
6
7
|
* Computes the expected genesis archive root from the genesis state config.
|
|
7
8
|
* Reads test accounts and sponsored FPC addresses as specified, then computes
|
|
@@ -11,6 +12,16 @@ export declare function computeExpectedGenesisRoot(config: GenesisStateConfig, u
|
|
|
11
12
|
genesisArchiveRoot: Fr;
|
|
12
13
|
prefilledPublicData: import("@aztec/stdlib/trees").PublicDataTreeLeaf[];
|
|
13
14
|
}>;
|
|
15
|
+
/**
|
|
16
|
+
* Compares the rollup's on-chain protocol constants (genesis archive root, VK tree root, protocol
|
|
17
|
+
* contracts hash) against the node's expected local values. Returns a list of human-readable mismatch
|
|
18
|
+
* descriptions, empty if the rollup is compatible.
|
|
19
|
+
*/
|
|
20
|
+
export declare function checkRollupCompatibility(rollup: RollupContract, expected: {
|
|
21
|
+
genesisArchiveRoot: Fr;
|
|
22
|
+
vkTreeRoot: Fr;
|
|
23
|
+
protocolContractsHash: Fr;
|
|
24
|
+
}): Promise<string[]>;
|
|
14
25
|
/**
|
|
15
26
|
* Waits until the canonical rollup's genesis archive root, VK tree root, and protocol contracts hash
|
|
16
27
|
* all match the expected local values. If the rollup is not yet compatible (e.g. during L1 contract upgrades),
|
|
@@ -29,4 +40,19 @@ export declare function waitForCompatibleRollup(config: {
|
|
|
29
40
|
vkTreeRoot: Fr;
|
|
30
41
|
protocolContractsHash: Fr;
|
|
31
42
|
}, port: number | undefined, userLog: LogFn): Promise<void>;
|
|
32
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Polls the canonical rollup's protocol constants every 10 minutes and soft-shuts-down the node once they
|
|
45
|
+
* diverge from the node's expected local values (i.e. an incompatible rollup has become canonical on L1).
|
|
46
|
+
* The HTTP health server is left running so K8s probes keep passing on the wound-down pod. This is the
|
|
47
|
+
* inverse of {@link waitForCompatibleRollup}; it should only be set up for nodes following the canonical
|
|
48
|
+
* rollup. Reuses the {@link checkRollupCompatibility} diff and the generic VersionChecker poll primitive.
|
|
49
|
+
*/
|
|
50
|
+
export declare function setupAutoShutdown(config: {
|
|
51
|
+
l1RpcUrls: string[];
|
|
52
|
+
l1ChainId: number;
|
|
53
|
+
}, registryAddress: EthAddress, rollupVersion: number | 'canonical', expected: {
|
|
54
|
+
genesisArchiveRoot: Fr;
|
|
55
|
+
vkTreeRoot: Fr;
|
|
56
|
+
protocolContractsHash: Fr;
|
|
57
|
+
}, signalHandlers: Array<() => Promise<void>>): Promise<void>;
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRieS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jbWRzL3N0YW5kYnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHakQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRSxPQUFPLEVBQW9CLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdFLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRWhFLE9BQU8sRUFBRSxLQUFLLEtBQUssRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQVlqRTs7OztHQUlHO0FBQ0gsd0JBQXNCLDBCQUEwQixDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsS0FBSzs7O0dBYTFGO0FBRUQ7Ozs7R0FJRztBQUNILHdCQUFzQix3QkFBd0IsQ0FDNUMsTUFBTSxFQUFFLGNBQWMsRUFDdEIsUUFBUSxFQUFFO0lBQUUsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO0lBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztJQUFDLHFCQUFxQixFQUFFLEVBQUUsQ0FBQTtDQUFFLEdBQzlFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQWlCbkI7QUFFRDs7Ozs7R0FLRztBQUNILHdCQUFzQix1QkFBdUIsQ0FDM0MsTUFBTSxFQUFFO0lBQ04sU0FBUyxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQ3BCLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsV0FBVyxFQUFFO1FBQUUsZUFBZSxFQUFFLFVBQVUsQ0FBQTtLQUFFLENBQUM7SUFDN0MsYUFBYSxDQUFDLEVBQUUsTUFBTSxDQUFDO0NBQ3hCLEVBQ0QsUUFBUSxFQUFFO0lBQUUsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO0lBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztJQUFDLHFCQUFxQixFQUFFLEVBQUUsQ0FBQTtDQUFFLEVBQy9FLElBQUksRUFBRSxNQUFNLEdBQUcsU0FBUyxFQUN4QixPQUFPLEVBQUUsS0FBSyxHQUNiLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0F3RGY7QUFFRDs7Ozs7O0dBTUc7QUFDSCx3QkFBc0IsaUJBQWlCLENBQ3JDLE1BQU0sRUFBRTtJQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUFDLFNBQVMsRUFBRSxNQUFNLENBQUE7Q0FBRSxFQUNsRCxlQUFlLEVBQUUsVUFBVSxFQUMzQixhQUFhLEVBQUUsTUFBTSxHQUFHLFdBQVcsRUFDbkMsUUFBUSxFQUFFO0lBQUUsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO0lBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztJQUFDLHFCQUFxQixFQUFFLEVBQUUsQ0FBQTtDQUFFLEVBQy9FLGNBQWMsRUFBRSxLQUFLLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FDekMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQTZCZiJ9
|
|
@@ -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;
|
|
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;AACjE,OAAO,EAAoB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,KAAK,KAAK,EAAgB,MAAM,uBAAuB,CAAC;AAYjE;;;;GAIG;AACH,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,KAAK;;;GAa1F;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE;IAAE,kBAAkB,EAAE,EAAE,CAAC;IAAC,UAAU,EAAE,EAAE,CAAC;IAAC,qBAAqB,EAAE,EAAE,CAAA;CAAE,GAC9E,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBnB;AAED;;;;;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;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAClD,eAAe,EAAE,UAAU,EAC3B,aAAa,EAAE,MAAM,GAAG,WAAW,EACnC,QAAQ,EAAE;IAAE,kBAAkB,EAAE,EAAE,CAAC;IAAC,UAAU,EAAE,EAAE,CAAC;IAAC,qBAAqB,EAAE,EAAE,CAAA;CAAE,EAC/E,cAAc,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
|
package/dest/cli/cmds/standby.js
CHANGED
|
@@ -3,10 +3,12 @@ import { getSponsoredFPCAddress } from '@aztec/cli/cli-utils';
|
|
|
3
3
|
import { getPublicClient } from '@aztec/ethereum/client';
|
|
4
4
|
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
5
5
|
import { startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
6
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
6
7
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
7
8
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
9
|
import { getGenesisValues } from '@aztec/world-state/testing';
|
|
9
10
|
import Koa from 'koa';
|
|
11
|
+
import { isShuttingDown, softShutdown } from '../util.js';
|
|
10
12
|
const ROLLUP_POLL_INTERVAL_S = 60;
|
|
11
13
|
/**
|
|
12
14
|
* Computes the expected genesis archive root from the genesis state config.
|
|
@@ -27,7 +29,11 @@ const ROLLUP_POLL_INTERVAL_S = 60;
|
|
|
27
29
|
prefilledPublicData
|
|
28
30
|
};
|
|
29
31
|
}
|
|
30
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Compares the rollup's on-chain protocol constants (genesis archive root, VK tree root, protocol
|
|
34
|
+
* contracts hash) against the node's expected local values. Returns a list of human-readable mismatch
|
|
35
|
+
* descriptions, empty if the rollup is compatible.
|
|
36
|
+
*/ export async function checkRollupCompatibility(rollup, expected) {
|
|
31
37
|
const mismatches = [];
|
|
32
38
|
const [l1Genesis, l1Vk, l1Protocol] = await Promise.all([
|
|
33
39
|
rollup.getGenesisArchiveTreeRoot(),
|
|
@@ -95,3 +101,40 @@ async function checkRollupCompatibility(rollup, expected) {
|
|
|
95
101
|
await new Promise((resolve, reject)=>standbyServer.close((err)=>err ? reject(err) : resolve()));
|
|
96
102
|
}
|
|
97
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Polls the canonical rollup's protocol constants every 10 minutes and soft-shuts-down the node once they
|
|
106
|
+
* diverge from the node's expected local values (i.e. an incompatible rollup has become canonical on L1).
|
|
107
|
+
* The HTTP health server is left running so K8s probes keep passing on the wound-down pod. This is the
|
|
108
|
+
* inverse of {@link waitForCompatibleRollup}; it should only be set up for nodes following the canonical
|
|
109
|
+
* rollup. Reuses the {@link checkRollupCompatibility} diff and the generic VersionChecker poll primitive.
|
|
110
|
+
*/ export async function setupAutoShutdown(config, registryAddress, rollupVersion, expected, signalHandlers) {
|
|
111
|
+
const { VersionChecker } = await import('@aztec/stdlib/update-checker');
|
|
112
|
+
const logger = createLogger('auto_shutdown');
|
|
113
|
+
const publicClient = getPublicClient(config);
|
|
114
|
+
const registry = new RegistryContract(publicClient, registryAddress);
|
|
115
|
+
const check = {
|
|
116
|
+
name: 'rollup',
|
|
117
|
+
currentVersion: 'compatible',
|
|
118
|
+
getLatestVersion: async ()=>{
|
|
119
|
+
const rollupAddress = await registry.getRollupAddress(rollupVersion);
|
|
120
|
+
const rollup = new RollupContract(publicClient, rollupAddress.toString());
|
|
121
|
+
const mismatches = await checkRollupCompatibility(rollup, expected);
|
|
122
|
+
return mismatches.length === 0 ? 'compatible' : `incompatible: ${mismatches.join('; ')}`;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const checker = new VersionChecker([
|
|
126
|
+
check
|
|
127
|
+
], 600_000, logger);
|
|
128
|
+
checker.on('newVersion', ({ latestVersion })=>{
|
|
129
|
+
if (isShuttingDown()) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
logger.warn('Canonical rollup is no longer compatible; auto-shutting down node', {
|
|
133
|
+
latestVersion
|
|
134
|
+
});
|
|
135
|
+
// softShutdown never rejects (it awaits handlers via allSettled); fire-and-forget from the listener.
|
|
136
|
+
void softShutdown(logger.info.bind(logger), signalHandlers);
|
|
137
|
+
});
|
|
138
|
+
checker.start();
|
|
139
|
+
signalHandlers.push(()=>checker.stop());
|
|
140
|
+
}
|
|
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnRfbm9kZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jbWRzL3N0YXJ0X25vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUE2QyxNQUFNLG1CQUFtQixDQUFDO0FBSXBHLE9BQU8sRUFBRSxLQUFLLFlBQVksRUFBZSxNQUFNLDBCQUEwQixDQUFDO0FBQzFFLE9BQU8sS0FBSyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFL0UsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUF5Qm5ELHdCQUFzQixTQUFTLENBQzdCLE9BQU8sRUFBRSxHQUFHLEVBQ1osY0FBYyxFQUFFLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUN2QyxRQUFRLEVBQUUscUJBQXFCLEVBQy9CLGFBQWEsRUFBRSxxQkFBcUIsRUFDcEMsT0FBTyxFQUFFLEtBQUssRUFDZCxXQUFXLEVBQUUsWUFBWSxHQUN4QixPQUFPLENBQUM7SUFBRSxNQUFNLEVBQUUsZUFBZSxDQUFBO0NBQUUsQ0FBQyxDQStKdEMifQ==
|
|
@@ -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;
|
|
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;AAIpG,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;AAyBnD,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,CA+JtC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { aztecNodeConfigMappings, getConfigEnvVars } from '@aztec/aztec-node';
|
|
2
2
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
3
3
|
import { getL1Config } from '@aztec/cli/config';
|
|
4
|
-
import { getPublicClient } from '@aztec/ethereum/client';
|
|
5
4
|
import { getGenesisStateConfigEnvVars } from '@aztec/ethereum/config';
|
|
6
5
|
import { SecretValue } from '@aztec/foundation/config';
|
|
7
6
|
import { Agent, makeUndiciFetch } from '@aztec/foundation/json-rpc/undici';
|
|
@@ -14,9 +13,9 @@ import { P2PApiSchema, ProverNodeApiSchema } from '@aztec/stdlib/interfaces/serv
|
|
|
14
13
|
import { initTelemetryClient, makeTracedFetch, telemetryClientConfigMappings } from '@aztec/telemetry-client';
|
|
15
14
|
import { EmbeddedWallet } from '@aztec/wallets/embedded';
|
|
16
15
|
import { createAztecNode } from '../../local-network/index.js';
|
|
17
|
-
import { extractNamespacedOptions, extractRelevantOptions, preloadCrsDataForVerifying
|
|
16
|
+
import { extractNamespacedOptions, extractRelevantOptions, preloadCrsDataForVerifying } from '../util.js';
|
|
18
17
|
import { getVersions } from '../versioning.js';
|
|
19
|
-
import { computeExpectedGenesisRoot, waitForCompatibleRollup } from './standby.js';
|
|
18
|
+
import { computeExpectedGenesisRoot, setupAutoShutdown, waitForCompatibleRollup } from './standby.js';
|
|
20
19
|
import { startProverBroker } from './start_prover_broker.js';
|
|
21
20
|
export async function startNode(options, signalHandlers, services, adminServices, userLog, networkName) {
|
|
22
21
|
// All options set from environment variables
|
|
@@ -149,10 +148,13 @@ export async function startNode(options, signalHandlers, services, adminServices
|
|
|
149
148
|
});
|
|
150
149
|
await addBot(options, signalHandlers, services, wallet, node, telemetry, undefined);
|
|
151
150
|
}
|
|
152
|
-
if (nodeConfig.
|
|
153
|
-
const cacheDir = process.env.DATA_DIRECTORY ? `${process.env.DATA_DIRECTORY}/cache` : undefined;
|
|
151
|
+
if (nodeConfig.enableAutoShutdown && networkName !== 'local' && followsCanonicalRollup) {
|
|
154
152
|
try {
|
|
155
|
-
await
|
|
153
|
+
await setupAutoShutdown(nodeConfig, nodeConfig.l1Contracts.registryAddress, nodeConfig.rollupVersion ?? 'canonical', {
|
|
154
|
+
genesisArchiveRoot,
|
|
155
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
156
|
+
protocolContractsHash
|
|
157
|
+
}, signalHandlers);
|
|
156
158
|
} catch {
|
|
157
159
|
/* no-op */ }
|
|
158
160
|
}
|
package/dest/cli/util.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { AztecNodeConfig } from '@aztec/aztec-node';
|
|
2
2
|
import type { AccountManager } from '@aztec/aztec.js/wallet';
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import { type LogFn } from '@aztec/foundation/log';
|
|
3
|
+
import type { ConfigMappingsType } from '@aztec/foundation/config';
|
|
4
|
+
import type { LogFn } from '@aztec/foundation/log';
|
|
6
5
|
import type { ProverConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
6
|
import type { EmbeddedWallet } from '@aztec/wallets/embedded';
|
|
8
7
|
import type { Command } from 'commander';
|
|
@@ -19,6 +18,13 @@ export declare const enum ExitCode {
|
|
|
19
18
|
}
|
|
20
19
|
export declare function shutdown(logFn: LogFn, exitCode: ExitCode, cb?: Array<() => Promise<void>>): Promise<never>;
|
|
21
20
|
export declare function isShuttingDown(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Stops the node's subsystems (via the registered signal handlers) without exiting the process, leaving
|
|
23
|
+
* the HTTP health server listening so K8s liveness/readiness probes keep passing. Unlike {@link shutdown}
|
|
24
|
+
* this deliberately does not latch `shutdownPromise` or call `process.exit`; instead it re-arms
|
|
25
|
+
* SIGTERM/SIGINT so a later K8s pod deletion still terminates the wound-down pod with a clean exit.
|
|
26
|
+
*/
|
|
27
|
+
export declare function softShutdown(logFn: LogFn, signalHandlers: Array<() => Promise<void>>): Promise<void>;
|
|
22
28
|
export declare const installSignalHandlers: (logFn: LogFn, cb?: (() => Promise<void>)[] | undefined) => void;
|
|
23
29
|
/**
|
|
24
30
|
* Creates logs for the initial accounts
|
|
@@ -61,6 +67,5 @@ export declare function preloadCrsDataForVerifying({ realProofs }: Pick<AztecNod
|
|
|
61
67
|
* @param log - Logging function
|
|
62
68
|
*/
|
|
63
69
|
export declare function preloadCrsDataForServerSideProving({ realProofs }: Pick<ProverConfig, 'realProofs'>, log: LogFn): Promise<void>;
|
|
64
|
-
export declare function setupVersionChecker(network: NetworkNames, followsCanonicalRollup: boolean, publicClient: ViemClient, signalHandlers: Array<() => Promise<void>>, cacheDir?: string): Promise<void>;
|
|
65
70
|
export declare function stringifyConfig(config: object): string;
|
|
66
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
71
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdELE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFbkUsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDcEUsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHOUQsT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXpDLE9BQU8sRUFBRSxLQUFLLGdCQUFnQixFQUFxQixNQUFNLDBCQUEwQixDQUFDO0FBRXBGLDBCQUFrQixRQUFRO0lBQ3hCLE9BQU8sSUFBSTtJQUNYLEtBQUssSUFBSTtJQUNULGNBQWMsS0FBSztJQUNuQixlQUFlLEtBQUs7SUFFcEIsTUFBTSxNQUFNO0lBQ1osTUFBTSxNQUFNO0lBQ1osT0FBTyxNQUFNO0lBQ2IsT0FBTyxNQUFNO0NBQ2Q7QUFHRCx3QkFBZ0IsUUFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBZ0IxRztBQUVELHdCQUFnQixjQUFjLElBQUksT0FBTyxDQUV4QztBQUVEOzs7OztHQUtHO0FBQ0gsd0JBQXNCLFlBQVksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxLQUFLLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBVTFHO0FBRUQsZUFBTyxNQUFNLHFCQUFxQixrRUFhakMsQ0FBQztBQUVGOzs7OztHQUtHO0FBQ0gsd0JBQXNCLGlCQUFpQixDQUFDLGVBQWUsRUFBRSxjQUFjLEVBQUUsRUFBRSxNQUFNLEVBQUUsY0FBYyxxQkF5QmhHO0FBRUQsd0JBQWdCLGFBQWEsQ0FBQyxRQUFRLEVBQUU7SUFBRSxDQUFDLEdBQUcsRUFBRSxNQUFNLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQTtDQUFFLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBaUIvRjtBQUVELHdCQUFnQixjQUFjLENBQzVCLE1BQU0sRUFBRSxNQUFNLEVBQ2QsWUFBWSxFQUFFLE1BQU0sRUFDcEIsTUFBTSxFQUFFLE1BQU0sRUFDZCxlQUFlLEVBQUUsTUFBTSxFQUN2QixnQkFBZ0IsRUFBRSxNQUFNLEdBQ3ZCLE1BQU0sQ0FLUjtBQWlDRCxlQUFPLE1BQU0sVUFBVSxxREFTdEIsQ0FBQztBQUVGLGVBQU8sTUFBTSx1QkFBdUIsY0F5Qm5DLENBQUM7QUFFRjs7Ozs7R0FLRztBQUNILGVBQU8sTUFBTSx3QkFBd0IsMEVBU3BDLENBQUM7QUFFRjs7Ozs7OztHQU9HO0FBQ0gsZUFBTyxNQUFNLHNCQUFzQixHQUFJLENBQUMsd0ZBa0N2QyxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILHdCQUFzQiwwQkFBMEIsQ0FDOUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxFQUNuRCxHQUFHLEVBQUUsS0FBSyxHQUNULE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FLZjtBQUVEOzs7O0dBSUc7QUFDSCx3QkFBc0Isa0NBQWtDLENBQ3RELEVBQUUsVUFBVSxFQUFFLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsRUFDaEQsR0FBRyxFQUFFLEtBQUssR0FDVCxPQUFPLENBQUMsSUFBSSxDQUFDLENBS2Y7QUFFRCx3QkFBZ0IsZUFBZSxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsTUFBTSxDQUl0RCJ9
|
package/dest/cli/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/cli/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/cli/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,KAAK,gBAAgB,EAAqB,MAAM,0BAA0B,CAAC;AAEpF,0BAAkB,QAAQ;IACxB,OAAO,IAAI;IACX,KAAK,IAAI;IACT,cAAc,KAAK;IACnB,eAAe,KAAK;IAEpB,MAAM,MAAM;IACZ,MAAM,MAAM;IACZ,OAAO,MAAM;IACb,OAAO,MAAM;CACd;AAGD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAgB1G;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1G;AAED,eAAO,MAAM,qBAAqB,kEAajC,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,eAAe,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,cAAc,qBAyBhG;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAAA;CAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAiB/F;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAKR;AAiCD,eAAO,MAAM,UAAU,qDAStB,CAAC;AAEF,eAAO,MAAM,uBAAuB,cAyBnC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,0EASpC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAAI,CAAC,wFAkCvC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,EAAE,UAAU,EAAE,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,EACnD,GAAG,EAAE,KAAK,GACT,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;;GAIG;AACH,wBAAsB,kCAAkC,CACtD,EAAE,UAAU,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,EAChD,GAAG,EAAE,KAAK,GACT,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAItD"}
|
package/dest/cli/util.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import { getNetworkConfig } from '@aztec/cli/config';
|
|
2
|
-
import { RegistryContract } from '@aztec/ethereum/contracts';
|
|
3
1
|
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
4
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
6
2
|
import chalk from 'chalk';
|
|
7
3
|
import { aztecStartOptions } from './aztec_start_options.js';
|
|
8
4
|
export var ExitCode = /*#__PURE__*/ function(ExitCode) {
|
|
@@ -38,6 +34,25 @@ export function shutdown(logFn, exitCode, cb) {
|
|
|
38
34
|
export function isShuttingDown() {
|
|
39
35
|
return shutdownPromise !== undefined;
|
|
40
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Stops the node's subsystems (via the registered signal handlers) without exiting the process, leaving
|
|
39
|
+
* the HTTP health server listening so K8s liveness/readiness probes keep passing. Unlike {@link shutdown}
|
|
40
|
+
* this deliberately does not latch `shutdownPromise` or call `process.exit`; instead it re-arms
|
|
41
|
+
* SIGTERM/SIGINT so a later K8s pod deletion still terminates the wound-down pod with a clean exit.
|
|
42
|
+
*/ export async function softShutdown(logFn, signalHandlers) {
|
|
43
|
+
logFn('Canonical rollup upgrade detected: stopping subsystems, health server stays up.', {
|
|
44
|
+
exitCode: 78
|
|
45
|
+
});
|
|
46
|
+
await Promise.allSettled(signalHandlers.map((fn)=>fn()));
|
|
47
|
+
for (const sig of [
|
|
48
|
+
'SIGTERM',
|
|
49
|
+
'SIGINT'
|
|
50
|
+
]){
|
|
51
|
+
process.removeAllListeners(sig);
|
|
52
|
+
process.once(sig, ()=>process.exit(78));
|
|
53
|
+
}
|
|
54
|
+
logFn('Subsystems stopped due to rollup upgrade. Health server remains active.');
|
|
55
|
+
}
|
|
41
56
|
export const installSignalHandlers = (logFn, cb)=>{
|
|
42
57
|
const signals = [
|
|
43
58
|
[
|
|
@@ -239,50 +254,6 @@ export const printAztecStartHelpText = ()=>{
|
|
|
239
254
|
]);
|
|
240
255
|
}
|
|
241
256
|
}
|
|
242
|
-
export async function setupVersionChecker(network, followsCanonicalRollup, publicClient, signalHandlers, cacheDir) {
|
|
243
|
-
const networkConfig = await getNetworkConfig(network, cacheDir);
|
|
244
|
-
if (!networkConfig) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
const { VersionChecker } = await import('@aztec/stdlib/update-checker');
|
|
248
|
-
const logger = createLogger('version_check');
|
|
249
|
-
const registry = new RegistryContract(publicClient, networkConfig.registryAddress);
|
|
250
|
-
const checks = [];
|
|
251
|
-
checks.push({
|
|
252
|
-
name: 'node',
|
|
253
|
-
currentVersion: getPackageVersion(),
|
|
254
|
-
getLatestVersion: async ()=>{
|
|
255
|
-
const cfg = await getNetworkConfig(network, cacheDir);
|
|
256
|
-
return cfg?.nodeVersion;
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
if (followsCanonicalRollup) {
|
|
260
|
-
const getLatestVersion = async ()=>{
|
|
261
|
-
const version = (await registry.getRollupVersions()).at(-1);
|
|
262
|
-
return version !== undefined ? String(version) : undefined;
|
|
263
|
-
};
|
|
264
|
-
const currentVersion = await getLatestVersion();
|
|
265
|
-
if (currentVersion !== undefined) {
|
|
266
|
-
checks.push({
|
|
267
|
-
name: 'rollup',
|
|
268
|
-
currentVersion,
|
|
269
|
-
getLatestVersion
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
const checker = new VersionChecker(checks, 600_000, logger);
|
|
274
|
-
checker.on('newVersion', ({ name, latestVersion, currentVersion })=>{
|
|
275
|
-
if (isShuttingDown()) {
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
logger.warn(`New ${name} version available`, {
|
|
279
|
-
latestVersion,
|
|
280
|
-
currentVersion
|
|
281
|
-
});
|
|
282
|
-
});
|
|
283
|
-
checker.start();
|
|
284
|
-
signalHandlers.push(()=>checker.stop());
|
|
285
|
-
}
|
|
286
257
|
export function stringifyConfig(config) {
|
|
287
258
|
return Object.entries(config).map(([key, value])=>`${key}=${jsonStringify(value)}`).join(' ');
|
|
288
259
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/aztec",
|
|
3
|
-
"version": "4.4.0
|
|
3
|
+
"version": "4.4.0",
|
|
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": "4.4.0
|
|
32
|
-
"@aztec/archiver": "4.4.0
|
|
33
|
-
"@aztec/aztec-faucet": "4.4.0
|
|
34
|
-
"@aztec/aztec-node": "4.4.0
|
|
35
|
-
"@aztec/aztec.js": "4.4.0
|
|
36
|
-
"@aztec/bb-prover": "4.4.0
|
|
37
|
-
"@aztec/bb.js": "4.4.0
|
|
38
|
-
"@aztec/blob-client": "4.4.0
|
|
39
|
-
"@aztec/bot": "4.4.0
|
|
40
|
-
"@aztec/builder": "4.4.0
|
|
41
|
-
"@aztec/cli": "4.4.0
|
|
42
|
-
"@aztec/constants": "4.4.0
|
|
43
|
-
"@aztec/entrypoints": "4.4.0
|
|
44
|
-
"@aztec/ethereum": "4.4.0
|
|
45
|
-
"@aztec/foundation": "4.4.0
|
|
46
|
-
"@aztec/kv-store": "4.4.0
|
|
47
|
-
"@aztec/l1-artifacts": "4.4.0
|
|
48
|
-
"@aztec/node-lib": "4.4.0
|
|
49
|
-
"@aztec/noir-contracts.js": "4.4.0
|
|
50
|
-
"@aztec/noir-protocol-circuits-types": "4.4.0
|
|
51
|
-
"@aztec/p2p": "4.4.0
|
|
52
|
-
"@aztec/p2p-bootstrap": "4.4.0
|
|
53
|
-
"@aztec/protocol-contracts": "4.4.0
|
|
54
|
-
"@aztec/prover-client": "4.4.0
|
|
55
|
-
"@aztec/prover-node": "4.4.0
|
|
56
|
-
"@aztec/pxe": "4.4.0
|
|
57
|
-
"@aztec/sequencer-client": "4.4.0
|
|
58
|
-
"@aztec/stdlib": "4.4.0
|
|
59
|
-
"@aztec/telemetry-client": "4.4.0
|
|
60
|
-
"@aztec/txe": "4.4.0
|
|
61
|
-
"@aztec/validator-ha-signer": "4.4.0
|
|
62
|
-
"@aztec/wallets": "4.4.0
|
|
63
|
-
"@aztec/world-state": "4.4.0
|
|
31
|
+
"@aztec/accounts": "4.4.0",
|
|
32
|
+
"@aztec/archiver": "4.4.0",
|
|
33
|
+
"@aztec/aztec-faucet": "4.4.0",
|
|
34
|
+
"@aztec/aztec-node": "4.4.0",
|
|
35
|
+
"@aztec/aztec.js": "4.4.0",
|
|
36
|
+
"@aztec/bb-prover": "4.4.0",
|
|
37
|
+
"@aztec/bb.js": "4.4.0",
|
|
38
|
+
"@aztec/blob-client": "4.4.0",
|
|
39
|
+
"@aztec/bot": "4.4.0",
|
|
40
|
+
"@aztec/builder": "4.4.0",
|
|
41
|
+
"@aztec/cli": "4.4.0",
|
|
42
|
+
"@aztec/constants": "4.4.0",
|
|
43
|
+
"@aztec/entrypoints": "4.4.0",
|
|
44
|
+
"@aztec/ethereum": "4.4.0",
|
|
45
|
+
"@aztec/foundation": "4.4.0",
|
|
46
|
+
"@aztec/kv-store": "4.4.0",
|
|
47
|
+
"@aztec/l1-artifacts": "4.4.0",
|
|
48
|
+
"@aztec/node-lib": "4.4.0",
|
|
49
|
+
"@aztec/noir-contracts.js": "4.4.0",
|
|
50
|
+
"@aztec/noir-protocol-circuits-types": "4.4.0",
|
|
51
|
+
"@aztec/p2p": "4.4.0",
|
|
52
|
+
"@aztec/p2p-bootstrap": "4.4.0",
|
|
53
|
+
"@aztec/protocol-contracts": "4.4.0",
|
|
54
|
+
"@aztec/prover-client": "4.4.0",
|
|
55
|
+
"@aztec/prover-node": "4.4.0",
|
|
56
|
+
"@aztec/pxe": "4.4.0",
|
|
57
|
+
"@aztec/sequencer-client": "4.4.0",
|
|
58
|
+
"@aztec/stdlib": "4.4.0",
|
|
59
|
+
"@aztec/telemetry-client": "4.4.0",
|
|
60
|
+
"@aztec/txe": "4.4.0",
|
|
61
|
+
"@aztec/validator-ha-signer": "4.4.0",
|
|
62
|
+
"@aztec/wallets": "4.4.0",
|
|
63
|
+
"@aztec/world-state": "4.4.0",
|
|
64
64
|
"@iarna/toml": "^2.2.5",
|
|
65
65
|
"@types/chalk": "^2.2.0",
|
|
66
66
|
"abitype": "^0.8.11",
|
|
@@ -105,7 +105,7 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
|
|
|
105
105
|
env: 'NETWORK',
|
|
106
106
|
},
|
|
107
107
|
|
|
108
|
-
configToFlag('--enable-
|
|
108
|
+
configToFlag('--enable-auto-shutdown', sharedNodeConfigMappings.enableAutoShutdown),
|
|
109
109
|
|
|
110
110
|
configToFlag('--sync-mode', sharedNodeConfigMappings.syncMode),
|
|
111
111
|
configToFlag('--snapshots-urls', sharedNodeConfigMappings.snapshotsUrls),
|
package/src/cli/cmds/standby.ts
CHANGED
|
@@ -6,13 +6,16 @@ import type { GenesisStateConfig } from '@aztec/ethereum/config';
|
|
|
6
6
|
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
7
7
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
8
8
|
import { startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
9
|
-
import type
|
|
9
|
+
import { type LogFn, createLogger } from '@aztec/foundation/log';
|
|
10
10
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
11
11
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
|
+
import type { VersionCheck } from '@aztec/stdlib/update-checker';
|
|
12
13
|
import { getGenesisValues } from '@aztec/world-state/testing';
|
|
13
14
|
|
|
14
15
|
import Koa from 'koa';
|
|
15
16
|
|
|
17
|
+
import { isShuttingDown, softShutdown } from '../util.js';
|
|
18
|
+
|
|
16
19
|
const ROLLUP_POLL_INTERVAL_S = 60;
|
|
17
20
|
|
|
18
21
|
/**
|
|
@@ -35,7 +38,12 @@ export async function computeExpectedGenesisRoot(config: GenesisStateConfig, use
|
|
|
35
38
|
return { genesisArchiveRoot, prefilledPublicData };
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Compares the rollup's on-chain protocol constants (genesis archive root, VK tree root, protocol
|
|
43
|
+
* contracts hash) against the node's expected local values. Returns a list of human-readable mismatch
|
|
44
|
+
* descriptions, empty if the rollup is compatible.
|
|
45
|
+
*/
|
|
46
|
+
export async function checkRollupCompatibility(
|
|
39
47
|
rollup: RollupContract,
|
|
40
48
|
expected: { genesisArchiveRoot: Fr; vkTreeRoot: Fr; protocolContractsHash: Fr },
|
|
41
49
|
): Promise<string[]> {
|
|
@@ -130,3 +138,47 @@ export async function waitForCompatibleRollup(
|
|
|
130
138
|
await new Promise<void>((resolve, reject) => standbyServer.close(err => (err ? reject(err) : resolve())));
|
|
131
139
|
}
|
|
132
140
|
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Polls the canonical rollup's protocol constants every 10 minutes and soft-shuts-down the node once they
|
|
144
|
+
* diverge from the node's expected local values (i.e. an incompatible rollup has become canonical on L1).
|
|
145
|
+
* The HTTP health server is left running so K8s probes keep passing on the wound-down pod. This is the
|
|
146
|
+
* inverse of {@link waitForCompatibleRollup}; it should only be set up for nodes following the canonical
|
|
147
|
+
* rollup. Reuses the {@link checkRollupCompatibility} diff and the generic VersionChecker poll primitive.
|
|
148
|
+
*/
|
|
149
|
+
export async function setupAutoShutdown(
|
|
150
|
+
config: { l1RpcUrls: string[]; l1ChainId: number },
|
|
151
|
+
registryAddress: EthAddress,
|
|
152
|
+
rollupVersion: number | 'canonical',
|
|
153
|
+
expected: { genesisArchiveRoot: Fr; vkTreeRoot: Fr; protocolContractsHash: Fr },
|
|
154
|
+
signalHandlers: Array<() => Promise<void>>,
|
|
155
|
+
): Promise<void> {
|
|
156
|
+
const { VersionChecker } = await import('@aztec/stdlib/update-checker');
|
|
157
|
+
|
|
158
|
+
const logger = createLogger('auto_shutdown');
|
|
159
|
+
const publicClient = getPublicClient(config);
|
|
160
|
+
const registry = new RegistryContract(publicClient, registryAddress);
|
|
161
|
+
|
|
162
|
+
const check: VersionCheck = {
|
|
163
|
+
name: 'rollup',
|
|
164
|
+
currentVersion: 'compatible',
|
|
165
|
+
getLatestVersion: async () => {
|
|
166
|
+
const rollupAddress = await registry.getRollupAddress(rollupVersion);
|
|
167
|
+
const rollup = new RollupContract(publicClient, rollupAddress.toString());
|
|
168
|
+
const mismatches = await checkRollupCompatibility(rollup, expected);
|
|
169
|
+
return mismatches.length === 0 ? 'compatible' : `incompatible: ${mismatches.join('; ')}`;
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const checker = new VersionChecker([check], 600_000, logger);
|
|
174
|
+
checker.on('newVersion', ({ latestVersion }) => {
|
|
175
|
+
if (isShuttingDown()) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
logger.warn('Canonical rollup is no longer compatible; auto-shutting down node', { latestVersion });
|
|
179
|
+
// softShutdown never rejects (it awaits handlers via allSettled); fire-and-forget from the listener.
|
|
180
|
+
void softShutdown(logger.info.bind(logger), signalHandlers);
|
|
181
|
+
});
|
|
182
|
+
checker.start();
|
|
183
|
+
signalHandlers.push(() => checker.stop());
|
|
184
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type AztecNodeConfig, aztecNodeConfigMappings, getConfigEnvVars } from '@aztec/aztec-node';
|
|
2
2
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
3
3
|
import { getL1Config } from '@aztec/cli/config';
|
|
4
|
-
import { getPublicClient } from '@aztec/ethereum/client';
|
|
5
4
|
import { getGenesisStateConfigEnvVars } from '@aztec/ethereum/config';
|
|
6
5
|
import { type NetworkNames, SecretValue } from '@aztec/foundation/config';
|
|
7
6
|
import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
@@ -26,14 +25,9 @@ import {
|
|
|
26
25
|
import { EmbeddedWallet } from '@aztec/wallets/embedded';
|
|
27
26
|
|
|
28
27
|
import { createAztecNode } from '../../local-network/index.js';
|
|
29
|
-
import {
|
|
30
|
-
extractNamespacedOptions,
|
|
31
|
-
extractRelevantOptions,
|
|
32
|
-
preloadCrsDataForVerifying,
|
|
33
|
-
setupVersionChecker,
|
|
34
|
-
} from '../util.js';
|
|
28
|
+
import { extractNamespacedOptions, extractRelevantOptions, preloadCrsDataForVerifying } from '../util.js';
|
|
35
29
|
import { getVersions } from '../versioning.js';
|
|
36
|
-
import { computeExpectedGenesisRoot, waitForCompatibleRollup } from './standby.js';
|
|
30
|
+
import { computeExpectedGenesisRoot, setupAutoShutdown, waitForCompatibleRollup } from './standby.js';
|
|
37
31
|
import { startProverBroker } from './start_prover_broker.js';
|
|
38
32
|
|
|
39
33
|
export async function startNode(
|
|
@@ -187,15 +181,14 @@ export async function startNode(
|
|
|
187
181
|
await addBot(options, signalHandlers, services, wallet, node, telemetry, undefined);
|
|
188
182
|
}
|
|
189
183
|
|
|
190
|
-
if (nodeConfig.
|
|
191
|
-
const cacheDir = process.env.DATA_DIRECTORY ? `${process.env.DATA_DIRECTORY}/cache` : undefined;
|
|
184
|
+
if (nodeConfig.enableAutoShutdown && networkName !== 'local' && followsCanonicalRollup) {
|
|
192
185
|
try {
|
|
193
|
-
await
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
186
|
+
await setupAutoShutdown(
|
|
187
|
+
nodeConfig,
|
|
188
|
+
nodeConfig.l1Contracts.registryAddress,
|
|
189
|
+
(nodeConfig.rollupVersion as number | 'canonical') ?? 'canonical',
|
|
190
|
+
{ genesisArchiveRoot, vkTreeRoot: getVKTreeRoot(), protocolContractsHash },
|
|
197
191
|
signalHandlers,
|
|
198
|
-
cacheDir,
|
|
199
192
|
);
|
|
200
193
|
} catch {
|
|
201
194
|
/* no-op */
|
package/src/cli/util.ts
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import type { AztecNodeConfig } from '@aztec/aztec-node';
|
|
2
2
|
import type { AccountManager } from '@aztec/aztec.js/wallet';
|
|
3
|
-
import {
|
|
4
|
-
import { RegistryContract } from '@aztec/ethereum/contracts';
|
|
5
|
-
import type { ViemClient } from '@aztec/ethereum/types';
|
|
6
|
-
import type { ConfigMappingsType, NetworkNames } from '@aztec/foundation/config';
|
|
3
|
+
import type { ConfigMappingsType } from '@aztec/foundation/config';
|
|
7
4
|
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
8
|
-
import {
|
|
5
|
+
import type { LogFn } from '@aztec/foundation/log';
|
|
9
6
|
import type { ProverConfig } from '@aztec/stdlib/interfaces/server';
|
|
10
|
-
import { type VersionCheck, getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
11
7
|
import type { EmbeddedWallet } from '@aztec/wallets/embedded';
|
|
12
8
|
|
|
13
9
|
import chalk from 'chalk';
|
|
14
10
|
import type { Command } from 'commander';
|
|
15
|
-
import type { Hex } from 'viem';
|
|
16
11
|
|
|
17
12
|
import { type AztecStartOption, aztecStartOptions } from './aztec_start_options.js';
|
|
18
13
|
|
|
@@ -51,6 +46,24 @@ export function isShuttingDown(): boolean {
|
|
|
51
46
|
return shutdownPromise !== undefined;
|
|
52
47
|
}
|
|
53
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Stops the node's subsystems (via the registered signal handlers) without exiting the process, leaving
|
|
51
|
+
* the HTTP health server listening so K8s liveness/readiness probes keep passing. Unlike {@link shutdown}
|
|
52
|
+
* this deliberately does not latch `shutdownPromise` or call `process.exit`; instead it re-arms
|
|
53
|
+
* SIGTERM/SIGINT so a later K8s pod deletion still terminates the wound-down pod with a clean exit.
|
|
54
|
+
*/
|
|
55
|
+
export async function softShutdown(logFn: LogFn, signalHandlers: Array<() => Promise<void>>): Promise<void> {
|
|
56
|
+
logFn('Canonical rollup upgrade detected: stopping subsystems, health server stays up.', {
|
|
57
|
+
exitCode: ExitCode.ROLLUP_UPGRADE,
|
|
58
|
+
});
|
|
59
|
+
await Promise.allSettled(signalHandlers.map(fn => fn()));
|
|
60
|
+
for (const sig of ['SIGTERM', 'SIGINT'] as const) {
|
|
61
|
+
process.removeAllListeners(sig);
|
|
62
|
+
process.once(sig, () => process.exit(ExitCode.ROLLUP_UPGRADE));
|
|
63
|
+
}
|
|
64
|
+
logFn('Subsystems stopped due to rollup upgrade. Health server remains active.');
|
|
65
|
+
}
|
|
66
|
+
|
|
54
67
|
export const installSignalHandlers = (logFn: LogFn, cb?: Array<() => Promise<void>>) => {
|
|
55
68
|
const signals = [
|
|
56
69
|
['SIGINT', ExitCode.SIGINT],
|
|
@@ -291,60 +304,6 @@ export async function preloadCrsDataForServerSideProving(
|
|
|
291
304
|
}
|
|
292
305
|
}
|
|
293
306
|
|
|
294
|
-
export async function setupVersionChecker(
|
|
295
|
-
network: NetworkNames,
|
|
296
|
-
followsCanonicalRollup: boolean,
|
|
297
|
-
publicClient: ViemClient,
|
|
298
|
-
signalHandlers: Array<() => Promise<void>>,
|
|
299
|
-
cacheDir?: string,
|
|
300
|
-
): Promise<void> {
|
|
301
|
-
const networkConfig = await getNetworkConfig(network, cacheDir);
|
|
302
|
-
if (!networkConfig) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const { VersionChecker } = await import('@aztec/stdlib/update-checker');
|
|
307
|
-
|
|
308
|
-
const logger = createLogger('version_check');
|
|
309
|
-
const registry = new RegistryContract(publicClient, networkConfig.registryAddress as Hex);
|
|
310
|
-
|
|
311
|
-
const checks: Array<VersionCheck> = [];
|
|
312
|
-
checks.push({
|
|
313
|
-
name: 'node',
|
|
314
|
-
currentVersion: getPackageVersion(),
|
|
315
|
-
getLatestVersion: async () => {
|
|
316
|
-
const cfg = await getNetworkConfig(network, cacheDir);
|
|
317
|
-
return cfg?.nodeVersion;
|
|
318
|
-
},
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
if (followsCanonicalRollup) {
|
|
322
|
-
const getLatestVersion = async () => {
|
|
323
|
-
const version = (await registry.getRollupVersions()).at(-1);
|
|
324
|
-
return version !== undefined ? String(version) : undefined;
|
|
325
|
-
};
|
|
326
|
-
const currentVersion = await getLatestVersion();
|
|
327
|
-
if (currentVersion !== undefined) {
|
|
328
|
-
checks.push({
|
|
329
|
-
name: 'rollup',
|
|
330
|
-
currentVersion,
|
|
331
|
-
getLatestVersion,
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
const checker = new VersionChecker(checks, 600_000, logger);
|
|
337
|
-
checker.on('newVersion', ({ name, latestVersion, currentVersion }) => {
|
|
338
|
-
if (isShuttingDown()) {
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
logger.warn(`New ${name} version available`, { latestVersion, currentVersion });
|
|
343
|
-
});
|
|
344
|
-
checker.start();
|
|
345
|
-
signalHandlers.push(() => checker.stop());
|
|
346
|
-
}
|
|
347
|
-
|
|
348
307
|
export function stringifyConfig(config: object): string {
|
|
349
308
|
return Object.entries(config)
|
|
350
309
|
.map(([key, value]) => `${key}=${jsonStringify(value)}`)
|