From f5da1bf2d103c40ad5c802aedd5153ba6dd97592 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Fri, 9 Feb 2024 15:37:36 +1100 Subject: [PATCH] Fix bug when delegation does not exists --- x/btcstaking/keeper/btc_delegators.go | 8 ++- x/btcstaking/keeper/keeper_test.go | 4 ++ x/btcstaking/keeper/msg_server_test.go | 75 +++++++++++++++++++++++--- 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/x/btcstaking/keeper/btc_delegators.go b/x/btcstaking/keeper/btc_delegators.go index 146b2e7be..f9d89dcca 100644 --- a/x/btcstaking/keeper/btc_delegators.go +++ b/x/btcstaking/keeper/btc_delegators.go @@ -139,7 +139,13 @@ func (k Keeper) GetBTCDelegation(ctx context.Context, stakingTxHashStr string) ( return nil, err } - return k.getBTCDelegation(ctx, *stakingTxHash), nil + // find BTC delegation from KV store + btcDel := k.getBTCDelegation(ctx, *stakingTxHash) + if btcDel == nil { + return nil, types.ErrBTCDelegationNotFound + } + + return btcDel, nil } // btcDelegatorStore returns the KVStore of the BTC delegators diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index dbaebda33..6cf8e67cc 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -53,6 +53,10 @@ func (h *Helper) NoError(err error) { require.NoError(h.t, err) } +func (h *Helper) Error(err error) { + require.Error(h.t, err) +} + func (h *Helper) GenAndApplyParams(r *rand.Rand) ([]*btcec.PrivateKey, []*btcec.PublicKey) { return h.GenAndApplyCustomParams(r, 100, 0) } diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 053fcb7ca..58b6536dc 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -70,7 +70,7 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { }) } -func FuzzCreateBTCDelegationAndAddCovenantSigs(f *testing.F) { +func FuzzCreateBTCDelegation(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { @@ -84,7 +84,7 @@ func FuzzCreateBTCDelegationAndAddCovenantSigs(f *testing.F) { h := NewHelper(t, btclcKeeper, btccKeeper) // set all parameters - covenantSKs, _ := h.GenAndApplyParams(r) + h.GenAndApplyParams(r) changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) require.NoError(t, err) @@ -114,9 +114,55 @@ func FuzzCreateBTCDelegationAndAddCovenantSigs(f *testing.F) { h.NoError(err) // delegation is not activated by covenant yet require.False(h.t, actualDel.HasCovenantQuorums(h.BTCStakingKeeper.GetParams(h.Ctx).CovenantQuorum)) + }) +} + +func FuzzAddCovenantSigs(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // mock BTC light client and BTC checkpoint modules + btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) + btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper) + + // set all parameters + covenantSKs, _ := h.GenAndApplyParams(r) + + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + require.NoError(t, err) + + // generate and insert new finality provider + _, fpPK, _ := h.CreateFinalityProvider(r) + + // generate and insert new BTC delegation + stakingValue := int64(2 * 10e8) + stakingTxHash, _, _, msgCreateBTCDel := h.CreateDelegation( + r, + fpPK, + changeAddress.EncodeAddress(), + stakingValue, + 1000, + ) + + // ensure consistency between the msg and the BTC delegation in DB + actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) + h.NoError(err) + // delegation is not activated by covenant yet + require.False(h.t, actualDel.HasCovenantQuorums(h.BTCStakingKeeper.GetParams(h.Ctx).CovenantQuorum)) msgs := h.GenerateCovenantSignaturesMessages(r, covenantSKs, msgCreateBTCDel, actualDel) + // ensure the system does not panick due to a bogus covenant sig request + bogusMsg := *msgs[0] + bogusMsg.StakingTxHash = datagen.GenRandomBtcdHash(r).String() + _, err = h.MsgServer.AddCovenantSigs(h.Ctx, &bogusMsg) + h.Error(err) + for _, msg := range msgs { _, err = h.MsgServer.AddCovenantSigs(h.Ctx, msg) h.NoError(err) @@ -182,14 +228,23 @@ func FuzzBTCUndelegate(f *testing.F) { status := actualDel.GetStatus(btcTip, wValue, bsParams.CovenantQuorum) require.Equal(t, types.BTCDelegationStatus_ACTIVE, status) - // delegator wants to unbond + // construct unbonding msg delUnbondingSig, err := actualDel.SignUnbondingTx(&bsParams, h.Net, delSK) h.NoError(err) - _, err = h.MsgServer.BTCUndelegate(h.Ctx, &types.MsgBTCUndelegate{ + msg := &types.MsgBTCUndelegate{ Signer: datagen.GenRandomAccount().Address, StakingTxHash: stakingTxHash, UnbondingTxSig: bbn.NewBIP340SignatureFromBTCSig(delUnbondingSig), - }) + } + + // ensure the system does not panick due to a bogus unbonding msg + bogusMsg := *msg + bogusMsg.StakingTxHash = datagen.GenRandomBtcdHash(r).String() + _, err = h.MsgServer.BTCUndelegate(h.Ctx, &bogusMsg) + h.Error(err) + + // unbond + _, err = h.MsgServer.BTCUndelegate(h.Ctx, msg) h.NoError(err) // ensure the BTC delegation is unbonded @@ -244,12 +299,20 @@ func FuzzSelectiveSlashing(f *testing.F) { h.NoError(err) require.True(t, actualDel.HasCovenantQuorums(bsParams.CovenantQuorum)) - // submit evidence of selective slashing + // construct message for the evidence of selective slashing msg := &types.MsgSelectiveSlashingEvidence{ Signer: datagen.GenRandomAccount().Address, StakingTxHash: actualDel.MustGetStakingTxHash().String(), RecoveredFpBtcSk: fpSK.Serialize(), } + + // ensure the system does not panick due to a bogus unbonding msg + bogusMsg := *msg + bogusMsg.StakingTxHash = datagen.GenRandomBtcdHash(r).String() + _, err = h.MsgServer.SelectiveSlashingEvidence(h.Ctx, &bogusMsg) + h.Error(err) + + // submit evidence of selective slashing _, err = h.MsgServer.SelectiveSlashingEvidence(h.Ctx, msg) h.NoError(err)