@aztec/ethereum 0.0.1-commit.6d3c34e → 0.0.1-commit.7cf39cb55
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 +15 -28
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +47 -56
- 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 +1 -1
- package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
- package/dest/contracts/fee_asset_handler.js +2 -0
- 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 +4 -1
- package/dest/contracts/inbox.d.ts +18 -1
- package/dest/contracts/inbox.d.ts.map +1 -1
- package/dest/contracts/inbox.js +32 -1
- package/dest/contracts/index.d.ts +2 -1
- package/dest/contracts/index.d.ts.map +1 -1
- package/dest/contracts/index.js +1 -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/rollup.d.ts +35 -3
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +76 -6
- 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 +6 -1
- package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_aztec_l1_contracts.js +56 -28
- 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 +1394 -471
- 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/p75_competitive.js +1 -1
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +1 -1
- package/dest/l1_tx_utils/l1_tx_utils.js +6 -6
- package/dest/l1_tx_utils/readonly_l1_tx_utils.js +3 -3
- 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 +4 -1
- 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 +4 -2
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
- package/dest/test/rollup_cheat_codes.js +10 -1
- 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 +56 -55
- package/src/contracts/README.md +157 -0
- package/src/contracts/empire_slashing_proposer.ts +16 -27
- package/src/contracts/fee_asset_handler.ts +2 -0
- package/src/contracts/governance.ts +10 -1
- package/src/contracts/governance_proposer.ts +4 -1
- package/src/contracts/inbox.ts +48 -1
- package/src/contracts/index.ts +1 -0
- package/src/contracts/log.ts +13 -0
- package/src/contracts/multicall.ts +5 -2
- package/src/contracts/rollup.ts +111 -11
- package/src/contracts/tally_slashing_proposer.ts +5 -1
- package/src/deploy_aztec_l1_contracts.ts +61 -33
- 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/p75_competitive.ts +1 -1
- package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +1 -1
- package/src/l1_tx_utils/l1_tx_utils.ts +6 -6
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +3 -3
- package/src/publisher_manager.ts +4 -2
- package/src/queries.ts +3 -1
- package/src/test/rollup_cheat_codes.ts +11 -2
- 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,12 +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 { cpSync, existsSync, mkdirSync, mkdtempSync,
|
|
13
|
+
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs';
|
|
14
14
|
import { tmpdir } from 'os';
|
|
15
15
|
import { dirname, join, resolve } from 'path';
|
|
16
16
|
import readline from 'readline';
|
|
17
17
|
import type { Hex } from 'viem';
|
|
18
|
-
import {
|
|
18
|
+
import { mainnet, sepolia } from 'viem/chains';
|
|
19
19
|
|
|
20
20
|
import { createEthereumChain, isAnvilTestChain } from './chain.js';
|
|
21
21
|
import { createExtendedL1Client } from './client.js';
|
|
@@ -31,9 +31,9 @@ const logger = createLogger('ethereum:deploy_aztec_l1_contracts');
|
|
|
31
31
|
const JSON_DEPLOY_RESULT_PREFIX = 'JSON DEPLOY RESULT:';
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Runs a process
|
|
35
|
-
*
|
|
36
|
-
*
|
|
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.
|
|
37
37
|
*/
|
|
38
38
|
function runProcess<T>(
|
|
39
39
|
command: string,
|
|
@@ -49,26 +49,41 @@ function runProcess<T>(
|
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
let result: T | undefined;
|
|
52
|
+
let parseError: Error | undefined;
|
|
53
|
+
let settled = false;
|
|
52
54
|
|
|
53
55
|
readline.createInterface({ input: proc.stdout }).on('line', line => {
|
|
54
56
|
const trimmedLine = line.trim();
|
|
55
57
|
if (trimmedLine.startsWith(JSON_DEPLOY_RESULT_PREFIX)) {
|
|
56
58
|
const jsonStr = trimmedLine.slice(JSON_DEPLOY_RESULT_PREFIX.length).trim();
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
try {
|
|
60
|
+
result = JSON.parse(jsonStr);
|
|
61
|
+
} catch {
|
|
62
|
+
parseError = new Error(`Failed to parse deploy result JSON: ${jsonStr.slice(0, 200)}`);
|
|
63
|
+
}
|
|
59
64
|
} else {
|
|
60
65
|
logger.info(line);
|
|
61
66
|
}
|
|
62
67
|
});
|
|
63
|
-
readline.createInterface({ input: proc.stderr }).on('line', logger.
|
|
68
|
+
readline.createInterface({ input: proc.stderr }).on('line', logger.warn.bind(logger));
|
|
64
69
|
|
|
65
70
|
proc.on('error', error => {
|
|
71
|
+
if (settled) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
settled = true;
|
|
66
75
|
reject(new Error(`Failed to spawn ${command}: ${error.message}`));
|
|
67
76
|
});
|
|
68
77
|
|
|
69
78
|
proc.on('close', code => {
|
|
79
|
+
if (settled) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
settled = true;
|
|
70
83
|
if (code !== 0) {
|
|
71
|
-
reject(new Error(`${command} exited with code ${code}
|
|
84
|
+
reject(new Error(`${command} exited with code ${code}`));
|
|
85
|
+
} else if (parseError) {
|
|
86
|
+
reject(parseError);
|
|
72
87
|
} else {
|
|
73
88
|
resolve(result);
|
|
74
89
|
}
|
|
@@ -141,11 +156,14 @@ function cleanupDeployDir() {
|
|
|
141
156
|
*/
|
|
142
157
|
export function prepareL1ContractsForDeployment(): string {
|
|
143
158
|
if (preparedDeployDir && existsSync(preparedDeployDir)) {
|
|
159
|
+
logger.verbose(`Using cached deployment directory: ${preparedDeployDir}`);
|
|
144
160
|
return preparedDeployDir;
|
|
145
161
|
}
|
|
146
162
|
|
|
147
163
|
const basePath = getL1ContractsPath();
|
|
164
|
+
logger.verbose(`Preparing L1 contracts from: ${basePath}`);
|
|
148
165
|
const tempDir = mkdtempSync(join(tmpdir(), '.foundry-deploy-'));
|
|
166
|
+
logger.verbose(`Created temp directory for deployment: ${tempDir}`);
|
|
149
167
|
preparedDeployDir = tempDir;
|
|
150
168
|
process.on('exit', cleanupDeployDir);
|
|
151
169
|
|
|
@@ -157,13 +175,24 @@ export function prepareL1ContractsForDeployment(): string {
|
|
|
157
175
|
cpSync(join(basePath, 'src'), join(tempDir, 'src'), copyOpts);
|
|
158
176
|
cpSync(join(basePath, 'script'), join(tempDir, 'script'), copyOpts);
|
|
159
177
|
cpSync(join(basePath, 'generated'), join(tempDir, 'generated'), copyOpts);
|
|
160
|
-
|
|
178
|
+
// Kludge: copy test/ to appease forge cache which references test/shouting.t.sol
|
|
179
|
+
cpSync(join(basePath, 'test'), join(tempDir, 'test'), copyOpts);
|
|
161
180
|
cpSync(join(basePath, 'foundry.lock'), join(tempDir, 'foundry.lock'));
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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}`);
|
|
166
194
|
}
|
|
195
|
+
writeFileSync(join(tempDir, 'foundry.toml'), foundryToml);
|
|
167
196
|
|
|
168
197
|
mkdirSync(join(tempDir, 'broadcast'));
|
|
169
198
|
return tempDir;
|
|
@@ -307,11 +336,8 @@ export async function deployAztecL1Contracts(
|
|
|
307
336
|
);
|
|
308
337
|
}
|
|
309
338
|
|
|
310
|
-
|
|
311
|
-
const MAGIC_ANVIL_BATCH_SIZE = 12;
|
|
312
|
-
// Anvil seems to stall with unbounded batch size. Otherwise no max batch size is desirable.
|
|
339
|
+
const scriptPath = join(getL1ContractsPath(), 'scripts', 'forge_broadcast.js');
|
|
313
340
|
const forgeArgs = [
|
|
314
|
-
'script',
|
|
315
341
|
FORGE_SCRIPT,
|
|
316
342
|
'--sig',
|
|
317
343
|
'run()',
|
|
@@ -319,8 +345,6 @@ export async function deployAztecL1Contracts(
|
|
|
319
345
|
privateKey,
|
|
320
346
|
'--rpc-url',
|
|
321
347
|
rpcUrl,
|
|
322
|
-
'--broadcast',
|
|
323
|
-
...(chainId === foundry.id ? ['--batch-size', MAGIC_ANVIL_BATCH_SIZE.toString()] : []),
|
|
324
348
|
...(shouldVerify ? ['--verify'] : []),
|
|
325
349
|
];
|
|
326
350
|
const forgeEnv = {
|
|
@@ -329,7 +353,12 @@ export async function deployAztecL1Contracts(
|
|
|
329
353
|
FOUNDRY_PROFILE: chainId === mainnet.id ? 'production' : undefined,
|
|
330
354
|
...getDeployAztecL1ContractsEnvVars(args),
|
|
331
355
|
};
|
|
332
|
-
const result = await runProcess<ForgeL1ContractsDeployResult>(
|
|
356
|
+
const result = await runProcess<ForgeL1ContractsDeployResult>(
|
|
357
|
+
process.execPath,
|
|
358
|
+
[scriptPath, ...forgeArgs],
|
|
359
|
+
forgeEnv,
|
|
360
|
+
l1ContractsPath,
|
|
361
|
+
);
|
|
333
362
|
if (!result) {
|
|
334
363
|
throw new Error('Forge script did not output deployment result');
|
|
335
364
|
}
|
|
@@ -497,6 +526,7 @@ export function getDeployAztecL1ContractsEnvVars(args: DeployAztecL1ContractsArg
|
|
|
497
526
|
AZTEC_EJECTION_THRESHOLD: args.ejectionThreshold?.toString(),
|
|
498
527
|
AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE: args.governanceProposerRoundSize?.toString(),
|
|
499
528
|
AZTEC_GOVERNANCE_PROPOSER_QUORUM: args.governanceProposerQuorum?.toString(),
|
|
529
|
+
AZTEC_GOVERNANCE_VOTING_DURATION: args.governanceVotingDuration?.toString(),
|
|
500
530
|
ZKPASSPORT_DOMAIN: args.zkPassportArgs?.zkPassportDomain,
|
|
501
531
|
ZKPASSPORT_SCOPE: args.zkPassportArgs?.zkPassportScope,
|
|
502
532
|
} as const;
|
|
@@ -531,11 +561,13 @@ export function getDeployRollupForUpgradeEnvVars(
|
|
|
531
561
|
AZTEC_PROOF_SUBMISSION_EPOCHS: args.aztecProofSubmissionEpochs.toString(),
|
|
532
562
|
AZTEC_LOCAL_EJECTION_THRESHOLD: args.localEjectionThreshold.toString(),
|
|
533
563
|
AZTEC_SLASHING_LIFETIME_IN_ROUNDS: args.slashingLifetimeInRounds.toString(),
|
|
564
|
+
AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS: args.slashingExecutionDelayInRounds.toString(),
|
|
534
565
|
AZTEC_SLASHING_VETOER: args.slashingVetoer.toString(),
|
|
535
566
|
AZTEC_SLASHING_DISABLE_DURATION: args.slashingDisableDuration.toString(),
|
|
536
567
|
AZTEC_MANA_TARGET: args.manaTarget.toString(),
|
|
537
568
|
AZTEC_EXIT_DELAY_SECONDS: args.exitDelaySeconds.toString(),
|
|
538
569
|
AZTEC_PROVING_COST_PER_MANA: args.provingCostPerMana.toString(),
|
|
570
|
+
AZTEC_INITIAL_ETH_PER_FEE_ASSET: args.initialEthPerFeeAsset.toString(),
|
|
539
571
|
AZTEC_SLASHER_FLAVOR: args.slasherFlavor,
|
|
540
572
|
AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS: args.slashingRoundSizeInEpochs.toString(),
|
|
541
573
|
AZTEC_SLASHING_QUORUM: args.slashingQuorum?.toString(),
|
|
@@ -569,17 +601,8 @@ export const deployRollupForUpgrade = async (
|
|
|
569
601
|
const FORGE_SCRIPT = 'script/deploy/DeployRollupForUpgrade.s.sol';
|
|
570
602
|
await maybeForgeForceProductionBuild(l1ContractsPath, FORGE_SCRIPT, chainId);
|
|
571
603
|
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
FORGE_SCRIPT,
|
|
575
|
-
'--sig',
|
|
576
|
-
'run()',
|
|
577
|
-
'--private-key',
|
|
578
|
-
privateKey,
|
|
579
|
-
'--rpc-url',
|
|
580
|
-
rpcUrl,
|
|
581
|
-
'--broadcast',
|
|
582
|
-
];
|
|
604
|
+
const scriptPath = join(getL1ContractsPath(), 'scripts', 'forge_broadcast.js');
|
|
605
|
+
const forgeArgs = [FORGE_SCRIPT, '--sig', 'run()', '--private-key', privateKey, '--rpc-url', rpcUrl];
|
|
583
606
|
const forgeEnv = {
|
|
584
607
|
FOUNDRY_PROFILE: chainId === mainnet.id ? 'production' : undefined,
|
|
585
608
|
// Env vars required by l1-contracts/script/deploy/RollupConfiguration.sol.
|
|
@@ -588,7 +611,12 @@ export const deployRollupForUpgrade = async (
|
|
|
588
611
|
...getDeployRollupForUpgradeEnvVars(args),
|
|
589
612
|
};
|
|
590
613
|
|
|
591
|
-
const result = await runProcess<ForgeRollupUpgradeResult>(
|
|
614
|
+
const result = await runProcess<ForgeRollupUpgradeResult>(
|
|
615
|
+
process.execPath,
|
|
616
|
+
[scriptPath, ...forgeArgs],
|
|
617
|
+
forgeEnv,
|
|
618
|
+
l1ContractsPath,
|
|
619
|
+
);
|
|
592
620
|
if (!result) {
|
|
593
621
|
throw new Error('Forge script did not output deployment result');
|
|
594
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
|
|
@@ -134,7 +134,7 @@ export const P75AllTxsPriorityFeeStrategy: PriorityFeeStrategy = {
|
|
|
134
134
|
// Sanity check: cap competitive fee at 100x network estimate to avoid using unrealistic fees
|
|
135
135
|
const maxReasonableFee = networkEstimate * 100n;
|
|
136
136
|
if (competitiveFee > maxReasonableFee && networkEstimate > 0n) {
|
|
137
|
-
logger?.
|
|
137
|
+
logger?.debug('Competitive fee exceeds sanity cap, using capped value', {
|
|
138
138
|
competitiveFee: formatGwei(competitiveFee),
|
|
139
139
|
networkEstimate: formatGwei(networkEstimate),
|
|
140
140
|
cappedTo: formatGwei(maxReasonableFee),
|
|
@@ -207,7 +207,7 @@ export const P75BlobTxsOnlyPriorityFeeStrategy: PriorityFeeStrategy = {
|
|
|
207
207
|
|
|
208
208
|
// Debug: Log suspicious fees from history
|
|
209
209
|
if (medianHistoricalFee > 100n * WEI_CONST) {
|
|
210
|
-
logger?.
|
|
210
|
+
logger?.debug('Suspicious high fee in history', {
|
|
211
211
|
historicalMedian: formatGwei(medianHistoricalFee),
|
|
212
212
|
allP75Fees: percentile75Fees.map(f => formatGwei(f)),
|
|
213
213
|
});
|
|
@@ -27,7 +27,7 @@ import { jsonRpc } from 'viem/nonce';
|
|
|
27
27
|
import type { ViemClient } from '../types.js';
|
|
28
28
|
import { formatViemError } from '../utils.js';
|
|
29
29
|
import { type L1TxUtilsConfig, l1TxUtilsConfigMappings } from './config.js';
|
|
30
|
-
import {
|
|
30
|
+
import { MAX_L1_TX_LIMIT } from './constants.js';
|
|
31
31
|
import type { IL1TxMetrics, IL1TxStore } from './interfaces.js';
|
|
32
32
|
import { ReadOnlyL1TxUtils } from './readonly_l1_tx_utils.js';
|
|
33
33
|
import {
|
|
@@ -207,7 +207,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
207
207
|
|
|
208
208
|
let gasLimit: bigint;
|
|
209
209
|
if (this.debugMaxGasLimit) {
|
|
210
|
-
gasLimit =
|
|
210
|
+
gasLimit = MAX_L1_TX_LIMIT;
|
|
211
211
|
} else if (gasConfig.gasLimit) {
|
|
212
212
|
gasLimit = gasConfig.gasLimit;
|
|
213
213
|
} else {
|
|
@@ -283,7 +283,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
283
283
|
return { txHash, state: l1TxState };
|
|
284
284
|
} catch (err: any) {
|
|
285
285
|
const viemError = formatViemError(err, request.abi);
|
|
286
|
-
this.logger.error(`Failed to send L1 transaction`, viemError, {
|
|
286
|
+
this.logger.error(`Failed to send L1 transaction: ${viemError.message}`, viemError, {
|
|
287
287
|
request: pick(request, 'to', 'value'),
|
|
288
288
|
});
|
|
289
289
|
throw viemError;
|
|
@@ -631,12 +631,12 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
|
|
|
631
631
|
from: request.from ?? this.getSenderAddress().toString(),
|
|
632
632
|
maxFeePerGas: gasPrice.maxFeePerGas,
|
|
633
633
|
maxPriorityFeePerGas: gasPrice.maxPriorityFeePerGas,
|
|
634
|
-
gas: request.gas ??
|
|
634
|
+
gas: request.gas ?? MAX_L1_TX_LIMIT,
|
|
635
635
|
};
|
|
636
636
|
|
|
637
637
|
if (!request.gas && !gasConfig.ignoreBlockGasLimit) {
|
|
638
|
-
//
|
|
639
|
-
blockOverrides.gasLimit =
|
|
638
|
+
// MAX_L1_TX_LIMIT is set as call.gas, ensure block gasLimit is sufficient
|
|
639
|
+
blockOverrides.gasLimit = MAX_L1_TX_LIMIT;
|
|
640
640
|
}
|
|
641
641
|
|
|
642
642
|
return this._simulate(call, blockOverrides, stateOverrides, gasConfig, abi);
|
|
@@ -27,7 +27,7 @@ import type { ViemClient } from '../types.js';
|
|
|
27
27
|
import { type L1TxUtilsConfig, defaultL1TxUtilsConfig, l1TxUtilsConfigMappings } from './config.js';
|
|
28
28
|
import {
|
|
29
29
|
BLOCK_TIME_MS,
|
|
30
|
-
|
|
30
|
+
MAX_L1_TX_LIMIT,
|
|
31
31
|
MIN_BLOB_REPLACEMENT_BUMP_PERCENTAGE,
|
|
32
32
|
MIN_REPLACEMENT_BUMP_PERCENTAGE,
|
|
33
33
|
WEI_CONST,
|
|
@@ -249,7 +249,7 @@ export class ReadOnlyL1TxUtils {
|
|
|
249
249
|
...request,
|
|
250
250
|
..._blobInputs,
|
|
251
251
|
maxFeePerBlobGas: gasPrice.maxFeePerBlobGas!,
|
|
252
|
-
gas:
|
|
252
|
+
gas: MAX_L1_TX_LIMIT,
|
|
253
253
|
blockTag: 'latest',
|
|
254
254
|
});
|
|
255
255
|
|
|
@@ -258,7 +258,7 @@ export class ReadOnlyL1TxUtils {
|
|
|
258
258
|
initialEstimate = await this.client.estimateGas({
|
|
259
259
|
account,
|
|
260
260
|
...request,
|
|
261
|
-
gas:
|
|
261
|
+
gas: MAX_L1_TX_LIMIT,
|
|
262
262
|
blockTag: 'latest',
|
|
263
263
|
});
|
|
264
264
|
this.logger?.trace(`Estimated gas for non-blob tx: ${initialEstimate}`);
|
package/src/publisher_manager.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { pick } from '@aztec/foundation/collection';
|
|
2
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
3
3
|
|
|
4
4
|
import { L1TxUtils, TxUtilsState } from './l1_tx_utils/index.js';
|
|
5
5
|
|
|
@@ -28,13 +28,15 @@ const busyStates: TxUtilsState[] = [
|
|
|
28
28
|
export type PublisherFilter<UtilsType extends L1TxUtils> = (utils: UtilsType) => boolean;
|
|
29
29
|
|
|
30
30
|
export class PublisherManager<UtilsType extends L1TxUtils = L1TxUtils> {
|
|
31
|
-
private log
|
|
31
|
+
private log: Logger;
|
|
32
32
|
private config: { publisherAllowInvalidStates?: boolean };
|
|
33
33
|
|
|
34
34
|
constructor(
|
|
35
35
|
private publishers: UtilsType[],
|
|
36
36
|
config: { publisherAllowInvalidStates?: boolean },
|
|
37
|
+
bindings?: LoggerBindings,
|
|
37
38
|
) {
|
|
39
|
+
this.log = createLogger('publisher:manager', bindings);
|
|
38
40
|
this.log.info(`PublisherManager initialized with ${publishers.length} publishers.`);
|
|
39
41
|
this.publishers = publishers;
|
|
40
42
|
this.config = pick(config, 'publisherAllowInvalidStates');
|
package/src/queries.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
2
|
|
|
3
|
-
import type
|
|
3
|
+
import { DefaultL1ContractsConfig, type L1ContractsConfig } from './config.js';
|
|
4
4
|
import { ReadOnlyGovernanceContract } from './contracts/governance.js';
|
|
5
5
|
import { GovernanceProposerContract } from './contracts/governance_proposer.js';
|
|
6
6
|
import { InboxContract } from './contracts/inbox.js';
|
|
@@ -99,6 +99,7 @@ export async function getL1ContractsConfig(
|
|
|
99
99
|
inboxLag: Number(inboxLag),
|
|
100
100
|
governanceProposerQuorum: Number(governanceProposerQuorum),
|
|
101
101
|
governanceProposerRoundSize: Number(governanceProposerRoundSize),
|
|
102
|
+
governanceVotingDuration: DefaultL1ContractsConfig.governanceVotingDuration,
|
|
102
103
|
activationThreshold,
|
|
103
104
|
ejectionThreshold,
|
|
104
105
|
localEjectionThreshold,
|
|
@@ -118,5 +119,6 @@ export async function getL1ContractsConfig(
|
|
|
118
119
|
slashAmountSmall: slashingAmounts[0],
|
|
119
120
|
slashAmountMedium: slashingAmounts[1],
|
|
120
121
|
slashAmountLarge: slashingAmounts[2],
|
|
122
|
+
initialEthPerFeeAsset: DefaultL1ContractsConfig.initialEthPerFeeAsset,
|
|
121
123
|
};
|
|
122
124
|
}
|
|
@@ -56,6 +56,15 @@ export class RollupCheatCodes {
|
|
|
56
56
|
return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([ts]));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/** Returns the number of seconds until the start of the given slot based on L1 block timestamp. */
|
|
60
|
+
public async getSecondsUntilSlot(slot: SlotNumber): Promise<number> {
|
|
61
|
+
const [currentTimestamp, targetTimestamp] = await Promise.all([
|
|
62
|
+
this.client.getBlock().then(b => BigInt(b.timestamp)),
|
|
63
|
+
this.rollup.read.getTimestampForSlot([BigInt(slot)]),
|
|
64
|
+
]);
|
|
65
|
+
return Math.max(0, Number(targetTimestamp - currentTimestamp));
|
|
66
|
+
}
|
|
67
|
+
|
|
59
68
|
/** Returns the current epoch */
|
|
60
69
|
public async getEpoch(): Promise<EpochNumber> {
|
|
61
70
|
const slotNumber = await this.getSlot();
|
|
@@ -124,7 +133,7 @@ export class RollupCheatCodes {
|
|
|
124
133
|
} = {},
|
|
125
134
|
) {
|
|
126
135
|
const { epochDuration: slotsInEpoch } = await this.getConfig();
|
|
127
|
-
const slotNumber = SlotNumber(epoch * Number(slotsInEpoch));
|
|
136
|
+
const slotNumber = SlotNumber(Number(epoch) * Number(slotsInEpoch));
|
|
128
137
|
const timestamp = (await this.rollup.read.getTimestampForSlot([BigInt(slotNumber)])) + BigInt(opts.offset ?? 0);
|
|
129
138
|
try {
|
|
130
139
|
await this.ethCheatCodes.warp(Number(timestamp), { ...opts, silent: true, resetBlockInterval: true });
|
|
@@ -176,7 +185,7 @@ export class RollupCheatCodes {
|
|
|
176
185
|
* Marks the specified checkpoint (or latest if none) as proven
|
|
177
186
|
* @param maybeCheckpointNumber - The checkpoint number to mark as proven (defaults to latest pending)
|
|
178
187
|
*/
|
|
179
|
-
public markAsProven(maybeCheckpointNumber?:
|
|
188
|
+
public markAsProven(maybeCheckpointNumber?: CheckpointNumber) {
|
|
180
189
|
return this.ethCheatCodes.execWithPausedAnvil(async () => {
|
|
181
190
|
const tipsBefore = await this.getTips();
|
|
182
191
|
const { pending, proven } = tipsBefore;
|
package/src/test/start_anvil.ts
CHANGED
|
@@ -33,7 +33,7 @@ export async function startAnvil(
|
|
|
33
33
|
const anvil = createAnvil({
|
|
34
34
|
anvilBinary,
|
|
35
35
|
host: '127.0.0.1',
|
|
36
|
-
port: opts.port ?? 8545,
|
|
36
|
+
port: opts.port ?? (process.env.ANVIL_PORT ? parseInt(process.env.ANVIL_PORT) : 8545),
|
|
37
37
|
blockTime: opts.l1BlockTime,
|
|
38
38
|
stopTimeout: 1000,
|
|
39
39
|
accounts: opts.accounts ?? 20,
|
package/src/utils.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { ErrorsAbi } from '@aztec/l1-artifacts/ErrorsAbi';
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
type Abi,
|
|
7
|
+
type AbiItem,
|
|
7
8
|
BaseError,
|
|
8
9
|
type ContractEventName,
|
|
9
10
|
ContractFunctionRevertedError,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
decodeErrorResult,
|
|
15
16
|
decodeEventLog,
|
|
16
17
|
} from 'viem';
|
|
18
|
+
import { formatAbiItem, formatAbiParams } from 'viem/utils';
|
|
17
19
|
|
|
18
20
|
export interface L2Claim {
|
|
19
21
|
claimSecret: Fr;
|
|
@@ -93,6 +95,57 @@ export function prettyLogViemErrorMsg(err: any) {
|
|
|
93
95
|
return err?.message ?? err;
|
|
94
96
|
}
|
|
95
97
|
|
|
98
|
+
export function mergeAbis(abis: Abi[]): Abi {
|
|
99
|
+
let merged: Abi = [];
|
|
100
|
+
const seen = new Set<string>();
|
|
101
|
+
|
|
102
|
+
for (const abi of abis) {
|
|
103
|
+
for (const item of abi) {
|
|
104
|
+
const key = getAbiItemKey(item);
|
|
105
|
+
if (!seen.has(key)) {
|
|
106
|
+
seen.add(key);
|
|
107
|
+
merged = [...merged, item];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return merged;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function getAbiItemKey(item: AbiItem): string {
|
|
116
|
+
if (item.type === 'function') {
|
|
117
|
+
const signature = formatAbiItem(item);
|
|
118
|
+
const outputs = formatAbiParams(item.outputs);
|
|
119
|
+
const stateMutability = typeof item.stateMutability === 'string' ? item.stateMutability : '';
|
|
120
|
+
return `function:${signature}:${outputs}:${stateMutability}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (item.type === 'event') {
|
|
124
|
+
const signature = formatAbiItem(item);
|
|
125
|
+
const indexed = (item.inputs ?? []).map(input => ((input as { indexed?: boolean }).indexed ? '1' : '0')).join('');
|
|
126
|
+
const anonymous = item.anonymous ? 'anonymous' : 'not-anonymous';
|
|
127
|
+
return `event:${signature}:${indexed}:${anonymous}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (item.type === 'error') {
|
|
131
|
+
const signature = formatAbiItem(item);
|
|
132
|
+
return `error:${signature}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (item.type === 'constructor') {
|
|
136
|
+
const inputs = formatAbiParams(item.inputs);
|
|
137
|
+
const stateMutability = typeof item.stateMutability === 'string' ? item.stateMutability : '';
|
|
138
|
+
return `constructor::${inputs}:${stateMutability}`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (item.type === 'fallback' || item.type === 'receive') {
|
|
142
|
+
const stateMutability = typeof item.stateMutability === 'string' ? item.stateMutability : '';
|
|
143
|
+
return `${item.type}:::${stateMutability}`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return 'unknown';
|
|
147
|
+
}
|
|
148
|
+
|
|
96
149
|
function getNestedErrorData(error: unknown): string | undefined {
|
|
97
150
|
// If nothing, bail
|
|
98
151
|
if (!error) {
|