Upgrade to tm version 23.0. (#1927)
* Start upgrade. Currently go test ./... hangs. * (squash this) Fix staking tests * wip * note what changes need to be made to make this work on tm v0.23.0 * Fix addr -> pubkey map * cleanup code * Fix slashing test failures except for begin blocker * fix all slashing tests * fix lcd tests * Address PR comments * add link to changelog. * (wip) start making addrToPubkey map persisted. Since amino can't handle maps, we have to change from what this commit is doing. * Use the correct method of storing a map * (squash this) address PR comments * Did you run 'make'? * remove gaiadebug binary
This commit is contained in:
+4
-4
@@ -158,10 +158,10 @@ func (msg StdSignMsg) Bytes() []byte {
|
||||
|
||||
// Standard Signature
|
||||
type StdSignature struct {
|
||||
crypto.PubKey `json:"pub_key"` // optional
|
||||
crypto.Signature `json:"signature"`
|
||||
AccountNumber int64 `json:"account_number"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
crypto.PubKey `json:"pub_key"` // optional
|
||||
Signature []byte `json:"signature"`
|
||||
AccountNumber int64 `json:"account_number"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
}
|
||||
|
||||
// logic for standard transaction decoding
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package slashing
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
)
|
||||
|
||||
// InitGenesis initializes the keeper's address to pubkey map.
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
||||
for _, validator := range data.Validators {
|
||||
keeper.addPubkey(ctx, validator.GetPubKey())
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -39,7 +39,7 @@ func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result {
|
||||
}
|
||||
|
||||
// Cannot be unrevoked until out of jail
|
||||
if ctx.BlockHeader().Time < info.JailedUntil {
|
||||
if ctx.BlockHeader().Time.Before(info.JailedUntil) {
|
||||
return ErrValidatorJailed(k.codespace).Result()
|
||||
}
|
||||
|
||||
|
||||
+59
-10
@@ -2,10 +2,14 @@ package slashing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
@@ -15,7 +19,6 @@ type Keeper struct {
|
||||
cdc *wire.Codec
|
||||
validatorSet sdk.ValidatorSet
|
||||
params params.Getter
|
||||
|
||||
// codespace
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
@@ -33,10 +36,10 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, vs sdk.ValidatorSet, params pa
|
||||
}
|
||||
|
||||
// handle a validator signing two blocks at the same height
|
||||
func (k Keeper) handleDoubleSign(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight int64, timestamp int64, power int64) {
|
||||
func (k Keeper) handleDoubleSign(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight int64, timestamp time.Time, power int64) {
|
||||
logger := ctx.Logger().With("module", "x/slashing")
|
||||
time := ctx.BlockHeader().Time
|
||||
age := time - timestamp
|
||||
age := time.Sub(timestamp)
|
||||
address := sdk.ValAddress(pubkey.Address())
|
||||
|
||||
// Double sign too old
|
||||
@@ -60,23 +63,26 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, pubkey crypto.PubKey, infracti
|
||||
if !found {
|
||||
panic(fmt.Sprintf("Expected signing info for validator %s but not found", address))
|
||||
}
|
||||
signInfo.JailedUntil = time + k.DoubleSignUnbondDuration(ctx)
|
||||
signInfo.JailedUntil = time.Add(k.DoubleSignUnbondDuration(ctx))
|
||||
k.setValidatorSigningInfo(ctx, address, signInfo)
|
||||
}
|
||||
|
||||
// handle a validator signature, must be called once per validator per block
|
||||
// nolint gocyclo
|
||||
func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey, power int64, signed bool) {
|
||||
func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, power int64, signed bool) {
|
||||
logger := ctx.Logger().With("module", "x/slashing")
|
||||
height := ctx.BlockHeight()
|
||||
address := sdk.ValAddress(pubkey.Address())
|
||||
|
||||
address := sdk.ValAddress(addr)
|
||||
pubkey, err := k.getPubkey(ctx, addr)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Validator address %v not found", addr))
|
||||
}
|
||||
// Local index, so counts blocks validator *should* have signed
|
||||
// Will use the 0-value default signing info if not present, except for start height
|
||||
signInfo, found := k.getValidatorSigningInfo(ctx, address)
|
||||
if !found {
|
||||
// If this validator has never been seen before, construct a new SigningInfo with the correct start height
|
||||
signInfo = NewValidatorSigningInfo(height, 0, 0, 0)
|
||||
signInfo = NewValidatorSigningInfo(height, 0, time.Unix(0, 0), 0)
|
||||
}
|
||||
index := signInfo.IndexOffset % k.SignedBlocksWindow(ctx)
|
||||
signInfo.IndexOffset++
|
||||
@@ -98,7 +104,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey,
|
||||
}
|
||||
|
||||
if !signed {
|
||||
logger.Info(fmt.Sprintf("Absent validator %s at height %d, %d signed, threshold %d", pubkey.Address(), height, signInfo.SignedBlocksCounter, k.MinSignedPerWindow(ctx)))
|
||||
logger.Info(fmt.Sprintf("Absent validator %s at height %d, %d signed, threshold %d", addr, height, signInfo.SignedBlocksCounter, k.MinSignedPerWindow(ctx)))
|
||||
}
|
||||
minHeight := signInfo.StartHeight + k.SignedBlocksWindow(ctx)
|
||||
if height > minHeight && signInfo.SignedBlocksCounter < k.MinSignedPerWindow(ctx) {
|
||||
@@ -109,7 +115,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey,
|
||||
pubkey.Address(), minHeight, k.MinSignedPerWindow(ctx)))
|
||||
k.validatorSet.Slash(ctx, pubkey, height, power, k.SlashFractionDowntime(ctx))
|
||||
k.validatorSet.Revoke(ctx, pubkey)
|
||||
signInfo.JailedUntil = ctx.BlockHeader().Time + k.DowntimeUnbondDuration(ctx)
|
||||
signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeUnbondDuration(ctx))
|
||||
} else {
|
||||
// Validator was (a) not found or (b) already revoked, don't slash
|
||||
logger.Info(fmt.Sprintf("Validator %s would have been slashed for downtime, but was either not found in store or already revoked",
|
||||
@@ -120,3 +126,46 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey,
|
||||
// Set the updated signing info
|
||||
k.setValidatorSigningInfo(ctx, address, signInfo)
|
||||
}
|
||||
|
||||
// AddValidators adds the validators to the keepers validator addr to pubkey mapping.
|
||||
func (k Keeper) AddValidators(ctx sdk.Context, vals []abci.Validator) {
|
||||
for i := 0; i < len(vals); i++ {
|
||||
val := vals[i]
|
||||
pubkey, err := tmtypes.PB2TM.PubKey(val.PubKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.addPubkey(ctx, pubkey)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make a method to remove the pubkey from the map when a validator is unbonded.
|
||||
func (k Keeper) addPubkey(ctx sdk.Context, pubkey crypto.PubKey) {
|
||||
addr := pubkey.Address()
|
||||
k.setAddrPubkeyRelation(ctx, addr, pubkey)
|
||||
}
|
||||
|
||||
func (k Keeper) getPubkey(ctx sdk.Context, address crypto.Address) (crypto.PubKey, error) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
var pubkey crypto.PubKey
|
||||
err := k.cdc.UnmarshalBinary(store.Get(getAddrPubkeyRelationKey(address)), &pubkey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("address %v not found", address)
|
||||
}
|
||||
return pubkey, nil
|
||||
}
|
||||
|
||||
func (k Keeper) setAddrPubkeyRelation(ctx sdk.Context, addr crypto.Address, pubkey crypto.PubKey) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := k.cdc.MustMarshalBinary(pubkey)
|
||||
store.Set(getAddrPubkeyRelationKey(addr), bz)
|
||||
}
|
||||
|
||||
func (k Keeper) deleteAddrPubkeyRelation(ctx sdk.Context, addr crypto.Address) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(getAddrPubkeyRelationKey(addr))
|
||||
}
|
||||
|
||||
func getAddrPubkeyRelationKey(address []byte) []byte {
|
||||
return append([]byte{0x03}, address...)
|
||||
}
|
||||
|
||||
+31
-26
@@ -2,13 +2,12 @@ package slashing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
)
|
||||
|
||||
// Have to change these parameters for tests
|
||||
@@ -29,15 +28,16 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
stake.EndBlocker(ctx, sk)
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||
require.True(t, sdk.NewRatFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||
|
||||
// handle a signature to set signing info
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, true)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
|
||||
|
||||
// double sign less than max age
|
||||
keeper.handleDoubleSign(ctx, val, 0, 0, amtInt)
|
||||
keeper.handleDoubleSign(ctx, val, 0, time.Unix(0, 0), amtInt)
|
||||
|
||||
// should be revoked
|
||||
require.True(t, sk.Validator(ctx, addr).GetRevoked())
|
||||
@@ -45,10 +45,10 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
sk.Unrevoke(ctx, val)
|
||||
// power should be reduced
|
||||
require.Equal(t, sdk.NewRatFromInt(amt).Mul(sdk.NewRat(19).Quo(sdk.NewRat(20))), sk.Validator(ctx, addr).GetPower())
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: 1 + keeper.MaxEvidenceAge(ctx)})
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))})
|
||||
|
||||
// double sign past max age
|
||||
keeper.handleDoubleSign(ctx, val, 0, 0, amtInt)
|
||||
keeper.handleDoubleSign(ctx, val, 0, time.Unix(0, 0), amtInt)
|
||||
require.Equal(t, sdk.NewRatFromInt(amt).Mul(sdk.NewRat(19).Quo(sdk.NewRat(20))), sk.Validator(ctx, addr).GetPower())
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
slh := NewHandler(keeper)
|
||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
stake.EndBlocker(ctx, sk)
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||
require.True(t, sdk.NewRatFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||
info, found := keeper.getValidatorSigningInfo(ctx, sdk.ValAddress(val.Address()))
|
||||
@@ -72,13 +73,15 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
require.Equal(t, int64(0), info.StartHeight)
|
||||
require.Equal(t, int64(0), info.IndexOffset)
|
||||
require.Equal(t, int64(0), info.SignedBlocksCounter)
|
||||
require.Equal(t, int64(0), info.JailedUntil)
|
||||
// default time.Time value
|
||||
var blankTime time.Time
|
||||
require.Equal(t, blankTime, info.JailedUntil)
|
||||
height := int64(0)
|
||||
|
||||
// 1000 first blocks OK
|
||||
for ; height < keeper.SignedBlocksWindow(ctx); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, true)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
|
||||
}
|
||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ValAddress(val.Address()))
|
||||
require.True(t, found)
|
||||
@@ -88,7 +91,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
// 500 blocks missed
|
||||
for ; height < keeper.SignedBlocksWindow(ctx)+(keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, false)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
||||
}
|
||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ValAddress(val.Address()))
|
||||
require.True(t, found)
|
||||
@@ -103,7 +106,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
|
||||
// 501st block missed
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, false)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ValAddress(val.Address()))
|
||||
require.True(t, found)
|
||||
require.Equal(t, int64(0), info.StartHeight)
|
||||
@@ -118,7 +121,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
require.False(t, got.IsOK())
|
||||
|
||||
// unrevocation should succeed after jail expiration
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: keeper.DowntimeUnbondDuration(ctx) + 1})
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.DowntimeUnbondDuration(ctx))})
|
||||
got = slh(ctx, NewMsgUnrevoke(addr))
|
||||
require.True(t, got.IsOK())
|
||||
|
||||
@@ -140,7 +143,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
// validator should not be immediately revoked again
|
||||
height++
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, false)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
||||
validator, _ = sk.GetValidatorByPubKey(ctx, val)
|
||||
require.Equal(t, sdk.Bonded, validator.GetStatus())
|
||||
|
||||
@@ -148,14 +151,14 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
nextHeight := height + keeper.MinSignedPerWindow(ctx) + 1
|
||||
for ; height < nextHeight; height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, false)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
||||
}
|
||||
|
||||
// validator should be revoked again after 500 unsigned blocks
|
||||
nextHeight = height + keeper.MinSignedPerWindow(ctx) + 1
|
||||
for ; height <= nextHeight; height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, false)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
||||
}
|
||||
validator, _ = sk.GetValidatorByPubKey(ctx, val)
|
||||
require.Equal(t, sdk.Unbonded, validator.GetStatus())
|
||||
@@ -171,7 +174,8 @@ func TestHandleNewValidator(t *testing.T) {
|
||||
sh := stake.NewHandler(sk)
|
||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, sdk.NewInt(amt)))
|
||||
require.True(t, got.IsOK())
|
||||
stake.EndBlocker(ctx, sk)
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.SubRaw(amt)}})
|
||||
require.Equal(t, sdk.NewRat(amt), sk.Validator(ctx, addr).GetPower())
|
||||
|
||||
@@ -179,16 +183,16 @@ func TestHandleNewValidator(t *testing.T) {
|
||||
ctx = ctx.WithBlockHeight(keeper.SignedBlocksWindow(ctx) + 1)
|
||||
|
||||
// Now a validator, for two blocks
|
||||
keeper.handleValidatorSignature(ctx, val, 100, true)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), 100, true)
|
||||
ctx = ctx.WithBlockHeight(keeper.SignedBlocksWindow(ctx) + 2)
|
||||
keeper.handleValidatorSignature(ctx, val, 100, false)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), 100, false)
|
||||
|
||||
info, found := keeper.getValidatorSigningInfo(ctx, sdk.ValAddress(val.Address()))
|
||||
require.True(t, found)
|
||||
require.Equal(t, int64(keeper.SignedBlocksWindow(ctx)+1), info.StartHeight)
|
||||
require.Equal(t, int64(2), info.IndexOffset)
|
||||
require.Equal(t, int64(1), info.SignedBlocksCounter)
|
||||
require.Equal(t, int64(0), info.JailedUntil)
|
||||
require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
|
||||
|
||||
// validator should be bonded still, should not have been revoked or slashed
|
||||
validator, _ := sk.GetValidatorByPubKey(ctx, val)
|
||||
@@ -208,19 +212,20 @@ func TestHandleAlreadyRevoked(t *testing.T) {
|
||||
sh := stake.NewHandler(sk)
|
||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
stake.EndBlocker(ctx, sk)
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
|
||||
// 1000 first blocks OK
|
||||
height := int64(0)
|
||||
for ; height < keeper.SignedBlocksWindow(ctx); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, true)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
|
||||
}
|
||||
|
||||
// 501 blocks missed
|
||||
for ; height < keeper.SignedBlocksWindow(ctx)+(keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx))+1; height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, false)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
||||
}
|
||||
|
||||
// validator should have been revoked and slashed
|
||||
@@ -232,7 +237,7 @@ func TestHandleAlreadyRevoked(t *testing.T) {
|
||||
|
||||
// another block missed
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
keeper.handleValidatorSignature(ctx, val, amtInt, false)
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
||||
|
||||
// validator should not have been slashed twice
|
||||
validator, _ = sk.GetValidatorByPubKey(ctx, val)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package slashing
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
@@ -17,8 +19,8 @@ const (
|
||||
|
||||
// MaxEvidenceAge - Max age for evidence - 21 days (3 weeks)
|
||||
// MaxEvidenceAge = 60 * 60 * 24 * 7 * 3
|
||||
func (k Keeper) MaxEvidenceAge(ctx sdk.Context) int64 {
|
||||
return k.params.GetInt64WithDefault(ctx, MaxEvidenceAgeKey, defaultMaxEvidenceAge)
|
||||
func (k Keeper) MaxEvidenceAge(ctx sdk.Context) time.Duration {
|
||||
return time.Duration(k.params.GetInt64WithDefault(ctx, MaxEvidenceAgeKey, defaultMaxEvidenceAge)) * time.Second
|
||||
}
|
||||
|
||||
// SignedBlocksWindow - sliding window for downtime slashing
|
||||
@@ -34,13 +36,13 @@ func (k Keeper) MinSignedPerWindow(ctx sdk.Context) int64 {
|
||||
}
|
||||
|
||||
// Double-sign unbond duration
|
||||
func (k Keeper) DoubleSignUnbondDuration(ctx sdk.Context) int64 {
|
||||
return k.params.GetInt64WithDefault(ctx, DoubleSignUnbondDurationKey, defaultDoubleSignUnbondDuration)
|
||||
func (k Keeper) DoubleSignUnbondDuration(ctx sdk.Context) time.Duration {
|
||||
return time.Duration(k.params.GetInt64WithDefault(ctx, DoubleSignUnbondDurationKey, defaultDoubleSignUnbondDuration)) * time.Second
|
||||
}
|
||||
|
||||
// Downtime unbond duration
|
||||
func (k Keeper) DowntimeUnbondDuration(ctx sdk.Context) int64 {
|
||||
return k.params.GetInt64WithDefault(ctx, DowntimeUnbondDurationKey, defaultDowntimeUnbondDuration)
|
||||
func (k Keeper) DowntimeUnbondDuration(ctx sdk.Context) time.Duration {
|
||||
return time.Duration(k.params.GetInt64WithDefault(ctx, DowntimeUnbondDurationKey, defaultDowntimeUnbondDuration)) * time.Second
|
||||
}
|
||||
|
||||
// SlashFractionDoubleSign - currently default 5%
|
||||
|
||||
@@ -3,6 +3,7 @@ package slashing
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
@@ -48,7 +49,7 @@ func (k Keeper) setValidatorSigningBitArray(ctx sdk.Context, address sdk.ValAddr
|
||||
}
|
||||
|
||||
// Construct a new `ValidatorSigningInfo` struct
|
||||
func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil int64, signedBlocksCounter int64) ValidatorSigningInfo {
|
||||
func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil time.Time, signedBlocksCounter int64) ValidatorSigningInfo {
|
||||
return ValidatorSigningInfo{
|
||||
StartHeight: startHeight,
|
||||
IndexOffset: indexOffset,
|
||||
@@ -59,15 +60,15 @@ func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil i
|
||||
|
||||
// Signing info for a validator
|
||||
type ValidatorSigningInfo struct {
|
||||
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
|
||||
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)
|
||||
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
|
||||
JailedUntil time.Time `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)
|
||||
}
|
||||
|
||||
// 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",
|
||||
return fmt.Sprintf("Start height: %d, index offset: %d, jailed until: %v, signed blocks counter: %d",
|
||||
i.StartHeight, i.IndexOffset, i.JailedUntil, i.SignedBlocksCounter)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package slashing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@@ -15,7 +16,7 @@ func TestGetSetValidatorSigningInfo(t *testing.T) {
|
||||
newInfo := ValidatorSigningInfo{
|
||||
StartHeight: int64(4),
|
||||
IndexOffset: int64(3),
|
||||
JailedUntil: int64(2),
|
||||
JailedUntil: time.Unix(2, 0),
|
||||
SignedBlocksCounter: int64(10),
|
||||
}
|
||||
keeper.setValidatorSigningInfo(ctx, sdk.ValAddress(addrs[0]), newInfo)
|
||||
@@ -23,7 +24,7 @@ func TestGetSetValidatorSigningInfo(t *testing.T) {
|
||||
require.True(t, found)
|
||||
require.Equal(t, info.StartHeight, int64(4))
|
||||
require.Equal(t, info.IndexOffset, int64(3))
|
||||
require.Equal(t, info.JailedUntil, int64(2))
|
||||
require.Equal(t, info.JailedUntil, time.Unix(2, 0).UTC())
|
||||
require.Equal(t, info.SignedBlocksCounter, int64(10))
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -20,13 +20,9 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags
|
||||
// Iterate over all the validators which *should* have signed this block
|
||||
// Store whether or not they have actually signed it and slash/unbond any
|
||||
// which have missed too many blocks in a row (downtime slashing)
|
||||
for _, signingValidator := range req.Validators {
|
||||
for _, signingValidator := range req.LastCommitInfo.GetValidators() {
|
||||
present := signingValidator.SignedLastBlock
|
||||
pubkey, err := tmtypes.PB2TM.PubKey(signingValidator.Validator.PubKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sk.handleValidatorSignature(ctx, pubkey, signingValidator.Validator.Power, present)
|
||||
sk.handleValidatorSignature(ctx, signingValidator.Validator.Address, signingValidator.Validator.Power, present)
|
||||
}
|
||||
|
||||
// Iterate through any newly discovered evidence of infraction
|
||||
|
||||
+24
-17
@@ -2,11 +2,11 @@ package slashing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
@@ -19,21 +19,24 @@ func TestBeginBlocker(t *testing.T) {
|
||||
// bond the validator
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, pk, amt))
|
||||
require.True(t, got.IsOK())
|
||||
stake.EndBlocker(ctx, sk)
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||
require.True(t, sdk.NewRatFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||
|
||||
val := abci.Validator{
|
||||
PubKey: tmtypes.TM2PB.PubKey(pk),
|
||||
Power: amt.Int64(),
|
||||
Address: pk.Address(),
|
||||
Power: amt.Int64(),
|
||||
}
|
||||
|
||||
// mark the validator as having signed
|
||||
req := abci.RequestBeginBlock{
|
||||
Validators: []abci.SigningValidator{{
|
||||
Validator: val,
|
||||
SignedLastBlock: true,
|
||||
}},
|
||||
LastCommitInfo: abci.LastCommitInfo{
|
||||
Validators: []abci.SigningValidator{{
|
||||
Validator: val,
|
||||
SignedLastBlock: true,
|
||||
}},
|
||||
},
|
||||
}
|
||||
BeginBlocker(ctx, req, keeper)
|
||||
|
||||
@@ -41,7 +44,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||
require.True(t, found)
|
||||
require.Equal(t, ctx.BlockHeight(), info.StartHeight)
|
||||
require.Equal(t, int64(1), info.IndexOffset)
|
||||
require.Equal(t, int64(0), info.JailedUntil)
|
||||
require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
|
||||
require.Equal(t, int64(1), info.SignedBlocksCounter)
|
||||
|
||||
height := int64(0)
|
||||
@@ -50,10 +53,12 @@ func TestBeginBlocker(t *testing.T) {
|
||||
for ; height < keeper.SignedBlocksWindow(ctx); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
req = abci.RequestBeginBlock{
|
||||
Validators: []abci.SigningValidator{{
|
||||
Validator: val,
|
||||
SignedLastBlock: true,
|
||||
}},
|
||||
LastCommitInfo: abci.LastCommitInfo{
|
||||
Validators: []abci.SigningValidator{{
|
||||
Validator: val,
|
||||
SignedLastBlock: true,
|
||||
}},
|
||||
},
|
||||
}
|
||||
BeginBlocker(ctx, req, keeper)
|
||||
}
|
||||
@@ -62,10 +67,12 @@ func TestBeginBlocker(t *testing.T) {
|
||||
for ; height < ((keeper.SignedBlocksWindow(ctx) * 2) - keeper.MinSignedPerWindow(ctx) + 1); height++ {
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
req = abci.RequestBeginBlock{
|
||||
Validators: []abci.SigningValidator{{
|
||||
Validator: val,
|
||||
SignedLastBlock: false,
|
||||
}},
|
||||
LastCommitInfo: abci.LastCommitInfo{
|
||||
Validators: []abci.SigningValidator{{
|
||||
Validator: val,
|
||||
SignedLastBlock: false,
|
||||
}},
|
||||
},
|
||||
}
|
||||
BeginBlocker(ctx, req, keeper)
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
package stake
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/tags"
|
||||
@@ -38,7 +40,7 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.Valid
|
||||
|
||||
// Process provision inflation
|
||||
blockTime := ctx.BlockHeader().Time
|
||||
if blockTime-pool.InflationLastTime >= 3600 {
|
||||
if blockTime.Sub(pool.InflationLastTime) >= time.Hour {
|
||||
params := k.GetParams(ctx)
|
||||
pool.InflationLastTime = blockTime
|
||||
pool = pool.ProcessProvisions(params)
|
||||
|
||||
@@ -2,6 +2,7 @@ package stake
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -500,7 +501,7 @@ func TestUnbondingPeriod(t *testing.T) {
|
||||
|
||||
// set the unbonding time
|
||||
params := keeper.GetParams(ctx)
|
||||
params.UnbondingTime = 7
|
||||
params.UnbondingTime = 7 * time.Second
|
||||
keeper.SetParams(ctx, params)
|
||||
|
||||
// create the validator
|
||||
@@ -516,19 +517,19 @@ func TestUnbondingPeriod(t *testing.T) {
|
||||
// cannot complete unbonding at same time
|
||||
msgCompleteUnbonding := NewMsgCompleteUnbonding(validatorAddr, validatorAddr)
|
||||
got = handleMsgCompleteUnbonding(ctx, msgCompleteUnbonding, keeper)
|
||||
require.True(t, !got.IsOK(), "expected no error")
|
||||
require.True(t, !got.IsOK(), "expected an error")
|
||||
|
||||
// cannot complete unbonding at time 6 seconds later
|
||||
origHeader := ctx.BlockHeader()
|
||||
headerTime6 := origHeader
|
||||
headerTime6.Time += 6
|
||||
headerTime6.Time = headerTime6.Time.Add(time.Second * 6)
|
||||
ctx = ctx.WithBlockHeader(headerTime6)
|
||||
got = handleMsgCompleteUnbonding(ctx, msgCompleteUnbonding, keeper)
|
||||
require.True(t, !got.IsOK(), "expected no error")
|
||||
require.True(t, !got.IsOK(), "expected an error")
|
||||
|
||||
// can complete unbonding at time 7 seconds later
|
||||
headerTime7 := origHeader
|
||||
headerTime7.Time += 7
|
||||
headerTime7.Time = headerTime7.Time.Add(time.Second * 7)
|
||||
ctx = ctx.WithBlockHeader(headerTime7)
|
||||
got = handleMsgCompleteUnbonding(ctx, msgCompleteUnbonding, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error")
|
||||
@@ -541,7 +542,7 @@ func TestRedelegationPeriod(t *testing.T) {
|
||||
|
||||
// set the unbonding time
|
||||
params := keeper.GetParams(ctx)
|
||||
params.UnbondingTime = 7
|
||||
params.UnbondingTime = 7 * time.Second
|
||||
keeper.SetParams(ctx, params)
|
||||
|
||||
// create the validators
|
||||
@@ -580,14 +581,14 @@ func TestRedelegationPeriod(t *testing.T) {
|
||||
// cannot complete redelegation at time 6 seconds later
|
||||
origHeader := ctx.BlockHeader()
|
||||
headerTime6 := origHeader
|
||||
headerTime6.Time += 6
|
||||
headerTime6.Time = headerTime6.Time.Add(time.Second * 6)
|
||||
ctx = ctx.WithBlockHeader(headerTime6)
|
||||
got = handleMsgCompleteRedelegate(ctx, msgCompleteRedelegate, keeper)
|
||||
require.True(t, !got.IsOK(), "expected an error")
|
||||
|
||||
// can complete redelegation at time 7 seconds later
|
||||
headerTime7 := origHeader
|
||||
headerTime7.Time += 7
|
||||
headerTime7.Time = headerTime7.Time.Add(time.Second * 7)
|
||||
ctx = ctx.WithBlockHeader(headerTime7)
|
||||
got = handleMsgCompleteRedelegate(ctx, msgCompleteRedelegate, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error")
|
||||
|
||||
@@ -327,7 +327,7 @@ func (k Keeper) BeginUnbonding(ctx sdk.Context, delegatorAddr, validatorAddr sdk
|
||||
|
||||
// create the unbonding delegation
|
||||
params := k.GetParams(ctx)
|
||||
minTime := ctx.BlockHeader().Time + params.UnbondingTime
|
||||
minTime := ctx.BlockHeader().Time.Add(params.UnbondingTime)
|
||||
balance := sdk.Coin{params.BondDenom, returnAmount.RoundInt()}
|
||||
|
||||
ubd := types.UnbondingDelegation{
|
||||
@@ -351,7 +351,7 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delegatorAddr, validatorAddr
|
||||
|
||||
// ensure that enough time has passed
|
||||
ctxTime := ctx.BlockHeader().Time
|
||||
if ubd.MinTime > ctxTime {
|
||||
if ubd.MinTime.After(ctxTime) {
|
||||
return types.ErrNotMature(k.Codespace(), "unbonding", "unit-time", ubd.MinTime, ctxTime)
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delegatorAddr, validatorSrcAd
|
||||
}
|
||||
|
||||
// create the unbonding delegation
|
||||
minTime := ctx.BlockHeader().Time + params.UnbondingTime
|
||||
minTime := ctx.BlockHeader().Time.Add(params.UnbondingTime)
|
||||
|
||||
red := types.Redelegation{
|
||||
DelegatorAddr: delegatorAddr,
|
||||
@@ -415,7 +415,7 @@ func (k Keeper) CompleteRedelegation(ctx sdk.Context, delegatorAddr, validatorSr
|
||||
|
||||
// ensure that enough time has passed
|
||||
ctxTime := ctx.BlockHeader().Time
|
||||
if red.MinTime > ctxTime {
|
||||
if red.MinTime.After(ctxTime) {
|
||||
return types.ErrNotMature(k.Codespace(), "redelegation", "unit-time", red.MinTime, ctxTime)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
@@ -115,7 +116,7 @@ func TestUnbondingDelegation(t *testing.T) {
|
||||
DelegatorAddr: addrDels[0],
|
||||
ValidatorAddr: addrVals[0],
|
||||
CreationHeight: 0,
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
Balance: sdk.NewInt64Coin("steak", 5),
|
||||
}
|
||||
|
||||
@@ -188,7 +189,7 @@ func TestGetRedelegationsFromValidator(t *testing.T) {
|
||||
ValidatorSrcAddr: addrVals[0],
|
||||
ValidatorDstAddr: addrVals[1],
|
||||
CreationHeight: 0,
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
SharesSrc: sdk.NewRat(5),
|
||||
SharesDst: sdk.NewRat(5),
|
||||
}
|
||||
@@ -218,7 +219,7 @@ func TestRedelegation(t *testing.T) {
|
||||
ValidatorSrcAddr: addrVals[0],
|
||||
ValidatorDstAddr: addrVals[1],
|
||||
CreationHeight: 0,
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
SharesSrc: sdk.NewRat(5),
|
||||
SharesDst: sdk.NewRat(5),
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty
|
||||
return sdk.ZeroRat()
|
||||
}
|
||||
|
||||
if unbondingDelegation.MinTime < now {
|
||||
if unbondingDelegation.MinTime.Before(now) {
|
||||
// Unbonding delegation no longer eligible for slashing, skip it
|
||||
// TODO Settle and delete it automatically?
|
||||
return sdk.ZeroRat()
|
||||
@@ -203,7 +203,7 @@ func (k Keeper) slashRedelegation(ctx sdk.Context, validator types.Validator, re
|
||||
return sdk.ZeroRat()
|
||||
}
|
||||
|
||||
if redelegation.MinTime < now {
|
||||
if redelegation.MinTime.Before(now) {
|
||||
// Redelegation no longer eligible for slashing, skip it
|
||||
// TODO Delete it automatically?
|
||||
return sdk.ZeroRat()
|
||||
|
||||
@@ -2,6 +2,7 @@ package keeper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@@ -70,7 +71,7 @@ func TestSlashUnbondingDelegation(t *testing.T) {
|
||||
ValidatorAddr: addrVals[0],
|
||||
CreationHeight: 0,
|
||||
// expiration timestamp (beyond which the unbonding delegation shouldn't be slashed)
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
InitialBalance: sdk.NewInt64Coin(params.BondDenom, 10),
|
||||
Balance: sdk.NewInt64Coin(params.BondDenom, 10),
|
||||
}
|
||||
@@ -81,14 +82,14 @@ func TestSlashUnbondingDelegation(t *testing.T) {
|
||||
require.Equal(t, int64(0), slashAmount.RoundInt64())
|
||||
|
||||
// after the expiration time, no longer eligible for slashing
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: int64(10)})
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
|
||||
require.Equal(t, int64(0), slashAmount.RoundInt64())
|
||||
|
||||
// test valid slash, before expiration timestamp and to which stake contributed
|
||||
oldPool := keeper.GetPool(ctx)
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: int64(0)})
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
|
||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
|
||||
require.Equal(t, int64(5), slashAmount.RoundInt64())
|
||||
@@ -114,7 +115,7 @@ func TestSlashRedelegation(t *testing.T) {
|
||||
ValidatorDstAddr: addrVals[1],
|
||||
CreationHeight: 0,
|
||||
// expiration timestamp (beyond which the redelegation shouldn't be slashed)
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
SharesSrc: sdk.NewRat(10),
|
||||
SharesDst: sdk.NewRat(10),
|
||||
InitialBalance: sdk.NewInt64Coin(params.BondDenom, 10),
|
||||
@@ -137,7 +138,7 @@ func TestSlashRedelegation(t *testing.T) {
|
||||
require.Equal(t, int64(0), slashAmount.RoundInt64())
|
||||
|
||||
// after the expiration time, no longer eligible for slashing
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: int64(10)})
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
||||
keeper.SetRedelegation(ctx, rd)
|
||||
validator, found = keeper.GetValidator(ctx, addrVals[1])
|
||||
require.True(t, found)
|
||||
@@ -146,7 +147,7 @@ func TestSlashRedelegation(t *testing.T) {
|
||||
|
||||
// test valid slash, before expiration timestamp and to which stake contributed
|
||||
oldPool := keeper.GetPool(ctx)
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: int64(0)})
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
|
||||
keeper.SetRedelegation(ctx, rd)
|
||||
validator, found = keeper.GetValidator(ctx, addrVals[1])
|
||||
require.True(t, found)
|
||||
@@ -209,7 +210,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||
ValidatorAddr: addrVals[0],
|
||||
CreationHeight: 11,
|
||||
// expiration timestamp (beyond which the unbonding delegation shouldn't be slashed)
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
InitialBalance: sdk.NewInt64Coin(params.BondDenom, 4),
|
||||
Balance: sdk.NewInt64Coin(params.BondDenom, 4),
|
||||
}
|
||||
@@ -310,7 +311,7 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||
ValidatorSrcAddr: addrVals[0],
|
||||
ValidatorDstAddr: addrVals[1],
|
||||
CreationHeight: 11,
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
SharesSrc: sdk.NewRat(6),
|
||||
SharesDst: sdk.NewRat(6),
|
||||
InitialBalance: sdk.NewInt64Coin(params.BondDenom, 6),
|
||||
@@ -432,7 +433,7 @@ func TestSlashBoth(t *testing.T) {
|
||||
ValidatorDstAddr: addrVals[1],
|
||||
CreationHeight: 11,
|
||||
// expiration timestamp (beyond which the redelegation shouldn't be slashed)
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
SharesSrc: sdk.NewRat(6),
|
||||
SharesDst: sdk.NewRat(6),
|
||||
InitialBalance: sdk.NewInt64Coin(params.BondDenom, 6),
|
||||
@@ -454,7 +455,7 @@ func TestSlashBoth(t *testing.T) {
|
||||
ValidatorAddr: addrVals[0],
|
||||
CreationHeight: 11,
|
||||
// expiration timestamp (beyond which the unbonding delegation shouldn't be slashed)
|
||||
MinTime: 0,
|
||||
MinTime: time.Unix(0, 0),
|
||||
InitialBalance: sdk.NewInt64Coin(params.BondDenom, 4),
|
||||
Balance: sdk.NewInt64Coin(params.BondDenom, 4),
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
@@ -100,14 +101,14 @@ type UnbondingDelegation struct {
|
||||
DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // delegator
|
||||
ValidatorAddr sdk.AccAddress `json:"validator_addr"` // validator unbonding from owner addr
|
||||
CreationHeight int64 `json:"creation_height"` // height which the unbonding took place
|
||||
MinTime int64 `json:"min_time"` // unix time for unbonding completion
|
||||
MinTime time.Time `json:"min_time"` // unix time for unbonding completion
|
||||
InitialBalance sdk.Coin `json:"initial_balance"` // atoms initially scheduled to receive at completion
|
||||
Balance sdk.Coin `json:"balance"` // atoms to receive at completion
|
||||
}
|
||||
|
||||
type ubdValue struct {
|
||||
CreationHeight int64
|
||||
MinTime int64
|
||||
MinTime time.Time
|
||||
InitialBalance sdk.Coin
|
||||
Balance sdk.Coin
|
||||
}
|
||||
@@ -186,7 +187,7 @@ type Redelegation struct {
|
||||
ValidatorSrcAddr sdk.AccAddress `json:"validator_src_addr"` // validator redelegation source owner addr
|
||||
ValidatorDstAddr sdk.AccAddress `json:"validator_dst_addr"` // validator redelegation destination owner addr
|
||||
CreationHeight int64 `json:"creation_height"` // height which the redelegation took place
|
||||
MinTime int64 `json:"min_time"` // unix time for redelegation completion
|
||||
MinTime time.Time `json:"min_time"` // unix time for redelegation completion
|
||||
InitialBalance sdk.Coin `json:"initial_balance"` // initial balance when redelegation started
|
||||
Balance sdk.Coin `json:"balance"` // current balance
|
||||
SharesSrc sdk.Rat `json:"shares_src"` // amount of source shares redelegating
|
||||
@@ -195,7 +196,7 @@ type Redelegation struct {
|
||||
|
||||
type redValue struct {
|
||||
CreationHeight int64
|
||||
MinTime int64
|
||||
MinTime time.Time
|
||||
InitialBalance sdk.Coin
|
||||
Balance sdk.Coin
|
||||
SharesSrc sdk.Rat
|
||||
|
||||
@@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -57,7 +58,7 @@ func TestUnbondingDelegationEqual(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
|
||||
ud2.ValidatorAddr = addr3
|
||||
ud2.MinTime = 20 * 20 * 2
|
||||
ud2.MinTime = time.Unix(20*20*2, 0)
|
||||
|
||||
ok = ud1.Equal(ud2)
|
||||
require.False(t, ok)
|
||||
@@ -93,7 +94,7 @@ func TestRedelegationEqual(t *testing.T) {
|
||||
|
||||
r2.SharesDst = sdk.NewRat(10)
|
||||
r2.SharesSrc = sdk.NewRat(20)
|
||||
r2.MinTime = 20 * 20 * 2
|
||||
r2.MinTime = time.Unix(20*20*2, 0)
|
||||
|
||||
ok = r1.Equal(r2)
|
||||
require.False(t, ok)
|
||||
|
||||
@@ -3,6 +3,7 @@ package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
@@ -110,7 +111,7 @@ func ErrBadSharesPercent(codespace sdk.CodespaceType) sdk.Error {
|
||||
return sdk.NewError(codespace, CodeInvalidDelegation, "shares percent must be >0 and <=1")
|
||||
}
|
||||
|
||||
func ErrNotMature(codespace sdk.CodespaceType, operation, descriptor string, got, min int64) sdk.Error {
|
||||
func ErrNotMature(codespace sdk.CodespaceType, operation, descriptor string, got, min time.Time) sdk.Error {
|
||||
msg := fmt.Sprintf("%v is not mature requires a min %v of %v, currently it is %v",
|
||||
operation, descriptor, got, min)
|
||||
return sdk.NewError(codespace, CodeUnauthorized, msg)
|
||||
|
||||
@@ -2,13 +2,14 @@ package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// defaultUnbondingTime reflects three weeks in seconds as the default
|
||||
// unbonding time.
|
||||
const defaultUnbondingTime int64 = 60 * 60 * 24 * 3
|
||||
const defaultUnbondingTime time.Duration = 60 * 60 * 24 * 3 * time.Second
|
||||
|
||||
// Params defines the high level settings for staking
|
||||
type Params struct {
|
||||
@@ -17,7 +18,7 @@ type Params struct {
|
||||
InflationMin sdk.Rat `json:"inflation_min"` // minimum inflation rate
|
||||
GoalBonded sdk.Rat `json:"goal_bonded"` // Goal of percent bonded atoms
|
||||
|
||||
UnbondingTime int64 `json:"unbonding_time"`
|
||||
UnbondingTime time.Duration `json:"unbonding_time"`
|
||||
|
||||
MaxValidators uint16 `json:"max_validators"` // maximum number of validators
|
||||
BondDenom string `json:"bond_denom"` // bondable coin denomination
|
||||
|
||||
@@ -3,16 +3,17 @@ package types
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Pool - dynamic parameters of the current state
|
||||
type Pool struct {
|
||||
LooseTokens sdk.Rat `json:"loose_tokens"` // tokens which are not bonded in a validator
|
||||
BondedTokens sdk.Rat `json:"bonded_tokens"` // reserve of bonded tokens
|
||||
InflationLastTime int64 `json:"inflation_last_time"` // block which the last inflation was processed // TODO make time
|
||||
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
|
||||
LooseTokens sdk.Rat `json:"loose_tokens"` // tokens which are not bonded in a validator
|
||||
BondedTokens sdk.Rat `json:"bonded_tokens"` // reserve of bonded tokens
|
||||
InflationLastTime time.Time `json:"inflation_last_time"` // block which the last inflation was processed
|
||||
Inflation sdk.Rat `json:"inflation"` // current annual inflation rate
|
||||
|
||||
DateLastCommissionReset int64 `json:"date_last_commission_reset"` // unix timestamp for last commission accounting reset (daily)
|
||||
|
||||
@@ -32,7 +33,7 @@ func InitialPool() Pool {
|
||||
return Pool{
|
||||
LooseTokens: sdk.ZeroRat(),
|
||||
BondedTokens: sdk.ZeroRat(),
|
||||
InflationLastTime: 0,
|
||||
InflationLastTime: time.Unix(0, 0),
|
||||
Inflation: sdk.NewRat(7, 100),
|
||||
DateLastCommissionReset: 0,
|
||||
PrevBondedShares: sdk.ZeroRat(),
|
||||
|
||||
@@ -3,6 +3,7 @@ package types
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -184,7 +185,7 @@ func TestRemoveDelShares(t *testing.T) {
|
||||
pool := Pool{
|
||||
BondedTokens: sdk.NewRat(248305),
|
||||
LooseTokens: sdk.NewRat(232147),
|
||||
InflationLastTime: 0,
|
||||
InflationLastTime: time.Unix(0, 0),
|
||||
Inflation: sdk.NewRat(7, 100),
|
||||
}
|
||||
shares := sdk.NewRat(29)
|
||||
@@ -232,7 +233,7 @@ func TestPossibleOverflow(t *testing.T) {
|
||||
pool := Pool{
|
||||
LooseTokens: sdk.NewRat(100),
|
||||
BondedTokens: poolTokens,
|
||||
InflationLastTime: 0,
|
||||
InflationLastTime: time.Unix(0, 0),
|
||||
Inflation: sdk.NewRat(7, 100),
|
||||
}
|
||||
tokens := int64(71)
|
||||
|
||||
Reference in New Issue
Block a user