@aztec/end-to-end 0.0.1-commit.db765a8 → 0.0.1-commit.ddcf04837
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_blacklist_token_contract/blacklist_token_contract_test.d.ts +3 -2
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +1 -1
- 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 +15 -14
- 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 +16 -8
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +24 -18
- 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 +24 -23
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +115 -80
- package/dest/test-wallet/worker_wallet.d.ts +4 -4
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet_schema.d.ts +9 -4
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
- package/package.json +40 -40
- package/src/bench/client_flows/client_flows_benchmark.ts +35 -23
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +3 -6
- 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 +23 -28
- 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 +38 -25
- 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 +144 -99
- package/src/test-wallet/worker_wallet.ts +3 -2
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { NO_FROM } from '@aztec/aztec.js/account';
|
|
1
2
|
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
3
|
import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
|
|
3
4
|
import { type FeePaymentMethod, PrivateFeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
|
|
4
5
|
import { type Logger, createLogger } from '@aztec/aztec.js/log';
|
|
5
6
|
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
6
7
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
7
|
-
import { CheatCodes } from '@aztec/aztec/testing';
|
|
8
|
+
import { CheatCodes, getTokenAllowedSetupFunctions } from '@aztec/aztec/testing';
|
|
8
9
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
9
10
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
10
11
|
import type { DeployAztecL1ContractsArgs } from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
@@ -130,11 +131,14 @@ export class ClientFlowsBenchmark {
|
|
|
130
131
|
|
|
131
132
|
async setup() {
|
|
132
133
|
this.logger.info('Setting up subsystems from fresh');
|
|
134
|
+
// Token allowlist entries are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha.
|
|
135
|
+
const tokenAllowList = await getTokenAllowedSetupFunctions();
|
|
133
136
|
this.context = await setup(0, {
|
|
134
137
|
...this.setupOptions,
|
|
135
138
|
fundSponsoredFPC: true,
|
|
136
139
|
skipAccountDeployment: true,
|
|
137
140
|
l1ContractsArgs: this.setupOptions,
|
|
141
|
+
txPublicSetupAllowListExtend: [...(this.setupOptions.txPublicSetupAllowListExtend ?? []), ...tokenAllowList],
|
|
138
142
|
});
|
|
139
143
|
await this.applyBaseSetup();
|
|
140
144
|
|
|
@@ -246,11 +250,14 @@ export class ClientFlowsBenchmark {
|
|
|
246
250
|
|
|
247
251
|
async applyDeployBananaToken() {
|
|
248
252
|
this.logger.info('Applying banana token deployment');
|
|
249
|
-
const {
|
|
250
|
-
|
|
251
|
-
|
|
253
|
+
const { contract: bananaCoin, instance: bananaCoinInstance } = await BananaCoin.deploy(
|
|
254
|
+
this.adminWallet,
|
|
255
|
+
this.adminAddress,
|
|
256
|
+
'BC',
|
|
257
|
+
'BC',
|
|
258
|
+
18n,
|
|
259
|
+
).send({
|
|
252
260
|
from: this.adminAddress,
|
|
253
|
-
wait: { returnReceipt: true },
|
|
254
261
|
});
|
|
255
262
|
this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`);
|
|
256
263
|
this.bananaCoin = bananaCoin;
|
|
@@ -259,11 +266,14 @@ export class ClientFlowsBenchmark {
|
|
|
259
266
|
|
|
260
267
|
async applyDeployCandyBarToken() {
|
|
261
268
|
this.logger.info('Applying candy bar token deployment');
|
|
262
|
-
const {
|
|
263
|
-
|
|
264
|
-
|
|
269
|
+
const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TokenContract.deploy(
|
|
270
|
+
this.adminWallet,
|
|
271
|
+
this.adminAddress,
|
|
272
|
+
'CBC',
|
|
273
|
+
'CBC',
|
|
274
|
+
18n,
|
|
275
|
+
).send({
|
|
265
276
|
from: this.adminAddress,
|
|
266
|
-
wait: { returnReceipt: true },
|
|
267
277
|
});
|
|
268
278
|
this.logger.info(`CandyBarCoin deployed at ${candyBarCoin.address}`);
|
|
269
279
|
this.candyBarCoin = candyBarCoin;
|
|
@@ -276,11 +286,12 @@ export class ClientFlowsBenchmark {
|
|
|
276
286
|
expect((await this.context.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true);
|
|
277
287
|
|
|
278
288
|
const bananaCoin = this.bananaCoin;
|
|
279
|
-
const {
|
|
280
|
-
|
|
281
|
-
|
|
289
|
+
const { contract: bananaFPC, instance: bananaFPCInstance } = await FPCContract.deploy(
|
|
290
|
+
this.adminWallet,
|
|
291
|
+
bananaCoin.address,
|
|
292
|
+
this.adminAddress,
|
|
293
|
+
).send({
|
|
282
294
|
from: this.adminAddress,
|
|
283
|
-
wait: { returnReceipt: true },
|
|
284
295
|
});
|
|
285
296
|
|
|
286
297
|
this.logger.info(`BananaPay deployed at ${bananaFPC.address}`);
|
|
@@ -330,7 +341,7 @@ export class ClientFlowsBenchmark {
|
|
|
330
341
|
const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(benchysAddress);
|
|
331
342
|
const behchysDeployMethod = await benchysAccountManager.getDeployMethod();
|
|
332
343
|
await behchysDeployMethod.send({
|
|
333
|
-
from:
|
|
344
|
+
from: NO_FROM,
|
|
334
345
|
fee: { paymentMethod: new FeeJuicePaymentMethodWithClaim(benchysAddress, claim) },
|
|
335
346
|
});
|
|
336
347
|
// Register benchy on the user's Wallet, where we're going to be interacting from
|
|
@@ -344,20 +355,21 @@ export class ClientFlowsBenchmark {
|
|
|
344
355
|
|
|
345
356
|
public async applyDeployAmm() {
|
|
346
357
|
this.logger.info('Applying AMM deployment');
|
|
347
|
-
const {
|
|
348
|
-
|
|
349
|
-
|
|
358
|
+
const { contract: liquidityToken, instance: liquidityTokenInstance } = await TokenContract.deploy(
|
|
359
|
+
this.adminWallet,
|
|
360
|
+
this.adminAddress,
|
|
361
|
+
'LPT',
|
|
362
|
+
'LPT',
|
|
363
|
+
18n,
|
|
364
|
+
).send({
|
|
350
365
|
from: this.adminAddress,
|
|
351
|
-
wait: { returnReceipt: true },
|
|
352
366
|
});
|
|
353
|
-
const {
|
|
354
|
-
receipt: { contract: amm, instance: ammInstance },
|
|
355
|
-
} = await AMMContract.deploy(
|
|
367
|
+
const { contract: amm, instance: ammInstance } = await AMMContract.deploy(
|
|
356
368
|
this.adminWallet,
|
|
357
369
|
this.bananaCoin.address,
|
|
358
370
|
this.candyBarCoin.address,
|
|
359
371
|
liquidityToken.address,
|
|
360
|
-
).send({ from: this.adminAddress
|
|
372
|
+
).send({ from: this.adminAddress });
|
|
361
373
|
this.logger.info(`AMM deployed at ${amm.address}`);
|
|
362
374
|
await liquidityToken.methods.set_minter(amm.address, true).send({ from: this.adminAddress });
|
|
363
375
|
this.liquidityToken = liquidityToken;
|
|
@@ -375,7 +387,7 @@ export class ClientFlowsBenchmark {
|
|
|
375
387
|
// The private fee paying method assembled on the app side requires knowledge of the maximum
|
|
376
388
|
// fee the user is willing to pay
|
|
377
389
|
const maxFeesPerGas = (await this.aztecNode.getCurrentMinFees()).mul(1.5);
|
|
378
|
-
const gasSettings = GasSettings.
|
|
390
|
+
const gasSettings = GasSettings.fallback({ maxFeesPerGas });
|
|
379
391
|
return new PrivateFeePaymentMethod(this.bananaFPC.address, sender, wallet, gasSettings);
|
|
380
392
|
}
|
|
381
393
|
|
|
@@ -10,6 +10,7 @@ import { TokenBlacklistContract } from '@aztec/noir-contracts.js/TokenBlacklist'
|
|
|
10
10
|
import { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
|
|
11
11
|
import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAccount';
|
|
12
12
|
import type { SequencerClient } from '@aztec/sequencer-client';
|
|
13
|
+
import type { AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
|
|
13
14
|
|
|
14
15
|
import { jest } from '@jest/globals';
|
|
15
16
|
|
|
@@ -57,7 +58,7 @@ export class BlacklistTokenContractTest {
|
|
|
57
58
|
authwitProxy!: GenericProxyContract;
|
|
58
59
|
cheatCodes!: CheatCodes;
|
|
59
60
|
sequencer!: SequencerClient;
|
|
60
|
-
aztecNode!: AztecNode;
|
|
61
|
+
aztecNode!: AztecNode & AztecNodeDebug;
|
|
61
62
|
|
|
62
63
|
adminAddress!: AztecAddress;
|
|
63
64
|
otherAddress!: AztecAddress;
|
|
@@ -68,11 +69,7 @@ export class BlacklistTokenContractTest {
|
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
async crossTimestampOfChange() {
|
|
71
|
-
await this.cheatCodes.warpL2TimeAtLeastBy(
|
|
72
|
-
this.sequencer,
|
|
73
|
-
this.aztecNode,
|
|
74
|
-
BlacklistTokenContractTest.CHANGE_ROLES_DELAY,
|
|
75
|
-
);
|
|
72
|
+
await this.cheatCodes.warpL2TimeAtLeastBy(this.aztecNode, BlacklistTokenContractTest.CHANGE_ROLES_DELAY);
|
|
76
73
|
}
|
|
77
74
|
|
|
78
75
|
/**
|
|
@@ -28,6 +28,7 @@ import { type SequencerClient, type SequencerEvents, SequencerState } from '@azt
|
|
|
28
28
|
import { type BlockParameter, EthAddress } from '@aztec/stdlib/block';
|
|
29
29
|
import { type L1RollupConstants, getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
30
30
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
31
|
+
import type { SlashingProtectionDatabase } from '@aztec/validator-ha-signer/types';
|
|
31
32
|
|
|
32
33
|
import { join } from 'path';
|
|
33
34
|
import type { Hex } from 'viem';
|
|
@@ -144,7 +145,7 @@ export class EpochsTestContext {
|
|
|
144
145
|
proverId: EthAddress.fromNumber(1),
|
|
145
146
|
worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
|
|
146
147
|
exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
|
|
147
|
-
|
|
148
|
+
slasherEnabled: false,
|
|
148
149
|
l1PublishingTime,
|
|
149
150
|
...opts,
|
|
150
151
|
},
|
|
@@ -181,6 +182,7 @@ export class EpochsTestContext {
|
|
|
181
182
|
ethereumSlotDuration,
|
|
182
183
|
proofSubmissionEpochs: Number(await this.rollup.getProofSubmissionEpochs()),
|
|
183
184
|
targetCommitteeSize: await this.rollup.getTargetCommitteeSize(),
|
|
185
|
+
rollupManaLimit: Number(await this.rollup.getManaLimit()),
|
|
184
186
|
};
|
|
185
187
|
|
|
186
188
|
this.logger.info(
|
|
@@ -221,7 +223,7 @@ export class EpochsTestContext {
|
|
|
221
223
|
},
|
|
222
224
|
},
|
|
223
225
|
{
|
|
224
|
-
|
|
226
|
+
genesis: this.context.genesis,
|
|
225
227
|
dontStart: opts.dontStart,
|
|
226
228
|
},
|
|
227
229
|
),
|
|
@@ -237,13 +239,21 @@ export class EpochsTestContext {
|
|
|
237
239
|
|
|
238
240
|
public createValidatorNode(
|
|
239
241
|
privateKeys: `0x${string}`[],
|
|
240
|
-
opts: Partial<AztecNodeConfig> & {
|
|
242
|
+
opts: Partial<AztecNodeConfig> & {
|
|
243
|
+
dontStartSequencer?: boolean;
|
|
244
|
+
slashingProtectionDb?: SlashingProtectionDatabase;
|
|
245
|
+
} = {},
|
|
241
246
|
) {
|
|
242
247
|
this.logger.warn('Creating and syncing a validator node...');
|
|
243
248
|
return this.createNode({ ...opts, disableValidator: false, validatorPrivateKeys: new SecretValue(privateKeys) });
|
|
244
249
|
}
|
|
245
250
|
|
|
246
|
-
private async createNode(
|
|
251
|
+
private async createNode(
|
|
252
|
+
opts: Partial<AztecNodeConfig> & {
|
|
253
|
+
dontStartSequencer?: boolean;
|
|
254
|
+
slashingProtectionDb?: SlashingProtectionDatabase;
|
|
255
|
+
} = {},
|
|
256
|
+
) {
|
|
247
257
|
const nodeIndex = this.nodes.length + 1;
|
|
248
258
|
const actorPrefix = opts.disableValidator ? 'node' : 'validator';
|
|
249
259
|
const { mockGossipSubNetwork } = this.context;
|
|
@@ -256,6 +266,7 @@ export class EpochsTestContext {
|
|
|
256
266
|
...resolvedConfig,
|
|
257
267
|
dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
|
|
258
268
|
validatorPrivateKeys: opts.validatorPrivateKeys ?? new SecretValue([]),
|
|
269
|
+
nodeId: resolvedConfig.nodeId || `${actorPrefix}-${nodeIndex}`,
|
|
259
270
|
p2pEnabled,
|
|
260
271
|
p2pIp,
|
|
261
272
|
},
|
|
@@ -264,9 +275,10 @@ export class EpochsTestContext {
|
|
|
264
275
|
p2pClientDeps: {
|
|
265
276
|
p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
|
|
266
277
|
},
|
|
278
|
+
slashingProtectionDb: opts.slashingProtectionDb,
|
|
267
279
|
},
|
|
268
280
|
{
|
|
269
|
-
|
|
281
|
+
genesis: this.context.genesis,
|
|
270
282
|
...opts,
|
|
271
283
|
},
|
|
272
284
|
),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
2
|
import { type Logger, createLogger } from '@aztec/aztec.js/log';
|
|
3
3
|
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
4
|
-
import { CheatCodes } from '@aztec/aztec/testing';
|
|
4
|
+
import { CheatCodes, getTokenAllowedSetupFunctions } from '@aztec/aztec/testing';
|
|
5
5
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
6
6
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
7
7
|
import type { DeployAztecL1ContractsArgs } from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
@@ -104,12 +104,15 @@ export class FeesTest {
|
|
|
104
104
|
|
|
105
105
|
async setup() {
|
|
106
106
|
this.logger.verbose('Setting up fresh context...');
|
|
107
|
+
// Token allowlist entries are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha.
|
|
108
|
+
const tokenAllowList = await getTokenAllowedSetupFunctions();
|
|
107
109
|
this.context = await setup(0, {
|
|
108
110
|
startProverNode: true,
|
|
109
111
|
...this.setupOptions,
|
|
110
112
|
fundSponsoredFPC: true,
|
|
111
113
|
skipAccountDeployment: true,
|
|
112
114
|
l1ContractsArgs: { ...this.setupOptions },
|
|
115
|
+
txPublicSetupAllowListExtend: [...(this.setupOptions.txPublicSetupAllowListExtend ?? []), ...tokenAllowList],
|
|
113
116
|
});
|
|
114
117
|
|
|
115
118
|
this.rollupContract = RollupContract.getFromConfig(this.context.config);
|
|
@@ -190,7 +193,7 @@ export class FeesTest {
|
|
|
190
193
|
this.wallet = this.context.wallet;
|
|
191
194
|
this.aztecNode = this.context.aztecNodeService;
|
|
192
195
|
this.aztecNodeAdmin = this.context.aztecNodeService;
|
|
193
|
-
this.gasSettings = GasSettings.
|
|
196
|
+
this.gasSettings = GasSettings.fallback({ maxFeesPerGas: (await this.aztecNode.getCurrentMinFees()).mul(2) });
|
|
194
197
|
this.cheatCodes = this.context.cheatCodes;
|
|
195
198
|
this.accounts = deployedAccounts.map(a => a.address);
|
|
196
199
|
this.accounts.forEach((a, i) => this.logger.verbose(`Account ${i} address: ${a}`));
|
|
@@ -58,6 +58,7 @@ export class P2PInactivityTest {
|
|
|
58
58
|
basePort: BOOT_NODE_UDP_PORT,
|
|
59
59
|
startProverNode: true,
|
|
60
60
|
initialConfig: {
|
|
61
|
+
anvilSlotsInAnEpoch: 4,
|
|
61
62
|
proverNodeConfig: { proverNodeEpochProvingDelayMs: AZTEC_SLOT_DURATION * 1000 },
|
|
62
63
|
aztecTargetCommitteeSize: COMMITTEE_SIZE,
|
|
63
64
|
aztecSlotDuration: AZTEC_SLOT_DURATION,
|
|
@@ -66,7 +67,6 @@ export class P2PInactivityTest {
|
|
|
66
67
|
listenAddress: '127.0.0.1',
|
|
67
68
|
minTxsPerBlock: 0,
|
|
68
69
|
aztecEpochDuration: EPOCH_DURATION,
|
|
69
|
-
validatorReexecute: false,
|
|
70
70
|
sentinelEnabled: true,
|
|
71
71
|
slashingQuorum: SLASHING_QUORUM,
|
|
72
72
|
slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE_IN_EPOCHS,
|
|
@@ -108,7 +108,7 @@ export class P2PInactivityTest {
|
|
|
108
108
|
this.test.bootstrapNodeEnr,
|
|
109
109
|
NUM_NODES - this.inactiveNodeCount - Number(this.keepInitialNode),
|
|
110
110
|
BOOT_NODE_UDP_PORT,
|
|
111
|
-
this.test.
|
|
111
|
+
this.test.genesis,
|
|
112
112
|
this.dataDir,
|
|
113
113
|
undefined,
|
|
114
114
|
Number(this.keepInitialNode),
|
|
@@ -122,7 +122,7 @@ export class P2PInactivityTest {
|
|
|
122
122
|
this.test.bootstrapNodeEnr,
|
|
123
123
|
this.inactiveNodeCount,
|
|
124
124
|
BOOT_NODE_UDP_PORT,
|
|
125
|
-
this.test.
|
|
125
|
+
this.test.genesis,
|
|
126
126
|
this.dataDir,
|
|
127
127
|
undefined,
|
|
128
128
|
NUM_NODES - this.inactiveNodeCount,
|
|
@@ -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,9 @@ 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
|
|
23
|
+
import { TxStatus } from '@aztec/stdlib/tx';
|
|
24
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
30
25
|
import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
|
|
31
26
|
import { getGenesisValues } from '@aztec/world-state/testing';
|
|
32
27
|
|
|
@@ -59,7 +54,7 @@ export const WAIT_FOR_TX_TIMEOUT = l1ContractsConfig.aztecSlotDuration * 3;
|
|
|
59
54
|
export const SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES = {
|
|
60
55
|
aztecSlotDuration: 12,
|
|
61
56
|
ethereumSlotDuration: 4,
|
|
62
|
-
|
|
57
|
+
aztecProofSubmissionEpochs: 640,
|
|
63
58
|
};
|
|
64
59
|
|
|
65
60
|
export class P2PNetworkTest {
|
|
@@ -77,7 +72,7 @@ export class P2PNetworkTest {
|
|
|
77
72
|
public validators: Operator[] = [];
|
|
78
73
|
|
|
79
74
|
public deployedAccounts: InitialAccountData[] = [];
|
|
80
|
-
public
|
|
75
|
+
public genesis: GenesisData | undefined;
|
|
81
76
|
|
|
82
77
|
// The re-execution test needs a wallet and a spam contract
|
|
83
78
|
public wallet?: TestWallet;
|
|
@@ -124,7 +119,7 @@ export class P2PNetworkTest {
|
|
|
124
119
|
initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
|
|
125
120
|
slashingRoundSizeInEpochs:
|
|
126
121
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
127
|
-
|
|
122
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
128
123
|
aztecTargetCommitteeSize: numberOfValidators,
|
|
129
124
|
metricsPort: metricsPort,
|
|
130
125
|
numberOfInitialFundedAccounts: 2,
|
|
@@ -137,7 +132,7 @@ export class P2PNetworkTest {
|
|
|
137
132
|
aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
|
|
138
133
|
slashingRoundSizeInEpochs:
|
|
139
134
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
140
|
-
|
|
135
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
141
136
|
|
|
142
137
|
ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
|
|
143
138
|
aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
|
|
@@ -305,10 +300,11 @@ export class P2PNetworkTest {
|
|
|
305
300
|
|
|
306
301
|
async setupAccount() {
|
|
307
302
|
this.logger.info('Setting up account');
|
|
308
|
-
const { deployedAccounts } = await deployAccounts(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
303
|
+
const { deployedAccounts } = await deployAccounts(1, this.logger, {
|
|
304
|
+
wait: {
|
|
305
|
+
waitForStatus: TxStatus.CHECKPOINTED,
|
|
306
|
+
},
|
|
307
|
+
})({
|
|
312
308
|
wallet: this.context.wallet,
|
|
313
309
|
initialFundedAccounts: this.context.initialFundedAccounts,
|
|
314
310
|
});
|
|
@@ -360,7 +356,7 @@ export class P2PNetworkTest {
|
|
|
360
356
|
...this.setupOptions,
|
|
361
357
|
fundSponsoredFPC: true,
|
|
362
358
|
skipAccountDeployment: true,
|
|
363
|
-
|
|
359
|
+
slasherEnabled: this.setupOptions.slasherEnabled ?? this.deployL1ContractsArgs.slasherEnabled ?? false,
|
|
364
360
|
aztecTargetCommitteeSize: 0,
|
|
365
361
|
l1ContractsArgs: this.deployL1ContractsArgs,
|
|
366
362
|
},
|
|
@@ -372,8 +368,13 @@ export class P2PNetworkTest {
|
|
|
372
368
|
const sponsoredFPCAddress = await getSponsoredFPCAddress();
|
|
373
369
|
const initialFundedAccounts = [...this.context.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
|
|
374
370
|
|
|
375
|
-
const {
|
|
376
|
-
|
|
371
|
+
const { genesis } = await getGenesisValues(
|
|
372
|
+
initialFundedAccounts,
|
|
373
|
+
undefined,
|
|
374
|
+
undefined,
|
|
375
|
+
this.context.genesis!.genesisTimestamp,
|
|
376
|
+
);
|
|
377
|
+
this.genesis = genesis;
|
|
377
378
|
|
|
378
379
|
const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
|
|
379
380
|
this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider).start();
|
|
@@ -468,8 +469,7 @@ export class P2PNetworkTest {
|
|
|
468
469
|
async getContracts(): Promise<{
|
|
469
470
|
rollup: RollupContract;
|
|
470
471
|
slasherContract: GetContractReturnType<typeof SlasherAbi, ViemClient>;
|
|
471
|
-
slashingProposer:
|
|
472
|
-
slashFactory: SlashFactoryContract;
|
|
472
|
+
slashingProposer: SlashingProposerContract | undefined;
|
|
473
473
|
}> {
|
|
474
474
|
if (!this.ctx.deployL1ContractsValues) {
|
|
475
475
|
throw new Error('DeployAztecL1ContractsValues not set');
|
|
@@ -486,14 +486,9 @@ export class P2PNetworkTest {
|
|
|
486
486
|
client: this.ctx.deployL1ContractsValues.l1Client,
|
|
487
487
|
});
|
|
488
488
|
|
|
489
|
-
// Get the actual slashing proposer from rollup
|
|
489
|
+
// Get the actual slashing proposer from rollup
|
|
490
490
|
const slashingProposer = await rollup.getSlashingProposer();
|
|
491
491
|
|
|
492
|
-
|
|
493
|
-
this.ctx.deployL1ContractsValues.l1Client,
|
|
494
|
-
getAddress(this.ctx.deployL1ContractsValues.l1ContractAddresses.slashFactoryAddress!.toString()),
|
|
495
|
-
);
|
|
496
|
-
|
|
497
|
-
return { rollup, slasherContract, slashingProposer, slashFactory };
|
|
492
|
+
return { rollup, slasherContract, slashingProposer };
|
|
498
493
|
}
|
|
499
494
|
}
|
|
@@ -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);
|