chore: x/slashing audit changes (#14211)

## Description

ref: #14158 



---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
This commit is contained in:
atheeshp 2022-12-09 15:30:44 +05:30 committed by GitHub
parent 93abfdd21d
commit 7ded32163b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 215 additions and 15 deletions

View File

@ -14,6 +14,7 @@ import (
var _ types.QueryServer = Keeper{}
// Params returns parameters of x/slashing module
func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
@ -25,6 +26,7 @@ func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types
return &types.QueryParamsResponse{Params: params}, nil
}
// SigningInfo returns signing-info of a specific validator.
func (k Keeper) SigningInfo(c context.Context, req *types.QuerySigningInfoRequest) (*types.QuerySigningInfoResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
@ -48,6 +50,7 @@ func (k Keeper) SigningInfo(c context.Context, req *types.QuerySigningInfoReques
return &types.QuerySigningInfoResponse{ValSigningInfo: signingInfo}, nil
}
// SigningInfos returns signing-infos of all validators.
func (k Keeper) SigningInfos(c context.Context, req *types.QuerySigningInfosRequest) (*types.QuerySigningInfosResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")

View File

@ -19,6 +19,7 @@ import (
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
slashingtestutil "github.com/cosmos/cosmos-sdk/x/slashing/testutil"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
var consAddr = sdk.ConsAddress(sdk.AccAddress([]byte("addr1_______________")))
@ -74,6 +75,28 @@ func (s *KeeperTestSuite) TestPubkey() {
require.Equal(pubKey, expectedPubKey)
}
func (s *KeeperTestSuite) TestJailAndSlash() {
s.stakingKeeper.EXPECT().Slash(s.ctx,
consAddr,
s.ctx.BlockHeight(),
sdk.TokensToConsensusPower(sdk.NewInt(1), sdk.DefaultPowerReduction),
s.slashingKeeper.SlashFractionDoubleSign(s.ctx),
types.Infraction_INFRACTION_DOUBLE_SIGN,
).Return(sdk.NewInt(0))
s.slashingKeeper.Slash(
s.ctx,
consAddr,
s.slashingKeeper.SlashFractionDoubleSign(s.ctx),
sdk.TokensToConsensusPower(sdk.NewInt(1), sdk.DefaultPowerReduction),
s.ctx.BlockHeight(),
types.Infraction_INFRACTION_DOUBLE_SIGN,
)
s.stakingKeeper.EXPECT().Jail(s.ctx, consAddr).Return()
s.slashingKeeper.Jail(s.ctx, consAddr)
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}

View File

@ -21,6 +21,8 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &msgServer{Keeper: keeper}
}
// UpdateParams implements MsgServer.UpdateParams method.
// It defines a method to update the x/slashing module parameters.
func (k msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
if k.authority != req.Authority {
return nil, errors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, req.Authority)

View File

@ -3,10 +3,10 @@ package keeper_test
import (
"time"
"github.com/golang/mock/gomock"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func (s *KeeperTestSuite) TestUpdateParams() {
@ -144,13 +144,179 @@ func (s *KeeperTestSuite) TestUpdateParams() {
}
func (s *KeeperTestSuite) TestUnjail() {
addr := sdk.AccAddress([]byte("val1_______________"))
request := &slashingtypes.MsgUnjail{
ValidatorAddr: sdk.ValAddress(addr).String(),
testCases := []struct {
name string
malleate func() *slashingtypes.MsgUnjail
expErr bool
expErrMsg string
}{
{
name: "no self delegation: invalid request",
malleate: func() *slashingtypes.MsgUnjail {
_, pubKey, addr := testdata.KeyTestPubAddr()
valAddr := sdk.ValAddress(addr)
val, err := types.NewValidator(valAddr, pubKey, types.Description{Moniker: "test"})
s.Require().NoError(err)
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(nil)
return &slashingtypes.MsgUnjail{
ValidatorAddr: sdk.ValAddress(addr).String(),
}
},
expErr: true,
expErrMsg: "validator has no self-delegation",
},
{
name: "validator not in the state: invalid request",
malleate: func() *slashingtypes.MsgUnjail {
_, _, addr := testdata.KeyTestPubAddr()
valAddr := sdk.ValAddress(addr)
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(nil)
return &slashingtypes.MsgUnjail{
ValidatorAddr: valAddr.String(),
}
},
expErr: true,
expErrMsg: "address is not associated with any known validator",
},
{
name: "validator not jailed: invalid request",
malleate: func() *slashingtypes.MsgUnjail {
_, pubKey, addr := testdata.KeyTestPubAddr()
valAddr := sdk.ValAddress(addr)
val, err := types.NewValidator(valAddr, pubKey, types.Description{Moniker: "test"})
val.Tokens = sdk.NewInt(1000)
val.DelegatorShares = sdk.NewDec(1)
val.Jailed = false
s.Require().NoError(err)
info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addr), int64(4), int64(3),
time.Unix(2, 0), false, int64(10))
s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
del := types.NewDelegation(addr, valAddr, sdk.NewDec(100))
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del)
return &slashingtypes.MsgUnjail{
ValidatorAddr: sdk.ValAddress(addr).String(),
}
},
expErr: true,
expErrMsg: "validator not jailed",
},
{
name: "validator tombstoned: invalid request",
malleate: func() *slashingtypes.MsgUnjail {
_, pubKey, addr := testdata.KeyTestPubAddr()
valAddr := sdk.ValAddress(addr)
val, err := types.NewValidator(valAddr, pubKey, types.Description{Moniker: "test"})
val.Tokens = sdk.NewInt(1000)
val.DelegatorShares = sdk.NewDec(1)
val.Jailed = true
s.Require().NoError(err)
info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addr), int64(4), int64(3),
time.Unix(2, 0), true, int64(10))
s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
del := types.NewDelegation(addr, valAddr, sdk.NewDec(100))
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del)
return &slashingtypes.MsgUnjail{
ValidatorAddr: sdk.ValAddress(addr).String(),
}
},
expErr: true,
expErrMsg: "validator still jailed; cannot be unjailed",
},
{
name: "unjailing before wait period: invalid request",
malleate: func() *slashingtypes.MsgUnjail {
_, pubKey, addr := testdata.KeyTestPubAddr()
valAddr := sdk.ValAddress(addr)
val, err := types.NewValidator(valAddr, pubKey, types.Description{Moniker: "test"})
val.Tokens = sdk.NewInt(1000)
val.DelegatorShares = sdk.NewDec(1)
val.Jailed = true
s.Require().NoError(err)
info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addr), int64(4), int64(3),
s.ctx.BlockTime().AddDate(0, 0, 1), false, int64(10))
s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
del := types.NewDelegation(addr, valAddr, sdk.NewDec(10000))
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del)
return &slashingtypes.MsgUnjail{
ValidatorAddr: sdk.ValAddress(addr).String(),
}
},
expErr: true,
expErrMsg: "validator still jailed; cannot be unjailed",
},
{
name: "valid request",
malleate: func() *slashingtypes.MsgUnjail {
_, pubKey, addr := testdata.KeyTestPubAddr()
valAddr := sdk.ValAddress(addr)
val, err := types.NewValidator(valAddr, pubKey, types.Description{Moniker: "test"})
val.Tokens = sdk.NewInt(1000)
val.DelegatorShares = sdk.NewDec(1)
val.Jailed = true
s.Require().NoError(err)
info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(addr), int64(4), int64(3),
time.Unix(2, 0), false, int64(10))
s.slashingKeeper.SetValidatorSigningInfo(s.ctx, sdk.ConsAddress(addr), info)
s.stakingKeeper.EXPECT().Validator(s.ctx, valAddr).Return(val)
del := types.NewDelegation(addr, valAddr, sdk.NewDec(100))
s.stakingKeeper.EXPECT().Delegation(s.ctx, addr, valAddr).Return(del)
s.stakingKeeper.EXPECT().Unjail(s.ctx, sdk.ConsAddress(addr)).Return()
return &slashingtypes.MsgUnjail{
ValidatorAddr: sdk.ValAddress(addr).String(),
}
},
expErr: false,
},
}
s.stakingKeeper.EXPECT().Validator(gomock.Any(), gomock.Any()).Return(nil)
_, err := s.msgServer.Unjail(s.ctx, request)
s.Require().Error(err)
s.Require().Equal(err, slashingtypes.ErrNoValidatorForAddress)
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
req := tc.malleate()
_, err := s.msgServer.Unjail(s.ctx, req)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
} else {
s.Require().NoError(err)
}
})
}
}

