Merge PR #3400: power reduction for Tendermint

* add uncompiled power functionality

* fix some compile errors

* Power -> TendermintPower

* tests rename GetTendermintPower

* test fix

* working

* fix delegation tests

* fix slash tests

* staking/keeper tests passing

* docs reversion

* debuggin workin

* x/staking test pass

* fix gov tests

* fix x/slashing tests

* working distribution test fixes

* fix distribution tests

* lint

* fix lcd tests

* fix gov test

* lint

* CLI fixes, rm stakingTypes

* typos

* working cli fixes

* cli test fix

* cli tests fixed

* testnet creation modification

* typo

* pending

* Sanitize Dec.Roundint64 (#3475)

* merge fixes

* @cwgoes comments

* fix tests

* change power reduction to 10^-6

* option to turn off minting for LCD tests
This commit is contained in:
frog power 4000
2019-02-05 21:30:48 -08:00
committed by GitHub
parent df94f522f9
commit 52f2ec71a9
56 changed files with 1159 additions and 955 deletions
+8 -6
View File
@@ -12,7 +12,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/mock"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingTypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
var (
@@ -26,7 +25,7 @@ func getMockApp(t *testing.T) (*mock.App, staking.Keeper, Keeper) {
mapp := mock.NewApp()
RegisterCodec(mapp.Cdc)
stakingTypes.RegisterCodec(mapp.Cdc)
staking.RegisterCodec(mapp.Cdc)
keyStaking := sdk.NewKVStoreKey(staking.StoreKey)
tkeyStaking := sdk.NewTransientStoreKey(staking.TStoreKey)
@@ -62,7 +61,8 @@ func getInitChainer(mapp *mock.App, keeper staking.Keeper) sdk.InitChainer {
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
mapp.InitChainer(ctx, req)
stakingGenesis := staking.DefaultGenesisState()
stakingGenesis.Pool.NotBondedTokens = sdk.NewInt(100000)
tokens := staking.TokensFromTendermintPower(100000)
stakingGenesis.Pool.NotBondedTokens = tokens
validators, err := staking.InitGenesis(ctx, keeper, stakingGenesis)
if err != nil {
panic(err)
@@ -93,8 +93,10 @@ func checkValidatorSigningInfo(t *testing.T, mapp *mock.App, keeper Keeper,
func TestSlashingMsgs(t *testing.T) {
mapp, stakingKeeper, keeper := getMockApp(t)
genCoin := sdk.NewInt64Coin(stakingTypes.DefaultBondDenom, 42)
bondCoin := sdk.NewInt64Coin(stakingTypes.DefaultBondDenom, 10)
genTokens := staking.TokensFromTendermintPower(42)
bondTokens := staking.TokensFromTendermintPower(10)
genCoin := sdk.NewCoin(staking.DefaultBondDenom, genTokens)
bondCoin := sdk.NewCoin(staking.DefaultBondDenom, bondTokens)
acc1 := &auth.BaseAccount{
Address: addr1,
@@ -116,7 +118,7 @@ func TestSlashingMsgs(t *testing.T) {
validator := checkValidator(t, mapp, stakingKeeper, addr1, true)
require.Equal(t, sdk.ValAddress(addr1), validator.OperatorAddr)
require.Equal(t, sdk.Bonded, validator.Status)
require.True(sdk.IntEq(t, sdk.NewInt(10), validator.BondedTokens()))
require.True(sdk.IntEq(t, bondTokens, validator.BondedTokens()))
unjailMsg := MsgUnjail{ValidatorAddr: sdk.ValAddress(validator.ConsPubKey.Address())}
// no signing info yet
+9 -13
View File
@@ -8,24 +8,25 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestCannotUnjailUnlessJailed(t *testing.T) {
// initial setup
ctx, ck, sk, _, keeper := createTestInput(t, DefaultParams())
slh := NewHandler(keeper)
amtInt := int64(100)
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
amt := types.TokensFromTendermintPower(100)
addr, val := addrs[0], pks[0]
msg := NewTestMsgCreateValidator(addr, val, amt)
got := staking.NewHandler(sk)(ctx, msg)
require.True(t, got.IsOK())
require.True(t, got.IsOK(), "%v", got)
staking.EndBlocker(ctx, sk)
require.Equal(
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
)
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, addr).GetPower()))
require.Equal(t, amt, sk.Validator(ctx, addr).GetBondedTokens())
// assert non-jailed validator can't be unjailed
got = slh(ctx, NewMsgUnjail(addr))
@@ -42,8 +43,8 @@ func TestJailedValidatorDelegations(t *testing.T) {
stakingKeeper.SetParams(ctx, stakingParams)
// create a validator
amount := int64(10)
valPubKey, bondAmount := pks[0], sdk.NewInt(amount)
bondAmount := staking.TokensFromTendermintPower(10)
valPubKey := pks[0]
valAddr, consAddr := addrs[1], sdk.ConsAddress(addrs[0])
msgCreateVal := NewTestMsgCreateValidator(valAddr, valPubKey, bondAmount)
@@ -54,12 +55,7 @@ func TestJailedValidatorDelegations(t *testing.T) {
staking.EndBlocker(ctx, stakingKeeper)
// set dummy signing info
newInfo := ValidatorSigningInfo{
StartHeight: int64(0),
IndexOffset: int64(0),
JailedUntil: time.Unix(0, 0),
MissedBlocksCounter: int64(0),
}
newInfo := NewValidatorSigningInfo(0, 0, time.Unix(0, 0), false, 0)
slashingKeeper.SetValidatorSigningInfo(ctx, consAddr, newInfo)
// delegate tokens to the validator
@@ -68,7 +64,7 @@ func TestJailedValidatorDelegations(t *testing.T) {
got = staking.NewHandler(stakingKeeper)(ctx, msgDelegate)
require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
unbondShares := sdk.NewDec(10)
unbondShares := sdk.NewDecFromInt(bondAmount)
// unbond validator total self-delegations (which should jail the validator)
msgUndelegate := staking.NewMsgUndelegate(sdk.AccAddress(valAddr), valAddr, unbondShares)
+3 -2
View File
@@ -9,7 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/params"
staking "github.com/cosmos/cosmos-sdk/x/staking/types"
staking "github.com/cosmos/cosmos-sdk/x/staking"
)
// Keeper of the slashing store
@@ -49,7 +49,8 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
// Reject evidence if the double is too old
if age > k.MaxEvidenceAge(ctx) {
logger.Info(fmt.Sprintf("Ignored double sign from %s at height %d, age of %d past max age of %d", pubkey.Address(), infractionHeight, age, k.MaxEvidenceAge(ctx)))
logger.Info(fmt.Sprintf("Ignored double sign from %s at height %d, age of %d past max age of %d",
pubkey.Address(), infractionHeight, age, k.MaxEvidenceAge(ctx)))
return
}
+60 -50
View File
@@ -9,6 +9,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// Have to change these parameters for tests
@@ -30,8 +31,9 @@ func TestHandleDoubleSign(t *testing.T) {
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
// validator added pre-genesis
ctx = ctx.WithBlockHeight(-1)
amtInt := int64(100)
operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
power := int64(100)
amt := staking.TokensFromTendermintPower(power)
operatorAddr, val := addrs[0], pks[0]
got := staking.NewHandler(sk)(ctx, NewTestMsgCreateValidator(operatorAddr, val, amt))
require.True(t, got.IsOK())
staking.EndBlocker(ctx, sk)
@@ -39,15 +41,15 @@ func TestHandleDoubleSign(t *testing.T) {
t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)),
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
)
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, operatorAddr).GetPower()))
require.Equal(t, amt, sk.Validator(ctx, operatorAddr).GetBondedTokens())
// handle a signature to set signing info
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
keeper.handleValidatorSignature(ctx, val.Address(), amt.Int64(), true)
oldTokens := sk.Validator(ctx, operatorAddr).GetTokens()
// double sign less than max age
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt)
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), power)
// should be jailed
require.True(t, sk.Validator(ctx, operatorAddr).GetJailed())
@@ -57,7 +59,7 @@ func TestHandleDoubleSign(t *testing.T) {
require.True(t, newTokens.LT(oldTokens))
// New evidence
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt)
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), power)
// tokens should be the same (capped slash)
require.True(t, sk.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens))
@@ -87,8 +89,9 @@ func TestPastMaxEvidenceAge(t *testing.T) {
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
// validator added pre-genesis
ctx = ctx.WithBlockHeight(-1)
amtInt := int64(100)
operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
power := int64(100)
amt := staking.TokensFromTendermintPower(power)
operatorAddr, val := addrs[0], pks[0]
got := staking.NewHandler(sk)(ctx, NewTestMsgCreateValidator(operatorAddr, val, amt))
require.True(t, got.IsOK())
staking.EndBlocker(ctx, sk)
@@ -96,23 +99,23 @@ func TestPastMaxEvidenceAge(t *testing.T) {
t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)),
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
)
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, operatorAddr).GetPower()))
require.Equal(t, amt, sk.Validator(ctx, operatorAddr).GetBondedTokens())
// handle a signature to set signing info
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
keeper.handleValidatorSignature(ctx, val.Address(), power, true)
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))})
oldPower := sk.Validator(ctx, operatorAddr).GetPower()
oldPower := sk.Validator(ctx, operatorAddr).GetTendermintPower()
// double sign past max age
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt)
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), power)
// should still be bonded
require.True(t, sk.Validator(ctx, operatorAddr).GetStatus() == sdk.Bonded)
// should still have same power
require.True(t, sk.Validator(ctx, operatorAddr).GetPower().Equal(oldPower))
require.Equal(t, oldPower, sk.Validator(ctx, operatorAddr).GetTendermintPower())
}
// Test a validator through uptime, downtime, revocation,
@@ -121,8 +124,9 @@ func TestHandleAbsentValidator(t *testing.T) {
// initial setup
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
amtInt64 := int64(100)
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt64)
power := int64(100)
amt := staking.TokensFromTendermintPower(power)
addr, val := addrs[0], pks[0]
sh := staking.NewHandler(sk)
slh := NewHandler(keeper)
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
@@ -133,7 +137,7 @@ func TestHandleAbsentValidator(t *testing.T) {
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
)
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, addr).GetPower()))
require.Equal(t, amt, sk.Validator(ctx, addr).GetBondedTokens())
// will exist since the validator has been bonded
info, found := keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
@@ -147,7 +151,7 @@ func TestHandleAbsentValidator(t *testing.T) {
// 1000 first blocks OK
for ; height < keeper.SignedBlocksWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, true)
keeper.handleValidatorSignature(ctx, val.Address(), power, true)
}
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
@@ -157,7 +161,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.Address(), amtInt64, false)
keeper.handleValidatorSignature(ctx, val.Address(), power, false)
}
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
@@ -172,7 +176,7 @@ func TestHandleAbsentValidator(t *testing.T) {
// 501st block missed
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
keeper.handleValidatorSignature(ctx, val.Address(), power, false)
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
@@ -186,15 +190,15 @@ func TestHandleAbsentValidator(t *testing.T) {
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, sdk.Unbonding, validator.GetStatus())
slashAmt := sdk.NewDec(amtInt64).Mul(keeper.SlashFractionDowntime(ctx)).RoundInt64()
slashAmt := sdk.NewDecFromInt(amt).Mul(keeper.SlashFractionDowntime(ctx)).RoundInt64()
// validator should have been slashed
require.Equal(t, amtInt64-slashAmt, validator.GetTokens().Int64())
require.Equal(t, amt.Int64()-slashAmt, validator.GetTokens().Int64())
// 502nd block *also* missed (since the LastCommit would have still included the just-unbonded validator)
height++
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
keeper.handleValidatorSignature(ctx, val.Address(), power, false)
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
@@ -205,7 +209,7 @@ func TestHandleAbsentValidator(t *testing.T) {
// validator should not have been slashed any more, since it was already jailed
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, amtInt64-slashAmt, validator.GetTokens().Int64())
require.Equal(t, amt.Int64()-slashAmt, validator.GetTokens().Int64())
// unrevocation should fail prior to jail expiration
got = slh(ctx, NewMsgUnjail(addr))
@@ -225,7 +229,7 @@ func TestHandleAbsentValidator(t *testing.T) {
// validator should have been slashed
pool = sk.GetPool(ctx)
require.Equal(t, amtInt64-slashAmt, pool.BondedTokens.Int64())
require.Equal(t, amt.Int64()-slashAmt, pool.BondedTokens.Int64())
// Validator start height should not have been changed
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
@@ -237,7 +241,7 @@ func TestHandleAbsentValidator(t *testing.T) {
// validator should not be immediately jailed again
height++
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
keeper.handleValidatorSignature(ctx, val.Address(), power, false)
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, sdk.Bonded, validator.GetStatus())
@@ -245,7 +249,7 @@ func TestHandleAbsentValidator(t *testing.T) {
nextHeight := height + keeper.MinSignedPerWindow(ctx) + 1
for ; height < nextHeight; height++ {
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
keeper.handleValidatorSignature(ctx, val.Address(), power, false)
}
// end block
@@ -255,7 +259,7 @@ func TestHandleAbsentValidator(t *testing.T) {
nextHeight = height + keeper.MinSignedPerWindow(ctx) + 1
for ; height <= nextHeight; height++ {
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
keeper.handleValidatorSignature(ctx, val.Address(), power, false)
}
// end block
@@ -271,22 +275,23 @@ func TestHandleAbsentValidator(t *testing.T) {
func TestHandleNewValidator(t *testing.T) {
// initial setup
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
addr, val, amt := addrs[0], pks[0], int64(100)
addr, val := addrs[0], pks[0]
amt := staking.TokensFromTendermintPower(100)
sh := staking.NewHandler(sk)
// 1000 first blocks not a validator
ctx = ctx.WithBlockHeight(keeper.SignedBlocksWindow(ctx) + 1)
// Validator created
got := sh(ctx, NewTestMsgCreateValidator(addr, val, sdk.NewInt(amt)))
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
require.True(t, got.IsOK())
staking.EndBlocker(ctx, sk)
require.Equal(
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.SubRaw(amt))},
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
)
require.Equal(t, amt, sk.Validator(ctx, addr).GetPower().Int64())
require.Equal(t, amt, sk.Validator(ctx, addr).GetBondedTokens())
// Now a validator, for two blocks
keeper.handleValidatorSignature(ctx, val.Address(), 100, true)
@@ -304,7 +309,8 @@ func TestHandleNewValidator(t *testing.T) {
validator, _ := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, sdk.Bonded, validator.GetStatus())
pool := sk.GetPool(ctx)
require.Equal(t, int64(100), pool.BondedTokens.Int64())
expTokens := staking.TokensFromTendermintPower(100)
require.Equal(t, expTokens, pool.BondedTokens)
}
// Test a jailed validator being "down" twice
@@ -313,8 +319,9 @@ func TestHandleAlreadyJailed(t *testing.T) {
// initial setup
ctx, _, sk, _, keeper := createTestInput(t, DefaultParams())
amtInt := int64(100)
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
power := int64(100)
amt := staking.TokensFromTendermintPower(power)
addr, val := addrs[0], pks[0]
sh := staking.NewHandler(sk)
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
require.True(t, got.IsOK())
@@ -324,13 +331,13 @@ func TestHandleAlreadyJailed(t *testing.T) {
height := int64(0)
for ; height < keeper.SignedBlocksWindow(ctx); height++ {
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
keeper.handleValidatorSignature(ctx, val.Address(), power, 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.Address(), amtInt, false)
keeper.handleValidatorSignature(ctx, val.Address(), power, false)
}
// end block
@@ -341,15 +348,16 @@ func TestHandleAlreadyJailed(t *testing.T) {
require.Equal(t, sdk.Unbonding, validator.GetStatus())
// validator should have been slashed
require.Equal(t, amtInt-1, validator.GetTokens().Int64())
resultingTokens := amt.Sub(staking.TokensFromTendermintPower(1))
require.Equal(t, resultingTokens, validator.GetTokens())
// another block missed
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
keeper.handleValidatorSignature(ctx, val.Address(), power, false)
// validator should not have been slashed twice
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
require.Equal(t, amtInt-1, validator.GetTokens().Int64())
require.Equal(t, resultingTokens, validator.GetTokens())
}
@@ -364,8 +372,9 @@ func TestValidatorDippingInAndOut(t *testing.T) {
params := sk.GetParams(ctx)
params.MaxValidators = 1
sk.SetParams(ctx, params)
amtInt := int64(100)
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
power := int64(100)
amt := staking.TokensFromTendermintPower(power)
addr, val := addrs[0], pks[0]
consAddr := sdk.ConsAddress(addr)
sh := staking.NewHandler(sk)
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
@@ -376,12 +385,12 @@ func TestValidatorDippingInAndOut(t *testing.T) {
height := int64(0)
for ; height < int64(100); height++ {
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
keeper.handleValidatorSignature(ctx, val.Address(), power, true)
}
// validator kicked out of validator set
newAmt := int64(101)
got = sh(ctx, NewTestMsgCreateValidator(addrs[1], pks[1], sdk.NewInt(newAmt)))
newAmt := staking.TokensFromTendermintPower(101)
got = sh(ctx, NewTestMsgCreateValidator(addrs[1], pks[1], newAmt))
require.True(t, got.IsOK())
validatorUpdates, _ := staking.EndBlocker(ctx, sk)
require.Equal(t, 2, len(validatorUpdates))
@@ -393,16 +402,17 @@ func TestValidatorDippingInAndOut(t *testing.T) {
ctx = ctx.WithBlockHeight(height)
// validator added back in
got = sh(ctx, newTestMsgDelegate(sdk.AccAddress(addrs[2]), addrs[0], sdk.NewInt(3)))
delTokens := types.TokensFromTendermintPower(3)
got = sh(ctx, newTestMsgDelegate(sdk.AccAddress(addrs[2]), addrs[0], delTokens))
require.True(t, got.IsOK())
validatorUpdates, _ = staking.EndBlocker(ctx, sk)
require.Equal(t, 2, len(validatorUpdates))
validator, _ = sk.GetValidator(ctx, addr)
require.Equal(t, sdk.Bonded, validator.Status)
newAmt = int64(103)
newPower := int64(103)
// validator misses a block
keeper.handleValidatorSignature(ctx, val.Address(), newAmt, false)
keeper.handleValidatorSignature(ctx, val.Address(), newPower, false)
height++
// shouldn't be jailed/kicked yet
@@ -413,7 +423,7 @@ func TestValidatorDippingInAndOut(t *testing.T) {
latest := height
for ; height < latest+500; height++ {
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), newAmt, false)
keeper.handleValidatorSignature(ctx, val.Address(), newPower, false)
}
// should now be jailed & kicked
@@ -438,7 +448,7 @@ func TestValidatorDippingInAndOut(t *testing.T) {
// validator rejoins and starts signing again
sk.Unjail(ctx, consAddr)
keeper.handleValidatorSignature(ctx, val.Address(), newAmt, true)
keeper.handleValidatorSignature(ctx, val.Address(), newPower, true)
height++
// validator should not be kicked since we reset counter/array when it was jailed
@@ -450,7 +460,7 @@ func TestValidatorDippingInAndOut(t *testing.T) {
latest = height
for ; height < latest+501; height++ {
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), newAmt, false)
keeper.handleValidatorSignature(ctx, val.Address(), newPower, false)
}
// validator should now be jailed & kicked
+8 -3
View File
@@ -81,11 +81,13 @@ func DefaultParams() Params {
// TODO Temporarily set to 10 minutes for testnets
DowntimeJailDuration: 60 * 10 * time.Second,
// CONTRACT must be less than 1
// TODO enforce this contract https://github.com/cosmos/cosmos-sdk/issues/3474
MinSignedPerWindow: sdk.NewDecWithPrec(5, 1),
SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(20)),
SlashFractionDoubleSign: sdk.NewDec(1).QuoInt64(20),
SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(100)),
SlashFractionDowntime: sdk.NewDec(1).QuoInt64(100),
}
}
@@ -107,7 +109,10 @@ func (k Keeper) MinSignedPerWindow(ctx sdk.Context) int64 {
var minSignedPerWindow sdk.Dec
k.paramspace.Get(ctx, KeyMinSignedPerWindow, &minSignedPerWindow)
signedBlocksWindow := k.SignedBlocksWindow(ctx)
return sdk.NewDec(signedBlocksWindow).Mul(minSignedPerWindow).RoundInt64()
// NOTE: RoundInt64 will never panic as minSignedPerWindow is
// less than 1.
return minSignedPerWindow.MulInt64(signedBlocksWindow).RoundInt64()
}
// Downtime unbond duration
+13 -11
View File
@@ -90,17 +90,6 @@ func (k Keeper) clearValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.C
}
}
// Construct a new `ValidatorSigningInfo` struct
func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil time.Time, tombstoned bool, missedBlocksCounter int64) ValidatorSigningInfo {
return ValidatorSigningInfo{
StartHeight: startHeight,
IndexOffset: indexOffset,
JailedUntil: jailedUntil,
Tombstoned: tombstoned,
MissedBlocksCounter: missedBlocksCounter,
}
}
// Signing info for a validator
type ValidatorSigningInfo struct {
StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unjailed
@@ -110,6 +99,19 @@ type ValidatorSigningInfo struct {
MissedBlocksCounter int64 `json:"missed_blocks_counter"` // missed blocks counter (to avoid scanning the array every time)
}
// Construct a new `ValidatorSigningInfo` struct
func NewValidatorSigningInfo(startHeight, indexOffset int64, jailedUntil time.Time,
tombstoned bool, missedBlocksCounter int64) ValidatorSigningInfo {
return ValidatorSigningInfo{
StartHeight: startHeight,
IndexOffset: indexOffset,
JailedUntil: jailedUntil,
Tombstoned: tombstoned,
MissedBlocksCounter: missedBlocksCounter,
}
}
// Return human readable signing info
func (i ValidatorSigningInfo) String() string {
return fmt.Sprintf(`Start Height: %d
+3 -4
View File
@@ -21,7 +21,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingTypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// TODO remove dependencies on staking (should only refer to validator set type from sdk)
@@ -37,7 +36,7 @@ var (
sdk.ValAddress(pks[1].Address()),
sdk.ValAddress(pks[2].Address()),
}
initCoins = sdk.NewInt(200)
initCoins = staking.TokensFromTendermintPower(200)
)
func createTestCodec() *codec.Codec {
@@ -76,7 +75,7 @@ func createTestInput(t *testing.T, defaults Params) (sdk.Context, bank.Keeper, s
sk := staking.NewKeeper(cdc, keyStaking, tkeyStaking, ck, paramsKeeper.Subspace(staking.DefaultParamspace), staking.DefaultCodespace)
genesis := staking.DefaultGenesisState()
genesis.Pool.NotBondedTokens = sdk.NewInt(initCoins.MulRaw(int64(len(addrs))).Int64())
genesis.Pool.NotBondedTokens = initCoins.MulRaw(int64(len(addrs)))
_, err = staking.InitGenesis(ctx, sk, genesis)
require.Nil(t, err)
@@ -116,7 +115,7 @@ func testAddr(addr string) sdk.AccAddress {
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator {
commission := staking.NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
return staking.NewMsgCreateValidator(
address, pubKey, sdk.NewCoin(stakingTypes.DefaultBondDenom, amt),
address, pubKey, sdk.NewCoin(staking.DefaultBondDenom, amt),
staking.Description{}, commission,
)
}
+5 -2
View File
@@ -10,11 +10,14 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestBeginBlocker(t *testing.T) {
ctx, ck, sk, _, keeper := createTestInput(t, DefaultParams())
addr, pk, amt := addrs[2], pks[2], sdk.NewInt(100)
power := int64(100)
amt := types.TokensFromTendermintPower(power)
addr, pk := addrs[2], pks[2]
// bond the validator
got := staking.NewHandler(sk)(ctx, NewTestMsgCreateValidator(addr, pk, amt))
@@ -24,7 +27,7 @@ func TestBeginBlocker(t *testing.T) {
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
)
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, addr).GetPower()))
require.Equal(t, amt, sk.Validator(ctx, addr).GetBondedTokens())
val := abci.Validator{
Address: pk.Address(),