@aztec/end-to-end 0.0.1-commit.f504929 → 0.0.1-commit.f650c0a5c
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/README.md +27 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +21 -29
- package/dest/e2e_epochs/epochs_test.d.ts +3 -1
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +8 -5
- package/dest/e2e_fees/fees_test.d.ts +1 -1
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +9 -2
- package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
- package/dest/e2e_p2p/p2p_network.d.ts +6 -8
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +9 -13
- package/dest/e2e_p2p/reqresp/utils.d.ts +1 -1
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/reqresp/utils.js +16 -3
- package/dest/e2e_p2p/shared.d.ts +16 -12
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +33 -51
- package/dest/fixtures/authwit_proxy.d.ts +1 -1
- package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
- package/dest/fixtures/authwit_proxy.js +4 -0
- package/dest/fixtures/e2e_prover_test.d.ts +4 -3
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +7 -12
- package/dest/fixtures/get_bb_config.d.ts +1 -1
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +5 -5
- package/dest/fixtures/setup.d.ts +10 -4
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +20 -15
- package/dest/fixtures/setup_p2p_test.d.ts +6 -6
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +8 -8
- package/dest/fixtures/token_utils.d.ts +1 -1
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +2 -5
- package/dest/legacy-jest-resolver.d.cts +3 -0
- package/dest/legacy-jest-resolver.d.cts.map +1 -0
- package/dest/shared/uniswap_l1_l2.d.ts +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +9 -12
- package/dest/simulators/lending_simulator.d.ts +1 -1
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +2 -2
- package/dest/simulators/token_simulator.js +1 -1
- package/dest/spartan/setup_test_wallets.d.ts +4 -2
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +70 -40
- package/dest/spartan/utils/config.d.ts +4 -1
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/config.js +1 -0
- package/dest/spartan/utils/index.d.ts +2 -1
- package/dest/spartan/utils/index.d.ts.map +1 -1
- package/dest/spartan/utils/index.js +2 -0
- package/dest/spartan/utils/pod_logs.d.ts +25 -0
- package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
- package/dest/spartan/utils/pod_logs.js +74 -0
- package/dest/test-wallet/test_wallet.d.ts +15 -23
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +72 -64
- package/dest/test-wallet/worker_wallet_schema.d.ts +2 -2
- package/package.json +40 -40
- package/src/bench/client_flows/client_flows_benchmark.ts +35 -23
- package/src/e2e_epochs/epochs_test.ts +17 -5
- package/src/e2e_fees/fees_test.ts +5 -2
- package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
- package/src/e2e_p2p/p2p_network.ts +17 -24
- package/src/e2e_p2p/reqresp/utils.ts +24 -3
- package/src/e2e_p2p/shared.ts +36 -67
- package/src/fixtures/authwit_proxy.ts +4 -0
- package/src/fixtures/e2e_prover_test.ts +12 -17
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/setup.ts +29 -21
- package/src/fixtures/setup_p2p_test.ts +9 -9
- package/src/fixtures/token_utils.ts +1 -4
- package/src/legacy-jest-resolver.cjs +135 -0
- package/src/shared/uniswap_l1_l2.ts +29 -24
- package/src/simulators/lending_simulator.ts +4 -2
- package/src/simulators/token_simulator.ts +1 -1
- package/src/spartan/setup_test_wallets.ts +97 -35
- package/src/spartan/utils/config.ts +1 -0
- package/src/spartan/utils/index.ts +3 -0
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/test-wallet/test_wallet.ts +99 -79
|
@@ -3,12 +3,7 @@ import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
|
|
|
3
3
|
import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
|
|
4
4
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
5
5
|
import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
6
|
-
import {
|
|
7
|
-
type EmpireSlashingProposerContract,
|
|
8
|
-
GSEContract,
|
|
9
|
-
RollupContract,
|
|
10
|
-
type TallySlashingProposerContract,
|
|
11
|
-
} from '@aztec/ethereum/contracts';
|
|
6
|
+
import { GSEContract, RollupContract, type SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
12
7
|
import type { Operator } from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
13
8
|
import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
|
|
14
9
|
import { MultiAdderArtifact } from '@aztec/ethereum/l1-artifacts';
|
|
@@ -24,9 +19,8 @@ import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
|
|
|
24
19
|
import type { BootstrapNode } from '@aztec/p2p/bootstrap';
|
|
25
20
|
import { createBootstrapNodeFromPrivateKey, getBootstrapNodeEnr } from '@aztec/p2p/test-helpers';
|
|
26
21
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
27
|
-
import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
28
22
|
import { TopicType } from '@aztec/stdlib/p2p';
|
|
29
|
-
import type {
|
|
23
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
30
24
|
import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
|
|
31
25
|
import { getGenesisValues } from '@aztec/world-state/testing';
|
|
32
26
|
|
|
@@ -59,7 +53,7 @@ export const WAIT_FOR_TX_TIMEOUT = l1ContractsConfig.aztecSlotDuration * 3;
|
|
|
59
53
|
export const SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES = {
|
|
60
54
|
aztecSlotDuration: 12,
|
|
61
55
|
ethereumSlotDuration: 4,
|
|
62
|
-
|
|
56
|
+
aztecProofSubmissionEpochs: 640,
|
|
63
57
|
};
|
|
64
58
|
|
|
65
59
|
export class P2PNetworkTest {
|
|
@@ -77,7 +71,7 @@ export class P2PNetworkTest {
|
|
|
77
71
|
public validators: Operator[] = [];
|
|
78
72
|
|
|
79
73
|
public deployedAccounts: InitialAccountData[] = [];
|
|
80
|
-
public
|
|
74
|
+
public genesis: GenesisData | undefined;
|
|
81
75
|
|
|
82
76
|
// The re-execution test needs a wallet and a spam contract
|
|
83
77
|
public wallet?: TestWallet;
|
|
@@ -124,7 +118,7 @@ export class P2PNetworkTest {
|
|
|
124
118
|
initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
|
|
125
119
|
slashingRoundSizeInEpochs:
|
|
126
120
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
127
|
-
|
|
121
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
128
122
|
aztecTargetCommitteeSize: numberOfValidators,
|
|
129
123
|
metricsPort: metricsPort,
|
|
130
124
|
numberOfInitialFundedAccounts: 2,
|
|
@@ -137,7 +131,7 @@ export class P2PNetworkTest {
|
|
|
137
131
|
aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
|
|
138
132
|
slashingRoundSizeInEpochs:
|
|
139
133
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
140
|
-
|
|
134
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
141
135
|
|
|
142
136
|
ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
|
|
143
137
|
aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
|
|
@@ -360,7 +354,7 @@ export class P2PNetworkTest {
|
|
|
360
354
|
...this.setupOptions,
|
|
361
355
|
fundSponsoredFPC: true,
|
|
362
356
|
skipAccountDeployment: true,
|
|
363
|
-
|
|
357
|
+
slasherEnabled: this.setupOptions.slasherEnabled ?? this.deployL1ContractsArgs.slasherEnabled ?? false,
|
|
364
358
|
aztecTargetCommitteeSize: 0,
|
|
365
359
|
l1ContractsArgs: this.deployL1ContractsArgs,
|
|
366
360
|
},
|
|
@@ -372,8 +366,13 @@ export class P2PNetworkTest {
|
|
|
372
366
|
const sponsoredFPCAddress = await getSponsoredFPCAddress();
|
|
373
367
|
const initialFundedAccounts = [...this.context.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
|
|
374
368
|
|
|
375
|
-
const {
|
|
376
|
-
|
|
369
|
+
const { genesis } = await getGenesisValues(
|
|
370
|
+
initialFundedAccounts,
|
|
371
|
+
undefined,
|
|
372
|
+
undefined,
|
|
373
|
+
this.context.genesis!.genesisTimestamp,
|
|
374
|
+
);
|
|
375
|
+
this.genesis = genesis;
|
|
377
376
|
|
|
378
377
|
const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
|
|
379
378
|
this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider).start();
|
|
@@ -468,8 +467,7 @@ export class P2PNetworkTest {
|
|
|
468
467
|
async getContracts(): Promise<{
|
|
469
468
|
rollup: RollupContract;
|
|
470
469
|
slasherContract: GetContractReturnType<typeof SlasherAbi, ViemClient>;
|
|
471
|
-
slashingProposer:
|
|
472
|
-
slashFactory: SlashFactoryContract;
|
|
470
|
+
slashingProposer: SlashingProposerContract | undefined;
|
|
473
471
|
}> {
|
|
474
472
|
if (!this.ctx.deployL1ContractsValues) {
|
|
475
473
|
throw new Error('DeployAztecL1ContractsValues not set');
|
|
@@ -486,14 +484,9 @@ export class P2PNetworkTest {
|
|
|
486
484
|
client: this.ctx.deployL1ContractsValues.l1Client,
|
|
487
485
|
});
|
|
488
486
|
|
|
489
|
-
// Get the actual slashing proposer from rollup
|
|
487
|
+
// Get the actual slashing proposer from rollup
|
|
490
488
|
const slashingProposer = await rollup.getSlashingProposer();
|
|
491
489
|
|
|
492
|
-
|
|
493
|
-
this.ctx.deployL1ContractsValues.l1Client,
|
|
494
|
-
getAddress(this.ctx.deployL1ContractsValues.l1ContractAddresses.slashFactoryAddress!.toString()),
|
|
495
|
-
);
|
|
496
|
-
|
|
497
|
-
return { rollup, slasherContract, slashingProposer, slashFactory };
|
|
490
|
+
return { rollup, slasherContract, slashingProposer };
|
|
498
491
|
}
|
|
499
492
|
}
|
|
@@ -91,7 +91,7 @@ export async function runReqrespTxTest(params: {
|
|
|
91
91
|
t.bootstrapNodeEnr,
|
|
92
92
|
NUM_VALIDATORS,
|
|
93
93
|
BOOT_NODE_UDP_PORT,
|
|
94
|
-
t.
|
|
94
|
+
t.genesis,
|
|
95
95
|
dataDir,
|
|
96
96
|
shouldCollectMetrics(),
|
|
97
97
|
);
|
|
@@ -149,6 +149,13 @@ export async function runReqrespTxTest(params: {
|
|
|
149
149
|
const submittedTxs = await Promise.all(
|
|
150
150
|
txBatches.map(async (batch, batchIndex) => {
|
|
151
151
|
const proposerNode = nodes[proposerIndexes[batchIndex]];
|
|
152
|
+
for (const tx of batch) {
|
|
153
|
+
t.logger.info(`Tx ${tx.getTxHash().toString()} base64: ${tx.toBuffer().toString('base64')}`);
|
|
154
|
+
}
|
|
155
|
+
const txHashes = batch.map(tx => tx.getTxHash().toString());
|
|
156
|
+
t.logger.info(
|
|
157
|
+
`Sending batch ${batchIndex} to proposer ${getNodePort(proposerIndexes[batchIndex])}: ${txHashes.join(', ')}`,
|
|
158
|
+
);
|
|
152
159
|
await Promise.all(
|
|
153
160
|
batch.map(async tx => {
|
|
154
161
|
try {
|
|
@@ -163,6 +170,12 @@ export async function runReqrespTxTest(params: {
|
|
|
163
170
|
}),
|
|
164
171
|
);
|
|
165
172
|
|
|
173
|
+
// Log pool state per node after sending
|
|
174
|
+
for (let i = 0; i < NUM_VALIDATORS; i++) {
|
|
175
|
+
const count = await nodes[i].getPendingTxCount();
|
|
176
|
+
t.logger.info(`Node ${getNodePort(i)} pool has ${count} pending txs`);
|
|
177
|
+
}
|
|
178
|
+
|
|
166
179
|
t.logger.info('Waiting for all transactions to be mined');
|
|
167
180
|
await Promise.all(
|
|
168
181
|
submittedTxs.flatMap((batch, batchIndex) =>
|
|
@@ -178,8 +191,16 @@ export async function runReqrespTxTest(params: {
|
|
|
178
191
|
|
|
179
192
|
// Assert that multiple blocks were built for at least one slot
|
|
180
193
|
t.logger.info('Verifying multiple blocks for at least one checkpoint');
|
|
181
|
-
|
|
182
|
-
|
|
194
|
+
// Wait for L1 checkpoint sync, which may lag behind P2P block propagation.
|
|
195
|
+
const checkpoints = await retryUntil(
|
|
196
|
+
async () => {
|
|
197
|
+
const cps = await nodes[0].getCheckpoints(CheckpointNumber(1), 50);
|
|
198
|
+
return cps.length > 0 && cps.some(cp => cp.checkpoint.blocks.length >= 2) ? cps : undefined;
|
|
199
|
+
},
|
|
200
|
+
'waiting for multi-block checkpoint to sync from L1',
|
|
201
|
+
30,
|
|
202
|
+
1,
|
|
203
|
+
);
|
|
183
204
|
|
|
184
205
|
let mbpsFound = false;
|
|
185
206
|
let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
|
package/src/e2e_p2p/shared.ts
CHANGED
|
@@ -7,11 +7,7 @@ import type { Logger } from '@aztec/aztec.js/log';
|
|
|
7
7
|
import { TxHash } from '@aztec/aztec.js/tx';
|
|
8
8
|
import type { RollupCheatCodes } from '@aztec/aztec/testing';
|
|
9
9
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
10
|
-
import type {
|
|
11
|
-
EmpireSlashingProposerContract,
|
|
12
|
-
RollupContract,
|
|
13
|
-
TallySlashingProposerContract,
|
|
14
|
-
} from '@aztec/ethereum/contracts';
|
|
10
|
+
import type { RollupContract, SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
15
11
|
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
16
12
|
import { timesAsync, unique } from '@aztec/foundation/collection';
|
|
17
13
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -22,7 +18,6 @@ import { TestContract, TestContractArtifact } from '@aztec/noir-test-contracts.j
|
|
|
22
18
|
import { getPXEConfig, getPXEConfig as getRpcConfig } from '@aztec/pxe/server';
|
|
23
19
|
import { getRoundForOffense } from '@aztec/slasher';
|
|
24
20
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
25
|
-
import type { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
26
21
|
|
|
27
22
|
import { submitTxsTo } from '../shared/submit-transactions.js';
|
|
28
23
|
import { TestWallet } from '../test-wallet/test_wallet.js';
|
|
@@ -99,7 +94,7 @@ export async function prepareTransactions(
|
|
|
99
94
|
}
|
|
100
95
|
|
|
101
96
|
export function awaitProposalExecution(
|
|
102
|
-
slashingProposer:
|
|
97
|
+
slashingProposer: SlashingProposerContract,
|
|
103
98
|
timeoutSeconds: number,
|
|
104
99
|
logger: Logger,
|
|
105
100
|
): Promise<bigint> {
|
|
@@ -109,24 +104,12 @@ export function awaitProposalExecution(
|
|
|
109
104
|
reject(new Error(`Timeout waiting for proposal execution after ${timeoutSeconds}s`));
|
|
110
105
|
}, timeoutSeconds * 1000);
|
|
111
106
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
logger.warn(`Proposal ${args.payload} from round ${args.round} executed`);
|
|
115
|
-
clearTimeout(timeout);
|
|
116
|
-
unwatch();
|
|
117
|
-
resolve(args.round);
|
|
118
|
-
});
|
|
119
|
-
} else if (slashingProposer.type === 'tally') {
|
|
120
|
-
const unwatch = slashingProposer.listenToRoundExecuted(args => {
|
|
121
|
-
logger.warn(`Slash from round ${args.round} executed`);
|
|
122
|
-
clearTimeout(timeout);
|
|
123
|
-
unwatch();
|
|
124
|
-
resolve(args.round);
|
|
125
|
-
});
|
|
126
|
-
} else {
|
|
107
|
+
const unwatch = slashingProposer.listenToRoundExecuted(args => {
|
|
108
|
+
logger.warn(`Slash from round ${args.round} executed`);
|
|
127
109
|
clearTimeout(timeout);
|
|
128
|
-
|
|
129
|
-
|
|
110
|
+
unwatch();
|
|
111
|
+
resolve(args.round);
|
|
112
|
+
});
|
|
130
113
|
});
|
|
131
114
|
}
|
|
132
115
|
|
|
@@ -152,11 +135,14 @@ export async function awaitCommitteeExists({
|
|
|
152
135
|
}
|
|
153
136
|
|
|
154
137
|
/**
|
|
155
|
-
* Advance epochs until we find one where the target proposer is selected for at least one slot
|
|
156
|
-
*
|
|
157
|
-
*
|
|
138
|
+
* Advance epochs until we find one where the target proposer is selected for at least one slot,
|
|
139
|
+
* then stop one epoch before it. This leaves time for the caller to start sequencers before
|
|
140
|
+
* warping to the target epoch, avoiding the race where the target epoch passes before sequencers
|
|
141
|
+
* are ready.
|
|
142
|
+
*
|
|
143
|
+
* Returns the target epoch number so the caller can warp to it after starting sequencers.
|
|
158
144
|
*/
|
|
159
|
-
export async function
|
|
145
|
+
export async function advanceToEpochBeforeProposer({
|
|
160
146
|
epochCache,
|
|
161
147
|
cheatCodes,
|
|
162
148
|
targetProposer,
|
|
@@ -168,25 +154,32 @@ export async function awaitEpochWithProposer({
|
|
|
168
154
|
targetProposer: EthAddress;
|
|
169
155
|
logger: Logger;
|
|
170
156
|
maxAttempts?: number;
|
|
171
|
-
}): Promise<
|
|
157
|
+
}): Promise<{ targetEpoch: EpochNumber }> {
|
|
172
158
|
const { epochDuration } = await cheatCodes.getConfig();
|
|
173
159
|
|
|
174
160
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
175
161
|
const currentEpoch = await cheatCodes.getEpoch();
|
|
176
|
-
|
|
162
|
+
// Check the NEXT epoch's slots so we stay one epoch before the target,
|
|
163
|
+
// giving the caller time to start sequencers before the target epoch arrives.
|
|
164
|
+
const nextEpoch = Number(currentEpoch) + 1;
|
|
165
|
+
const startSlot = nextEpoch * Number(epochDuration);
|
|
177
166
|
const endSlot = startSlot + Number(epochDuration);
|
|
178
167
|
|
|
179
|
-
logger.info(
|
|
168
|
+
logger.info(
|
|
169
|
+
`Checking next epoch ${nextEpoch} (slots ${startSlot}-${endSlot - 1}) for proposer ${targetProposer} (current epoch: ${currentEpoch})`,
|
|
170
|
+
);
|
|
180
171
|
|
|
181
172
|
for (let s = startSlot; s < endSlot; s++) {
|
|
182
173
|
const proposer = await epochCache.getProposerAttesterAddressInSlot(SlotNumber(s));
|
|
183
174
|
if (proposer && proposer.equals(targetProposer)) {
|
|
184
|
-
logger.warn(
|
|
185
|
-
|
|
175
|
+
logger.warn(
|
|
176
|
+
`Found target proposer ${targetProposer} in slot ${s} of epoch ${nextEpoch}. Staying at epoch ${currentEpoch} to allow sequencer startup.`,
|
|
177
|
+
);
|
|
178
|
+
return { targetEpoch: EpochNumber(nextEpoch) };
|
|
186
179
|
}
|
|
187
180
|
}
|
|
188
181
|
|
|
189
|
-
logger.info(`Target proposer not found in epoch ${
|
|
182
|
+
logger.info(`Target proposer not found in epoch ${nextEpoch}, advancing to next epoch`);
|
|
190
183
|
await cheatCodes.advanceToNextEpoch();
|
|
191
184
|
}
|
|
192
185
|
|
|
@@ -235,7 +228,6 @@ export async function awaitCommitteeKicked({
|
|
|
235
228
|
rollup,
|
|
236
229
|
cheatCodes,
|
|
237
230
|
committee,
|
|
238
|
-
slashFactory,
|
|
239
231
|
slashingProposer,
|
|
240
232
|
slashingRoundSize,
|
|
241
233
|
aztecSlotDuration,
|
|
@@ -246,8 +238,7 @@ export async function awaitCommitteeKicked({
|
|
|
246
238
|
rollup: RollupContract;
|
|
247
239
|
cheatCodes: RollupCheatCodes;
|
|
248
240
|
committee: readonly `0x${string}`[];
|
|
249
|
-
|
|
250
|
-
slashingProposer: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
|
|
241
|
+
slashingProposer: SlashingProposerContract | undefined;
|
|
251
242
|
slashingRoundSize: number;
|
|
252
243
|
aztecSlotDuration: number;
|
|
253
244
|
aztecEpochDuration: number;
|
|
@@ -260,36 +251,14 @@ export async function awaitCommitteeKicked({
|
|
|
260
251
|
|
|
261
252
|
await cheatCodes.debugRollup();
|
|
262
253
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const events = await slashFactory.getSlashPayloadCreatedEvents();
|
|
272
|
-
return events.length > 0 ? events : undefined;
|
|
273
|
-
},
|
|
274
|
-
'slash payload created',
|
|
275
|
-
120,
|
|
276
|
-
1,
|
|
277
|
-
);
|
|
278
|
-
expect(slashPayloadEvents.length).toBe(1);
|
|
279
|
-
// The uniqueness check is needed since a validator may be slashed more than once on the same round (eg because they let two epochs be pruned)
|
|
280
|
-
expect(unique(slashPayloadEvents[0].slashes.map(slash => slash.validator.toString()))).toHaveLength(
|
|
281
|
-
committee.length,
|
|
282
|
-
);
|
|
283
|
-
} else {
|
|
284
|
-
// Use the slash offset to ensure we are in the right epoch for tally
|
|
285
|
-
const slashOffsetInRounds = await slashingProposer.getSlashOffsetInRounds();
|
|
286
|
-
const slashingRoundSizeInEpochs = slashingRoundSize / aztecEpochDuration;
|
|
287
|
-
const slashingOffsetInEpochs = Number(slashOffsetInRounds) * slashingRoundSizeInEpochs;
|
|
288
|
-
const firstEpochInOffenseRound = offenseEpoch - (offenseEpoch % slashingRoundSizeInEpochs);
|
|
289
|
-
const targetEpoch = firstEpochInOffenseRound + slashingOffsetInEpochs;
|
|
290
|
-
logger.info(`Advancing to epoch ${targetEpoch} so we start slashing`);
|
|
291
|
-
await cheatCodes.advanceToEpoch(EpochNumber(targetEpoch), { offset: -aztecSlotDuration / 2 });
|
|
292
|
-
}
|
|
254
|
+
// Use the slash offset to ensure we are in the right epoch for tally
|
|
255
|
+
const slashOffsetInRounds = await slashingProposer.getSlashOffsetInRounds();
|
|
256
|
+
const slashingRoundSizeInEpochs = slashingRoundSize / aztecEpochDuration;
|
|
257
|
+
const slashingOffsetInEpochs = Number(slashOffsetInRounds) * slashingRoundSizeInEpochs;
|
|
258
|
+
const firstEpochInOffenseRound = offenseEpoch - (offenseEpoch % slashingRoundSizeInEpochs);
|
|
259
|
+
const targetEpoch = firstEpochInOffenseRound + slashingOffsetInEpochs;
|
|
260
|
+
logger.info(`Advancing to epoch ${targetEpoch} so we start slashing`);
|
|
261
|
+
await cheatCodes.advanceToEpoch(EpochNumber(targetEpoch), { offset: -aztecSlotDuration / 2 });
|
|
293
262
|
|
|
294
263
|
const attestersPre = await rollup.getAttesters();
|
|
295
264
|
expect(attestersPre.length).toBe(committee.length);
|
|
@@ -17,6 +17,10 @@ async function buildProxyCall(proxy: GenericProxyContract, action: ContractFunct
|
|
|
17
17
|
return proxy.methods.forward_private_3(call.to, call.selector, call.args);
|
|
18
18
|
} else if (argCount === 4) {
|
|
19
19
|
return proxy.methods.forward_private_4(call.to, call.selector, call.args);
|
|
20
|
+
} else if (argCount === 5) {
|
|
21
|
+
return proxy.methods.forward_private_5(call.to, call.selector, call.args);
|
|
22
|
+
} else if (argCount === 6) {
|
|
23
|
+
return proxy.methods.forward_private_6(call.to, call.selector, call.args);
|
|
20
24
|
}
|
|
21
25
|
throw new Error(`No forward_private_${argCount} method on proxy`);
|
|
22
26
|
}
|
|
@@ -4,12 +4,7 @@ import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
|
|
|
4
4
|
import { type Logger, createLogger } from '@aztec/aztec.js/log';
|
|
5
5
|
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
6
6
|
import { CheatCodes } from '@aztec/aztec/testing';
|
|
7
|
-
import {
|
|
8
|
-
BBCircuitVerifier,
|
|
9
|
-
type ClientProtocolCircuitVerifier,
|
|
10
|
-
QueuedIVCVerifier,
|
|
11
|
-
TestCircuitVerifier,
|
|
12
|
-
} from '@aztec/bb-prover';
|
|
7
|
+
import type { ClientProtocolCircuitVerifier } from '@aztec/bb-prover';
|
|
13
8
|
import { BackendType, Barretenberg } from '@aztec/bb.js';
|
|
14
9
|
import type { DeployAztecL1ContractsReturnType } from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
15
10
|
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
@@ -68,7 +63,10 @@ export class FullProverTest {
|
|
|
68
63
|
private provenComponents: ProvenSetup[] = [];
|
|
69
64
|
private bbConfigCleanup?: () => Promise<void>;
|
|
70
65
|
private acvmConfigCleanup?: () => Promise<void>;
|
|
71
|
-
|
|
66
|
+
/** Returns the proof verifier from the prover node (for test assertions). */
|
|
67
|
+
get circuitProofVerifier(): ClientProtocolCircuitVerifier | undefined {
|
|
68
|
+
return this.proverAztecNode?.getProofVerifier();
|
|
69
|
+
}
|
|
72
70
|
provenAsset!: TokenContract;
|
|
73
71
|
context!: EndToEndContext;
|
|
74
72
|
private proverAztecNode!: AztecNodeService;
|
|
@@ -106,15 +104,13 @@ export class FullProverTest {
|
|
|
106
104
|
await publicDeployAccounts(this.wallet, this.accounts.slice(0, 2));
|
|
107
105
|
|
|
108
106
|
this.logger.info('Applying base setup: deploying token contract');
|
|
109
|
-
const {
|
|
110
|
-
receipt: { contract: asset, instance },
|
|
111
|
-
} = await TokenContract.deploy(
|
|
107
|
+
const { contract: asset, instance } = await TokenContract.deploy(
|
|
112
108
|
this.wallet,
|
|
113
109
|
this.accounts[0],
|
|
114
110
|
FullProverTest.TOKEN_NAME,
|
|
115
111
|
FullProverTest.TOKEN_SYMBOL,
|
|
116
112
|
FullProverTest.TOKEN_DECIMALS,
|
|
117
|
-
).send({ from: this.accounts[0]
|
|
113
|
+
).send({ from: this.accounts[0] });
|
|
118
114
|
this.logger.verbose(`Token deployed to ${asset.address}`);
|
|
119
115
|
|
|
120
116
|
this.fakeProofsAsset = asset;
|
|
@@ -170,9 +166,6 @@ export class FullProverTest {
|
|
|
170
166
|
|
|
171
167
|
await Barretenberg.initSingleton({ backend: BackendType.NativeUnixSocket });
|
|
172
168
|
|
|
173
|
-
const verifier = await BBCircuitVerifier.new(bbConfig);
|
|
174
|
-
this.circuitProofVerifier = new QueuedIVCVerifier(bbConfig, verifier);
|
|
175
|
-
|
|
176
169
|
this.logger.debug(`Configuring the node for real proofs...`);
|
|
177
170
|
await this.aztecNodeAdmin.setConfig({
|
|
178
171
|
realProofs: true,
|
|
@@ -180,7 +173,6 @@ export class FullProverTest {
|
|
|
180
173
|
});
|
|
181
174
|
} else {
|
|
182
175
|
this.logger.debug(`Configuring the node min txs per block ${this.minNumberOfTxsPerBlock}...`);
|
|
183
|
-
this.circuitProofVerifier = new TestCircuitVerifier();
|
|
184
176
|
await this.aztecNodeAdmin.setConfig({
|
|
185
177
|
minTxsPerBlock: this.minNumberOfTxsPerBlock,
|
|
186
178
|
});
|
|
@@ -231,8 +223,11 @@ export class FullProverTest {
|
|
|
231
223
|
|
|
232
224
|
this.logger.verbose('Starting prover node');
|
|
233
225
|
const sponsoredFPCAddress = await getSponsoredFPCAddress();
|
|
234
|
-
const {
|
|
226
|
+
const { genesis } = await getGenesisValues(
|
|
235
227
|
this.context.initialFundedAccounts.map(a => a.address).concat(sponsoredFPCAddress),
|
|
228
|
+
undefined,
|
|
229
|
+
undefined,
|
|
230
|
+
this.context.genesis!.genesisTimestamp,
|
|
236
231
|
);
|
|
237
232
|
|
|
238
233
|
const proverNodeConfig: Parameters<typeof AztecNodeService.createAndSync>[0] = {
|
|
@@ -260,7 +255,7 @@ export class FullProverTest {
|
|
|
260
255
|
this.proverAztecNode = await AztecNodeService.createAndSync(
|
|
261
256
|
proverNodeConfig,
|
|
262
257
|
{ dateProvider: this.context.dateProvider, p2pClientDeps: { rpcTxProviders: [this.aztecNode] } },
|
|
263
|
-
{
|
|
258
|
+
{ genesis },
|
|
264
259
|
);
|
|
265
260
|
this.logger.warn(`Proofs are now enabled`, { realProofs: this.realProofs });
|
|
266
261
|
return this;
|
|
@@ -13,8 +13,10 @@ const {
|
|
|
13
13
|
BB_SKIP_CLEANUP = '',
|
|
14
14
|
TEMP_DIR = tmpdir(),
|
|
15
15
|
BB_WORKING_DIRECTORY = '',
|
|
16
|
-
BB_NUM_IVC_VERIFIERS = '
|
|
16
|
+
BB_NUM_IVC_VERIFIERS = '8',
|
|
17
17
|
BB_IVC_CONCURRENCY = '1',
|
|
18
|
+
BB_CHONK_VERIFY_MAX_BATCH = '16',
|
|
19
|
+
BB_CHONK_VERIFY_BATCH_CONCURRENCY = '6',
|
|
18
20
|
} = process.env;
|
|
19
21
|
|
|
20
22
|
export const getBBConfig = async (
|
|
@@ -41,16 +43,15 @@ export const getBBConfig = async (
|
|
|
41
43
|
const bbSkipCleanup = ['1', 'true'].includes(BB_SKIP_CLEANUP);
|
|
42
44
|
const cleanup = bbSkipCleanup ? () => Promise.resolve() : () => tryRmDir(directoryToCleanup);
|
|
43
45
|
|
|
44
|
-
const numIvcVerifiers = Number(BB_NUM_IVC_VERIFIERS);
|
|
45
|
-
const ivcConcurrency = Number(BB_IVC_CONCURRENCY);
|
|
46
|
-
|
|
47
46
|
return {
|
|
48
47
|
bbSkipCleanup,
|
|
49
48
|
bbBinaryPath,
|
|
50
49
|
bbWorkingDirectory,
|
|
51
50
|
cleanup,
|
|
52
|
-
numConcurrentIVCVerifiers:
|
|
53
|
-
bbIVCConcurrency:
|
|
51
|
+
numConcurrentIVCVerifiers: Number(BB_NUM_IVC_VERIFIERS),
|
|
52
|
+
bbIVCConcurrency: Number(BB_IVC_CONCURRENCY),
|
|
53
|
+
bbChonkVerifyMaxBatch: Number(BB_CHONK_VERIFY_MAX_BATCH),
|
|
54
|
+
bbChonkVerifyConcurrency: Number(BB_CHONK_VERIFY_BATCH_CONCURRENCY),
|
|
54
55
|
};
|
|
55
56
|
} catch (err) {
|
|
56
57
|
logger.error(`Native BB not available, error: ${err}`);
|
package/src/fixtures/setup.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SchnorrAccountContractArtifact } from '@aztec/accounts/schnorr';
|
|
2
2
|
import { type InitialAccountData, generateSchnorrAccounts } from '@aztec/accounts/testing';
|
|
3
3
|
import { type AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node';
|
|
4
|
+
import { NO_FROM } from '@aztec/aztec.js/account';
|
|
4
5
|
import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
|
|
5
6
|
import {
|
|
6
7
|
BatchCall,
|
|
@@ -51,6 +52,7 @@ import { type ContractInstanceWithAddress, getContractInstanceFromInstantiationP
|
|
|
51
52
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
52
53
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
53
54
|
import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
|
|
55
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
54
56
|
import {
|
|
55
57
|
type TelemetryClient,
|
|
56
58
|
type TelemetryClientConfig,
|
|
@@ -185,6 +187,11 @@ export type SetupOptions = {
|
|
|
185
187
|
anvilAccounts?: number;
|
|
186
188
|
/** Port to start anvil (defaults to 8545) */
|
|
187
189
|
anvilPort?: number;
|
|
190
|
+
/**
|
|
191
|
+
* Number of slots per epoch for Anvil's finality simulation.
|
|
192
|
+
* Anvil reports `finalized = latest - slotsInAnEpoch * 2`.
|
|
193
|
+
*/
|
|
194
|
+
anvilSlotsInAnEpoch?: number;
|
|
188
195
|
/** Key to use for publishing L1 contracts */
|
|
189
196
|
l1PublisherKey?: SecretValue<`0x${string}`>;
|
|
190
197
|
/** ZkPassport configuration (domain, scope, mock verifier) */
|
|
@@ -243,8 +250,8 @@ export type EndToEndContext = {
|
|
|
243
250
|
sequencerDelayer: Delayer | undefined;
|
|
244
251
|
/** Delayer for prover node L1 txs (only when enableDelayer and startProverNode are true). */
|
|
245
252
|
proverDelayer: Delayer | undefined;
|
|
246
|
-
/**
|
|
247
|
-
|
|
253
|
+
/** Genesis data used for setting up nodes. */
|
|
254
|
+
genesis: GenesisData | undefined;
|
|
248
255
|
/** ACVM config (only set if running locally). */
|
|
249
256
|
acvmConfig: Awaited<ReturnType<typeof getACVMConfig>>;
|
|
250
257
|
/** BB config (only set if running locally). */
|
|
@@ -270,7 +277,7 @@ export async function setup(
|
|
|
270
277
|
let anvil: Anvil | undefined;
|
|
271
278
|
try {
|
|
272
279
|
opts.aztecTargetCommitteeSize ??= 0;
|
|
273
|
-
opts.
|
|
280
|
+
opts.slasherEnabled ??= false;
|
|
274
281
|
|
|
275
282
|
const config: AztecNodeConfig & SetupOptions = { ...getConfigEnvVars(), ...opts };
|
|
276
283
|
// use initialValidators for the node config
|
|
@@ -297,6 +304,8 @@ export async function setup(
|
|
|
297
304
|
config.dataDirectory = directoryToCleanup;
|
|
298
305
|
}
|
|
299
306
|
|
|
307
|
+
const dateProvider = new TestDateProvider();
|
|
308
|
+
|
|
300
309
|
if (!config.l1RpcUrls?.length) {
|
|
301
310
|
if (!isAnvilTestChain(chain.id)) {
|
|
302
311
|
throw new Error(`No ETHEREUM_HOSTS set but non anvil chain requested`);
|
|
@@ -305,6 +314,8 @@ export async function setup(
|
|
|
305
314
|
l1BlockTime: opts.ethereumSlotDuration,
|
|
306
315
|
accounts: opts.anvilAccounts,
|
|
307
316
|
port: opts.anvilPort ?? (process.env.ANVIL_PORT ? parseInt(process.env.ANVIL_PORT) : undefined),
|
|
317
|
+
slotsInAnEpoch: opts.anvilSlotsInAnEpoch,
|
|
318
|
+
dateProvider,
|
|
308
319
|
});
|
|
309
320
|
anvil = res.anvil;
|
|
310
321
|
config.l1RpcUrls = [res.rpcUrl];
|
|
@@ -316,8 +327,6 @@ export async function setup(
|
|
|
316
327
|
logger.info(`Logging metrics to ${filename}`);
|
|
317
328
|
setupMetricsLogger(filename);
|
|
318
329
|
}
|
|
319
|
-
|
|
320
|
-
const dateProvider = new TestDateProvider();
|
|
321
330
|
const ethCheatCodes = new EthCheatCodesWithState(config.l1RpcUrls, dateProvider);
|
|
322
331
|
|
|
323
332
|
if (opts.stateLoad) {
|
|
@@ -367,10 +376,12 @@ export async function setup(
|
|
|
367
376
|
addressesToFund.push(sponsoredFPCAddress);
|
|
368
377
|
}
|
|
369
378
|
|
|
370
|
-
const
|
|
379
|
+
const genesisTimestamp = BigInt(Math.floor(Date.now() / 1000));
|
|
380
|
+
const { genesisArchiveRoot, genesis, fundingNeeded } = await getGenesisValues(
|
|
371
381
|
addressesToFund,
|
|
372
382
|
opts.initialAccountFeeJuice,
|
|
373
383
|
opts.genesisPublicData,
|
|
384
|
+
genesisTimestamp,
|
|
374
385
|
);
|
|
375
386
|
|
|
376
387
|
const wasAutomining = await ethCheatCodes.isAutoMining();
|
|
@@ -413,11 +424,12 @@ export async function setup(
|
|
|
413
424
|
await ethCheatCodes.setIntervalMining(config.ethereumSlotDuration);
|
|
414
425
|
}
|
|
415
426
|
|
|
416
|
-
//
|
|
417
|
-
//
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
|
|
427
|
+
// In compose mode (no local anvil), sync dateProvider to L1 time since it may have drifted
|
|
428
|
+
// ahead of system time due to the local-network watcher warping time forward on each filled slot.
|
|
429
|
+
// When running with a local anvil, the dateProvider is kept in sync via the stdout listener.
|
|
430
|
+
if (!anvil) {
|
|
431
|
+
dateProvider.setTime((await ethCheatCodes.lastBlockTimestamp()) * 1000);
|
|
432
|
+
}
|
|
421
433
|
|
|
422
434
|
if (opts.l2StartTime) {
|
|
423
435
|
await ethCheatCodes.warp(opts.l2StartTime, { resetBlockInterval: true });
|
|
@@ -487,11 +499,7 @@ export async function setup(
|
|
|
487
499
|
}
|
|
488
500
|
|
|
489
501
|
const aztecNodeService = await withLoggerBindings({ actor: 'node-0' }, () =>
|
|
490
|
-
AztecNodeService.createAndSync(
|
|
491
|
-
config,
|
|
492
|
-
{ dateProvider, telemetry: telemetryClient, p2pClientDeps },
|
|
493
|
-
{ prefilledPublicData },
|
|
494
|
-
),
|
|
502
|
+
AztecNodeService.createAndSync(config, { dateProvider, telemetry: telemetryClient, p2pClientDeps }, { genesis }),
|
|
495
503
|
);
|
|
496
504
|
const sequencerClient = aztecNodeService.getSequencer();
|
|
497
505
|
|
|
@@ -515,7 +523,7 @@ export async function setup(
|
|
|
515
523
|
dataDirectory: proverNodeDataDirectory,
|
|
516
524
|
},
|
|
517
525
|
{ dateProvider, p2pClientDeps, telemetry: telemetryClient },
|
|
518
|
-
{
|
|
526
|
+
{ genesis },
|
|
519
527
|
));
|
|
520
528
|
}
|
|
521
529
|
|
|
@@ -620,7 +628,7 @@ export async function setup(
|
|
|
620
628
|
initialFundedAccounts,
|
|
621
629
|
logger,
|
|
622
630
|
mockGossipSubNetwork,
|
|
623
|
-
|
|
631
|
+
genesis,
|
|
624
632
|
proverNode,
|
|
625
633
|
sequencerDelayer,
|
|
626
634
|
proverDelayer,
|
|
@@ -720,7 +728,7 @@ export function createAndSyncProverNode(
|
|
|
720
728
|
dateProvider: DateProvider;
|
|
721
729
|
p2pClientDeps?: P2PClientDeps;
|
|
722
730
|
},
|
|
723
|
-
options: {
|
|
731
|
+
options: { genesis?: GenesisData; dontStart?: boolean },
|
|
724
732
|
): Promise<{ proverNode: AztecNodeService }> {
|
|
725
733
|
return withLoggerBindings({ actor: 'prover-0' }, async () => {
|
|
726
734
|
const proverNode = await AztecNodeService.createAndSync(
|
|
@@ -733,7 +741,7 @@ export function createAndSyncProverNode(
|
|
|
733
741
|
proverPublisherPrivateKeys: [new SecretValue(proverNodePrivateKey)],
|
|
734
742
|
},
|
|
735
743
|
deps,
|
|
736
|
-
{
|
|
744
|
+
{ genesis: options.genesis, dontStartProverNode: options.dontStart },
|
|
737
745
|
);
|
|
738
746
|
|
|
739
747
|
if (!proverNode.getProverNode()) {
|
|
@@ -841,7 +849,7 @@ export const deployAccounts =
|
|
|
841
849
|
);
|
|
842
850
|
const deployMethod = await accountManager.getDeployMethod();
|
|
843
851
|
await deployMethod.send({
|
|
844
|
-
from:
|
|
852
|
+
from: NO_FROM,
|
|
845
853
|
skipClassPublication: i !== 0, // Publish the contract class at most once.
|
|
846
854
|
});
|
|
847
855
|
}
|