View File

@ -19,6 +19,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
legacy.RegisterAminoMsg(cdc, &MsgUpdateParams{}, "cosmos-sdk/x/slashing/MsgUpdateParams")
}
// RegisterInterfaces registers the interfaces types with the Interface Registry.
func RegisterInterfaces(registry types.InterfaceRegistry) {
registry.RegisterImplementations((*sdk.Msg)(nil),
&MsgUnjail{},

View File

@ -25,8 +25,13 @@ func NewMsgUnjail(validatorAddr sdk.ValAddress) *MsgUnjail {
}
}
// Route implements the sdk.Msg interface.
func (msg MsgUnjail) Route() string { return RouterKey }
func (msg MsgUnjail) Type() string { return TypeMsgUnjail }
// Type implements the sdk.Msg interface.
func (msg MsgUnjail) Type() string { return TypeMsgUnjail }
// GetSigners returns the expected signers for MsgUnjail.
func (msg MsgUnjail) GetSigners() []sdk.AccAddress {
valAddr, _ := sdk.ValAddressFromBech32(msg.ValidatorAddr)
return []sdk.AccAddress{sdk.AccAddress(valAddr)}
@ -38,7 +43,7 @@ func (msg MsgUnjail) GetSignBytes() []byte {
return sdk.MustSortJSON(bz)
}
// ValidateBasic does a sanity check on the provided message
// ValidateBasic does a sanity check on the provided message.
func (msg MsgUnjail) ValidateBasic() error {
if _, err := sdk.ValAddressFromBech32(msg.ValidatorAddr); err != nil {
return sdkerrors.ErrInvalidAddress.Wrapf("validator input address: %s", err)

View File

@ -46,7 +46,7 @@ func DefaultParams() Params {
)
}
// validate params
// Validate validates the params
func (p Params) Validate() error {
if err := validateSignedBlocksWindow(p.SignedBlocksWindow); err != nil {
return err

View File

@ -11,11 +11,11 @@ import (
//
//nolint:interfacer
func NewValidatorSigningInfo(
condAddr sdk.ConsAddress, startHeight, indexOffset int64,
consAddr sdk.ConsAddress, startHeight, indexOffset int64,
jailedUntil time.Time, tombstoned bool, missedBlocksCounter int64,
) ValidatorSigningInfo {
return ValidatorSigningInfo{
Address: condAddr.String(),
Address: consAddr.String(),
StartHeight: startHeight,
IndexOffset: indexOffset,
JailedUntil: jailedUntil,
@ -24,7 +24,7 @@ func NewValidatorSigningInfo(
}
}
// unmarshal a validator signing info from a store value
// UnmarshalValSigningInfo unmarshals a validator signing info from a store value
func UnmarshalValSigningInfo(cdc codec.Codec, value []byte) (signingInfo ValidatorSigningInfo, err error) {
err = cdc.Unmarshal(value, &signingInfo)
return signingInfo, err