@@ -630,13 +630,224 @@ func TestGasConsumption_ZeroIncomingLimit(t *testing.T) {
630630 require .Zero (t , pendingMBs ) // added all
631631}
632632
633+ func TestGasConsumption_RevertIncomingMiniBlocks (t * testing.T ) {
634+ t .Parallel ()
635+
636+ t .Run ("empty mini block hashes should early exit" , func (t * testing.T ) {
637+ t .Parallel ()
638+
639+ gc , _ := block .NewGasConsumption (getMockArgsGasConsumption ())
640+ require .NotNil (t , gc )
641+
642+ gc .RevertIncomingMiniBlocks (nil )
643+ })
644+
645+ t .Run ("revert non-pending mini block should decrease total gas consumed" , func (t * testing.T ) {
646+ t .Parallel ()
647+
648+ gc , _ := block .NewGasConsumption (getMockArgsGasConsumption ())
649+ require .NotNil (t , gc )
650+
651+ // add mini blocks that will be within limits
652+ mbs := generateMiniBlocks (3 , 5 )
653+ txs := generateTxsForMiniBlocks (mbs )
654+ lastMbIndex , pendingMbs , err := gc .CheckIncomingMiniBlocks (mbs , txs )
655+ require .NoError (t , err )
656+ require .Equal (t , 2 , lastMbIndex )
657+ require .Zero (t , pendingMbs )
658+
659+ totalGasBeforeRevert := gc .TotalGasConsumed ()
660+ expectedGasPerMb := maxGasLimitPerTx * 5 // 5 txs per mini block
661+
662+ // revert the first mini block and one none existing for coverage
663+ gc .RevertIncomingMiniBlocks ([][]byte {mbs [0 ].GetHash (), []byte ("non-existent-hash" )})
664+
665+ // total gas should decrease by the gas consumed by the first mini block
666+ require .Equal (t , totalGasBeforeRevert - expectedGasPerMb , gc .TotalGasConsumed ())
667+
668+ // revert the second and third mini blocks
669+ gc .RevertIncomingMiniBlocks ([][]byte {mbs [1 ].GetHash (), mbs [2 ].GetHash ()})
670+
671+ // total gas should be zero now
672+ require .Equal (t , uint64 (0 ), gc .TotalGasConsumed ())
673+ })
674+
675+ t .Run ("revert pending mini block at first position" , func (t * testing.T ) {
676+ t .Parallel ()
677+
678+ gc , _ := block .NewGasConsumption (getMockArgsGasConsumption ())
679+ require .NotNil (t , gc )
680+
681+ // add more mini blocks than the limit to create pending ones
682+ mbs := generateMiniBlocks (10 , 5 )
683+ txs := generateTxsForMiniBlocks (mbs )
684+ lastMbIndex , pendingMbs , err := gc .CheckIncomingMiniBlocks (mbs , txs )
685+ require .NoError (t , err )
686+ require .Equal (t , 7 , lastMbIndex )
687+ require .Equal (t , 2 , pendingMbs )
688+
689+ // get pending mini blocks
690+ pendingMiniBlocks := gc .GetPendingMiniBlocks ()
691+ require .Len (t , pendingMiniBlocks , 2 )
692+
693+ totalGasBeforeRevert := gc .TotalGasConsumed ()
694+
695+ // revert the first pending mini block
696+ firstPendingHash := mbs [8 ].GetHash ()
697+ gc .RevertIncomingMiniBlocks ([][]byte {firstPendingHash })
698+
699+ // total gas should stay the same, only a pending mini block was removed
700+ require .Equal (t , totalGasBeforeRevert , gc .TotalGasConsumed ())
701+
702+ // check that pending mini blocks were updated
703+ updatedPendingMiniBlocks := gc .GetPendingMiniBlocks ()
704+ require .Len (t , updatedPendingMiniBlocks , 1 )
705+ require .Equal (t , mbs [9 ].GetHash (), updatedPendingMiniBlocks [0 ].GetHash ())
706+ })
707+
708+ t .Run ("revert pending mini block at last position" , func (t * testing.T ) {
709+ t .Parallel ()
710+
711+ gc , _ := block .NewGasConsumption (getMockArgsGasConsumption ())
712+ require .NotNil (t , gc )
713+
714+ // add more mini blocks than the limit to create pending ones
715+ mbs := generateMiniBlocks (10 , 5 )
716+ txs := generateTxsForMiniBlocks (mbs )
717+ lastMbIndex , pendingMbs , err := gc .CheckIncomingMiniBlocks (mbs , txs )
718+ require .NoError (t , err )
719+ require .Equal (t , 7 , lastMbIndex )
720+ require .Equal (t , 2 , pendingMbs )
721+
722+ // get pending mini blocks
723+ pendingMiniBlocks := gc .GetPendingMiniBlocks ()
724+ require .Len (t , pendingMiniBlocks , 2 )
725+
726+ totalGasBeforeRevert := gc .TotalGasConsumed ()
727+
728+ // revert the last pending mini block (index 9, which is the last in pending)
729+ lastPendingHash := mbs [9 ].GetHash ()
730+ gc .RevertIncomingMiniBlocks ([][]byte {lastPendingHash })
731+
732+ // total gas should stay the same, only a pending mini block was removed
733+ require .Equal (t , totalGasBeforeRevert , gc .TotalGasConsumed ())
734+
735+ // check that pending mini blocks were updated
736+ updatedPendingMiniBlocks := gc .GetPendingMiniBlocks ()
737+ require .Len (t , updatedPendingMiniBlocks , 1 )
738+ require .Equal (t , mbs [8 ].GetHash (), updatedPendingMiniBlocks [0 ].GetHash ())
739+ })
740+
741+ t .Run ("revert pending mini block at middle position" , func (t * testing.T ) {
742+ t .Parallel ()
743+
744+ gc , _ := block .NewGasConsumption (getMockArgsGasConsumption ())
745+ require .NotNil (t , gc )
746+
747+ // add more mini blocks than the limit to create 3 pending ones
748+ mbs := generateMiniBlocks (11 , 5 )
749+ txs := generateTxsForMiniBlocks (mbs )
750+ lastMbIndex , pendingMbs , err := gc .CheckIncomingMiniBlocks (mbs , txs )
751+ require .NoError (t , err )
752+ require .Equal (t , 7 , lastMbIndex )
753+ require .Equal (t , 3 , pendingMbs )
754+
755+ // get pending mini blocks
756+ pendingMiniBlocks := gc .GetPendingMiniBlocks ()
757+ require .Len (t , pendingMiniBlocks , 3 )
758+
759+ totalGasBeforeRevert := gc .TotalGasConsumed ()
760+
761+ // revert the middle pending mini block (index 9, which is the middle in pending)
762+ middlePendingHash := mbs [9 ].GetHash ()
763+ gc .RevertIncomingMiniBlocks ([][]byte {middlePendingHash })
764+
765+ // total gas should stay the same, only a pending mini block was removed
766+ require .Equal (t , totalGasBeforeRevert , gc .TotalGasConsumed ())
767+
768+ // check that pending mini blocks were updated
769+ updatedPendingMiniBlocks := gc .GetPendingMiniBlocks ()
770+ require .Len (t , updatedPendingMiniBlocks , 2 )
771+ require .Equal (t , mbs [8 ].GetHash (), updatedPendingMiniBlocks [0 ].GetHash ())
772+ require .Equal (t , mbs [10 ].GetHash (), updatedPendingMiniBlocks [1 ].GetHash ())
773+ })
774+
775+ t .Run ("revert multiple mini blocks with mixed pending and non-pending" , func (t * testing.T ) {
776+ t .Parallel ()
777+
778+ gc , _ := block .NewGasConsumption (getMockArgsGasConsumption ())
779+ require .NotNil (t , gc )
780+
781+ // add mini blocks, some will be pending
782+ mbs := generateMiniBlocks (10 , 5 )
783+ txs := generateTxsForMiniBlocks (mbs )
784+ lastMbIndex , pendingMbs , err := gc .CheckIncomingMiniBlocks (mbs , txs )
785+ require .NoError (t , err )
786+ require .Equal (t , 7 , lastMbIndex )
787+ require .Equal (t , 2 , pendingMbs )
788+
789+ totalGasBeforeRevert := gc .TotalGasConsumed ()
790+ expectedGasPerMb := maxGasLimitPerTx * 5
791+
792+ // revert both a non-pending mini block (index 0) and a pending one (index 8)
793+ hashesToRevert := [][]byte {
794+ mbs [0 ].GetHash (), // non-pending
795+ mbs [8 ].GetHash (), // pending (first in pending)
796+ }
797+ gc .RevertIncomingMiniBlocks (hashesToRevert )
798+
799+ // total gas should decrease only by the non-pending mini block
800+ require .Equal (t , totalGasBeforeRevert - expectedGasPerMb , gc .TotalGasConsumed ())
801+
802+ // pending mini blocks should be reduced by one
803+ updatedPendingMiniBlocks := gc .GetPendingMiniBlocks ()
804+ require .Len (t , updatedPendingMiniBlocks , 1 )
805+ require .Equal (t , mbs [9 ].GetHash (), updatedPendingMiniBlocks [0 ].GetHash ())
806+ })
807+
808+ t .Run ("revert all pending mini blocks" , func (t * testing.T ) {
809+ t .Parallel ()
810+
811+ gc , _ := block .NewGasConsumption (getMockArgsGasConsumption ())
812+ require .NotNil (t , gc )
813+
814+ // add mini blocks with pending ones
815+ mbs := generateMiniBlocks (10 , 5 )
816+ txs := generateTxsForMiniBlocks (mbs )
817+ lastMbIndex , pendingMbs , err := gc .CheckIncomingMiniBlocks (mbs , txs )
818+ require .NoError (t , err )
819+ require .Equal (t , 7 , lastMbIndex )
820+ require .Equal (t , 2 , pendingMbs )
821+
822+ totalGasBeforeRevert := gc .TotalGasConsumed ()
823+
824+ // revert all pending mini blocks
825+ hashesToRevert := [][]byte {
826+ mbs [8 ].GetHash (),
827+ mbs [9 ].GetHash (),
828+ }
829+ gc .RevertIncomingMiniBlocks (hashesToRevert )
830+
831+ // total gas should stay the same, only pending mini blocks were removed
832+ require .Equal (t , totalGasBeforeRevert , gc .TotalGasConsumed ())
833+
834+ // no pending mini blocks should remain
835+ updatedPendingMiniBlocks := gc .GetPendingMiniBlocks ()
836+ require .Len (t , updatedPendingMiniBlocks , 0 )
837+ })
838+ }
839+
633840func TestGasConsumption_ConcurrentOps (t * testing.T ) {
634841 if testing .Short () {
635842 t .Skip ("this is not a short test" )
636843 }
637844
638845 require .NotPanics (t , func () {
639846 mbs := generateMiniBlocks (1 , 2 )
847+ mbsHashes := make ([][]byte , len (mbs ))
848+ for _ , mb := range mbs {
849+ mbsHashes = append (mbsHashes , mb .GetHash ())
850+ }
640851 txsInMBs := generateTxsForMiniBlocks (mbs )
641852
642853 txHashes , txs := generateTxs (maxGasLimitPerTx , 3 )
@@ -650,7 +861,7 @@ func TestGasConsumption_ConcurrentOps(t *testing.T) {
650861
651862 for i := 0 ; i < numCalls ; i ++ {
652863 go func (idx int ) {
653- switch idx % 11 {
864+ switch idx % 12 {
654865 case 0 :
655866 _ , _ , _ = gc .CheckOutgoingTransactions (txHashes , txs )
656867 case 1 :
@@ -673,6 +884,8 @@ func TestGasConsumption_ConcurrentOps(t *testing.T) {
673884 gc .ZeroIncomingLimit ()
674885 case 10 :
675886 gc .ZeroOutgoingLimit ()
887+ case 11 :
888+ gc .RevertIncomingMiniBlocks (mbsHashes )
676889 default :
677890 require .Fail (t , "should have not been called" )
678891 }
0 commit comments