Skip to content

Commit

Permalink
feat: require secp256k1 pubkey registration for unjail
Browse files Browse the repository at this point in the history
  • Loading branch information
hacheigriega committed Dec 9, 2024
1 parent a3d0bba commit 49d2cc9
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 38 deletions.
8 changes: 5 additions & 3 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/mint"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
sdkslashing "github.com/cosmos/cosmos-sdk/x/slashing"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
sdkstakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
Expand All @@ -135,6 +135,7 @@ import (
"github.com/sedaprotocol/seda-chain/app/keepers"
appparams "github.com/sedaprotocol/seda-chain/app/params"
"github.com/sedaprotocol/seda-chain/app/utils"

// Used in cosmos-sdk when registering the route for swagger docs.
_ "github.com/sedaprotocol/seda-chain/client/docs/statik"
"github.com/sedaprotocol/seda-chain/cmd/sedad/gentx"
Expand All @@ -147,6 +148,7 @@ import (
"github.com/sedaprotocol/seda-chain/x/pubkey"
pubkeykeeper "github.com/sedaprotocol/seda-chain/x/pubkey/keeper"
pubkeytypes "github.com/sedaprotocol/seda-chain/x/pubkey/types"
"github.com/sedaprotocol/seda-chain/x/slashing"
"github.com/sedaprotocol/seda-chain/x/staking"
stakingkeeper "github.com/sedaprotocol/seda-chain/x/staking/keeper"
"github.com/sedaprotocol/seda-chain/x/tally"
Expand Down Expand Up @@ -180,7 +182,7 @@ var (
groupmodule.AppModuleBasic{},
gov.NewAppModuleBasic([]govclient.ProposalHandler{}),
mintModule{}, // custom modifications
slashing.AppModuleBasic{},
sdkslashing.AppModuleBasic{},
distrModule{}, // custom modifications
stakingModule{}, // custom modifications
upgrade.AppModuleBasic{},
Expand Down Expand Up @@ -782,7 +784,7 @@ func NewApp(
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, nil),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, nil),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil, app.interfaceRegistry),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil, app.interfaceRegistry, app.PubKeyKeeper, authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix())),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.PubKeyKeeper),
upgrade.NewAppModule(app.UpgradeKeeper, app.AccountKeeper.AddressCodec()),
Expand Down
46 changes: 21 additions & 25 deletions x/pubkey/keeper/endblock.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package keeper

