diff --git a/testutil/helper/helper.go b/testutil/helper/helper.go index fc34f024a..40dd21015 100644 --- a/testutil/helper/helper.go +++ b/testutil/helper/helper.go @@ -307,8 +307,8 @@ func (h *Helper) CheckDelegator(delegator sdk.AccAddress, val sdk.ValAddress, fo require.Equal(h.t, ok, found) } -func (h *Helper) AddDelegation(del *btcstakingtypes.BTCDelegation) { - err := h.App.BTCStakingKeeper.AddBTCDelegation(h.Ctx, del) +func (h *Helper) AddDelegation(del *btcstakingtypes.BTCDelegation, minUnbondingTime uint32) { + err := h.App.BTCStakingKeeper.AddBTCDelegation(h.Ctx, del, minUnbondingTime) h.NoError(err) } diff --git a/x/btcstaking/keeper/btc_delegations.go b/x/btcstaking/keeper/btc_delegations.go index 961362414..56ab5de75 100644 --- a/x/btcstaking/keeper/btc_delegations.go +++ b/x/btcstaking/keeper/btc_delegations.go @@ -18,7 +18,11 @@ import ( // - indexing the given BTC delegation in the BTC delegator store, // - saving it under BTC delegation store, and // - emit events about this BTC delegation. -func (k Keeper) AddBTCDelegation(ctx sdk.Context, btcDel *types.BTCDelegation) error { +func (k Keeper) AddBTCDelegation( + ctx sdk.Context, + btcDel *types.BTCDelegation, + minUnbondingTime uint32, +) error { if err := btcDel.ValidateBasic(); err != nil { return err } @@ -76,11 +80,6 @@ func (k Keeper) AddBTCDelegation(ctx sdk.Context, btcDel *types.BTCDelegation) e NewState: types.BTCDelegationStatus_UNBONDED, }) - btccheckpointParams := k.btccKeeper.GetParams(ctx) - stakingParams := k.GetParamsWithVersion(ctx).Params - - minUnbondingTime := types.MinimumUnbondingTime(&stakingParams, &btccheckpointParams) - // NOTE: we should have verified that EndHeight > btcTip.Height + max(w, min_unbonding_time) k.addPowerDistUpdateEvent(ctx, btcDel.EndHeight-minUnbondingTime, unbondedEvent) } diff --git a/x/btcstaking/keeper/genesis_test.go b/x/btcstaking/keeper/genesis_test.go index 7943cf0a4..03f5a9584 100644 --- a/x/btcstaking/keeper/genesis_test.go +++ b/x/btcstaking/keeper/genesis_test.go @@ -72,7 +72,7 @@ func TestExportGenesis(t *testing.T) { totalDelegations++ // sets delegations - h.AddDelegation(del) + h.AddDelegation(del, minUnbondingTime) btcDelegations = append(btcDelegations, del) // BTC delegators idx diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index ec784e11f..0e0e0cf24 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -238,7 +238,7 @@ func FuzzPendingBTCDelegations(f *testing.F) { btcDel.CovenantSigs = nil pendingBtcDelsMap[btcDel.BtcPk.MarshalHex()] = btcDel } - err = keeper.AddBTCDelegation(ctx, btcDel) + err = keeper.AddBTCDelegation(ctx, btcDel, btcDel.UnbondingTime-1) require.NoError(t, err) txHash := btcDel.MustGetStakingTxHash().String() @@ -443,7 +443,7 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { slashingChangeLockTime, ) require.NoError(t, err) - err = keeper.AddBTCDelegation(ctx, btcDel) + err = keeper.AddBTCDelegation(ctx, btcDel, btcDel.UnbondingTime-1) require.NoError(t, err) totalVotingPower += btcDel.TotalSat } @@ -556,7 +556,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) { ) require.NoError(t, err) expectedBtcDelsMap[btcDel.BtcPk.MarshalHex()] = btcDel - err = keeper.AddBTCDelegation(ctx, btcDel) + err = keeper.AddBTCDelegation(ctx, btcDel, btcDel.UnbondingTime-1) require.NoError(t, err) } diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 8a430883e..73d73fea2 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -183,8 +183,6 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre return nil, err } - minUnbondingTime := types.MinimumUnbondingTime(&vp.Params, &btccParams) - // 6. If the delegation contains the inclusion proof, we need to verify the proof // and set start height and end height var startHeight, endHeight uint32 @@ -194,7 +192,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre btcutil.NewTx(parsedMsg.StakingTx.Transaction), btccParams.BtcConfirmationDepth, uint32(parsedMsg.StakingTime), - minUnbondingTime, + paramsValidationResult.MinUnbondingTime, parsedMsg.StakingTxProofOfInclusion) if err != nil { return nil, fmt.Errorf("invalid inclusion proof: %w", err) @@ -238,7 +236,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre } // add this BTC delegation, and emit corresponding events - if err := ms.AddBTCDelegation(ctx, newBTCDel); err != nil { + if err := ms.AddBTCDelegation(ctx, newBTCDel, paramsValidationResult.MinUnbondingTime); err != nil { panic(fmt.Errorf("failed to add BTC delegation that has passed verification: %w", err)) } diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 3721519d4..f5dde15b4 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -976,9 +976,12 @@ func FuzzDeterminismBtcstakingBeginBlocker(f *testing.F) { require.Equal(t, appHash1, appHash2) // Default params are the same in both apps - covQuorum := h.App.BTCStakingKeeper.GetParams(h.Ctx).CovenantQuorum - maxFinalityProviders := int32(h.App.BTCStakingKeeper.GetParams(h.Ctx).MaxActiveFinalityProviders) + stakingParams := h.App.BTCStakingKeeper.GetParams(h.Ctx) + covQuorum := stakingParams.CovenantQuorum + maxFinalityProviders := int32(stakingParams.MaxActiveFinalityProviders) + btcckptParams := h.App.BtcCheckpointKeeper.GetParams(h.Ctx) + minUnbondingTime := types.MinimumUnbondingTime(&stakingParams, &btcckptParams) // Number of finality providers from 10 to maxFinalityProviders + 10 numFinalityProviders := int(r.Int31n(maxFinalityProviders) + 10) @@ -1012,8 +1015,8 @@ func FuzzDeterminismBtcstakingBeginBlocker(f *testing.F) { ) for _, del := range delegations { - h.AddDelegation(del) - h1.AddDelegation(del) + h.AddDelegation(del, minUnbondingTime) + h1.AddDelegation(del, minUnbondingTime) } } diff --git a/x/btcstaking/types/validate_parsed_message.go b/x/btcstaking/types/validate_parsed_message.go index 7daa1c0ae..d334c7136 100644 --- a/x/btcstaking/types/validate_parsed_message.go +++ b/x/btcstaking/types/validate_parsed_message.go @@ -12,6 +12,7 @@ import ( type ParamsValidationResult struct { StakingOutputIdx uint32 UnbondingOutputIdx uint32 + MinUnbondingTime uint32 } // ValidateParsedMessageAgainstTheParams validates parsed message against parameters @@ -196,5 +197,6 @@ func ValidateParsedMessageAgainstTheParams( return &ParamsValidationResult{ StakingOutputIdx: stakingOutputIdx, UnbondingOutputIdx: unbondingOutputIdx, + MinUnbondingTime: minUnbondingTime, }, nil } diff --git a/x/btcstaking/types/validate_parsed_message_test.go b/x/btcstaking/types/validate_parsed_message_test.go index 3d0e4b7dd..307a2d725 100644 --- a/x/btcstaking/types/validate_parsed_message_test.go +++ b/x/btcstaking/types/validate_parsed_message_test.go @@ -759,20 +759,6 @@ func TestValidateParsedMessageAgainstTheParams(t *testing.T) { }, err: types.ErrInvalidUnbondingTx, }, - { - name: "Msg.UnbondingTime larger than Msg.StakingTime - CheckpointFinalizationTimeout", - fn: func(r *rand.Rand, t *testing.T) (*types.MsgCreateBTCDelegation, *types.Params, *btcckpttypes.Params) { - params := testStakingParams(r, t) - checkpointParams := testCheckpointParams() - msg, _ := createMsgDelegationForParams(r, t, params, checkpointParams) - - maxUnbondingTime := msg.StakingTime - checkpointParams.CheckpointFinalizationTimeout - msg.UnbondingTime = maxUnbondingTime + 1 - - return msg, params, checkpointParams - }, - err: types.ErrInvalidUnbondingTx, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -796,6 +782,9 @@ func TestValidateParsedMessageAgainstTheParams(t *testing.T) { } else { require.NoError(t, err) require.NotNil(t, got) + + minUnbondingTime := types.MinimumUnbondingTime(params, checkpointParams) + require.Equal(t, minUnbondingTime, got.MinUnbondingTime) } })