@aztec/cli 2.1.2 → 2.1.3-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/cmds/validator_keys/add.d.ts.map +1 -1
- package/dest/cmds/validator_keys/add.js +1 -2
- package/dest/cmds/validator_keys/index.d.ts.map +1 -1
- package/dest/cmds/validator_keys/index.js +10 -3
- package/dest/cmds/validator_keys/new.d.ts +4 -1
- package/dest/cmds/validator_keys/new.d.ts.map +1 -1
- package/dest/cmds/validator_keys/new.js +82 -8
- package/dest/cmds/validator_keys/shared.d.ts +0 -1
- package/dest/cmds/validator_keys/shared.d.ts.map +1 -1
- package/dest/cmds/validator_keys/shared.js +2 -14
- package/dest/cmds/validator_keys/staker.d.ts +38 -0
- package/dest/cmds/validator_keys/staker.d.ts.map +1 -0
- package/dest/cmds/validator_keys/staker.js +206 -0
- package/dest/config/chain_l2_config.d.ts +11 -9
- package/dest/config/chain_l2_config.d.ts.map +1 -1
- package/dest/config/chain_l2_config.js +113 -21
- package/package.json +27 -24
- package/src/cmds/validator_keys/add.ts +0 -2
- package/src/cmds/validator_keys/index.ts +31 -3
- package/src/cmds/validator_keys/new.ts +97 -9
- package/src/cmds/validator_keys/shared.ts +1 -9
- package/src/cmds/validator_keys/staker.ts +298 -0
- package/src/config/chain_l2_config.ts +159 -33
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { prettyPrintJSON } from '@aztec/cli/utils';
|
|
2
|
+
import { GSEContract, createEthereumChain } from '@aztec/ethereum';
|
|
3
|
+
import { computeBn254G1PublicKey, computeBn254G2PublicKey } from '@aztec/foundation/crypto';
|
|
4
|
+
import { decryptBn254Keystore } from '@aztec/foundation/crypto/bls/bn254_keystore';
|
|
5
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
7
|
+
import type { LogFn } from '@aztec/foundation/log';
|
|
8
|
+
import { loadKeystoreFile } from '@aztec/node-keystore/loader';
|
|
9
|
+
import type {
|
|
10
|
+
AttesterAccount,
|
|
11
|
+
AttesterAccounts,
|
|
12
|
+
BLSAccount,
|
|
13
|
+
EncryptedKeyFileConfig,
|
|
14
|
+
EthAccount,
|
|
15
|
+
MnemonicConfig,
|
|
16
|
+
} from '@aztec/node-keystore/types';
|
|
17
|
+
|
|
18
|
+
import { Wallet } from '@ethersproject/wallet';
|
|
19
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
20
|
+
import { createPublicClient, fallback, http } from 'viem';
|
|
21
|
+
import { privateKeyToAddress } from 'viem/accounts';
|
|
22
|
+
|
|
23
|
+
export type StakerOptions = {
|
|
24
|
+
from: string;
|
|
25
|
+
password?: string;
|
|
26
|
+
output?: string;
|
|
27
|
+
gseAddress: EthAddress;
|
|
28
|
+
l1RpcUrls: string[];
|
|
29
|
+
l1ChainId: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type StakerOutput = {
|
|
33
|
+
attester: string;
|
|
34
|
+
publicKeyG1: {
|
|
35
|
+
x: string;
|
|
36
|
+
y: string;
|
|
37
|
+
};
|
|
38
|
+
publicKeyG2: {
|
|
39
|
+
x0: string;
|
|
40
|
+
x1: string;
|
|
41
|
+
y0: string;
|
|
42
|
+
y1: string;
|
|
43
|
+
};
|
|
44
|
+
proofOfPossession: {
|
|
45
|
+
x: string;
|
|
46
|
+
y: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check if an object is a MnemonicConfig
|
|
52
|
+
*/
|
|
53
|
+
function isMnemonicConfig(obj: unknown): obj is MnemonicConfig {
|
|
54
|
+
return typeof obj === 'object' && obj !== null && 'mnemonic' in obj;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Check if a value is an encrypted keystore file config
|
|
59
|
+
*/
|
|
60
|
+
function isEncryptedKeyFileConfig(value: unknown): value is EncryptedKeyFileConfig {
|
|
61
|
+
return typeof value === 'object' && value !== null && 'path' in value;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Check if a BLSAccount is a private key string (not an encrypted keystore file)
|
|
66
|
+
*/
|
|
67
|
+
function isBlsPrivateKey(bls: unknown): bls is string {
|
|
68
|
+
return typeof bls === 'string' && bls.startsWith('0x');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Check if an EthAccount is a private key string (66 chars: 0x + 64 hex)
|
|
73
|
+
*/
|
|
74
|
+
function isEthPrivateKey(eth: unknown): eth is string {
|
|
75
|
+
return typeof eth === 'string' && eth.startsWith('0x') && eth.length === 66;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Check if a string is an Ethereum address (42 chars: 0x + 40 hex)
|
|
80
|
+
*/
|
|
81
|
+
function isEthAddress(value: unknown): value is string {
|
|
82
|
+
return typeof value === 'string' && /^0x[0-9a-fA-F]{40}$/.test(value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Decrypt a BLS private key from an encrypted keystore file
|
|
87
|
+
*/
|
|
88
|
+
function decryptBlsKey(bls: BLSAccount, password?: string): string | undefined {
|
|
89
|
+
if (isBlsPrivateKey(bls)) {
|
|
90
|
+
return bls;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (isEncryptedKeyFileConfig(bls)) {
|
|
94
|
+
if (!password && !bls.password) {
|
|
95
|
+
return undefined; // Can't decrypt without password
|
|
96
|
+
}
|
|
97
|
+
const pwd = password ?? bls.password!;
|
|
98
|
+
return decryptBn254Keystore(bls.path, pwd);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Decrypt an Ethereum private key from an encrypted keystore file
|
|
106
|
+
*/
|
|
107
|
+
async function decryptEthKey(eth: EthAccount, password?: string): Promise<string | undefined> {
|
|
108
|
+
if (isEthPrivateKey(eth)) {
|
|
109
|
+
return eth;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (isEncryptedKeyFileConfig(eth)) {
|
|
113
|
+
if (!password && !eth.password) {
|
|
114
|
+
return undefined; // Can't decrypt without password
|
|
115
|
+
}
|
|
116
|
+
const pwd = password ?? eth.password!;
|
|
117
|
+
const json = readFileSync(eth.path, 'utf-8');
|
|
118
|
+
const wallet = await Wallet.fromEncryptedJson(json, pwd);
|
|
119
|
+
return wallet.privateKey as string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Extract Ethereum address from an EthAccount (or private key)
|
|
127
|
+
*/
|
|
128
|
+
async function getEthAddress(eth: EthAccount | string, password?: string): Promise<EthAddress | undefined> {
|
|
129
|
+
// Case 1: It's a private key string - derive the address
|
|
130
|
+
if (isEthPrivateKey(eth)) {
|
|
131
|
+
return privateKeyToAddress(eth as `0x${string}`) as unknown as EthAddress;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Case 2: It's just an address string directly (EthRemoteSignerAccount can be just EthAddress)
|
|
135
|
+
if (isEthAddress(eth)) {
|
|
136
|
+
return eth as unknown as EthAddress;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Case 3: It's an object with an address property (remote signer config)
|
|
140
|
+
if (typeof eth === 'object' && eth !== null && 'address' in eth) {
|
|
141
|
+
return (eth as any).address as EthAddress;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Case 4: It's an encrypted keystore file - decrypt and derive address
|
|
145
|
+
if (isEncryptedKeyFileConfig(eth)) {
|
|
146
|
+
const privateKey = await decryptEthKey(eth, password);
|
|
147
|
+
if (privateKey) {
|
|
148
|
+
return privateKeyToAddress(privateKey as `0x${string}`) as unknown as EthAddress;
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Extract BLS private key and Ethereum address from an AttesterAccount
|
|
158
|
+
*/
|
|
159
|
+
async function extractAttesterInfo(
|
|
160
|
+
attester: AttesterAccount,
|
|
161
|
+
password?: string,
|
|
162
|
+
): Promise<{ blsPrivateKey?: string; ethAddress?: EthAddress }> {
|
|
163
|
+
// Case 1: attester is { eth: EthAccount, bls?: BLSAccount }
|
|
164
|
+
if (typeof attester === 'object' && attester !== null && 'eth' in attester) {
|
|
165
|
+
const ethAddress = await getEthAddress(attester.eth, password);
|
|
166
|
+
const blsPrivateKey = attester.bls ? decryptBlsKey(attester.bls, password) : undefined;
|
|
167
|
+
return { blsPrivateKey, ethAddress };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Case 2: attester is just an EthAccount directly (no BLS key)
|
|
171
|
+
return {
|
|
172
|
+
blsPrivateKey: undefined,
|
|
173
|
+
ethAddress: await getEthAddress(attester as EthAccount, password),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Process a single attester entry and output staking JSON
|
|
179
|
+
*/
|
|
180
|
+
async function processAttester(
|
|
181
|
+
attester: AttesterAccount,
|
|
182
|
+
gse: GSEContract,
|
|
183
|
+
password?: string,
|
|
184
|
+
): Promise<StakerOutput | undefined> {
|
|
185
|
+
const { blsPrivateKey, ethAddress } = await extractAttesterInfo(attester, password);
|
|
186
|
+
|
|
187
|
+
// Skip if no BLS private key or no Ethereum address
|
|
188
|
+
if (!blsPrivateKey || !ethAddress) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Derive G1 and G2 public keys
|
|
193
|
+
const g1PublicKey = await computeBn254G1PublicKey(blsPrivateKey);
|
|
194
|
+
const g2PublicKey = await computeBn254G2PublicKey(blsPrivateKey);
|
|
195
|
+
|
|
196
|
+
// Generate proof of possession
|
|
197
|
+
const bn254SecretKeyFieldElement = Fr.fromString(blsPrivateKey);
|
|
198
|
+
const registrationTuple = await gse.makeRegistrationTuple(bn254SecretKeyFieldElement.toBigInt());
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
attester: String(ethAddress),
|
|
202
|
+
publicKeyG1: {
|
|
203
|
+
x: '0x' + g1PublicKey.x.toString(16).padStart(64, '0'),
|
|
204
|
+
y: '0x' + g1PublicKey.y.toString(16).padStart(64, '0'),
|
|
205
|
+
},
|
|
206
|
+
publicKeyG2: {
|
|
207
|
+
x0: '0x' + g2PublicKey.x.c0.toString(16).padStart(64, '0'),
|
|
208
|
+
x1: '0x' + g2PublicKey.x.c1.toString(16).padStart(64, '0'),
|
|
209
|
+
y0: '0x' + g2PublicKey.y.c0.toString(16).padStart(64, '0'),
|
|
210
|
+
y1: '0x' + g2PublicKey.y.c1.toString(16).padStart(64, '0'),
|
|
211
|
+
},
|
|
212
|
+
proofOfPossession: {
|
|
213
|
+
x: '0x' + registrationTuple.proofOfPossession.x.toString(16),
|
|
214
|
+
y: '0x' + registrationTuple.proofOfPossession.y.toString(16),
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Process AttesterAccounts (which can be a single attester, array, or mnemonic)
|
|
221
|
+
*/
|
|
222
|
+
export async function processAttesterAccounts(
|
|
223
|
+
attesterAccounts: AttesterAccounts,
|
|
224
|
+
gse: GSEContract,
|
|
225
|
+
password?: string,
|
|
226
|
+
): Promise<StakerOutput[]> {
|
|
227
|
+
// Skip mnemonic configs
|
|
228
|
+
if (isMnemonicConfig(attesterAccounts)) {
|
|
229
|
+
return [];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Handle array of attesters
|
|
233
|
+
if (Array.isArray(attesterAccounts)) {
|
|
234
|
+
const results: StakerOutput[] = [];
|
|
235
|
+
for (const attester of attesterAccounts) {
|
|
236
|
+
const result = await processAttester(attester, gse, password);
|
|
237
|
+
if (result) {
|
|
238
|
+
results.push(result);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return results;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Handle single attester
|
|
245
|
+
const result = await processAttester(attesterAccounts, gse, password);
|
|
246
|
+
return result ? [result] : [];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Main staker command function
|
|
251
|
+
*/
|
|
252
|
+
export async function generateStakerJson(options: StakerOptions, log: LogFn): Promise<void> {
|
|
253
|
+
const { from, password, gseAddress, l1RpcUrls, l1ChainId, output } = options;
|
|
254
|
+
|
|
255
|
+
// Load the keystore file
|
|
256
|
+
const keystore = loadKeystoreFile(from);
|
|
257
|
+
|
|
258
|
+
if (!gseAddress) {
|
|
259
|
+
throw new Error('GSE contract address is required');
|
|
260
|
+
}
|
|
261
|
+
log(`Calling GSE contract ${gseAddress} on chain ${l1ChainId}, using ${l1RpcUrls.join(', ')} to get staker outputs`);
|
|
262
|
+
|
|
263
|
+
if (!keystore.validators || keystore.validators.length === 0) {
|
|
264
|
+
log('No validators found in keystore');
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const allOutputs: StakerOutput[] = [];
|
|
269
|
+
|
|
270
|
+
// L1 client for proof of possession
|
|
271
|
+
const chain = createEthereumChain(l1RpcUrls, l1ChainId);
|
|
272
|
+
const publicClient = createPublicClient({
|
|
273
|
+
chain: chain.chainInfo,
|
|
274
|
+
transport: fallback(l1RpcUrls.map(url => http(url))),
|
|
275
|
+
});
|
|
276
|
+
const gse = new GSEContract(publicClient, gseAddress);
|
|
277
|
+
|
|
278
|
+
// Process each validator
|
|
279
|
+
for (const validator of keystore.validators) {
|
|
280
|
+
const outputs = await processAttesterAccounts(validator.attester, gse, password);
|
|
281
|
+
allOutputs.push(...outputs);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (allOutputs.length === 0) {
|
|
285
|
+
log('No attesters with BLS keys found (skipping mnemonics and encrypted keystores without password)');
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const jsonOutput = prettyPrintJSON(allOutputs);
|
|
290
|
+
|
|
291
|
+
// Write to file if output is specified, otherwise log to stdout
|
|
292
|
+
if (output) {
|
|
293
|
+
writeFileSync(output, jsonOutput, 'utf-8');
|
|
294
|
+
log(`Wrote staking data to ${output}`);
|
|
295
|
+
} else {
|
|
296
|
+
log(jsonOutput);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DefaultL1ContractsConfig, type L1ContractsConfig } from '@aztec/ethereum';
|
|
1
|
+
import { DefaultL1ContractsConfig, type L1ContractsConfig, type L1TxUtilsConfig } from '@aztec/ethereum';
|
|
2
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
|
-
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
6
|
+
import type { SequencerConfig, SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
7
|
|
|
8
8
|
import path from 'path';
|
|
9
9
|
|
|
@@ -15,30 +15,30 @@ const SNAPSHOTS_URL = 'https://aztec-labs-snapshots.com';
|
|
|
15
15
|
const defaultDBMapSizeKb = 128 * 1_024 * 1_024; // 128 GB
|
|
16
16
|
const tbMapSizeKb = 1_024 * 1_024 * 1_024; // 1 TB
|
|
17
17
|
|
|
18
|
-
export type L2ChainConfig = L1ContractsConfig &
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
export type L2ChainConfig = Omit<L1ContractsConfig, keyof L1TxUtilsConfig> &
|
|
19
|
+
Omit<SlasherConfig, 'slashValidatorsNever' | 'slashValidatorsAlways' | 'slashOverridePayload' | 'slashSelfAllowed'> &
|
|
20
|
+
Pick<P2PConfig, 'bootstrapNodes' | 'p2pEnabled' | 'txPoolDeleteTxsAfterReorg'> &
|
|
21
|
+
Pick<SequencerConfig, 'minTxsPerBlock' | 'maxTxsPerBlock'> & {
|
|
21
22
|
l1ChainId: number;
|
|
22
23
|
testAccounts: boolean;
|
|
23
24
|
sponsoredFPC: boolean;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
seqMinTxsPerBlock: number;
|
|
27
|
-
seqMaxTxsPerBlock: number;
|
|
25
|
+
minTxsPerBlock: number;
|
|
26
|
+
maxTxsPerBlock: number;
|
|
28
27
|
realProofs: boolean;
|
|
29
28
|
snapshotsUrls: string[];
|
|
30
29
|
autoUpdate: SharedNodeConfig['autoUpdate'];
|
|
31
30
|
autoUpdateUrl?: string;
|
|
32
31
|
maxTxPoolSize: number;
|
|
32
|
+
publicMetricsOptOut: boolean;
|
|
33
33
|
publicIncludeMetrics?: string[];
|
|
34
34
|
publicMetricsCollectorUrl?: string;
|
|
35
35
|
publicMetricsCollectFrom?: string[];
|
|
36
36
|
skipArchiverInitialSync?: boolean;
|
|
37
37
|
blobAllowEmptySources?: boolean;
|
|
38
38
|
|
|
39
|
-
// Setting the
|
|
39
|
+
// Setting the dataStoreMapSize provides the default for every DB in the node.
|
|
40
40
|
// Then we explicitly override the sizes for the archiver and the larger trees.
|
|
41
|
-
|
|
41
|
+
dataStoreMapSizeKb: number;
|
|
42
42
|
archiverStoreMapSizeKb: number;
|
|
43
43
|
noteHashTreeMapSizeKb: number;
|
|
44
44
|
nullifierTreeMapSizeKb: number;
|
|
@@ -87,7 +87,7 @@ const DefaultSlashConfig = {
|
|
|
87
87
|
} satisfies Partial<L2ChainConfig>;
|
|
88
88
|
|
|
89
89
|
const DefaultNetworkDBMapSizeConfig = {
|
|
90
|
-
|
|
90
|
+
dataStoreMapSizeKb: defaultDBMapSizeKb,
|
|
91
91
|
archiverStoreMapSizeKb: tbMapSizeKb,
|
|
92
92
|
noteHashTreeMapSizeKb: tbMapSizeKb,
|
|
93
93
|
nullifierTreeMapSizeKb: tbMapSizeKb,
|
|
@@ -100,14 +100,15 @@ export const stagingIgnitionL2ChainConfig: L2ChainConfig = {
|
|
|
100
100
|
sponsoredFPC: false,
|
|
101
101
|
disableTransactions: true,
|
|
102
102
|
p2pEnabled: true,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
bootstrapNodes: [],
|
|
104
|
+
minTxsPerBlock: 0,
|
|
105
|
+
maxTxsPerBlock: 0,
|
|
106
106
|
realProofs: true,
|
|
107
107
|
snapshotsUrls: [`${SNAPSHOTS_URL}/staging-ignition/`],
|
|
108
108
|
autoUpdate: 'config-and-version',
|
|
109
109
|
autoUpdateUrl: 'https://storage.googleapis.com/aztec-testnet/auto-update/staging-ignition.json',
|
|
110
|
-
maxTxPoolSize:
|
|
110
|
+
maxTxPoolSize: 0,
|
|
111
|
+
publicMetricsOptOut: false,
|
|
111
112
|
publicIncludeMetrics,
|
|
112
113
|
publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
|
|
113
114
|
publicMetricsCollectFrom: ['sequencer'],
|
|
@@ -138,7 +139,7 @@ export const stagingIgnitionL2ChainConfig: L2ChainConfig = {
|
|
|
138
139
|
slashAmountLarge: 50_000n * 10n ** 18n,
|
|
139
140
|
slashingOffsetInRounds: 2,
|
|
140
141
|
slasherFlavor: 'tally',
|
|
141
|
-
slashingVetoer: EthAddress.ZERO,
|
|
142
|
+
slashingVetoer: EthAddress.ZERO,
|
|
142
143
|
|
|
143
144
|
/** The mana target for the rollup */
|
|
144
145
|
manaTarget: 0n,
|
|
@@ -182,13 +183,14 @@ export const stagingPublicL2ChainConfig: L2ChainConfig = {
|
|
|
182
183
|
sponsoredFPC: true,
|
|
183
184
|
disableTransactions: false,
|
|
184
185
|
p2pEnabled: true,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
bootstrapNodes: [],
|
|
187
|
+
minTxsPerBlock: 0,
|
|
188
|
+
maxTxsPerBlock: 20,
|
|
188
189
|
realProofs: true,
|
|
189
190
|
snapshotsUrls: [`${SNAPSHOTS_URL}/staging-public/`],
|
|
190
191
|
autoUpdate: 'config-and-version',
|
|
191
192
|
autoUpdateUrl: 'https://storage.googleapis.com/aztec-testnet/auto-update/staging-public.json',
|
|
193
|
+
publicMetricsOptOut: false,
|
|
192
194
|
publicIncludeMetrics,
|
|
193
195
|
publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
|
|
194
196
|
publicMetricsCollectFrom: ['sequencer'],
|
|
@@ -230,20 +232,76 @@ export const stagingPublicL2ChainConfig: L2ChainConfig = {
|
|
|
230
232
|
...DefaultNetworkDBMapSizeConfig,
|
|
231
233
|
};
|
|
232
234
|
|
|
235
|
+
export const nextNetL2ChainConfig: L2ChainConfig = {
|
|
236
|
+
l1ChainId: 11155111,
|
|
237
|
+
testAccounts: true,
|
|
238
|
+
sponsoredFPC: true,
|
|
239
|
+
p2pEnabled: true,
|
|
240
|
+
disableTransactions: false,
|
|
241
|
+
bootstrapNodes: [],
|
|
242
|
+
minTxsPerBlock: 0,
|
|
243
|
+
maxTxsPerBlock: 8,
|
|
244
|
+
realProofs: true,
|
|
245
|
+
snapshotsUrls: [],
|
|
246
|
+
autoUpdate: 'config-and-version',
|
|
247
|
+
autoUpdateUrl: '',
|
|
248
|
+
publicMetricsOptOut: true,
|
|
249
|
+
publicIncludeMetrics,
|
|
250
|
+
publicMetricsCollectorUrl: '',
|
|
251
|
+
publicMetricsCollectFrom: [''],
|
|
252
|
+
maxTxPoolSize: 100_000_000, // 100MB
|
|
253
|
+
txPoolDeleteTxsAfterReorg: false,
|
|
254
|
+
|
|
255
|
+
// Deployment stuff
|
|
256
|
+
/** How many seconds an L1 slot lasts. */
|
|
257
|
+
ethereumSlotDuration: 12,
|
|
258
|
+
/** How many seconds an L2 slots lasts (must be multiple of ethereum slot duration). */
|
|
259
|
+
aztecSlotDuration: 36,
|
|
260
|
+
/** How many L2 slots an epoch lasts. */
|
|
261
|
+
aztecEpochDuration: 32,
|
|
262
|
+
/** The target validator committee size. */
|
|
263
|
+
aztecTargetCommitteeSize: 48,
|
|
264
|
+
/** The number of epochs to lag behind the current epoch for validator selection. */
|
|
265
|
+
lagInEpochs: DefaultL1ContractsConfig.lagInEpochs,
|
|
266
|
+
/** The local ejection threshold for a validator. Stricter than ejectionThreshold but local to a specific rollup */
|
|
267
|
+
localEjectionThreshold: DefaultL1ContractsConfig.localEjectionThreshold,
|
|
268
|
+
/** The number of epochs after an epoch ends that proofs are still accepted. */
|
|
269
|
+
aztecProofSubmissionEpochs: 1,
|
|
270
|
+
/** The deposit amount for a validator */
|
|
271
|
+
activationThreshold: DefaultL1ContractsConfig.activationThreshold,
|
|
272
|
+
/** The minimum stake for a validator. */
|
|
273
|
+
ejectionThreshold: DefaultL1ContractsConfig.ejectionThreshold,
|
|
274
|
+
/** The slashing round size */
|
|
275
|
+
slashingRoundSizeInEpochs: DefaultL1ContractsConfig.slashingRoundSizeInEpochs,
|
|
276
|
+
/** Governance proposing round size */
|
|
277
|
+
governanceProposerRoundSize: DefaultL1ContractsConfig.governanceProposerRoundSize,
|
|
278
|
+
/** The mana target for the rollup */
|
|
279
|
+
manaTarget: DefaultL1ContractsConfig.manaTarget,
|
|
280
|
+
/** The proving cost per mana */
|
|
281
|
+
provingCostPerMana: DefaultL1ContractsConfig.provingCostPerMana,
|
|
282
|
+
/** Exit delay for stakers */
|
|
283
|
+
exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
|
|
284
|
+
|
|
285
|
+
...DefaultSlashConfig,
|
|
286
|
+
|
|
287
|
+
...DefaultNetworkDBMapSizeConfig,
|
|
288
|
+
};
|
|
289
|
+
|
|
233
290
|
export const testnetL2ChainConfig: L2ChainConfig = {
|
|
234
291
|
l1ChainId: 11155111,
|
|
235
292
|
testAccounts: false,
|
|
236
293
|
sponsoredFPC: true,
|
|
237
294
|
p2pEnabled: true,
|
|
238
295
|
disableTransactions: true,
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
296
|
+
bootstrapNodes: [],
|
|
297
|
+
minTxsPerBlock: 0,
|
|
298
|
+
maxTxsPerBlock: 0,
|
|
242
299
|
realProofs: true,
|
|
243
300
|
snapshotsUrls: [`${SNAPSHOTS_URL}/testnet/`],
|
|
244
301
|
autoUpdate: 'config-and-version',
|
|
245
302
|
autoUpdateUrl: 'https://storage.googleapis.com/aztec-testnet/auto-update/testnet.json',
|
|
246
303
|
maxTxPoolSize: 100_000_000, // 100MB
|
|
304
|
+
publicMetricsOptOut: false,
|
|
247
305
|
publicIncludeMetrics,
|
|
248
306
|
publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
|
|
249
307
|
publicMetricsCollectFrom: ['sequencer'],
|
|
@@ -326,17 +384,19 @@ export const mainnetL2ChainConfig: L2ChainConfig = {
|
|
|
326
384
|
testAccounts: false,
|
|
327
385
|
sponsoredFPC: false,
|
|
328
386
|
p2pEnabled: true,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
387
|
+
bootstrapNodes: [],
|
|
388
|
+
minTxsPerBlock: 0,
|
|
389
|
+
maxTxsPerBlock: 0,
|
|
332
390
|
realProofs: true,
|
|
333
391
|
snapshotsUrls: [`${SNAPSHOTS_URL}/mainnet/`],
|
|
334
392
|
autoUpdate: 'notify',
|
|
335
393
|
autoUpdateUrl: 'https://storage.googleapis.com/aztec-mainnet/auto-update/mainnet.json',
|
|
336
|
-
maxTxPoolSize:
|
|
394
|
+
maxTxPoolSize: 0,
|
|
395
|
+
publicMetricsOptOut: true,
|
|
337
396
|
publicIncludeMetrics,
|
|
338
397
|
publicMetricsCollectorUrl: 'https://telemetry.alpha-testnet.aztec-labs.com/v1/metrics',
|
|
339
398
|
publicMetricsCollectFrom: ['sequencer'],
|
|
399
|
+
blobAllowEmptySources: true,
|
|
340
400
|
|
|
341
401
|
/** How many seconds an L1 slot lasts. */
|
|
342
402
|
ethereumSlotDuration: 12,
|
|
@@ -357,7 +417,7 @@ export const mainnetL2ChainConfig: L2ChainConfig = {
|
|
|
357
417
|
slashingRoundSizeInEpochs: 4,
|
|
358
418
|
slashingExecutionDelayInRounds: 28,
|
|
359
419
|
slashingLifetimeInRounds: 34,
|
|
360
|
-
slashingVetoer: EthAddress.
|
|
420
|
+
slashingVetoer: EthAddress.fromString('0xBbB4aF368d02827945748b28CD4b2D42e4A37480'),
|
|
361
421
|
slashingOffsetInRounds: 2,
|
|
362
422
|
|
|
363
423
|
slashingDisableDuration: 259_200, // 3 days
|
|
@@ -404,6 +464,61 @@ export const mainnetL2ChainConfig: L2ChainConfig = {
|
|
|
404
464
|
...DefaultNetworkDBMapSizeConfig,
|
|
405
465
|
};
|
|
406
466
|
|
|
467
|
+
export const devnetL2ChainConfig: L2ChainConfig = {
|
|
468
|
+
l1ChainId: 11155111,
|
|
469
|
+
testAccounts: true,
|
|
470
|
+
sponsoredFPC: true,
|
|
471
|
+
p2pEnabled: true,
|
|
472
|
+
disableTransactions: false,
|
|
473
|
+
bootstrapNodes: [],
|
|
474
|
+
minTxsPerBlock: 0,
|
|
475
|
+
maxTxsPerBlock: 8,
|
|
476
|
+
realProofs: false,
|
|
477
|
+
snapshotsUrls: [],
|
|
478
|
+
autoUpdate: 'config-and-version',
|
|
479
|
+
autoUpdateUrl: '',
|
|
480
|
+
publicMetricsOptOut: true,
|
|
481
|
+
publicIncludeMetrics,
|
|
482
|
+
publicMetricsCollectorUrl: '',
|
|
483
|
+
publicMetricsCollectFrom: [''],
|
|
484
|
+
maxTxPoolSize: 100_000_000, // 100MB
|
|
485
|
+
txPoolDeleteTxsAfterReorg: true,
|
|
486
|
+
|
|
487
|
+
// Deployment stuff
|
|
488
|
+
/** How many seconds an L1 slot lasts. */
|
|
489
|
+
ethereumSlotDuration: 12,
|
|
490
|
+
/** How many seconds an L2 slots lasts (must be multiple of ethereum slot duration). */
|
|
491
|
+
aztecSlotDuration: 36,
|
|
492
|
+
/** How many L2 slots an epoch lasts. */
|
|
493
|
+
aztecEpochDuration: 8,
|
|
494
|
+
/** The target validator committee size. */
|
|
495
|
+
aztecTargetCommitteeSize: 1,
|
|
496
|
+
/** The number of epochs to lag behind the current epoch for validator selection. */
|
|
497
|
+
lagInEpochs: 1,
|
|
498
|
+
/** The local ejection threshold for a validator. Stricter than ejectionThreshold but local to a specific rollup */
|
|
499
|
+
localEjectionThreshold: DefaultL1ContractsConfig.localEjectionThreshold,
|
|
500
|
+
/** The number of epochs after an epoch ends that proofs are still accepted. */
|
|
501
|
+
aztecProofSubmissionEpochs: 1,
|
|
502
|
+
/** The deposit amount for a validator */
|
|
503
|
+
activationThreshold: DefaultL1ContractsConfig.activationThreshold,
|
|
504
|
+
/** The minimum stake for a validator. */
|
|
505
|
+
ejectionThreshold: DefaultL1ContractsConfig.ejectionThreshold,
|
|
506
|
+
/** The slashing round size */
|
|
507
|
+
slashingRoundSizeInEpochs: DefaultL1ContractsConfig.slashingRoundSizeInEpochs,
|
|
508
|
+
/** Governance proposing round size */
|
|
509
|
+
governanceProposerRoundSize: DefaultL1ContractsConfig.governanceProposerRoundSize,
|
|
510
|
+
/** The mana target for the rollup */
|
|
511
|
+
manaTarget: DefaultL1ContractsConfig.manaTarget,
|
|
512
|
+
/** The proving cost per mana */
|
|
513
|
+
provingCostPerMana: DefaultL1ContractsConfig.provingCostPerMana,
|
|
514
|
+
/** Exit delay for stakers */
|
|
515
|
+
exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
|
|
516
|
+
|
|
517
|
+
...DefaultSlashConfig,
|
|
518
|
+
|
|
519
|
+
...DefaultNetworkDBMapSizeConfig,
|
|
520
|
+
};
|
|
521
|
+
|
|
407
522
|
export function getL2ChainConfig(networkName: NetworkNames): L2ChainConfig | undefined {
|
|
408
523
|
let config: L2ChainConfig | undefined;
|
|
409
524
|
if (networkName === 'staging-public') {
|
|
@@ -422,7 +537,7 @@ function getDefaultDataDir(networkName: NetworkNames): string {
|
|
|
422
537
|
return path.join(process.env.HOME || '~', '.aztec', networkName, 'data');
|
|
423
538
|
}
|
|
424
539
|
|
|
425
|
-
export function
|
|
540
|
+
export function enrichEnvironmentWithChainName(networkName: NetworkNames) {
|
|
426
541
|
if (networkName === 'local') {
|
|
427
542
|
return;
|
|
428
543
|
}
|
|
@@ -434,19 +549,24 @@ export function enrichEnvironmentWithChainConfig(networkName: NetworkNames) {
|
|
|
434
549
|
throw new Error(`Unknown network name: ${networkName}`);
|
|
435
550
|
}
|
|
436
551
|
|
|
437
|
-
|
|
552
|
+
enrichEnvironmentWithChainConfig(config);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export function enrichEnvironmentWithChainConfig(config: L2ChainConfig) {
|
|
556
|
+
enrichVar('BOOTSTRAP_NODES', config.bootstrapNodes.join(','));
|
|
438
557
|
enrichVar('TEST_ACCOUNTS', config.testAccounts.toString());
|
|
439
558
|
enrichVar('SPONSORED_FPC', config.sponsoredFPC.toString());
|
|
440
559
|
enrichVar('P2P_ENABLED', config.p2pEnabled.toString());
|
|
441
560
|
enrichVar('L1_CHAIN_ID', config.l1ChainId.toString());
|
|
442
|
-
enrichVar('SEQ_MIN_TX_PER_BLOCK', config.
|
|
443
|
-
enrichVar('SEQ_MAX_TX_PER_BLOCK', config.
|
|
561
|
+
enrichVar('SEQ_MIN_TX_PER_BLOCK', config.minTxsPerBlock.toString());
|
|
562
|
+
enrichVar('SEQ_MAX_TX_PER_BLOCK', config.maxTxsPerBlock.toString());
|
|
444
563
|
enrichVar('PROVER_REAL_PROOFS', config.realProofs.toString());
|
|
445
564
|
enrichVar('PXE_PROVER_ENABLED', config.realProofs.toString());
|
|
446
565
|
enrichVar('SYNC_SNAPSHOTS_URLS', config.snapshotsUrls.join(','));
|
|
447
566
|
enrichVar('P2P_MAX_TX_POOL_SIZE', config.maxTxPoolSize.toString());
|
|
567
|
+
enrichVar('P2P_TX_POOL_DELETE_TXS_AFTER_REORG', config.txPoolDeleteTxsAfterReorg.toString());
|
|
448
568
|
|
|
449
|
-
enrichVar('DATA_STORE_MAP_SIZE_KB', config.
|
|
569
|
+
enrichVar('DATA_STORE_MAP_SIZE_KB', config.dataStoreMapSizeKb.toString());
|
|
450
570
|
enrichVar('ARCHIVER_STORE_MAP_SIZE_KB', config.archiverStoreMapSizeKb.toString());
|
|
451
571
|
enrichVar('NOTE_HASH_TREE_MAP_SIZE_KB', config.noteHashTreeMapSizeKb.toString());
|
|
452
572
|
enrichVar('NULLIFIER_TREE_MAP_SIZE_KB', config.nullifierTreeMapSizeKb.toString());
|
|
@@ -480,11 +600,14 @@ export function enrichEnvironmentWithChainConfig(networkName: NetworkNames) {
|
|
|
480
600
|
enrichVar('PUBLIC_OTEL_COLLECT_FROM', config.publicMetricsCollectFrom.join(','));
|
|
481
601
|
}
|
|
482
602
|
|
|
603
|
+
enrichVar('PUBLIC_OTEL_OPT_OUT', config.publicMetricsOptOut.toString());
|
|
604
|
+
|
|
483
605
|
// Deployment stuff
|
|
484
606
|
enrichVar('ETHEREUM_SLOT_DURATION', config.ethereumSlotDuration.toString());
|
|
485
607
|
enrichVar('AZTEC_SLOT_DURATION', config.aztecSlotDuration.toString());
|
|
486
608
|
enrichVar('AZTEC_EPOCH_DURATION', config.aztecEpochDuration.toString());
|
|
487
609
|
enrichVar('AZTEC_TARGET_COMMITTEE_SIZE', config.aztecTargetCommitteeSize.toString());
|
|
610
|
+
enrichVar('AZTEC_LAG_IN_EPOCHS', config.lagInEpochs.toString());
|
|
488
611
|
enrichVar('AZTEC_PROOF_SUBMISSION_EPOCHS', config.aztecProofSubmissionEpochs.toString());
|
|
489
612
|
enrichVar('AZTEC_ACTIVATION_THRESHOLD', config.activationThreshold.toString());
|
|
490
613
|
enrichVar('AZTEC_EJECTION_THRESHOLD', config.ejectionThreshold.toString());
|
|
@@ -502,6 +625,7 @@ export function enrichEnvironmentWithChainConfig(networkName: NetworkNames) {
|
|
|
502
625
|
enrichVar('AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS', config.slashingExecutionDelayInRounds.toString());
|
|
503
626
|
enrichVar('AZTEC_SLASHING_OFFSET_IN_ROUNDS', config.slashingOffsetInRounds.toString());
|
|
504
627
|
enrichVar('AZTEC_SLASHER_FLAVOR', config.slasherFlavor);
|
|
628
|
+
enrichVar('AZTEC_SLASHING_DISABLE_DURATION', config.slashingDisableDuration.toString());
|
|
505
629
|
enrichVar('AZTEC_EXIT_DELAY_SECONDS', config.exitDelaySeconds.toString());
|
|
506
630
|
enrichEthAddressVar('AZTEC_SLASHING_VETOER', config.slashingVetoer.toString());
|
|
507
631
|
|
|
@@ -519,6 +643,8 @@ export function enrichEnvironmentWithChainConfig(networkName: NetworkNames) {
|
|
|
519
643
|
enrichVar('SLASH_INVALID_BLOCK_PENALTY', config.slashBroadcastedInvalidBlockPenalty.toString());
|
|
520
644
|
enrichVar('SLASH_OFFENSE_EXPIRATION_ROUNDS', config.slashOffenseExpirationRounds.toString());
|
|
521
645
|
enrichVar('SLASH_MAX_PAYLOAD_SIZE', config.slashMaxPayloadSize.toString());
|
|
646
|
+
enrichVar('SLASH_GRACE_PERIOD_L2_SLOTS', config.slashGracePeriodL2Slots.toString());
|
|
647
|
+
enrichVar('SLASH_EXECUTE_ROUNDS_LOOK_BACK', config.slashExecuteRoundsLookBack.toString());
|
|
522
648
|
|
|
523
649
|
enrichVar('SENTINEL_ENABLED', config.sentinelEnabled.toString());
|
|
524
650
|
enrichVar('TRANSACTIONS_DISABLED', config.disableTransactions.toString());
|