diff --git a/x/cada/keeper/vote_extension.go b/x/cada/keeper/vote_extension.go index 8428a11..ede6845 100644 --- a/x/cada/keeper/vote_extension.go +++ b/x/cada/keeper/vote_extension.go @@ -94,9 +94,35 @@ func (h *VoteExtHandler) ExtendVoteHandler() sdk.ExtendVoteHandler { // VerifyVoteExtensionHandler handles the verification of vote extensions by validating the provided vote extension data. // This function is used to verify the correctness and validity of the vote extensions submitted during the voting process. +// func (h *VoteExtHandler) VerifyVoteExtensionHandler() sdk.VerifyVoteExtensionHandler { +// return func(_ sdk.Context, _ *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { +// // TODO: add proper validation for the votes if any +// return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil +// } +// } + func (h *VoteExtHandler) VerifyVoteExtensionHandler() sdk.VerifyVoteExtensionHandler { - return func(_ sdk.Context, _ *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { - // TODO: add proper validation for the votes if any - return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil + return func(_ sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + if req == nil { + return &abci.ResponseVerifyVoteExtension{ + Status: abci.ResponseVerifyVoteExtension_REJECT, + }, fmt.Errorf("request is nil") + } + // Example: Validate vote height (assuming the vote has a height field) + if req.Height <= 0 { + return &abci.ResponseVerifyVoteExtension{ + Status: abci.ResponseVerifyVoteExtension_REJECT, + }, fmt.Errorf("invalid vote height: %d", req.Height) + } + + if len(req.VoteExtension) == 0 { + return &abci.ResponseVerifyVoteExtension{ + Status: abci.ResponseVerifyVoteExtension_REJECT, + }, fmt.Errorf("vote extension data is empty") + } + + return &abci.ResponseVerifyVoteExtension{ + Status: abci.ResponseVerifyVoteExtension_ACCEPT, + }, nil } } diff --git a/x/cada/keeper/vote_extension_test.go b/x/cada/keeper/vote_extension_test.go index a130bc0..860524e 100644 --- a/x/cada/keeper/vote_extension_test.go +++ b/x/cada/keeper/vote_extension_test.go @@ -76,3 +76,123 @@ func (s *TestSuite) TestExtendVoteHandler() { }) } } + +func (s *TestSuite) TestVerifyVoteExtensionHandler() { + testCases := []struct { + name string + startHeight uint64 + endHeight uint64 + availHeight uint64 + blobStatus uint32 + currentHeight int64 + voteEndHeight uint64 + isLastVoting bool + expectErr bool + req *abci.RequestVerifyVoteExtension + expectedError string + }{ + { + name: "nil request", + startHeight: 1, + endHeight: 20, + availHeight: 30, + blobStatus: 3, + currentHeight: 22, + voteEndHeight: 20, + isLastVoting: false, + expectErr: true, + req: nil, + expectedError: "request is nil", + }, + { + name: "invalid vote height", + startHeight: 1, + endHeight: 20, + availHeight: 30, + blobStatus: 2, + currentHeight: 30, + voteEndHeight: 31, + isLastVoting: true, + expectErr: true, + req: &abci.RequestVerifyVoteExtension{ + Height: -1, + VoteExtension: []byte("valid extension"), + }, + expectedError: "invalid vote height: -1", + }, + { + name: "empty vote extension", + startHeight: 1, + endHeight: 20, + availHeight: 30, + blobStatus: 2, + currentHeight: 30, + voteEndHeight: 31, + isLastVoting: true, + expectErr: true, + req: &abci.RequestVerifyVoteExtension{ + Height: 1, + VoteExtension: []byte{}, + }, + expectedError: "vote extension data is empty", + }, + { + name: "valid request", + startHeight: 1, + endHeight: 20, + availHeight: 30, + blobStatus: 2, + currentHeight: 30, + voteEndHeight: 31, + isLastVoting: true, + expectErr: false, + req: &abci.RequestVerifyVoteExtension{ + Height: 1, + VoteExtension: []byte("valid extension"), + }, + expectedError: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + // Set up block height and blob status + s.ctx = s.ctx.WithBlockHeight(tc.currentHeight) + + err := store.UpdateStartHeight(s.ctx, s.store, tc.startHeight) + s.Require().NoError(err) + + err = store.UpdateEndHeight(s.ctx, s.store, tc.endHeight) + s.Require().NoError(err) + + err = store.UpdateAvailHeight(s.ctx, s.store, tc.availHeight) + s.Require().NoError(err) + + err = store.UpdateBlobStatus(s.ctx, s.store, tc.blobStatus) + s.Require().NoError(err) + + err = store.UpdateVotingEndHeight(s.ctx, s.store, tc.voteEndHeight, tc.isLastVoting) + s.Require().NoError(err) + + verifyVoteExtensionHandler := s.voteExtensionHandler.VerifyVoteExtensionHandler() + + // Handle nil request + var res *abci.ResponseVerifyVoteExtension + if tc.req == nil { + res, err = verifyVoteExtensionHandler(s.ctx, nil) + } else { + res, err = verifyVoteExtensionHandler(s.ctx, tc.req) + } + + if tc.expectErr { + s.Require().Error(err) + s.Require().Contains(err.Error(), tc.expectedError) + s.Require().Equal(abci.ResponseVerifyVoteExtension_REJECT, res.Status) + } else { + s.Require().NoError(err) + s.Require().NotNil(res) + s.Require().Equal(abci.ResponseVerifyVoteExtension_ACCEPT, res.Status) + } + }) + } +}