@@ -22,6 +22,9 @@ const AZTEC_SLOT_DURATION = 8;
2222const SLASHING_UNIT = BigInt ( 1e18 ) ;
2323const 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+
2528export 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
0 commit comments