@aztec/ethereum 0.0.1-commit.03f7ef2 → 0.0.1-commit.08c5969dc
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.d.ts +17 -27
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +51 -54
- package/dest/contracts/empire_slashing_proposer.d.ts +1 -1
- package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.js +13 -15
- package/dest/contracts/fee_asset_handler.d.ts +6 -5
- package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
- package/dest/contracts/fee_asset_handler.js +11 -9
- package/dest/contracts/governance.d.ts +3 -1
- package/dest/contracts/governance.d.ts.map +1 -1
- package/dest/contracts/governance.js +11 -1
- package/dest/contracts/governance_proposer.d.ts +1 -1
- package/dest/contracts/governance_proposer.d.ts.map +1 -1
- package/dest/contracts/governance_proposer.js +386 -9
- package/dest/contracts/inbox.d.ts +22 -1
- package/dest/contracts/inbox.d.ts.map +1 -1
- package/dest/contracts/inbox.js +36 -1
- package/dest/contracts/index.d.ts +3 -1
- package/dest/contracts/index.d.ts.map +1 -1
- package/dest/contracts/index.js +2 -0
- package/dest/contracts/log.d.ts +13 -0
- package/dest/contracts/log.d.ts.map +1 -0
- package/dest/contracts/log.js +1 -0
- package/dest/contracts/multicall.d.ts +1 -1
- package/dest/contracts/multicall.d.ts.map +1 -1
- package/dest/contracts/multicall.js +2 -1
- package/dest/contracts/outbox.d.ts +41 -0
- package/dest/contracts/outbox.d.ts.map +1 -0
- package/dest/contracts/outbox.js +86 -0
- package/dest/contracts/rollup.d.ts +161 -96
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +677 -132
- package/dest/contracts/tally_slashing_proposer.d.ts +1 -1
- package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/tally_slashing_proposer.js +8 -1
- package/dest/deploy_aztec_l1_contracts.d.ts +17 -2
- package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_aztec_l1_contracts.js +111 -33
- package/dest/generated/l1-contracts-defaults.d.ts +30 -0
- package/dest/generated/l1-contracts-defaults.d.ts.map +1 -0
- package/dest/generated/l1-contracts-defaults.js +30 -0
- package/dest/l1_artifacts.d.ts +4904 -1533
- package/dest/l1_artifacts.d.ts.map +1 -1
- package/dest/l1_tx_utils/constants.d.ts +1 -1
- package/dest/l1_tx_utils/constants.js +2 -2
- package/dest/l1_tx_utils/fee-strategies/index.d.ts +3 -2
- package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -1
- package/dest/l1_tx_utils/fee-strategies/index.js +2 -1
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +2 -12
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -1
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +36 -18
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +2 -11
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -1
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +37 -19
- package/dest/l1_tx_utils/fee-strategies/types.d.ts +14 -27
- package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -1
- package/dest/l1_tx_utils/fee-strategies/types.js +0 -21
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +2 -2
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -1
- package/dest/l1_tx_utils/l1_fee_analyzer.js +3 -3
- package/dest/l1_tx_utils/l1_tx_utils.js +6 -6
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +1 -5
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils/readonly_l1_tx_utils.js +17 -54
- package/dest/publisher_manager.d.ts +3 -2
- package/dest/publisher_manager.d.ts.map +1 -1
- package/dest/publisher_manager.js +2 -2
- package/dest/queries.d.ts +2 -2
- package/dest/queries.d.ts.map +1 -1
- package/dest/queries.js +12 -4
- package/dest/test/chain_monitor.js +1 -2
- package/dest/test/eth_cheat_codes.d.ts +13 -1
- package/dest/test/eth_cheat_codes.d.ts.map +1 -1
- package/dest/test/rollup_cheat_codes.d.ts +5 -2
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
- package/dest/test/rollup_cheat_codes.js +19 -2
- package/dest/test/start_anvil.js +1 -1
- package/dest/utils.d.ts +2 -1
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +46 -0
- package/package.json +8 -7
- package/src/config.ts +62 -53
- package/src/contracts/README.md +157 -0
- package/src/contracts/empire_slashing_proposer.ts +16 -27
- package/src/contracts/fee_asset_handler.ts +10 -7
- package/src/contracts/governance.ts +10 -1
- package/src/contracts/governance_proposer.ts +4 -1
- package/src/contracts/inbox.ts +53 -1
- package/src/contracts/index.ts +2 -0
- package/src/contracts/log.ts +13 -0
- package/src/contracts/multicall.ts +5 -2
- package/src/contracts/outbox.ts +98 -0
- package/src/contracts/rollup.ts +348 -100
- package/src/contracts/tally_slashing_proposer.ts +5 -1
- package/src/deploy_aztec_l1_contracts.ts +117 -40
- package/src/generated/l1-contracts-defaults.ts +32 -0
- package/src/l1_tx_utils/constants.ts +2 -2
- package/src/l1_tx_utils/fee-strategies/index.ts +1 -1
- package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +46 -42
- package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +49 -45
- package/src/l1_tx_utils/fee-strategies/types.ts +14 -46
- package/src/l1_tx_utils/l1_fee_analyzer.ts +2 -3
- package/src/l1_tx_utils/l1_tx_utils.ts +6 -6
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +23 -62
- package/src/publisher_manager.ts +4 -2
- package/src/queries.ts +11 -3
- package/src/test/chain_monitor.ts +1 -1
- package/src/test/rollup_cheat_codes.ts +21 -3
- package/src/test/start_anvil.ts +1 -1
- package/src/utils.ts +53 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { L1TxRequest } from '@aztec/ethereum/l1-tx-utils';
|
|
2
2
|
import type { ViemClient } from '@aztec/ethereum/types';
|
|
3
|
-
import { tryExtractEvent } from '@aztec/ethereum/utils';
|
|
3
|
+
import { mergeAbis, tryExtractEvent } from '@aztec/ethereum/utils';
|
|
4
4
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
5
5
|
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
6
6
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
7
7
|
import { Signature } from '@aztec/foundation/eth-signature';
|
|
8
8
|
import { hexToBuffer } from '@aztec/foundation/string';
|
|
9
|
+
import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
|
|
9
10
|
import { TallySlashingProposerAbi } from '@aztec/l1-artifacts/TallySlashingProposerAbi';
|
|
10
11
|
|
|
11
12
|
import {
|
|
@@ -160,6 +161,7 @@ export class TallySlashingProposerContract {
|
|
|
160
161
|
|
|
161
162
|
return {
|
|
162
163
|
to: this.contract.address,
|
|
164
|
+
abi: TallySlashingProposerAbi,
|
|
163
165
|
data: encodeFunctionData({
|
|
164
166
|
abi: TallySlashingProposerAbi,
|
|
165
167
|
functionName: 'vote',
|
|
@@ -207,6 +209,7 @@ export class TallySlashingProposerContract {
|
|
|
207
209
|
public buildVoteRequestWithSignature(votes: Hex, signature: { v: number; r: Hex; s: Hex }): L1TxRequest {
|
|
208
210
|
return {
|
|
209
211
|
to: this.contract.address,
|
|
212
|
+
abi: TallySlashingProposerAbi,
|
|
210
213
|
data: encodeFunctionData({
|
|
211
214
|
abi: TallySlashingProposerAbi,
|
|
212
215
|
functionName: 'vote',
|
|
@@ -224,6 +227,7 @@ export class TallySlashingProposerContract {
|
|
|
224
227
|
public buildExecuteRoundRequest(round: bigint, committees: EthAddress[][]): L1TxRequest {
|
|
225
228
|
return {
|
|
226
229
|
to: this.contract.address,
|
|
230
|
+
abi: mergeAbis([TallySlashingProposerAbi, SlasherAbi]),
|
|
227
231
|
data: encodeFunctionData({
|
|
228
232
|
abi: TallySlashingProposerAbi,
|
|
229
233
|
functionName: 'executeRound',
|
|
@@ -10,10 +10,12 @@ import { fileURLToPath } from '@aztec/foundation/url';
|
|
|
10
10
|
import { bn254 } from '@noble/curves/bn254';
|
|
11
11
|
import type { Abi, Narrow } from 'abitype';
|
|
12
12
|
import { spawn } from 'child_process';
|
|
13
|
-
import {
|
|
13
|
+
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs';
|
|
14
|
+
import { tmpdir } from 'os';
|
|
15
|
+
import { dirname, join, resolve } from 'path';
|
|
14
16
|
import readline from 'readline';
|
|
15
17
|
import type { Hex } from 'viem';
|
|
16
|
-
import {
|
|
18
|
+
import { mainnet, sepolia } from 'viem/chains';
|
|
17
19
|
|
|
18
20
|
import { createEthereumChain, isAnvilTestChain } from './chain.js';
|
|
19
21
|
import { createExtendedL1Client } from './client.js';
|
|
@@ -29,9 +31,9 @@ const logger = createLogger('ethereum:deploy_aztec_l1_contracts');
|
|
|
29
31
|
const JSON_DEPLOY_RESULT_PREFIX = 'JSON DEPLOY RESULT:';
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
|
-
* Runs a process
|
|
33
|
-
*
|
|
34
|
-
*
|
|
34
|
+
* Runs a process and parses JSON deploy results from stdout.
|
|
35
|
+
* Lines starting with JSON_DEPLOY_RESULT_PREFIX are parsed and returned.
|
|
36
|
+
* All other stdout goes to logger.info, stderr goes to logger.warn.
|
|
35
37
|
*/
|
|
36
38
|
function runProcess<T>(
|
|
37
39
|
command: string,
|
|
@@ -47,26 +49,41 @@ function runProcess<T>(
|
|
|
47
49
|
});
|
|
48
50
|
|
|
49
51
|
let result: T | undefined;
|
|
52
|
+
let parseError: Error | undefined;
|
|
53
|
+
let settled = false;
|
|
50
54
|
|
|
51
55
|
readline.createInterface({ input: proc.stdout }).on('line', line => {
|
|
52
56
|
const trimmedLine = line.trim();
|
|
53
57
|
if (trimmedLine.startsWith(JSON_DEPLOY_RESULT_PREFIX)) {
|
|
54
58
|
const jsonStr = trimmedLine.slice(JSON_DEPLOY_RESULT_PREFIX.length).trim();
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
try {
|
|
60
|
+
result = JSON.parse(jsonStr);
|
|
61
|
+
} catch {
|
|
62
|
+
parseError = new Error(`Failed to parse deploy result JSON: ${jsonStr.slice(0, 200)}`);
|
|
63
|
+
}
|
|
57
64
|
} else {
|
|
58
65
|
logger.info(line);
|
|
59
66
|
}
|
|
60
67
|
});
|
|
61
|
-
readline.createInterface({ input: proc.stderr }).on('line', logger.
|
|
68
|
+
readline.createInterface({ input: proc.stderr }).on('line', logger.warn.bind(logger));
|
|
62
69
|
|
|
63
70
|
proc.on('error', error => {
|
|
71
|
+
if (settled) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
settled = true;
|
|
64
75
|
reject(new Error(`Failed to spawn ${command}: ${error.message}`));
|
|
65
76
|
});
|
|
66
77
|
|
|
67
78
|
proc.on('close', code => {
|
|
79
|
+
if (settled) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
settled = true;
|
|
68
83
|
if (code !== 0) {
|
|
69
|
-
reject(new Error(`${command} exited with code ${code}
|
|
84
|
+
reject(new Error(`${command} exited with code ${code}`));
|
|
85
|
+
} else if (parseError) {
|
|
86
|
+
reject(parseError);
|
|
70
87
|
} else {
|
|
71
88
|
resolve(result);
|
|
72
89
|
}
|
|
@@ -107,17 +124,80 @@ export interface ValidatorJson {
|
|
|
107
124
|
}
|
|
108
125
|
|
|
109
126
|
/**
|
|
110
|
-
* Gets the path to the l1-contracts directory.
|
|
127
|
+
* Gets the path to the l1-contracts foundry artifacts directory.
|
|
128
|
+
* These are copied from l1-contracts to yarn-project/l1-artifacts/l1-contracts
|
|
129
|
+
* during build to make yarn-project self-contained.
|
|
111
130
|
*/
|
|
112
131
|
export function getL1ContractsPath(): string {
|
|
113
|
-
// Try to find l1-contracts relative to this file
|
|
114
132
|
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const l1ContractsPath = resolve(currentDir, '..', '..', '..', 'l1-contracts');
|
|
133
|
+
// Go up from yarn-project/ethereum/dest to yarn-project, then to l1-artifacts/l1-contracts
|
|
134
|
+
const l1ContractsPath = resolve(currentDir, '..', '..', 'l1-artifacts', 'l1-contracts');
|
|
118
135
|
return l1ContractsPath;
|
|
119
136
|
}
|
|
120
137
|
|
|
138
|
+
// Cached deployment directory
|
|
139
|
+
let preparedDeployDir: string | undefined;
|
|
140
|
+
|
|
141
|
+
function cleanupDeployDir() {
|
|
142
|
+
if (preparedDeployDir) {
|
|
143
|
+
try {
|
|
144
|
+
rmSync(preparedDeployDir, { recursive: true, force: true });
|
|
145
|
+
} catch {
|
|
146
|
+
// ignore cleanup errors
|
|
147
|
+
}
|
|
148
|
+
preparedDeployDir = undefined;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Prepares a temp directory for forge deployment.
|
|
154
|
+
* Copies all artifacts with preserved timestamps (required for forge cache validity).
|
|
155
|
+
* A fresh broadcast/ directory is created for deployment outputs.
|
|
156
|
+
*/
|
|
157
|
+
export function prepareL1ContractsForDeployment(): string {
|
|
158
|
+
if (preparedDeployDir && existsSync(preparedDeployDir)) {
|
|
159
|
+
logger.verbose(`Using cached deployment directory: ${preparedDeployDir}`);
|
|
160
|
+
return preparedDeployDir;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const basePath = getL1ContractsPath();
|
|
164
|
+
logger.verbose(`Preparing L1 contracts from: ${basePath}`);
|
|
165
|
+
const tempDir = mkdtempSync(join(tmpdir(), '.foundry-deploy-'));
|
|
166
|
+
logger.verbose(`Created temp directory for deployment: ${tempDir}`);
|
|
167
|
+
preparedDeployDir = tempDir;
|
|
168
|
+
process.on('exit', cleanupDeployDir);
|
|
169
|
+
|
|
170
|
+
// Copy all dirs with preserved timestamps (required for forge cache validity)
|
|
171
|
+
const copyOpts = { recursive: true, preserveTimestamps: true };
|
|
172
|
+
cpSync(join(basePath, 'out'), join(tempDir, 'out'), copyOpts);
|
|
173
|
+
cpSync(join(basePath, 'lib'), join(tempDir, 'lib'), copyOpts);
|
|
174
|
+
cpSync(join(basePath, 'cache'), join(tempDir, 'cache'), copyOpts);
|
|
175
|
+
cpSync(join(basePath, 'src'), join(tempDir, 'src'), copyOpts);
|
|
176
|
+
cpSync(join(basePath, 'script'), join(tempDir, 'script'), copyOpts);
|
|
177
|
+
cpSync(join(basePath, 'generated'), join(tempDir, 'generated'), copyOpts);
|
|
178
|
+
// Kludge: copy test/ to appease forge cache which references test/shouting.t.sol
|
|
179
|
+
cpSync(join(basePath, 'test'), join(tempDir, 'test'), copyOpts);
|
|
180
|
+
cpSync(join(basePath, 'foundry.lock'), join(tempDir, 'foundry.lock'));
|
|
181
|
+
|
|
182
|
+
// Update foundry.toml to use absolute path to solc binary (avoids copying to noexec tmpfs)
|
|
183
|
+
const foundryTomlPath = join(basePath, 'foundry.toml');
|
|
184
|
+
let foundryToml = readFileSync(foundryTomlPath, 'utf-8');
|
|
185
|
+
const solcPathMatch = foundryToml.match(/solc\s*=\s*"\.\/solc-([^"]+)"/);
|
|
186
|
+
// Did we find a hardcoded solc path that we need to make absolute?
|
|
187
|
+
// This code path happens in CI currently as we bundle solc there to avoid race conditions when
|
|
188
|
+
// downloading solc.
|
|
189
|
+
if (solcPathMatch) {
|
|
190
|
+
const solcVersion = solcPathMatch[1];
|
|
191
|
+
const absoluteSolcPath = join(basePath, `solc-${solcVersion}`);
|
|
192
|
+
foundryToml = foundryToml.replace(/solc\s*=\s*"\.\/solc-[^"]+"/, `solc = "${absoluteSolcPath}"`);
|
|
193
|
+
logger.verbose(`Updated solc path in foundry.toml to: ${absoluteSolcPath}`);
|
|
194
|
+
}
|
|
195
|
+
writeFileSync(join(tempDir, 'foundry.toml'), foundryToml);
|
|
196
|
+
|
|
197
|
+
mkdirSync(join(tempDir, 'broadcast'));
|
|
198
|
+
return tempDir;
|
|
199
|
+
}
|
|
200
|
+
|
|
121
201
|
/**
|
|
122
202
|
* Computes the validator data for passing to Solidity.
|
|
123
203
|
* Only computes the G2 public key (which requires scalar multiplication on G2, not available in EVM).
|
|
@@ -211,7 +291,6 @@ export async function deployAztecL1Contracts(
|
|
|
211
291
|
'Initial validator funding requires minting tokens, which is not possible with an external token.',
|
|
212
292
|
);
|
|
213
293
|
}
|
|
214
|
-
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
215
294
|
const chain = createEthereumChain([rpcUrl], chainId);
|
|
216
295
|
|
|
217
296
|
const l1Client = createExtendedL1Client([rpcUrl], privateKey, chain.chainInfo);
|
|
@@ -240,8 +319,8 @@ export async function deployAztecL1Contracts(
|
|
|
240
319
|
}
|
|
241
320
|
}
|
|
242
321
|
|
|
243
|
-
//
|
|
244
|
-
const l1ContractsPath =
|
|
322
|
+
// Use foundry-artifacts from l1-artifacts package
|
|
323
|
+
const l1ContractsPath = prepareL1ContractsForDeployment();
|
|
245
324
|
|
|
246
325
|
const FORGE_SCRIPT = 'script/deploy/DeployAztecL1Contracts.s.sol';
|
|
247
326
|
await maybeForgeForceProductionBuild(l1ContractsPath, FORGE_SCRIPT, chainId);
|
|
@@ -257,11 +336,8 @@ export async function deployAztecL1Contracts(
|
|
|
257
336
|
);
|
|
258
337
|
}
|
|
259
338
|
|
|
260
|
-
|
|
261
|
-
const MAGIC_ANVIL_BATCH_SIZE = 12;
|
|
262
|
-
// Anvil seems to stall with unbounded batch size. Otherwise no max batch size is desirable.
|
|
339
|
+
const scriptPath = join(getL1ContractsPath(), 'scripts', 'forge_broadcast.js');
|
|
263
340
|
const forgeArgs = [
|
|
264
|
-
'script',
|
|
265
341
|
FORGE_SCRIPT,
|
|
266
342
|
'--sig',
|
|
267
343
|
'run()',
|
|
@@ -269,8 +345,6 @@ export async function deployAztecL1Contracts(
|
|
|
269
345
|
privateKey,
|
|
270
346
|
'--rpc-url',
|
|
271
347
|
rpcUrl,
|
|
272
|
-
'--broadcast',
|
|
273
|
-
...(chainId === foundry.id ? ['--batch-size', MAGIC_ANVIL_BATCH_SIZE.toString()] : []),
|
|
274
348
|
...(shouldVerify ? ['--verify'] : []),
|
|
275
349
|
];
|
|
276
350
|
const forgeEnv = {
|
|
@@ -279,7 +353,12 @@ export async function deployAztecL1Contracts(
|
|
|
279
353
|
FOUNDRY_PROFILE: chainId === mainnet.id ? 'production' : undefined,
|
|
280
354
|
...getDeployAztecL1ContractsEnvVars(args),
|
|
281
355
|
};
|
|
282
|
-
const result = await runProcess<ForgeL1ContractsDeployResult>(
|
|
356
|
+
const result = await runProcess<ForgeL1ContractsDeployResult>(
|
|
357
|
+
process.execPath,
|
|
358
|
+
[scriptPath, ...forgeArgs],
|
|
359
|
+
forgeEnv,
|
|
360
|
+
l1ContractsPath,
|
|
361
|
+
);
|
|
283
362
|
if (!result) {
|
|
284
363
|
throw new Error('Forge script did not output deployment result');
|
|
285
364
|
}
|
|
@@ -447,6 +526,7 @@ export function getDeployAztecL1ContractsEnvVars(args: DeployAztecL1ContractsArg
|
|
|
447
526
|
AZTEC_EJECTION_THRESHOLD: args.ejectionThreshold?.toString(),
|
|
448
527
|
AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE: args.governanceProposerRoundSize?.toString(),
|
|
449
528
|
AZTEC_GOVERNANCE_PROPOSER_QUORUM: args.governanceProposerQuorum?.toString(),
|
|
529
|
+
AZTEC_GOVERNANCE_VOTING_DURATION: args.governanceVotingDuration?.toString(),
|
|
450
530
|
ZKPASSPORT_DOMAIN: args.zkPassportArgs?.zkPassportDomain,
|
|
451
531
|
ZKPASSPORT_SCOPE: args.zkPassportArgs?.zkPassportScope,
|
|
452
532
|
} as const;
|
|
@@ -477,14 +557,17 @@ export function getDeployRollupForUpgradeEnvVars(
|
|
|
477
557
|
AZTEC_TARGET_COMMITTEE_SIZE: args.aztecTargetCommitteeSize.toString(),
|
|
478
558
|
AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: args.lagInEpochsForValidatorSet.toString(),
|
|
479
559
|
AZTEC_LAG_IN_EPOCHS_FOR_RANDAO: args.lagInEpochsForRandao.toString(),
|
|
560
|
+
AZTEC_INBOX_LAG: args.inboxLag?.toString(),
|
|
480
561
|
AZTEC_PROOF_SUBMISSION_EPOCHS: args.aztecProofSubmissionEpochs.toString(),
|
|
481
562
|
AZTEC_LOCAL_EJECTION_THRESHOLD: args.localEjectionThreshold.toString(),
|
|
482
563
|
AZTEC_SLASHING_LIFETIME_IN_ROUNDS: args.slashingLifetimeInRounds.toString(),
|
|
564
|
+
AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS: args.slashingExecutionDelayInRounds.toString(),
|
|
483
565
|
AZTEC_SLASHING_VETOER: args.slashingVetoer.toString(),
|
|
484
566
|
AZTEC_SLASHING_DISABLE_DURATION: args.slashingDisableDuration.toString(),
|
|
485
567
|
AZTEC_MANA_TARGET: args.manaTarget.toString(),
|
|
486
568
|
AZTEC_EXIT_DELAY_SECONDS: args.exitDelaySeconds.toString(),
|
|
487
569
|
AZTEC_PROVING_COST_PER_MANA: args.provingCostPerMana.toString(),
|
|
570
|
+
AZTEC_INITIAL_ETH_PER_FEE_ASSET: args.initialEthPerFeeAsset.toString(),
|
|
488
571
|
AZTEC_SLASHER_FLAVOR: args.slasherFlavor,
|
|
489
572
|
AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS: args.slashingRoundSizeInEpochs.toString(),
|
|
490
573
|
AZTEC_SLASHING_QUORUM: args.slashingQuorum?.toString(),
|
|
@@ -512,25 +595,14 @@ export const deployRollupForUpgrade = async (
|
|
|
512
595
|
| 'zkPassportArgs'
|
|
513
596
|
>,
|
|
514
597
|
) => {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
// Relative location of l1-contracts in monorepo or docker image.
|
|
518
|
-
const l1ContractsPath = resolve(currentDir, '..', '..', '..', 'l1-contracts');
|
|
598
|
+
// Use foundry-artifacts from l1-artifacts package
|
|
599
|
+
const l1ContractsPath = prepareL1ContractsForDeployment();
|
|
519
600
|
|
|
520
601
|
const FORGE_SCRIPT = 'script/deploy/DeployRollupForUpgrade.s.sol';
|
|
521
602
|
await maybeForgeForceProductionBuild(l1ContractsPath, FORGE_SCRIPT, chainId);
|
|
522
603
|
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
FORGE_SCRIPT,
|
|
526
|
-
'--sig',
|
|
527
|
-
'run()',
|
|
528
|
-
'--private-key',
|
|
529
|
-
privateKey,
|
|
530
|
-
'--rpc-url',
|
|
531
|
-
rpcUrl,
|
|
532
|
-
'--broadcast',
|
|
533
|
-
];
|
|
604
|
+
const scriptPath = join(getL1ContractsPath(), 'scripts', 'forge_broadcast.js');
|
|
605
|
+
const forgeArgs = [FORGE_SCRIPT, '--sig', 'run()', '--private-key', privateKey, '--rpc-url', rpcUrl];
|
|
534
606
|
const forgeEnv = {
|
|
535
607
|
FOUNDRY_PROFILE: chainId === mainnet.id ? 'production' : undefined,
|
|
536
608
|
// Env vars required by l1-contracts/script/deploy/RollupConfiguration.sol.
|
|
@@ -539,7 +611,12 @@ export const deployRollupForUpgrade = async (
|
|
|
539
611
|
...getDeployRollupForUpgradeEnvVars(args),
|
|
540
612
|
};
|
|
541
613
|
|
|
542
|
-
const result = await runProcess<ForgeRollupUpgradeResult>(
|
|
614
|
+
const result = await runProcess<ForgeRollupUpgradeResult>(
|
|
615
|
+
process.execPath,
|
|
616
|
+
[scriptPath, ...forgeArgs],
|
|
617
|
+
forgeEnv,
|
|
618
|
+
l1ContractsPath,
|
|
619
|
+
);
|
|
543
620
|
if (!result) {
|
|
544
621
|
throw new Error('Forge script did not output deployment result');
|
|
545
622
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Auto-generated from spartan/environments/network-defaults.yml
|
|
2
|
+
// Do not edit manually - run yarn generate to regenerate
|
|
3
|
+
|
|
4
|
+
/** Default L1 contracts configuration values from network-defaults.yml */
|
|
5
|
+
export const l1ContractsDefaultEnv = {
|
|
6
|
+
ETHEREUM_SLOT_DURATION: 12,
|
|
7
|
+
AZTEC_SLOT_DURATION: 36,
|
|
8
|
+
AZTEC_EPOCH_DURATION: 32,
|
|
9
|
+
AZTEC_TARGET_COMMITTEE_SIZE: 48,
|
|
10
|
+
AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: 2,
|
|
11
|
+
AZTEC_LAG_IN_EPOCHS_FOR_RANDAO: 2,
|
|
12
|
+
AZTEC_ACTIVATION_THRESHOLD: 100000000000000000000,
|
|
13
|
+
AZTEC_EJECTION_THRESHOLD: 50000000000000000000,
|
|
14
|
+
AZTEC_LOCAL_EJECTION_THRESHOLD: 98000000000000000000,
|
|
15
|
+
AZTEC_EXIT_DELAY_SECONDS: 172800,
|
|
16
|
+
AZTEC_INBOX_LAG: 1,
|
|
17
|
+
AZTEC_PROOF_SUBMISSION_EPOCHS: 1,
|
|
18
|
+
AZTEC_MANA_TARGET: 100000000,
|
|
19
|
+
AZTEC_PROVING_COST_PER_MANA: 100,
|
|
20
|
+
AZTEC_INITIAL_ETH_PER_FEE_ASSET: 10000000,
|
|
21
|
+
AZTEC_SLASHER_FLAVOR: 'tally',
|
|
22
|
+
AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS: 4,
|
|
23
|
+
AZTEC_SLASHING_LIFETIME_IN_ROUNDS: 5,
|
|
24
|
+
AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS: 0,
|
|
25
|
+
AZTEC_SLASHING_OFFSET_IN_ROUNDS: 2,
|
|
26
|
+
AZTEC_SLASHING_VETOER: '0x0000000000000000000000000000000000000000',
|
|
27
|
+
AZTEC_SLASHING_DISABLE_DURATION: 432000,
|
|
28
|
+
AZTEC_SLASH_AMOUNT_SMALL: 10000000000000000000,
|
|
29
|
+
AZTEC_SLASH_AMOUNT_MEDIUM: 20000000000000000000,
|
|
30
|
+
AZTEC_SLASH_AMOUNT_LARGE: 50000000000000000000,
|
|
31
|
+
AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE: 300,
|
|
32
|
+
} as const;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// 1_000_000_000_000_000_000 Wei = 1 ETH
|
|
4
4
|
export const WEI_CONST = 1_000_000_000n;
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
export const
|
|
6
|
+
// EIP-7825: protocol-level cap on tx gas limit (2^24). Clients reject above this.
|
|
7
|
+
export const MAX_L1_TX_LIMIT = 16_777_216n;
|
|
8
8
|
|
|
9
9
|
// setting a minimum bump percentage to 10% due to geth's implementation
|
|
10
10
|
// https://github.com/ethereum/go-ethereum/blob/e3d61e6db028c412f74bc4d4c7e117a9e29d0de0/core/txpool/legacypool/list.go#L298
|
|
@@ -4,13 +4,13 @@ import type { PriorityFeeStrategy } from './types.js';
|
|
|
4
4
|
|
|
5
5
|
export {
|
|
6
6
|
HISTORICAL_BLOCK_COUNT,
|
|
7
|
-
executeStrategy,
|
|
8
7
|
type PriorityFeeStrategy,
|
|
9
8
|
type PriorityFeeStrategyContext,
|
|
10
9
|
type PriorityFeeStrategyResult,
|
|
11
10
|
} from './types.js';
|
|
12
11
|
|
|
13
12
|
export { P75AllTxsPriorityFeeStrategy } from './p75_competitive.js';
|
|
13
|
+
export { P75BlobTxsOnlyPriorityFeeStrategy } from './p75_competitive_blob_txs_only.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Default list of priority fee strategies to analyze.
|
|
@@ -12,50 +12,54 @@ import {
|
|
|
12
12
|
type PriorityFeeStrategyResult,
|
|
13
13
|
} from './types.js';
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
* Type for the promises required by the competitive strategy
|
|
17
|
-
*/
|
|
18
|
-
type P75AllTxsStrategyPromises = {
|
|
19
|
-
networkEstimate: Promise<bigint>;
|
|
20
|
-
pendingBlock: Promise<Awaited<ReturnType<ViemClient['getBlock']>> | null>;
|
|
21
|
-
feeHistory: Promise<Awaited<ReturnType<ViemClient['getFeeHistory']>> | null>;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
15
|
/**
|
|
25
16
|
* Our current competitive priority fee strategy.
|
|
26
17
|
* Analyzes p75 of pending transactions and 5-block fee history to determine a competitive priority fee.
|
|
27
18
|
* Falls back to network estimate if data is unavailable.
|
|
28
19
|
*/
|
|
29
|
-
export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy
|
|
20
|
+
export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy = {
|
|
30
21
|
name: 'Competitive (P75 + History) - CURRENT',
|
|
31
22
|
id: 'p75_pending_txs_and_history_all_txs',
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
24
|
+
async execute(client: ViemClient, context: PriorityFeeStrategyContext): Promise<PriorityFeeStrategyResult> {
|
|
25
|
+
const { isBlobTx, logger } = context;
|
|
26
|
+
|
|
27
|
+
// Fire all RPC calls in parallel
|
|
28
|
+
const [latestBlockResult, blobBaseFeeResult, networkEstimateResult, pendingBlockResult, feeHistoryResult] =
|
|
29
|
+
await Promise.allSettled([
|
|
30
|
+
client.getBlock({ blockTag: 'latest' }),
|
|
31
|
+
isBlobTx ? client.getBlobBaseFee() : Promise.resolve(undefined),
|
|
32
|
+
client.estimateMaxPriorityFeePerGas().catch(() => 0n),
|
|
33
|
+
client.getBlock({ blockTag: 'pending', includeTransactions: true }).catch(() => null),
|
|
34
|
+
client
|
|
35
|
+
.getFeeHistory({
|
|
36
|
+
blockCount: HISTORICAL_BLOCK_COUNT,
|
|
37
|
+
rewardPercentiles: [75],
|
|
38
|
+
blockTag: 'latest',
|
|
39
|
+
})
|
|
40
|
+
.catch(() => null),
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
// Extract latest block
|
|
44
|
+
if (latestBlockResult.status === 'rejected') {
|
|
45
|
+
throw new Error(`Failed to get latest block: ${latestBlockResult.reason}`);
|
|
46
|
+
}
|
|
47
|
+
const latestBlock = latestBlockResult.value;
|
|
48
|
+
|
|
49
|
+
// Extract blob base fee (only for blob txs)
|
|
50
|
+
let blobBaseFee: bigint | undefined;
|
|
51
|
+
if (isBlobTx) {
|
|
52
|
+
if (blobBaseFeeResult.status === 'fulfilled' && typeof blobBaseFeeResult.value === 'bigint') {
|
|
53
|
+
blobBaseFee = blobBaseFeeResult.value;
|
|
54
|
+
} else {
|
|
55
|
+
logger?.warn('Failed to get L1 blob base fee');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
54
58
|
|
|
55
|
-
// Extract network estimate
|
|
59
|
+
// Extract network estimate
|
|
56
60
|
const networkEstimate =
|
|
57
|
-
|
|
58
|
-
?
|
|
61
|
+
networkEstimateResult.status === 'fulfilled' && typeof networkEstimateResult.value === 'bigint'
|
|
62
|
+
? networkEstimateResult.value
|
|
59
63
|
: 0n;
|
|
60
64
|
|
|
61
65
|
let competitiveFee = networkEstimate;
|
|
@@ -63,8 +67,8 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
63
67
|
networkEstimateGwei: formatGwei(networkEstimate),
|
|
64
68
|
};
|
|
65
69
|
|
|
66
|
-
// Extract pending block
|
|
67
|
-
const pendingBlock =
|
|
70
|
+
// Extract pending block
|
|
71
|
+
const pendingBlock = pendingBlockResult.status === 'fulfilled' ? pendingBlockResult.value : null;
|
|
68
72
|
|
|
69
73
|
// Analyze pending block transactions
|
|
70
74
|
if (pendingBlock?.transactions && pendingBlock.transactions.length > 0) {
|
|
@@ -73,9 +77,7 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
73
77
|
if (typeof tx === 'string') {
|
|
74
78
|
return 0n;
|
|
75
79
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return fee;
|
|
80
|
+
return tx.maxPriorityFeePerGas || 0n;
|
|
79
81
|
})
|
|
80
82
|
.filter((fee: bigint) => fee > 0n);
|
|
81
83
|
|
|
@@ -97,8 +99,8 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
|
|
100
|
-
// Extract fee history
|
|
101
|
-
const feeHistory =
|
|
102
|
+
// Extract fee history
|
|
103
|
+
const feeHistory = feeHistoryResult.status === 'fulfilled' ? feeHistoryResult.value : null;
|
|
102
104
|
|
|
103
105
|
// Analyze fee history
|
|
104
106
|
if (feeHistory?.reward && feeHistory.reward.length > 0) {
|
|
@@ -132,7 +134,7 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
132
134
|
// Sanity check: cap competitive fee at 100x network estimate to avoid using unrealistic fees
|
|
133
135
|
const maxReasonableFee = networkEstimate * 100n;
|
|
134
136
|
if (competitiveFee > maxReasonableFee && networkEstimate > 0n) {
|
|
135
|
-
logger?.
|
|
137
|
+
logger?.debug('Competitive fee exceeds sanity cap, using capped value', {
|
|
136
138
|
competitiveFee: formatGwei(competitiveFee),
|
|
137
139
|
networkEstimate: formatGwei(networkEstimate),
|
|
138
140
|
cappedTo: formatGwei(maxReasonableFee),
|
|
@@ -153,6 +155,8 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy<P75AllTxsStrategy
|
|
|
153
155
|
|
|
154
156
|
return {
|
|
155
157
|
priorityFee: competitiveFee,
|
|
158
|
+
latestBlock,
|
|
159
|
+
blobBaseFee,
|
|
156
160
|
debugInfo,
|
|
157
161
|
};
|
|
158
162
|
},
|