From aa13e8d91b35b3f41f45bc1533e375dcf1da801f Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Tue, 6 Aug 2024 13:35:05 +0800 Subject: [PATCH] add fuzz tests --- x/finality/keeper/grpc_query_test.go | 1 + x/finality/keeper/msg_server_test.go | 36 ++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/x/finality/keeper/grpc_query_test.go b/x/finality/keeper/grpc_query_test.go index d8d878696..4be3cf145 100644 --- a/x/finality/keeper/grpc_query_test.go +++ b/x/finality/keeper/grpc_query_test.go @@ -205,6 +205,7 @@ func FuzzListPubRandCommit(f *testing.F) { require.NoError(t, err) bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(bip340PK.MustMarshal())).Return(fp, nil).AnyTimes() bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(bip340PK.MustMarshal())).Return(true).AnyTimes() + bsKeeper.EXPECT().GetEpoch(gomock.Any()).Return(uint64(1)).AnyTimes() numPrCommitList := datagen.RandomInt(r, 10) + 1 prCommitList := []*types.PubRandCommit{} diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index 231ef895e..e622fd0e3 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -7,14 +7,15 @@ import ( "time" "cosmossdk.io/core/header" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonlabs-io/babylon/testutil/datagen" keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" bbn "github.com/babylonlabs-io/babylon/types" bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/babylonlabs-io/babylon/x/finality/keeper" "github.com/babylonlabs-io/babylon/x/finality/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func setupMsgServer(t testing.TB) (*keeper.Keeper, types.MsgServer, context.Context) { @@ -29,7 +30,7 @@ func TestMsgServer(t *testing.T) { } func FuzzCommitPubRandList(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) + datagen.AddRandomSeedsToFuzzer(f, 100) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) @@ -39,6 +40,8 @@ func FuzzCommitPubRandList(f *testing.F) { bsKeeper := types.NewMockBTCStakingKeeper(ctrl) fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil) ms := keeper.NewMsgServerImpl(*fKeeper) + committedEpochNum := datagen.GenRandomEpochNum(r) + bsKeeper.EXPECT().GetEpoch(gomock.Any()).Return(committedEpochNum).AnyTimes() // create a random finality provider btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) @@ -75,6 +78,11 @@ func FuzzCommitPubRandList(f *testing.F) { // query last public randomness and assert lastPrCommit := fKeeper.GetLastPubRandCommit(ctx, fpBTCPK) require.NotNil(t, lastPrCommit) + require.Equal(t, committedEpochNum, lastPrCommit.EpochNum) + committedHeight := datagen.RandomInt(r, int(numPubRand)) + startHeight + commitByHeight, err := fKeeper.GetPubRandCommitForHeight(ctx, fpBTCPK, committedHeight) + require.NoError(t, err) + require.Equal(t, committedEpochNum, commitByHeight.EpochNum) // Case 4: commit a pubrand list with overlap of the existing pubrand in KVStore and it should fail overlappedStartHeight := startHeight + numPubRand - 1 - datagen.RandomInt(r, 5) @@ -93,7 +101,7 @@ func FuzzCommitPubRandList(f *testing.F) { } func FuzzAddFinalitySig(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) + datagen.AddRandomSeedsToFuzzer(f, 100) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) @@ -113,6 +121,11 @@ func FuzzAddFinalitySig(f *testing.F) { fpBTCPKBytes := fpBTCPK.MustMarshal() require.NoError(t, err) bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(true).AnyTimes() + + // set committed epoch num + committedEpochNum := datagen.GenRandomEpochNum(r) + 1 + bsKeeper.EXPECT().GetEpoch(gomock.Any()).Return(committedEpochNum).AnyTimes() + // commit some public randomness startHeight := uint64(0) numPubRand := uint64(200) @@ -128,6 +141,18 @@ func FuzzAddFinalitySig(f *testing.F) { msg, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blockHeight, randListInfo, blockAppHash) require.NoError(t, err) + // Case 0: fail if the committed epoch is not finalized + lastFinalizedEpoch := datagen.RandomInt(r, int(committedEpochNum)) + o1 := bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(lastFinalizedEpoch).Times(1) + bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes), gomock.Eq(blockHeight)).Return(uint64(1)).Times(1) + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) + _, err = ms.AddFinalitySig(ctx, msg) + require.ErrorIs(t, err, types.ErrPubRandCommitNotBTCTimestamped) + + // set the committed epoch finalized for the rest of the cases + lastFinalizedEpoch = datagen.GenRandomEpochNum(r) + committedEpochNum + bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(lastFinalizedEpoch).After(o1).AnyTimes() + // Case 1: fail if the finality provider does not have voting power bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes), gomock.Eq(blockHeight)).Return(uint64(0)).Times(1) bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) @@ -220,6 +245,8 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { require.NoError(t, err) bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(true).AnyTimes() + bsKeeper.EXPECT().GetEpoch(gomock.Any()).Return(uint64(1)).AnyTimes() + bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(1)).AnyTimes() // commit some public randomness startHeight := uint64(0) numPubRand := uint64(200) @@ -245,7 +272,6 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { // some "evidence" ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: forkHash}) msg1, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blockHeight, randListInfo, forkHash) - require.NoError(t, err) bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes),