Merge PR #2958: Validator Power Dec-> Int
* Validator Power Dec-> Int, working * non-test code compiles * working, many test compile fixes * all test compile errors resolved * ... * slashing test fixes minor * test cover passes * invariant rounding issue * comment update * PENDING and doc updates * @cwgoes comments * RemoveDelShares trimmings to the final delegation share * fixes * ... * fix the oopsie * @alexanderbez comments * merge fixes * address @cwgoes comments
This commit is contained in:
parent
67a1e47c6e
commit
a98a5a056a
|
@ -18,6 +18,7 @@ BREAKING CHANGES
|
||||||
in order to trigger a simulation of the tx before the actual execution.
|
in order to trigger a simulation of the tx before the actual execution.
|
||||||
|
|
||||||
* SDK
|
* SDK
|
||||||
|
* [stake] \#2513 Validator power type from Dec -> Int
|
||||||
* [\#3064](https://github.com/cosmos/cosmos-sdk/issues/3064) Sanitize `sdk.Coin` denom. Coins denoms are now case insensitive, i.e. 100fooToken equals to 100FOOTOKEN.
|
* [\#3064](https://github.com/cosmos/cosmos-sdk/issues/3064) Sanitize `sdk.Coin` denom. Coins denoms are now case insensitive, i.e. 100fooToken equals to 100FOOTOKEN.
|
||||||
* \#3207 - Fix token printing bug
|
* \#3207 - Fix token printing bug
|
||||||
|
|
||||||
|
|
|
@ -347,9 +347,9 @@ func TestPoolParamsQuery(t *testing.T) {
|
||||||
pool := getStakePool(t, port)
|
pool := getStakePool(t, port)
|
||||||
|
|
||||||
initialPool := stake.InitialPool()
|
initialPool := stake.InitialPool()
|
||||||
initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewDec(100))
|
initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewInt(100))
|
||||||
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(100)) // Delegate tx on GaiaAppGenState
|
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewInt(100)) // Delegate tx on GaiaAppGenState
|
||||||
initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewDec(int64(50))) // freeFermionsAcc = 50 on GaiaAppGenState
|
initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewInt(50)) // freeFermionsAcc = 50 on GaiaAppGenState
|
||||||
|
|
||||||
require.Equal(t, initialPool.BondedTokens, pool.BondedTokens)
|
require.Equal(t, initialPool.BondedTokens, pool.BondedTokens)
|
||||||
require.Equal(t, initialPool.LooseTokens, pool.LooseTokens)
|
require.Equal(t, initialPool.LooseTokens, pool.LooseTokens)
|
||||||
|
|
|
@ -291,7 +291,7 @@ func InitializeTestLCD(
|
||||||
accAuth.Coins = sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 100)}
|
accAuth.Coins = sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 100)}
|
||||||
acc := gapp.NewGenesisAccount(&accAuth)
|
acc := gapp.NewGenesisAccount(&accAuth)
|
||||||
genesisState.Accounts = append(genesisState.Accounts, acc)
|
genesisState.Accounts = append(genesisState.Accounts, acc)
|
||||||
genesisState.StakeData.Pool.LooseTokens = genesisState.StakeData.Pool.LooseTokens.Add(sdk.NewDec(100))
|
genesisState.StakeData.Pool.LooseTokens = genesisState.StakeData.Pool.LooseTokens.Add(sdk.NewInt(100))
|
||||||
}
|
}
|
||||||
|
|
||||||
appState, err := codec.MarshalJSONIndent(cdc, genesisState)
|
appState, err := codec.MarshalJSONIndent(cdc, genesisState)
|
||||||
|
|
|
@ -130,7 +130,7 @@ func GaiaAppGenState(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []js
|
||||||
for _, coin := range acc.Coins {
|
for _, coin := range acc.Coins {
|
||||||
if coin.Denom == bondDenom {
|
if coin.Denom == bondDenom {
|
||||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.
|
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.
|
||||||
Add(sdk.NewDecFromInt(coin.Amount)) // increase the supply
|
Add(coin.Amount) // increase the supply
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ func makeGenesisState(t *testing.T, genTxs []auth.StdTx) GenesisState {
|
||||||
acc := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddr))
|
acc := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddr))
|
||||||
acc.Coins = sdk.Coins{sdk.NewInt64Coin(bondDenom, 150)}
|
acc.Coins = sdk.Coins{sdk.NewInt64Coin(bondDenom, 150)}
|
||||||
genAccs[i] = NewGenesisAccount(&acc)
|
genAccs[i] = NewGenesisAccount(&acc)
|
||||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDec(150)) // increase the supply
|
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewInt(150)) // increase the supply
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the final app state
|
// create the final app state
|
||||||
|
|
|
@ -151,13 +151,13 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
||||||
valAddrs[i] = valAddr
|
valAddrs[i] = valAddr
|
||||||
|
|
||||||
validator := stake.NewValidator(valAddr, accs[i].PubKey, stake.Description{})
|
validator := stake.NewValidator(valAddr, accs[i].PubKey, stake.Description{})
|
||||||
validator.Tokens = sdk.NewDec(amount)
|
validator.Tokens = sdk.NewInt(amount)
|
||||||
validator.DelegatorShares = sdk.NewDec(amount)
|
validator.DelegatorShares = sdk.NewDec(amount)
|
||||||
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(amount)}
|
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(amount)}
|
||||||
validators = append(validators, validator)
|
validators = append(validators, validator)
|
||||||
delegations = append(delegations, delegation)
|
delegations = append(delegations, delegation)
|
||||||
}
|
}
|
||||||
stakeGenesis.Pool.LooseTokens = sdk.NewDec((amount * numAccs) + (numInitiallyBonded * amount))
|
stakeGenesis.Pool.LooseTokens = sdk.NewInt((amount * numAccs) + (numInitiallyBonded * amount))
|
||||||
stakeGenesis.Validators = validators
|
stakeGenesis.Validators = validators
|
||||||
stakeGenesis.Bonds = delegations
|
stakeGenesis.Bonds = delegations
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||||
|
|
||||||
defaultParams := stake.DefaultParams()
|
defaultParams := stake.DefaultParams()
|
||||||
initialPool := stake.InitialPool()
|
initialPool := stake.InitialPool()
|
||||||
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(100)) // Delegate tx on GaiaAppGenState
|
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewInt(100)) // Delegate tx on GaiaAppGenState
|
||||||
|
|
||||||
// create validator
|
// create validator
|
||||||
cvStr := fmt.Sprintf("gaiacli tx stake create-validator %v", flags)
|
cvStr := fmt.Sprintf("gaiacli tx stake create-validator %v", flags)
|
||||||
|
@ -244,7 +244,7 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||||
cvStr += fmt.Sprintf(" --commission-max-rate=%v", "0.20")
|
cvStr += fmt.Sprintf(" --commission-max-rate=%v", "0.20")
|
||||||
cvStr += fmt.Sprintf(" --commission-max-change-rate=%v", "0.10")
|
cvStr += fmt.Sprintf(" --commission-max-change-rate=%v", "0.10")
|
||||||
|
|
||||||
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(1))
|
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewInt(1))
|
||||||
|
|
||||||
// Test --generate-only
|
// Test --generate-only
|
||||||
success, stdout, stderr := executeWriteRetStdStreams(t, cvStr+" --generate-only", app.DefaultKeyPass)
|
success, stdout, stderr := executeWriteRetStdStreams(t, cvStr+" --generate-only", app.DefaultKeyPass)
|
||||||
|
@ -268,7 +268,7 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||||
|
|
||||||
validator := executeGetValidator(t, fmt.Sprintf("gaiacli query stake validator %s %v", sdk.ValAddress(barAddr), flags))
|
validator := executeGetValidator(t, fmt.Sprintf("gaiacli query stake validator %s %v", sdk.ValAddress(barAddr), flags))
|
||||||
require.Equal(t, validator.OperatorAddr, sdk.ValAddress(barAddr))
|
require.Equal(t, validator.OperatorAddr, sdk.ValAddress(barAddr))
|
||||||
require.True(sdk.DecEq(t, sdk.NewDec(2), validator.Tokens))
|
require.True(sdk.IntEq(t, sdk.NewInt(2), validator.Tokens))
|
||||||
|
|
||||||
validatorDelegations := executeGetValidatorDelegations(t, fmt.Sprintf("gaiacli query stake delegations-to %s %v", sdk.ValAddress(barAddr), flags))
|
validatorDelegations := executeGetValidatorDelegations(t, fmt.Sprintf("gaiacli query stake delegations-to %s %v", sdk.ValAddress(barAddr), flags))
|
||||||
require.Len(t, validatorDelegations, 1)
|
require.Len(t, validatorDelegations, 1)
|
||||||
|
@ -289,7 +289,7 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||||
require.Equal(t, int64(9), barAcc.GetCoins().AmountOf(stakeTypes.DefaultBondDenom).Int64(), "%v", barAcc)
|
require.Equal(t, int64(9), barAcc.GetCoins().AmountOf(stakeTypes.DefaultBondDenom).Int64(), "%v", barAcc)
|
||||||
*/
|
*/
|
||||||
validator = executeGetValidator(t, fmt.Sprintf("gaiacli query stake validator %s %v", sdk.ValAddress(barAddr), flags))
|
validator = executeGetValidator(t, fmt.Sprintf("gaiacli query stake validator %s %v", sdk.ValAddress(barAddr), flags))
|
||||||
require.Equal(t, "1.0000000000", validator.Tokens.String())
|
require.Equal(t, "1", validator.Tokens.String())
|
||||||
|
|
||||||
validatorUbds := executeGetValidatorUnbondingDelegations(t,
|
validatorUbds := executeGetValidatorUnbondingDelegations(t,
|
||||||
fmt.Sprintf("gaiacli query stake unbonding-delegations-from %s %v", sdk.ValAddress(barAddr), flags))
|
fmt.Sprintf("gaiacli query stake unbonding-delegations-from %s %v", sdk.ValAddress(barAddr), flags))
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
// Validator implements sdk.Validator
|
// Validator implements sdk.Validator
|
||||||
type Validator struct {
|
type Validator struct {
|
||||||
Address sdk.ValAddress
|
Address sdk.ValAddress
|
||||||
Power sdk.Dec
|
Power sdk.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements sdk.Validator
|
// Implements sdk.Validator
|
||||||
|
@ -35,12 +35,12 @@ func (v Validator) GetConsAddr() sdk.ConsAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements sdk.Validator
|
// Implements sdk.Validator
|
||||||
func (v Validator) GetTokens() sdk.Dec {
|
func (v Validator) GetTokens() sdk.Int {
|
||||||
return sdk.ZeroDec()
|
return sdk.ZeroInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements sdk.Validator
|
// Implements sdk.Validator
|
||||||
func (v Validator) GetPower() sdk.Dec {
|
func (v Validator) GetPower() sdk.Int {
|
||||||
return v.Power
|
return v.Power
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +114,8 @@ func (vs *ValidatorSet) ValidatorByConsAddr(_ sdk.Context, _ sdk.ConsAddress) sd
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalPower implements sdk.ValidatorSet
|
// TotalPower implements sdk.ValidatorSet
|
||||||
func (vs *ValidatorSet) TotalPower(ctx sdk.Context) sdk.Dec {
|
func (vs *ValidatorSet) TotalPower(ctx sdk.Context) sdk.Int {
|
||||||
res := sdk.ZeroDec()
|
res := sdk.ZeroInt()
|
||||||
for _, val := range vs.Validators {
|
for _, val := range vs.Validators {
|
||||||
res = res.Add(val.Power)
|
res = res.Add(val.Power)
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ func TestValidatorSet(t *testing.T) {
|
||||||
addr2 := []byte("addr2")
|
addr2 := []byte("addr2")
|
||||||
|
|
||||||
base := &mock.ValidatorSet{[]mock.Validator{
|
base := &mock.ValidatorSet{[]mock.Validator{
|
||||||
{addr1, sdk.NewDec(1)},
|
{addr1, sdk.NewInt(1)},
|
||||||
{addr2, sdk.NewDec(2)},
|
{addr2, sdk.NewInt(2)},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
valset := NewValidatorSet(codec.New(), ctx.KVStore(key).Prefix([]byte("assoc")), base, 1, 5)
|
valset := NewValidatorSet(codec.New(), ctx.KVStore(key).Prefix([]byte("assoc")), base, 1, 5)
|
||||||
|
|
|
@ -14,7 +14,7 @@ func (keeper Keeper) update(ctx sdk.Context, val sdk.Validator, valset sdk.Valid
|
||||||
|
|
||||||
// Return if the voted power is not bigger than required power
|
// Return if the voted power is not bigger than required power
|
||||||
totalPower := valset.TotalPower(ctx)
|
totalPower := valset.TotalPower(ctx)
|
||||||
requiredPower := totalPower.Mul(keeper.supermaj)
|
requiredPower := keeper.supermaj.MulInt(totalPower).RoundInt()
|
||||||
if !info.Power.GT(requiredPower) {
|
if !info.Power.GT(requiredPower) {
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ func (keeper Keeper) update(ctx sdk.Context, val sdk.Validator, valset sdk.Valid
|
||||||
// and recalculate voted power
|
// and recalculate voted power
|
||||||
hash := ctx.BlockHeader().ValidatorsHash
|
hash := ctx.BlockHeader().ValidatorsHash
|
||||||
if !bytes.Equal(hash, info.Hash) {
|
if !bytes.Equal(hash, info.Hash) {
|
||||||
info.Power = sdk.ZeroDec()
|
info.Power = sdk.ZeroInt()
|
||||||
info.Hash = hash
|
info.Hash = hash
|
||||||
prefix := GetSignPrefix(p, keeper.cdc)
|
prefix := GetSignPrefix(p, keeper.cdc)
|
||||||
store := ctx.KVStore(keeper.key)
|
store := ctx.KVStore(keeper.key)
|
||||||
|
@ -36,7 +36,7 @@ func (keeper Keeper) update(ctx sdk.Context, val sdk.Validator, valset sdk.Valid
|
||||||
}
|
}
|
||||||
info.Power = info.Power.Add(val.GetPower())
|
info.Power = info.Power.Add(val.GetPower())
|
||||||
}
|
}
|
||||||
if !info.Power.GT(totalPower.Mul(keeper.supermaj)) {
|
if !info.Power.GT(keeper.supermaj.MulInt(totalPower).RoundInt()) {
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ const (
|
||||||
|
|
||||||
// Info for each payload
|
// Info for each payload
|
||||||
type Info struct {
|
type Info struct {
|
||||||
Power sdk.Dec
|
Power sdk.Int
|
||||||
Hash []byte
|
Hash []byte
|
||||||
LastSigned int64
|
LastSigned int64
|
||||||
Status InfoStatus
|
Status InfoStatus
|
||||||
|
@ -55,7 +55,7 @@ type Info struct {
|
||||||
// EmptyInfo construct an empty Info
|
// EmptyInfo construct an empty Info
|
||||||
func EmptyInfo(ctx sdk.Context) Info {
|
func EmptyInfo(ctx sdk.Context) Info {
|
||||||
return Info{
|
return Info{
|
||||||
Power: sdk.ZeroDec(),
|
Power: sdk.ZeroInt(),
|
||||||
Hash: ctx.BlockHeader().ValidatorsHash,
|
Hash: ctx.BlockHeader().ValidatorsHash,
|
||||||
LastSigned: ctx.BlockHeight(),
|
LastSigned: ctx.BlockHeight(),
|
||||||
Status: Pending,
|
Status: Pending,
|
||||||
|
|
|
@ -110,9 +110,9 @@ func TestOracle(t *testing.T) {
|
||||||
addr3 := []byte("addr3")
|
addr3 := []byte("addr3")
|
||||||
addr4 := []byte("addr4")
|
addr4 := []byte("addr4")
|
||||||
valset := &mock.ValidatorSet{[]mock.Validator{
|
valset := &mock.ValidatorSet{[]mock.Validator{
|
||||||
{addr1, sdk.NewDec(7)},
|
{addr1, sdk.NewInt(7)},
|
||||||
{addr2, sdk.NewDec(7)},
|
{addr2, sdk.NewInt(7)},
|
||||||
{addr3, sdk.NewDec(1)},
|
{addr3, sdk.NewInt(1)},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
key := sdk.NewKVStoreKey("testkey")
|
key := sdk.NewKVStoreKey("testkey")
|
||||||
|
@ -174,7 +174,7 @@ func TestOracle(t *testing.T) {
|
||||||
require.Equal(t, 1, getSequence(ctx, key))
|
require.Equal(t, 1, getSequence(ctx, key))
|
||||||
|
|
||||||
// Should handle mock.Validator set change
|
// Should handle mock.Validator set change
|
||||||
valset.AddValidator(mock.Validator{addr4, sdk.NewDec(12)})
|
valset.AddValidator(mock.Validator{addr4, sdk.NewInt(12)})
|
||||||
bz, err = json.Marshal(valset)
|
bz, err = json.Marshal(valset)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{ValidatorsHash: bz})
|
ctx = ctx.WithBlockHeader(abci.Header{ValidatorsHash: bz})
|
||||||
|
|
|
@ -10,8 +10,8 @@ inflation information, etc.
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
type Pool struct {
|
type Pool struct {
|
||||||
LooseTokens int64 // tokens not associated with any bonded validator
|
LooseTokens sdk.Int // tokens not associated with any bonded validator
|
||||||
BondedTokens int64 // reserve of bonded tokens
|
BondedTokens sdk.Int // reserve of bonded tokens
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -65,9 +65,8 @@ type Validator struct {
|
||||||
Jailed bool // has the validator been jailed?
|
Jailed bool // has the validator been jailed?
|
||||||
|
|
||||||
Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
|
Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
|
||||||
Tokens sdk.Dec // delegated tokens (incl. self-delegation)
|
Tokens sdk.Int // delegated tokens (incl. self-delegation)
|
||||||
DelegatorShares sdk.Dec // total shares issued to a validator's delegators
|
DelegatorShares sdk.Dec // total shares issued to a validator's delegators
|
||||||
SlashRatio sdk.Dec // increases each time the validator is slashed
|
|
||||||
|
|
||||||
Description Description // description terms for the validator
|
Description Description // description terms for the validator
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ Other notes:
|
||||||
* `getXxx`, `setXxx`, and `removeXxx` functions are used to retrieve and
|
* `getXxx`, `setXxx`, and `removeXxx` functions are used to retrieve and
|
||||||
modify objects from the store
|
modify objects from the store
|
||||||
* `sdk.Dec` refers to a decimal type specified by the SDK.
|
* `sdk.Dec` refers to a decimal type specified by the SDK.
|
||||||
|
* `sdk.Int` refers to an integer type specified by the SDK.
|
||||||
|
|
||||||
## TxCreateValidator
|
## TxCreateValidator
|
||||||
|
|
||||||
|
|
24
types/int.go
24
types/int.go
|
@ -40,6 +40,13 @@ func min(i *big.Int, i2 *big.Int) *big.Int {
|
||||||
return new(big.Int).Set(i)
|
return new(big.Int).Set(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func max(i *big.Int, i2 *big.Int) *big.Int {
|
||||||
|
if i.Cmp(i2) == 1 {
|
||||||
|
return new(big.Int).Set(i)
|
||||||
|
}
|
||||||
|
return new(big.Int).Set(i2)
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalAmino for custom encoding scheme
|
// MarshalAmino for custom encoding scheme
|
||||||
func marshalAmino(i *big.Int) (string, error) {
|
func marshalAmino(i *big.Int) (string, error) {
|
||||||
bz, err := i.MarshalText()
|
bz, err := i.MarshalText()
|
||||||
|
@ -153,6 +160,16 @@ func (i Int) IsZero() bool {
|
||||||
return i.i.Sign() == 0
|
return i.i.Sign() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsNegative returns true if Int is negative
|
||||||
|
func (i Int) IsNegative() bool {
|
||||||
|
return i.i.Sign() == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPositive returns true if Int is positive
|
||||||
|
func (i Int) IsPositive() bool {
|
||||||
|
return i.i.Sign() == 1
|
||||||
|
}
|
||||||
|
|
||||||
// Sign returns sign of Int
|
// Sign returns sign of Int
|
||||||
func (i Int) Sign() int {
|
func (i Int) Sign() int {
|
||||||
return i.i.Sign()
|
return i.i.Sign()
|
||||||
|
@ -254,11 +271,16 @@ func (i Int) Neg() (res Int) {
|
||||||
return Int{neg(i.i)}
|
return Int{neg(i.i)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the minimum of the ints
|
// return the minimum of the ints
|
||||||
func MinInt(i1, i2 Int) Int {
|
func MinInt(i1, i2 Int) Int {
|
||||||
return Int{min(i1.BigInt(), i2.BigInt())}
|
return Int{min(i1.BigInt(), i2.BigInt())}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return the maximum of the ints
|
||||||
|
func MaxInt(i1, i2 Int) Int {
|
||||||
|
return Int{max(i1.BigInt(), i2.BigInt())}
|
||||||
|
}
|
||||||
|
|
||||||
// Human readable string
|
// Human readable string
|
||||||
func (i Int) String() string {
|
func (i Int) String() string {
|
||||||
return i.i.String()
|
return i.i.String()
|
||||||
|
|
|
@ -42,8 +42,8 @@ type Validator interface {
|
||||||
GetOperator() ValAddress // operator address to receive/return validators coins
|
GetOperator() ValAddress // operator address to receive/return validators coins
|
||||||
GetConsPubKey() crypto.PubKey // validation consensus pubkey
|
GetConsPubKey() crypto.PubKey // validation consensus pubkey
|
||||||
GetConsAddr() ConsAddress // validation consensus address
|
GetConsAddr() ConsAddress // validation consensus address
|
||||||
GetPower() Dec // validation power
|
GetPower() Int // validation power
|
||||||
GetTokens() Dec // validation tokens
|
GetTokens() Int // validation tokens
|
||||||
GetCommission() Dec // validator commission rate
|
GetCommission() Dec // validator commission rate
|
||||||
GetDelegatorShares() Dec // Total out standing delegator shares
|
GetDelegatorShares() Dec // Total out standing delegator shares
|
||||||
GetBondHeight() int64 // height in which the validator became active
|
GetBondHeight() int64 // height in which the validator became active
|
||||||
|
@ -53,7 +53,7 @@ type Validator interface {
|
||||||
func ABCIValidator(v Validator) abci.Validator {
|
func ABCIValidator(v Validator) abci.Validator {
|
||||||
return abci.Validator{
|
return abci.Validator{
|
||||||
Address: v.GetConsPubKey().Address(),
|
Address: v.GetConsPubKey().Address(),
|
||||||
Power: v.GetPower().RoundInt64(),
|
Power: v.GetPower().Int64(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ type ValidatorSet interface {
|
||||||
|
|
||||||
Validator(Context, ValAddress) Validator // get a particular validator by operator address
|
Validator(Context, ValAddress) Validator // get a particular validator by operator address
|
||||||
ValidatorByConsAddr(Context, ConsAddress) Validator // get a particular validator by consensus address
|
ValidatorByConsAddr(Context, ConsAddress) Validator // get a particular validator by consensus address
|
||||||
TotalPower(Context) Dec // total power of the validator set
|
TotalPower(Context) Int // total power of the validator set
|
||||||
|
|
||||||
// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
|
// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
|
||||||
Slash(Context, ConsAddress, int64, int64, Dec)
|
Slash(Context, ConsAddress, int64, int64, Dec)
|
||||||
|
|
|
@ -19,7 +19,7 @@ func TestAllocateTokensBasic(t *testing.T) {
|
||||||
|
|
||||||
//first make a validator
|
//first make a validator
|
||||||
totalPower := int64(10)
|
totalPower := int64(10)
|
||||||
totalPowerDec := sdk.NewDec(totalPower)
|
totalPowerInt := sdk.NewInt(totalPower)
|
||||||
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, totalPower)
|
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, totalPower)
|
||||||
got := stakeHandler(ctx, msgCreateValidator)
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
@ -29,10 +29,10 @@ func TestAllocateTokensBasic(t *testing.T) {
|
||||||
validator, found := sk.GetValidator(ctx, valOpAddr1)
|
validator, found := sk.GetValidator(ctx, valOpAddr1)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
assert.True(sdk.DecEq(t, totalPowerDec, validator.Tokens))
|
assert.True(sdk.IntEq(t, totalPowerInt, validator.Tokens))
|
||||||
assert.True(sdk.DecEq(t, totalPowerDec, validator.DelegatorShares))
|
assert.True(sdk.DecEq(t, sdk.NewDec(totalPower), validator.DelegatorShares))
|
||||||
bondedTokens := sk.TotalPower(ctx)
|
bondedTokens := sk.TotalPower(ctx)
|
||||||
assert.True(sdk.DecEq(t, totalPowerDec, bondedTokens))
|
assert.True(sdk.IntEq(t, totalPowerInt, bondedTokens))
|
||||||
|
|
||||||
// initial fee pool should be empty
|
// initial fee pool should be empty
|
||||||
feePool := keeper.GetFeePool(ctx)
|
feePool := keeper.GetFeePool(ctx)
|
||||||
|
|
|
@ -122,7 +122,7 @@ func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initCoins int64,
|
||||||
{sk.GetParams(ctx).BondDenom, sdk.NewInt(initCoins)},
|
{sk.GetParams(ctx).BondDenom, sdk.NewInt(initCoins)},
|
||||||
})
|
})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
pool.LooseTokens = pool.LooseTokens.Add(sdk.NewDec(initCoins))
|
pool.LooseTokens = pool.LooseTokens.Add(sdk.NewInt(initCoins))
|
||||||
sk.SetPool(ctx, pool)
|
sk.SetPool(ctx, pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ type StakeKeeper interface {
|
||||||
Delegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) sdk.Delegation
|
Delegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) sdk.Delegation
|
||||||
Validator(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Validator
|
Validator(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Validator
|
||||||
ValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) sdk.Validator
|
ValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) sdk.Validator
|
||||||
TotalPower(ctx sdk.Context) sdk.Dec
|
TotalPower(ctx sdk.Context) sdk.Int
|
||||||
GetLastTotalPower(ctx sdk.Context) sdk.Int
|
GetLastTotalPower(ctx sdk.Context) sdk.Int
|
||||||
GetLastValidatorPower(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Int
|
GetLastValidatorPower(ctx sdk.Context, valAddr sdk.ValAddress) sdk.Int
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
|
||||||
keeper.vs.IterateBondedValidatorsByPower(ctx, func(index int64, validator sdk.Validator) (stop bool) {
|
keeper.vs.IterateBondedValidatorsByPower(ctx, func(index int64, validator sdk.Validator) (stop bool) {
|
||||||
currValidators[validator.GetOperator().String()] = validatorGovInfo{
|
currValidators[validator.GetOperator().String()] = validatorGovInfo{
|
||||||
Address: validator.GetOperator(),
|
Address: validator.GetOperator(),
|
||||||
Power: validator.GetPower(),
|
Power: sdk.NewDecFromInt(validator.GetPower()),
|
||||||
DelegatorShares: validator.GetDelegatorShares(),
|
DelegatorShares: validator.GetDelegatorShares(),
|
||||||
Minus: sdk.ZeroDec(),
|
Minus: sdk.ZeroDec(),
|
||||||
Vote: OptionEmpty,
|
Vote: OptionEmpty,
|
||||||
|
@ -94,11 +94,12 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no staked coins, the proposal fails
|
// If there is no staked coins, the proposal fails
|
||||||
if keeper.vs.TotalPower(ctx).Equal(sdk.ZeroDec()) {
|
if keeper.vs.TotalPower(ctx).IsZero() {
|
||||||
return false, tallyResults
|
return false, tallyResults
|
||||||
}
|
}
|
||||||
// If there is not enough quorum of votes, the proposal fails
|
// If there is not enough quorum of votes, the proposal fails
|
||||||
if totalVotingPower.Quo(keeper.vs.TotalPower(ctx)).LT(tallyParams.Quorum) {
|
percentVoting := totalVotingPower.Quo(sdk.NewDecFromInt(keeper.vs.TotalPower(ctx)))
|
||||||
|
if percentVoting.LT(tallyParams.Quorum) {
|
||||||
return false, tallyResults
|
return false, tallyResults
|
||||||
}
|
}
|
||||||
// If no one votes (everyone abstains), proposal fails
|
// If no one votes (everyone abstains), proposal fails
|
||||||
|
|
|
@ -65,7 +65,7 @@ func getInitChainer(mapp *mock.App, keeper Keeper, stakeKeeper stake.Keeper) sdk
|
||||||
mapp.InitChainer(ctx, req)
|
mapp.InitChainer(ctx, req)
|
||||||
|
|
||||||
stakeGenesis := stake.DefaultGenesisState()
|
stakeGenesis := stake.DefaultGenesisState()
|
||||||
stakeGenesis.Pool.LooseTokens = sdk.NewDec(100000)
|
stakeGenesis.Pool.LooseTokens = sdk.NewInt(100000)
|
||||||
|
|
||||||
validators, err := stake.InitGenesis(ctx, stakeKeeper, stakeGenesis)
|
validators, err := stake.InitGenesis(ctx, stakeKeeper, stakeGenesis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -21,6 +21,6 @@ func BeginBlocker(ctx sdk.Context, k Keeper) {
|
||||||
// mint coins, add to collected fees, update supply
|
// mint coins, add to collected fees, update supply
|
||||||
mintedCoin := minter.BlockProvision(params)
|
mintedCoin := minter.BlockProvision(params)
|
||||||
k.fck.AddCollectedFees(ctx, sdk.Coins{mintedCoin})
|
k.fck.AddCollectedFees(ctx, sdk.Coins{mintedCoin})
|
||||||
k.sk.InflateSupply(ctx, sdk.NewDecFromInt(mintedCoin.Amount))
|
k.sk.InflateSupply(ctx, mintedCoin.Amount)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
|
|
||||||
// expected stake keeper
|
// expected stake keeper
|
||||||
type StakeKeeper interface {
|
type StakeKeeper interface {
|
||||||
TotalPower(ctx sdk.Context) sdk.Dec
|
TotalPower(ctx sdk.Context) sdk.Int
|
||||||
BondedRatio(ctx sdk.Context) sdk.Dec
|
BondedRatio(ctx sdk.Context) sdk.Dec
|
||||||
InflateSupply(ctx sdk.Context, newTokens sdk.Dec)
|
InflateSupply(ctx sdk.Context, newTokens sdk.Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
// expected fee collection keeper interface
|
// expected fee collection keeper interface
|
||||||
|
|
|
@ -74,10 +74,10 @@ func (m Minter) NextInflationRate(params Params, bondedRatio sdk.Dec) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the annual provisions based on current total supply and inflation rate
|
// calculate the annual provisions based on current total supply and inflation rate
|
||||||
func (m Minter) NextAnnualProvisions(params Params, totalSupply sdk.Dec) (
|
func (m Minter) NextAnnualProvisions(params Params, totalSupply sdk.Int) (
|
||||||
provisions sdk.Dec) {
|
provisions sdk.Dec) {
|
||||||
|
|
||||||
return m.Inflation.Mul(totalSupply)
|
return m.Inflation.MulInt(totalSupply)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the provisions for a block based on the annual provisions rate
|
// get the provisions for a block based on the annual provisions rate
|
||||||
|
|
|
@ -121,7 +121,7 @@ func BenchmarkNextInflation(b *testing.B) {
|
||||||
func BenchmarkNextAnnualProvisions(b *testing.B) {
|
func BenchmarkNextAnnualProvisions(b *testing.B) {
|
||||||
minter := InitialMinter(sdk.NewDecWithPrec(1, 1))
|
minter := InitialMinter(sdk.NewDecWithPrec(1, 1))
|
||||||
params := DefaultParams()
|
params := DefaultParams()
|
||||||
totalSupply := sdk.NewDec(100000000000000)
|
totalSupply := sdk.NewInt(100000000000000)
|
||||||
|
|
||||||
// run the NextAnnualProvisions function b.N times
|
// run the NextAnnualProvisions function b.N times
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
|
|
|
@ -60,7 +60,7 @@ func getInitChainer(mapp *mock.App, keeper stake.Keeper) sdk.InitChainer {
|
||||||
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||||
mapp.InitChainer(ctx, req)
|
mapp.InitChainer(ctx, req)
|
||||||
stakeGenesis := stake.DefaultGenesisState()
|
stakeGenesis := stake.DefaultGenesisState()
|
||||||
stakeGenesis.Pool.LooseTokens = sdk.NewDec(100000)
|
stakeGenesis.Pool.LooseTokens = sdk.NewInt(100000)
|
||||||
validators, err := stake.InitGenesis(ctx, keeper, stakeGenesis)
|
validators, err := stake.InitGenesis(ctx, keeper, stakeGenesis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -114,7 +114,7 @@ func TestSlashingMsgs(t *testing.T) {
|
||||||
validator := checkValidator(t, mapp, stakeKeeper, addr1, true)
|
validator := checkValidator(t, mapp, stakeKeeper, addr1, true)
|
||||||
require.Equal(t, sdk.ValAddress(addr1), validator.OperatorAddr)
|
require.Equal(t, sdk.ValAddress(addr1), validator.OperatorAddr)
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
require.True(sdk.DecEq(t, sdk.NewDec(10), validator.BondedTokens()))
|
require.True(sdk.IntEq(t, sdk.NewInt(10), validator.BondedTokens()))
|
||||||
unjailMsg := MsgUnjail{ValidatorAddr: sdk.ValAddress(validator.ConsPubKey.Address())}
|
unjailMsg := MsgUnjail{ValidatorAddr: sdk.ValAddress(validator.ConsPubKey.Address())}
|
||||||
|
|
||||||
// no signing info yet
|
// no signing info yet
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestCannotUnjailUnlessJailed(t *testing.T) {
|
||||||
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
|
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
|
||||||
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
||||||
)
|
)
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, addr).GetPower()))
|
||||||
|
|
||||||
// assert non-jailed validator can't be unjailed
|
// assert non-jailed validator can't be unjailed
|
||||||
got = slh(ctx, NewMsgUnjail(addr))
|
got = slh(ctx, NewMsgUnjail(addr))
|
||||||
|
|
|
@ -40,7 +40,7 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||||
t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)),
|
t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)),
|
||||||
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
||||||
)
|
)
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower()))
|
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, operatorAddr).GetPower()))
|
||||||
|
|
||||||
// handle a signature to set signing info
|
// handle a signature to set signing info
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
|
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
|
||||||
|
@ -53,18 +53,18 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||||
// unjail to measure power
|
// unjail to measure power
|
||||||
sk.Unjail(ctx, sdk.ConsAddress(val.Address()))
|
sk.Unjail(ctx, sdk.ConsAddress(val.Address()))
|
||||||
// power should be reduced
|
// power should be reduced
|
||||||
require.Equal(
|
require.True(sdk.IntEq(
|
||||||
t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))),
|
t, amt.Mul(sdk.NewInt(19)).Div(sdk.NewInt(20)),
|
||||||
sk.Validator(ctx, operatorAddr).GetPower(),
|
sk.Validator(ctx, operatorAddr).GetPower(),
|
||||||
)
|
))
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))})
|
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))})
|
||||||
|
|
||||||
// double sign past max age
|
// 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), amtInt)
|
||||||
require.Equal(
|
require.True(sdk.IntEq(
|
||||||
t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))),
|
t, amt.Mul(sdk.NewInt(19)).Div(sdk.NewInt(20)),
|
||||||
sk.Validator(ctx, operatorAddr).GetPower(),
|
sk.Validator(ctx, operatorAddr).GetPower(),
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the amount a validator is slashed for multiple double signs
|
// Test that the amount a validator is slashed for multiple double signs
|
||||||
|
@ -84,7 +84,7 @@ func TestSlashingPeriodCap(t *testing.T) {
|
||||||
t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)),
|
t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)),
|
||||||
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
||||||
)
|
)
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower()))
|
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, operatorAddr).GetPower()))
|
||||||
|
|
||||||
// handle a signature to set signing info
|
// handle a signature to set signing info
|
||||||
keeper.handleValidatorSignature(ctx, valConsAddr, amtInt, true)
|
keeper.handleValidatorSignature(ctx, valConsAddr, amtInt, true)
|
||||||
|
@ -102,8 +102,8 @@ func TestSlashingPeriodCap(t *testing.T) {
|
||||||
// end block
|
// end block
|
||||||
stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
// power should be reduced
|
// power should be reduced
|
||||||
expectedPower := sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20)))
|
expectedPower := amt.Mul(sdk.NewInt(19)).Div(sdk.NewInt(20))
|
||||||
require.Equal(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower())
|
require.True(sdk.IntEq(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower()))
|
||||||
|
|
||||||
// double sign again, same slashing period
|
// double sign again, same slashing period
|
||||||
keeper.handleDoubleSign(ctx, valConsAddr, 1, time.Unix(0, 0), amtInt)
|
keeper.handleDoubleSign(ctx, valConsAddr, 1, time.Unix(0, 0), amtInt)
|
||||||
|
@ -118,8 +118,8 @@ func TestSlashingPeriodCap(t *testing.T) {
|
||||||
// end block
|
// end block
|
||||||
stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
// power should be equal, no more should have been slashed
|
// power should be equal, no more should have been slashed
|
||||||
expectedPower = sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20)))
|
expectedPower = amt.Mul(sdk.NewInt(19)).Div(sdk.NewInt(20))
|
||||||
require.Equal(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower())
|
require.True(sdk.IntEq(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower()))
|
||||||
|
|
||||||
// double sign again, new slashing period
|
// double sign again, new slashing period
|
||||||
keeper.handleDoubleSign(ctx, valConsAddr, 3, time.Unix(0, 0), amtInt)
|
keeper.handleDoubleSign(ctx, valConsAddr, 3, time.Unix(0, 0), amtInt)
|
||||||
|
@ -130,8 +130,8 @@ func TestSlashingPeriodCap(t *testing.T) {
|
||||||
// end block
|
// end block
|
||||||
stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
// power should be reduced
|
// power should be reduced
|
||||||
expectedPower = sdk.NewDecFromInt(amt).Mul(sdk.NewDec(18).Quo(sdk.NewDec(20)))
|
expectedPower = amt.Mul(sdk.NewInt(18)).Div(sdk.NewInt(20))
|
||||||
require.Equal(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower())
|
require.True(sdk.IntEq(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test a validator through uptime, downtime, revocation,
|
// Test a validator through uptime, downtime, revocation,
|
||||||
|
@ -140,8 +140,8 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
|
|
||||||
// initial setup
|
// initial setup
|
||||||
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
|
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
|
||||||
amtInt := int64(100)
|
amtInt64 := int64(100)
|
||||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt64)
|
||||||
sh := stake.NewHandler(sk)
|
sh := stake.NewHandler(sk)
|
||||||
slh := NewHandler(keeper)
|
slh := NewHandler(keeper)
|
||||||
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
||||||
|
@ -152,7 +152,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
|
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
|
||||||
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
||||||
)
|
)
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, addr).GetPower()))
|
||||||
|
|
||||||
// will exist since the validator has been bonded
|
// will exist since the validator has been bonded
|
||||||
info, found := keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
info, found := keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
|
@ -166,7 +166,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
// 1000 first blocks OK
|
// 1000 first blocks OK
|
||||||
for ; height < keeper.SignedBlocksWindow(ctx); height++ {
|
for ; height < keeper.SignedBlocksWindow(ctx); height++ {
|
||||||
ctx = ctx.WithBlockHeight(height)
|
ctx = ctx.WithBlockHeight(height)
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
|
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, true)
|
||||||
}
|
}
|
||||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
@ -176,7 +176,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
// 500 blocks missed
|
// 500 blocks missed
|
||||||
for ; height < keeper.SignedBlocksWindow(ctx)+(keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)); height++ {
|
for ; height < keeper.SignedBlocksWindow(ctx)+(keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)); height++ {
|
||||||
ctx = ctx.WithBlockHeight(height)
|
ctx = ctx.WithBlockHeight(height)
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
|
||||||
}
|
}
|
||||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
@ -187,11 +187,11 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
validator, _ := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
validator, _ := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||||
require.Equal(t, sdk.Bonded, validator.GetStatus())
|
require.Equal(t, sdk.Bonded, validator.GetStatus())
|
||||||
pool := sk.GetPool(ctx)
|
pool := sk.GetPool(ctx)
|
||||||
require.Equal(t, amtInt, pool.BondedTokens.RoundInt64())
|
require.True(sdk.IntEq(t, amt, pool.BondedTokens))
|
||||||
|
|
||||||
// 501st block missed
|
// 501st block missed
|
||||||
ctx = ctx.WithBlockHeight(height)
|
ctx = ctx.WithBlockHeight(height)
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
|
||||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(0), info.StartHeight)
|
require.Equal(t, int64(0), info.StartHeight)
|
||||||
|
@ -205,15 +205,15 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||||
require.Equal(t, sdk.Unbonding, validator.GetStatus())
|
require.Equal(t, sdk.Unbonding, validator.GetStatus())
|
||||||
|
|
||||||
slashAmt := sdk.NewDec(amtInt).Mul(keeper.SlashFractionDowntime(ctx)).RoundInt64()
|
slashAmt := sdk.NewDec(amtInt64).Mul(keeper.SlashFractionDowntime(ctx)).RoundInt64()
|
||||||
|
|
||||||
// validator should have been slashed
|
// validator should have been slashed
|
||||||
require.Equal(t, amtInt-slashAmt, validator.GetTokens().RoundInt64())
|
require.Equal(t, amtInt64-slashAmt, validator.GetTokens().Int64())
|
||||||
|
|
||||||
// 502nd block *also* missed (since the LastCommit would have still included the just-unbonded validator)
|
// 502nd block *also* missed (since the LastCommit would have still included the just-unbonded validator)
|
||||||
height++
|
height++
|
||||||
ctx = ctx.WithBlockHeight(height)
|
ctx = ctx.WithBlockHeight(height)
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
|
||||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(0), info.StartHeight)
|
require.Equal(t, int64(0), info.StartHeight)
|
||||||
|
@ -224,15 +224,15 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
|
|
||||||
// validator should not have been slashed any more, since it was already jailed
|
// validator should not have been slashed any more, since it was already jailed
|
||||||
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||||
require.Equal(t, amtInt-slashAmt, validator.GetTokens().RoundInt64())
|
require.Equal(t, amtInt64-slashAmt, validator.GetTokens().Int64())
|
||||||
|
|
||||||
// 502nd block *double signed* (oh no!)
|
// 502nd block *double signed* (oh no!)
|
||||||
keeper.handleDoubleSign(ctx, val.Address(), height, ctx.BlockHeader().Time, amtInt)
|
keeper.handleDoubleSign(ctx, val.Address(), height, ctx.BlockHeader().Time, amtInt64)
|
||||||
|
|
||||||
// validator should have been slashed
|
// validator should have been slashed
|
||||||
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||||
secondSlashAmt := sdk.NewDec(amtInt).Mul(keeper.SlashFractionDoubleSign(ctx)).RoundInt64()
|
secondSlashAmt := sdk.NewDec(amtInt64).Mul(keeper.SlashFractionDoubleSign(ctx)).RoundInt64()
|
||||||
require.Equal(t, amtInt-slashAmt-secondSlashAmt, validator.GetTokens().RoundInt64())
|
require.Equal(t, amtInt64-slashAmt-secondSlashAmt, validator.GetTokens().Int64())
|
||||||
|
|
||||||
// unrevocation should fail prior to jail expiration
|
// unrevocation should fail prior to jail expiration
|
||||||
got = slh(ctx, NewMsgUnjail(addr))
|
got = slh(ctx, NewMsgUnjail(addr))
|
||||||
|
@ -252,7 +252,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
|
|
||||||
// validator should have been slashed
|
// validator should have been slashed
|
||||||
pool = sk.GetPool(ctx)
|
pool = sk.GetPool(ctx)
|
||||||
require.Equal(t, amtInt-slashAmt-secondSlashAmt, pool.BondedTokens.RoundInt64())
|
require.Equal(t, amtInt64-slashAmt-secondSlashAmt, pool.BondedTokens.Int64())
|
||||||
|
|
||||||
// validator start height should not have been changed
|
// validator start height should not have been changed
|
||||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
|
@ -264,7 +264,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
// validator should not be immediately jailed again
|
// validator should not be immediately jailed again
|
||||||
height++
|
height++
|
||||||
ctx = ctx.WithBlockHeight(height)
|
ctx = ctx.WithBlockHeight(height)
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
|
||||||
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||||
require.Equal(t, sdk.Bonded, validator.GetStatus())
|
require.Equal(t, sdk.Bonded, validator.GetStatus())
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
nextHeight := height + keeper.MinSignedPerWindow(ctx) + 1
|
nextHeight := height + keeper.MinSignedPerWindow(ctx) + 1
|
||||||
for ; height < nextHeight; height++ {
|
for ; height < nextHeight; height++ {
|
||||||
ctx = ctx.WithBlockHeight(height)
|
ctx = ctx.WithBlockHeight(height)
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// end block
|
// end block
|
||||||
|
@ -282,7 +282,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
nextHeight = height + keeper.MinSignedPerWindow(ctx) + 1
|
nextHeight = height + keeper.MinSignedPerWindow(ctx) + 1
|
||||||
for ; height <= nextHeight; height++ {
|
for ; height <= nextHeight; height++ {
|
||||||
ctx = ctx.WithBlockHeight(height)
|
ctx = ctx.WithBlockHeight(height)
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
|
keeper.handleValidatorSignature(ctx, val.Address(), amtInt64, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// end block
|
// end block
|
||||||
|
@ -313,7 +313,7 @@ func TestHandleNewValidator(t *testing.T) {
|
||||||
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
|
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.SubRaw(amt))},
|
||||||
)
|
)
|
||||||
require.Equal(t, sdk.NewDec(amt), sk.Validator(ctx, addr).GetPower())
|
require.Equal(t, amt, sk.Validator(ctx, addr).GetPower().Int64())
|
||||||
|
|
||||||
// Now a validator, for two blocks
|
// Now a validator, for two blocks
|
||||||
keeper.handleValidatorSignature(ctx, val.Address(), 100, true)
|
keeper.handleValidatorSignature(ctx, val.Address(), 100, true)
|
||||||
|
@ -331,7 +331,7 @@ func TestHandleNewValidator(t *testing.T) {
|
||||||
validator, _ := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
validator, _ := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||||
require.Equal(t, sdk.Bonded, validator.GetStatus())
|
require.Equal(t, sdk.Bonded, validator.GetStatus())
|
||||||
pool := sk.GetPool(ctx)
|
pool := sk.GetPool(ctx)
|
||||||
require.Equal(t, int64(100), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(100), pool.BondedTokens.Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test a jailed validator being "down" twice
|
// Test a jailed validator being "down" twice
|
||||||
|
@ -368,7 +368,7 @@ func TestHandleAlreadyJailed(t *testing.T) {
|
||||||
require.Equal(t, sdk.Unbonding, validator.GetStatus())
|
require.Equal(t, sdk.Unbonding, validator.GetStatus())
|
||||||
|
|
||||||
// validator should have been slashed
|
// validator should have been slashed
|
||||||
require.Equal(t, amtInt-1, validator.GetTokens().RoundInt64())
|
require.Equal(t, amtInt-1, validator.GetTokens().Int64())
|
||||||
|
|
||||||
// another block missed
|
// another block missed
|
||||||
ctx = ctx.WithBlockHeight(height)
|
ctx = ctx.WithBlockHeight(height)
|
||||||
|
@ -376,7 +376,7 @@ func TestHandleAlreadyJailed(t *testing.T) {
|
||||||
|
|
||||||
// validator should not have been slashed twice
|
// validator should not have been slashed twice
|
||||||
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
||||||
require.Equal(t, amtInt-1, validator.GetTokens().RoundInt64())
|
require.Equal(t, amtInt-1, validator.GetTokens().Int64())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ func createTestInput(t *testing.T, defaults Params) (sdk.Context, bank.Keeper, s
|
||||||
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, paramsKeeper.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
|
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, paramsKeeper.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
|
||||||
genesis := stake.DefaultGenesisState()
|
genesis := stake.DefaultGenesisState()
|
||||||
|
|
||||||
genesis.Pool.LooseTokens = sdk.NewDec(initCoins.MulRaw(int64(len(addrs))).Int64())
|
genesis.Pool.LooseTokens = sdk.NewInt(initCoins.MulRaw(int64(len(addrs))).Int64())
|
||||||
|
|
||||||
_, err = stake.InitGenesis(ctx, sk, genesis)
|
_, err = stake.InitGenesis(ctx, sk, genesis)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
|
@ -24,7 +24,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||||
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
|
t, ck.GetCoins(ctx, sdk.AccAddress(addr)),
|
||||||
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
sdk.Coins{sdk.NewCoin(sk.GetParams(ctx).BondDenom, initCoins.Sub(amt))},
|
||||||
)
|
)
|
||||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
require.True(sdk.IntEq(t, amt, sk.Validator(ctx, addr).GetPower()))
|
||||||
|
|
||||||
val := abci.Validator{
|
val := abci.Validator{
|
||||||
Address: pk.Address(),
|
Address: pk.Address(),
|
||||||
|
|
|
@ -52,7 +52,7 @@ func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer {
|
||||||
mapp.InitChainer(ctx, req)
|
mapp.InitChainer(ctx, req)
|
||||||
|
|
||||||
stakeGenesis := DefaultGenesisState()
|
stakeGenesis := DefaultGenesisState()
|
||||||
stakeGenesis.Pool.LooseTokens = sdk.NewDec(100000)
|
stakeGenesis.Pool.LooseTokens = sdk.NewInt(100000)
|
||||||
|
|
||||||
validators, err := InitGenesis(ctx, keeper, stakeGenesis)
|
validators, err := InitGenesis(ctx, keeper, stakeGenesis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -127,7 +127,7 @@ func TestStakeMsgs(t *testing.T) {
|
||||||
validator := checkValidator(t, mApp, keeper, sdk.ValAddress(addr1), true)
|
validator := checkValidator(t, mApp, keeper, sdk.ValAddress(addr1), true)
|
||||||
require.Equal(t, sdk.ValAddress(addr1), validator.OperatorAddr)
|
require.Equal(t, sdk.ValAddress(addr1), validator.OperatorAddr)
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
require.True(sdk.DecEq(t, sdk.NewDec(10), validator.BondedTokens()))
|
require.True(sdk.IntEq(t, sdk.NewInt(10), validator.BondedTokens()))
|
||||||
|
|
||||||
// addr1 create validator on behalf of addr2
|
// addr1 create validator on behalf of addr2
|
||||||
createValidatorMsgOnBehalfOf := NewMsgCreateValidatorOnBehalfOf(
|
createValidatorMsgOnBehalfOf := NewMsgCreateValidatorOnBehalfOf(
|
||||||
|
@ -141,7 +141,7 @@ func TestStakeMsgs(t *testing.T) {
|
||||||
validator = checkValidator(t, mApp, keeper, sdk.ValAddress(addr2), true)
|
validator = checkValidator(t, mApp, keeper, sdk.ValAddress(addr2), true)
|
||||||
require.Equal(t, sdk.ValAddress(addr2), validator.OperatorAddr)
|
require.Equal(t, sdk.ValAddress(addr2), validator.OperatorAddr)
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
require.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens))
|
require.True(sdk.IntEq(t, sdk.NewInt(10), validator.Tokens))
|
||||||
|
|
||||||
// check the bond that should have been created as well
|
// check the bond that should have been created as well
|
||||||
checkDelegation(t, mApp, keeper, addr1, sdk.ValAddress(addr1), true, sdk.NewDec(10))
|
checkDelegation(t, mApp, keeper, addr1, sdk.ValAddress(addr1), true, sdk.NewDec(10))
|
||||||
|
|
|
@ -124,7 +124,7 @@ func WriteValidators(ctx sdk.Context, keeper Keeper) (vals []tmtypes.GenesisVali
|
||||||
keeper.IterateLastValidators(ctx, func(_ int64, validator sdk.Validator) (stop bool) {
|
keeper.IterateLastValidators(ctx, func(_ int64, validator sdk.Validator) (stop bool) {
|
||||||
vals = append(vals, tmtypes.GenesisValidator{
|
vals = append(vals, tmtypes.GenesisValidator{
|
||||||
PubKey: validator.GetConsPubKey(),
|
PubKey: validator.GetConsPubKey(),
|
||||||
Power: validator.GetPower().RoundInt64(),
|
Power: validator.GetPower().Int64(),
|
||||||
Name: validator.GetMoniker(),
|
Name: validator.GetMoniker(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ func TestInitGenesis(t *testing.T) {
|
||||||
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
|
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
|
||||||
|
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.BondedTokens = sdk.NewDec(2)
|
pool.BondedTokens = sdk.NewInt(2)
|
||||||
|
|
||||||
params := keeper.GetParams(ctx)
|
params := keeper.GetParams(ctx)
|
||||||
validators := make([]Validator, 2)
|
validators := make([]Validator, 2)
|
||||||
|
@ -31,13 +31,13 @@ func TestInitGenesis(t *testing.T) {
|
||||||
validators[0].ConsPubKey = keep.PKs[0]
|
validators[0].ConsPubKey = keep.PKs[0]
|
||||||
validators[0].Description = Description{Moniker: "hoop"}
|
validators[0].Description = Description{Moniker: "hoop"}
|
||||||
validators[0].Status = sdk.Bonded
|
validators[0].Status = sdk.Bonded
|
||||||
validators[0].Tokens = sdk.OneDec()
|
validators[0].Tokens = sdk.OneInt()
|
||||||
validators[0].DelegatorShares = sdk.OneDec()
|
validators[0].DelegatorShares = sdk.OneDec()
|
||||||
validators[1].OperatorAddr = sdk.ValAddress(keep.Addrs[1])
|
validators[1].OperatorAddr = sdk.ValAddress(keep.Addrs[1])
|
||||||
validators[1].ConsPubKey = keep.PKs[1]
|
validators[1].ConsPubKey = keep.PKs[1]
|
||||||
validators[1].Description = Description{Moniker: "bloop"}
|
validators[1].Description = Description{Moniker: "bloop"}
|
||||||
validators[1].Status = sdk.Bonded
|
validators[1].Status = sdk.Bonded
|
||||||
validators[1].Tokens = sdk.OneDec()
|
validators[1].Tokens = sdk.OneInt()
|
||||||
validators[1].DelegatorShares = sdk.OneDec()
|
validators[1].DelegatorShares = sdk.OneDec()
|
||||||
|
|
||||||
genesisState := types.NewGenesisState(pool, params, validators, delegations)
|
genesisState := types.NewGenesisState(pool, params, validators, delegations)
|
||||||
|
@ -75,7 +75,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
|
||||||
|
|
||||||
// Assigning 2 to the first 100 vals, 1 to the rest
|
// Assigning 2 to the first 100 vals, 1 to the rest
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.BondedTokens = sdk.NewDec(int64(200 + (size - 100)))
|
pool.BondedTokens = sdk.NewInt(int64(200 + (size - 100)))
|
||||||
|
|
||||||
params := keeper.GetParams(ctx)
|
params := keeper.GetParams(ctx)
|
||||||
delegations := []Delegation{}
|
delegations := []Delegation{}
|
||||||
|
@ -86,10 +86,10 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) {
|
||||||
|
|
||||||
validators[i].Status = sdk.Bonded
|
validators[i].Status = sdk.Bonded
|
||||||
if i < 100 {
|
if i < 100 {
|
||||||
validators[i].Tokens = sdk.NewDec(2)
|
validators[i].Tokens = sdk.NewInt(2)
|
||||||
validators[i].DelegatorShares = sdk.NewDec(2)
|
validators[i].DelegatorShares = sdk.NewDec(2)
|
||||||
} else {
|
} else {
|
||||||
validators[i].Tokens = sdk.OneDec()
|
validators[i].Tokens = sdk.OneInt()
|
||||||
validators[i].DelegatorShares = sdk.OneDec()
|
validators[i].DelegatorShares = sdk.OneDec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ func TestValidateGenesis(t *testing.T) {
|
||||||
genValidators1 := make([]types.Validator, 1, 5)
|
genValidators1 := make([]types.Validator, 1, 5)
|
||||||
pk := ed25519.GenPrivKey().PubKey()
|
pk := ed25519.GenPrivKey().PubKey()
|
||||||
genValidators1[0] = types.NewValidator(sdk.ValAddress(pk.Address()), pk, types.NewDescription("", "", "", ""))
|
genValidators1[0] = types.NewValidator(sdk.ValAddress(pk.Address()), pk, types.NewDescription("", "", "", ""))
|
||||||
genValidators1[0].Tokens = sdk.OneDec()
|
genValidators1[0].Tokens = sdk.OneInt()
|
||||||
genValidators1[0].DelegatorShares = sdk.OneDec()
|
genValidators1[0].DelegatorShares = sdk.OneDec()
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
|
@ -74,8 +74,8 @@ func TestValidatorByPowerIndex(t *testing.T) {
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
validator, found = keeper.GetValidator(ctx, validatorAddr)
|
validator, found = keeper.GetValidator(ctx, validatorAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, sdk.Unbonding, validator.Status) // ensure is unbonding
|
require.Equal(t, sdk.Unbonding, validator.Status) // ensure is unbonding
|
||||||
require.Equal(t, int64(500000), validator.Tokens.RoundInt64()) // ensure tokens slashed
|
require.Equal(t, int64(500000), validator.Tokens.Int64()) // ensure tokens slashed
|
||||||
keeper.Unjail(ctx, consAddr0)
|
keeper.Unjail(ctx, consAddr0)
|
||||||
|
|
||||||
// the old power record should have been deleted as the power changed
|
// the old power record should have been deleted as the power changed
|
||||||
|
@ -125,7 +125,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) {
|
||||||
assert.Equal(t, sdk.Bonded, validator.Status)
|
assert.Equal(t, sdk.Bonded, validator.Status)
|
||||||
assert.Equal(t, addr1, validator.OperatorAddr)
|
assert.Equal(t, addr1, validator.OperatorAddr)
|
||||||
assert.Equal(t, pk1, validator.ConsPubKey)
|
assert.Equal(t, pk1, validator.ConsPubKey)
|
||||||
assert.Equal(t, sdk.NewDec(10), validator.BondedTokens())
|
assert.Equal(t, int64(10), validator.BondedTokens().Int64())
|
||||||
assert.Equal(t, sdk.NewDec(10), validator.DelegatorShares)
|
assert.Equal(t, sdk.NewDec(10), validator.DelegatorShares)
|
||||||
assert.Equal(t, Description{}, validator.Description)
|
assert.Equal(t, Description{}, validator.Description)
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) {
|
||||||
assert.Equal(t, sdk.Bonded, validator.Status)
|
assert.Equal(t, sdk.Bonded, validator.Status)
|
||||||
assert.Equal(t, addr2, validator.OperatorAddr)
|
assert.Equal(t, addr2, validator.OperatorAddr)
|
||||||
assert.Equal(t, pk2, validator.ConsPubKey)
|
assert.Equal(t, pk2, validator.ConsPubKey)
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(10), validator.Tokens))
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
||||||
assert.Equal(t, Description{}, validator.Description)
|
assert.Equal(t, Description{}, validator.Description)
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ func TestDuplicatesMsgCreateValidatorOnBehalfOf(t *testing.T) {
|
||||||
assert.Equal(t, sdk.Bonded, validator.Status)
|
assert.Equal(t, sdk.Bonded, validator.Status)
|
||||||
assert.Equal(t, validatorAddr, validator.OperatorAddr)
|
assert.Equal(t, validatorAddr, validator.OperatorAddr)
|
||||||
assert.Equal(t, pk, validator.ConsPubKey)
|
assert.Equal(t, pk, validator.ConsPubKey)
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(10), validator.Tokens))
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
||||||
assert.Equal(t, Description{}, validator.Description)
|
assert.Equal(t, Description{}, validator.Description)
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt64())
|
require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt64())
|
||||||
require.Equal(t, bondAmount, validator.BondedTokens().RoundInt64())
|
require.Equal(t, bondAmount, validator.BondedTokens().Int64())
|
||||||
|
|
||||||
// delegate tokens to the validator
|
// delegate tokens to the validator
|
||||||
msgDelegate := NewTestMsgDelegate(delAddr, valAddr, bondAmount)
|
msgDelegate := NewTestMsgDelegate(delAddr, valAddr, bondAmount)
|
||||||
|
@ -243,7 +243,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
validator, found = keeper.GetValidator(ctx, valAddr)
|
validator, found = keeper.GetValidator(ctx, valAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, bondAmount*2, validator.DelegatorShares.RoundInt64())
|
require.Equal(t, bondAmount*2, validator.DelegatorShares.RoundInt64())
|
||||||
require.Equal(t, bondAmount*2, validator.BondedTokens().RoundInt64())
|
require.Equal(t, bondAmount*2, validator.BondedTokens().Int64())
|
||||||
|
|
||||||
// unbond validator total self-delegations (which should jail the validator)
|
// unbond validator total self-delegations (which should jail the validator)
|
||||||
unbondShares := sdk.NewDec(10)
|
unbondShares := sdk.NewDec(10)
|
||||||
|
@ -261,7 +261,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
validator, found = keeper.GetValidator(ctx, valAddr)
|
validator, found = keeper.GetValidator(ctx, valAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.True(t, validator.Jailed)
|
require.True(t, validator.Jailed)
|
||||||
require.Equal(t, sdk.NewDec(10), validator.Tokens)
|
require.Equal(t, int64(10), validator.Tokens.Int64())
|
||||||
|
|
||||||
// verify delegation still exists
|
// verify delegation still exists
|
||||||
bond, found := keeper.GetDelegation(ctx, delAddr, valAddr)
|
bond, found := keeper.GetDelegation(ctx, delAddr, valAddr)
|
||||||
|
@ -283,7 +283,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
validator, found = keeper.GetValidator(ctx, valAddr)
|
validator, found = keeper.GetValidator(ctx, valAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, bondAmount*2, validator.DelegatorShares.RoundInt64())
|
require.Equal(t, bondAmount*2, validator.DelegatorShares.RoundInt64())
|
||||||
require.Equal(t, bondAmount*2, validator.Tokens.RoundInt64())
|
require.Equal(t, bondAmount*2, validator.Tokens.Int64())
|
||||||
|
|
||||||
// unjail the validator now that is has non-zero self-delegated shares
|
// unjail the validator now that is has non-zero self-delegated shares
|
||||||
keeper.Unjail(ctx, valConsAddr)
|
keeper.Unjail(ctx, valConsAddr)
|
||||||
|
@ -297,7 +297,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
validator, found = keeper.GetValidator(ctx, valAddr)
|
validator, found = keeper.GetValidator(ctx, valAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, bondAmount*3, validator.DelegatorShares.RoundInt64())
|
require.Equal(t, bondAmount*3, validator.DelegatorShares.RoundInt64())
|
||||||
require.Equal(t, bondAmount*3, validator.Tokens.RoundInt64())
|
require.Equal(t, bondAmount*3, validator.Tokens.Int64())
|
||||||
|
|
||||||
// verify new delegation
|
// verify new delegation
|
||||||
bond, found = keeper.GetDelegation(ctx, delAddr, valAddr)
|
bond, found = keeper.GetDelegation(ctx, delAddr, valAddr)
|
||||||
|
@ -326,7 +326,7 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt64())
|
require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt64())
|
||||||
require.Equal(t, bondAmount, validator.BondedTokens().RoundInt64(), "validator: %v", validator)
|
require.Equal(t, bondAmount, validator.BondedTokens().Int64(), "validator: %v", validator)
|
||||||
|
|
||||||
_, found = keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
_, found = keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
|
||||||
require.False(t, found)
|
require.False(t, found)
|
||||||
|
@ -338,7 +338,7 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
exRate := validator.DelegatorShareExRate()
|
exRate := validator.DelegatorShareExRate()
|
||||||
require.True(t, exRate.Equal(sdk.OneDec()), "expected exRate 1 got %v", exRate)
|
require.True(t, exRate.Equal(sdk.OneDec()), "expected exRate 1 got %v", exRate)
|
||||||
require.Equal(t, bondAmount, pool.BondedTokens.RoundInt64())
|
require.Equal(t, bondAmount, pool.BondedTokens.Int64())
|
||||||
|
|
||||||
// just send the same msgbond multiple times
|
// just send the same msgbond multiple times
|
||||||
msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, bondAmount)
|
msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, bondAmount)
|
||||||
|
@ -408,7 +408,7 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
||||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, initBond*2, validator.DelegatorShares.RoundInt64())
|
require.Equal(t, initBond*2, validator.DelegatorShares.RoundInt64())
|
||||||
require.Equal(t, initBond*2, validator.BondedTokens().RoundInt64())
|
require.Equal(t, initBond*2, validator.BondedTokens().Int64())
|
||||||
|
|
||||||
// just send the same msgUnbond multiple times
|
// just send the same msgUnbond multiple times
|
||||||
// TODO use decimals here
|
// TODO use decimals here
|
||||||
|
@ -1008,7 +1008,7 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) {
|
||||||
// validator power should have been reduced by half
|
// validator power should have been reduced by half
|
||||||
validator, found := keeper.GetValidator(ctx, valA)
|
validator, found := keeper.GetValidator(ctx, valA)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, sdk.NewDec(5), validator.GetPower())
|
require.Equal(t, int64(5), validator.GetPower().Int64())
|
||||||
|
|
||||||
// slash the validator for an infraction committed after the unbonding and redelegation begin
|
// slash the validator for an infraction committed after the unbonding and redelegation begin
|
||||||
ctx = ctx.WithBlockHeight(3)
|
ctx = ctx.WithBlockHeight(3)
|
||||||
|
|
|
@ -422,28 +422,25 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Co
|
||||||
|
|
||||||
// unbond the the delegation return
|
// unbond the the delegation return
|
||||||
func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress,
|
func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress,
|
||||||
shares sdk.Dec) (amount sdk.Dec, err sdk.Error) {
|
shares sdk.Dec) (amount sdk.Int, err sdk.Error) {
|
||||||
|
|
||||||
// check if delegation has any shares in it unbond
|
// check if delegation has any shares in it unbond
|
||||||
delegation, found := k.GetDelegation(ctx, delAddr, valAddr)
|
delegation, found := k.GetDelegation(ctx, delAddr, valAddr)
|
||||||
if !found {
|
if !found {
|
||||||
err = types.ErrNoDelegatorForAddress(k.Codespace())
|
return amount, types.ErrNoDelegatorForAddress(k.Codespace())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
k.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
k.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
||||||
|
|
||||||
// retrieve the amount to remove
|
// retrieve the amount to remove
|
||||||
if delegation.Shares.LT(shares) {
|
if delegation.Shares.LT(shares) {
|
||||||
err = types.ErrNotEnoughDelegationShares(k.Codespace(), delegation.Shares.String())
|
return amount, types.ErrNotEnoughDelegationShares(k.Codespace(), delegation.Shares.String())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get validator
|
// get validator
|
||||||
validator, found := k.GetValidator(ctx, valAddr)
|
validator, found := k.GetValidator(ctx, valAddr)
|
||||||
if !found {
|
if !found {
|
||||||
err = types.ErrNoValidatorFound(k.Codespace())
|
return amount, types.ErrNoValidatorFound(k.Codespace())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// subtract shares from delegator
|
// subtract shares from delegator
|
||||||
|
@ -522,15 +519,7 @@ func (k Keeper) BeginUnbonding(ctx sdk.Context,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.UnbondingDelegation{}, err
|
return types.UnbondingDelegation{}, err
|
||||||
}
|
}
|
||||||
|
balance := sdk.NewCoin(k.BondDenom(ctx), returnAmount)
|
||||||
rounded := returnAmount.TruncateInt()
|
|
||||||
balance := sdk.NewCoin(k.BondDenom(ctx), rounded)
|
|
||||||
change := returnAmount.Sub(sdk.NewDecFromInt(rounded))
|
|
||||||
|
|
||||||
// for now, change is just burned
|
|
||||||
pool := k.GetPool(ctx)
|
|
||||||
pool.LooseTokens = pool.LooseTokens.Sub(change)
|
|
||||||
k.SetPool(ctx, pool)
|
|
||||||
|
|
||||||
// no need to create the ubd object just complete now
|
// no need to create the ubd object just complete now
|
||||||
if completeNow {
|
if completeNow {
|
||||||
|
@ -597,17 +586,10 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||||
return types.Redelegation{}, err
|
return types.Redelegation{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rounded := returnAmount.TruncateInt()
|
if returnAmount.IsZero() {
|
||||||
if rounded.IsZero() { //TODO design consideration
|
|
||||||
return types.Redelegation{}, types.ErrVerySmallRedelegation(k.Codespace())
|
return types.Redelegation{}, types.ErrVerySmallRedelegation(k.Codespace())
|
||||||
}
|
}
|
||||||
returnCoin := sdk.NewCoin(k.BondDenom(ctx), rounded)
|
returnCoin := sdk.NewCoin(k.BondDenom(ctx), returnAmount)
|
||||||
change := returnAmount.Sub(sdk.NewDecFromInt(rounded))
|
|
||||||
|
|
||||||
// for now, change is just burned
|
|
||||||
pool := k.GetPool(ctx)
|
|
||||||
pool.LooseTokens = pool.LooseTokens.Sub(change)
|
|
||||||
k.SetPool(ctx, pool)
|
|
||||||
|
|
||||||
dstValidator, found := k.GetValidator(ctx, valDstAddr)
|
dstValidator, found := k.GetValidator(ctx, valDstAddr)
|
||||||
if !found {
|
if !found {
|
||||||
|
|
|
@ -181,7 +181,7 @@ func TestUnbondingDelegation(t *testing.T) {
|
||||||
func TestUnbondDelegation(t *testing.T) {
|
func TestUnbondDelegation(t *testing.T) {
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(10)
|
pool.LooseTokens = sdk.NewInt(10)
|
||||||
|
|
||||||
//create a validator and a delegator to that validator
|
//create a validator and a delegator to that validator
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
@ -191,8 +191,8 @@ func TestUnbondDelegation(t *testing.T) {
|
||||||
validator = TestingUpdateValidator(keeper, ctx, validator, true)
|
validator = TestingUpdateValidator(keeper, ctx, validator, true)
|
||||||
|
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
require.Equal(t, int64(10), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(10), pool.BondedTokens.Int64())
|
||||||
require.Equal(t, int64(10), validator.BondedTokens().RoundInt64())
|
require.Equal(t, int64(10), validator.BondedTokens().Int64())
|
||||||
|
|
||||||
delegation := types.Delegation{
|
delegation := types.Delegation{
|
||||||
DelegatorAddr: addrDels[0],
|
DelegatorAddr: addrDels[0],
|
||||||
|
@ -203,7 +203,7 @@ func TestUnbondDelegation(t *testing.T) {
|
||||||
|
|
||||||
amount, err := keeper.unbond(ctx, addrDels[0], addrVals[0], sdk.NewDec(6))
|
amount, err := keeper.unbond(ctx, addrDels[0], addrVals[0], sdk.NewDec(6))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(6), amount.RoundInt64()) // shares to be added to an unbonding delegation / redelegation
|
require.Equal(t, int64(6), amount.Int64()) // shares to be added to an unbonding delegation / redelegation
|
||||||
|
|
||||||
delegation, found := keeper.GetDelegation(ctx, addrDels[0], addrVals[0])
|
delegation, found := keeper.GetDelegation(ctx, addrDels[0], addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
@ -212,9 +212,9 @@ func TestUnbondDelegation(t *testing.T) {
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
|
|
||||||
require.Equal(t, int64(4), delegation.Shares.RoundInt64())
|
require.Equal(t, int64(4), delegation.Shares.RoundInt64())
|
||||||
require.Equal(t, int64(4), validator.BondedTokens().RoundInt64())
|
require.Equal(t, int64(4), validator.BondedTokens().Int64())
|
||||||
require.Equal(t, int64(6), pool.LooseTokens.RoundInt64(), "%v", pool)
|
require.Equal(t, int64(6), pool.LooseTokens.Int64(), "%v", pool)
|
||||||
require.Equal(t, int64(4), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(4), pool.BondedTokens.Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// test removing all self delegation from a validator which should
|
// test removing all self delegation from a validator which should
|
||||||
|
@ -223,7 +223,7 @@ func TestUndelegateSelfDelegation(t *testing.T) {
|
||||||
|
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(20)
|
pool.LooseTokens = sdk.NewInt(20)
|
||||||
|
|
||||||
//create a validator with a self-delegation
|
//create a validator with a self-delegation
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
@ -263,14 +263,14 @@ func TestUndelegateSelfDelegation(t *testing.T) {
|
||||||
|
|
||||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(10), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(10), validator.Tokens.Int64())
|
||||||
require.Equal(t, sdk.Unbonding, validator.Status)
|
require.Equal(t, sdk.Unbonding, validator.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUndelegateFromUnbondingValidator(t *testing.T) {
|
func TestUndelegateFromUnbondingValidator(t *testing.T) {
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(20)
|
pool.LooseTokens = sdk.NewInt(20)
|
||||||
|
|
||||||
//create a validator with a self-delegation
|
//create a validator with a self-delegation
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
@ -346,7 +346,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) {
|
||||||
func TestUndelegateFromUnbondedValidator(t *testing.T) {
|
func TestUndelegateFromUnbondedValidator(t *testing.T) {
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(20)
|
pool.LooseTokens = sdk.NewInt(20)
|
||||||
|
|
||||||
//create a validator with a self-delegation
|
//create a validator with a self-delegation
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
@ -425,7 +425,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) {
|
||||||
func TestUnbondingAllDelegationFromValidator(t *testing.T) {
|
func TestUnbondingAllDelegationFromValidator(t *testing.T) {
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(20)
|
pool.LooseTokens = sdk.NewInt(20)
|
||||||
|
|
||||||
//create a validator with a self-delegation
|
//create a validator with a self-delegation
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
@ -585,10 +585,9 @@ func TestRedelegation(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRedelegateToSameValidator(t *testing.T) {
|
func TestRedelegateToSameValidator(t *testing.T) {
|
||||||
|
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(30)
|
pool.LooseTokens = sdk.NewInt(30)
|
||||||
|
|
||||||
// create a validator with a self-delegation
|
// create a validator with a self-delegation
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
@ -611,10 +610,9 @@ func TestRedelegateToSameValidator(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRedelegateSelfDelegation(t *testing.T) {
|
func TestRedelegateSelfDelegation(t *testing.T) {
|
||||||
|
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(30)
|
pool.LooseTokens = sdk.NewInt(30)
|
||||||
|
|
||||||
//create a validator with a self-delegation
|
//create a validator with a self-delegation
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
@ -635,7 +633,7 @@ func TestRedelegateSelfDelegation(t *testing.T) {
|
||||||
validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{})
|
validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{})
|
||||||
validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(10))
|
pool.BondedTokens = pool.BondedTokens.Add(sdk.NewInt(10))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator2 = TestingUpdateValidator(keeper, ctx, validator2, true)
|
validator2 = TestingUpdateValidator(keeper, ctx, validator2, true)
|
||||||
require.Equal(t, sdk.Bonded, validator2.Status)
|
require.Equal(t, sdk.Bonded, validator2.Status)
|
||||||
|
@ -662,14 +660,14 @@ func TestRedelegateSelfDelegation(t *testing.T) {
|
||||||
|
|
||||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(10), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(10), validator.Tokens.Int64())
|
||||||
require.Equal(t, sdk.Unbonding, validator.Status)
|
require.Equal(t, sdk.Unbonding, validator.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRedelegateFromUnbondingValidator(t *testing.T) {
|
func TestRedelegateFromUnbondingValidator(t *testing.T) {
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(30)
|
pool.LooseTokens = sdk.NewInt(30)
|
||||||
|
|
||||||
//create a validator with a self-delegation
|
//create a validator with a self-delegation
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
@ -752,7 +750,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) {
|
||||||
func TestRedelegateFromUnbondedValidator(t *testing.T) {
|
func TestRedelegateFromUnbondedValidator(t *testing.T) {
|
||||||
ctx, _, keeper := CreateTestInput(t, false, 0)
|
ctx, _, keeper := CreateTestInput(t, false, 0)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.LooseTokens = sdk.NewDec(30)
|
pool.LooseTokens = sdk.NewInt(30)
|
||||||
|
|
||||||
//create a validator with a self-delegation
|
//create a validator with a self-delegation
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
|
|
|
@ -33,7 +33,7 @@ func TestPool(t *testing.T) {
|
||||||
require.True(t, expPool.Equal(resPool))
|
require.True(t, expPool.Equal(resPool))
|
||||||
|
|
||||||
//modify a params, save, and retrieve
|
//modify a params, save, and retrieve
|
||||||
expPool.BondedTokens = sdk.NewDec(777)
|
expPool.BondedTokens = sdk.NewInt(777)
|
||||||
keeper.SetPool(ctx, expPool)
|
keeper.SetPool(ctx, expPool)
|
||||||
resPool = keeper.GetPool(ctx)
|
resPool = keeper.GetPool(ctx)
|
||||||
require.True(t, expPool.Equal(resPool))
|
require.True(t, expPool.Equal(resPool))
|
||||||
|
|
|
@ -78,7 +78,7 @@ func getValidatorPowerRank(validator types.Validator) []byte {
|
||||||
potentialPower := validator.Tokens
|
potentialPower := validator.Tokens
|
||||||
|
|
||||||
// todo: deal with cases above 2**64, ref https://github.com/cosmos/cosmos-sdk/issues/2439#issuecomment-427167556
|
// todo: deal with cases above 2**64, ref https://github.com/cosmos/cosmos-sdk/issues/2439#issuecomment-427167556
|
||||||
tendermintPower := potentialPower.RoundInt64()
|
tendermintPower := potentialPower.Int64()
|
||||||
tendermintPowerBytes := make([]byte, 8)
|
tendermintPowerBytes := make([]byte, 8)
|
||||||
binary.BigEndian.PutUint64(tendermintPowerBytes[:], uint64(tendermintPower))
|
binary.BigEndian.PutUint64(tendermintPowerBytes[:], uint64(tendermintPower))
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,12 @@ func TestGetValidatorPowerRank(t *testing.T) {
|
||||||
valAddr1 := sdk.ValAddress(addr1)
|
valAddr1 := sdk.ValAddress(addr1)
|
||||||
emptyDesc := types.Description{}
|
emptyDesc := types.Description{}
|
||||||
val1 := types.NewValidator(valAddr1, pk1, emptyDesc)
|
val1 := types.NewValidator(valAddr1, pk1, emptyDesc)
|
||||||
val1.Tokens = sdk.NewDec(0)
|
val1.Tokens = sdk.ZeroInt()
|
||||||
val2, val3, val4 := val1, val1, val1
|
val2, val3, val4 := val1, val1, val1
|
||||||
val2.Tokens = sdk.NewDec(1)
|
val2.Tokens = sdk.NewInt(1)
|
||||||
val3.Tokens = sdk.NewDec(10)
|
val3.Tokens = sdk.NewInt(10)
|
||||||
x := new(big.Int).Exp(big.NewInt(2), big.NewInt(40), big.NewInt(0))
|
x := new(big.Int).Exp(big.NewInt(2), big.NewInt(40), big.NewInt(0))
|
||||||
val4.Tokens = sdk.NewDecFromBigInt(x)
|
val4.Tokens = sdk.NewIntFromBigInt(x)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
validator types.Validator
|
validator types.Validator
|
||||||
|
|
|
@ -89,7 +89,7 @@ func (k Keeper) ValidatorByConsAddr(ctx sdk.Context, addr sdk.ConsAddress) sdk.V
|
||||||
}
|
}
|
||||||
|
|
||||||
// total power from the bond (not last, but current)
|
// total power from the bond (not last, but current)
|
||||||
func (k Keeper) TotalPower(ctx sdk.Context) sdk.Dec {
|
func (k Keeper) TotalPower(ctx sdk.Context) sdk.Int {
|
||||||
pool := k.GetPool(ctx)
|
pool := k.GetPool(ctx)
|
||||||
return pool.BondedTokens
|
return pool.BondedTokens
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ func (k Keeper) BondedRatio(ctx sdk.Context) sdk.Dec {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when minting new tokens
|
// when minting new tokens
|
||||||
func (k Keeper) InflateSupply(ctx sdk.Context, newTokens sdk.Dec) {
|
func (k Keeper) InflateSupply(ctx sdk.Context, newTokens sdk.Int) {
|
||||||
pool := k.GetPool(ctx)
|
pool := k.GetPool(ctx)
|
||||||
pool.LooseTokens = pool.LooseTokens.Add(newTokens)
|
pool.LooseTokens = pool.LooseTokens.Add(newTokens)
|
||||||
k.SetPool(ctx, pool)
|
k.SetPool(ctx, pool)
|
||||||
|
|
|
@ -29,7 +29,9 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||||
}
|
}
|
||||||
|
|
||||||
// Amount of slashing = slash slashFactor * power at time of infraction
|
// Amount of slashing = slash slashFactor * power at time of infraction
|
||||||
slashAmount := sdk.NewDec(power).Mul(slashFactor)
|
slashAmountDec := sdk.NewDec(power).Mul(slashFactor)
|
||||||
|
slashAmount := slashAmountDec.TruncateInt()
|
||||||
|
|
||||||
// ref https://github.com/cosmos/cosmos-sdk/issues/1348
|
// ref https://github.com/cosmos/cosmos-sdk/issues/1348
|
||||||
// ref https://github.com/cosmos/cosmos-sdk/issues/1471
|
// ref https://github.com/cosmos/cosmos-sdk/issues/1471
|
||||||
|
|
||||||
|
@ -97,8 +99,8 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
|
||||||
}
|
}
|
||||||
|
|
||||||
// cannot decrease balance below zero
|
// cannot decrease balance below zero
|
||||||
tokensToBurn := sdk.MinDec(remainingSlashAmount, validator.Tokens)
|
tokensToBurn := sdk.MinInt(remainingSlashAmount, validator.Tokens)
|
||||||
tokensToBurn = sdk.MaxDec(tokensToBurn, sdk.ZeroDec()) // defensive.
|
tokensToBurn = sdk.MaxInt(tokensToBurn, sdk.ZeroInt()) // defensive.
|
||||||
|
|
||||||
// Deduct from validator's bonded tokens and update the validator.
|
// Deduct from validator's bonded tokens and update the validator.
|
||||||
// The deducted tokens are returned to pool.LooseTokens.
|
// The deducted tokens are returned to pool.LooseTokens.
|
||||||
|
@ -143,29 +145,30 @@ func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) {
|
||||||
// (the amount actually slashed may be less if there's
|
// (the amount actually slashed may be less if there's
|
||||||
// insufficient stake remaining)
|
// insufficient stake remaining)
|
||||||
func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation types.UnbondingDelegation,
|
func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation types.UnbondingDelegation,
|
||||||
infractionHeight int64, slashFactor sdk.Dec) (slashAmount sdk.Dec) {
|
infractionHeight int64, slashFactor sdk.Dec) (slashAmount sdk.Int) {
|
||||||
|
|
||||||
now := ctx.BlockHeader().Time
|
now := ctx.BlockHeader().Time
|
||||||
|
|
||||||
// If unbonding started before this height, stake didn't contribute to infraction
|
// If unbonding started before this height, stake didn't contribute to infraction
|
||||||
if unbondingDelegation.CreationHeight < infractionHeight {
|
if unbondingDelegation.CreationHeight < infractionHeight {
|
||||||
return sdk.ZeroDec()
|
return sdk.ZeroInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
if unbondingDelegation.MinTime.Before(now) {
|
if unbondingDelegation.MinTime.Before(now) {
|
||||||
// Unbonding delegation no longer eligible for slashing, skip it
|
// Unbonding delegation no longer eligible for slashing, skip it
|
||||||
// TODO Settle and delete it automatically?
|
// TODO Settle and delete it automatically?
|
||||||
return sdk.ZeroDec()
|
return sdk.ZeroInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate slash amount proportional to stake contributing to infraction
|
// Calculate slash amount proportional to stake contributing to infraction
|
||||||
slashAmount = slashFactor.MulInt(unbondingDelegation.InitialBalance.Amount)
|
slashAmountDec := slashFactor.MulInt(unbondingDelegation.InitialBalance.Amount)
|
||||||
|
slashAmount = slashAmountDec.TruncateInt()
|
||||||
|
|
||||||
// Don't slash more tokens than held
|
// Don't slash more tokens than held
|
||||||
// Possible since the unbonding delegation may already
|
// Possible since the unbonding delegation may already
|
||||||
// have been slashed, and slash amounts are calculated
|
// have been slashed, and slash amounts are calculated
|
||||||
// according to stake held at time of infraction
|
// according to stake held at time of infraction
|
||||||
unbondingSlashAmount := sdk.MinInt(slashAmount.RoundInt(), unbondingDelegation.Balance.Amount)
|
unbondingSlashAmount := sdk.MinInt(slashAmount, unbondingDelegation.Balance.Amount)
|
||||||
|
|
||||||
// Update unbonding delegation if necessary
|
// Update unbonding delegation if necessary
|
||||||
if !unbondingSlashAmount.IsZero() {
|
if !unbondingSlashAmount.IsZero() {
|
||||||
|
@ -175,11 +178,11 @@ func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty
|
||||||
|
|
||||||
// Burn loose tokens
|
// Burn loose tokens
|
||||||
// Ref https://github.com/cosmos/cosmos-sdk/pull/1278#discussion_r198657760
|
// Ref https://github.com/cosmos/cosmos-sdk/pull/1278#discussion_r198657760
|
||||||
pool.LooseTokens = pool.LooseTokens.Sub(sdk.NewDecFromInt(unbondingSlashAmount))
|
pool.LooseTokens = pool.LooseTokens.Sub(unbondingSlashAmount)
|
||||||
k.SetPool(ctx, pool)
|
k.SetPool(ctx, pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return slashAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
// slash a redelegation and update the pool
|
// slash a redelegation and update the pool
|
||||||
|
@ -189,29 +192,30 @@ func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty
|
||||||
// insufficient stake remaining)
|
// insufficient stake remaining)
|
||||||
// nolint: unparam
|
// nolint: unparam
|
||||||
func (k Keeper) slashRedelegation(ctx sdk.Context, validator types.Validator, redelegation types.Redelegation,
|
func (k Keeper) slashRedelegation(ctx sdk.Context, validator types.Validator, redelegation types.Redelegation,
|
||||||
infractionHeight int64, slashFactor sdk.Dec) (slashAmount sdk.Dec) {
|
infractionHeight int64, slashFactor sdk.Dec) (slashAmount sdk.Int) {
|
||||||
|
|
||||||
now := ctx.BlockHeader().Time
|
now := ctx.BlockHeader().Time
|
||||||
|
|
||||||
// If redelegation started before this height, stake didn't contribute to infraction
|
// If redelegation started before this height, stake didn't contribute to infraction
|
||||||
if redelegation.CreationHeight < infractionHeight {
|
if redelegation.CreationHeight < infractionHeight {
|
||||||
return sdk.ZeroDec()
|
return sdk.ZeroInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
if redelegation.MinTime.Before(now) {
|
if redelegation.MinTime.Before(now) {
|
||||||
// Redelegation no longer eligible for slashing, skip it
|
// Redelegation no longer eligible for slashing, skip it
|
||||||
// TODO Delete it automatically?
|
// TODO Delete it automatically?
|
||||||
return sdk.ZeroDec()
|
return sdk.ZeroInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate slash amount proportional to stake contributing to infraction
|
// Calculate slash amount proportional to stake contributing to infraction
|
||||||
slashAmount = slashFactor.MulInt(redelegation.InitialBalance.Amount)
|
slashAmountDec := slashFactor.MulInt(redelegation.InitialBalance.Amount)
|
||||||
|
slashAmount = slashAmountDec.TruncateInt()
|
||||||
|
|
||||||
// Don't slash more tokens than held
|
// Don't slash more tokens than held
|
||||||
// Possible since the redelegation may already
|
// Possible since the redelegation may already
|
||||||
// have been slashed, and slash amounts are calculated
|
// have been slashed, and slash amounts are calculated
|
||||||
// according to stake held at time of infraction
|
// according to stake held at time of infraction
|
||||||
redelegationSlashAmount := sdk.MinInt(slashAmount.RoundInt(), redelegation.Balance.Amount)
|
redelegationSlashAmount := sdk.MinInt(slashAmount, redelegation.Balance.Amount)
|
||||||
|
|
||||||
// Update redelegation if necessary
|
// Update redelegation if necessary
|
||||||
if !redelegationSlashAmount.IsZero() {
|
if !redelegationSlashAmount.IsZero() {
|
||||||
|
|
|
@ -21,13 +21,13 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) {
|
||||||
params := keeper.GetParams(ctx)
|
params := keeper.GetParams(ctx)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
numVals := 3
|
numVals := 3
|
||||||
pool.LooseTokens = sdk.NewDec(amt * int64(numVals))
|
pool.LooseTokens = sdk.NewInt(amt * int64(numVals))
|
||||||
|
|
||||||
// add numVals validators
|
// add numVals validators
|
||||||
for i := 0; i < numVals; i++ {
|
for i := 0; i < numVals; i++ {
|
||||||
validator := types.NewValidator(addrVals[i], PKs[i], types.Description{})
|
validator := types.NewValidator(addrVals[i], PKs[i], types.Description{})
|
||||||
validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(amt))
|
validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(amt))
|
||||||
pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(amt))
|
pool.BondedTokens = pool.BondedTokens.Add(sdk.NewInt(amt))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = TestingUpdateValidator(keeper, ctx, validator, true)
|
validator = TestingUpdateValidator(keeper, ctx, validator, true)
|
||||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||||
|
@ -84,20 +84,20 @@ func TestSlashUnbondingDelegation(t *testing.T) {
|
||||||
|
|
||||||
// unbonding started prior to the infraction height, stake didn't contribute
|
// unbonding started prior to the infraction height, stake didn't contribute
|
||||||
slashAmount := keeper.slashUnbondingDelegation(ctx, ubd, 1, fraction)
|
slashAmount := keeper.slashUnbondingDelegation(ctx, ubd, 1, fraction)
|
||||||
require.Equal(t, int64(0), slashAmount.RoundInt64())
|
require.Equal(t, int64(0), slashAmount.Int64())
|
||||||
|
|
||||||
// after the expiration time, no longer eligible for slashing
|
// after the expiration time, no longer eligible for slashing
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
||||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||||
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
|
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
|
||||||
require.Equal(t, int64(0), slashAmount.RoundInt64())
|
require.Equal(t, int64(0), slashAmount.Int64())
|
||||||
|
|
||||||
// test valid slash, before expiration timestamp and to which stake contributed
|
// test valid slash, before expiration timestamp and to which stake contributed
|
||||||
oldPool := keeper.GetPool(ctx)
|
oldPool := keeper.GetPool(ctx)
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
|
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)})
|
||||||
keeper.SetUnbondingDelegation(ctx, ubd)
|
keeper.SetUnbondingDelegation(ctx, ubd)
|
||||||
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
|
slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction)
|
||||||
require.Equal(t, int64(5), slashAmount.RoundInt64())
|
require.Equal(t, int64(5), slashAmount.Int64())
|
||||||
ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ func TestSlashUnbondingDelegation(t *testing.T) {
|
||||||
// balance decreased
|
// balance decreased
|
||||||
require.Equal(t, sdk.NewInt64Coin(params.BondDenom, 5), ubd.Balance)
|
require.Equal(t, sdk.NewInt64Coin(params.BondDenom, 5), ubd.Balance)
|
||||||
newPool := keeper.GetPool(ctx)
|
newPool := keeper.GetPool(ctx)
|
||||||
require.Equal(t, int64(5), oldPool.LooseTokens.Sub(newPool.LooseTokens).RoundInt64())
|
require.Equal(t, int64(5), oldPool.LooseTokens.Sub(newPool.LooseTokens).Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests slashRedelegation
|
// tests slashRedelegation
|
||||||
|
@ -142,7 +142,7 @@ func TestSlashRedelegation(t *testing.T) {
|
||||||
validator, found := keeper.GetValidator(ctx, addrVals[1])
|
validator, found := keeper.GetValidator(ctx, addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
slashAmount := keeper.slashRedelegation(ctx, validator, rd, 1, fraction)
|
slashAmount := keeper.slashRedelegation(ctx, validator, rd, 1, fraction)
|
||||||
require.Equal(t, int64(0), slashAmount.RoundInt64())
|
require.Equal(t, int64(0), slashAmount.Int64())
|
||||||
|
|
||||||
// after the expiration time, no longer eligible for slashing
|
// after the expiration time, no longer eligible for slashing
|
||||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)})
|
||||||
|
@ -150,7 +150,7 @@ func TestSlashRedelegation(t *testing.T) {
|
||||||
validator, found = keeper.GetValidator(ctx, addrVals[1])
|
validator, found = keeper.GetValidator(ctx, addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction)
|
slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction)
|
||||||
require.Equal(t, int64(0), slashAmount.RoundInt64())
|
require.Equal(t, int64(0), slashAmount.Int64())
|
||||||
|
|
||||||
// test valid slash, before expiration timestamp and to which stake contributed
|
// test valid slash, before expiration timestamp and to which stake contributed
|
||||||
oldPool := keeper.GetPool(ctx)
|
oldPool := keeper.GetPool(ctx)
|
||||||
|
@ -159,7 +159,7 @@ func TestSlashRedelegation(t *testing.T) {
|
||||||
validator, found = keeper.GetValidator(ctx, addrVals[1])
|
validator, found = keeper.GetValidator(ctx, addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction)
|
slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction)
|
||||||
require.Equal(t, int64(5), slashAmount.RoundInt64())
|
require.Equal(t, int64(5), slashAmount.Int64())
|
||||||
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ func TestSlashRedelegation(t *testing.T) {
|
||||||
|
|
||||||
// pool bonded tokens decreased
|
// pool bonded tokens decreased
|
||||||
newPool := keeper.GetPool(ctx)
|
newPool := keeper.GetPool(ctx)
|
||||||
require.Equal(t, int64(5), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(5), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests Slash at a future height (must panic)
|
// tests Slash at a future height (must panic)
|
||||||
|
@ -214,9 +214,9 @@ func TestSlashAtNegativeHeight(t *testing.T) {
|
||||||
|
|
||||||
validator = keeper.mustGetValidator(ctx, validator.OperatorAddr)
|
validator = keeper.mustGetValidator(ctx, validator.OperatorAddr)
|
||||||
// power decreased
|
// power decreased
|
||||||
require.Equal(t, sdk.NewDec(5), validator.GetPower())
|
require.True(sdk.IntEq(t, sdk.NewInt(5), validator.GetPower()))
|
||||||
// pool bonded shares decreased
|
// pool bonded shares decreased
|
||||||
require.Equal(t, sdk.NewDec(5).RoundInt64(), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(5), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests Slash at the current height
|
// tests Slash at the current height
|
||||||
|
@ -241,9 +241,9 @@ func TestSlashValidatorAtCurrentHeight(t *testing.T) {
|
||||||
|
|
||||||
validator = keeper.mustGetValidator(ctx, validator.OperatorAddr)
|
validator = keeper.mustGetValidator(ctx, validator.OperatorAddr)
|
||||||
// power decreased
|
// power decreased
|
||||||
require.Equal(t, sdk.NewDec(5), validator.GetPower())
|
require.True(sdk.IntEq(t, sdk.NewInt(5), validator.GetPower()))
|
||||||
// pool bonded shares decreased
|
// pool bonded shares decreased
|
||||||
require.Equal(t, sdk.NewDec(5).RoundInt64(), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(5), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests Slash at a previous height with an unbonding delegation
|
// tests Slash at a previous height with an unbonding delegation
|
||||||
|
@ -283,7 +283,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool := keeper.GetPool(ctx)
|
newPool := keeper.GetPool(ctx)
|
||||||
// bonded tokens burned
|
// bonded tokens burned
|
||||||
require.Equal(t, int64(3), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(3), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
@ -291,7 +291,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
// was still bonded at the time of discovery and was slashed by half, 4 stake
|
// was still bonded at the time of discovery and was slashed by half, 4 stake
|
||||||
// bonded at the time of discovery hadn't been bonded at the time of infraction
|
// bonded at the time of discovery hadn't been bonded at the time of infraction
|
||||||
// and wasn't slashed
|
// and wasn't slashed
|
||||||
require.Equal(t, sdk.NewDec(7), validator.GetPower())
|
require.True(sdk.IntEq(t, sdk.NewInt(7), validator.GetPower()))
|
||||||
|
|
||||||
// slash validator again
|
// slash validator again
|
||||||
ctx = ctx.WithBlockHeight(13)
|
ctx = ctx.WithBlockHeight(13)
|
||||||
|
@ -303,12 +303,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool = keeper.GetPool(ctx)
|
newPool = keeper.GetPool(ctx)
|
||||||
// bonded tokens burned again
|
// bonded tokens burned again
|
||||||
require.Equal(t, int64(6), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(6), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
// power decreased by 3 again
|
// power decreased by 3 again
|
||||||
require.Equal(t, sdk.NewDec(4), validator.GetPower())
|
require.True(sdk.IntEq(t, sdk.NewInt(4), validator.GetPower()))
|
||||||
|
|
||||||
// slash validator again
|
// slash validator again
|
||||||
// all originally bonded stake has been slashed, so this will have no effect
|
// all originally bonded stake has been slashed, so this will have no effect
|
||||||
|
@ -323,12 +323,12 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool = keeper.GetPool(ctx)
|
newPool = keeper.GetPool(ctx)
|
||||||
// bonded tokens burned again
|
// bonded tokens burned again
|
||||||
require.Equal(t, int64(9), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(9), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
// power decreased by 3 again
|
// power decreased by 3 again
|
||||||
require.Equal(t, sdk.NewDec(1), validator.GetPower())
|
require.True(sdk.IntEq(t, sdk.NewInt(1), validator.GetPower()))
|
||||||
|
|
||||||
// slash validator again
|
// slash validator again
|
||||||
// all originally bonded stake has been slashed, so this will have no effect
|
// all originally bonded stake has been slashed, so this will have no effect
|
||||||
|
@ -343,7 +343,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool = keeper.GetPool(ctx)
|
newPool = keeper.GetPool(ctx)
|
||||||
// just 1 bonded token burned again since that's all the validator now has
|
// just 1 bonded token burned again since that's all the validator now has
|
||||||
require.Equal(t, int64(10), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(10), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// apply TM updates
|
// apply TM updates
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
// read updated validator
|
// read updated validator
|
||||||
|
@ -383,7 +383,7 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||||
|
|
||||||
// update bonded tokens
|
// update bonded tokens
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(6))
|
pool.BondedTokens = pool.BondedTokens.Add(sdk.NewInt(6))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
|
|
||||||
// slash validator
|
// slash validator
|
||||||
|
@ -401,7 +401,7 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool := keeper.GetPool(ctx)
|
newPool := keeper.GetPool(ctx)
|
||||||
// bonded tokens burned
|
// bonded tokens burned
|
||||||
require.Equal(t, int64(5), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(5), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
@ -409,7 +409,7 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||||
// was still bonded at the time of discovery and was slashed by half, 4 stake
|
// was still bonded at the time of discovery and was slashed by half, 4 stake
|
||||||
// bonded at the time of discovery hadn't been bonded at the time of infraction
|
// bonded at the time of discovery hadn't been bonded at the time of infraction
|
||||||
// and wasn't slashed
|
// and wasn't slashed
|
||||||
require.Equal(t, sdk.NewDec(8), validator.GetPower())
|
require.True(sdk.IntEq(t, sdk.NewInt(8), validator.GetPower()))
|
||||||
|
|
||||||
// slash the validator again
|
// slash the validator again
|
||||||
ctx = ctx.WithBlockHeight(12)
|
ctx = ctx.WithBlockHeight(12)
|
||||||
|
@ -425,12 +425,12 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool = keeper.GetPool(ctx)
|
newPool = keeper.GetPool(ctx)
|
||||||
// seven bonded tokens burned
|
// seven bonded tokens burned
|
||||||
require.Equal(t, int64(12), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(12), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
// power decreased by 4
|
// power decreased by 4
|
||||||
require.Equal(t, sdk.NewDec(4), validator.GetPower())
|
require.True(sdk.IntEq(t, sdk.NewInt(4), validator.GetPower()))
|
||||||
|
|
||||||
// slash the validator again, by 100%
|
// slash the validator again, by 100%
|
||||||
ctx = ctx.WithBlockHeight(12)
|
ctx = ctx.WithBlockHeight(12)
|
||||||
|
@ -446,7 +446,7 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool = keeper.GetPool(ctx)
|
newPool = keeper.GetPool(ctx)
|
||||||
// four more bonded tokens burned
|
// four more bonded tokens burned
|
||||||
require.Equal(t, int64(16), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(16), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// apply TM updates
|
// apply TM updates
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
// read updated validator
|
// read updated validator
|
||||||
|
@ -470,7 +470,7 @@ func TestSlashWithRedelegation(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool = keeper.GetPool(ctx)
|
newPool = keeper.GetPool(ctx)
|
||||||
// no more bonded tokens burned
|
// no more bonded tokens burned
|
||||||
require.Equal(t, int64(16), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(16), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// read updated validator
|
// read updated validator
|
||||||
// power still zero, still in unbonding period
|
// power still zero, still in unbonding period
|
||||||
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
|
@ -533,12 +533,12 @@ func TestSlashBoth(t *testing.T) {
|
||||||
// read updated pool
|
// read updated pool
|
||||||
newPool := keeper.GetPool(ctx)
|
newPool := keeper.GetPool(ctx)
|
||||||
// loose tokens burned
|
// loose tokens burned
|
||||||
require.Equal(t, int64(2), oldPool.LooseTokens.Sub(newPool.LooseTokens).RoundInt64())
|
require.Equal(t, int64(2), oldPool.LooseTokens.Sub(newPool.LooseTokens).Int64())
|
||||||
// bonded tokens burned
|
// bonded tokens burned
|
||||||
require.Equal(t, int64(3), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
|
require.Equal(t, int64(3), oldPool.BondedTokens.Sub(newPool.BondedTokens).Int64())
|
||||||
// read updated validator
|
// read updated validator
|
||||||
validator, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
|
validator, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0]))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
// power not decreased, all stake was bonded since
|
// power not decreased, all stake was bonded since
|
||||||
require.Equal(t, sdk.NewDec(10), validator.GetPower())
|
require.True(sdk.IntEq(t, sdk.NewInt(10), validator.GetPower()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
|
||||||
{keeper.BondDenom(ctx), sdk.NewInt(initCoins)},
|
{keeper.BondDenom(ctx), sdk.NewInt(initCoins)},
|
||||||
})
|
})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
pool.LooseTokens = pool.LooseTokens.Add(sdk.NewDec(initCoins))
|
pool.LooseTokens = pool.LooseTokens.Add(sdk.NewInt(initCoins))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,7 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||||
|
|
||||||
// if we get to a zero-power validator (which we don't bond),
|
// if we get to a zero-power validator (which we don't bond),
|
||||||
// there are no more possible bonded validators
|
// there are no more possible bonded validators
|
||||||
// note: we must check the ABCI power, since we round before sending to Tendermint
|
if validator.Tokens.IsZero() {
|
||||||
if validator.Tokens.RoundInt64() == int64(0) {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||||
oldPowerBytes, found := last[valAddrBytes]
|
oldPowerBytes, found := last[valAddrBytes]
|
||||||
|
|
||||||
// calculate the new power bytes
|
// calculate the new power bytes
|
||||||
newPower := validator.BondedTokens().RoundInt64()
|
newPower := validator.BondedTokens().Int64()
|
||||||
newPowerBytes := k.cdc.MustMarshalBinaryLengthPrefixed(sdk.NewInt(newPower))
|
newPowerBytes := k.cdc.MustMarshalBinaryLengthPrefixed(sdk.NewInt(newPower))
|
||||||
// update the validator set if power has changed
|
// update the validator set if power has changed
|
||||||
if !found || !bytes.Equal(oldPowerBytes, newPowerBytes) {
|
if !found || !bytes.Equal(oldPowerBytes, newPowerBytes) {
|
||||||
|
|
|
@ -132,7 +132,7 @@ func (k Keeper) AddValidatorTokensAndShares(ctx sdk.Context, validator types.Val
|
||||||
|
|
||||||
// Update the tokens of an existing validator, update the validators power index key
|
// Update the tokens of an existing validator, update the validators power index key
|
||||||
func (k Keeper) RemoveValidatorTokensAndShares(ctx sdk.Context, validator types.Validator,
|
func (k Keeper) RemoveValidatorTokensAndShares(ctx sdk.Context, validator types.Validator,
|
||||||
sharesToRemove sdk.Dec) (valOut types.Validator, removedTokens sdk.Dec) {
|
sharesToRemove sdk.Dec) (valOut types.Validator, removedTokens sdk.Int) {
|
||||||
|
|
||||||
k.DeleteValidatorByPowerIndex(ctx, validator)
|
k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||||
pool := k.GetPool(ctx)
|
pool := k.GetPool(ctx)
|
||||||
|
@ -144,7 +144,8 @@ func (k Keeper) RemoveValidatorTokensAndShares(ctx sdk.Context, validator types.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the tokens of an existing validator, update the validators power index key
|
// Update the tokens of an existing validator, update the validators power index key
|
||||||
func (k Keeper) RemoveValidatorTokens(ctx sdk.Context, validator types.Validator, tokensToRemove sdk.Dec) types.Validator {
|
func (k Keeper) RemoveValidatorTokens(ctx sdk.Context,
|
||||||
|
validator types.Validator, tokensToRemove sdk.Int) types.Validator {
|
||||||
|
|
||||||
k.DeleteValidatorByPowerIndex(ctx, validator)
|
k.DeleteValidatorByPowerIndex(ctx, validator)
|
||||||
pool := k.GetPool(ctx)
|
pool := k.GetPool(ctx)
|
||||||
|
@ -157,7 +158,9 @@ func (k Keeper) RemoveValidatorTokens(ctx sdk.Context, validator types.Validator
|
||||||
|
|
||||||
// UpdateValidatorCommission attempts to update a validator's commission rate.
|
// UpdateValidatorCommission attempts to update a validator's commission rate.
|
||||||
// An error is returned if the new commission rate is invalid.
|
// An error is returned if the new commission rate is invalid.
|
||||||
func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Validator, newRate sdk.Dec) (types.Commission, sdk.Error) {
|
func (k Keeper) UpdateValidatorCommission(ctx sdk.Context,
|
||||||
|
validator types.Validator, newRate sdk.Dec) (types.Commission, sdk.Error) {
|
||||||
|
|
||||||
commission := validator.Commission
|
commission := validator.Commission
|
||||||
blockTime := ctx.BlockHeader().Time
|
blockTime := ctx.BlockHeader().Time
|
||||||
|
|
||||||
|
@ -330,12 +333,13 @@ func (k Keeper) DeleteValidatorQueueTimeSlice(ctx sdk.Context, timestamp time.Ti
|
||||||
// Insert an validator address to the appropriate timeslice in the validator queue
|
// Insert an validator address to the appropriate timeslice in the validator queue
|
||||||
func (k Keeper) InsertValidatorQueue(ctx sdk.Context, val types.Validator) {
|
func (k Keeper) InsertValidatorQueue(ctx sdk.Context, val types.Validator) {
|
||||||
timeSlice := k.GetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime)
|
timeSlice := k.GetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime)
|
||||||
|
var keys []sdk.ValAddress
|
||||||
if len(timeSlice) == 0 {
|
if len(timeSlice) == 0 {
|
||||||
k.SetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime, []sdk.ValAddress{val.OperatorAddr})
|
keys = []sdk.ValAddress{val.OperatorAddr}
|
||||||
} else {
|
} else {
|
||||||
timeSlice = append(timeSlice, val.OperatorAddr)
|
keys = append(timeSlice, val.OperatorAddr)
|
||||||
k.SetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime, timeSlice)
|
|
||||||
}
|
}
|
||||||
|
k.SetValidatorQueueTimeSlice(ctx, val.UnbondingMinTime, keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a validator address from the validator queue
|
// Delete a validator address from the validator queue
|
||||||
|
@ -357,7 +361,8 @@ func (k Keeper) DeleteValidatorQueue(ctx sdk.Context, val types.Validator) {
|
||||||
// Returns all the validator queue timeslices from time 0 until endTime
|
// Returns all the validator queue timeslices from time 0 until endTime
|
||||||
func (k Keeper) ValidatorQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
|
func (k Keeper) ValidatorQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
return store.Iterator(ValidatorQueueKey, sdk.InclusiveEndBytes(GetValidatorQueueTimeKey(endTime)))
|
return store.Iterator(ValidatorQueueKey,
|
||||||
|
sdk.InclusiveEndBytes(GetValidatorQueueTimeKey(endTime)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a concatenated list of all the timeslices before currTime, and deletes the timeslices from the queue
|
// Returns a concatenated list of all the timeslices before currTime, and deletes the timeslices from the queue
|
||||||
|
|
|
@ -27,7 +27,7 @@ func TestSetValidator(t *testing.T) {
|
||||||
validator := types.NewValidator(valAddr, valPubKey, types.Description{})
|
validator := types.NewValidator(valAddr, valPubKey, types.Description{})
|
||||||
validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, sdk.Unbonded, validator.Status)
|
require.Equal(t, sdk.Unbonded, validator.Status)
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(10), validator.Tokens))
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
keeper.SetValidator(ctx, validator)
|
keeper.SetValidator(ctx, validator)
|
||||||
|
@ -42,7 +42,7 @@ func TestSetValidator(t *testing.T) {
|
||||||
|
|
||||||
// after the save the validator should be bonded
|
// after the save the validator should be bonded
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(10), validator.Tokens))
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
||||||
|
|
||||||
// Check each store for being saved
|
// Check each store for being saved
|
||||||
|
@ -75,20 +75,20 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) {
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
|
|
||||||
// create a random pool
|
// create a random pool
|
||||||
pool.LooseTokens = sdk.NewDec(10000)
|
pool.LooseTokens = sdk.NewInt(10000)
|
||||||
pool.BondedTokens = sdk.NewDec(1234)
|
pool.BondedTokens = sdk.NewInt(1234)
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
|
|
||||||
// add a validator
|
// add a validator
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
validator, pool, delSharesCreated := validator.AddTokensFromDel(pool, sdk.NewInt(100))
|
validator, pool, delSharesCreated := validator.AddTokensFromDel(pool, sdk.NewInt(100))
|
||||||
require.Equal(t, sdk.Unbonded, validator.Status)
|
require.Equal(t, sdk.Unbonded, validator.Status)
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(100), validator.Tokens.Int64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
TestingUpdateValidator(keeper, ctx, validator, true)
|
TestingUpdateValidator(keeper, ctx, validator, true)
|
||||||
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
validator, found := keeper.GetValidator(ctx, addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool)
|
require.Equal(t, int64(100), validator.Tokens.Int64(), "\nvalidator %v\npool %v", validator, pool)
|
||||||
|
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
power := GetValidatorsByPowerIndexKey(validator)
|
power := GetValidatorsByPowerIndexKey(validator)
|
||||||
|
@ -97,7 +97,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) {
|
||||||
// burn half the delegator shares
|
// burn half the delegator shares
|
||||||
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
keeper.DeleteValidatorByPowerIndex(ctx, validator)
|
||||||
validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2)))
|
validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2)))
|
||||||
require.Equal(t, int64(50), burned.RoundInt64())
|
require.Equal(t, int64(50), burned.Int64())
|
||||||
keeper.SetPool(ctx, pool) // update the pool
|
keeper.SetPool(ctx, pool) // update the pool
|
||||||
TestingUpdateValidator(keeper, ctx, validator, true) // update the validator, possibly kicking it out
|
TestingUpdateValidator(keeper, ctx, validator, true) // update the validator, possibly kicking it out
|
||||||
require.False(t, validatorByPowerIndexExists(keeper, ctx, power))
|
require.False(t, validatorByPowerIndexExists(keeper, ctx, power))
|
||||||
|
@ -123,8 +123,8 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) {
|
||||||
keeper.SetParams(ctx, params)
|
keeper.SetParams(ctx, params)
|
||||||
|
|
||||||
// create a random pool
|
// create a random pool
|
||||||
pool.LooseTokens = sdk.NewDec(10000)
|
pool.LooseTokens = sdk.NewInt(10000)
|
||||||
pool.BondedTokens = sdk.NewDec(1234)
|
pool.BondedTokens = sdk.NewInt(1234)
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
|
|
||||||
validators := make([]types.Validator, numVals)
|
validators := make([]types.Validator, numVals)
|
||||||
|
@ -175,11 +175,11 @@ func TestSlashToZeroPowerRemoved(t *testing.T) {
|
||||||
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
validator := types.NewValidator(addrVals[0], PKs[0], types.Description{})
|
||||||
validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(100))
|
validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(100))
|
||||||
require.Equal(t, sdk.Unbonded, validator.Status)
|
require.Equal(t, sdk.Unbonded, validator.Status)
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(100), validator.Tokens.Int64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||||
validator = TestingUpdateValidator(keeper, ctx, validator, true)
|
validator = TestingUpdateValidator(keeper, ctx, validator, true)
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool)
|
require.Equal(t, int64(100), validator.Tokens.Int64(), "\nvalidator %v\npool %v", validator, pool)
|
||||||
|
|
||||||
// slash the validator by 100%
|
// slash the validator by 100%
|
||||||
consAddr0 := sdk.ConsAddress(PKs[0].Address())
|
consAddr0 := sdk.ConsAddress(PKs[0].Address())
|
||||||
|
@ -202,13 +202,13 @@ func TestValidatorBasics(t *testing.T) {
|
||||||
for i, amt := range amts {
|
for i, amt := range amts {
|
||||||
validators[i] = types.NewValidator(addrVals[i], PKs[i], types.Description{})
|
validators[i] = types.NewValidator(addrVals[i], PKs[i], types.Description{})
|
||||||
validators[i].Status = sdk.Unbonded
|
validators[i].Status = sdk.Unbonded
|
||||||
validators[i].Tokens = sdk.ZeroDec()
|
validators[i].Tokens = sdk.ZeroInt()
|
||||||
validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt))
|
validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
}
|
}
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(9), validators[0].Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(9), validators[0].Tokens))
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(8), validators[1].Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(8), validators[1].Tokens))
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(7), validators[2].Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(7), validators[2].Tokens))
|
||||||
|
|
||||||
// check the empty keeper first
|
// check the empty keeper first
|
||||||
_, found := keeper.GetValidator(ctx, addrVals[0])
|
_, found := keeper.GetValidator(ctx, addrVals[0])
|
||||||
|
@ -220,7 +220,7 @@ func TestValidatorBasics(t *testing.T) {
|
||||||
require.Zero(t, len(resVals))
|
require.Zero(t, len(resVals))
|
||||||
|
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
assert.True(sdk.DecEq(t, sdk.ZeroDec(), pool.BondedTokens))
|
assert.True(sdk.IntEq(t, sdk.ZeroInt(), pool.BondedTokens))
|
||||||
|
|
||||||
// set and retrieve a record
|
// set and retrieve a record
|
||||||
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true)
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true)
|
||||||
|
@ -241,14 +241,14 @@ func TestValidatorBasics(t *testing.T) {
|
||||||
require.Equal(t, 1, len(resVals))
|
require.Equal(t, 1, len(resVals))
|
||||||
assert.True(ValEq(t, validators[0], resVals[0]))
|
assert.True(ValEq(t, validators[0], resVals[0]))
|
||||||
assert.Equal(t, sdk.Bonded, validators[0].Status)
|
assert.Equal(t, sdk.Bonded, validators[0].Status)
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(9), validators[0].BondedTokens()))
|
assert.True(sdk.IntEq(t, sdk.NewInt(9), validators[0].BondedTokens()))
|
||||||
|
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
assert.True(sdk.DecEq(t, pool.BondedTokens, validators[0].BondedTokens()))
|
assert.True(sdk.IntEq(t, pool.BondedTokens, validators[0].BondedTokens()))
|
||||||
|
|
||||||
// modify a records, save, and retrieve
|
// modify a records, save, and retrieve
|
||||||
validators[0].Status = sdk.Bonded
|
validators[0].Status = sdk.Bonded
|
||||||
validators[0].Tokens = sdk.NewDec(10)
|
validators[0].Tokens = sdk.NewInt(10)
|
||||||
validators[0].DelegatorShares = sdk.NewDec(10)
|
validators[0].DelegatorShares = sdk.NewDec(10)
|
||||||
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true)
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true)
|
||||||
resVal, found = keeper.GetValidator(ctx, addrVals[0])
|
resVal, found = keeper.GetValidator(ctx, addrVals[0])
|
||||||
|
@ -294,7 +294,7 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
for i, amt := range amts {
|
for i, amt := range amts {
|
||||||
validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{})
|
validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{})
|
||||||
validators[i].Status = sdk.Bonded
|
validators[i].Status = sdk.Bonded
|
||||||
validators[i].Tokens = sdk.NewDec(amt)
|
validators[i].Tokens = sdk.NewInt(amt)
|
||||||
validators[i].DelegatorShares = sdk.NewDec(amt)
|
validators[i].DelegatorShares = sdk.NewDec(amt)
|
||||||
TestingUpdateValidator(keeper, ctx, validators[i], true)
|
TestingUpdateValidator(keeper, ctx, validators[i], true)
|
||||||
}
|
}
|
||||||
|
@ -302,11 +302,11 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
// first make sure everything made it in to the gotValidator group
|
// first make sure everything made it in to the gotValidator group
|
||||||
resValidators := keeper.GetBondedValidatorsByPower(ctx)
|
resValidators := keeper.GetBondedValidatorsByPower(ctx)
|
||||||
assert.Equal(t, n, len(resValidators))
|
assert.Equal(t, n, len(resValidators))
|
||||||
assert.Equal(t, sdk.NewDec(400), resValidators[0].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(400), resValidators[0].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, sdk.NewDec(200), resValidators[1].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(200), resValidators[1].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, sdk.NewDec(100), resValidators[2].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(100), resValidators[2].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, sdk.NewDec(1), resValidators[3].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(1), resValidators[3].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, sdk.NewDec(0), resValidators[4].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(0), resValidators[4].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, validators[3].OperatorAddr, resValidators[0].OperatorAddr, "%v", resValidators)
|
assert.Equal(t, validators[3].OperatorAddr, resValidators[0].OperatorAddr, "%v", resValidators)
|
||||||
assert.Equal(t, validators[4].OperatorAddr, resValidators[1].OperatorAddr, "%v", resValidators)
|
assert.Equal(t, validators[4].OperatorAddr, resValidators[1].OperatorAddr, "%v", resValidators)
|
||||||
assert.Equal(t, validators[1].OperatorAddr, resValidators[2].OperatorAddr, "%v", resValidators)
|
assert.Equal(t, validators[1].OperatorAddr, resValidators[2].OperatorAddr, "%v", resValidators)
|
||||||
|
@ -314,14 +314,14 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
assert.Equal(t, validators[0].OperatorAddr, resValidators[4].OperatorAddr, "%v", resValidators)
|
assert.Equal(t, validators[0].OperatorAddr, resValidators[4].OperatorAddr, "%v", resValidators)
|
||||||
|
|
||||||
// test a basic increase in voting power
|
// test a basic increase in voting power
|
||||||
validators[3].Tokens = sdk.NewDec(500)
|
validators[3].Tokens = sdk.NewInt(500)
|
||||||
TestingUpdateValidator(keeper, ctx, validators[3], true)
|
TestingUpdateValidator(keeper, ctx, validators[3], true)
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, len(resValidators), n)
|
require.Equal(t, len(resValidators), n)
|
||||||
assert.True(ValEq(t, validators[3], resValidators[0]))
|
assert.True(ValEq(t, validators[3], resValidators[0]))
|
||||||
|
|
||||||
// test a decrease in voting power
|
// test a decrease in voting power
|
||||||
validators[3].Tokens = sdk.NewDec(300)
|
validators[3].Tokens = sdk.NewInt(300)
|
||||||
TestingUpdateValidator(keeper, ctx, validators[3], true)
|
TestingUpdateValidator(keeper, ctx, validators[3], true)
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, len(resValidators), n)
|
require.Equal(t, len(resValidators), n)
|
||||||
|
@ -329,7 +329,7 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
assert.True(ValEq(t, validators[4], resValidators[1]))
|
assert.True(ValEq(t, validators[4], resValidators[1]))
|
||||||
|
|
||||||
// test equal voting power, different age
|
// test equal voting power, different age
|
||||||
validators[3].Tokens = sdk.NewDec(200)
|
validators[3].Tokens = sdk.NewInt(200)
|
||||||
ctx = ctx.WithBlockHeight(10)
|
ctx = ctx.WithBlockHeight(10)
|
||||||
TestingUpdateValidator(keeper, ctx, validators[3], true)
|
TestingUpdateValidator(keeper, ctx, validators[3], true)
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
|
@ -348,8 +348,8 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
assert.True(ValEq(t, validators[4], resValidators[1]))
|
assert.True(ValEq(t, validators[4], resValidators[1]))
|
||||||
|
|
||||||
// change in voting power of both validators, both still in v-set, no age change
|
// change in voting power of both validators, both still in v-set, no age change
|
||||||
validators[3].Tokens = sdk.NewDec(300)
|
validators[3].Tokens = sdk.NewInt(300)
|
||||||
validators[4].Tokens = sdk.NewDec(300)
|
validators[4].Tokens = sdk.NewInt(300)
|
||||||
TestingUpdateValidator(keeper, ctx, validators[3], true)
|
TestingUpdateValidator(keeper, ctx, validators[3], true)
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, len(resValidators), n)
|
require.Equal(t, len(resValidators), n)
|
||||||
|
@ -382,14 +382,14 @@ func GetValidatorSortingMixed(t *testing.T) {
|
||||||
validators[0].Status = sdk.Bonded
|
validators[0].Status = sdk.Bonded
|
||||||
validators[1].Status = sdk.Bonded
|
validators[1].Status = sdk.Bonded
|
||||||
validators[2].Status = sdk.Bonded
|
validators[2].Status = sdk.Bonded
|
||||||
validators[0].Tokens = sdk.NewDec(amts[0])
|
validators[0].Tokens = sdk.NewInt(amts[0])
|
||||||
validators[1].Tokens = sdk.NewDec(amts[1])
|
validators[1].Tokens = sdk.NewInt(amts[1])
|
||||||
validators[2].Tokens = sdk.NewDec(amts[2])
|
validators[2].Tokens = sdk.NewInt(amts[2])
|
||||||
|
|
||||||
validators[3].Status = sdk.Bonded
|
validators[3].Status = sdk.Bonded
|
||||||
validators[4].Status = sdk.Bonded
|
validators[4].Status = sdk.Bonded
|
||||||
validators[3].Tokens = sdk.NewDec(amts[3])
|
validators[3].Tokens = sdk.NewInt(amts[3])
|
||||||
validators[4].Tokens = sdk.NewDec(amts[4])
|
validators[4].Tokens = sdk.NewInt(amts[4])
|
||||||
|
|
||||||
for i := range amts {
|
for i := range amts {
|
||||||
TestingUpdateValidator(keeper, ctx, validators[i], true)
|
TestingUpdateValidator(keeper, ctx, validators[i], true)
|
||||||
|
@ -413,11 +413,11 @@ func GetValidatorSortingMixed(t *testing.T) {
|
||||||
// first make sure everything made it in to the gotValidator group
|
// first make sure everything made it in to the gotValidator group
|
||||||
resValidators := keeper.GetBondedValidatorsByPower(ctx)
|
resValidators := keeper.GetBondedValidatorsByPower(ctx)
|
||||||
assert.Equal(t, n, len(resValidators))
|
assert.Equal(t, n, len(resValidators))
|
||||||
assert.Equal(t, sdk.NewDec(400), resValidators[0].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(400), resValidators[0].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, sdk.NewDec(200), resValidators[1].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(200), resValidators[1].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, sdk.NewDec(100), resValidators[2].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(100), resValidators[2].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, sdk.NewDec(1), resValidators[3].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(1), resValidators[3].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, sdk.NewDec(0), resValidators[4].BondedTokens(), "%v", resValidators)
|
assert.Equal(t, sdk.NewInt(0), resValidators[4].BondedTokens(), "%v", resValidators)
|
||||||
assert.Equal(t, validators[3].OperatorAddr, resValidators[0].OperatorAddr, "%v", resValidators)
|
assert.Equal(t, validators[3].OperatorAddr, resValidators[0].OperatorAddr, "%v", resValidators)
|
||||||
assert.Equal(t, validators[4].OperatorAddr, resValidators[1].OperatorAddr, "%v", resValidators)
|
assert.Equal(t, validators[4].OperatorAddr, resValidators[1].OperatorAddr, "%v", resValidators)
|
||||||
assert.Equal(t, validators[1].OperatorAddr, resValidators[2].OperatorAddr, "%v", resValidators)
|
assert.Equal(t, validators[1].OperatorAddr, resValidators[2].OperatorAddr, "%v", resValidators)
|
||||||
|
@ -672,7 +672,7 @@ func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) {
|
||||||
// test single value change
|
// test single value change
|
||||||
// tendermintUpdate set: {} -> {c1'}
|
// tendermintUpdate set: {} -> {c1'}
|
||||||
validators[0].Status = sdk.Bonded
|
validators[0].Status = sdk.Bonded
|
||||||
validators[0].Tokens = sdk.NewDec(600)
|
validators[0].Tokens = sdk.NewInt(600)
|
||||||
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false)
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false)
|
||||||
|
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
@ -810,8 +810,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) {
|
||||||
require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
||||||
|
|
||||||
// check initial power
|
// check initial power
|
||||||
require.Equal(t, sdk.NewDec(100).RoundInt64(), validators[0].GetPower().RoundInt64())
|
require.Equal(t, int64(100), validators[0].GetPower().Int64())
|
||||||
require.Equal(t, sdk.NewDec(100).RoundInt64(), validators[1].GetPower().RoundInt64())
|
require.Equal(t, int64(100), validators[1].GetPower().Int64())
|
||||||
|
|
||||||
// test multiple value change
|
// test multiple value change
|
||||||
// tendermintUpdate set: {c1, c3} -> {c1', c3'}
|
// tendermintUpdate set: {c1, c3} -> {c1', c3'}
|
||||||
|
@ -823,8 +823,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) {
|
||||||
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false)
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false)
|
||||||
|
|
||||||
// power has changed
|
// power has changed
|
||||||
require.Equal(t, sdk.NewDec(80).RoundInt64(), validators[0].GetPower().RoundInt64())
|
require.Equal(t, int64(80), validators[0].GetPower().Int64())
|
||||||
require.Equal(t, sdk.NewDec(70).RoundInt64(), validators[1].GetPower().RoundInt64())
|
require.Equal(t, int64(70), validators[1].GetPower().Int64())
|
||||||
|
|
||||||
// Tendermint updates should reflect power change
|
// Tendermint updates should reflect power change
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
|
@ -65,11 +65,9 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper,
|
||||||
k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool {
|
k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool {
|
||||||
switch validator.GetStatus() {
|
switch validator.GetStatus() {
|
||||||
case sdk.Bonded:
|
case sdk.Bonded:
|
||||||
bonded = bonded.Add(validator.GetPower())
|
bonded = bonded.Add(sdk.NewDecFromInt(validator.GetPower()))
|
||||||
case sdk.Unbonding:
|
case sdk.Unbonding, sdk.Unbonded:
|
||||||
loose = loose.Add(validator.GetTokens())
|
loose = loose.Add(sdk.NewDecFromInt(validator.GetTokens()))
|
||||||
case sdk.Unbonded:
|
|
||||||
loose = loose.Add(validator.GetTokens())
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
@ -96,15 +94,17 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper,
|
||||||
|
|
||||||
// Loose tokens should equal coin supply plus unbonding delegations
|
// Loose tokens should equal coin supply plus unbonding delegations
|
||||||
// plus tokens on unbonded validators
|
// plus tokens on unbonded validators
|
||||||
if !pool.LooseTokens.Equal(loose) {
|
if !sdk.NewDecFromInt(pool.LooseTokens).Equal(loose) {
|
||||||
return fmt.Errorf("loose token invariance:\n\tpool.LooseTokens: %v"+
|
return fmt.Errorf("loose token invariance:\n"+
|
||||||
"\n\tsum of account tokens: %v", pool.LooseTokens, loose)
|
"\tpool.LooseTokens: %v\n"+
|
||||||
|
"\tsum of account tokens: %v", pool.LooseTokens, loose)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bonded tokens should equal sum of tokens with bonded validators
|
// Bonded tokens should equal sum of tokens with bonded validators
|
||||||
if !pool.BondedTokens.Equal(bonded) {
|
if !sdk.NewDecFromInt(pool.BondedTokens).Equal(bonded) {
|
||||||
return fmt.Errorf("bonded token invariance:\n\tpool.BondedTokens: %v"+
|
return fmt.Errorf("bonded token invariance:\n"+
|
||||||
"\n\tsum of account tokens: %v", pool.BondedTokens, bonded)
|
"\tpool.BondedTokens: %v\n"+
|
||||||
|
"\tsum of account tokens: %v", pool.BondedTokens, bonded)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -129,7 +129,7 @@ func NonNegativePowerInvariant(k stake.Keeper) simulation.Invariant {
|
||||||
"\n\tkey should be: %v\n\tkey in store: %v", validator.GetPower(), powerKey, iterator.Key())
|
"\n\tkey should be: %v\n\tkey in store: %v", validator.GetPower(), powerKey, iterator.Key())
|
||||||
}
|
}
|
||||||
|
|
||||||
if validator.Tokens.LT(sdk.ZeroDec()) {
|
if validator.Tokens.IsNegative() {
|
||||||
return fmt.Errorf("negative tokens for validator: %v", validator)
|
return fmt.Errorf("negative tokens for validator: %v", validator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ import (
|
||||||
|
|
||||||
// Pool - dynamic parameters of the current state
|
// Pool - dynamic parameters of the current state
|
||||||
type Pool struct {
|
type Pool struct {
|
||||||
LooseTokens sdk.Dec `json:"loose_tokens"` // tokens which are not bonded in a validator
|
LooseTokens sdk.Int `json:"loose_tokens"` // tokens which are not bonded in a validator
|
||||||
BondedTokens sdk.Dec `json:"bonded_tokens"` // reserve of bonded tokens
|
BondedTokens sdk.Int `json:"bonded_tokens"` // reserve of bonded tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
|
@ -24,15 +24,15 @@ func (p Pool) Equal(p2 Pool) bool {
|
||||||
// initial pool for testing
|
// initial pool for testing
|
||||||
func InitialPool() Pool {
|
func InitialPool() Pool {
|
||||||
return Pool{
|
return Pool{
|
||||||
LooseTokens: sdk.ZeroDec(),
|
LooseTokens: sdk.ZeroInt(),
|
||||||
BondedTokens: sdk.ZeroDec(),
|
BondedTokens: sdk.ZeroInt(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//____________________________________________________________________
|
//____________________________________________________________________
|
||||||
|
|
||||||
// Sum total of all staking tokens in the pool
|
// Sum total of all staking tokens in the pool
|
||||||
func (p Pool) TokenSupply() sdk.Dec {
|
func (p Pool) TokenSupply() sdk.Int {
|
||||||
return p.LooseTokens.Add(p.BondedTokens)
|
return p.LooseTokens.Add(p.BondedTokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,27 +41,28 @@ func (p Pool) TokenSupply() sdk.Dec {
|
||||||
// get the bond ratio of the global state
|
// get the bond ratio of the global state
|
||||||
func (p Pool) BondedRatio() sdk.Dec {
|
func (p Pool) BondedRatio() sdk.Dec {
|
||||||
supply := p.TokenSupply()
|
supply := p.TokenSupply()
|
||||||
if supply.GT(sdk.ZeroDec()) {
|
if supply.IsPositive() {
|
||||||
return p.BondedTokens.Quo(supply)
|
return sdk.NewDecFromInt(p.BondedTokens).
|
||||||
|
QuoInt(supply)
|
||||||
}
|
}
|
||||||
return sdk.ZeroDec()
|
return sdk.ZeroDec()
|
||||||
}
|
}
|
||||||
|
|
||||||
//_______________________________________________________________________
|
//_______________________________________________________________________
|
||||||
|
|
||||||
func (p Pool) looseTokensToBonded(bondedTokens sdk.Dec) Pool {
|
func (p Pool) looseTokensToBonded(bondedTokens sdk.Int) Pool {
|
||||||
p.BondedTokens = p.BondedTokens.Add(bondedTokens)
|
p.BondedTokens = p.BondedTokens.Add(bondedTokens)
|
||||||
p.LooseTokens = p.LooseTokens.Sub(bondedTokens)
|
p.LooseTokens = p.LooseTokens.Sub(bondedTokens)
|
||||||
if p.LooseTokens.LT(sdk.ZeroDec()) {
|
if p.LooseTokens.IsNegative() {
|
||||||
panic(fmt.Sprintf("sanity check: loose tokens negative, pool: %v", p))
|
panic(fmt.Sprintf("sanity check: loose tokens negative, pool: %v", p))
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Pool) bondedTokensToLoose(bondedTokens sdk.Dec) Pool {
|
func (p Pool) bondedTokensToLoose(bondedTokens sdk.Int) Pool {
|
||||||
p.BondedTokens = p.BondedTokens.Sub(bondedTokens)
|
p.BondedTokens = p.BondedTokens.Sub(bondedTokens)
|
||||||
p.LooseTokens = p.LooseTokens.Add(bondedTokens)
|
p.LooseTokens = p.LooseTokens.Add(bondedTokens)
|
||||||
if p.BondedTokens.LT(sdk.ZeroDec()) {
|
if p.BondedTokens.IsNegative() {
|
||||||
panic(fmt.Sprintf("sanity check: bonded tokens negative, pool: %v", p))
|
panic(fmt.Sprintf("sanity check: bonded tokens negative, pool: %v", p))
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
|
|
|
@ -12,28 +12,28 @@ func TestPoolEqual(t *testing.T) {
|
||||||
p1 := InitialPool()
|
p1 := InitialPool()
|
||||||
p2 := InitialPool()
|
p2 := InitialPool()
|
||||||
require.True(t, p1.Equal(p2))
|
require.True(t, p1.Equal(p2))
|
||||||
p2.BondedTokens = sdk.NewDec(3)
|
p2.BondedTokens = sdk.NewInt(3)
|
||||||
require.False(t, p1.Equal(p2))
|
require.False(t, p1.Equal(p2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddBondedTokens(t *testing.T) {
|
func TestAddBondedTokens(t *testing.T) {
|
||||||
pool := InitialPool()
|
pool := InitialPool()
|
||||||
pool.LooseTokens = sdk.NewDec(10)
|
pool.LooseTokens = sdk.NewInt(10)
|
||||||
pool.BondedTokens = sdk.NewDec(10)
|
pool.BondedTokens = sdk.NewInt(10)
|
||||||
|
|
||||||
pool = pool.looseTokensToBonded(sdk.NewDec(10))
|
pool = pool.looseTokensToBonded(sdk.NewInt(10))
|
||||||
|
|
||||||
require.True(sdk.DecEq(t, sdk.NewDec(20), pool.BondedTokens))
|
require.True(sdk.IntEq(t, sdk.NewInt(20), pool.BondedTokens))
|
||||||
require.True(sdk.DecEq(t, sdk.NewDec(0), pool.LooseTokens))
|
require.True(sdk.IntEq(t, sdk.NewInt(0), pool.LooseTokens))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveBondedTokens(t *testing.T) {
|
func TestRemoveBondedTokens(t *testing.T) {
|
||||||
pool := InitialPool()
|
pool := InitialPool()
|
||||||
pool.LooseTokens = sdk.NewDec(10)
|
pool.LooseTokens = sdk.NewInt(10)
|
||||||
pool.BondedTokens = sdk.NewDec(10)
|
pool.BondedTokens = sdk.NewInt(10)
|
||||||
|
|
||||||
pool = pool.bondedTokensToLoose(sdk.NewDec(5))
|
pool = pool.bondedTokensToLoose(sdk.NewInt(5))
|
||||||
|
|
||||||
require.True(sdk.DecEq(t, sdk.NewDec(5), pool.BondedTokens))
|
require.True(sdk.IntEq(t, sdk.NewInt(5), pool.BondedTokens))
|
||||||
require.True(sdk.DecEq(t, sdk.NewDec(15), pool.LooseTokens))
|
require.True(sdk.IntEq(t, sdk.NewInt(15), pool.LooseTokens))
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ type Validator struct {
|
||||||
Jailed bool `json:"jailed"` // has the validator been jailed from bonded status?
|
Jailed bool `json:"jailed"` // has the validator been jailed from bonded status?
|
||||||
|
|
||||||
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
|
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
|
||||||
Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation)
|
Tokens sdk.Int `json:"tokens"` // delegated tokens (incl. self-delegation)
|
||||||
DelegatorShares sdk.Dec `json:"delegator_shares"` // total shares issued to a validator's delegators
|
DelegatorShares sdk.Dec `json:"delegator_shares"` // total shares issued to a validator's delegators
|
||||||
|
|
||||||
Description Description `json:"description"` // description terms for the validator
|
Description Description `json:"description"` // description terms for the validator
|
||||||
|
@ -45,7 +45,7 @@ func NewValidator(operator sdk.ValAddress, pubKey crypto.PubKey, description Des
|
||||||
ConsPubKey: pubKey,
|
ConsPubKey: pubKey,
|
||||||
Jailed: false,
|
Jailed: false,
|
||||||
Status: sdk.Unbonded,
|
Status: sdk.Unbonded,
|
||||||
Tokens: sdk.ZeroDec(),
|
Tokens: sdk.ZeroInt(),
|
||||||
DelegatorShares: sdk.ZeroDec(),
|
DelegatorShares: sdk.ZeroDec(),
|
||||||
Description: description,
|
Description: description,
|
||||||
BondHeight: int64(0),
|
BondHeight: int64(0),
|
||||||
|
@ -60,7 +60,7 @@ type validatorValue struct {
|
||||||
ConsPubKey crypto.PubKey
|
ConsPubKey crypto.PubKey
|
||||||
Jailed bool
|
Jailed bool
|
||||||
Status sdk.BondStatus
|
Status sdk.BondStatus
|
||||||
Tokens sdk.Dec
|
Tokens sdk.Int
|
||||||
DelegatorShares sdk.Dec
|
DelegatorShares sdk.Dec
|
||||||
Description Description
|
Description Description
|
||||||
BondHeight int64
|
BondHeight int64
|
||||||
|
@ -137,7 +137,7 @@ func (v Validator) HumanReadableString() (string, error) {
|
||||||
resp += fmt.Sprintf("Jailed: %v\n", v.Jailed)
|
resp += fmt.Sprintf("Jailed: %v\n", v.Jailed)
|
||||||
resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status))
|
resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status))
|
||||||
resp += fmt.Sprintf("Tokens: %s\n", v.Tokens)
|
resp += fmt.Sprintf("Tokens: %s\n", v.Tokens)
|
||||||
resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares)
|
resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.String())
|
||||||
resp += fmt.Sprintf("Description: %s\n", v.Description)
|
resp += fmt.Sprintf("Description: %s\n", v.Description)
|
||||||
resp += fmt.Sprintf("Bond Height: %d\n", v.BondHeight)
|
resp += fmt.Sprintf("Bond Height: %d\n", v.BondHeight)
|
||||||
resp += fmt.Sprintf("Unbonding Height: %d\n", v.UnbondingHeight)
|
resp += fmt.Sprintf("Unbonding Height: %d\n", v.UnbondingHeight)
|
||||||
|
@ -156,7 +156,7 @@ type bechValidator struct {
|
||||||
Jailed bool `json:"jailed"` // has the validator been jailed from bonded status?
|
Jailed bool `json:"jailed"` // has the validator been jailed from bonded status?
|
||||||
|
|
||||||
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
|
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
|
||||||
Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation)
|
Tokens sdk.Int `json:"tokens"` // delegated tokens (incl. self-delegation)
|
||||||
DelegatorShares sdk.Dec `json:"delegator_shares"` // total shares issued to a validator's delegators
|
DelegatorShares sdk.Dec `json:"delegator_shares"` // total shares issued to a validator's delegators
|
||||||
|
|
||||||
Description Description `json:"description"` // description terms for the validator
|
Description Description `json:"description"` // description terms for the validator
|
||||||
|
@ -302,7 +302,7 @@ func (d Description) EnsureLength() (Description, sdk.Error) {
|
||||||
func (v Validator) ABCIValidatorUpdate() abci.ValidatorUpdate {
|
func (v Validator) ABCIValidatorUpdate() abci.ValidatorUpdate {
|
||||||
return abci.ValidatorUpdate{
|
return abci.ValidatorUpdate{
|
||||||
PubKey: tmtypes.TM2PB.PubKey(v.ConsPubKey),
|
PubKey: tmtypes.TM2PB.PubKey(v.ConsPubKey),
|
||||||
Power: v.BondedTokens().RoundInt64(),
|
Power: v.BondedTokens().Int64(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ func (v Validator) UpdateStatus(pool Pool, NewStatus sdk.BondStatus) (Validator,
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes tokens from a validator
|
// removes tokens from a validator
|
||||||
func (v Validator) RemoveTokens(pool Pool, tokens sdk.Dec) (Validator, Pool) {
|
func (v Validator) RemoveTokens(pool Pool, tokens sdk.Int) (Validator, Pool) {
|
||||||
if tokens.IsNegative() {
|
if tokens.IsNegative() {
|
||||||
panic(fmt.Sprintf("should not happen: trying to remove negative tokens %v", tokens))
|
panic(fmt.Sprintf("should not happen: trying to remove negative tokens %v", tokens))
|
||||||
}
|
}
|
||||||
|
@ -383,29 +383,50 @@ func (v Validator) AddTokensFromDel(pool Pool, amount sdk.Int) (Validator, Pool,
|
||||||
|
|
||||||
// bondedShare/delegatedShare
|
// bondedShare/delegatedShare
|
||||||
exRate := v.DelegatorShareExRate()
|
exRate := v.DelegatorShareExRate()
|
||||||
amountDec := sdk.NewDecFromInt(amount)
|
|
||||||
|
|
||||||
if v.Status == sdk.Bonded {
|
|
||||||
pool = pool.looseTokensToBonded(amountDec)
|
|
||||||
}
|
|
||||||
|
|
||||||
if exRate.IsZero() {
|
if exRate.IsZero() {
|
||||||
panic("zero exRate should not happen")
|
panic("zero exRate should not happen")
|
||||||
}
|
}
|
||||||
v.Tokens = v.Tokens.Add(amountDec)
|
|
||||||
issuedShares := amountDec.Quo(exRate)
|
if v.Status == sdk.Bonded {
|
||||||
|
pool = pool.looseTokensToBonded(amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
v.Tokens = v.Tokens.Add(amount)
|
||||||
|
issuedShares := sdk.NewDecFromInt(amount).Quo(exRate)
|
||||||
v.DelegatorShares = v.DelegatorShares.Add(issuedShares)
|
v.DelegatorShares = v.DelegatorShares.Add(issuedShares)
|
||||||
|
|
||||||
return v, pool, issuedShares
|
return v, pool, issuedShares
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveDelShares removes delegator shares from a validator.
|
// RemoveDelShares removes delegator shares from a validator.
|
||||||
func (v Validator) RemoveDelShares(pool Pool, delShares sdk.Dec) (Validator, Pool, sdk.Dec) {
|
// NOTE: because token fractions are left in the valiadator,
|
||||||
delTokens := v.DelegatorShareExRate().Mul(delShares)
|
// the exchange rate of future shares of this validator can increase.
|
||||||
delTokens = sdk.MinDec(delTokens, v.Tokens)
|
func (v Validator) RemoveDelShares(pool Pool, delShares sdk.Dec) (Validator, Pool, sdk.Int) {
|
||||||
v, pool = v.RemoveTokens(pool, delTokens)
|
|
||||||
v.DelegatorShares = v.DelegatorShares.Sub(delShares)
|
remainingShares := v.DelegatorShares.Sub(delShares)
|
||||||
return v, pool, delTokens
|
var issuedTokens sdk.Int
|
||||||
|
if remainingShares.IsZero() {
|
||||||
|
|
||||||
|
// last delegation share gets any trimmings
|
||||||
|
issuedTokens = v.Tokens
|
||||||
|
v.Tokens = sdk.ZeroInt()
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// leave excess tokens in the validator
|
||||||
|
// however fully use all the delegator shares
|
||||||
|
issuedTokens = v.DelegatorShareExRate().Mul(delShares).TruncateInt()
|
||||||
|
v.Tokens = v.Tokens.Sub(issuedTokens)
|
||||||
|
if v.Tokens.IsNegative() {
|
||||||
|
panic("attempting to remove more tokens than available in validator")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v.DelegatorShares = remainingShares
|
||||||
|
if v.Status == sdk.Bonded {
|
||||||
|
pool = pool.bondedTokensToLoose(issuedTokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v, pool, issuedTokens
|
||||||
}
|
}
|
||||||
|
|
||||||
// DelegatorShareExRate gets the exchange rate of tokens over delegator shares.
|
// DelegatorShareExRate gets the exchange rate of tokens over delegator shares.
|
||||||
|
@ -414,15 +435,15 @@ func (v Validator) DelegatorShareExRate() sdk.Dec {
|
||||||
if v.DelegatorShares.IsZero() {
|
if v.DelegatorShares.IsZero() {
|
||||||
return sdk.OneDec()
|
return sdk.OneDec()
|
||||||
}
|
}
|
||||||
return v.Tokens.Quo(v.DelegatorShares)
|
return sdk.NewDecFromInt(v.Tokens).Quo(v.DelegatorShares)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the bonded tokens which the validator holds
|
// Get the bonded tokens which the validator holds
|
||||||
func (v Validator) BondedTokens() sdk.Dec {
|
func (v Validator) BondedTokens() sdk.Int {
|
||||||
if v.Status == sdk.Bonded {
|
if v.Status == sdk.Bonded {
|
||||||
return v.Tokens
|
return v.Tokens
|
||||||
}
|
}
|
||||||
return sdk.ZeroDec()
|
return sdk.ZeroInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
//______________________________________________________________________
|
//______________________________________________________________________
|
||||||
|
@ -437,8 +458,8 @@ func (v Validator) GetStatus() sdk.BondStatus { return v.Status }
|
||||||
func (v Validator) GetOperator() sdk.ValAddress { return v.OperatorAddr }
|
func (v Validator) GetOperator() sdk.ValAddress { return v.OperatorAddr }
|
||||||
func (v Validator) GetConsPubKey() crypto.PubKey { return v.ConsPubKey }
|
func (v Validator) GetConsPubKey() crypto.PubKey { return v.ConsPubKey }
|
||||||
func (v Validator) GetConsAddr() sdk.ConsAddress { return sdk.ConsAddress(v.ConsPubKey.Address()) }
|
func (v Validator) GetConsAddr() sdk.ConsAddress { return sdk.ConsAddress(v.ConsPubKey.Address()) }
|
||||||
func (v Validator) GetPower() sdk.Dec { return v.BondedTokens() }
|
func (v Validator) GetPower() sdk.Int { return v.BondedTokens() }
|
||||||
func (v Validator) GetTokens() sdk.Dec { return v.Tokens }
|
func (v Validator) GetTokens() sdk.Int { return v.Tokens }
|
||||||
func (v Validator) GetCommission() sdk.Dec { return v.Commission.Rate }
|
func (v Validator) GetCommission() sdk.Dec { return v.Commission.Rate }
|
||||||
func (v Validator) GetDelegatorShares() sdk.Dec { return v.DelegatorShares }
|
func (v Validator) GetDelegatorShares() sdk.Dec { return v.DelegatorShares }
|
||||||
func (v Validator) GetBondHeight() int64 { return v.BondHeight }
|
func (v Validator) GetBondHeight() int64 { return v.BondHeight }
|
||||||
|
|
|
@ -59,7 +59,7 @@ func TestABCIValidatorUpdate(t *testing.T) {
|
||||||
|
|
||||||
abciVal := validator.ABCIValidatorUpdate()
|
abciVal := validator.ABCIValidatorUpdate()
|
||||||
require.Equal(t, tmtypes.TM2PB.PubKey(validator.ConsPubKey), abciVal.PubKey)
|
require.Equal(t, tmtypes.TM2PB.PubKey(validator.ConsPubKey), abciVal.PubKey)
|
||||||
require.Equal(t, validator.BondedTokens().RoundInt64(), abciVal.Power)
|
require.Equal(t, validator.BondedTokens().Int64(), abciVal.Power)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestABCIValidatorUpdateZero(t *testing.T) {
|
func TestABCIValidatorUpdateZero(t *testing.T) {
|
||||||
|
@ -76,38 +76,38 @@ func TestRemoveTokens(t *testing.T) {
|
||||||
OperatorAddr: addr1,
|
OperatorAddr: addr1,
|
||||||
ConsPubKey: pk1,
|
ConsPubKey: pk1,
|
||||||
Status: sdk.Bonded,
|
Status: sdk.Bonded,
|
||||||
Tokens: sdk.NewDec(100),
|
Tokens: sdk.NewInt(100),
|
||||||
DelegatorShares: sdk.NewDec(100),
|
DelegatorShares: sdk.NewDec(100),
|
||||||
}
|
}
|
||||||
|
|
||||||
pool := InitialPool()
|
pool := InitialPool()
|
||||||
pool.LooseTokens = sdk.NewDec(10)
|
pool.LooseTokens = sdk.NewInt(10)
|
||||||
pool.BondedTokens = validator.BondedTokens()
|
pool.BondedTokens = validator.BondedTokens()
|
||||||
|
|
||||||
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
|
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
|
|
||||||
// remove tokens and test check everything
|
// remove tokens and test check everything
|
||||||
validator, pool = validator.RemoveTokens(pool, sdk.NewDec(10))
|
validator, pool = validator.RemoveTokens(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(90), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(90), validator.Tokens.Int64())
|
||||||
require.Equal(t, int64(90), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(90), pool.BondedTokens.Int64())
|
||||||
require.Equal(t, int64(20), pool.LooseTokens.RoundInt64())
|
require.Equal(t, int64(20), pool.LooseTokens.Int64())
|
||||||
|
|
||||||
// update validator to unbonded and remove some more tokens
|
// update validator to unbonded and remove some more tokens
|
||||||
validator, pool = validator.UpdateStatus(pool, sdk.Unbonded)
|
validator, pool = validator.UpdateStatus(pool, sdk.Unbonded)
|
||||||
require.Equal(t, sdk.Unbonded, validator.Status)
|
require.Equal(t, sdk.Unbonded, validator.Status)
|
||||||
require.Equal(t, int64(0), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(0), pool.BondedTokens.Int64())
|
||||||
require.Equal(t, int64(110), pool.LooseTokens.RoundInt64())
|
require.Equal(t, int64(110), pool.LooseTokens.Int64())
|
||||||
|
|
||||||
validator, pool = validator.RemoveTokens(pool, sdk.NewDec(10))
|
validator, pool = validator.RemoveTokens(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(80), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(80), validator.Tokens.Int64())
|
||||||
require.Equal(t, int64(0), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(0), pool.BondedTokens.Int64())
|
||||||
require.Equal(t, int64(110), pool.LooseTokens.RoundInt64())
|
require.Equal(t, int64(110), pool.LooseTokens.Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddTokensValidatorBonded(t *testing.T) {
|
func TestAddTokensValidatorBonded(t *testing.T) {
|
||||||
pool := InitialPool()
|
pool := InitialPool()
|
||||||
pool.LooseTokens = sdk.NewDec(10)
|
pool.LooseTokens = sdk.NewInt(10)
|
||||||
validator := NewValidator(addr1, pk1, Description{})
|
validator := NewValidator(addr1, pk1, Description{})
|
||||||
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
|
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
|
||||||
validator, pool, delShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, delShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
|
@ -115,12 +115,12 @@ func TestAddTokensValidatorBonded(t *testing.T) {
|
||||||
require.Equal(t, sdk.OneDec(), validator.DelegatorShareExRate())
|
require.Equal(t, sdk.OneDec(), validator.DelegatorShareExRate())
|
||||||
|
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), delShares))
|
assert.True(sdk.DecEq(t, sdk.NewDec(10), delShares))
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.BondedTokens()))
|
assert.True(sdk.IntEq(t, sdk.NewInt(10), validator.BondedTokens()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddTokensValidatorUnbonding(t *testing.T) {
|
func TestAddTokensValidatorUnbonding(t *testing.T) {
|
||||||
pool := InitialPool()
|
pool := InitialPool()
|
||||||
pool.LooseTokens = sdk.NewDec(10)
|
pool.LooseTokens = sdk.NewInt(10)
|
||||||
validator := NewValidator(addr1, pk1, Description{})
|
validator := NewValidator(addr1, pk1, Description{})
|
||||||
validator, pool = validator.UpdateStatus(pool, sdk.Unbonding)
|
validator, pool = validator.UpdateStatus(pool, sdk.Unbonding)
|
||||||
validator, pool, delShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, delShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
|
@ -129,12 +129,12 @@ func TestAddTokensValidatorUnbonding(t *testing.T) {
|
||||||
|
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), delShares))
|
assert.True(sdk.DecEq(t, sdk.NewDec(10), delShares))
|
||||||
assert.Equal(t, sdk.Unbonding, validator.Status)
|
assert.Equal(t, sdk.Unbonding, validator.Status)
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(10), validator.Tokens))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddTokensValidatorUnbonded(t *testing.T) {
|
func TestAddTokensValidatorUnbonded(t *testing.T) {
|
||||||
pool := InitialPool()
|
pool := InitialPool()
|
||||||
pool.LooseTokens = sdk.NewDec(10)
|
pool.LooseTokens = sdk.NewInt(10)
|
||||||
validator := NewValidator(addr1, pk1, Description{})
|
validator := NewValidator(addr1, pk1, Description{})
|
||||||
validator, pool = validator.UpdateStatus(pool, sdk.Unbonded)
|
validator, pool = validator.UpdateStatus(pool, sdk.Unbonded)
|
||||||
validator, pool, delShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, delShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
|
@ -143,7 +143,7 @@ func TestAddTokensValidatorUnbonded(t *testing.T) {
|
||||||
|
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), delShares))
|
assert.True(sdk.DecEq(t, sdk.NewDec(10), delShares))
|
||||||
assert.Equal(t, sdk.Unbonded, validator.Status)
|
assert.Equal(t, sdk.Unbonded, validator.Status)
|
||||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens))
|
assert.True(sdk.IntEq(t, sdk.NewInt(10), validator.Tokens))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO refactor to make simpler like the AddToken tests above
|
// TODO refactor to make simpler like the AddToken tests above
|
||||||
|
@ -152,29 +152,29 @@ func TestRemoveDelShares(t *testing.T) {
|
||||||
OperatorAddr: addr1,
|
OperatorAddr: addr1,
|
||||||
ConsPubKey: pk1,
|
ConsPubKey: pk1,
|
||||||
Status: sdk.Bonded,
|
Status: sdk.Bonded,
|
||||||
Tokens: sdk.NewDec(100),
|
Tokens: sdk.NewInt(100),
|
||||||
DelegatorShares: sdk.NewDec(100),
|
DelegatorShares: sdk.NewDec(100),
|
||||||
}
|
}
|
||||||
poolA := InitialPool()
|
poolA := InitialPool()
|
||||||
poolA.LooseTokens = sdk.NewDec(10)
|
poolA.LooseTokens = sdk.NewInt(10)
|
||||||
poolA.BondedTokens = valA.BondedTokens()
|
poolA.BondedTokens = valA.BondedTokens()
|
||||||
require.Equal(t, valA.DelegatorShareExRate(), sdk.OneDec())
|
require.Equal(t, valA.DelegatorShareExRate(), sdk.OneDec())
|
||||||
|
|
||||||
// Remove delegator shares
|
// Remove delegator shares
|
||||||
valB, poolB, coinsB := valA.RemoveDelShares(poolA, sdk.NewDec(10))
|
valB, poolB, coinsB := valA.RemoveDelShares(poolA, sdk.NewDec(10))
|
||||||
assert.Equal(t, int64(10), coinsB.RoundInt64())
|
require.Equal(t, int64(10), coinsB.Int64())
|
||||||
assert.Equal(t, int64(90), valB.DelegatorShares.RoundInt64())
|
require.Equal(t, int64(90), valB.DelegatorShares.RoundInt64())
|
||||||
assert.Equal(t, int64(90), valB.BondedTokens().RoundInt64())
|
require.Equal(t, int64(90), valB.BondedTokens().Int64())
|
||||||
assert.Equal(t, int64(90), poolB.BondedTokens.RoundInt64())
|
require.Equal(t, int64(90), poolB.BondedTokens.Int64())
|
||||||
assert.Equal(t, int64(20), poolB.LooseTokens.RoundInt64())
|
require.Equal(t, int64(20), poolB.LooseTokens.Int64())
|
||||||
|
|
||||||
// conservation of tokens
|
// conservation of tokens
|
||||||
require.True(sdk.DecEq(t,
|
require.True(sdk.IntEq(t,
|
||||||
poolB.LooseTokens.Add(poolB.BondedTokens),
|
poolB.LooseTokens.Add(poolB.BondedTokens),
|
||||||
poolA.LooseTokens.Add(poolA.BondedTokens)))
|
poolA.LooseTokens.Add(poolA.BondedTokens)))
|
||||||
|
|
||||||
// specific case from random tests
|
// specific case from random tests
|
||||||
poolTokens := sdk.NewDec(5102)
|
poolTokens := sdk.NewInt(5102)
|
||||||
delShares := sdk.NewDec(115)
|
delShares := sdk.NewDec(115)
|
||||||
validator := Validator{
|
validator := Validator{
|
||||||
OperatorAddr: addr1,
|
OperatorAddr: addr1,
|
||||||
|
@ -184,48 +184,45 @@ func TestRemoveDelShares(t *testing.T) {
|
||||||
DelegatorShares: delShares,
|
DelegatorShares: delShares,
|
||||||
}
|
}
|
||||||
pool := Pool{
|
pool := Pool{
|
||||||
BondedTokens: sdk.NewDec(248305),
|
BondedTokens: sdk.NewInt(248305),
|
||||||
LooseTokens: sdk.NewDec(232147),
|
LooseTokens: sdk.NewInt(232147),
|
||||||
}
|
}
|
||||||
shares := sdk.NewDec(29)
|
shares := sdk.NewDec(29)
|
||||||
_, newPool, tokens := validator.RemoveDelShares(pool, shares)
|
_, newPool, tokens := validator.RemoveDelShares(pool, shares)
|
||||||
|
|
||||||
exp, err := sdk.NewDecFromStr("1286.5913043477")
|
require.True(sdk.IntEq(t, sdk.NewInt(1286), tokens))
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.True(sdk.DecEq(t, exp, tokens))
|
require.True(sdk.IntEq(t,
|
||||||
|
|
||||||
require.True(sdk.DecEq(t,
|
|
||||||
newPool.LooseTokens.Add(newPool.BondedTokens),
|
newPool.LooseTokens.Add(newPool.BondedTokens),
|
||||||
pool.LooseTokens.Add(pool.BondedTokens)))
|
pool.LooseTokens.Add(pool.BondedTokens)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateStatus(t *testing.T) {
|
func TestUpdateStatus(t *testing.T) {
|
||||||
pool := InitialPool()
|
pool := InitialPool()
|
||||||
pool.LooseTokens = sdk.NewDec(100)
|
pool.LooseTokens = sdk.NewInt(100)
|
||||||
|
|
||||||
validator := NewValidator(addr1, pk1, Description{})
|
validator := NewValidator(addr1, pk1, Description{})
|
||||||
validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(100))
|
validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(100))
|
||||||
require.Equal(t, sdk.Unbonded, validator.Status)
|
require.Equal(t, sdk.Unbonded, validator.Status)
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(100), validator.Tokens.Int64())
|
||||||
require.Equal(t, int64(0), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(0), pool.BondedTokens.Int64())
|
||||||
require.Equal(t, int64(100), pool.LooseTokens.RoundInt64())
|
require.Equal(t, int64(100), pool.LooseTokens.Int64())
|
||||||
|
|
||||||
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
|
validator, pool = validator.UpdateStatus(pool, sdk.Bonded)
|
||||||
require.Equal(t, sdk.Bonded, validator.Status)
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(100), validator.Tokens.Int64())
|
||||||
require.Equal(t, int64(100), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(100), pool.BondedTokens.Int64())
|
||||||
require.Equal(t, int64(0), pool.LooseTokens.RoundInt64())
|
require.Equal(t, int64(0), pool.LooseTokens.Int64())
|
||||||
|
|
||||||
validator, pool = validator.UpdateStatus(pool, sdk.Unbonding)
|
validator, pool = validator.UpdateStatus(pool, sdk.Unbonding)
|
||||||
require.Equal(t, sdk.Unbonding, validator.Status)
|
require.Equal(t, sdk.Unbonding, validator.Status)
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(100), validator.Tokens.Int64())
|
||||||
require.Equal(t, int64(0), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(0), pool.BondedTokens.Int64())
|
||||||
require.Equal(t, int64(100), pool.LooseTokens.RoundInt64())
|
require.Equal(t, int64(100), pool.LooseTokens.Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPossibleOverflow(t *testing.T) {
|
func TestPossibleOverflow(t *testing.T) {
|
||||||
poolTokens := sdk.NewDec(2159)
|
poolTokens := sdk.NewInt(2159)
|
||||||
delShares := sdk.NewDec(391432570689183511).Quo(sdk.NewDec(40113011844664))
|
delShares := sdk.NewDec(391432570689183511).Quo(sdk.NewDec(40113011844664))
|
||||||
validator := Validator{
|
validator := Validator{
|
||||||
OperatorAddr: addr1,
|
OperatorAddr: addr1,
|
||||||
|
@ -235,7 +232,7 @@ func TestPossibleOverflow(t *testing.T) {
|
||||||
DelegatorShares: delShares,
|
DelegatorShares: delShares,
|
||||||
}
|
}
|
||||||
pool := Pool{
|
pool := Pool{
|
||||||
LooseTokens: sdk.NewDec(100),
|
LooseTokens: sdk.NewInt(100),
|
||||||
BondedTokens: poolTokens,
|
BondedTokens: poolTokens,
|
||||||
}
|
}
|
||||||
tokens := int64(71)
|
tokens := int64(71)
|
||||||
|
|
Loading…
Reference in New Issue