@@ -224,7 +224,7 @@ func TestContractEvent(t *testing.T) {
224
224
225
225
// TestWithdrawalSafetyAllInvariants ... Tests the E2E flow of a withdrawal
226
226
// safety heuristic session. This test ensures that an alert is produced in the event
227
- // of a highly suspicious withdrawal.
227
+ // of a highly suspicious withdrawal at every step of the withdrawal flow .
228
228
func TestWithdrawalSafetyAllInvariants (t * testing.T ) {
229
229
ts := e2e .CreateSysTestSuite (t , "" )
230
230
defer ts .Close ()
@@ -259,6 +259,22 @@ func TestWithdrawalSafetyAllInvariants(t *testing.T) {
259
259
core .L2ToL1MessagePasser : fakeAddr .String (),
260
260
},
261
261
},
262
+ {
263
+ Network : core .Layer2 .String (),
264
+ HeuristicType : core .WithdrawalSafety .String (),
265
+ StartHeight : nil ,
266
+ EndHeight : nil ,
267
+ AlertingParams : & core.AlertPolicy {
268
+ Sev : core .LOW .String (),
269
+ Msg : alertMsg ,
270
+ },
271
+ SessionParams : map [string ]interface {}{
272
+ "threshold" : 0.20 ,
273
+ "coefficient_threshold" : 0.20 ,
274
+ core .L1Portal : ts .Cfg .L1Deployments .OptimismPortalProxy .String (),
275
+ core .L2ToL1MessagePasser : predeploys .L2ToL1MessagePasserAddr .String (),
276
+ },
277
+ },
262
278
})
263
279
require .NoError (t , err , "Error bootstrapping heuristic session" )
264
280
@@ -284,12 +300,33 @@ func TestWithdrawalSafetyAllInvariants(t *testing.T) {
284
300
_ , err = wait .ForReceiptOK (context .Background (), ts .L1Client , depositTx .Hash ())
285
301
require .NoError (t , err )
286
302
287
- // Initiate and prove a withdrawal
303
+ // Initiate withdrawal
288
304
withdrawTx , err := l2ToL1MessagePasser .InitiateWithdrawal (l2Opts , aliceAddr , big .NewInt (100_000 ), calldata )
289
305
require .NoError (t , err )
290
- withdrawReceipt , err := wait .ForReceiptOK (context .Background (), ts .L2Client , withdrawTx .Hash ())
306
+ initReceipt , err := wait .ForReceiptOK (context .Background (), ts .L2Client , withdrawTx .Hash ())
291
307
require .NoError (t , err )
292
308
309
+ // Wait for Pessimism to process initiation
310
+ require .NoError (t , wait .For (context .Background (), 500 * time .Millisecond , func () (bool , error ) {
311
+ id := ids [0 ].PathID
312
+ height , err := ts .Subsystems .PathHeight (id )
313
+ if err != nil {
314
+ return false , err
315
+ }
316
+
317
+ return height != nil && height .Uint64 () > initReceipt .BlockNumber .Uint64 (), nil
318
+ }))
319
+
320
+ // Ensure Pessimism has detected what it considers an unsafe withdrawal
321
+ alerts := ts .TestSlackSvr .SlackAlerts ()
322
+ require .Equal (t , 1 , len (alerts ), "expected 1 alerts" )
323
+ assert .Contains (t , alerts [0 ].Text , core .WithdrawalSafety .String (), "expected alert to be for withdrawal_safety" )
324
+ assert .Contains (t , alerts [0 ].Text , alertMsg , "expected alert to have alert message" )
325
+
326
+ // Ensure that specific invariant messages are included in the alert
327
+ assert .Contains (t , alerts [0 ].Text , alertMsg , registry .GreaterThanPortal )
328
+
329
+ ts .TestSlackSvr .ClearAlerts ()
293
330
// Mock the indexer call to return a really high withdrawal amount
294
331
ts .TestIxClient .EXPECT ().GetAllWithdrawalsByAddress (gomock .Any ()).Return ([]api_mods.WithdrawalItem {
295
332
{
@@ -298,7 +335,7 @@ func TestWithdrawalSafetyAllInvariants(t *testing.T) {
298
335
},
299
336
}, nil ).AnyTimes ()
300
337
301
- _ , proveReceipt := op_e2e .ProveWithdrawal (t , * ts .Cfg , ts .L1Client , ts .Sys .EthInstances ["sequencer" ], ts .Cfg .Secrets .Alice , withdrawReceipt )
338
+ params , proveReceipt := op_e2e .ProveWithdrawal (t , * ts .Cfg , ts .L1Client , ts .Sys .EthInstances ["sequencer" ], ts .Cfg .Secrets .Alice , initReceipt )
302
339
303
340
// Wait for Pessimism to process the proven withdrawal and send a notification to the mocked Slack server.
304
341
require .NoError (t , wait .For (context .Background (), 500 * time .Millisecond , func () (bool , error ) {
@@ -312,7 +349,7 @@ func TestWithdrawalSafetyAllInvariants(t *testing.T) {
312
349
}))
313
350
314
351
// Ensure Pessimism has detected what it considers an unsafe withdrawal
315
- alerts : = ts .TestSlackSvr .SlackAlerts ()
352
+ alerts = ts .TestSlackSvr .SlackAlerts ()
316
353
require .Equal (t , 1 , len (alerts ), "expected 1 alerts" )
317
354
assert .Contains (t , alerts [0 ].Text , core .WithdrawalSafety .String (), "expected alert to be for withdrawal_safety" )
318
355
assert .Contains (t , alerts [0 ].Text , fakeAddr .String (), "expected alert to be for dummy L2ToL1MessagePasser" )
@@ -323,34 +360,34 @@ func TestWithdrawalSafetyAllInvariants(t *testing.T) {
323
360
assert .Contains (t , alerts [0 ].Text , alertMsg , registry .GreaterThanPortal )
324
361
assert .Contains (t , alerts [0 ].Text , alertMsg , fmt .Sprintf (registry .GreaterThanThreshold , 20.0 ))
325
362
326
- // TODO(#178) - Feat - Support WithdrawalProven processing in withdrawal_safety heuristic
327
- // Mock the indexer call to return a really low withdrawal amount
328
- // ts.TestIxClient.EXPECT().GetAllWithdrawalsByAddress(gomock.Any()).Return([]api_mods.WithdrawalItem{
329
- // {
330
- // TransactionHash: "0x123",
331
- // Amount: "1",
332
- // },
333
- // }, nil).AnyTimes()
363
+ ts .TestIxClient .EXPECT ().GetAllWithdrawalsByAddress (gomock .Any ()).Return ([]api_mods.WithdrawalItem {
364
+ {
365
+ TransactionHash : "0x123" ,
366
+ Amount : "1" ,
367
+ },
368
+ }, nil ).AnyTimes ()
334
369
335
370
// Finalize the withdrawal
336
- // finalizeReceipt := op_e2e.FinalizeWithdrawal(t, *ts.Cfg, ts.L1Client, ts.Cfg.Secrets.Alice, proveReceipt, proveParams)
337
-
338
- // // Wait for Pessimism to process the finalized withdrawal and send a notification to the mocked Slack server.
339
- // require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) {
340
- // id := ids[0].PathID
341
- // height, err := ts.Subsystems.PathHeight(id)
342
- // if err != nil {
343
- // return false, err
344
- // }
345
-
346
- // return height.Uint64() > finalizeReceipt.BlockNumber.Uint64(), nil
347
- // }))
348
-
349
- // alerts = ts.TestSlackSvr.SlackAlerts()
350
- // require.Equal(t, 3, len(alerts), "expected 3 alerts")
351
- // assert.Contains(t, alerts[0].Text, "unsafe_withdrawal", "expected alert to be for unsafe_withdrawal")
352
- // assert.Contains(t, alerts[0].Text, fakeAddr.String(), "expected alert to be for dummy L2ToL1MessagePasser")
353
- // assert.Contains(t, alerts[0].Text, alertMsg, "expected alert to have alert message")
371
+ finalizeReceipt := op_e2e .FinalizeWithdrawal (t , * ts .Cfg , ts .L1Client , ts .Cfg .Secrets .Alice , proveReceipt , params )
372
+
373
+ // Wait for Pessimism to process the finalized withdrawal and send a notification to the mocked Slack server.
374
+ require .NoError (t , wait .For (context .Background (), 500 * time .Millisecond , func () (bool , error ) {
375
+ id := ids [0 ].PathID
376
+ height , err := ts .Subsystems .PathHeight (id )
377
+ if err != nil {
378
+ return false , err
379
+ }
380
+
381
+ return height .Uint64 () > finalizeReceipt .BlockNumber .Uint64 (), nil
382
+ }))
383
+
384
+ alerts = ts .TestSlackSvr .SlackAlerts ()
385
+ require .Equal (t , 1 , len (alerts ), "expected 1 alert" )
386
+ assert .Contains (t , alerts [0 ].Text , core .WithdrawalSafety .String ())
387
+ assert .Contains (t , alerts [0 ].Text , alertMsg , "expected alert to have alert message" )
388
+
389
+ // Ensure that specific invariant messages are included in the alert
390
+ assert .Contains (t , alerts [0 ].Text , alertMsg , registry .TooSimilarToMax )
354
391
}
355
392
356
393
// TestWithdrawalSafetyNoInvariants ... Verify that no alerts are produced in the event
@@ -418,7 +455,7 @@ func TestWithdrawalSafetyNoInvariants(t *testing.T) {
418
455
},
419
456
}, nil ).AnyTimes ()
420
457
421
- _ , proveReceipt := op_e2e .ProveWithdrawal (t , * ts .Cfg , ts .L1Client , ts .Sys .EthInstances ["sequencer" ], ts .Cfg .Secrets .Alice , withdrawReceipt )
458
+ params , proveReceipt := op_e2e .ProveWithdrawal (t , * ts .Cfg , ts .L1Client , ts .Sys .EthInstances ["sequencer" ], ts .Cfg .Secrets .Alice , withdrawReceipt )
422
459
423
460
// Wait for Pessimism to process the proven withdrawal and send a notification to the mocked Slack server.
424
461
require .NoError (t , wait .For (context .Background (), 500 * time .Millisecond , func () (bool , error ) {
@@ -431,9 +468,23 @@ func TestWithdrawalSafetyNoInvariants(t *testing.T) {
431
468
return height != nil && height .Uint64 () > proveReceipt .BlockNumber .Uint64 (), nil
432
469
}))
433
470
434
- // Ensure that this withdrawal triggered no alerts
471
+ // Finalize the withdrawal
472
+ finalizeReceipt := op_e2e .FinalizeWithdrawal (t , * ts .Cfg , ts .L1Client , ts .Cfg .Secrets .Alice , proveReceipt , params )
473
+
474
+ // Wait for Pessimism to process the finalized withdrawal and send a notification to the mocked Slack server.
475
+ require .NoError (t , wait .For (context .Background (), 500 * time .Millisecond , func () (bool , error ) {
476
+ id := ids [0 ].PathID
477
+ height , err := ts .Subsystems .PathHeight (id )
478
+ if err != nil {
479
+ return false , err
480
+ }
481
+
482
+ return height .Uint64 () > finalizeReceipt .BlockNumber .Uint64 (), nil
483
+ }))
484
+
485
+ // Ensure that this withdrawal flow triggered no alerts
435
486
alerts := ts .TestSlackSvr .SlackAlerts ()
436
- require .Equal (t , 0 , len (alerts ), "expected 0 alerts" )
487
+ require .Equal (t , 0 , len (alerts ))
437
488
}
438
489
439
490
// TestFaultDetector ... Ensures that an alert is produced in the presence of a faulty L2Output root
0 commit comments