From cef7d7089aaaf0ffa26cd7b6ecee7535aa9baf33 Mon Sep 17 00:00:00 2001
From: Troy Kessler <43882936+troykessler@users.noreply.github.com>
Date: Thu, 12 Dec 2024 16:31:26 +0100
Subject: [PATCH] fix: added test case for points (#207)

Co-authored-by: rapha <dev@uupi.cloud>
---
 .../keeper/msg_server_skip_uploader_role.go   | 16 ++++
 .../msg_server_skip_uploader_role_test.go     | 86 ++++++++++++++++++-
 2 files changed, 98 insertions(+), 4 deletions(-)

diff --git a/x/bundles/keeper/msg_server_skip_uploader_role.go b/x/bundles/keeper/msg_server_skip_uploader_role.go
index bc5d41e1..66da8df7 100644
--- a/x/bundles/keeper/msg_server_skip_uploader_role.go
+++ b/x/bundles/keeper/msg_server_skip_uploader_role.go
@@ -20,6 +20,22 @@ func (k msgServer) SkipUploaderRole(goCtx context.Context, msg *types.MsgSkipUpl
 	// reset points of uploader as node has proven to be active
 	k.resetPoints(ctx, msg.PoolId, msg.Staker)
 
+	// If previous bundle was dropped just skip uploader role
+	// No previous round needs to be evaluated
+	if bundleProposal.StorageId == "" {
+		nextUploader := k.chooseNextUploader(ctx, msg.PoolId)
+
+		// Register empty bundle with next uploader
+		bundleProposal = types.BundleProposal{
+			PoolId:       msg.PoolId,
+			NextUploader: nextUploader,
+			UpdatedAt:    uint64(ctx.BlockTime().Unix()),
+		}
+		k.SetBundleProposal(ctx, bundleProposal)
+
+		return &types.MsgSkipUploaderRoleResponse{}, nil
+	}
+
 	// Previous round contains a bundle which needs to be validated now
 	result, err := k.tallyBundleProposal(ctx, bundleProposal, msg.PoolId)
 	if err != nil {
diff --git a/x/bundles/keeper/msg_server_skip_uploader_role_test.go b/x/bundles/keeper/msg_server_skip_uploader_role_test.go
index 7ab91d7c..5bc09f8c 100644
--- a/x/bundles/keeper/msg_server_skip_uploader_role_test.go
+++ b/x/bundles/keeper/msg_server_skip_uploader_role_test.go
@@ -50,7 +50,7 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 		}
 		s.RunTxPoolSuccess(msg)
 
-		//// create funders
+		// create funders
 		s.RunTxFundersSuccess(&funderstypes.MsgCreateFunder{
 			Creator: i.ALICE,
 			Moniker: "Alice",
@@ -125,6 +125,22 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 
 	It("Skip uploader role on data bundle if staker is next uploader", func() {
 		// ARRANGE
+		s.RunTxBundlesSuccess(&bundletypes.MsgVoteBundleProposal{
+			Creator:   i.VALADDRESS_1_A,
+			Staker:    i.STAKER_1,
+			PoolId:    0,
+			StorageId: "y62A3tfbSNcNYDGoL-eXwzyV-Zc9Q0OVtDvR1biJmNI",
+			Vote:      bundletypes.VOTE_TYPE_ABSTAIN,
+		})
+
+		s.RunTxBundlesSuccess(&bundletypes.MsgVoteBundleProposal{
+			Creator:   i.VALADDRESS_2_A,
+			Staker:    i.STAKER_2,
+			PoolId:    0,
+			StorageId: "y62A3tfbSNcNYDGoL-eXwzyV-Zc9Q0OVtDvR1biJmNI",
+			Vote:      bundletypes.VOTE_TYPE_ABSTAIN,
+		})
+
 		s.Commit()
 		s.WaitSeconds(60)
 
@@ -152,7 +168,8 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 		Expect(bundleProposal.UpdatedAt).NotTo(BeZero())
 		Expect(bundleProposal.VotersValid).To(ContainElement(i.STAKER_0))
 		Expect(bundleProposal.VotersInvalid).To(BeEmpty())
-		Expect(bundleProposal.VotersAbstain).To(BeEmpty())
+		Expect(bundleProposal.VotersAbstain).To(ContainElement(i.STAKER_1))
+		Expect(bundleProposal.VotersAbstain).To(ContainElement(i.STAKER_2))
 
 		// here the next uploader should be always be different after skipping
 		Expect(bundleProposal.NextUploader).To(Equal(i.STAKER_0))
@@ -160,10 +177,32 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 		// check that the bundle is not finalized
 		_, found = s.App().BundlesKeeper.GetFinalizedBundle(s.Ctx(), 0, 0)
 		Expect(found).To(BeFalse())
+
+		// check that no validator got a point for the second round
+		valaccounts := s.App().StakersKeeper.GetAllValaccountsOfPool(s.Ctx(), 0)
+		for _, valaccount := range valaccounts {
+			Expect(valaccount.Points).To(BeZero())
+		}
 	})
 
 	It("Skip uploader on data bundle after uploader role has already been skipped", func() {
 		// ARRANGE
+		s.RunTxBundlesSuccess(&bundletypes.MsgVoteBundleProposal{
+			Creator:   i.VALADDRESS_1_A,
+			Staker:    i.STAKER_1,
+			PoolId:    0,
+			StorageId: "y62A3tfbSNcNYDGoL-eXwzyV-Zc9Q0OVtDvR1biJmNI",
+			Vote:      bundletypes.VOTE_TYPE_ABSTAIN,
+		})
+
+		s.RunTxBundlesSuccess(&bundletypes.MsgVoteBundleProposal{
+			Creator:   i.VALADDRESS_2_A,
+			Staker:    i.STAKER_2,
+			PoolId:    0,
+			StorageId: "y62A3tfbSNcNYDGoL-eXwzyV-Zc9Q0OVtDvR1biJmNI",
+			Vote:      bundletypes.VOTE_TYPE_ABSTAIN,
+		})
+
 		s.Commit()
 		s.WaitSeconds(60)
 
@@ -201,14 +240,21 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 		Expect(bundleProposal.UpdatedAt).NotTo(BeZero())
 		Expect(bundleProposal.VotersValid).To(ContainElement(i.STAKER_0))
 		Expect(bundleProposal.VotersInvalid).To(BeEmpty())
-		Expect(bundleProposal.VotersAbstain).To(BeEmpty())
+		Expect(bundleProposal.VotersAbstain).To(ContainElement(i.STAKER_1))
+		Expect(bundleProposal.VotersAbstain).To(ContainElement(i.STAKER_2))
 
-		// here the next uploader should be always be different after skipping
+		// here the next uploader should always be different after skipping
 		Expect(bundleProposal.NextUploader).NotTo(Equal(i.STAKER_0))
 
 		// check that the bundle is not finalized
 		_, found = s.App().BundlesKeeper.GetFinalizedBundle(s.Ctx(), 0, 0)
 		Expect(found).To(BeFalse())
+
+		// check that no validator got a point for the second round
+		valaccounts := s.App().StakersKeeper.GetAllValaccountsOfPool(s.Ctx(), 0)
+		for _, valaccount := range valaccounts {
+			Expect(valaccount.Points).To(BeZero())
+		}
 	})
 
 	It("Skip uploader role on dropped bundle", func() {
@@ -252,6 +298,17 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 		// check that the bundle is not finalized
 		_, found = s.App().BundlesKeeper.GetFinalizedBundle(s.Ctx(), 0, 0)
 		Expect(found).To(BeFalse())
+
+		// check that no validator got a point for the second round
+		valaccounts := s.App().StakersKeeper.GetAllValaccountsOfPool(s.Ctx(), 0)
+		for _, valaccount := range valaccounts {
+			if valaccount.Staker == i.STAKER_0 {
+				Expect(valaccount.Points).To(BeZero())
+			} else {
+				// All others have one point because they did not vote at all
+				Expect(valaccount.Points).To(Equal(uint64(1)))
+			}
+		}
 	})
 
 	It("Skip uploader role on data bundle with current round containing a valid bundle", func() {
@@ -264,6 +321,14 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 			Vote:      bundletypes.VOTE_TYPE_VALID,
 		})
 
+		s.RunTxBundlesSuccess(&bundletypes.MsgVoteBundleProposal{
+			Creator:   i.VALADDRESS_2_A,
+			Staker:    i.STAKER_2,
+			PoolId:    0,
+			StorageId: "y62A3tfbSNcNYDGoL-eXwzyV-Zc9Q0OVtDvR1biJmNI",
+			Vote:      bundletypes.VOTE_TYPE_VALID,
+		})
+
 		s.Commit()
 		s.WaitSeconds(60)
 
@@ -300,6 +365,12 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 
 		Expect(finalizedBundle.PoolId).To(Equal(uint64(0)))
 		Expect(finalizedBundle.Uploader).To(Equal(i.STAKER_0))
+
+		// check if no validator got a point for the second round
+		valaccounts := s.App().StakersKeeper.GetAllValaccountsOfPool(s.Ctx(), 0)
+		for _, valaccount := range valaccounts {
+			Expect(valaccount.Points).To(BeZero())
+		}
 	})
 
 	It("Skip uploader role on data bundle with current round containing an invalid bundle", func() {
@@ -311,6 +382,7 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 			StorageId: "y62A3tfbSNcNYDGoL-eXwzyV-Zc9Q0OVtDvR1biJmNI",
 			Vote:      bundletypes.VOTE_TYPE_INVALID,
 		})
+
 		s.RunTxBundlesSuccess(&bundletypes.MsgVoteBundleProposal{
 			Creator:   i.VALADDRESS_2_A,
 			Staker:    i.STAKER_2,
@@ -352,5 +424,11 @@ var _ = Describe("msg_server_skip_uploader_role.go", Ordered, func() {
 		// check that the bundle is not finalized
 		_, found = s.App().BundlesKeeper.GetFinalizedBundle(s.Ctx(), 0, 0)
 		Expect(found).To(BeFalse())
+
+		// check that no validator got a point
+		valaccounts := s.App().StakersKeeper.GetAllValaccountsOfPool(s.Ctx(), 0)
+		for _, valaccount := range valaccounts {
+			Expect(valaccount.Points).To(BeZero())
+		}
 	})
 })