Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change val's consensus pubkey #3321

Open
wants to merge 1 commit into
base: release/v1.7.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
icacontroller "github.com/okex/exchain/libs/ibc-go/modules/apps/27-interchain-accounts/controller"
icahost "github.com/okex/exchain/libs/ibc-go/modules/apps/27-interchain-accounts/host"
"github.com/okex/exchain/libs/ibc-go/modules/apps/common"
"github.com/okex/exchain/x/icamauth"

ibccommon "github.com/okex/exchain/libs/ibc-go/modules/core/common"
"github.com/okex/exchain/x/icamauth"
paramstypes "github.com/okex/exchain/x/params/types"

icacontrollertypes "github.com/okex/exchain/libs/ibc-go/modules/apps/27-interchain-accounts/controller/types"
icahosttypes "github.com/okex/exchain/libs/ibc-go/modules/apps/27-interchain-accounts/host/types"
Expand Down Expand Up @@ -773,10 +773,7 @@ func NewOKExChainApp(
tmos.Exit(fmt.Sprintf("failed initialize pinned codes %s", err))
}

if err := app.ParamsKeeper.ApplyEffectiveUpgrade(ctx); err != nil {
tmos.Exit(fmt.Sprintf("failed apply effective upgrade height info: %s", err))
}

app.InitUpgrade(ctx)
app.WasmKeeper.UpdateGasRegister(ctx)
}

Expand All @@ -793,6 +790,17 @@ func NewOKExChainApp(
return app
}

func (app *OKExChainApp) InitUpgrade(ctx sdk.Context) {
// Claim before ApplyEffectiveUpgrade
app.ParamsKeeper.ClaimReadyForUpgrade(tmtypes.MILESTONE_VENUS8_NAME, func(info paramstypes.UpgradeInfo) {
tmtypes.InitMilestoneVenus8Height(int64(info.EffectiveHeight))
})

if err := app.ParamsKeeper.ApplyEffectiveUpgrade(ctx); err != nil {
tmos.Exit(fmt.Sprintf("failed apply effective upgrade height info: %s", err))
}
}

