@@ -318,6 +318,266 @@ func TestUpdater(t *testing.T) {
318318 }
319319}
320320
321+ func TestUpdaterRevertedTxns (t * testing.T ) {
322+ t .Parallel ()
323+
324+ // timestamp of the First block commitment is X
325+ startTimestamp := time .UnixMilli (1615195200000 )
326+ midTimestamp := startTimestamp .Add (time .Duration (2.5 * float64 (time .Second )))
327+ endTimestamp := startTimestamp .Add (5 * time .Second )
328+
329+ key , err := crypto .GenerateKey ()
330+ if err != nil {
331+ t .Fatal (err )
332+ }
333+
334+ builderAddr := common .HexToAddress ("0xabcd" )
335+ otherBuilderAddr := common .HexToAddress ("0xabdc" )
336+
337+ signer := types .NewLondonSigner (big .NewInt (5 ))
338+ var txns []* types.Transaction
339+ for i := 0 ; i < 10 ; i ++ {
340+ txns = append (txns , types .MustSignNewTx (key , signer , & types.DynamicFeeTx {
341+ Nonce : uint64 (i + 1 ),
342+ Gas : 1000000 ,
343+ Value : big .NewInt (1 ),
344+ GasTipCap : big .NewInt (500 ),
345+ GasFeeCap : big .NewInt (500 ),
346+ }))
347+ }
348+
349+ encCommitments := make ([]preconf.PreconfcommitmentstoreEncryptedCommitmentStored , 0 )
350+ commitments := make ([]preconf.PreconfcommitmentstoreCommitmentStored , 0 )
351+
352+ for i , txn := range txns {
353+ idxBytes := getIdxBytes (int64 (i ))
354+
355+ encCommitment := preconf.PreconfcommitmentstoreEncryptedCommitmentStored {
356+ CommitmentIndex : idxBytes ,
357+ CommitmentDigest : common .HexToHash (fmt .Sprintf ("0x%02d" , i )),
358+ CommitmentSignature : []byte ("signature" ),
359+ DispatchTimestamp : uint64 (midTimestamp .UnixMilli ()),
360+ }
361+ commitment := preconf.PreconfcommitmentstoreCommitmentStored {
362+ CommitmentIndex : idxBytes ,
363+ TxnHash : strings .TrimPrefix (txn .Hash ().Hex (), "0x" ),
364+ Bid : big .NewInt (10 ),
365+ BlockNumber : 5 ,
366+ CommitmentHash : common .HexToHash (fmt .Sprintf ("0x%02d" , i )),
367+ CommitmentSignature : []byte ("signature" ),
368+ DecayStartTimeStamp : uint64 (startTimestamp .UnixMilli ()),
369+ DecayEndTimeStamp : uint64 (endTimestamp .UnixMilli ()),
370+ DispatchTimestamp : uint64 (midTimestamp .UnixMilli ()),
371+ }
372+
373+ if i % 2 == 0 {
374+ encCommitment .Commiter = builderAddr
375+ commitment .Commiter = builderAddr
376+ encCommitments = append (encCommitments , encCommitment )
377+ commitments = append (commitments , commitment )
378+ } else {
379+ encCommitment .Commiter = otherBuilderAddr
380+ commitment .Commiter = otherBuilderAddr
381+ encCommitments = append (encCommitments , encCommitment )
382+ commitments = append (commitments , commitment )
383+ }
384+ }
385+
386+ // constructing bundles
387+ for i := 0 ; i < 10 ; i ++ {
388+ idxBytes := getIdxBytes (int64 (i + 10 ))
389+
390+ bundle := strings .TrimPrefix (txns [i ].Hash ().Hex (), "0x" )
391+ for j := i + 1 ; j < 10 ; j ++ {
392+ bundle += "," + strings .TrimPrefix (txns [j ].Hash ().Hex (), "0x" )
393+ }
394+
395+ encCommitment := preconf.PreconfcommitmentstoreEncryptedCommitmentStored {
396+ CommitmentIndex : idxBytes ,
397+ Commiter : builderAddr ,
398+ CommitmentDigest : common .HexToHash (fmt .Sprintf ("0x%02d" , i )),
399+ CommitmentSignature : []byte ("signature" ),
400+ DispatchTimestamp : uint64 (midTimestamp .UnixMilli ()),
401+ }
402+ commitment := preconf.PreconfcommitmentstoreCommitmentStored {
403+ CommitmentIndex : idxBytes ,
404+ Commiter : builderAddr ,
405+ Bid : big .NewInt (10 ),
406+ TxnHash : bundle ,
407+ BlockNumber : 5 ,
408+ CommitmentHash : common .HexToHash (fmt .Sprintf ("0x%02d" , i )),
409+ CommitmentSignature : []byte ("signature" ),
410+ DecayStartTimeStamp : uint64 (startTimestamp .UnixMilli ()),
411+ DecayEndTimeStamp : uint64 (endTimestamp .UnixMilli ()),
412+ DispatchTimestamp : uint64 (midTimestamp .UnixMilli ()),
413+ }
414+ encCommitments = append (encCommitments , encCommitment )
415+ commitments = append (commitments , commitment )
416+ }
417+
418+ register := & testWinnerRegister {
419+ winners : []testWinner {
420+ {
421+ blockNum : 5 ,
422+ winner : updater.Winner {
423+ Winner : builderAddr .Bytes (),
424+ Window : 1 ,
425+ },
426+ },
427+ },
428+ settlements : make (chan testSettlement , 1 ),
429+ encCommit : make (chan testEncryptedCommitment , 1 ),
430+ }
431+
432+ l1Client := & testEVMClient {
433+ blocks : map [int64 ]* types.Block {
434+ 5 : types .NewBlock (& types.Header {}, txns , nil , nil , NewHasher ()),
435+ },
436+ receipts : make (map [string ]* types.Receipt ),
437+ }
438+ for _ , txn := range txns {
439+ receipt := & types.Receipt {
440+ Status : types .ReceiptStatusFailed ,
441+ TxHash : txn .Hash (),
442+ }
443+ l1Client .receipts [txn .Hash ().Hex ()] = receipt
444+ }
445+
446+ pcABI , err := abi .JSON (strings .NewReader (preconf .PreconfcommitmentstoreABI ))
447+ if err != nil {
448+ t .Fatal (err )
449+ }
450+
451+ btABI , err := abi .JSON (strings .NewReader (blocktracker .BlocktrackerABI ))
452+ if err != nil {
453+ t .Fatal (err )
454+ }
455+
456+ evtMgr := events .NewListener (
457+ util .NewTestLogger (io .Discard ),
458+ & btABI ,
459+ & pcABI ,
460+ )
461+
462+ oracle := & testOracle {
463+ commitments : make (chan processedCommitment , 1 ),
464+ }
465+
466+ updtr , err := updater .NewUpdater (
467+ slog .New (slog .NewTextHandler (io .Discard , nil )),
468+ l1Client ,
469+ register ,
470+ evtMgr ,
471+ oracle ,
472+ )
473+ if err != nil {
474+ t .Fatal (err )
475+ }
476+
477+ ctx , cancel := context .WithCancel (context .Background ())
478+ done := updtr .Start (ctx )
479+
480+ w := blocktracker.BlocktrackerNewWindow {
481+ Window : big .NewInt (1 ),
482+ }
483+ publishNewWindow (evtMgr , & btABI , w )
484+
485+ for _ , ec := range encCommitments {
486+ if err := publishEncCommitment (evtMgr , & pcABI , ec ); err != nil {
487+ t .Fatal (err )
488+ }
489+
490+ select {
491+ case <- time .After (5 * time .Second ):
492+ t .Fatal ("timeout" )
493+ case enc := <- register .encCommit :
494+ if ! bytes .Equal (enc .commitmentIdx , ec .CommitmentIndex [:]) {
495+ t .Fatal ("wrong commitment index" )
496+ }
497+ if ! bytes .Equal (enc .committer , ec .Commiter .Bytes ()) {
498+ t .Fatal ("wrong committer" )
499+ }
500+ if ! bytes .Equal (enc .commitmentHash , ec .CommitmentDigest [:]) {
501+ t .Fatal ("wrong commitment hash" )
502+ }
503+ if ! bytes .Equal (enc .commitmentSignature , ec .CommitmentSignature ) {
504+ t .Fatal ("wrong commitment signature" )
505+ }
506+ if enc .dispatchTimestamp != ec .DispatchTimestamp {
507+ t .Fatal ("wrong dispatch timestamp" )
508+ }
509+ }
510+ }
511+
512+ for _ , c := range commitments {
513+ if err := publishCommitment (evtMgr , & pcABI , c ); err != nil {
514+ t .Fatal (err )
515+ }
516+
517+ if c .Commiter .Cmp (otherBuilderAddr ) == 0 {
518+ continue
519+ }
520+
521+ select {
522+ case <- time .After (5 * time .Second ):
523+ t .Fatal ("timeout" )
524+ case commitment := <- oracle .commitments :
525+ if ! bytes .Equal (commitment .commitmentIdx [:], c .CommitmentIndex [:]) {
526+ t .Fatal ("wrong commitment index" )
527+ }
528+ if commitment .blockNum .Cmp (big .NewInt (5 )) != 0 {
529+ t .Fatal ("wrong block number" )
530+ }
531+ if commitment .builder != c .Commiter {
532+ t .Fatal ("wrong builder" )
533+ }
534+ if ! commitment .isSlash {
535+ t .Fatal ("wrong isSlash" )
536+ }
537+ if commitment .residualDecay .Cmp (big .NewInt (50 )) != 0 {
538+ t .Fatal ("wrong residual decay" )
539+ }
540+ }
541+
542+ select {
543+ case <- time .After (5 * time .Second ):
544+ t .Fatal ("timeout" )
545+ case settlement := <- register .settlements :
546+ if ! bytes .Equal (settlement .commitmentIdx , c .CommitmentIndex [:]) {
547+ t .Fatal ("wrong commitment index" )
548+ }
549+ if settlement .txHash != c .TxnHash {
550+ t .Fatal ("wrong txn hash" )
551+ }
552+ if settlement .blockNum != 5 {
553+ t .Fatal ("wrong block number" )
554+ }
555+ if ! bytes .Equal (settlement .builder , c .Commiter .Bytes ()) {
556+ t .Fatal ("wrong builder" )
557+ }
558+ if settlement .amount .Uint64 () != 10 {
559+ t .Fatal ("wrong amount" )
560+ }
561+ if settlement .settlementType != updater .SettlementTypeSlash {
562+ t .Fatal ("wrong settlement type" )
563+ }
564+ if settlement .decayPercentage != 50 {
565+ t .Fatal ("wrong decay percentage" )
566+ }
567+ if settlement .window != 1 {
568+ t .Fatal ("wrong window" )
569+ }
570+ }
571+ }
572+
573+ cancel ()
574+ select {
575+ case <- done :
576+ case <- time .After (5 * time .Second ):
577+ t .Fatal ("timeout" )
578+ }
579+ }
580+
321581func TestUpdaterBundlesFailure (t * testing.T ) {
322582 t .Parallel ()
323583
0 commit comments