@aztec/cli 3.0.0-nightly.20250930 → 3.0.0-nightly.20251001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/config/cached_fetch.d.ts +18 -0
- package/dest/config/cached_fetch.d.ts.map +1 -0
- package/dest/config/cached_fetch.js +54 -0
- package/dest/config/chain_l2_config.d.ts +6 -0
- package/dest/config/chain_l2_config.d.ts.map +1 -1
- package/dest/config/chain_l2_config.js +104 -53
- package/dest/config/enrich_env.d.ts +4 -0
- package/dest/config/enrich_env.d.ts.map +1 -0
- package/dest/config/enrich_env.js +12 -0
- package/dest/config/index.d.ts +2 -0
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +2 -0
- package/dest/config/network_config.d.ts +19 -0
- package/dest/config/network_config.d.ts.map +1 -0
- package/dest/config/network_config.js +84 -0
- package/package.json +24 -24
- package/src/config/cached_fetch.ts +67 -0
- package/src/config/chain_l2_config.ts +132 -54
- package/src/config/enrich_env.ts +15 -0
- package/src/config/index.ts +2 -0
- package/src/config/network_config.ts +108 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface CachedFetchOptions {
|
|
2
|
+
/** Cache duration in milliseconds */
|
|
3
|
+
cacheDurationMs: number;
|
|
4
|
+
/** The cache file */
|
|
5
|
+
cacheFile?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Fetches data from a URL with file-based caching support.
|
|
9
|
+
* This utility can be used by both remote config and bootnodes fetching.
|
|
10
|
+
*
|
|
11
|
+
* @param url - The URL to fetch from
|
|
12
|
+
* @param networkName - Network name for cache directory structure
|
|
13
|
+
* @param options - Caching and error handling options
|
|
14
|
+
* @param cacheDir - Optional cache directory (defaults to no caching)
|
|
15
|
+
* @returns The fetched and parsed JSON data, or undefined if fetch fails and throwOnError is false
|
|
16
|
+
*/
|
|
17
|
+
export declare function cachedFetch<T = any>(url: string, options: CachedFetchOptions, fetch?: typeof globalThis.fetch, log?: import("@aztec/aztec.js").Logger): Promise<T | undefined>;
|
|
18
|
+
//# sourceMappingURL=cached_fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cached_fetch.d.ts","sourceRoot":"","sources":["../../src/config/cached_fetch.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,GAAG,EACvC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,kBAAkB,EAC3B,KAAK,0BAAmB,EACxB,GAAG,mCAA+B,GACjC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAuCxB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createLogger } from '@aztec/aztec.js';
|
|
2
|
+
import { mkdir, readFile, stat, writeFile } from 'fs/promises';
|
|
3
|
+
import { dirname } from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Fetches data from a URL with file-based caching support.
|
|
6
|
+
* This utility can be used by both remote config and bootnodes fetching.
|
|
7
|
+
*
|
|
8
|
+
* @param url - The URL to fetch from
|
|
9
|
+
* @param networkName - Network name for cache directory structure
|
|
10
|
+
* @param options - Caching and error handling options
|
|
11
|
+
* @param cacheDir - Optional cache directory (defaults to no caching)
|
|
12
|
+
* @returns The fetched and parsed JSON data, or undefined if fetch fails and throwOnError is false
|
|
13
|
+
*/ export async function cachedFetch(url, options, fetch = globalThis.fetch, log = createLogger('cached_fetch')) {
|
|
14
|
+
const { cacheDurationMs, cacheFile } = options;
|
|
15
|
+
// Try to read from cache first
|
|
16
|
+
try {
|
|
17
|
+
if (cacheFile) {
|
|
18
|
+
const info = await stat(cacheFile);
|
|
19
|
+
if (info.mtimeMs + cacheDurationMs > Date.now()) {
|
|
20
|
+
const cachedData = JSON.parse(await readFile(cacheFile, 'utf-8'));
|
|
21
|
+
return cachedData;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
log.trace('Failed to read data from cache');
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(url);
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
log.warn(`Failed to fetch from ${url}: ${response.status} ${response.statusText}`);
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const data = await response.json();
|
|
34
|
+
try {
|
|
35
|
+
if (cacheFile) {
|
|
36
|
+
await mkdir(dirname(cacheFile), {
|
|
37
|
+
recursive: true
|
|
38
|
+
});
|
|
39
|
+
await writeFile(cacheFile, JSON.stringify(data), 'utf-8');
|
|
40
|
+
}
|
|
41
|
+
} catch (err) {
|
|
42
|
+
log.warn('Failed to cache data on disk: ' + cacheFile, {
|
|
43
|
+
cacheFile,
|
|
44
|
+
err
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return data;
|
|
48
|
+
} catch (err) {
|
|
49
|
+
log.warn(`Failed to fetch from ${url}`, {
|
|
50
|
+
err
|
|
51
|
+
});
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -21,11 +21,17 @@ export type L2ChainConfig = L1ContractsConfig & Omit<SlasherConfig, 'slashValida
|
|
|
21
21
|
publicIncludeMetrics?: string[];
|
|
22
22
|
publicMetricsCollectorUrl?: string;
|
|
23
23
|
publicMetricsCollectFrom?: string[];
|
|
24
|
+
dbMapSizeKb: number;
|
|
25
|
+
archiverStoreMapSizeKb: number;
|
|
26
|
+
noteHashTreeMapSizeKb: number;
|
|
27
|
+
nullifierTreeMapSizeKb: number;
|
|
28
|
+
publicDataTreeMapSizeKb: number;
|
|
24
29
|
sentinelEnabled: boolean;
|
|
25
30
|
};
|
|
26
31
|
export declare const stagingIgnitionL2ChainConfig: L2ChainConfig;
|
|
27
32
|
export declare const stagingPublicL2ChainConfig: L2ChainConfig;
|
|
28
33
|
export declare const testnetL2ChainConfig: L2ChainConfig;
|
|
34
|
+
export declare const ignitionL2ChainConfig: L2ChainConfig;
|
|
29
35
|
export declare function getBootnodes(networkName: NetworkNames, cacheDir?: string): Promise<any>;
|
|
30
36
|
export declare function getL2ChainConfig(networkName: NetworkNames, cacheDir?: string): Promise<L2ChainConfig | undefined>;
|
|
31
37
|
export declare function enrichEnvironmentWithChainConfig(networkName: NetworkNames): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain_l2_config.d.ts","sourceRoot":"","sources":["../../src/config/chain_l2_config.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"chain_l2_config.d.ts","sourceRoot":"","sources":["../../src/config/chain_l2_config.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAarE,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAC3C,IAAI,CAAC,aAAa,EAAE,sBAAsB,GAAG,uBAAuB,CAAC,GAAG;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;IAIpC,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAGhC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AA+CJ,eAAO,MAAM,4BAA4B,EAAE,aAiF1C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,aAqDxC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,aAuDlC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,aAmFnC,CAAC;AAIF,wBAAsB,YAAY,CAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,MAAM,gBAQ9E;AAED,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,YAAY,EACzB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAoBpC;AAMD,wBAAsB,gCAAgC,CAAC,WAAW,EAAE,YAAY,iBAgG/E"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { DefaultL1ContractsConfig } from '@aztec/ethereum';
|
|
2
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
-
import
|
|
4
|
-
import path, { dirname, join } from 'path';
|
|
3
|
+
import path, { join } from 'path';
|
|
5
4
|
import publicIncludeMetrics from '../../public_include_metric_prefixes.json' with {
|
|
6
5
|
type: 'json'
|
|
7
6
|
};
|
|
7
|
+
import { cachedFetch } from './cached_fetch.js';
|
|
8
|
+
import { enrichEthAddressVar, enrichVar } from './enrich_env.js';
|
|
8
9
|
const SNAPSHOT_URL = 'https://pub-f4a8c34d4bb7441ebf8f48d904512180.r2.dev/snapshots';
|
|
10
|
+
const defaultDBMapSizeKb = 128 * 1_024 * 1_024; // 128 GB
|
|
11
|
+
const tbMapSizeKb = 1_024 * 1_024 * 1_024; // 1 TB
|
|
9
12
|
const DefaultSlashConfig = {
|
|
10
13
|
/** Tally-style slashing */ slasherFlavor: 'tally',
|
|
11
14
|
/** Allow one round for vetoing */ slashingExecutionDelayInRounds: 1,
|
|
@@ -34,15 +37,22 @@ const DefaultSlashConfig = {
|
|
|
34
37
|
sentinelEnabled: true,
|
|
35
38
|
slashExecuteRoundsLookBack: 4
|
|
36
39
|
};
|
|
40
|
+
const DefaultNetworkDBMapSizeConfig = {
|
|
41
|
+
dbMapSizeKb: defaultDBMapSizeKb,
|
|
42
|
+
archiverStoreMapSizeKb: tbMapSizeKb,
|
|
43
|
+
noteHashTreeMapSizeKb: tbMapSizeKb,
|
|
44
|
+
nullifierTreeMapSizeKb: tbMapSizeKb,
|
|
45
|
+
publicDataTreeMapSizeKb: tbMapSizeKb
|
|
46
|
+
};
|
|
37
47
|
export const stagingIgnitionL2ChainConfig = {
|
|
38
48
|
l1ChainId: 11155111,
|
|
39
49
|
testAccounts: false,
|
|
40
50
|
sponsoredFPC: false,
|
|
41
51
|
p2pEnabled: true,
|
|
42
52
|
p2pBootstrapNodes: [],
|
|
43
|
-
registryAddress: '
|
|
44
|
-
slashFactoryAddress: '
|
|
45
|
-
feeAssetHandlerAddress: '
|
|
53
|
+
registryAddress: '0x53e2c2148da04fd0e8dd282f016f627a187c292c',
|
|
54
|
+
slashFactoryAddress: '0x56448efb139ef440438dfa445333734ea5ed60a0',
|
|
55
|
+
feeAssetHandlerAddress: '0x3613b834544030c166a4d47eca14b910f4816f57',
|
|
46
56
|
seqMinTxsPerBlock: 0,
|
|
47
57
|
seqMaxTxsPerBlock: 0,
|
|
48
58
|
realProofs: true,
|
|
@@ -97,7 +107,8 @@ export const stagingIgnitionL2ChainConfig = {
|
|
|
97
107
|
slashOffenseExpirationRounds: 8,
|
|
98
108
|
sentinelEnabled: true,
|
|
99
109
|
slashingDisableDuration: 5 * 24 * 60 * 60,
|
|
100
|
-
slashExecuteRoundsLookBack: 4
|
|
110
|
+
slashExecuteRoundsLookBack: 4,
|
|
111
|
+
...DefaultNetworkDBMapSizeConfig
|
|
101
112
|
};
|
|
102
113
|
export const stagingPublicL2ChainConfig = {
|
|
103
114
|
l1ChainId: 11155111,
|
|
@@ -105,9 +116,9 @@ export const stagingPublicL2ChainConfig = {
|
|
|
105
116
|
sponsoredFPC: true,
|
|
106
117
|
p2pEnabled: true,
|
|
107
118
|
p2pBootstrapNodes: [],
|
|
108
|
-
registryAddress: '
|
|
109
|
-
slashFactoryAddress: '
|
|
110
|
-
feeAssetHandlerAddress: '
|
|
119
|
+
registryAddress: '0xe83067689f3cf837ccbf8a3966f0e0fe985dcb3e',
|
|
120
|
+
slashFactoryAddress: '0x8b87a1812162d4890f01bb40f410047f37d3ceb8',
|
|
121
|
+
feeAssetHandlerAddress: '0xa8159159a9e2a57c6e8c59fd5b3dd94c6dbddfe3',
|
|
111
122
|
seqMinTxsPerBlock: 0,
|
|
112
123
|
seqMaxTxsPerBlock: 20,
|
|
113
124
|
realProofs: true,
|
|
@@ -135,7 +146,8 @@ export const stagingPublicL2ChainConfig = {
|
|
|
135
146
|
/** The mana target for the rollup */ manaTarget: DefaultL1ContractsConfig.manaTarget,
|
|
136
147
|
/** The proving cost per mana */ provingCostPerMana: DefaultL1ContractsConfig.provingCostPerMana,
|
|
137
148
|
/** Exit delay for stakers */ exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
|
|
138
|
-
...DefaultSlashConfig
|
|
149
|
+
...DefaultSlashConfig,
|
|
150
|
+
...DefaultNetworkDBMapSizeConfig
|
|
139
151
|
};
|
|
140
152
|
export const testnetL2ChainConfig = {
|
|
141
153
|
l1ChainId: 11155111,
|
|
@@ -175,38 +187,83 @@ export const testnetL2ChainConfig = {
|
|
|
175
187
|
/** Exit delay for stakers */ exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
|
|
176
188
|
...DefaultSlashConfig,
|
|
177
189
|
slashPrunePenalty: 0n,
|
|
178
|
-
slashDataWithholdingPenalty: 0n
|
|
190
|
+
slashDataWithholdingPenalty: 0n,
|
|
191
|
+
...DefaultNetworkDBMapSizeConfig
|
|
192
|
+
};
|
|
193
|
+
export const ignitionL2ChainConfig = {
|
|
194
|
+
l1ChainId: 1,
|
|
195
|
+
testAccounts: false,
|
|
196
|
+
sponsoredFPC: false,
|
|
197
|
+
p2pEnabled: true,
|
|
198
|
+
p2pBootstrapNodes: [],
|
|
199
|
+
registryAddress: '',
|
|
200
|
+
slashFactoryAddress: '',
|
|
201
|
+
feeAssetHandlerAddress: '',
|
|
202
|
+
seqMinTxsPerBlock: 0,
|
|
203
|
+
seqMaxTxsPerBlock: 0,
|
|
204
|
+
realProofs: true,
|
|
205
|
+
snapshotsUrl: 'https://storage.googleapis.com/aztec-testnet/snapshots/ignition/',
|
|
206
|
+
autoUpdate: 'notify',
|
|
207
|
+
autoUpdateUrl: 'https://storage.googleapis.com/aztec-testnet/auto-update/ignition.json',
|
|
208
|
+
maxTxPoolSize: 100_000_000,
|
|
209
|
+
publicIncludeMetrics,
|
|
210
|
+
publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
|
|
211
|
+
publicMetricsCollectFrom: [
|
|
212
|
+
'sequencer'
|
|
213
|
+
],
|
|
214
|
+
/** How many seconds an L1 slot lasts. */ ethereumSlotDuration: 12,
|
|
215
|
+
/** How many seconds an L2 slots lasts (must be multiple of ethereum slot duration). */ aztecSlotDuration: 72,
|
|
216
|
+
/** How many L2 slots an epoch lasts. */ aztecEpochDuration: 32,
|
|
217
|
+
/** The target validator committee size. */ aztecTargetCommitteeSize: 24,
|
|
218
|
+
/** The number of epochs after an epoch ends that proofs are still accepted. */ aztecProofSubmissionEpochs: 1,
|
|
219
|
+
/** How many sequencers must agree with a slash for it to be executed. */ slashingQuorum: 65,
|
|
220
|
+
/** The number of epochs to lag behind the current epoch for validator selection. */ lagInEpochs: 2,
|
|
221
|
+
localEjectionThreshold: 196_000n * 10n ** 18n,
|
|
222
|
+
slashingDisableDuration: 5 * 24 * 60 * 60,
|
|
223
|
+
slashingRoundSizeInEpochs: 4,
|
|
224
|
+
slashingLifetimeInRounds: 40,
|
|
225
|
+
slashingExecutionDelayInRounds: 28,
|
|
226
|
+
slashAmountSmall: 2_000n * 10n ** 18n,
|
|
227
|
+
slashAmountMedium: 10_000n * 10n ** 18n,
|
|
228
|
+
slashAmountLarge: 50_000n * 10n ** 18n,
|
|
229
|
+
slashingOffsetInRounds: 2,
|
|
230
|
+
slasherFlavor: 'tally',
|
|
231
|
+
slashingVetoer: EthAddress.ZERO,
|
|
232
|
+
/** The mana target for the rollup */ manaTarget: 0n,
|
|
233
|
+
exitDelaySeconds: 5 * 24 * 60 * 60,
|
|
234
|
+
/** The proving cost per mana */ provingCostPerMana: 0n,
|
|
235
|
+
ejectionThreshold: 100_000n * 10n ** 18n,
|
|
236
|
+
activationThreshold: 200_000n * 10n ** 18n,
|
|
237
|
+
governanceProposerRoundSize: 300,
|
|
238
|
+
governanceProposerQuorum: 151,
|
|
239
|
+
// Node slashing config
|
|
240
|
+
// TODO TMNT-330
|
|
241
|
+
slashMinPenaltyPercentage: 0.5,
|
|
242
|
+
slashMaxPenaltyPercentage: 2.0,
|
|
243
|
+
slashInactivityTargetPercentage: 0.7,
|
|
244
|
+
slashInactivityConsecutiveEpochThreshold: 2,
|
|
245
|
+
slashInactivityPenalty: 2_000n * 10n ** 18n,
|
|
246
|
+
slashPrunePenalty: 0n,
|
|
247
|
+
slashDataWithholdingPenalty: 0n,
|
|
248
|
+
slashProposeInvalidAttestationsPenalty: 50_000n * 10n ** 18n,
|
|
249
|
+
slashAttestDescendantOfInvalidPenalty: 50_000n * 10n ** 18n,
|
|
250
|
+
slashUnknownPenalty: 2_000n * 10n ** 18n,
|
|
251
|
+
slashBroadcastedInvalidBlockPenalty: 0n,
|
|
252
|
+
slashMaxPayloadSize: 50,
|
|
253
|
+
slashGracePeriodL2Slots: 32 * 4,
|
|
254
|
+
slashOffenseExpirationRounds: 8,
|
|
255
|
+
sentinelEnabled: true,
|
|
256
|
+
slashExecuteRoundsLookBack: 4,
|
|
257
|
+
...DefaultNetworkDBMapSizeConfig
|
|
179
258
|
};
|
|
180
259
|
const BOOTNODE_CACHE_DURATION_MS = 60 * 60 * 1000; // 1 hour;
|
|
181
260
|
export async function getBootnodes(networkName, cacheDir) {
|
|
182
|
-
const cacheFile = cacheDir ? join(cacheDir, networkName, 'bootnodes.json') : undefined;
|
|
183
|
-
try {
|
|
184
|
-
if (cacheFile) {
|
|
185
|
-
const info = await stat(cacheFile);
|
|
186
|
-
if (info.mtimeMs + BOOTNODE_CACHE_DURATION_MS > Date.now()) {
|
|
187
|
-
return JSON.parse(await readFile(cacheFile, 'utf-8'))['bootnodes'];
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
} catch {
|
|
191
|
-
// no-op. Get the remote-file
|
|
192
|
-
}
|
|
193
261
|
const url = `http://static.aztec.network/${networkName}/bootnodes.json`;
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
if (cacheFile) {
|
|
201
|
-
await mkdir(dirname(cacheFile), {
|
|
202
|
-
recursive: true
|
|
203
|
-
});
|
|
204
|
-
await writeFile(cacheFile, JSON.stringify(json), 'utf-8');
|
|
205
|
-
}
|
|
206
|
-
} catch {
|
|
207
|
-
// no-op
|
|
208
|
-
}
|
|
209
|
-
return json['bootnodes'];
|
|
262
|
+
const data = await cachedFetch(url, {
|
|
263
|
+
cacheDurationMs: BOOTNODE_CACHE_DURATION_MS,
|
|
264
|
+
cacheFile: cacheDir ? join(cacheDir, networkName, 'bootnodes.json') : undefined
|
|
265
|
+
});
|
|
266
|
+
return data?.bootnodes;
|
|
210
267
|
}
|
|
211
268
|
export async function getL2ChainConfig(networkName, cacheDir) {
|
|
212
269
|
let config;
|
|
@@ -222,6 +279,10 @@ export async function getL2ChainConfig(networkName, cacheDir) {
|
|
|
222
279
|
config = {
|
|
223
280
|
...stagingIgnitionL2ChainConfig
|
|
224
281
|
};
|
|
282
|
+
} else if (networkName === 'ignition') {
|
|
283
|
+
config = {
|
|
284
|
+
...ignitionL2ChainConfig
|
|
285
|
+
};
|
|
225
286
|
}
|
|
226
287
|
if (!config) {
|
|
227
288
|
return undefined;
|
|
@@ -233,21 +294,6 @@ export async function getL2ChainConfig(networkName, cacheDir) {
|
|
|
233
294
|
}
|
|
234
295
|
return config;
|
|
235
296
|
}
|
|
236
|
-
function enrichVar(envVar, value) {
|
|
237
|
-
// Don't override
|
|
238
|
-
if (process.env[envVar] || value === undefined) {
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
process.env[envVar] = value;
|
|
242
|
-
}
|
|
243
|
-
function enrichEthAddressVar(envVar, value) {
|
|
244
|
-
// EthAddress doesn't like being given empty strings
|
|
245
|
-
if (value === '') {
|
|
246
|
-
enrichVar(envVar, EthAddress.ZERO.toString());
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
enrichVar(envVar, value);
|
|
250
|
-
}
|
|
251
297
|
function getDefaultDataDir(networkName) {
|
|
252
298
|
return path.join(process.env.HOME || '~', '.aztec', networkName, 'data');
|
|
253
299
|
}
|
|
@@ -272,6 +318,11 @@ export async function enrichEnvironmentWithChainConfig(networkName) {
|
|
|
272
318
|
enrichVar('PXE_PROVER_ENABLED', config.realProofs.toString());
|
|
273
319
|
enrichVar('SYNC_SNAPSHOTS_URL', config.snapshotsUrl);
|
|
274
320
|
enrichVar('P2P_MAX_TX_POOL_SIZE', config.maxTxPoolSize.toString());
|
|
321
|
+
enrichVar('DATA_STORE_MAP_SIZE_KB', config.dbMapSizeKb.toString());
|
|
322
|
+
enrichVar('ARCHIVER_STORE_MAP_SIZE_KB', config.archiverStoreMapSizeKb.toString());
|
|
323
|
+
enrichVar('NOTE_HASH_TREE_MAP_SIZE_KB', config.noteHashTreeMapSizeKb.toString());
|
|
324
|
+
enrichVar('NULLIFIER_TREE_MAP_SIZE_KB', config.nullifierTreeMapSizeKb.toString());
|
|
325
|
+
enrichVar('PUBLIC_DATA_TREE_MAP_SIZE_KB', config.publicDataTreeMapSizeKb.toString());
|
|
275
326
|
if (config.autoUpdate) {
|
|
276
327
|
enrichVar('AUTO_UPDATE', config.autoUpdate?.toString());
|
|
277
328
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enrich_env.d.ts","sourceRoot":"","sources":["../../src/config/enrich_env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,QAMlE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAGhE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec/aztec.js';
|
|
2
|
+
export function enrichVar(envVar, value) {
|
|
3
|
+
// Don't override
|
|
4
|
+
if (process.env[envVar] || value === undefined) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
process.env[envVar] = value;
|
|
8
|
+
}
|
|
9
|
+
export function enrichEthAddressVar(envVar, value) {
|
|
10
|
+
// EthAddress doesn't like being given empty strings
|
|
11
|
+
enrichVar(envVar, value || EthAddress.ZERO.toString());
|
|
12
|
+
}
|
package/dest/config/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
|
package/dest/config/index.js
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type NetworkConfig, type NetworkNames } from '@aztec/foundation/config';
|
|
2
|
+
/**
|
|
3
|
+
* Fetches remote network configuration from GitHub with caching support.
|
|
4
|
+
* Uses the reusable cachedFetch utility.
|
|
5
|
+
*
|
|
6
|
+
* @param networkName - The network name to fetch config for
|
|
7
|
+
* @param cacheDir - Optional cache directory for storing fetched config
|
|
8
|
+
* @returns Remote configuration for the specified network, or undefined if not found/error
|
|
9
|
+
*/
|
|
10
|
+
export declare function getNetworkConfig(networkName: NetworkNames, cacheDir?: string): Promise<NetworkConfig | undefined>;
|
|
11
|
+
/**
|
|
12
|
+
* Enriches environment variables with remote network configuration.
|
|
13
|
+
* This function is called before node config initialization to set env vars
|
|
14
|
+
* from the remote config, following the same pattern as enrichEnvironmentWithChainConfig().
|
|
15
|
+
*
|
|
16
|
+
* @param networkName - The network name to fetch remote config for
|
|
17
|
+
*/
|
|
18
|
+
export declare function enrichEnvironmentWithNetworkConfig(networkName: NetworkNames): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=network_config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network_config.d.ts","sourceRoot":"","sources":["../../src/config/network_config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAA0B,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAYzG;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,YAAY,EACzB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAiDpC;AAED;;;;;;GAMG;AACH,wBAAsB,kCAAkC,CAAC,WAAW,EAAE,YAAY,iBA0BjF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { NetworkConfigMapSchema } from '@aztec/foundation/config';
|
|
2
|
+
import { readFile } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { cachedFetch } from './cached_fetch.js';
|
|
5
|
+
import { enrichEthAddressVar, enrichVar } from './enrich_env.js';
|
|
6
|
+
const DEFAULT_CONFIG_URL = 'https://raw.githubusercontent.com/AztecProtocol/networks/refs/heads/main/network_config.json';
|
|
7
|
+
const NETWORK_CONFIG_CACHE_DURATION_MS = 60 * 60 * 1000; // 1 hour
|
|
8
|
+
/**
|
|
9
|
+
* Fetches remote network configuration from GitHub with caching support.
|
|
10
|
+
* Uses the reusable cachedFetch utility.
|
|
11
|
+
*
|
|
12
|
+
* @param networkName - The network name to fetch config for
|
|
13
|
+
* @param cacheDir - Optional cache directory for storing fetched config
|
|
14
|
+
* @returns Remote configuration for the specified network, or undefined if not found/error
|
|
15
|
+
*/ export async function getNetworkConfig(networkName, cacheDir) {
|
|
16
|
+
let url;
|
|
17
|
+
const configLocation = process.env.NETWORK_CONFIG_LOCATION || DEFAULT_CONFIG_URL;
|
|
18
|
+
if (!configLocation) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
if (configLocation.includes('://')) {
|
|
23
|
+
url = new URL(configLocation);
|
|
24
|
+
} else {
|
|
25
|
+
url = new URL(`file://${configLocation}`);
|
|
26
|
+
}
|
|
27
|
+
} catch {
|
|
28
|
+
/* no-op */ }
|
|
29
|
+
if (!url) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
let rawConfig;
|
|
34
|
+
if (url.protocol === 'http:' || url.protocol === 'https:') {
|
|
35
|
+
rawConfig = await cachedFetch(url.href, {
|
|
36
|
+
cacheDurationMs: NETWORK_CONFIG_CACHE_DURATION_MS,
|
|
37
|
+
cacheFile: cacheDir ? join(cacheDir, networkName, 'network_config.json') : undefined
|
|
38
|
+
});
|
|
39
|
+
} else if (url.protocol === 'file:') {
|
|
40
|
+
rawConfig = JSON.parse(await readFile(url.pathname, 'utf-8'));
|
|
41
|
+
} else {
|
|
42
|
+
throw new Error('Unsupported Aztec network config protocol: ' + url.href);
|
|
43
|
+
}
|
|
44
|
+
if (!rawConfig) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const networkConfigMap = NetworkConfigMapSchema.parse(rawConfig);
|
|
48
|
+
if (networkName in networkConfigMap) {
|
|
49
|
+
return networkConfigMap[networkName];
|
|
50
|
+
} else {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
} catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Enriches environment variables with remote network configuration.
|
|
59
|
+
* This function is called before node config initialization to set env vars
|
|
60
|
+
* from the remote config, following the same pattern as enrichEnvironmentWithChainConfig().
|
|
61
|
+
*
|
|
62
|
+
* @param networkName - The network name to fetch remote config for
|
|
63
|
+
*/ export async function enrichEnvironmentWithNetworkConfig(networkName) {
|
|
64
|
+
if (networkName === 'local') {
|
|
65
|
+
return; // No remote config for local development
|
|
66
|
+
}
|
|
67
|
+
const cacheDir = process.env.DATA_DIRECTORY ? join(process.env.DATA_DIRECTORY, 'cache') : undefined;
|
|
68
|
+
const networkConfig = await getNetworkConfig(networkName, cacheDir);
|
|
69
|
+
if (!networkConfig) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
enrichVar('BOOTSTRAP_NODES', networkConfig.bootnodes.join(','));
|
|
73
|
+
enrichVar('L1_CHAIN_ID', String(networkConfig.l1ChainId));
|
|
74
|
+
// Snapshot synch only supports a single source. Take the first
|
|
75
|
+
// See A-101 for more details
|
|
76
|
+
const firstSource = networkConfig[0];
|
|
77
|
+
if (firstSource) {
|
|
78
|
+
enrichVar('SYNC_SNAPSHOTS_URL', networkConfig.snapshots.join(','));
|
|
79
|
+
}
|
|
80
|
+
enrichEthAddressVar('REGISTRY_CONTRACT_ADDRESS', networkConfig.registryAddress.toString());
|
|
81
|
+
if (networkConfig.feeAssetHandlerAddress) {
|
|
82
|
+
enrichEthAddressVar('FEE_ASSET_HANDLER_CONTRACT_ADDRESS', networkConfig.feeAssetHandlerAddress.toString());
|
|
83
|
+
}
|
|
84
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/cli",
|
|
3
|
-
"version": "3.0.0-nightly.
|
|
3
|
+
"version": "3.0.0-nightly.20251001",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./contracts": "./dest/cmds/contracts/index.js",
|
|
@@ -70,20 +70,20 @@
|
|
|
70
70
|
]
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@aztec/accounts": "3.0.0-nightly.
|
|
74
|
-
"@aztec/archiver": "3.0.0-nightly.
|
|
75
|
-
"@aztec/aztec.js": "3.0.0-nightly.
|
|
76
|
-
"@aztec/constants": "3.0.0-nightly.
|
|
77
|
-
"@aztec/entrypoints": "3.0.0-nightly.
|
|
78
|
-
"@aztec/ethereum": "3.0.0-nightly.
|
|
79
|
-
"@aztec/foundation": "3.0.0-nightly.
|
|
80
|
-
"@aztec/l1-artifacts": "3.0.0-nightly.
|
|
81
|
-
"@aztec/node-lib": "3.0.0-nightly.
|
|
82
|
-
"@aztec/p2p": "3.0.0-nightly.
|
|
83
|
-
"@aztec/protocol-contracts": "3.0.0-nightly.
|
|
84
|
-
"@aztec/stdlib": "3.0.0-nightly.
|
|
85
|
-
"@aztec/test-wallet": "3.0.0-nightly.
|
|
86
|
-
"@aztec/world-state": "3.0.0-nightly.
|
|
73
|
+
"@aztec/accounts": "3.0.0-nightly.20251001",
|
|
74
|
+
"@aztec/archiver": "3.0.0-nightly.20251001",
|
|
75
|
+
"@aztec/aztec.js": "3.0.0-nightly.20251001",
|
|
76
|
+
"@aztec/constants": "3.0.0-nightly.20251001",
|
|
77
|
+
"@aztec/entrypoints": "3.0.0-nightly.20251001",
|
|
78
|
+
"@aztec/ethereum": "3.0.0-nightly.20251001",
|
|
79
|
+
"@aztec/foundation": "3.0.0-nightly.20251001",
|
|
80
|
+
"@aztec/l1-artifacts": "3.0.0-nightly.20251001",
|
|
81
|
+
"@aztec/node-lib": "3.0.0-nightly.20251001",
|
|
82
|
+
"@aztec/p2p": "3.0.0-nightly.20251001",
|
|
83
|
+
"@aztec/protocol-contracts": "3.0.0-nightly.20251001",
|
|
84
|
+
"@aztec/stdlib": "3.0.0-nightly.20251001",
|
|
85
|
+
"@aztec/test-wallet": "3.0.0-nightly.20251001",
|
|
86
|
+
"@aztec/world-state": "3.0.0-nightly.20251001",
|
|
87
87
|
"@iarna/toml": "^2.2.5",
|
|
88
88
|
"@libp2p/peer-id-factory": "^3.0.4",
|
|
89
89
|
"commander": "^12.1.0",
|
|
@@ -110,15 +110,15 @@
|
|
|
110
110
|
"typescript": "^5.3.3"
|
|
111
111
|
},
|
|
112
112
|
"peerDependencies": {
|
|
113
|
-
"@aztec/accounts": "3.0.0-nightly.
|
|
114
|
-
"@aztec/bb-prover": "3.0.0-nightly.
|
|
115
|
-
"@aztec/ethereum": "3.0.0-nightly.
|
|
116
|
-
"@aztec/l1-artifacts": "3.0.0-nightly.
|
|
117
|
-
"@aztec/noir-contracts.js": "3.0.0-nightly.
|
|
118
|
-
"@aztec/noir-protocol-circuits-types": "3.0.0-nightly.
|
|
119
|
-
"@aztec/noir-test-contracts.js": "3.0.0-nightly.
|
|
120
|
-
"@aztec/protocol-contracts": "3.0.0-nightly.
|
|
121
|
-
"@aztec/stdlib": "3.0.0-nightly.
|
|
113
|
+
"@aztec/accounts": "3.0.0-nightly.20251001",
|
|
114
|
+
"@aztec/bb-prover": "3.0.0-nightly.20251001",
|
|
115
|
+
"@aztec/ethereum": "3.0.0-nightly.20251001",
|
|
116
|
+
"@aztec/l1-artifacts": "3.0.0-nightly.20251001",
|
|
117
|
+
"@aztec/noir-contracts.js": "3.0.0-nightly.20251001",
|
|
118
|
+
"@aztec/noir-protocol-circuits-types": "3.0.0-nightly.20251001",
|
|
119
|
+
"@aztec/noir-test-contracts.js": "3.0.0-nightly.20251001",
|
|
120
|
+
"@aztec/protocol-contracts": "3.0.0-nightly.20251001",
|
|
121
|
+
"@aztec/stdlib": "3.0.0-nightly.20251001"
|
|
122
122
|
},
|
|
123
123
|
"files": [
|
|
124
124
|
"dest",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createLogger } from '@aztec/aztec.js';
|
|
2
|
+
|
|
3
|
+
import { mkdir, readFile, stat, writeFile } from 'fs/promises';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
|
|
6
|
+
export interface CachedFetchOptions {
|
|
7
|
+
/** Cache duration in milliseconds */
|
|
8
|
+
cacheDurationMs: number;
|
|
9
|
+
/** The cache file */
|
|
10
|
+
cacheFile?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Fetches data from a URL with file-based caching support.
|
|
15
|
+
* This utility can be used by both remote config and bootnodes fetching.
|
|
16
|
+
*
|
|
17
|
+
* @param url - The URL to fetch from
|
|
18
|
+
* @param networkName - Network name for cache directory structure
|
|
19
|
+
* @param options - Caching and error handling options
|
|
20
|
+
* @param cacheDir - Optional cache directory (defaults to no caching)
|
|
21
|
+
* @returns The fetched and parsed JSON data, or undefined if fetch fails and throwOnError is false
|
|
22
|
+
*/
|
|
23
|
+
export async function cachedFetch<T = any>(
|
|
24
|
+
url: string,
|
|
25
|
+
options: CachedFetchOptions,
|
|
26
|
+
fetch = globalThis.fetch,
|
|
27
|
+
log = createLogger('cached_fetch'),
|
|
28
|
+
): Promise<T | undefined> {
|
|
29
|
+
const { cacheDurationMs, cacheFile } = options;
|
|
30
|
+
|
|
31
|
+
// Try to read from cache first
|
|
32
|
+
try {
|
|
33
|
+
if (cacheFile) {
|
|
34
|
+
const info = await stat(cacheFile);
|
|
35
|
+
if (info.mtimeMs + cacheDurationMs > Date.now()) {
|
|
36
|
+
const cachedData = JSON.parse(await readFile(cacheFile, 'utf-8'));
|
|
37
|
+
return cachedData;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
} catch {
|
|
41
|
+
log.trace('Failed to read data from cache');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const response = await fetch(url);
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
log.warn(`Failed to fetch from ${url}: ${response.status} ${response.statusText}`);
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const data = await response.json();
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
if (cacheFile) {
|
|
55
|
+
await mkdir(dirname(cacheFile), { recursive: true });
|
|
56
|
+
await writeFile(cacheFile, JSON.stringify(data), 'utf-8');
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
log.warn('Failed to cache data on disk: ' + cacheFile, { cacheFile, err });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return data;
|
|
63
|
+
} catch (err) {
|
|
64
|
+
log.warn(`Failed to fetch from ${url}`, { err });
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -4,13 +4,17 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
4
4
|
import type { SharedNodeConfig } from '@aztec/node-lib/config';
|
|
5
5
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
6
6
|
|
|
7
|
-
import
|
|
8
|
-
import path, { dirname, join } from 'path';
|
|
7
|
+
import path, { join } from 'path';
|
|
9
8
|
|
|
10
9
|
import publicIncludeMetrics from '../../public_include_metric_prefixes.json' with { type: 'json' };
|
|
10
|
+
import { cachedFetch } from './cached_fetch.js';
|
|
11
|
+
import { enrichEthAddressVar, enrichVar } from './enrich_env.js';
|
|
11
12
|
|
|
12
13
|
const SNAPSHOT_URL = 'https://pub-f4a8c34d4bb7441ebf8f48d904512180.r2.dev/snapshots';
|
|
13
14
|
|
|
15
|
+
const defaultDBMapSizeKb = 128 * 1_024 * 1_024; // 128 GB
|
|
16
|
+
const tbMapSizeKb = 1_024 * 1_024 * 1_024; // 1 TB
|
|
17
|
+
|
|
14
18
|
export type L2ChainConfig = L1ContractsConfig &
|
|
15
19
|
Omit<SlasherConfig, 'slashValidatorsNever' | 'slashValidatorsAlways'> & {
|
|
16
20
|
l1ChainId: number;
|
|
@@ -32,6 +36,14 @@ export type L2ChainConfig = L1ContractsConfig &
|
|
|
32
36
|
publicMetricsCollectorUrl?: string;
|
|
33
37
|
publicMetricsCollectFrom?: string[];
|
|
34
38
|
|
|
39
|
+
// Setting the dbMapSize provides the default for every DB in the node.
|
|
40
|
+
// Then we explicitly override the sizes for the archiver and the larger trees.
|
|
41
|
+
dbMapSizeKb: number;
|
|
42
|
+
archiverStoreMapSizeKb: number;
|
|
43
|
+
noteHashTreeMapSizeKb: number;
|
|
44
|
+
nullifierTreeMapSizeKb: number;
|
|
45
|
+
publicDataTreeMapSizeKb: number;
|
|
46
|
+
|
|
35
47
|
// Control whether sentinel is enabled or not. Needed for slashing
|
|
36
48
|
sentinelEnabled: boolean;
|
|
37
49
|
};
|
|
@@ -73,15 +85,23 @@ const DefaultSlashConfig = {
|
|
|
73
85
|
slashExecuteRoundsLookBack: 4,
|
|
74
86
|
} satisfies Partial<L2ChainConfig>;
|
|
75
87
|
|
|
88
|
+
const DefaultNetworkDBMapSizeConfig = {
|
|
89
|
+
dbMapSizeKb: defaultDBMapSizeKb,
|
|
90
|
+
archiverStoreMapSizeKb: tbMapSizeKb,
|
|
91
|
+
noteHashTreeMapSizeKb: tbMapSizeKb,
|
|
92
|
+
nullifierTreeMapSizeKb: tbMapSizeKb,
|
|
93
|
+
publicDataTreeMapSizeKb: tbMapSizeKb,
|
|
94
|
+
} satisfies Partial<L2ChainConfig>;
|
|
95
|
+
|
|
76
96
|
export const stagingIgnitionL2ChainConfig: L2ChainConfig = {
|
|
77
97
|
l1ChainId: 11155111,
|
|
78
98
|
testAccounts: false,
|
|
79
99
|
sponsoredFPC: false,
|
|
80
100
|
p2pEnabled: true,
|
|
81
101
|
p2pBootstrapNodes: [],
|
|
82
|
-
registryAddress: '
|
|
83
|
-
slashFactoryAddress: '
|
|
84
|
-
feeAssetHandlerAddress: '
|
|
102
|
+
registryAddress: '0x53e2c2148da04fd0e8dd282f016f627a187c292c',
|
|
103
|
+
slashFactoryAddress: '0x56448efb139ef440438dfa445333734ea5ed60a0',
|
|
104
|
+
feeAssetHandlerAddress: '0x3613b834544030c166a4d47eca14b910f4816f57',
|
|
85
105
|
seqMinTxsPerBlock: 0,
|
|
86
106
|
seqMaxTxsPerBlock: 0,
|
|
87
107
|
realProofs: true,
|
|
@@ -152,6 +172,8 @@ export const stagingIgnitionL2ChainConfig: L2ChainConfig = {
|
|
|
152
172
|
sentinelEnabled: true,
|
|
153
173
|
slashingDisableDuration: 5 * 24 * 60 * 60,
|
|
154
174
|
slashExecuteRoundsLookBack: 4,
|
|
175
|
+
|
|
176
|
+
...DefaultNetworkDBMapSizeConfig,
|
|
155
177
|
};
|
|
156
178
|
|
|
157
179
|
export const stagingPublicL2ChainConfig: L2ChainConfig = {
|
|
@@ -160,9 +182,9 @@ export const stagingPublicL2ChainConfig: L2ChainConfig = {
|
|
|
160
182
|
sponsoredFPC: true,
|
|
161
183
|
p2pEnabled: true,
|
|
162
184
|
p2pBootstrapNodes: [],
|
|
163
|
-
registryAddress: '
|
|
164
|
-
slashFactoryAddress: '
|
|
165
|
-
feeAssetHandlerAddress: '
|
|
185
|
+
registryAddress: '0xe83067689f3cf837ccbf8a3966f0e0fe985dcb3e',
|
|
186
|
+
slashFactoryAddress: '0x8b87a1812162d4890f01bb40f410047f37d3ceb8',
|
|
187
|
+
feeAssetHandlerAddress: '0xa8159159a9e2a57c6e8c59fd5b3dd94c6dbddfe3',
|
|
166
188
|
seqMinTxsPerBlock: 0,
|
|
167
189
|
seqMaxTxsPerBlock: 20,
|
|
168
190
|
realProofs: true,
|
|
@@ -205,6 +227,8 @@ export const stagingPublicL2ChainConfig: L2ChainConfig = {
|
|
|
205
227
|
exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
|
|
206
228
|
|
|
207
229
|
...DefaultSlashConfig,
|
|
230
|
+
|
|
231
|
+
...DefaultNetworkDBMapSizeConfig,
|
|
208
232
|
};
|
|
209
233
|
|
|
210
234
|
export const testnetL2ChainConfig: L2ChainConfig = {
|
|
@@ -260,42 +284,105 @@ export const testnetL2ChainConfig: L2ChainConfig = {
|
|
|
260
284
|
...DefaultSlashConfig,
|
|
261
285
|
slashPrunePenalty: 0n,
|
|
262
286
|
slashDataWithholdingPenalty: 0n,
|
|
287
|
+
|
|
288
|
+
...DefaultNetworkDBMapSizeConfig,
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
export const ignitionL2ChainConfig: L2ChainConfig = {
|
|
292
|
+
l1ChainId: 1,
|
|
293
|
+
testAccounts: false,
|
|
294
|
+
sponsoredFPC: false,
|
|
295
|
+
p2pEnabled: true,
|
|
296
|
+
p2pBootstrapNodes: [],
|
|
297
|
+
registryAddress: '',
|
|
298
|
+
slashFactoryAddress: '',
|
|
299
|
+
feeAssetHandlerAddress: '',
|
|
300
|
+
seqMinTxsPerBlock: 0,
|
|
301
|
+
seqMaxTxsPerBlock: 0,
|
|
302
|
+
realProofs: true,
|
|
303
|
+
snapshotsUrl: 'https://storage.googleapis.com/aztec-testnet/snapshots/ignition/',
|
|
304
|
+
autoUpdate: 'notify',
|
|
305
|
+
autoUpdateUrl: 'https://storage.googleapis.com/aztec-testnet/auto-update/ignition.json',
|
|
306
|
+
maxTxPoolSize: 100_000_000, // 100MB
|
|
307
|
+
publicIncludeMetrics,
|
|
308
|
+
publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
|
|
309
|
+
publicMetricsCollectFrom: ['sequencer'],
|
|
310
|
+
|
|
311
|
+
/** How many seconds an L1 slot lasts. */
|
|
312
|
+
ethereumSlotDuration: 12,
|
|
313
|
+
/** How many seconds an L2 slots lasts (must be multiple of ethereum slot duration). */
|
|
314
|
+
aztecSlotDuration: 72,
|
|
315
|
+
/** How many L2 slots an epoch lasts. */
|
|
316
|
+
aztecEpochDuration: 32,
|
|
317
|
+
/** The target validator committee size. */
|
|
318
|
+
aztecTargetCommitteeSize: 24,
|
|
319
|
+
/** The number of epochs after an epoch ends that proofs are still accepted. */
|
|
320
|
+
aztecProofSubmissionEpochs: 1,
|
|
321
|
+
/** How many sequencers must agree with a slash for it to be executed. */
|
|
322
|
+
slashingQuorum: 65,
|
|
323
|
+
|
|
324
|
+
/** The number of epochs to lag behind the current epoch for validator selection. */
|
|
325
|
+
lagInEpochs: 2,
|
|
326
|
+
|
|
327
|
+
localEjectionThreshold: 196_000n * 10n ** 18n,
|
|
328
|
+
slashingDisableDuration: 5 * 24 * 60 * 60,
|
|
329
|
+
|
|
330
|
+
slashingRoundSizeInEpochs: 4,
|
|
331
|
+
slashingLifetimeInRounds: 40,
|
|
332
|
+
slashingExecutionDelayInRounds: 28,
|
|
333
|
+
slashAmountSmall: 2_000n * 10n ** 18n,
|
|
334
|
+
slashAmountMedium: 10_000n * 10n ** 18n,
|
|
335
|
+
slashAmountLarge: 50_000n * 10n ** 18n,
|
|
336
|
+
slashingOffsetInRounds: 2,
|
|
337
|
+
slasherFlavor: 'tally',
|
|
338
|
+
slashingVetoer: EthAddress.ZERO, // TODO TMNT-329
|
|
339
|
+
|
|
340
|
+
/** The mana target for the rollup */
|
|
341
|
+
manaTarget: 0n,
|
|
342
|
+
|
|
343
|
+
exitDelaySeconds: 5 * 24 * 60 * 60,
|
|
344
|
+
|
|
345
|
+
/** The proving cost per mana */
|
|
346
|
+
provingCostPerMana: 0n,
|
|
347
|
+
|
|
348
|
+
ejectionThreshold: 100_000n * 10n ** 18n,
|
|
349
|
+
activationThreshold: 200_000n * 10n ** 18n,
|
|
350
|
+
|
|
351
|
+
governanceProposerRoundSize: 300, // TODO TMNT-322
|
|
352
|
+
governanceProposerQuorum: 151, // TODO TMNT-322
|
|
353
|
+
|
|
354
|
+
// Node slashing config
|
|
355
|
+
// TODO TMNT-330
|
|
356
|
+
slashMinPenaltyPercentage: 0.5,
|
|
357
|
+
slashMaxPenaltyPercentage: 2.0,
|
|
358
|
+
slashInactivityTargetPercentage: 0.7,
|
|
359
|
+
slashInactivityConsecutiveEpochThreshold: 2,
|
|
360
|
+
slashInactivityPenalty: 2_000n * 10n ** 18n,
|
|
361
|
+
slashPrunePenalty: 0n, // 2_000n * 10n ** 18n, We disable slashing for prune offenses right now
|
|
362
|
+
slashDataWithholdingPenalty: 0n, // 2_000n * 10n ** 18n, We disable slashing for data withholding offenses right now
|
|
363
|
+
slashProposeInvalidAttestationsPenalty: 50_000n * 10n ** 18n,
|
|
364
|
+
slashAttestDescendantOfInvalidPenalty: 50_000n * 10n ** 18n,
|
|
365
|
+
slashUnknownPenalty: 2_000n * 10n ** 18n,
|
|
366
|
+
slashBroadcastedInvalidBlockPenalty: 0n, // 10_000n * 10n ** 18n, Disabled for now until further testing
|
|
367
|
+
slashMaxPayloadSize: 50,
|
|
368
|
+
slashGracePeriodL2Slots: 32 * 4, // One round from genesis
|
|
369
|
+
slashOffenseExpirationRounds: 8,
|
|
370
|
+
sentinelEnabled: true,
|
|
371
|
+
slashExecuteRoundsLookBack: 4,
|
|
372
|
+
|
|
373
|
+
...DefaultNetworkDBMapSizeConfig,
|
|
263
374
|
};
|
|
264
375
|
|
|
265
376
|
const BOOTNODE_CACHE_DURATION_MS = 60 * 60 * 1000; // 1 hour;
|
|
266
377
|
|
|
267
378
|
export async function getBootnodes(networkName: NetworkNames, cacheDir?: string) {
|
|
268
|
-
const cacheFile = cacheDir ? join(cacheDir, networkName, 'bootnodes.json') : undefined;
|
|
269
|
-
try {
|
|
270
|
-
if (cacheFile) {
|
|
271
|
-
const info = await stat(cacheFile);
|
|
272
|
-
if (info.mtimeMs + BOOTNODE_CACHE_DURATION_MS > Date.now()) {
|
|
273
|
-
return JSON.parse(await readFile(cacheFile, 'utf-8'))['bootnodes'];
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
} catch {
|
|
277
|
-
// no-op. Get the remote-file
|
|
278
|
-
}
|
|
279
|
-
|
|
280
379
|
const url = `http://static.aztec.network/${networkName}/bootnodes.json`;
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
const json = await response.json();
|
|
288
|
-
|
|
289
|
-
try {
|
|
290
|
-
if (cacheFile) {
|
|
291
|
-
await mkdir(dirname(cacheFile), { recursive: true });
|
|
292
|
-
await writeFile(cacheFile, JSON.stringify(json), 'utf-8');
|
|
293
|
-
}
|
|
294
|
-
} catch {
|
|
295
|
-
// no-op
|
|
296
|
-
}
|
|
380
|
+
const data = await cachedFetch(url, {
|
|
381
|
+
cacheDurationMs: BOOTNODE_CACHE_DURATION_MS,
|
|
382
|
+
cacheFile: cacheDir ? join(cacheDir, networkName, 'bootnodes.json') : undefined,
|
|
383
|
+
});
|
|
297
384
|
|
|
298
|
-
return
|
|
385
|
+
return data?.bootnodes;
|
|
299
386
|
}
|
|
300
387
|
|
|
301
388
|
export async function getL2ChainConfig(
|
|
@@ -309,6 +396,8 @@ export async function getL2ChainConfig(
|
|
|
309
396
|
config = { ...testnetL2ChainConfig };
|
|
310
397
|
} else if (networkName === 'staging-ignition') {
|
|
311
398
|
config = { ...stagingIgnitionL2ChainConfig };
|
|
399
|
+
} else if (networkName === 'ignition') {
|
|
400
|
+
config = { ...ignitionL2ChainConfig };
|
|
312
401
|
}
|
|
313
402
|
if (!config) {
|
|
314
403
|
return undefined;
|
|
@@ -321,23 +410,6 @@ export async function getL2ChainConfig(
|
|
|
321
410
|
return config;
|
|
322
411
|
}
|
|
323
412
|
|
|
324
|
-
function enrichVar(envVar: EnvVar, value: string | undefined) {
|
|
325
|
-
// Don't override
|
|
326
|
-
if (process.env[envVar] || value === undefined) {
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
process.env[envVar] = value;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
function enrichEthAddressVar(envVar: EnvVar, value: string) {
|
|
333
|
-
// EthAddress doesn't like being given empty strings
|
|
334
|
-
if (value === '') {
|
|
335
|
-
enrichVar(envVar, EthAddress.ZERO.toString());
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
enrichVar(envVar, value);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
413
|
function getDefaultDataDir(networkName: NetworkNames): string {
|
|
342
414
|
return path.join(process.env.HOME || '~', '.aztec', networkName, 'data');
|
|
343
415
|
}
|
|
@@ -367,6 +439,12 @@ export async function enrichEnvironmentWithChainConfig(networkName: NetworkNames
|
|
|
367
439
|
enrichVar('SYNC_SNAPSHOTS_URL', config.snapshotsUrl);
|
|
368
440
|
enrichVar('P2P_MAX_TX_POOL_SIZE', config.maxTxPoolSize.toString());
|
|
369
441
|
|
|
442
|
+
enrichVar('DATA_STORE_MAP_SIZE_KB', config.dbMapSizeKb.toString());
|
|
443
|
+
enrichVar('ARCHIVER_STORE_MAP_SIZE_KB', config.archiverStoreMapSizeKb.toString());
|
|
444
|
+
enrichVar('NOTE_HASH_TREE_MAP_SIZE_KB', config.noteHashTreeMapSizeKb.toString());
|
|
445
|
+
enrichVar('NULLIFIER_TREE_MAP_SIZE_KB', config.nullifierTreeMapSizeKb.toString());
|
|
446
|
+
enrichVar('PUBLIC_DATA_TREE_MAP_SIZE_KB', config.publicDataTreeMapSizeKb.toString());
|
|
447
|
+
|
|
370
448
|
if (config.autoUpdate) {
|
|
371
449
|
enrichVar('AUTO_UPDATE', config.autoUpdate?.toString());
|
|
372
450
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec/aztec.js';
|
|
2
|
+
import type { EnvVar } from '@aztec/foundation/config';
|
|
3
|
+
|
|
4
|
+
export function enrichVar(envVar: EnvVar, value: string | undefined) {
|
|
5
|
+
// Don't override
|
|
6
|
+
if (process.env[envVar] || value === undefined) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
process.env[envVar] = value;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function enrichEthAddressVar(envVar: EnvVar, value: string) {
|
|
13
|
+
// EthAddress doesn't like being given empty strings
|
|
14
|
+
enrichVar(envVar, value || EthAddress.ZERO.toString());
|
|
15
|
+
}
|
package/src/config/index.ts
CHANGED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { type NetworkConfig, NetworkConfigMapSchema, type NetworkNames } from '@aztec/foundation/config';
|
|
2
|
+
|
|
3
|
+
import { readFile } from 'fs/promises';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
|
|
6
|
+
import { cachedFetch } from './cached_fetch.js';
|
|
7
|
+
import { enrichEthAddressVar, enrichVar } from './enrich_env.js';
|
|
8
|
+
|
|
9
|
+
const DEFAULT_CONFIG_URL =
|
|
10
|
+
'https://raw.githubusercontent.com/AztecProtocol/networks/refs/heads/main/network_config.json';
|
|
11
|
+
const NETWORK_CONFIG_CACHE_DURATION_MS = 60 * 60 * 1000; // 1 hour
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Fetches remote network configuration from GitHub with caching support.
|
|
15
|
+
* Uses the reusable cachedFetch utility.
|
|
16
|
+
*
|
|
17
|
+
* @param networkName - The network name to fetch config for
|
|
18
|
+
* @param cacheDir - Optional cache directory for storing fetched config
|
|
19
|
+
* @returns Remote configuration for the specified network, or undefined if not found/error
|
|
20
|
+
*/
|
|
21
|
+
export async function getNetworkConfig(
|
|
22
|
+
networkName: NetworkNames,
|
|
23
|
+
cacheDir?: string,
|
|
24
|
+
): Promise<NetworkConfig | undefined> {
|
|
25
|
+
let url: URL | undefined;
|
|
26
|
+
const configLocation = process.env.NETWORK_CONFIG_LOCATION || DEFAULT_CONFIG_URL;
|
|
27
|
+
|
|
28
|
+
if (!configLocation) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
if (configLocation.includes('://')) {
|
|
34
|
+
url = new URL(configLocation);
|
|
35
|
+
} else {
|
|
36
|
+
url = new URL(`file://${configLocation}`);
|
|
37
|
+
}
|
|
38
|
+
} catch {
|
|
39
|
+
/* no-op */
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!url) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
let rawConfig: any;
|
|
48
|
+
|
|
49
|
+
if (url.protocol === 'http:' || url.protocol === 'https:') {
|
|
50
|
+
rawConfig = await cachedFetch(url.href, {
|
|
51
|
+
cacheDurationMs: NETWORK_CONFIG_CACHE_DURATION_MS,
|
|
52
|
+
cacheFile: cacheDir ? join(cacheDir, networkName, 'network_config.json') : undefined,
|
|
53
|
+
});
|
|
54
|
+
} else if (url.protocol === 'file:') {
|
|
55
|
+
rawConfig = JSON.parse(await readFile(url.pathname, 'utf-8'));
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error('Unsupported Aztec network config protocol: ' + url.href);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!rawConfig) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const networkConfigMap = NetworkConfigMapSchema.parse(rawConfig);
|
|
65
|
+
if (networkName in networkConfigMap) {
|
|
66
|
+
return networkConfigMap[networkName];
|
|
67
|
+
} else {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Enriches environment variables with remote network configuration.
|
|
77
|
+
* This function is called before node config initialization to set env vars
|
|
78
|
+
* from the remote config, following the same pattern as enrichEnvironmentWithChainConfig().
|
|
79
|
+
*
|
|
80
|
+
* @param networkName - The network name to fetch remote config for
|
|
81
|
+
*/
|
|
82
|
+
export async function enrichEnvironmentWithNetworkConfig(networkName: NetworkNames) {
|
|
83
|
+
if (networkName === 'local') {
|
|
84
|
+
return; // No remote config for local development
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const cacheDir = process.env.DATA_DIRECTORY ? join(process.env.DATA_DIRECTORY, 'cache') : undefined;
|
|
88
|
+
const networkConfig = await getNetworkConfig(networkName, cacheDir);
|
|
89
|
+
|
|
90
|
+
if (!networkConfig) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
enrichVar('BOOTSTRAP_NODES', networkConfig.bootnodes.join(','));
|
|
95
|
+
enrichVar('L1_CHAIN_ID', String(networkConfig.l1ChainId));
|
|
96
|
+
|
|
97
|
+
// Snapshot synch only supports a single source. Take the first
|
|
98
|
+
// See A-101 for more details
|
|
99
|
+
const firstSource = networkConfig[0];
|
|
100
|
+
if (firstSource) {
|
|
101
|
+
enrichVar('SYNC_SNAPSHOTS_URL', networkConfig.snapshots.join(','));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
enrichEthAddressVar('REGISTRY_CONTRACT_ADDRESS', networkConfig.registryAddress.toString());
|
|
105
|
+
if (networkConfig.feeAssetHandlerAddress) {
|
|
106
|
+
enrichEthAddressVar('FEE_ASSET_HANDLER_CONTRACT_ADDRESS', networkConfig.feeAssetHandlerAddress.toString());
|
|
107
|
+
}
|
|
108
|
+
}
|