Skip to content

Commit 886c1f9

Browse files
authored
chore: Deflake inactivity slash e2e test (#17090)
Attempt at fixing the flake on `inactivity_slash.test`. The test was failing as sometimes other validator than the "offline" one was getting slashed, due to inactivity during setup. We try addressing that by setting up a long slashing grace period, so we can safely set up every sequencer during that period, and then warping to after that to start slashing. We also try avoid slashing an active validator by bumping the inactivity threshold on this PR.
2 parents 19e8b21 + 650ddc6 commit 886c1f9

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

yarn-project/end-to-end/src/e2e_p2p/inactivity_slash.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ describe('e2e_p2p_inactivity_slash', () => {
1717
test = await P2PInactivityTest.create('e2e_p2p_inactivity_slash', {
1818
slashInactivityConsecutiveEpochThreshold: SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD,
1919
inactiveNodeCount: 1,
20+
keepInitialNode: false,
2021
}).then(t => t.setup());
2122
});
2223

yarn-project/end-to-end/src/e2e_p2p/inactivity_slash_test.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ const AZTEC_SLOT_DURATION = 8;
2222
const SLASHING_UNIT = BigInt(1e18);
2323
const SLASHING_AMOUNT = SLASHING_UNIT * 3n;
2424

25+
// How many epochs it may take to set everything up, so we dont slash during this period
26+
const SETUP_EPOCH_DURATION = 5;
27+
2528
export class P2PInactivityTest {
2629
public nodes!: AztecNodeService[];
2730
public activeNodes!: AztecNodeService[];
@@ -32,18 +35,20 @@ export class P2PInactivityTest {
3235

3336
private dataDir: string;
3437
private inactiveNodeCount: number;
38+
private keepInitialNode: boolean;
3539

3640
constructor(
3741
public readonly test: P2PNetworkTest,
38-
opts: { inactiveNodeCount: number },
42+
opts: { inactiveNodeCount: number; keepInitialNode?: boolean },
3943
) {
4044
this.dataDir = fs.mkdtempSync(path.join(os.tmpdir(), test.testName));
4145
this.inactiveNodeCount = opts.inactiveNodeCount;
46+
this.keepInitialNode = opts.keepInitialNode ?? false;
4247
}
4348

4449
static async create(
4550
testName: string,
46-
opts: { slashInactivityConsecutiveEpochThreshold: number; inactiveNodeCount: number },
51+
opts: { slashInactivityConsecutiveEpochThreshold: number; inactiveNodeCount: number; keepInitialNode?: boolean },
4752
) {
4853
const test = await P2PNetworkTest.create({
4954
testName,
@@ -64,8 +69,8 @@ export class P2PInactivityTest {
6469
sentinelEnabled: true,
6570
slashingQuorum: SLASHING_QUORUM,
6671
slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE_IN_EPOCHS,
67-
slashInactivityTargetPercentage: 0.5,
68-
slashGracePeriodL2Slots: EPOCH_DURATION, // do not slash during the first epoch
72+
slashInactivityTargetPercentage: 0.8,
73+
slashGracePeriodL2Slots: SETUP_EPOCH_DURATION * EPOCH_DURATION, // do not slash during setup
6974
slashAmountSmall: SLASHING_UNIT,
7075
slashAmountMedium: SLASHING_UNIT * 2n,
7176
slashAmountLarge: SLASHING_UNIT * 3n,
@@ -91,18 +96,21 @@ export class P2PInactivityTest {
9196
this.test.ctx.aztecNodeConfig.slashInactivityPenalty = SLASHING_AMOUNT;
9297
this.rollup = rollup;
9398

94-
// The initial validator that ran on this node is picked up by the first new node started below
95-
await this.test.removeInitialNode();
99+
if (!this.keepInitialNode) {
100+
await this.test.ctx.aztecNode.stop();
101+
}
96102

97103
// Create all active nodes
98104
this.activeNodes = await createNodes(
99105
this.test.ctx.aztecNodeConfig,
100106
this.test.ctx.dateProvider,
101107
this.test.bootstrapNodeEnr,
102-
NUM_NODES - this.inactiveNodeCount,
108+
NUM_NODES - this.inactiveNodeCount - Number(this.keepInitialNode),
103109
BOOT_NODE_UDP_PORT,
104110
this.test.prefilledPublicData,
105111
this.dataDir,
112+
undefined,
113+
Number(this.keepInitialNode),
106114
);
107115

108116
// And the ones with an initially disabled sequencer
@@ -119,7 +127,15 @@ export class P2PInactivityTest {
119127
NUM_NODES - this.inactiveNodeCount,
120128
);
121129

122-
this.nodes = [...this.activeNodes, ...this.inactiveNodes];
130+
this.nodes = [
131+
...(this.keepInitialNode ? [this.test.ctx.aztecNode] : []),
132+
...this.activeNodes,
133+
...this.inactiveNodes,
134+
];
135+
136+
if (this.nodes.length !== NUM_NODES) {
137+
throw new Error(`Expected ${NUM_NODES} nodes but got ${this.nodes.length}`);
138+
}
123139

124140
this.offlineValidators = this.test.validators
125141
.slice(this.test.validators.length - this.inactiveNodeCount)
@@ -130,6 +146,9 @@ export class P2PInactivityTest {
130146
offlineValidators: this.offlineValidators,
131147
});
132148

149+
this.test.logger.warn(`Advancing to epoch ${SETUP_EPOCH_DURATION + 1} to start slashing`);
150+
await this.test.ctx.cheatCodes.rollup.advanceToEpoch(SETUP_EPOCH_DURATION + 1);
151+
133152
return this;
134153
}
135154

yarn-project/end-to-end/src/fixtures/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ export async function setup(
573573
await blobSink.start();
574574
config.blobSinkUrl = `http://localhost:${blobSinkPort}`;
575575

576-
logger.verbose('Creating and synching an aztec node...');
576+
logger.verbose('Creating and synching an aztec node', config);
577577

578578
const acvmConfig = await getACVMConfig(logger);
579579
if (acvmConfig) {

yarn-project/ethereum/src/test/rollup_cheat_codes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,14 @@ export class RollupCheatCodes {
112112
* @param opts - Options
113113
*/
114114
public async advanceToEpoch(
115-
epoch: bigint,
115+
epoch: bigint | number,
116116
opts: {
117117
/** Optional test date provider to update with the epoch timestamp */
118118
updateDateProvider?: TestDateProvider;
119119
} = {},
120120
) {
121121
const { epochDuration: slotsInEpoch } = await this.getConfig();
122-
const timestamp = await this.rollup.read.getTimestampForSlot([epoch * slotsInEpoch]);
122+
const timestamp = await this.rollup.read.getTimestampForSlot([BigInt(epoch) * slotsInEpoch]);
123123
try {
124124
await this.ethCheatCodes.warp(Number(timestamp), { ...opts, silent: true, resetBlockInterval: true });
125125
this.logger.warn(`Warped to epoch ${epoch}`);

0 commit comments

Comments
 (0)