@aztec/cli 2.1.0-rc.9 → 2.1.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dest/cmds/l1/deploy_new_rollup.d.ts +1 -1
  2. package/dest/cmds/l1/deploy_new_rollup.d.ts.map +1 -1
  3. package/dest/cmds/l1/deploy_new_rollup.js +2 -2
  4. package/dest/cmds/l1/index.d.ts.map +1 -1
  5. package/dest/cmds/l1/index.js +2 -2
  6. package/dest/cmds/validator_keys/add.d.ts +5 -0
  7. package/dest/cmds/validator_keys/add.d.ts.map +1 -0
  8. package/dest/cmds/validator_keys/add.js +70 -0
  9. package/dest/cmds/validator_keys/generate_bls_keypair.d.ts +12 -0
  10. package/dest/cmds/validator_keys/generate_bls_keypair.d.ts.map +1 -0
  11. package/dest/cmds/validator_keys/generate_bls_keypair.js +26 -0
  12. package/dest/cmds/validator_keys/index.d.ts +4 -0
  13. package/dest/cmds/validator_keys/index.d.ts.map +1 -0
  14. package/dest/cmds/validator_keys/index.js +20 -0
  15. package/dest/cmds/validator_keys/new.d.ts +26 -0
  16. package/dest/cmds/validator_keys/new.d.ts.map +1 -0
  17. package/dest/cmds/validator_keys/new.js +60 -0
  18. package/dest/cmds/validator_keys/shared.d.ts +68 -0
  19. package/dest/cmds/validator_keys/shared.d.ts.map +1 -0
  20. package/dest/cmds/validator_keys/shared.js +271 -0
  21. package/dest/config/chain_l2_config.d.ts +6 -4
  22. package/dest/config/chain_l2_config.d.ts.map +1 -1
  23. package/dest/config/chain_l2_config.js +82 -65
  24. package/dest/utils/aztec.d.ts +1 -1
  25. package/dest/utils/aztec.d.ts.map +1 -1
  26. package/dest/utils/aztec.js +2 -2
  27. package/dest/utils/commands.d.ts +10 -1
  28. package/dest/utils/commands.d.ts.map +1 -1
  29. package/dest/utils/commands.js +30 -3
  30. package/package.json +28 -24
  31. package/src/cmds/l1/deploy_new_rollup.ts +2 -0
  32. package/src/cmds/l1/index.ts +2 -0
  33. package/src/cmds/validator_keys/add.ts +113 -0
  34. package/src/cmds/validator_keys/generate_bls_keypair.ts +33 -0
  35. package/src/cmds/validator_keys/index.ts +96 -0
  36. package/src/cmds/validator_keys/new.ts +120 -0
  37. package/src/cmds/validator_keys/shared.ts +321 -0
  38. package/src/config/chain_l2_config.ts +110 -84
  39. package/src/utils/aztec.ts +2 -0
  40. package/src/utils/commands.ts +41 -3
