Merge pull request #1105 from cosmos/cwgoes/slashing-v1.1
Fix minor slashing issues
This commit is contained in:
commit
537ce91e33
|
@ -14,6 +14,7 @@ import (
|
||||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||||
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
|
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
|
||||||
ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli"
|
ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli"
|
||||||
|
slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
|
||||||
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli"
|
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||||
|
@ -86,6 +87,7 @@ func main() {
|
||||||
stakecmd.GetCmdQueryValidators("stake", cdc),
|
stakecmd.GetCmdQueryValidators("stake", cdc),
|
||||||
stakecmd.GetCmdQueryDelegation("stake", cdc),
|
stakecmd.GetCmdQueryDelegation("stake", cdc),
|
||||||
stakecmd.GetCmdQueryDelegations("stake", cdc),
|
stakecmd.GetCmdQueryDelegations("stake", cdc),
|
||||||
|
slashingcmd.GetCmdQuerySigningInfo("slashing", cdc),
|
||||||
)...)
|
)...)
|
||||||
stakeCmd.AddCommand(
|
stakeCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
|
@ -93,6 +95,7 @@ func main() {
|
||||||
stakecmd.GetCmdEditValidator(cdc),
|
stakecmd.GetCmdEditValidator(cdc),
|
||||||
stakecmd.GetCmdDelegate(cdc),
|
stakecmd.GetCmdDelegate(cdc),
|
||||||
stakecmd.GetCmdUnbond(cdc),
|
stakecmd.GetCmdUnbond(cdc),
|
||||||
|
slashingcmd.GetCmdUnrevoke(cdc),
|
||||||
)...)
|
)...)
|
||||||
rootCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
stakeCmd,
|
stakeCmd,
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package cli
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
const (
|
||||||
|
FlagAddressValidator = "address-validator"
|
||||||
|
)
|
|
@ -0,0 +1,57 @@
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/wire" // XXX fix
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// get the command to query signing info
|
||||||
|
func GetCmdQuerySigningInfo(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "signing_info [validator-pubkey]",
|
||||||
|
Short: "Query a validator's signing information",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
|
pk, err := sdk.GetValPubKeyBech32Cosmos(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
key := slashing.GetValidatorSigningInfoKey(pk.Address())
|
||||||
|
ctx := context.NewCoreContextFromViper()
|
||||||
|
res, err := ctx.Query(key, storeName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
signingInfo := new(slashing.ValidatorSigningInfo)
|
||||||
|
cdc.MustUnmarshalBinary(res, signingInfo)
|
||||||
|
|
||||||
|
switch viper.Get(cli.OutputFlag) {
|
||||||
|
|
||||||
|
case "text":
|
||||||
|
human := signingInfo.HumanReadableString()
|
||||||
|
fmt.Println(human)
|
||||||
|
|
||||||
|
case "json":
|
||||||
|
// parse out the signing info
|
||||||
|
output, err := wire.MarshalJSONIndent(cdc, signingInfo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/wire"
|
||||||
|
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// create unrevoke command
|
||||||
|
func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "unrevoke",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Short: "unrevoke validator previously revoked for downtime",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||||
|
|
||||||
|
validatorAddr, err := sdk.GetAccAddressBech32Cosmos(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := slashing.NewMsgUnrevoke(validatorAddr)
|
||||||
|
|
||||||
|
// build and sign the transaction, then broadcast to Tendermint
|
||||||
|
res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String())
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
|
@ -2,14 +2,15 @@ package slashing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Stored by *validator* address (not owner address)
|
// Stored by *validator* address (not owner address)
|
||||||
func (k Keeper) getValidatorSigningInfo(ctx sdk.Context, address sdk.Address) (info validatorSigningInfo, found bool) {
|
func (k Keeper) getValidatorSigningInfo(ctx sdk.Context, address sdk.Address) (info ValidatorSigningInfo, found bool) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
bz := store.Get(validatorSigningInfoKey(address))
|
bz := store.Get(GetValidatorSigningInfoKey(address))
|
||||||
if bz == nil {
|
if bz == nil {
|
||||||
found = false
|
found = false
|
||||||
return
|
return
|
||||||
|
@ -20,16 +21,16 @@ func (k Keeper) getValidatorSigningInfo(ctx sdk.Context, address sdk.Address) (i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stored by *validator* address (not owner address)
|
// Stored by *validator* address (not owner address)
|
||||||
func (k Keeper) setValidatorSigningInfo(ctx sdk.Context, address sdk.Address, info validatorSigningInfo) {
|
func (k Keeper) setValidatorSigningInfo(ctx sdk.Context, address sdk.Address, info ValidatorSigningInfo) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
bz := k.cdc.MustMarshalBinary(info)
|
bz := k.cdc.MustMarshalBinary(info)
|
||||||
store.Set(validatorSigningInfoKey(address), bz)
|
store.Set(GetValidatorSigningInfoKey(address), bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stored by *validator* address (not owner address)
|
// Stored by *validator* address (not owner address)
|
||||||
func (k Keeper) getValidatorSigningBitArray(ctx sdk.Context, address sdk.Address, index int64) (signed bool) {
|
func (k Keeper) getValidatorSigningBitArray(ctx sdk.Context, address sdk.Address, index int64) (signed bool) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
bz := store.Get(validatorSigningBitArrayKey(address, index))
|
bz := store.Get(GetValidatorSigningBitArrayKey(address, index))
|
||||||
if bz == nil {
|
if bz == nil {
|
||||||
// lazy: treat empty key as unsigned
|
// lazy: treat empty key as unsigned
|
||||||
signed = false
|
signed = false
|
||||||
|
@ -43,23 +44,30 @@ func (k Keeper) getValidatorSigningBitArray(ctx sdk.Context, address sdk.Address
|
||||||
func (k Keeper) setValidatorSigningBitArray(ctx sdk.Context, address sdk.Address, index int64, signed bool) {
|
func (k Keeper) setValidatorSigningBitArray(ctx sdk.Context, address sdk.Address, index int64, signed bool) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
bz := k.cdc.MustMarshalBinary(signed)
|
bz := k.cdc.MustMarshalBinary(signed)
|
||||||
store.Set(validatorSigningBitArrayKey(address, index), bz)
|
store.Set(GetValidatorSigningBitArrayKey(address, index), bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
type validatorSigningInfo struct {
|
// Signing info for a validator
|
||||||
|
type ValidatorSigningInfo struct {
|
||||||
StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unrevoked
|
StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unrevoked
|
||||||
IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array
|
IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array
|
||||||
JailedUntil int64 `json:"jailed_until"` // timestamp validator cannot be unrevoked until
|
JailedUntil int64 `json:"jailed_until"` // timestamp validator cannot be unrevoked until
|
||||||
SignedBlocksCounter int64 `json:"signed_blocks_counter"` // signed blocks counter (to avoid scanning the array every time)
|
SignedBlocksCounter int64 `json:"signed_blocks_counter"` // signed blocks counter (to avoid scanning the array every time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return human readable signing info
|
||||||
|
func (i ValidatorSigningInfo) HumanReadableString() string {
|
||||||
|
return fmt.Sprintf("Start height: %d, index offset: %d, jailed until: %d, signed blocks counter: %d",
|
||||||
|
i.StartHeight, i.IndexOffset, i.JailedUntil, i.SignedBlocksCounter)
|
||||||
|
}
|
||||||
|
|
||||||
// Stored by *validator* address (not owner address)
|
// Stored by *validator* address (not owner address)
|
||||||
func validatorSigningInfoKey(v sdk.Address) []byte {
|
func GetValidatorSigningInfoKey(v sdk.Address) []byte {
|
||||||
return append([]byte{0x01}, v.Bytes()...)
|
return append([]byte{0x01}, v.Bytes()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stored by *validator* address (not owner address)
|
// Stored by *validator* address (not owner address)
|
||||||
func validatorSigningBitArrayKey(v sdk.Address, i int64) []byte {
|
func GetValidatorSigningBitArrayKey(v sdk.Address, i int64) []byte {
|
||||||
b := make([]byte, 8)
|
b := make([]byte, 8)
|
||||||
binary.LittleEndian.PutUint64(b, uint64(i))
|
binary.LittleEndian.PutUint64(b, uint64(i))
|
||||||
return append([]byte{0x02}, append(v.Bytes(), b...)...)
|
return append([]byte{0x02}, append(v.Bytes(), b...)...)
|
||||||
|
|
|
@ -10,7 +10,7 @@ func TestGetSetValidatorSigningInfo(t *testing.T) {
|
||||||
ctx, _, _, keeper := createTestInput(t)
|
ctx, _, _, keeper := createTestInput(t)
|
||||||
info, found := keeper.getValidatorSigningInfo(ctx, addrs[0])
|
info, found := keeper.getValidatorSigningInfo(ctx, addrs[0])
|
||||||
require.False(t, found)
|
require.False(t, found)
|
||||||
newInfo := validatorSigningInfo{
|
newInfo := ValidatorSigningInfo{
|
||||||
StartHeight: int64(4),
|
StartHeight: int64(4),
|
||||||
IndexOffset: int64(3),
|
IndexOffset: int64(3),
|
||||||
JailedUntil: int64(2),
|
JailedUntil: int64(2),
|
||||||
|
|
Loading…
Reference in New Issue