import (
"errors"

"cosmossdk.io/collections"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/sedaprotocol/seda-chain/app/utils"
Expand Down Expand Up @@ -89,13 +85,13 @@ func (k Keeper) CheckKeyRegistrationRate(ctx sdk.Context, keyIndex utils.SEDAKey

var powerSum uint64
err = k.stakingKeeper.IterateLastValidatorPowers(ctx, func(valAddr sdk.ValAddress, power int64) (stop bool) {
_, err := k.GetValidatorKeyAtIndex(ctx, valAddr, keyIndex)
registered, err := k.HasRegisteredKey(ctx, valAddr, keyIndex)
if err != nil {
if errors.Is(err, collections.ErrNotFound) {
return false
}
panic(err)
}
if !registered {
return false
}
//nolint:gosec // G115: We shouldn't get negative power anyway.
powerSum += uint64(power)
return false
Expand Down Expand Up @@ -133,27 +129,27 @@ func (k Keeper) JailValidators(ctx sdk.Context, keyIndex utils.SEDAKeyIndex) err
if err != nil {
return err
}
_, err = k.GetValidatorKeyAtIndex(ctx, valAddr, keyIndex)
registered, err := k.HasRegisteredKey(ctx, valAddr, keyIndex)
if err != nil {
if errors.Is(err, collections.ErrNotFound) {
consAddr, err := val.GetConsAddr()
if err != nil {
return err
}
err = k.slashingKeeper.Jail(ctx, consAddr)
if err != nil {
return err
}
k.Logger(ctx).Info(
"jailed validator for not having required public key",
"consensus_address", consAddr,
"operator_address", val.OperatorAddress,
"key_index", keyIndex,
)
} else {
return err
}
if !registered {
consAddr, err := val.GetConsAddr()
if err != nil {
return err
}
err = k.slashingKeeper.Jail(ctx, consAddr)
if err != nil {
return err
}
k.Logger(ctx).Info(
"jailed validator for missing required public key",
"consensus_address", consAddr,
"operator_address", val.OperatorAddress,
"key_index", keyIndex,
)
}
}

return nil
}
14 changes: 14 additions & 0 deletions x/pubkey/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/hex"
"errors"
"fmt"

"cosmossdk.io/collections"
Expand Down Expand Up @@ -97,6 +98,19 @@ func (k Keeper) GetValidatorKeyAtIndex(ctx context.Context, validatorAddr sdk.Va
return pubKey, nil
}

// HasRegisteredKey returns true if the validator has registered a key
// at the index.
func (k Keeper) HasRegisteredKey(ctx context.Context, validatorAddr sdk.ValAddress, index utils.SEDAKeyIndex) (bool, error) {
_, err := k.pubKeys.Get(ctx, collections.Join(validatorAddr.Bytes(), uint32(index)))
if err != nil {
if errors.Is(err, collections.ErrNotFound) {
return false, nil
}
return false, err
}
return true, nil
}

// GetValidatorKeys returns all public keys of a given validator.
func (k Keeper) GetValidatorKeys(ctx context.Context, validatorAddr string) (result types.ValidatorPubKeys, err error) {
valAddr, err := k.validatorAddressCodec.StringToBytes(validatorAddr)
Expand Down
58 changes: 58 additions & 0 deletions x/slashing/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package slashing

import (
addresscodec "cosmossdk.io/core/address"
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/slashing/exported"
"github.com/cosmos/cosmos-sdk/x/slashing/keeper"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
)

var (
_ module.AppModule = AppModule{}
)

// ----------------------------------------------------------------------------
// AppModule
// ----------------------------------------------------------------------------

// AppModule implements an application module for the slashing module.
type AppModule struct {
slashing.AppModule

keeper keeper.Keeper
pubKeyKeeper PubKeyKeeper
validatorAddressCodec addresscodec.Codec
}

// NewAppModule creates a new AppModule object.
func NewAppModule(
cdc codec.Codec,
keeper keeper.Keeper,
ak types.AccountKeeper,
bk types.BankKeeper,
sk types.StakingKeeper,
ss exported.Subspace,
registry cdctypes.InterfaceRegistry,
pk PubKeyKeeper,
valAddrCdc addresscodec.Codec,
) AppModule {
baseAppModule := slashing.NewAppModule(cdc, keeper, ak, bk, sk, ss, registry)
return AppModule{
AppModule: baseAppModule,
keeper: keeper,
pubKeyKeeper: pk,
validatorAddressCodec: valAddrCdc,
}
}

// RegisterServices registers module services.
func (am AppModule) RegisterServices(cfg module.Configurator) {
sdkMsgServer := keeper.NewMsgServerImpl(am.keeper)
msgServer := NewMsgServerImpl(sdkMsgServer, am.pubKeyKeeper, am.validatorAddressCodec)
types.RegisterMsgServer(cfg.MsgServer(), msgServer)
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
}
51 changes: 51 additions & 0 deletions x/slashing/msg_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package slashing

import (
"context"

addresscodec "cosmossdk.io/core/address"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/sedaprotocol/seda-chain/app/utils"
)

var _ types.MsgServer = msgServer{}

type msgServer struct {
types.MsgServer
pubKeyKeeper PubKeyKeeper
validatorAddressCodec addresscodec.Codec
}

type PubKeyKeeper interface {
HasRegisteredKey(ctx context.Context, validatorAddr sdk.ValAddress, index utils.SEDAKeyIndex) (bool, error)
}

func NewMsgServerImpl(sdkMsgServer types.MsgServer, pubKeyKeeper PubKeyKeeper, valAddrCdc addresscodec.Codec) types.MsgServer {
ms := &msgServer{
MsgServer: sdkMsgServer,
pubKeyKeeper: pubKeyKeeper,
validatorAddressCodec: valAddrCdc,
}
return ms
}

// Unjail overrides the default Unjail method to add an additional
// check for registration of required public keys.
func (m msgServer) Unjail(ctx context.Context, req *types.MsgUnjail) (*types.MsgUnjailResponse, error) {
valAddr, err := m.validatorAddressCodec.StringToBytes(req.ValidatorAddr)
if err != nil {
panic(err)
}
registered, err := m.pubKeyKeeper.HasRegisteredKey(ctx, valAddr, utils.SEDAKeyIndexSecp256k1)
if err != nil {
return nil, err
}
if !registered {
return nil, sdkerrors.ErrInvalidRequest.Wrap("validator has not registered required SEDA keys")
}

return m.MsgServer.Unjail(ctx, req)
}
15 changes: 6 additions & 9 deletions x/staking/keeper/invariants.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package keeper

import (
"errors"
"fmt"

"cosmossdk.io/collections"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
Expand Down Expand Up @@ -45,15 +42,15 @@ func PubKeyRegistrationInvariant(k *Keeper) sdk.Invariant {
if err != nil {
panic(err)
}
_, err = k.pubKeyKeeper.GetValidatorKeyAtIndex(ctx, valAddr, utils.SEDAKeyIndexSecp256k1)
registered, err := k.pubKeyKeeper.HasRegisteredKey(ctx, valAddr, utils.SEDAKeyIndexSecp256k1)
if err != nil {
if errors.Is(err, collections.ErrNotFound) {
broken = true
violator = validator.GetOperator()
return true
}
panic(err)
}
if !registered {
broken = true
violator = validator.GetOperator()
return true
}
return false
})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion x/staking/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ import (
type PubKeyKeeper interface {
StoreIndexedPubKeys(ctx sdk.Context, valAddr sdk.ValAddress, pubKeys []types.IndexedPubKey) error
IsProvingSchemeActivated(ctx context.Context, index utils.SEDAKeyIndex) (bool, error)
GetValidatorKeyAtIndex(ctx context.Context, validatorAddr sdk.ValAddress, index utils.SEDAKeyIndex) ([]byte, error)
HasRegisteredKey(ctx context.Context, validatorAddr sdk.ValAddress, index utils.SEDAKeyIndex) (bool, error)
}

0 comments on commit 49d2cc9

Please sign in to comment.