@@ -0,0 +1,321 @@
1
+ import { prettyPrintJSON } from '@aztec/cli/utils';
2
+ import { computeBn254G1PublicKeyCompressed, deriveBlsPrivateKey } from '@aztec/foundation/crypto';
3
+ import { createBn254Keystore } from '@aztec/foundation/crypto/bls/bn254_keystore';
4
+ import type { EthAddress } from '@aztec/foundation/eth-address';
5
+ import type { LogFn } from '@aztec/foundation/log';
6
+ import type { EthAccount, EthPrivateKey, ValidatorKeyStore } from '@aztec/node-keystore/types';
7
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
8
+
9
+ import { Wallet } from '@ethersproject/wallet';
10
+ import { constants as fsConstants, mkdirSync } from 'fs';
11
+ import { access, writeFile } from 'fs/promises';
12
+ import { homedir } from 'os';
13
+ import { dirname, isAbsolute, join } from 'path';
14
+ import { mnemonicToAccount } from 'viem/accounts';
15
+
16
+ export type ValidatorSummary = { attesterEth?: string; attesterBls?: string; publisherEth?: string[] };
17
+
18
+ export type BuildValidatorsInput = {
19
+ validatorCount: number;
20
+ publisherCount?: number;
21
+ accountIndex: number;
22
+ baseAddressIndex: number;
23
+ mnemonic: string;
24
+ ikm?: string;
25
+ blsPath?: string;
26
+ blsOnly?: boolean;
27
+ feeRecipient: AztecAddress;
28
+ coinbase?: EthAddress;
29
+ remoteSigner?: string;
30
+ fundingAccount?: EthAddress;
31
+ };
32
+
33
+ export function withValidatorIndex(path: string, index: number) {
34
+ const parts = path.split('/');
35
+ if (parts.length >= 4 && parts[0] === 'm' && parts[1] === '12381' && parts[2] === '3600') {
36
+ parts[3] = String(index);
37
+ return parts.join('/');
38
+ }
39
+ return path;
40
+ }
41
+
42
+ /**
43
+ * Compute a compressed BN254 G1 public key from a private key.
44
+ * @param privateKeyHex - Private key as 0x-prefixed hex string
45
+ * @returns Compressed G1 point (32 bytes with sign bit in MSB)
46
+ */
47
+ export async function computeBlsPublicKeyCompressed(privateKeyHex: string): Promise<string> {
48
+ return await computeBn254G1PublicKeyCompressed(privateKeyHex);
49
+ }
50
+
51
+ export function deriveEthAttester(
52
+ mnemonic: string,
53
+ baseAccountIndex: number,
54
+ addressIndex: number,
55
+ remoteSigner?: string,
56
+ ): EthAccount | EthPrivateKey {
57
+ const acct = mnemonicToAccount(mnemonic, { accountIndex: baseAccountIndex, addressIndex });
58
+ return remoteSigner
59
+ ? ({ address: acct.address as unknown as EthAddress, remoteSignerUrl: remoteSigner } as EthAccount)
60
+ : (('0x' + Buffer.from(acct.getHdKey().privateKey!).toString('hex')) as EthPrivateKey);
61
+ }
62
+
63
+ export async function buildValidatorEntries(input: BuildValidatorsInput) {
64
+ const {
65
+ validatorCount,
66
+ publisherCount = 0,
67
+ accountIndex,
68
+ baseAddressIndex,
69
+ mnemonic,
70
+ ikm,
71
+ blsPath,
72
+ blsOnly,
73
+ feeRecipient,
74
+ coinbase,
75
+ remoteSigner,
76
+ fundingAccount,
77
+ } = input;
78
+
79
+ const defaultBlsPath = 'm/12381/3600/0/0/0';
80
+ const summaries: ValidatorSummary[] = [];
81
+
82
+ const validators = await Promise.all(
83
+ Array.from({ length: validatorCount }, async (_unused, i) => {
84
+ const addressIndex = baseAddressIndex + i;
85
+ const basePath = blsPath ?? defaultBlsPath;
86
+ const perValidatorPath = withValidatorIndex(basePath, addressIndex);
87
+
88
+ const blsPrivKey = blsOnly || ikm || mnemonic ? deriveBlsPrivateKey(mnemonic, ikm, perValidatorPath) : undefined;
89
+ const blsPubCompressed = blsPrivKey ? await computeBlsPublicKeyCompressed(blsPrivKey) : undefined;
90
+
91
+ if (blsOnly) {
92
+ const attester = { bls: blsPrivKey! };
93
+ summaries.push({ attesterBls: blsPubCompressed });
94
+ return { attester, feeRecipient } as ValidatorKeyStore;
95
+ }
96
+
97
+ const ethAttester = deriveEthAttester(mnemonic, accountIndex, addressIndex, remoteSigner);
98
+ const attester = blsPrivKey ? { eth: ethAttester, bls: blsPrivKey } : ethAttester;
99
+
100
+ let publisherField: EthAccount | EthPrivateKey | (EthAccount | EthPrivateKey)[] | undefined;
101
+ const publisherAddresses: string[] = [];
102
+ if (publisherCount > 0) {
103
+ const publishersBaseIndex = baseAddressIndex + validatorCount + i * publisherCount;
104
+ const publisherAccounts = Array.from({ length: publisherCount }, (_unused2, j) => {
105
+ const publisherAddressIndex = publishersBaseIndex + j;
106
+ const pubAcct = mnemonicToAccount(mnemonic, {
107
+ accountIndex,
108
+ addressIndex: publisherAddressIndex,
109
+ });
110
+ publisherAddresses.push(pubAcct.address as unknown as string);
111
+ return remoteSigner
112
+ ? ({ address: pubAcct.address as unknown as EthAddress, remoteSignerUrl: remoteSigner } as EthAccount)
113
+ : (('0x' + Buffer.from(pubAcct.getHdKey().privateKey!).toString('hex')) as EthPrivateKey);
114
+ });
115
+ publisherField = publisherCount === 1 ? publisherAccounts[0] : publisherAccounts;
116
+ }
117
+
118
+ const acct = mnemonicToAccount(mnemonic, {
119
+ accountIndex,
120
+ addressIndex,
121
+ });
122
+ const attesterEthAddress = acct.address as unknown as string;
123
+ summaries.push({
124
+ attesterEth: attesterEthAddress,
125
+ attesterBls: blsPubCompressed,
126
+ publisherEth: publisherAddresses.length > 0 ? publisherAddresses : undefined,
127
+ });
128
+
129
+ return {
130
+ attester,
131
+ ...(publisherField !== undefined ? { publisher: publisherField } : {}),
132
+ feeRecipient,
133
+ coinbase,
134
+ fundingAccount,
135
+ } as ValidatorKeyStore;
136
+ }),
137
+ );
138
+
139
+ return { validators, summaries };
140
+ }
141
+
142
+ export async function resolveKeystoreOutputPath(dataDir?: string, file?: string) {
143
+ const defaultDataDir = join(homedir(), '.aztec', 'keystore');
144
+ const resolvedDir = dataDir && dataDir.length > 0 ? dataDir : defaultDataDir;
145
+ let outputPath: string;
146
+ if (file && file.length > 0) {
147
+ outputPath = isAbsolute(file) ? file : join(resolvedDir, file);
148
+ } else {
149
+ let index = 1;
150
+ while (true) {
151
+ const candidate = join(resolvedDir, `key${index}.json`);
152
+ try {
153
+ await access(candidate, fsConstants.F_OK);
154
+ index += 1;
155
+ } catch {
156
+ outputPath = candidate;
157
+ break;
158
+ }
159
+ }
160
+ }
161
+ return { resolvedDir, outputPath: outputPath! };
162
+ }
163
+
164
+ export async function writeKeystoreFile(path: string, keystore: unknown) {
165
+ mkdirSync(dirname(path), { recursive: true });
166
+ await writeFile(path, JSON.stringify(keystore, null, 2), { encoding: 'utf-8' });
167
+ }
168
+
169
+ export function logValidatorSummaries(log: LogFn, summaries: ValidatorSummary[]) {
170
+ const lines: string[] = [];
171
+ for (let i = 0; i < summaries.length; i++) {
172
+ const v = summaries[i];
173
+ lines.push(`acc${i + 1}:`);
174
+ lines.push(` attester:`);
175
+ if (v.attesterEth) {
176
+ lines.push(` eth: ${v.attesterEth}`);
177
+ }
178
+ if (v.attesterBls) {
179
+ lines.push(` bls: ${v.attesterBls}`);
180
+ }
181
+ if (v.publisherEth && v.publisherEth.length > 0) {
182
+ lines.push(` publisher:`);
183
+ for (const addr of v.publisherEth) {
184
+ lines.push(` - ${addr}`);
185
+ }
186
+ }
187
+ }
188
+ if (lines.length > 0) {
189
+ log(lines.join('\n'));
190
+ }
191
+ }
192
+
193
+ export function maybePrintJson(log: LogFn, jsonFlag: boolean | undefined, obj: unknown) {
194
+ if (jsonFlag) {
195
+ log(prettyPrintJSON(obj as Record<string, any>));
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Writes a BN254 keystore file for a BN254 BLS private key.
201
+ * Returns the absolute path to the written file.
202
+ *
203
+ * @param outDir - Directory to write the keystore file to
204
+ * @param fileNameBase - Base name for the keystore file (will be sanitized)
205
+ * @param password - Password for encrypting the private key
206
+ * @param privateKeyHex - Private key as 0x-prefixed hex string (32 bytes)
207
+ * @param pubkeyHex - Public key as hex string
208
+ * @param derivationPath - BIP-44 style derivation path
209
+ * @returns Absolute path to the written keystore file
210
+ */
211
+ export async function writeBn254BlsKeystore(
212
+ outDir: string,
213
+ fileNameBase: string,
214
+ password: string,
215
+ privateKeyHex: string,
216
+ pubkeyHex: string,
217
+ derivationPath: string,
218
+ ): Promise<string> {
219
+ mkdirSync(outDir, { recursive: true });
220
+
221
+ const keystore = createBn254Keystore(password, privateKeyHex, pubkeyHex, derivationPath);
222
+
223
+ const safeBase = fileNameBase.replace(/[^a-zA-Z0-9_-]/g, '_');
224
+ const outPath = join(outDir, `keystore-${safeBase}.json`);
225
+ await writeFile(outPath, JSON.stringify(keystore, null, 2), { encoding: 'utf-8' });
226
+ return outPath;
227
+ }
228
+
229
+ /** Replace plaintext BLS keys in validators with { path, password } pointing to BN254 keystore files. */
230
+ export async function writeBlsBn254ToFile(
231
+ validators: ValidatorKeyStore[],
232
+ options: { outDir: string; password: string },
233
+ ): Promise<void> {
234
+ for (let i = 0; i < validators.length; i++) {
235
+ const v = validators[i];
236
+ if (!v || typeof v !== 'object' || !('attester' in v)) {
237
+ continue;
238
+ }
239
+ const att = (v as any).attester;
240
+
241
+ // Shapes: { bls: <hex> } or { eth: <ethAccount>, bls?: <hex> } or plain EthAccount
242
+ const blsKey: string | undefined = typeof att === 'object' && 'bls' in att ? (att as any).bls : undefined;
243
+ if (!blsKey || typeof blsKey !== 'string') {
244
+ continue;
245
+ }
246
+
247
+ const pub = await computeBlsPublicKeyCompressed(blsKey);
248
+ const path = 'm/12381/3600/0/0/0';
249
+ const fileBase = `${String(i + 1)}_${pub.slice(2, 18)}`;
250
+ const keystorePath = await writeBn254BlsKeystore(options.outDir, fileBase, options.password, blsKey, pub, path);
251
+
252
+ if (typeof att === 'object') {
253
+ (att as any).bls = { path: keystorePath, password: options.password };
254
+ }
255
+ }
256
+ }
257
+
258
+ /** Writes an Ethereum JSON V3 keystore using ethers, returns absolute path */
259
+ export async function writeEthJsonV3Keystore(
260
+ outDir: string,
261
+ fileNameBase: string,
262
+ password: string,
263
+ privateKeyHex: string,
264
+ ): Promise<string> {
265
+ const safeBase = fileNameBase.replace(/[^a-zA-Z0-9_-]/g, '_');
266
+ mkdirSync(outDir, { recursive: true });
267
+ const wallet = new Wallet(privateKeyHex);
268
+ const json = await wallet.encrypt(password);
269
+ const outPath = join(outDir, `keystore-eth-${safeBase}.json`);
270
+ await writeFile(outPath, json, { encoding: 'utf-8' });
271
+ return outPath;
272
+ }
273
+
274
+ /** Replace plaintext ETH keys in validators with { path, password } pointing to JSON V3 files. */
275
+ export async function writeEthJsonV3ToFile(
276
+ validators: ValidatorKeyStore[],
277
+ options: { outDir: string; password: string },
278
+ ): Promise<void> {
279
+ const maybeEncryptEth = async (account: any, label: string) => {
280
+ if (typeof account === 'string' && account.startsWith('0x') && account.length === 66) {
281
+ const fileBase = `${label}_${account.slice(2, 10)}`;
282
+ const p = await writeEthJsonV3Keystore(options.outDir, fileBase, options.password, account);
283
+ return { path: p, password: options.password };
284
+ }
285
+ return account;
286
+ };
287
+
288
+ for (let i = 0; i < validators.length; i++) {
289
+ const v = validators[i];
290
+ if (!v || typeof v !== 'object') {
291
+ continue;
292
+ }
293
+
294
+ // attester may be string (eth), object with eth, or remote signer
295
+ const att = (v as any).attester;
296
+ if (typeof att === 'string') {
297
+ (v as any).attester = await maybeEncryptEth(att, `attester_${i + 1}`);
298
+ } else if (att && typeof att === 'object' && 'eth' in att) {
299
+ (att as any).eth = await maybeEncryptEth((att as any).eth, `attester_${i + 1}`);
300
+ }
301
+
302
+ // publisher can be single or array
303
+ if ('publisher' in v) {
304
+ const pub = (v as any).publisher;
305
+ if (Array.isArray(pub)) {
306
+ const out: any[] = [];
307
+ for (let j = 0; j < pub.length; j++) {
308
+ out.push(await maybeEncryptEth(pub[j], `publisher_${i + 1}_${j + 1}`));
309
+ }
310
+ (v as any).publisher = out;
311
+ } else if (pub !== undefined) {
312
+ (v as any).publisher = await maybeEncryptEth(pub, `publisher_${i + 1}`);
313
+ }
314
+ }
315
+
316
+ // Optional fundingAccount within validator
317
+ if ('fundingAccount' in v) {
318
+ (v as any).fundingAccount = await maybeEncryptEth((v as any).fundingAccount, `funding_${i + 1}`);
319
+ }
320
+ }
321
+ }
@@ -1,14 +1,13 @@
1
1
  import { DefaultL1ContractsConfig, type L1ContractsConfig } from '@aztec/ethereum';
2
- import type { EnvVar, NetworkNames } from '@aztec/foundation/config';
2
+ import type { NetworkNames } from '@aztec/foundation/config';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import type { SharedNodeConfig } from '@aztec/node-lib/config';
5
5
  import type { P2PConfig } from '@aztec/p2p/config';
6
6
  import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
7
7
 
8
- import path, { join } from 'path';
8
+ import path from 'path';
9
9
 
10
10
  import publicIncludeMetrics from '../../public_include_metric_prefixes.json' with { type: 'json' };
11
- import { cachedFetch } from './cached_fetch.js';
12
11
  import { enrichEthAddressVar, enrichVar } from './enrich_env.js';
13
12
 
14
13
  const SNAPSHOTS_URL = 'https://aztec-labs-snapshots.com';
@@ -34,6 +33,8 @@ export type L2ChainConfig = L1ContractsConfig &
34
33
  publicIncludeMetrics?: string[];
35
34
  publicMetricsCollectorUrl?: string;
36
35
  publicMetricsCollectFrom?: string[];
36
+ skipArchiverInitialSync?: boolean;
37
+ blobAllowEmptySources?: boolean;
37
38
 
38
39
  // Setting the dbMapSize provides the default for every DB in the node.
39
40
  // Then we explicitly override the sizes for the archiver and the larger trees.
@@ -45,6 +46,7 @@ export type L2ChainConfig = L1ContractsConfig &
45
46
 
46
47
  // Control whether sentinel is enabled or not. Needed for slashing
47
48
  sentinelEnabled: boolean;
49
+ disableTransactions: boolean;
48
50
  };
49
51
 
50
52
  const DefaultSlashConfig = {
@@ -96,6 +98,7 @@ export const stagingIgnitionL2ChainConfig: L2ChainConfig = {
96
98
  l1ChainId: 11155111,
97
99
  testAccounts: false,
98
100
  sponsoredFPC: false,
101
+ disableTransactions: true,
99
102
  p2pEnabled: true,
100
103
  p2pBootstrapNodes: [],
101
104
  seqMinTxsPerBlock: 0,
@@ -109,6 +112,7 @@ export const stagingIgnitionL2ChainConfig: L2ChainConfig = {
109
112
  publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
110
113
  publicMetricsCollectFrom: ['sequencer'],
111
114
  txPoolDeleteTxsAfterReorg: false,
115
+ blobAllowEmptySources: true,
112
116
 
113
117
  /** How many seconds an L1 slot lasts. */
114
118
  ethereumSlotDuration: 12,
@@ -148,11 +152,10 @@ export const stagingIgnitionL2ChainConfig: L2ChainConfig = {
148
152
  activationThreshold: 200_000n * 10n ** 18n,
149
153
  localEjectionThreshold: 196_000n * 10n ** 18n,
150
154
 
151
- governanceProposerRoundSize: 300, // TODO TMNT-322
152
- governanceProposerQuorum: 151, // TODO TMNT-322
155
+ governanceProposerRoundSize: 300,
156
+ governanceProposerQuorum: 151,
153
157
 
154
158
  // Node slashing config
155
- // TODO TMNT-330
156
159
  slashMinPenaltyPercentage: 0.5,
157
160
  slashMaxPenaltyPercentage: 2.0,
158
161
  slashInactivityTargetPercentage: 0.7,
@@ -177,6 +180,7 @@ export const stagingPublicL2ChainConfig: L2ChainConfig = {
177
180
  l1ChainId: 11155111,
178
181
  testAccounts: false,
179
182
  sponsoredFPC: true,
183
+ disableTransactions: false,
180
184
  p2pEnabled: true,
181
185
  p2pBootstrapNodes: [],
182
186
  seqMinTxsPerBlock: 0,
@@ -231,9 +235,10 @@ export const testnetL2ChainConfig: L2ChainConfig = {
231
235
  testAccounts: false,
232
236
  sponsoredFPC: true,
233
237
  p2pEnabled: true,
238
+ disableTransactions: true,
234
239
  p2pBootstrapNodes: [],
235
240
  seqMinTxsPerBlock: 0,
236
- seqMaxTxsPerBlock: 20,
241
+ seqMaxTxsPerBlock: 0,
237
242
  realProofs: true,
238
243
  snapshotsUrls: [`${SNAPSHOTS_URL}/testnet/`],
239
244
  autoUpdate: 'config-and-version',
@@ -243,46 +248,80 @@ export const testnetL2ChainConfig: L2ChainConfig = {
243
248
  publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
244
249
  publicMetricsCollectFrom: ['sequencer'],
245
250
  txPoolDeleteTxsAfterReorg: true,
251
+ skipArchiverInitialSync: true,
252
+ blobAllowEmptySources: true,
246
253
 
247
- // Deployment stuff
248
254
  /** How many seconds an L1 slot lasts. */
249
255
  ethereumSlotDuration: 12,
250
256
  /** How many seconds an L2 slots lasts (must be multiple of ethereum slot duration). */
251
- aztecSlotDuration: 36,
257
+ aztecSlotDuration: 72,
252
258
  /** How many L2 slots an epoch lasts. */
253
259
  aztecEpochDuration: 32,
254
260
  /** The target validator committee size. */
255
- aztecTargetCommitteeSize: 48,
261
+ aztecTargetCommitteeSize: 24,
256
262
  /** The number of epochs to lag behind the current epoch for validator selection. */
257
263
  lagInEpochs: 2,
258
264
  /** The number of epochs after an epoch ends that proofs are still accepted. */
259
265
  aztecProofSubmissionEpochs: 1,
260
- /** The deposit amount for a validator */
261
- activationThreshold: DefaultL1ContractsConfig.activationThreshold,
262
- /** The minimum stake for a validator. */
263
- ejectionThreshold: DefaultL1ContractsConfig.ejectionThreshold,
264
- /** The local ejection threshold for a validator. Stricter than ejectionThreshold but local to a specific rollup */
265
- localEjectionThreshold: DefaultL1ContractsConfig.localEjectionThreshold,
266
- /** The slashing round size */
267
- slashingRoundSizeInEpochs: DefaultL1ContractsConfig.slashingRoundSizeInEpochs,
268
- /** Governance proposing round size */
269
- governanceProposerRoundSize: DefaultL1ContractsConfig.governanceProposerRoundSize,
266
+
267
+ // This is a diff from mainnet: we have 2-strikes you're out, rather than 3 on mainnet.
268
+ localEjectionThreshold: 198_000n * 10n ** 18n,
269
+ /** How many sequencers must agree with a slash for it to be executed. */
270
+ slashingQuorum: 65,
271
+ slashingRoundSizeInEpochs: 4,
272
+ slashingExecutionDelayInRounds: 28,
273
+ slashingLifetimeInRounds: 34,
274
+ slashingVetoer: EthAddress.fromString('0xBbB4aF368d02827945748b28CD4b2D42e4A37480'),
275
+ slashingOffsetInRounds: 2,
276
+
277
+ slashingDisableDuration: 259_200, // 3 days
278
+ slasherFlavor: 'tally',
279
+
280
+ slashAmountSmall: 2_000n * 10n ** 18n,
281
+ slashAmountMedium: 2_000n * 10n ** 18n,
282
+ slashAmountLarge: 2_000n * 10n ** 18n,
283
+
270
284
  /** The mana target for the rollup */
271
- manaTarget: DefaultL1ContractsConfig.manaTarget,
285
+ manaTarget: 0n,
286
+
272
287
  /** The proving cost per mana */
273
- provingCostPerMana: DefaultL1ContractsConfig.provingCostPerMana,
274
- /** Exit delay for stakers */
275
- exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
288
+ provingCostPerMana: 0n,
276
289
 
277
- ...DefaultSlashConfig,
278
- slashPrunePenalty: 0n,
279
- slashDataWithholdingPenalty: 0n,
280
- slashInactivityPenalty: DefaultL1ContractsConfig.slashAmountMedium,
290
+ exitDelaySeconds: 4 * 24 * 60 * 60, // 4 days
291
+
292
+ activationThreshold: 200_000n * 10n ** 18n,
293
+ ejectionThreshold: 100_000n * 10n ** 18n,
294
+
295
+ governanceProposerRoundSize: 300,
296
+ governanceProposerQuorum: 151,
297
+
298
+ // Node slashing config
299
+ slashInactivityTargetPercentage: 0.8,
300
+ slashInactivityConsecutiveEpochThreshold: 2,
301
+ slashInactivityPenalty: 2_000n * 10n ** 18n,
302
+ slashPrunePenalty: 0n, // 2_000n * 10n ** 18n, We disable slashing for prune offenses right now
303
+ slashDataWithholdingPenalty: 0n, // 2_000n * 10n ** 18n, We disable slashing for data withholding offenses right now
304
+ slashProposeInvalidAttestationsPenalty: 2_000n * 10n ** 18n,
305
+ slashAttestDescendantOfInvalidPenalty: 2_000n * 10n ** 18n,
306
+ slashUnknownPenalty: 2_000n * 10n ** 18n,
307
+ slashBroadcastedInvalidBlockPenalty: 2_000n * 10n ** 18n, // 10_000n * 10n ** 18n, Disabled for now until further testing
308
+ slashGracePeriodL2Slots: 1_200, // One day from deployment
309
+ slashOffenseExpirationRounds: 8,
310
+
311
+ slashMinPenaltyPercentage: 0.5,
312
+ slashMaxPenaltyPercentage: 2.0,
313
+ slashMaxPayloadSize: 50,
314
+ slashExecuteRoundsLookBack: 4,
315
+
316
+ sentinelEnabled: true,
281
317
 
282
318
  ...DefaultNetworkDBMapSizeConfig,
283
319
  };
284
320
 
285
- export const ignitionL2ChainConfig: L2ChainConfig = {
321
+ export const mainnetL2ChainConfig: L2ChainConfig = {
322
+ txPoolDeleteTxsAfterReorg: true,
323
+ disableTransactions: true,
324
+
286
325
  l1ChainId: 1,
287
326
  testAccounts: false,
288
327
  sponsoredFPC: false,
@@ -291,14 +330,13 @@ export const ignitionL2ChainConfig: L2ChainConfig = {
291
330
  seqMinTxsPerBlock: 0,
292
331
  seqMaxTxsPerBlock: 0,
293
332
  realProofs: true,
294
- snapshotsUrls: [`${SNAPSHOTS_URL}/ignition/`],
333
+ snapshotsUrls: [`${SNAPSHOTS_URL}/mainnet/`],
295
334
  autoUpdate: 'notify',
296
- autoUpdateUrl: 'https://storage.googleapis.com/aztec-testnet/auto-update/ignition.json',
335
+ autoUpdateUrl: 'https://storage.googleapis.com/aztec-mainnet/auto-update/mainnet.json',
297
336
  maxTxPoolSize: 100_000_000, // 100MB
298
337
  publicIncludeMetrics,
299
338
  publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
300
339
  publicMetricsCollectFrom: ['sequencer'],
301
- txPoolDeleteTxsAfterReorg: false,
302
340
 
303
341
  /** How many seconds an L1 slot lasts. */
304
342
  ethereumSlotDuration: 12,
@@ -312,73 +350,61 @@ export const ignitionL2ChainConfig: L2ChainConfig = {
312
350
  lagInEpochs: 2,
313
351
  /** The number of epochs after an epoch ends that proofs are still accepted. */
314
352
  aztecProofSubmissionEpochs: 1,
353
+
354
+ localEjectionThreshold: 196_000n * 10n ** 18n,
315
355
  /** How many sequencers must agree with a slash for it to be executed. */
316
356
  slashingQuorum: 65,
317
-
318
357
  slashingRoundSizeInEpochs: 4,
319
- slashingLifetimeInRounds: 40,
320
358
  slashingExecutionDelayInRounds: 28,
321
- slashingDisableDuration: 5 * 24 * 60 * 60, // 5 days in seconds
322
- slashAmountSmall: 2_000n * 10n ** 18n,
323
- slashAmountMedium: 10_000n * 10n ** 18n,
324
- slashAmountLarge: 50_000n * 10n ** 18n,
359
+ slashingLifetimeInRounds: 34,
360
+ slashingVetoer: EthAddress.ZERO, // TODO TMNT-329
325
361
  slashingOffsetInRounds: 2,
362
+
363
+ slashingDisableDuration: 259_200, // 3 days
326
364
  slasherFlavor: 'tally',
327
- slashingVetoer: EthAddress.ZERO, // TODO TMNT-329
365
+
366
+ slashAmountSmall: 2_000n * 10n ** 18n,
367
+ slashAmountMedium: 2_000n * 10n ** 18n,
368
+ slashAmountLarge: 2_000n * 10n ** 18n,
328
369
 
329
370
  /** The mana target for the rollup */
330
371
  manaTarget: 0n,
331
372
 
332
- exitDelaySeconds: 5 * 24 * 60 * 60,
333
-
334
373
  /** The proving cost per mana */
335
374
  provingCostPerMana: 0n,
336
375
 
337
- ejectionThreshold: 100_000n * 10n ** 18n,
376
+ exitDelaySeconds: 4 * 24 * 60 * 60, // 4 days
377
+
338
378
  activationThreshold: 200_000n * 10n ** 18n,
339
- localEjectionThreshold: 196_000n * 10n ** 18n,
379
+ ejectionThreshold: 100_000n * 10n ** 18n,
340
380
 
341
- governanceProposerRoundSize: 300, // TODO TMNT-322
342
- governanceProposerQuorum: 151, // TODO TMNT-322
381
+ governanceProposerRoundSize: 1000,
382
+ governanceProposerQuorum: 600,
343
383
 
344
384
  // Node slashing config
345
- // TODO TMNT-330
346
- slashMinPenaltyPercentage: 0.5,
347
- slashMaxPenaltyPercentage: 2.0,
348
- slashInactivityTargetPercentage: 0.7,
385
+ slashInactivityTargetPercentage: 0.8,
349
386
  slashInactivityConsecutiveEpochThreshold: 2,
350
387
  slashInactivityPenalty: 2_000n * 10n ** 18n,
351
388
  slashPrunePenalty: 0n, // 2_000n * 10n ** 18n, We disable slashing for prune offenses right now
352
389
  slashDataWithholdingPenalty: 0n, // 2_000n * 10n ** 18n, We disable slashing for data withholding offenses right now
353
- slashProposeInvalidAttestationsPenalty: 50_000n * 10n ** 18n,
354
- slashAttestDescendantOfInvalidPenalty: 50_000n * 10n ** 18n,
390
+ slashProposeInvalidAttestationsPenalty: 2_000n * 10n ** 18n,
391
+ slashAttestDescendantOfInvalidPenalty: 2_000n * 10n ** 18n,
355
392
  slashUnknownPenalty: 2_000n * 10n ** 18n,
356
- slashBroadcastedInvalidBlockPenalty: 0n, // 10_000n * 10n ** 18n, Disabled for now until further testing
357
- slashMaxPayloadSize: 50,
358
- slashGracePeriodL2Slots: 32 * 4, // One round from genesis
393
+ slashBroadcastedInvalidBlockPenalty: 2_000n * 10n ** 18n, // 10_000n * 10n ** 18n, Disabled for now until further testing
394
+ slashGracePeriodL2Slots: 1_200, // One day from deployment
359
395
  slashOffenseExpirationRounds: 8,
360
- sentinelEnabled: true,
396
+
397
+ slashMinPenaltyPercentage: 0.5,
398
+ slashMaxPenaltyPercentage: 2.0,
399
+ slashMaxPayloadSize: 50,
361
400
  slashExecuteRoundsLookBack: 4,
362
401
 
402
+ sentinelEnabled: true,
403
+
363
404
  ...DefaultNetworkDBMapSizeConfig,
364
405
  };
365
406
 
366
- const BOOTNODE_CACHE_DURATION_MS = 60 * 60 * 1000; // 1 hour;
367
-
368
- export async function getBootnodes(networkName: NetworkNames, cacheDir?: string) {
369
- const url = `http://static.aztec.network/${networkName}/bootnodes.json`;
370
- const data = await cachedFetch(url, {
371
- cacheDurationMs: BOOTNODE_CACHE_DURATION_MS,
372
- cacheFile: cacheDir ? join(cacheDir, networkName, 'bootnodes.json') : undefined,
373
- });
374
-
375
- return data?.bootnodes;
376
- }
377
-
378
- export async function getL2ChainConfig(
379
- networkName: NetworkNames,
380
- cacheDir?: string,
381
- ): Promise<L2ChainConfig | undefined> {
407
+ export function getL2ChainConfig(networkName: NetworkNames): L2ChainConfig | undefined {
382
408
  let config: L2ChainConfig | undefined;
383
409
  if (networkName === 'staging-public') {
384
410
  config = { ...stagingPublicL2ChainConfig };
@@ -386,16 +412,8 @@ export async function getL2ChainConfig(
386
412
  config = { ...testnetL2ChainConfig };
387
413
  } else if (networkName === 'staging-ignition') {
388
414
  config = { ...stagingIgnitionL2ChainConfig };
389
- } else if (networkName === 'ignition') {
390
- config = { ...ignitionL2ChainConfig };
391
- }
392
- if (!config) {
393
- return undefined;
394
- }
395
- // If the bootnodes are not set, get them from the network
396
- const bootnodeKey: EnvVar = 'BOOTSTRAP_NODES';
397
- if (!process.env[bootnodeKey]) {
398
- config.p2pBootstrapNodes = await getBootnodes(networkName, cacheDir);
415
+ } else if (networkName === 'mainnet') {
416
+ config = { ...mainnetL2ChainConfig };
399
417
  }
400
418
  return config;
401
419
  }
@@ -404,14 +422,13 @@ function getDefaultDataDir(networkName: NetworkNames): string {
404
422
  return path.join(process.env.HOME || '~', '.aztec', networkName, 'data');
405
423
  }
406
424
 
407
- export async function enrichEnvironmentWithChainConfig(networkName: NetworkNames) {
425
+ export function enrichEnvironmentWithChainConfig(networkName: NetworkNames) {
408
426
  if (networkName === 'local') {
409
427
  return;
410
428
  }
411
429
 
412
430
  enrichVar('DATA_DIRECTORY', getDefaultDataDir(networkName));
413
- const cacheDir = process.env.DATA_DIRECTORY ? join(process.env.DATA_DIRECTORY, 'cache') : undefined;
414
- const config = await getL2ChainConfig(networkName, cacheDir);
431
+ const config = getL2ChainConfig(networkName);
415
432
 
416
433
  if (!config) {
417
434
  throw new Error(`Unknown network name: ${networkName}`);
@@ -435,6 +452,14 @@ export async function enrichEnvironmentWithChainConfig(networkName: NetworkNames
435
452
  enrichVar('NULLIFIER_TREE_MAP_SIZE_KB', config.nullifierTreeMapSizeKb.toString());
436
453
  enrichVar('PUBLIC_DATA_TREE_MAP_SIZE_KB', config.publicDataTreeMapSizeKb.toString());
437
454
 
455
+ if (config.skipArchiverInitialSync !== undefined) {
456
+ enrichVar('SKIP_ARCHIVER_INITIAL_SYNC', config.skipArchiverInitialSync.toString());
457
+ }
458
+
459
+ if (config.blobAllowEmptySources !== undefined) {
460
+ enrichVar('BLOB_ALLOW_EMPTY_SOURCES', config.blobAllowEmptySources.toString());
461
+ }
462
+
438
463
  if (config.autoUpdate) {
439
464
  enrichVar('AUTO_UPDATE', config.autoUpdate?.toString());
440
465
  }
@@ -496,4 +521,5 @@ export async function enrichEnvironmentWithChainConfig(networkName: NetworkNames
496
521
  enrichVar('SLASH_MAX_PAYLOAD_SIZE', config.slashMaxPayloadSize.toString());
497
522
 
498
523
  enrichVar('SENTINEL_ENABLED', config.sentinelEnabled.toString());
524
+ enrichVar('TRANSACTIONS_DISABLED', config.disableTransactions.toString());
499
525
  }