func (app *OKExChainApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOption) {
if req.Key == "CheckChainID" {
if err := okexchain.IsValidateChainIdWithGenesisHeight(req.Value); err != nil {
Expand Down
19 changes: 17 additions & 2 deletions libs/tendermint/types/milestone.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ var (
MILESTONE_VENUS5_HEIGHT string
milestoneVenus5Height int64

MILESTONE_VENUS8_NAME = "venus8"
milestoneVenus8Height int64 = 0

// note: it stores the earlies height of the node,and it is used by cli
nodePruneHeight int64

Expand Down Expand Up @@ -112,7 +115,7 @@ func SetupTestNetEnvironment(pruneH int64) {
milestoneVenus1Height = TestNetVeneus1Height
}

//depracate homstead signer support
// depracate homstead signer support
func HigherThanMercury(height int64) bool {
if milestoneMercuryHeight == 0 {
// milestoneMercuryHeight not enabled
Expand All @@ -128,7 +131,7 @@ func HigherThanVenus(height int64) bool {
return height >= milestoneVenusHeight
}

//use MPT storage model to replace IAVL storage model
// use MPT storage model to replace IAVL storage model
func HigherThanMars(height int64) bool {
if milestoneMarsHeight == 0 {
return false
Expand Down Expand Up @@ -304,3 +307,15 @@ func GetVenus5Height() int64 {

// =========== Venus4 ===============
// ==================================

// change val's pubkey
func HigherThanVenus8(h int64) bool {
if milestoneVenus8Height == 0 {
return false
}
return h > milestoneVenus8Height
}

func InitMilestoneVenus8Height(h int64) {
milestoneVenus8Height = h
}
4 changes: 4 additions & 0 deletions x/distribution/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
sdk "github.com/okex/exchain/libs/cosmos-sdk/types"
"github.com/okex/exchain/libs/tendermint/crypto"

"github.com/okex/exchain/x/distribution/types"
stakingtypes "github.com/okex/exchain/x/staking/types"
Expand All @@ -23,6 +24,9 @@ func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
h.k.initializeValidator(ctx, val)
}

func (h Hooks) AfterValidatorPubkeyChanged(ctx sdk.Context, oldAddress sdk.ConsAddress, newAddress sdk.ConsAddress, newPubkey crypto.PubKey) {
}

// AfterValidatorRemoved cleans up for after validator is removed
func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
if h.k.CheckDistributionProposalValid(ctx) {
Expand Down
15 changes: 15 additions & 0 deletions x/slashing/internal/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, address sdk.ConsAddress)
k.modifyValidatorStatus(ctx, address, types.Destroyed)
}

func (k Keeper) AfterValidatorPubkeyChanged(ctx sdk.Context, oldAddress sdk.ConsAddress, newAddress sdk.ConsAddress, newPubkey crypto.PubKey) {
k.deleteAddrPubkeyRelation(ctx, crypto.Address(oldAddress))
signingInfo, found := k.GetValidatorSigningInfo(ctx, oldAddress)
k.modifyValidatorStatus(ctx, oldAddress, types.Destroyed)

k.AddPubkey(ctx, newPubkey)
if found {
k.SetValidatorSigningInfo(ctx, newAddress, signingInfo)
}
}

func (k Keeper) AfterValidatorDestroyed(ctx sdk.Context, valAddr sdk.ValAddress) {
validator := k.sk.Validator(ctx, valAddr)
if validator != nil {
Expand Down Expand Up @@ -76,6 +87,10 @@ func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
h.k.AfterValidatorCreated(ctx, valAddr)
}

func (h Hooks) AfterValidatorPubkeyChanged(ctx sdk.Context, oldAddress sdk.ConsAddress, newAddress sdk.ConsAddress, newPubkey crypto.PubKey) {
h.k.AfterValidatorPubkeyChanged(ctx, oldAddress, newAddress, newPubkey)
}

func (h Hooks) AfterValidatorDestroyed(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
h.k.AfterValidatorDestroyed(ctx, valAddr)
}
Expand Down
3 changes: 2 additions & 1 deletion x/slashing/internal/keeper/infractions.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ func (k Keeper) HandleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
// fetch the validator public key
consAddr := sdk.ConsAddress(addr)
if _, err := k.GetPubkey(ctx, addr); err != nil {
panic(fmt.Sprintf("Validator consensus-address %s not found", consAddr))
// ignore this panic, now we can change the validator's pub key
//panic(fmt.Sprintf("Validator consensus-address %s not found", consAddr))
}

// fetch signing info
Expand Down
1 change: 1 addition & 0 deletions x/staking/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var (
RegisterCodec = types.RegisterCodec
NewCommission = types.NewCommission
ErrNoValidatorFound = types.ErrNoValidatorFound
ErrPubkeyEqual = types.ErrPubkeyEqual
ErrValidatorOwnerExists = types.ErrValidatorOwnerExists
ErrValidatorPubKeyExists = types.ErrValidatorPubKeyExists
ErrValidatorPubKeyTypeNotSupported = types.ErrValidatorPubKeyTypeNotSupported
Expand Down
41 changes: 33 additions & 8 deletions x/staking/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,40 @@ func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keepe
return nil, ErrNoValidatorFound(msg.ValidatorAddress.String())
}

// replace all editable fields (clients should autofill existing values)
description, err := validator.Description.UpdateDescription(msg.Description)
if err != nil {
return nil, err
}

validator.Description = description
pk, err := types.GetConsPubKeyBech32(msg.Details)
if err == nil && tmtypes.HigherThanVenus8(ctx.BlockHeight()) {
if validator.ConsPubKey.Equals(pk) {
return nil, ErrPubkeyEqual(pk.Address().String())
}
if _, found := k.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(pk)); found {
return nil, ErrValidatorPubKeyExists()
}
if ctx.ConsensusParams() != nil {
tmPubKey := tmtypes.TM2PB.PubKey(pk)
if !StringInSlice(tmPubKey.Type, ctx.ConsensusParams().Validator.PubKeyTypes) {
return nil, ErrValidatorPubKeyTypeNotSupported(tmPubKey.Type,
ctx.ConsensusParams().Validator.PubKeyTypes)
}
}
k.SetChangePubkey(ctx, validator.OperatorAddress, validator.GetConsPubKey())
oldConsAddr := validator.GetConsAddr()

validator.ConsPubKey = pk
newConsAddr := validator.GetConsAddr()
k.SetValidator(ctx, validator)
k.SetValidatorByConsAddr(ctx, validator)
k.DeleteValidatorByConsAddr(ctx, oldConsAddr)
k.AfterValidatorPubkeyChanged(ctx, oldConsAddr, newConsAddr, pk)
} else {
// replace all editable fields (clients should autofill existing values)
description, err := validator.Description.UpdateDescription(msg.Description)
if err != nil {
return nil, err
}

k.SetValidator(ctx, validator)
validator.Description = description
k.SetValidator(ctx, validator)
}

ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(types.EventTypeEditValidator,
Expand Down
7 changes: 7 additions & 0 deletions x/staking/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
sdk "github.com/okex/exchain/libs/cosmos-sdk/types"
"github.com/okex/exchain/libs/tendermint/crypto"
"github.com/okex/exchain/x/staking/types"
)

Expand All @@ -15,6 +16,12 @@ func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
}
}

func (k Keeper) AfterValidatorPubkeyChanged(ctx sdk.Context, oldAddress sdk.ConsAddress, newAddress sdk.ConsAddress, newPubkey crypto.PubKey) {
if k.hooks != nil {
k.hooks.AfterValidatorPubkeyChanged(ctx, oldAddress, newAddress, newPubkey)
}
}

// BeforeValidatorModified - call hook if registered
func (k Keeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
if k.hooks != nil {
Expand Down
6 changes: 4 additions & 2 deletions x/staking/keeper/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,10 @@ func SimpleCheckValidator(t *testing.T, ctx sdk.Context, stkKeeper Keeper, vaAdd
// mockDistributionKeeper is supported to test Hooks
type mockDistributionKeeper struct{}

func (dk mockDistributionKeeper) Hooks() types.StakingHooks { return dk }
func (dk mockDistributionKeeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {}
func (dk mockDistributionKeeper) Hooks() types.StakingHooks { return dk }
func (dk mockDistributionKeeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {}
func (dk mockDistributionKeeper) AfterValidatorPubkeyChanged(ctx sdk.Context, oldAddress sdk.ConsAddress, newAddress sdk.ConsAddress, newPubkey crypto.PubKey) {
}
func (dk mockDistributionKeeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {}
func (dk mockDistributionKeeper) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
}
Expand Down
10 changes: 10 additions & 0 deletions x/staking/keeper/val_state_change.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
k.SetLastValidatorPower(ctx, valAddr, newPower)
}

// change val node key
if pk, found := k.GetChangePubkey(ctx, validator.OperatorAddress); found {
oldVal := types.Validator{ConsPubKey: pk}
// delete old pubkey
updates = append(updates, oldVal.ABCIValidatorUpdateZero())
// add new pubkey
updates = append(updates, validator.ABCIValidatorUpdateByShares())
k.DeleteChangePubkey(ctx, validator.OperatorAddress)
}

// validator still in the validator set, so delete from the copy
delete(last, valAddrBytes)

Expand Down
30 changes: 30 additions & 0 deletions x/staking/keeper/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"time"

sdk "github.com/okex/exchain/libs/cosmos-sdk/types"
"github.com/okex/exchain/libs/tendermint/crypto"
cryptoAmino "github.com/okex/exchain/libs/tendermint/crypto/encoding/amino"
"github.com/okex/exchain/x/staking/types"
)

Expand Down Expand Up @@ -54,13 +56,41 @@ func (k Keeper) SetValidator(ctx sdk.Context, validator types.Validator) {
store.Set(types.GetValidatorKey(validator.OperatorAddress), bz)
}

func (k Keeper) SetChangePubkey(ctx sdk.Context, addr sdk.ValAddress, pubkey crypto.PubKey) {
store := ctx.KVStore(k.storeKey)
store.Set(types.GetValidatorChangePubkeyKey(addr), pubkey.Bytes())
}

func (k Keeper) DeleteChangePubkey(ctx sdk.Context, addr sdk.ValAddress) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.GetValidatorChangePubkeyKey(addr))
}

func (k Keeper) GetChangePubkey(ctx sdk.Context, addr sdk.ValAddress) (pubkey crypto.PubKey, found bool) {
store := ctx.KVStore(k.storeKey)
value := store.Get(types.GetValidatorChangePubkeyKey(addr))
if value == nil {
return nil, false
}
pk, err := cryptoAmino.PubKeyFromBytes(value)
if err != nil {
panic(err)
}
return pk, true
}

// SetValidatorByConsAddr sets the operator address with the key of validator consensus pubkey
func (k Keeper) SetValidatorByConsAddr(ctx sdk.Context, validator types.Validator) {
store := ctx.KVStore(k.storeKey)
consAddr := sdk.ConsAddress(validator.ConsPubKey.Address())
store.Set(types.GetValidatorByConsAddrKey(consAddr), validator.OperatorAddress)
}

func (k Keeper) DeleteValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.GetValidatorByConsAddrKey(consAddr))
}

// SetValidatorByPowerIndex sets the power index key of an unjailed validator
func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Validator) {
// jailed validators are not kept in the power index
Expand Down
11 changes: 9 additions & 2 deletions x/staking/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,24 @@ const (
CodeNoDelegatorExisted uint32 = 67044
CodeTargetValsDuplicate uint32 = 67045
CodeAlreadyBound uint32 = 67046

CodePubkeyEqual uint32 = 67047
)

var (
ErrInvalidHistoricalInfo = sdkerrors.Register(ModuleName, 144, "invalid historical info")
ErrNoHistoricalInfo = sdkerrors.Register(ModuleName, 145, "no historical info found")
ErrInvalidHistoricalInfo = sdkerrors.Register(ModuleName, 144, "invalid historical info")
ErrNoHistoricalInfo = sdkerrors.Register(ModuleName, 145, "no historical info found")
)

// ErrNoValidatorFound returns an error when a validator doesn't exist
func ErrNoValidatorFound(valAddr string) sdk.EnvelopedErr {
return sdk.EnvelopedErr{Err: sdkerrors.New(DefaultCodespace, CodeNoValidatorFound, fmt.Sprintf("validator %s does not exist", valAddr))}
}

func ErrPubkeyEqual(pubkey string) sdk.EnvelopedErr {
return sdk.EnvelopedErr{Err: sdkerrors.New(DefaultCodespace, CodePubkeyEqual, fmt.Sprintf("validator pubkey %s does exist", pubkey))}
}

// ErrInvalidDelegation returns an error when the delegation is invalid
func ErrInvalidDelegation(delegator string) sdk.EnvelopedErr {
return sdk.EnvelopedErr{Err: sdkerrors.New(DefaultCodespace, CodeInvalidDelegation,
Expand Down
2 changes: 2 additions & 0 deletions x/staking/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
sdk "github.com/okex/exchain/libs/cosmos-sdk/types"
authexported "github.com/okex/exchain/libs/cosmos-sdk/x/auth/exported"
supplyexported "github.com/okex/exchain/libs/cosmos-sdk/x/supply/exported"
"github.com/okex/exchain/libs/tendermint/crypto"
stakingexported "github.com/okex/exchain/x/staking/exported"
)

Expand Down Expand Up @@ -74,6 +75,7 @@ type ValidatorSet interface {
type StakingHooks interface {
// Must be called when a validator is created
AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress)
AfterValidatorPubkeyChanged(ctx sdk.Context, oldAddress sdk.ConsAddress, newAddress sdk.ConsAddress, newPubkey crypto.PubKey)
// Must be called when a validator's state changes
BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress)
// Must be called when a validator is deleted
Expand Down
7 changes: 7 additions & 0 deletions x/staking/types/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
sdk "github.com/okex/exchain/libs/cosmos-sdk/types"
"github.com/okex/exchain/libs/tendermint/crypto"
)

// MultiStakingHooks combines multiple staking hooks, all hook functions are run in array sequence
Expand All @@ -20,6 +21,12 @@ func (h MultiStakingHooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.Va
}
}

func (h MultiStakingHooks) AfterValidatorPubkeyChanged(ctx sdk.Context, oldAddress sdk.ConsAddress, newAddress sdk.ConsAddress, newPubkey crypto.PubKey) {
for i := range h {
h[i].AfterValidatorPubkeyChanged(ctx, oldAddress, newAddress, newPubkey)
}
}

// BeforeValidatorModified handles the hooks before the validator modified
func (h MultiStakingHooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
for i := range h {
Expand Down
7 changes: 6 additions & 1 deletion x/staking/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const (
RouterKey = ModuleName
)

//nolint
// nolint
var (
// Keys for store prefixes
// Last* values are constant during a block.
Expand All @@ -40,6 +40,7 @@ var (
ValidatorsKey = []byte{0x21} // prefix for each key to a validator
ValidatorsByConsAddrKey = []byte{0x22} // prefix for each key to a validator index, by pubkey
ValidatorsByPowerIndexKey = []byte{0x23} // prefix for each key to a validator index, sorted by power
ValChangePubkeyKey = []byte{0x24}

ValidatorQueueKey = []byte{0x43} // prefix for the timestamps in validator queue

Expand Down Expand Up @@ -67,6 +68,10 @@ func GetValidatorByConsAddrKey(addr sdk.ConsAddress) []byte {
return append(ValidatorsByConsAddrKey, addr.Bytes()...)
}

func GetValidatorChangePubkeyKey(operatorAddr sdk.ValAddress) []byte {
return append(ValChangePubkeyKey, operatorAddr.Bytes()...)
}

// AddressFromLastValidatorPowerKey gets the validator operator address from LastValidatorPowerKey
func AddressFromLastValidatorPowerKey(key []byte) []byte {
return key[1:] // remove prefix bytes
Expand Down
Loading