Merge PR #2236: Distr-PR-5 Implement Distribution
This commit is contained in:
commit
2803830c7e
|
@ -16,6 +16,7 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||||
|
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
"github.com/cosmos/cosmos-sdk/x/params"
|
"github.com/cosmos/cosmos-sdk/x/params"
|
||||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||||
|
@ -43,6 +44,8 @@ type GaiaApp struct {
|
||||||
keyStake *sdk.KVStoreKey
|
keyStake *sdk.KVStoreKey
|
||||||
tkeyStake *sdk.TransientStoreKey
|
tkeyStake *sdk.TransientStoreKey
|
||||||
keySlashing *sdk.KVStoreKey
|
keySlashing *sdk.KVStoreKey
|
||||||
|
keyDistr *sdk.KVStoreKey
|
||||||
|
tkeyDistr *sdk.TransientStoreKey
|
||||||
keyGov *sdk.KVStoreKey
|
keyGov *sdk.KVStoreKey
|
||||||
keyFeeCollection *sdk.KVStoreKey
|
keyFeeCollection *sdk.KVStoreKey
|
||||||
keyParams *sdk.KVStoreKey
|
keyParams *sdk.KVStoreKey
|
||||||
|
@ -54,6 +57,7 @@ type GaiaApp struct {
|
||||||
bankKeeper bank.Keeper
|
bankKeeper bank.Keeper
|
||||||
stakeKeeper stake.Keeper
|
stakeKeeper stake.Keeper
|
||||||
slashingKeeper slashing.Keeper
|
slashingKeeper slashing.Keeper
|
||||||
|
distrKeeper distr.Keeper
|
||||||
govKeeper gov.Keeper
|
govKeeper gov.Keeper
|
||||||
paramsKeeper params.Keeper
|
paramsKeeper params.Keeper
|
||||||
}
|
}
|
||||||
|
@ -72,6 +76,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
|
||||||
keyAccount: sdk.NewKVStoreKey("acc"),
|
keyAccount: sdk.NewKVStoreKey("acc"),
|
||||||
keyStake: sdk.NewKVStoreKey("stake"),
|
keyStake: sdk.NewKVStoreKey("stake"),
|
||||||
tkeyStake: sdk.NewTransientStoreKey("transient_stake"),
|
tkeyStake: sdk.NewTransientStoreKey("transient_stake"),
|
||||||
|
keyDistr: sdk.NewKVStoreKey("distr"),
|
||||||
|
tkeyDistr: sdk.NewTransientStoreKey("transient_distr"),
|
||||||
keySlashing: sdk.NewKVStoreKey("slashing"),
|
keySlashing: sdk.NewKVStoreKey("slashing"),
|
||||||
keyGov: sdk.NewKVStoreKey("gov"),
|
keyGov: sdk.NewKVStoreKey("gov"),
|
||||||
keyFeeCollection: sdk.NewKVStoreKey("fee"),
|
keyFeeCollection: sdk.NewKVStoreKey("fee"),
|
||||||
|
@ -88,30 +94,33 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
|
||||||
|
|
||||||
// add handlers
|
// add handlers
|
||||||
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
||||||
|
app.feeCollectionKeeper = auth.NewFeeCollectionKeeper(
|
||||||
|
app.cdc,
|
||||||
|
app.keyFeeCollection,
|
||||||
|
)
|
||||||
app.paramsKeeper = params.NewKeeper(
|
app.paramsKeeper = params.NewKeeper(
|
||||||
app.cdc,
|
app.cdc,
|
||||||
app.keyParams, app.tkeyParams,
|
app.keyParams, app.tkeyParams,
|
||||||
)
|
)
|
||||||
|
|
||||||
app.stakeKeeper = stake.NewKeeper(
|
app.stakeKeeper = stake.NewKeeper(
|
||||||
app.cdc,
|
app.cdc,
|
||||||
app.keyStake, app.tkeyStake,
|
app.keyStake, app.tkeyStake,
|
||||||
app.bankKeeper, app.paramsKeeper.Subspace(stake.DefaultParamspace),
|
app.bankKeeper, app.paramsKeeper.Subspace(stake.DefaultParamspace),
|
||||||
app.RegisterCodespace(stake.DefaultCodespace),
|
app.RegisterCodespace(stake.DefaultCodespace),
|
||||||
)
|
)
|
||||||
|
app.distrKeeper = distr.NewKeeper(
|
||||||
|
app.cdc,
|
||||||
|
app.keyDistr,
|
||||||
|
app.paramsKeeper.Subspace(distr.DefaultParamspace),
|
||||||
|
app.bankKeeper, app.stakeKeeper, app.feeCollectionKeeper,
|
||||||
|
app.RegisterCodespace(stake.DefaultCodespace),
|
||||||
|
)
|
||||||
app.slashingKeeper = slashing.NewKeeper(
|
app.slashingKeeper = slashing.NewKeeper(
|
||||||
app.cdc,
|
app.cdc,
|
||||||
app.keySlashing,
|
app.keySlashing,
|
||||||
app.stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace),
|
app.stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace),
|
||||||
app.RegisterCodespace(slashing.DefaultCodespace),
|
app.RegisterCodespace(slashing.DefaultCodespace),
|
||||||
)
|
)
|
||||||
|
|
||||||
app.stakeKeeper = app.stakeKeeper.WithHooks(
|
|
||||||
app.slashingKeeper.Hooks(),
|
|
||||||
)
|
|
||||||
|
|
||||||
app.govKeeper = gov.NewKeeper(
|
app.govKeeper = gov.NewKeeper(
|
||||||
app.cdc,
|
app.cdc,
|
||||||
app.keyGov,
|
app.keyGov,
|
||||||
|
@ -119,15 +128,15 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
|
||||||
app.RegisterCodespace(gov.DefaultCodespace),
|
app.RegisterCodespace(gov.DefaultCodespace),
|
||||||
)
|
)
|
||||||
|
|
||||||
app.feeCollectionKeeper = auth.NewFeeCollectionKeeper(
|
// register the staking hooks
|
||||||
app.cdc,
|
app.stakeKeeper = app.stakeKeeper.WithHooks(
|
||||||
app.keyFeeCollection,
|
NewHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks()))
|
||||||
)
|
|
||||||
|
|
||||||
// register message routes
|
// register message routes
|
||||||
app.Router().
|
app.Router().
|
||||||
AddRoute("bank", bank.NewHandler(app.bankKeeper)).
|
AddRoute("bank", bank.NewHandler(app.bankKeeper)).
|
||||||
AddRoute("stake", stake.NewHandler(app.stakeKeeper)).
|
AddRoute("stake", stake.NewHandler(app.stakeKeeper)).
|
||||||
|
AddRoute("distr", distr.NewHandler(app.distrKeeper)).
|
||||||
AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)).
|
AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)).
|
||||||
AddRoute("gov", gov.NewHandler(app.govKeeper))
|
AddRoute("gov", gov.NewHandler(app.govKeeper))
|
||||||
|
|
||||||
|
@ -138,11 +147,12 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
|
||||||
// initialize BaseApp
|
// initialize BaseApp
|
||||||
app.SetInitChainer(app.initChainer)
|
app.SetInitChainer(app.initChainer)
|
||||||
app.SetBeginBlocker(app.BeginBlocker)
|
app.SetBeginBlocker(app.BeginBlocker)
|
||||||
app.SetEndBlocker(app.EndBlocker)
|
|
||||||
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper))
|
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper))
|
||||||
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyStake,
|
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyStake, app.keyDistr,
|
||||||
app.keySlashing, app.keyGov, app.keyFeeCollection, app.keyParams)
|
app.keySlashing, app.keyGov, app.keyFeeCollection, app.keyParams)
|
||||||
app.MountStoresTransient(app.tkeyParams, app.tkeyStake)
|
app.MountStoresTransient(app.tkeyParams, app.tkeyStake, app.tkeyDistr)
|
||||||
|
app.SetEndBlocker(app.EndBlocker)
|
||||||
|
|
||||||
err := app.LoadLatestVersion(app.keyMain)
|
err := app.LoadLatestVersion(app.keyMain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmn.Exit(err.Error())
|
cmn.Exit(err.Error())
|
||||||
|
@ -156,6 +166,7 @@ func MakeCodec() *codec.Codec {
|
||||||
var cdc = codec.New()
|
var cdc = codec.New()
|
||||||
bank.RegisterCodec(cdc)
|
bank.RegisterCodec(cdc)
|
||||||
stake.RegisterCodec(cdc)
|
stake.RegisterCodec(cdc)
|
||||||
|
distr.RegisterCodec(cdc)
|
||||||
slashing.RegisterCodec(cdc)
|
slashing.RegisterCodec(cdc)
|
||||||
gov.RegisterCodec(cdc)
|
gov.RegisterCodec(cdc)
|
||||||
auth.RegisterCodec(cdc)
|
auth.RegisterCodec(cdc)
|
||||||
|
@ -168,6 +179,9 @@ func MakeCodec() *codec.Codec {
|
||||||
func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
|
func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
|
||||||
tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper)
|
tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper)
|
||||||
|
|
||||||
|
// distribute rewards from previous block
|
||||||
|
distr.BeginBlocker(ctx, req, app.distrKeeper)
|
||||||
|
|
||||||
return abci.ResponseBeginBlock{
|
return abci.ResponseBeginBlock{
|
||||||
Tags: tags.ToKVPairs(),
|
Tags: tags.ToKVPairs(),
|
||||||
}
|
}
|
||||||
|
@ -176,10 +190,13 @@ func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) ab
|
||||||
// application updates every end block
|
// application updates every end block
|
||||||
// nolint: unparam
|
// nolint: unparam
|
||||||
func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||||
|
|
||||||
tags := gov.EndBlocker(ctx, app.govKeeper)
|
tags := gov.EndBlocker(ctx, app.govKeeper)
|
||||||
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
|
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
|
||||||
|
|
||||||
// Add these new validators to the addr -> pubkey map.
|
// Add these new validators to the addr -> pubkey map.
|
||||||
app.slashingKeeper.AddValidators(ctx, validatorUpdates)
|
app.slashingKeeper.AddValidators(ctx, validatorUpdates)
|
||||||
|
|
||||||
return abci.ResponseEndBlock{
|
return abci.ResponseEndBlock{
|
||||||
ValidatorUpdates: validatorUpdates,
|
ValidatorUpdates: validatorUpdates,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
|
@ -208,18 +225,17 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||||
// load the initial stake information
|
// load the initial stake information
|
||||||
validators, err := stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
|
validators, err := stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
|
panic(err) // TODO find a way to do this w/o panics
|
||||||
// return sdk.ErrGenesisParse("").TraceCause(err, "")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the address to pubkey map
|
// load the address to pubkey map
|
||||||
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
|
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
|
||||||
|
|
||||||
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
||||||
|
distr.InitGenesis(ctx, app.distrKeeper, genesisState.DistrData)
|
||||||
err = GaiaValidateGenesisState(genesisState)
|
err = GaiaValidateGenesisState(genesisState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO find a way to do this w/o panics
|
panic(err) // TODO find a way to do this w/o panics
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return abci.ResponseInitChain{
|
return abci.ResponseInitChain{
|
||||||
|
@ -243,6 +259,7 @@ func (app *GaiaApp) ExportAppStateAndValidators() (appState json.RawMessage, val
|
||||||
genState := GenesisState{
|
genState := GenesisState{
|
||||||
Accounts: accounts,
|
Accounts: accounts,
|
||||||
StakeData: stake.WriteGenesis(ctx, app.stakeKeeper),
|
StakeData: stake.WriteGenesis(ctx, app.stakeKeeper),
|
||||||
|
DistrData: distr.WriteGenesis(ctx, app.distrKeeper),
|
||||||
GovData: gov.WriteGenesis(ctx, app.govKeeper),
|
GovData: gov.WriteGenesis(ctx, app.govKeeper),
|
||||||
}
|
}
|
||||||
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
|
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
|
||||||
|
@ -252,3 +269,43 @@ func (app *GaiaApp) ExportAppStateAndValidators() (appState json.RawMessage, val
|
||||||
validators = stake.WriteValidators(ctx, app.stakeKeeper)
|
validators = stake.WriteValidators(ctx, app.stakeKeeper)
|
||||||
return appState, validators, nil
|
return appState, validators, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//______________________________________________________________________________________________
|
||||||
|
|
||||||
|
// Combined Staking Hooks
|
||||||
|
type Hooks struct {
|
||||||
|
dh distr.Hooks
|
||||||
|
sh slashing.Hooks
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHooks(dh distr.Hooks, sh slashing.Hooks) Hooks {
|
||||||
|
return Hooks{dh, sh}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ sdk.StakingHooks = Hooks{}
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func (h Hooks) OnValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
h.dh.OnValidatorCreated(ctx, addr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnValidatorCommissionChange(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
h.dh.OnValidatorCommissionChange(ctx, addr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
h.dh.OnValidatorRemoved(ctx, addr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnValidatorBonded(ctx sdk.Context, addr sdk.ConsAddress) {
|
||||||
|
h.sh.OnValidatorBonded(ctx, addr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, addr sdk.ConsAddress) {
|
||||||
|
h.sh.OnValidatorBeginUnbonding(ctx, addr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
|
h.dh.OnDelegationCreated(ctx, delAddr, valAddr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
|
h.dh.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
|
h.dh.OnDelegationRemoved(ctx, delAddr, valAddr)
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -24,6 +25,7 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error {
|
||||||
genesisState := GenesisState{
|
genesisState := GenesisState{
|
||||||
Accounts: genaccs,
|
Accounts: genaccs,
|
||||||
StakeData: stake.DefaultGenesisState(),
|
StakeData: stake.DefaultGenesisState(),
|
||||||
|
DistrData: distr.DefaultGenesisState(),
|
||||||
SlashingData: slashing.DefaultGenesisState(),
|
SlashingData: slashing.DefaultGenesisState(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/server/config"
|
"github.com/cosmos/cosmos-sdk/server/config"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
@ -34,6 +35,7 @@ var (
|
||||||
type GenesisState struct {
|
type GenesisState struct {
|
||||||
Accounts []GenesisAccount `json:"accounts"`
|
Accounts []GenesisAccount `json:"accounts"`
|
||||||
StakeData stake.GenesisState `json:"stake"`
|
StakeData stake.GenesisState `json:"stake"`
|
||||||
|
DistrData distr.GenesisState `json:"distr"`
|
||||||
GovData gov.GenesisState `json:"gov"`
|
GovData gov.GenesisState `json:"gov"`
|
||||||
SlashingData slashing.GenesisState `json:"slashing"`
|
SlashingData slashing.GenesisState `json:"slashing"`
|
||||||
}
|
}
|
||||||
|
@ -196,6 +198,7 @@ func GaiaAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (genesisStat
|
||||||
genesisState = GenesisState{
|
genesisState = GenesisState{
|
||||||
Accounts: genaccs,
|
Accounts: genaccs,
|
||||||
StakeData: stakeData,
|
StakeData: stakeData,
|
||||||
|
DistrData: distr.DefaultGenesisState(),
|
||||||
GovData: gov.DefaultGenesisState(),
|
GovData: gov.DefaultGenesisState(),
|
||||||
SlashingData: slashingData,
|
SlashingData: slashingData,
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation"
|
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation"
|
||||||
|
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
|
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
|
||||||
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
|
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
|
||||||
|
@ -60,13 +61,18 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
||||||
slashingGenesis := slashing.DefaultGenesisState()
|
slashingGenesis := slashing.DefaultGenesisState()
|
||||||
var validators []stake.Validator
|
var validators []stake.Validator
|
||||||
var delegations []stake.Delegation
|
var delegations []stake.Delegation
|
||||||
|
|
||||||
// XXX Try different numbers of initially bonded validators
|
// XXX Try different numbers of initially bonded validators
|
||||||
numInitiallyBonded := int64(50)
|
numInitiallyBonded := int64(50)
|
||||||
|
valAddrs := make([]sdk.ValAddress, numInitiallyBonded)
|
||||||
for i := 0; i < int(numInitiallyBonded); i++ {
|
for i := 0; i < int(numInitiallyBonded); i++ {
|
||||||
validator := stake.NewValidator(sdk.ValAddress(accs[i].Address), accs[i].PubKey, stake.Description{})
|
valAddr := sdk.ValAddress(accs[i].Address)
|
||||||
|
valAddrs[i] = valAddr
|
||||||
|
|
||||||
|
validator := stake.NewValidator(valAddr, accs[i].PubKey, stake.Description{})
|
||||||
validator.Tokens = sdk.NewDec(100)
|
validator.Tokens = sdk.NewDec(100)
|
||||||
validator.DelegatorShares = sdk.NewDec(100)
|
validator.DelegatorShares = sdk.NewDec(100)
|
||||||
delegation := stake.Delegation{accs[i].Address, sdk.ValAddress(accs[i].Address), sdk.NewDec(100), 0}
|
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(100), 0}
|
||||||
validators = append(validators, validator)
|
validators = append(validators, validator)
|
||||||
delegations = append(delegations, delegation)
|
delegations = append(delegations, delegation)
|
||||||
}
|
}
|
||||||
|
@ -76,9 +82,11 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
||||||
// No inflation, for now
|
// No inflation, for now
|
||||||
stakeGenesis.Params.InflationMax = sdk.NewDec(0)
|
stakeGenesis.Params.InflationMax = sdk.NewDec(0)
|
||||||
stakeGenesis.Params.InflationMin = sdk.NewDec(0)
|
stakeGenesis.Params.InflationMin = sdk.NewDec(0)
|
||||||
|
|
||||||
genesis := GenesisState{
|
genesis := GenesisState{
|
||||||
Accounts: genesisAccounts,
|
Accounts: genesisAccounts,
|
||||||
StakeData: stakeGenesis,
|
StakeData: stakeGenesis,
|
||||||
|
DistrData: distr.DefaultGenesisWithValidators(valAddrs),
|
||||||
SlashingData: slashingGenesis,
|
SlashingData: slashingGenesis,
|
||||||
GovData: govGenesis,
|
GovData: govGenesis,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
@ -72,6 +73,7 @@ func NewTestGaiaAppGenState(
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
Accounts: genAccs,
|
Accounts: genAccs,
|
||||||
StakeData: stakeData,
|
StakeData: stakeData,
|
||||||
|
DistrData: distr.DefaultGenesisState(),
|
||||||
SlashingData: slashing.DefaultGenesisState(),
|
SlashingData: slashing.DefaultGenesisState(),
|
||||||
GovData: gov.DefaultGenesisState(),
|
GovData: gov.DefaultGenesisState(),
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/libs/cli"
|
"github.com/tendermint/tendermint/libs/cli"
|
||||||
|
|
||||||
|
@ -10,18 +14,17 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/client/lcd"
|
"github.com/cosmos/cosmos-sdk/client/lcd"
|
||||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||||
|
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||||
"github.com/cosmos/cosmos-sdk/version"
|
"github.com/cosmos/cosmos-sdk/version"
|
||||||
|
|
||||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||||
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
|
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
|
||||||
|
distrcmd "github.com/cosmos/cosmos-sdk/x/distribution/client/cli"
|
||||||
govcmd "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
|
govcmd "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
|
||||||
slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
|
slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
|
||||||
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli"
|
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli"
|
||||||
|
|
||||||
_ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
|
_ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
|
||||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -101,11 +104,13 @@ func main() {
|
||||||
stakecmd.GetCmdCreateValidator(cdc),
|
stakecmd.GetCmdCreateValidator(cdc),
|
||||||
stakecmd.GetCmdEditValidator(cdc),
|
stakecmd.GetCmdEditValidator(cdc),
|
||||||
stakecmd.GetCmdDelegate(cdc),
|
stakecmd.GetCmdDelegate(cdc),
|
||||||
govcmd.GetCmdDeposit(cdc),
|
|
||||||
stakecmd.GetCmdRedelegate(storeStake, cdc),
|
stakecmd.GetCmdRedelegate(storeStake, cdc),
|
||||||
|
stakecmd.GetCmdUnbond(storeStake, cdc),
|
||||||
|
distrcmd.GetCmdWithdrawRewards(cdc),
|
||||||
|
distrcmd.GetCmdSetWithdrawAddr(cdc),
|
||||||
|
govcmd.GetCmdDeposit(cdc),
|
||||||
bankcmd.SendTxCmd(cdc),
|
bankcmd.SendTxCmd(cdc),
|
||||||
govcmd.GetCmdSubmitProposal(cdc),
|
govcmd.GetCmdSubmitProposal(cdc),
|
||||||
stakecmd.GetCmdUnbond(storeStake, cdc),
|
|
||||||
slashingcmd.GetCmdUnjail(cdc),
|
slashingcmd.GetCmdUnjail(cdc),
|
||||||
govcmd.GetCmdVote(cdc),
|
govcmd.GetCmdVote(cdc),
|
||||||
)...)
|
)...)
|
||||||
|
|
|
@ -15,7 +15,7 @@ pool which validator holds individually
|
||||||
(`ValidatorDistribution.ProvisionsRewardPool`).
|
(`ValidatorDistribution.ProvisionsRewardPool`).
|
||||||
|
|
||||||
```
|
```
|
||||||
func AllocateFees(feesCollected sdk.Coins, global Global, proposer ValidatorDistribution,
|
func AllocateFees(feesCollected sdk.Coins, feePool FeePool, proposer ValidatorDistribution,
|
||||||
sumPowerPrecommitValidators, totalBondedTokens, communityTax,
|
sumPowerPrecommitValidators, totalBondedTokens, communityTax,
|
||||||
proposerCommissionRate sdk.Dec)
|
proposerCommissionRate sdk.Dec)
|
||||||
|
|
||||||
|
@ -28,13 +28,11 @@ func AllocateFees(feesCollected sdk.Coins, global Global, proposer ValidatorDist
|
||||||
proposer.Pool += proposerReward - commission
|
proposer.Pool += proposerReward - commission
|
||||||
|
|
||||||
communityFunding = feesCollectedDec * communityTax
|
communityFunding = feesCollectedDec * communityTax
|
||||||
global.CommunityFund += communityFunding
|
feePool.CommunityFund += communityFunding
|
||||||
|
|
||||||
poolReceived = feesCollectedDec - proposerReward - communityFunding
|
poolReceived = feesCollectedDec - proposerReward - communityFunding
|
||||||
global.Pool += poolReceived
|
feePool.Pool += poolReceived
|
||||||
global.EverReceivedPool += poolReceived
|
|
||||||
global.LastReceivedPool = poolReceived
|
|
||||||
|
|
||||||
SetValidatorDistribution(proposer)
|
SetValidatorDistribution(proposer)
|
||||||
SetGlobal(global)
|
SetFeePool(feePool)
|
||||||
```
|
```
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
The pool of a new delegator bond will be 0 for the height at which the bond was
|
The pool of a new delegator bond will be 0 for the height at which the bond was
|
||||||
added, or the withdrawal has taken place. This is achieved by setting
|
added, or the withdrawal has taken place. This is achieved by setting
|
||||||
`DelegatorDistInfo.WithdrawalHeight` to the height of the triggering transaction.
|
`DelegationDistInfo.WithdrawalHeight` to the height of the triggering transaction.
|
||||||
|
|
||||||
## Commission rate change
|
## Commission rate change
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ to independently and lazily withdraw their rewards.
|
||||||
|
|
||||||
As a part of the lazy computations, each delegator holds an accumulation term
|
As a part of the lazy computations, each delegator holds an accumulation term
|
||||||
specific to each validator which is used to estimate what their approximate
|
specific to each validator which is used to estimate what their approximate
|
||||||
fair portion of tokens held in the global pool is owed to them.
|
fair portion of tokens held in the global fee pool is owed to them.
|
||||||
|
|
||||||
```
|
```
|
||||||
entitlement = delegator-accumulation / all-delegators-accumulation
|
entitlement = delegator-accumulation / all-delegators-accumulation
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
## State
|
## State
|
||||||
|
|
||||||
### Global
|
### FeePool
|
||||||
|
|
||||||
All globally tracked parameters for distribution are stored within
|
All globally tracked parameters for distribution are stored within
|
||||||
`Global`. Rewards are collected and added to the reward pool and
|
`FeePool`. Rewards are collected and added to the reward pool and
|
||||||
distributed to validators/delegators from here.
|
distributed to validators/delegators from here.
|
||||||
|
|
||||||
Note that the reward pool holds decimal coins (`DecCoins`) to allow
|
Note that the reward pool holds decimal coins (`DecCoins`) to allow
|
||||||
|
@ -11,7 +11,7 @@ for fractions of coins to be received from operations like inflation.
|
||||||
When coins are distributed from the pool they are truncated back to
|
When coins are distributed from the pool they are truncated back to
|
||||||
`sdk.Coins` which are non-decimal.
|
`sdk.Coins` which are non-decimal.
|
||||||
|
|
||||||
- Global: `0x00 -> amino(global)`
|
- FeePool: `0x00 -> amino(FeePool)`
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
// coins with decimal
|
// coins with decimal
|
||||||
|
@ -22,7 +22,7 @@ type DecCoin struct {
|
||||||
Denom string
|
Denom string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Global struct {
|
type FeePool struct {
|
||||||
TotalValAccumUpdateHeight int64 // last height which the total validator accum was updated
|
TotalValAccumUpdateHeight int64 // last height which the total validator accum was updated
|
||||||
TotalValAccum sdk.Dec // total valdator accum held by validators
|
TotalValAccum sdk.Dec // total valdator accum held by validators
|
||||||
Pool DecCoins // funds for all validators which have yet to be withdrawn
|
Pool DecCoins // funds for all validators which have yet to be withdrawn
|
||||||
|
@ -42,7 +42,7 @@ Validator distribution information for the relevant validator is updated each ti
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
type ValidatorDistInfo struct {
|
type ValidatorDistInfo struct {
|
||||||
GlobalWithdrawalHeight int64 // last height this validator withdrew from the global pool
|
FeePoolWithdrawalHeight int64 // last height this validator withdrew from the global fee pool
|
||||||
Pool DecCoins // rewards owed to delegators, commission has already been charged (includes proposer reward)
|
Pool DecCoins // rewards owed to delegators, commission has already been charged (includes proposer reward)
|
||||||
PoolCommission DecCoins // commission collected by this validator (pending withdrawal)
|
PoolCommission DecCoins // commission collected by this validator (pending withdrawal)
|
||||||
|
|
||||||
|
@ -59,10 +59,10 @@ properties change (aka bonded tokens etc.) its properties will remain constant
|
||||||
and the delegator's _accumulation_ factor can be calculated passively knowing
|
and the delegator's _accumulation_ factor can be calculated passively knowing
|
||||||
only the height of the last withdrawal and its current properties.
|
only the height of the last withdrawal and its current properties.
|
||||||
|
|
||||||
- DelegatorDistInfo: ` 0x02 | DelegatorAddr | ValOperatorAddr -> amino(delegatorDist)`
|
- DelegationDistInfo: ` 0x02 | DelegatorAddr | ValOperatorAddr -> amino(delegatorDist)`
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
type DelegatorDistInfo struct {
|
type DelegationDistInfo struct {
|
||||||
WithdrawalHeight int64 // last time this delegation withdrew rewards
|
WithdrawalHeight int64 // last time this delegation withdrew rewards
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
# Transactions
|
# Transactions
|
||||||
|
|
||||||
## TxWithdrawDelegationRewardsAll
|
## MsgWithdrawDelegationRewardsAll
|
||||||
|
|
||||||
When a delegator wishes to withdraw their rewards it must send
|
When a delegator wishes to withdraw their rewards it must send
|
||||||
`TxWithdrawDelegationRewardsAll`. Note that parts of this transaction logic are also
|
`MsgWithdrawDelegationRewardsAll`. Note that parts of this transaction logic are also
|
||||||
triggered each with any change in individual delegations, such as an unbond,
|
triggered each with any change in individual delegations, such as an unbond,
|
||||||
redelegation, or delegation of additional tokens to a specific validator.
|
redelegation, or delegation of additional tokens to a specific validator.
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
type TxWithdrawDelegationRewardsAll struct {
|
type MsgWithdrawDelegationRewardsAll struct {
|
||||||
delegatorAddr sdk.AccAddress
|
DelegatorAddr sdk.AccAddress
|
||||||
withdrawAddr sdk.AccAddress // address to make the withdrawal to
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithdrawDelegationRewardsAll(delegatorAddr, withdrawAddr sdk.AccAddress)
|
func WithdrawDelegationRewardsAll(delegatorAddr, withdrawAddr sdk.AccAddress)
|
||||||
|
@ -26,31 +25,30 @@ func GetDelegatorRewardsAll(delegatorAddr sdk.AccAddress, height int64) DecCoins
|
||||||
// collect all entitled rewards
|
// collect all entitled rewards
|
||||||
withdraw = 0
|
withdraw = 0
|
||||||
pool = stake.GetPool()
|
pool = stake.GetPool()
|
||||||
global = GetGlobal()
|
feePool = GetFeePool()
|
||||||
for delegation = range delegations
|
for delegation = range delegations
|
||||||
delInfo = GetDelegationDistInfo(delegation.DelegatorAddr,
|
delInfo = GetDelegationDistInfo(delegation.DelegatorAddr,
|
||||||
delegation.ValidatorAddr)
|
delegation.ValidatorAddr)
|
||||||
valInfo = GetValidatorDistInfo(delegation.ValidatorAddr)
|
valInfo = GetValidatorDistInfo(delegation.ValidatorAddr)
|
||||||
validator = GetValidator(delegation.ValidatorAddr)
|
validator = GetValidator(delegation.ValidatorAddr)
|
||||||
|
|
||||||
global, diWithdraw = delInfo.WithdrawRewards(global, valInfo, height, pool.BondedTokens,
|
feePool, diWithdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens,
|
||||||
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
||||||
withdraw += diWithdraw
|
withdraw += diWithdraw
|
||||||
|
|
||||||
SetGlobal(global)
|
SetFeePool(feePool)
|
||||||
return withdraw
|
return withdraw
|
||||||
```
|
```
|
||||||
|
|
||||||
## TxWithdrawDelegationReward
|
## MsgWithdrawDelegationReward
|
||||||
|
|
||||||
under special circumstances a delegator may wish to withdraw rewards from only
|
under special circumstances a delegator may wish to withdraw rewards from only
|
||||||
a single validator.
|
a single validator.
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
type TxWithdrawDelegationReward struct {
|
type MsgWithdrawDelegationReward struct {
|
||||||
delegatorAddr sdk.AccAddress
|
DelegatorAddr sdk.AccAddress
|
||||||
validatorAddr sdk.AccAddress
|
ValidatorAddr sdk.ValAddress
|
||||||
withdrawAddr sdk.AccAddress // address to make the withdrawal to
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.AccAddress)
|
func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.AccAddress)
|
||||||
|
@ -58,39 +56,38 @@ func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.Acc
|
||||||
|
|
||||||
// get all distribution scenarios
|
// get all distribution scenarios
|
||||||
pool = stake.GetPool()
|
pool = stake.GetPool()
|
||||||
global = GetGlobal()
|
feePool = GetFeePool()
|
||||||
delInfo = GetDelegationDistInfo(delegatorAddr,
|
delInfo = GetDelegationDistInfo(delegatorAddr,
|
||||||
validatorAddr)
|
validatorAddr)
|
||||||
valInfo = GetValidatorDistInfo(validatorAddr)
|
valInfo = GetValidatorDistInfo(validatorAddr)
|
||||||
validator = GetValidator(validatorAddr)
|
validator = GetValidator(validatorAddr)
|
||||||
|
|
||||||
global, withdraw = delInfo.WithdrawRewards(global, valInfo, height, pool.BondedTokens,
|
feePool, withdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens,
|
||||||
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
||||||
|
|
||||||
SetGlobal(global)
|
SetFeePool(feePool)
|
||||||
AddCoins(withdrawAddr, withdraw.TruncateDecimal())
|
AddCoins(withdrawAddr, withdraw.TruncateDecimal())
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## TxWithdrawValidatorRewardsAll
|
## MsgWithdrawValidatorRewardsAll
|
||||||
|
|
||||||
When a validator wishes to withdraw their rewards it must send
|
When a validator wishes to withdraw their rewards it must send
|
||||||
`TxWithdrawValidatorRewardsAll`. Note that parts of this transaction logic are also
|
`MsgWithdrawValidatorRewardsAll`. Note that parts of this transaction logic are also
|
||||||
triggered each with any change in individual delegations, such as an unbond,
|
triggered each with any change in individual delegations, such as an unbond,
|
||||||
redelegation, or delegation of additional tokens to a specific validator. This
|
redelegation, or delegation of additional tokens to a specific validator. This
|
||||||
transaction withdraws the validators commission fee, as well as any rewards
|
transaction withdraws the validators commission fee, as well as any rewards
|
||||||
earning on their self-delegation.
|
earning on their self-delegation.
|
||||||
|
|
||||||
```
|
```
|
||||||
type TxWithdrawValidatorRewardsAll struct {
|
type MsgWithdrawValidatorRewardsAll struct {
|
||||||
operatorAddr sdk.AccAddress // validator address to withdraw from
|
OperatorAddr sdk.ValAddress // validator address to withdraw from
|
||||||
withdrawAddr sdk.AccAddress // address to make the withdrawal to
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress)
|
func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress)
|
||||||
|
|
||||||
height = GetHeight()
|
height = GetHeight()
|
||||||
global = GetGlobal()
|
feePool = GetFeePool()
|
||||||
pool = GetPool()
|
pool = GetPool()
|
||||||
ValInfo = GetValidatorDistInfo(delegation.ValidatorAddr)
|
ValInfo = GetValidatorDistInfo(delegation.ValidatorAddr)
|
||||||
validator = GetValidator(delegation.ValidatorAddr)
|
validator = GetValidator(delegation.ValidatorAddr)
|
||||||
|
@ -99,10 +96,10 @@ func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress)
|
||||||
withdraw = GetDelegatorRewardsAll(validator.OperatorAddr, height)
|
withdraw = GetDelegatorRewardsAll(validator.OperatorAddr, height)
|
||||||
|
|
||||||
// withdrawal validator commission rewards
|
// withdrawal validator commission rewards
|
||||||
global, commission = valInfo.WithdrawCommission(global, valInfo, height, pool.BondedTokens,
|
feePool, commission = valInfo.WithdrawCommission(feePool, valInfo, height, pool.BondedTokens,
|
||||||
validator.Tokens, validator.Commission)
|
validator.Tokens, validator.Commission)
|
||||||
withdraw += commission
|
withdraw += commission
|
||||||
SetGlobal(global)
|
SetFeePool(feePool)
|
||||||
|
|
||||||
AddCoins(withdrawAddr, withdraw.TruncateDecimal())
|
AddCoins(withdrawAddr, withdraw.TruncateDecimal())
|
||||||
```
|
```
|
||||||
|
@ -117,7 +114,7 @@ block. The accum is always additive to the existing accum. This term is to be
|
||||||
updated each time rewards are withdrawn from the system.
|
updated each time rewards are withdrawn from the system.
|
||||||
|
|
||||||
```
|
```
|
||||||
func (g Global) UpdateTotalValAccum(height int64, totalBondedTokens Dec) Global
|
func (g FeePool) UpdateTotalValAccum(height int64, totalBondedTokens Dec) FeePool
|
||||||
blocks = height - g.TotalValAccumUpdateHeight
|
blocks = height - g.TotalValAccumUpdateHeight
|
||||||
g.TotalValAccum += totalDelShares * blocks
|
g.TotalValAccum += totalDelShares * blocks
|
||||||
g.TotalValAccumUpdateHeight = height
|
g.TotalValAccumUpdateHeight = height
|
||||||
|
@ -140,7 +137,7 @@ func (vi ValidatorDistInfo) UpdateTotalDelAccum(height int64, totalDelShares Dec
|
||||||
return vi
|
return vi
|
||||||
```
|
```
|
||||||
|
|
||||||
### Global pool to validator pool
|
### FeePool pool to validator pool
|
||||||
|
|
||||||
Every time a validator or delegator executes a withdrawal or the validator is
|
Every time a validator or delegator executes a withdrawal or the validator is
|
||||||
the proposer and receives new tokens, the relevant validator must move tokens
|
the proposer and receives new tokens, the relevant validator must move tokens
|
||||||
|
@ -148,14 +145,14 @@ from the passive global pool to their own pool. It is at this point that the
|
||||||
commission is withdrawn
|
commission is withdrawn
|
||||||
|
|
||||||
```
|
```
|
||||||
func (vi ValidatorDistInfo) TakeAccum(g Global, height int64, totalBonded, vdTokens, commissionRate Dec) (
|
func (vi ValidatorDistInfo) TakeFeePoolRewards(g FeePool, height int64, totalBonded, vdTokens, commissionRate Dec) (
|
||||||
vi ValidatorDistInfo, g Global)
|
vi ValidatorDistInfo, g FeePool)
|
||||||
|
|
||||||
g.UpdateTotalValAccum(height, totalBondedShares)
|
g.UpdateTotalValAccum(height, totalBondedShares)
|
||||||
|
|
||||||
// update the validators pool
|
// update the validators pool
|
||||||
blocks = height - vi.GlobalWithdrawalHeight
|
blocks = height - vi.FeePoolWithdrawalHeight
|
||||||
vi.GlobalWithdrawalHeight = height
|
vi.FeePoolWithdrawalHeight = height
|
||||||
accum = blocks * vdTokens
|
accum = blocks * vdTokens
|
||||||
withdrawalTokens := g.Pool * accum / g.TotalValAccum
|
withdrawalTokens := g.Pool * accum / g.TotalValAccum
|
||||||
commission := withdrawalTokens * commissionRate
|
commission := withdrawalTokens * commissionRate
|
||||||
|
@ -175,12 +172,12 @@ For delegations (including validator's self-delegation) all rewards from reward
|
||||||
pool have already had the validator's commission taken away.
|
pool have already had the validator's commission taken away.
|
||||||
|
|
||||||
```
|
```
|
||||||
func (di DelegatorDistInfo) WithdrawRewards(g Global, vi ValidatorDistInfo,
|
func (di DelegationDistInfo) WithdrawRewards(g FeePool, vi ValidatorDistInfo,
|
||||||
height int64, totalBonded, vdTokens, totalDelShares, commissionRate Dec) (
|
height int64, totalBonded, vdTokens, totalDelShares, commissionRate Dec) (
|
||||||
di DelegatorDistInfo, g Global, withdrawn DecCoins)
|
di DelegationDistInfo, g FeePool, withdrawn DecCoins)
|
||||||
|
|
||||||
vi.UpdateTotalDelAccum(height, totalDelShares)
|
vi.UpdateTotalDelAccum(height, totalDelShares)
|
||||||
g = vi.TakeAccum(g, height, totalBonded, vdTokens, commissionRate)
|
g = vi.TakeFeePoolRewards(g, height, totalBonded, vdTokens, commissionRate)
|
||||||
|
|
||||||
blocks = height - di.WithdrawalHeight
|
blocks = height - di.WithdrawalHeight
|
||||||
di.WithdrawalHeight = height
|
di.WithdrawalHeight = height
|
||||||
|
@ -200,11 +197,11 @@ func (di DelegatorDistInfo) WithdrawRewards(g Global, vi ValidatorDistInfo,
|
||||||
Commission is calculated each time rewards enter into the validator.
|
Commission is calculated each time rewards enter into the validator.
|
||||||
|
|
||||||
```
|
```
|
||||||
func (vi ValidatorDistInfo) WithdrawCommission(g Global, height int64,
|
func (vi ValidatorDistInfo) WithdrawCommission(g FeePool, height int64,
|
||||||
totalBonded, vdTokens, commissionRate Dec) (
|
totalBonded, vdTokens, commissionRate Dec) (
|
||||||
vi ValidatorDistInfo, g Global, withdrawn DecCoins)
|
vi ValidatorDistInfo, g FeePool, withdrawn DecCoins)
|
||||||
|
|
||||||
g = vi.TakeAccum(g, height, totalBonded, vdTokens, commissionRate)
|
g = vi.TakeFeePoolRewards(g, height, totalBonded, vdTokens, commissionRate)
|
||||||
|
|
||||||
withdrawalTokens := vi.PoolCommission
|
withdrawalTokens := vi.PoolCommission
|
||||||
vi.PoolCommission = 0
|
vi.PoolCommission = 0
|
||||||
|
|
|
@ -48,6 +48,11 @@ func (v Validator) GetDelegatorShares() sdk.Dec {
|
||||||
return sdk.ZeroDec()
|
return sdk.ZeroDec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements sdk.Validator
|
||||||
|
func (v Validator) GetCommission() sdk.Dec {
|
||||||
|
return sdk.ZeroDec()
|
||||||
|
}
|
||||||
|
|
||||||
// Implements sdk.Validator
|
// Implements sdk.Validator
|
||||||
func (v Validator) GetJailed() bool {
|
func (v Validator) GetJailed() bool {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -187,6 +187,12 @@ func (c Context) WithBlockTime(newTime time.Time) Context {
|
||||||
return c.WithBlockHeader(newHeader)
|
return c.WithBlockHeader(newHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Context) WithProposer(addr ConsAddress) Context {
|
||||||
|
newHeader := c.BlockHeader()
|
||||||
|
newHeader.ProposerAddress = addr.Bytes()
|
||||||
|
return c.WithBlockHeader(newHeader)
|
||||||
|
}
|
||||||
|
|
||||||
func (c Context) WithBlockHeight(height int64) Context {
|
func (c Context) WithBlockHeight(height int64) Context {
|
||||||
newHeader := c.BlockHeader()
|
newHeader := c.BlockHeader()
|
||||||
newHeader.Height = height
|
newHeader.Height = height
|
||||||
|
|
|
@ -241,6 +241,12 @@ func (d Dec) Quo(d2 Dec) Dec {
|
||||||
return Dec{chopped}
|
return Dec{chopped}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// quotient
|
||||||
|
func (d Dec) QuoInt(i Int) Dec {
|
||||||
|
mul := new(big.Int).Quo(d.Int, i.i)
|
||||||
|
return Dec{mul}
|
||||||
|
}
|
||||||
|
|
||||||
func (d Dec) String() string {
|
func (d Dec) String() string {
|
||||||
str := d.ToLeftPaddedWithDecimals(Precision)
|
str := d.ToLeftPaddedWithDecimals(Precision)
|
||||||
placement := len(str) - Precision
|
placement := len(str) - Precision
|
||||||
|
@ -462,6 +468,6 @@ func MaxDec(d1, d2 Dec) Dec {
|
||||||
}
|
}
|
||||||
|
|
||||||
// intended to be used with require/assert: require.True(DecEq(...))
|
// intended to be used with require/assert: require.True(DecEq(...))
|
||||||
func DecEq(t *testing.T, exp, got Dec) (*testing.T, bool, string, Dec, Dec) {
|
func DecEq(t *testing.T, exp, got Dec) (*testing.T, bool, string, string, string) {
|
||||||
return t, exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp, got
|
return t, exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -525,3 +526,10 @@ func (i *Uint) UnmarshalJSON(bz []byte) error {
|
||||||
}
|
}
|
||||||
return unmarshalJSON(i.i, bz)
|
return unmarshalJSON(i.i, bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//__________________________________________________________________________
|
||||||
|
|
||||||
|
// intended to be used with require/assert: require.True(IntEq(...))
|
||||||
|
func IntEq(t *testing.T, exp, got Int) (*testing.T, bool, string, string, string) {
|
||||||
|
return t, exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String()
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ type Validator interface {
|
||||||
GetConsAddr() ConsAddress // validation consensus address
|
GetConsAddr() ConsAddress // validation consensus address
|
||||||
GetPower() Dec // validation power
|
GetPower() Dec // validation power
|
||||||
GetTokens() Dec // validation tokens
|
GetTokens() Dec // validation tokens
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,6 +302,3 @@ func getSignBytesList(chainID string, stdTx StdTx, stdSigs []StdSignature) (sign
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// BurnFeeHandler burns all fees (decreasing total supply)
|
|
||||||
func BurnFeeHandler(_ sdk.Context, _ sdk.Tx, _ sdk.Coins) {}
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ type FeeCollectionKeeper struct {
|
||||||
cdc *codec.Codec
|
cdc *codec.Codec
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFeeKeeper returns a new FeeKeeper
|
|
||||||
func NewFeeCollectionKeeper(cdc *codec.Codec, key sdk.StoreKey) FeeCollectionKeeper {
|
func NewFeeCollectionKeeper(cdc *codec.Codec, key sdk.StoreKey) FeeCollectionKeeper {
|
||||||
return FeeCollectionKeeper{
|
return FeeCollectionKeeper{
|
||||||
key: key,
|
key: key,
|
||||||
|
@ -28,7 +27,7 @@ func NewFeeCollectionKeeper(cdc *codec.Codec, key sdk.StoreKey) FeeCollectionKee
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds to Collected Fee Pool
|
// retrieves the collected fee pool
|
||||||
func (fck FeeCollectionKeeper) GetCollectedFees(ctx sdk.Context) sdk.Coins {
|
func (fck FeeCollectionKeeper) GetCollectedFees(ctx sdk.Context) sdk.Coins {
|
||||||
store := ctx.KVStore(fck.key)
|
store := ctx.KVStore(fck.key)
|
||||||
bz := store.Get(collectedFeesKey)
|
bz := store.Get(collectedFeesKey)
|
||||||
|
@ -41,14 +40,12 @@ func (fck FeeCollectionKeeper) GetCollectedFees(ctx sdk.Context) sdk.Coins {
|
||||||
return *feePool
|
return *feePool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets to Collected Fee Pool
|
|
||||||
func (fck FeeCollectionKeeper) setCollectedFees(ctx sdk.Context, coins sdk.Coins) {
|
func (fck FeeCollectionKeeper) setCollectedFees(ctx sdk.Context, coins sdk.Coins) {
|
||||||
bz := fck.cdc.MustMarshalBinary(coins)
|
bz := fck.cdc.MustMarshalBinary(coins)
|
||||||
store := ctx.KVStore(fck.key)
|
store := ctx.KVStore(fck.key)
|
||||||
store.Set(collectedFeesKey, bz)
|
store.Set(collectedFeesKey, bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds to Collected Fee Pool
|
|
||||||
func (fck FeeCollectionKeeper) addCollectedFees(ctx sdk.Context, coins sdk.Coins) sdk.Coins {
|
func (fck FeeCollectionKeeper) addCollectedFees(ctx sdk.Context, coins sdk.Coins) sdk.Coins {
|
||||||
newCoins := fck.GetCollectedFees(ctx).Plus(coins)
|
newCoins := fck.GetCollectedFees(ctx).Plus(coins)
|
||||||
fck.setCollectedFees(ctx, newCoins)
|
fck.setCollectedFees(ctx, newCoins)
|
||||||
|
@ -56,7 +53,7 @@ func (fck FeeCollectionKeeper) addCollectedFees(ctx sdk.Context, coins sdk.Coins
|
||||||
return newCoins
|
return newCoins
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears the collected Fee Pool
|
// clear the fee pool
|
||||||
func (fck FeeCollectionKeeper) ClearCollectedFees(ctx sdk.Context) {
|
func (fck FeeCollectionKeeper) ClearCollectedFees(ctx sdk.Context) {
|
||||||
fck.setCollectedFees(ctx, sdk.Coins{})
|
fck.setCollectedFees(ctx, sdk.Coins{})
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package distribution
|
||||||
|
|
||||||
|
import (
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||||
|
)
|
||||||
|
|
||||||
|
// set the proposer for determining distribution during endblock
|
||||||
|
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) {
|
||||||
|
|
||||||
|
if ctx.BlockHeight() > 1 {
|
||||||
|
previousPercentPrecommitVotes := getPreviousPercentPrecommitVotes(req)
|
||||||
|
previousProposer := k.GetPreviousProposerConsAddr(ctx)
|
||||||
|
k.AllocateFees(ctx, previousPercentPrecommitVotes, previousProposer)
|
||||||
|
}
|
||||||
|
|
||||||
|
consAddr := sdk.ConsAddress(req.Header.ProposerAddress)
|
||||||
|
k.SetPreviousProposerConsAddr(ctx, consAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// percent precommit votes for the previous block
|
||||||
|
func getPreviousPercentPrecommitVotes(req abci.RequestBeginBlock) sdk.Dec {
|
||||||
|
|
||||||
|
// determine the total number of signed power
|
||||||
|
totalPower, sumPrecommitPower := int64(0), int64(0)
|
||||||
|
for _, voteInfo := range req.LastCommitInfo.GetVotes() {
|
||||||
|
totalPower += voteInfo.Validator.Power
|
||||||
|
if voteInfo.SignedLastBlock {
|
||||||
|
sumPrecommitPower += voteInfo.Validator.Power
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if totalPower == 0 {
|
||||||
|
return sdk.ZeroDec()
|
||||||
|
}
|
||||||
|
return sdk.NewDec(sumPrecommitPower).Quo(sdk.NewDec(totalPower))
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
// nolint
|
||||||
|
package distribution
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/tags"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Keeper = keeper.Keeper
|
||||||
|
Hooks = keeper.Hooks
|
||||||
|
|
||||||
|
DelegatorWithdrawInfo = types.DelegatorWithdrawInfo
|
||||||
|
DelegationDistInfo = types.DelegationDistInfo
|
||||||
|
ValidatorDistInfo = types.ValidatorDistInfo
|
||||||
|
TotalAccum = types.TotalAccum
|
||||||
|
FeePool = types.FeePool
|
||||||
|
|
||||||
|
MsgSetWithdrawAddress = types.MsgSetWithdrawAddress
|
||||||
|
MsgWithdrawDelegatorRewardsAll = types.MsgWithdrawDelegatorRewardsAll
|
||||||
|
MsgWithdrawDelegatorReward = types.MsgWithdrawDelegatorReward
|
||||||
|
MsgWithdrawValidatorRewardsAll = types.MsgWithdrawValidatorRewardsAll
|
||||||
|
|
||||||
|
GenesisState = types.GenesisState
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
NewKeeper = keeper.NewKeeper
|
||||||
|
|
||||||
|
GetValidatorDistInfoKey = keeper.GetValidatorDistInfoKey
|
||||||
|
GetDelegationDistInfoKey = keeper.GetDelegationDistInfoKey
|
||||||
|
GetDelegationDistInfosKey = keeper.GetDelegationDistInfosKey
|
||||||
|
GetDelegatorWithdrawAddrKey = keeper.GetDelegatorWithdrawAddrKey
|
||||||
|
FeePoolKey = keeper.FeePoolKey
|
||||||
|
ValidatorDistInfoKey = keeper.ValidatorDistInfoKey
|
||||||
|
DelegationDistInfoKey = keeper.DelegationDistInfoKey
|
||||||
|
DelegatorWithdrawInfoKey = keeper.DelegatorWithdrawInfoKey
|
||||||
|
ProposerKey = keeper.ProposerKey
|
||||||
|
DefaultParamspace = keeper.DefaultParamspace
|
||||||
|
|
||||||
|
InitialFeePool = types.InitialFeePool
|
||||||
|
|
||||||
|
NewGenesisState = types.NewGenesisState
|
||||||
|
DefaultGenesisState = types.DefaultGenesisState
|
||||||
|
DefaultGenesisWithValidators = types.DefaultGenesisWithValidators
|
||||||
|
|
||||||
|
RegisterCodec = types.RegisterCodec
|
||||||
|
|
||||||
|
NewMsgSetWithdrawAddress = types.NewMsgSetWithdrawAddress
|
||||||
|
NewMsgWithdrawDelegatorRewardsAll = types.NewMsgWithdrawDelegatorRewardsAll
|
||||||
|
NewMsgWithdrawDelegationReward = types.NewMsgWithdrawDelegatorReward
|
||||||
|
NewMsgWithdrawValidatorRewardsAll = types.NewMsgWithdrawValidatorRewardsAll
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultCodespace = types.DefaultCodespace
|
||||||
|
CodeInvalidInput = types.CodeInvalidInput
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrNilDelegatorAddr = types.ErrNilDelegatorAddr
|
||||||
|
ErrNilWithdrawAddr = types.ErrNilWithdrawAddr
|
||||||
|
ErrNilValidatorAddr = types.ErrNilValidatorAddr
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ActionModifyWithdrawAddress = tags.ActionModifyWithdrawAddress
|
||||||
|
ActionWithdrawDelegatorRewardsAll = tags.ActionWithdrawDelegatorRewardsAll
|
||||||
|
ActionWithdrawDelegatorReward = tags.ActionWithdrawDelegatorReward
|
||||||
|
ActionWithdrawValidatorRewardsAll = tags.ActionWithdrawValidatorRewardsAll
|
||||||
|
|
||||||
|
TagAction = tags.Action
|
||||||
|
TagValidator = tags.Validator
|
||||||
|
TagDelegator = tags.Delegator
|
||||||
|
)
|
|
@ -0,0 +1,114 @@
|
||||||
|
// nolint
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||||
|
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
flagOnlyFromValidator = "only-from-validator"
|
||||||
|
flagIsValidator = "is-validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
// command to withdraw rewards
|
||||||
|
func GetCmdWithdrawRewards(cdc *codec.Codec) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "withdraw-rewards",
|
||||||
|
Short: "withdraw rewards for either: all-delegations, a delegation, or a validator",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
|
onlyFromVal := viper.GetString(flagOnlyFromValidator)
|
||||||
|
isVal := viper.GetBool(flagIsValidator)
|
||||||
|
|
||||||
|
if onlyFromVal != "" && isVal {
|
||||||
|
return fmt.Errorf("cannot use --%v, and --%v flags together",
|
||||||
|
flagOnlyFromValidator, flagIsValidator)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||||
|
cliCtx := context.NewCLIContext().
|
||||||
|
WithCodec(cdc).
|
||||||
|
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
|
||||||
|
|
||||||
|
var msg sdk.Msg
|
||||||
|
switch {
|
||||||
|
case isVal:
|
||||||
|
addr, err := cliCtx.GetFromAddress()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
valAddr := sdk.ValAddress(addr.Bytes())
|
||||||
|
msg = types.NewMsgWithdrawValidatorRewardsAll(valAddr)
|
||||||
|
case onlyFromVal != "":
|
||||||
|
delAddr, err := cliCtx.GetFromAddress()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
valAddr, err := sdk.ValAddressFromBech32(onlyFromVal)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = types.NewMsgWithdrawDelegatorReward(delAddr, valAddr)
|
||||||
|
default:
|
||||||
|
delAddr, err := cliCtx.GetFromAddress()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
msg = types.NewMsgWithdrawDelegatorRewardsAll(delAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// build and sign the transaction, then broadcast to Tendermint
|
||||||
|
return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().String(flagOnlyFromValidator, "", "only withdraw from this validator address (in bech)")
|
||||||
|
cmd.Flags().Bool(flagIsValidator, false, "also withdraw validator's commission")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCmdDelegate implements the delegate command.
|
||||||
|
func GetCmdSetWithdrawAddr(cdc *codec.Codec) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "set-withdraw-addr [withdraw-addr]",
|
||||||
|
Short: "change the default withdraw address for rewards associated with an address",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
|
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||||
|
cliCtx := context.NewCLIContext().
|
||||||
|
WithCodec(cdc).
|
||||||
|
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
|
||||||
|
|
||||||
|
delAddr, err := cliCtx.GetFromAddress()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
withdrawAddr, err := sdk.AccAddressFromBech32(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := types.NewMsgSetWithdrawAddress(delAddr, withdrawAddr)
|
||||||
|
|
||||||
|
// build and sign the transaction, then broadcast to Tendermint
|
||||||
|
return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package distribution
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitGenesis sets distribution information for genesis
|
||||||
|
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
||||||
|
keeper.SetFeePool(ctx, data.FeePool)
|
||||||
|
keeper.SetCommunityTax(ctx, data.CommunityTax)
|
||||||
|
keeper.SetBaseProposerReward(ctx, data.BaseProposerReward)
|
||||||
|
keeper.SetBonusProposerReward(ctx, data.BonusProposerReward)
|
||||||
|
|
||||||
|
for _, vdi := range data.ValidatorDistInfos {
|
||||||
|
keeper.SetValidatorDistInfo(ctx, vdi)
|
||||||
|
}
|
||||||
|
for _, ddi := range data.DelegationDistInfos {
|
||||||
|
keeper.SetDelegationDistInfo(ctx, ddi)
|
||||||
|
}
|
||||||
|
for _, dw := range data.DelegatorWithdrawInfos {
|
||||||
|
keeper.SetDelegatorWithdrawAddr(ctx, dw.DelegatorAddr, dw.WithdrawAddr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteGenesis returns a GenesisState for a given context and keeper. The
|
||||||
|
// GenesisState will contain the pool, and validator/delegator distribution info's
|
||||||
|
func WriteGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
|
||||||
|
feePool := keeper.GetFeePool(ctx)
|
||||||
|
communityTax := keeper.GetCommunityTax(ctx)
|
||||||
|
baseProposerRewards := keeper.GetBaseProposerReward(ctx)
|
||||||
|
bonusProposerRewards := keeper.GetBonusProposerReward(ctx)
|
||||||
|
vdis := keeper.GetAllValidatorDistInfos(ctx)
|
||||||
|
ddis := keeper.GetAllDelegationDistInfos(ctx)
|
||||||
|
dwis := keeper.GetAllDelegatorWithdrawInfos(ctx)
|
||||||
|
return NewGenesisState(feePool, communityTax, baseProposerRewards,
|
||||||
|
bonusProposerRewards, vdis, ddis, dwis)
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package distribution
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/tags"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||||
|
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||||
|
// NOTE msg already has validate basic run
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case types.MsgSetWithdrawAddress:
|
||||||
|
return handleMsgModifyWithdrawAddress(ctx, msg, k)
|
||||||
|
case types.MsgWithdrawDelegatorRewardsAll:
|
||||||
|
return handleMsgWithdrawDelegatorRewardsAll(ctx, msg, k)
|
||||||
|
case types.MsgWithdrawDelegatorReward:
|
||||||
|
return handleMsgWithdrawDelegatorReward(ctx, msg, k)
|
||||||
|
case types.MsgWithdrawValidatorRewardsAll:
|
||||||
|
return handleMsgWithdrawValidatorRewardsAll(ctx, msg, k)
|
||||||
|
default:
|
||||||
|
return sdk.ErrTxDecode("invalid message parse in distribution module").Result()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//_____________________________________________________________________
|
||||||
|
|
||||||
|
// These functions assume everything has been authenticated,
|
||||||
|
// now we just perform action and save
|
||||||
|
|
||||||
|
func handleMsgModifyWithdrawAddress(ctx sdk.Context, msg types.MsgSetWithdrawAddress, k keeper.Keeper) sdk.Result {
|
||||||
|
|
||||||
|
k.SetDelegatorWithdrawAddr(ctx, msg.DelegatorAddr, msg.WithdrawAddr)
|
||||||
|
|
||||||
|
tags := sdk.NewTags(
|
||||||
|
tags.Action, tags.ActionModifyWithdrawAddress,
|
||||||
|
tags.Delegator, []byte(msg.DelegatorAddr.String()),
|
||||||
|
)
|
||||||
|
return sdk.Result{
|
||||||
|
Tags: tags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgWithdrawDelegatorRewardsAll(ctx sdk.Context, msg types.MsgWithdrawDelegatorRewardsAll, k keeper.Keeper) sdk.Result {
|
||||||
|
|
||||||
|
k.WithdrawDelegationRewardsAll(ctx, msg.DelegatorAddr)
|
||||||
|
|
||||||
|
tags := sdk.NewTags(
|
||||||
|
tags.Action, tags.ActionWithdrawDelegatorRewardsAll,
|
||||||
|
tags.Delegator, []byte(msg.DelegatorAddr.String()),
|
||||||
|
)
|
||||||
|
return sdk.Result{
|
||||||
|
Tags: tags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgWithdrawDelegatorReward(ctx sdk.Context, msg types.MsgWithdrawDelegatorReward, k keeper.Keeper) sdk.Result {
|
||||||
|
|
||||||
|
k.WithdrawDelegationReward(ctx, msg.DelegatorAddr, msg.ValidatorAddr)
|
||||||
|
|
||||||
|
tags := sdk.NewTags(
|
||||||
|
tags.Action, tags.ActionWithdrawDelegatorReward,
|
||||||
|
tags.Delegator, []byte(msg.DelegatorAddr.String()),
|
||||||
|
tags.Validator, []byte(msg.ValidatorAddr.String()),
|
||||||
|
)
|
||||||
|
return sdk.Result{
|
||||||
|
Tags: tags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgWithdrawValidatorRewardsAll(ctx sdk.Context, msg types.MsgWithdrawValidatorRewardsAll, k keeper.Keeper) sdk.Result {
|
||||||
|
|
||||||
|
k.WithdrawValidatorRewardsAll(ctx, msg.ValidatorAddr)
|
||||||
|
|
||||||
|
tags := sdk.NewTags(
|
||||||
|
tags.Action, tags.ActionWithdrawValidatorRewardsAll,
|
||||||
|
tags.Validator, []byte(msg.ValidatorAddr.String()),
|
||||||
|
)
|
||||||
|
return sdk.Result{
|
||||||
|
Tags: tags,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Allocate fees handles distribution of the collected fees
|
||||||
|
func (k Keeper) AllocateFees(ctx sdk.Context, percentVotes sdk.Dec, proposer sdk.ConsAddress) {
|
||||||
|
ctx.Logger().With("module", "x/distribution").Error(fmt.Sprintf("allocation height: %v", ctx.BlockHeight()))
|
||||||
|
|
||||||
|
// get the proposer of this block
|
||||||
|
proposerValidator := k.stakeKeeper.ValidatorByConsAddr(ctx, proposer)
|
||||||
|
proposerDist := k.GetValidatorDistInfo(ctx, proposerValidator.GetOperator())
|
||||||
|
|
||||||
|
// get the fees which have been getting collected through all the
|
||||||
|
// transactions in the block
|
||||||
|
feesCollected := k.feeCollectionKeeper.GetCollectedFees(ctx)
|
||||||
|
feesCollectedDec := types.NewDecCoins(feesCollected)
|
||||||
|
|
||||||
|
// allocated rewards to proposer
|
||||||
|
baseProposerReward := k.GetBaseProposerReward(ctx)
|
||||||
|
bonusProposerReward := k.GetBonusProposerReward(ctx)
|
||||||
|
proposerMultiplier := baseProposerReward.Add(bonusProposerReward.Mul(percentVotes))
|
||||||
|
proposerReward := feesCollectedDec.MulDec(proposerMultiplier)
|
||||||
|
|
||||||
|
// apply commission
|
||||||
|
commission := proposerReward.MulDec(proposerValidator.GetCommission())
|
||||||
|
remaining := proposerReward.Minus(commission)
|
||||||
|
proposerDist.PoolCommission = proposerDist.PoolCommission.Plus(commission)
|
||||||
|
proposerDist.Pool = proposerDist.Pool.Plus(remaining)
|
||||||
|
|
||||||
|
// allocate community funding
|
||||||
|
communityTax := k.GetCommunityTax(ctx)
|
||||||
|
communityFunding := feesCollectedDec.MulDec(communityTax)
|
||||||
|
feePool := k.GetFeePool(ctx)
|
||||||
|
feePool.CommunityPool = feePool.CommunityPool.Plus(communityFunding)
|
||||||
|
|
||||||
|
// set the global pool within the distribution module
|
||||||
|
poolReceived := feesCollectedDec.Minus(proposerReward).Minus(communityFunding)
|
||||||
|
feePool.Pool = feePool.Pool.Plus(poolReceived)
|
||||||
|
|
||||||
|
k.SetValidatorDistInfo(ctx, proposerDist)
|
||||||
|
k.SetFeePool(ctx, feePool)
|
||||||
|
|
||||||
|
// clear the now distributed fees
|
||||||
|
k.feeCollectionKeeper.ClearCollectedFees(ctx)
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAllocateFeesBasic(t *testing.T) {
|
||||||
|
|
||||||
|
// no community tax on inputs
|
||||||
|
ctx, _, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator
|
||||||
|
totalPower := int64(10)
|
||||||
|
totalPowerDec := sdk.NewDec(totalPower)
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, totalPower)
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// verify everything has been set in staking correctly
|
||||||
|
validator, found := sk.GetValidator(ctx, valOpAddr1)
|
||||||
|
require.True(t, found)
|
||||||
|
require.Equal(t, sdk.Bonded, validator.Status)
|
||||||
|
assert.True(sdk.DecEq(t, totalPowerDec, validator.Tokens))
|
||||||
|
assert.True(sdk.DecEq(t, totalPowerDec, validator.DelegatorShares))
|
||||||
|
bondedTokens := sk.TotalPower(ctx)
|
||||||
|
assert.True(sdk.DecEq(t, totalPowerDec, bondedTokens))
|
||||||
|
|
||||||
|
// initial fee pool should be empty
|
||||||
|
feePool := keeper.GetFeePool(ctx)
|
||||||
|
require.Nil(t, feePool.Pool)
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// verify that these fees have been received by the feePool
|
||||||
|
percentProposer := sdk.NewDecWithPrec(5, 2)
|
||||||
|
percentRemaining := sdk.OneDec().Sub(percentProposer)
|
||||||
|
feePool = keeper.GetFeePool(ctx)
|
||||||
|
expRes := sdk.NewDecFromInt(feeInputs).Mul(percentRemaining)
|
||||||
|
require.Equal(t, 1, len(feePool.Pool))
|
||||||
|
require.True(sdk.DecEq(t, expRes, feePool.Pool[0].Amount))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAllocateFeesWithCommunityTax(t *testing.T) {
|
||||||
|
communityTax := sdk.NewDecWithPrec(1, 2) //1%
|
||||||
|
ctx, _, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, communityTax)
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator
|
||||||
|
totalPower := int64(10)
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, totalPower)
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// verify that these fees have been received by the feePool
|
||||||
|
feePool := keeper.GetFeePool(ctx)
|
||||||
|
// 5% goes to proposer, 1% community tax
|
||||||
|
percentProposer := sdk.NewDecWithPrec(5, 2)
|
||||||
|
percentRemaining := sdk.OneDec().Sub(communityTax.Add(percentProposer))
|
||||||
|
expRes := sdk.NewDecFromInt(feeInputs).Mul(percentRemaining)
|
||||||
|
require.Equal(t, 1, len(feePool.Pool))
|
||||||
|
require.True(sdk.DecEq(t, expRes, feePool.Pool[0].Amount))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAllocateFeesWithPartialPrecommitPower(t *testing.T) {
|
||||||
|
communityTax := sdk.NewDecWithPrec(1, 2)
|
||||||
|
ctx, _, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, communityTax)
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator
|
||||||
|
totalPower := int64(100)
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, totalPower)
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
percentPrecommitVotes := sdk.NewDecWithPrec(25, 2)
|
||||||
|
keeper.AllocateFees(ctx, percentPrecommitVotes, valConsAddr1)
|
||||||
|
|
||||||
|
// verify that these fees have been received by the feePool
|
||||||
|
feePool := keeper.GetFeePool(ctx)
|
||||||
|
// 1% + 4%*0.25 to proposer + 1% community tax = 97%
|
||||||
|
percentProposer := sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(4, 2).Mul(percentPrecommitVotes))
|
||||||
|
percentRemaining := sdk.OneDec().Sub(communityTax.Add(percentProposer))
|
||||||
|
expRes := sdk.NewDecFromInt(feeInputs).Mul(percentRemaining)
|
||||||
|
require.Equal(t, 1, len(feePool.Pool))
|
||||||
|
require.True(sdk.DecEq(t, expRes, feePool.Pool[0].Amount))
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// get the delegator distribution info
|
||||||
|
func (k Keeper) GetDelegationDistInfo(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||||
|
valOperatorAddr sdk.ValAddress) (ddi types.DelegationDistInfo) {
|
||||||
|
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
|
||||||
|
b := store.Get(GetDelegationDistInfoKey(delAddr, valOperatorAddr))
|
||||||
|
if b == nil {
|
||||||
|
panic("Stored delegation-distribution info should not have been nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
k.cdc.MustUnmarshalBinary(b, &ddi)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the delegator distribution info
|
||||||
|
func (k Keeper) SetDelegationDistInfo(ctx sdk.Context, ddi types.DelegationDistInfo) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
b := k.cdc.MustMarshalBinary(ddi)
|
||||||
|
store.Set(GetDelegationDistInfoKey(ddi.DelegatorAddr, ddi.ValOperatorAddr), b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove a delegator distribution info
|
||||||
|
func (k Keeper) RemoveDelegationDistInfo(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||||
|
valOperatorAddr sdk.ValAddress) {
|
||||||
|
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
store.Delete(GetDelegationDistInfoKey(delAddr, valOperatorAddr))
|
||||||
|
}
|
||||||
|
|
||||||
|
//___________________________________________________________________________________________
|
||||||
|
|
||||||
|
// get the delegator withdraw address, return the delegator address if not set
|
||||||
|
func (k Keeper) GetDelegatorWithdrawAddr(ctx sdk.Context, delAddr sdk.AccAddress) sdk.AccAddress {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
|
||||||
|
b := store.Get(GetDelegatorWithdrawAddrKey(delAddr))
|
||||||
|
if b == nil {
|
||||||
|
return delAddr
|
||||||
|
}
|
||||||
|
return sdk.AccAddress(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the delegator withdraw address
|
||||||
|
func (k Keeper) SetDelegatorWithdrawAddr(ctx sdk.Context, delAddr, withdrawAddr sdk.AccAddress) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
store.Set(GetDelegatorWithdrawAddrKey(delAddr), withdrawAddr.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove a delegator withdraw info
|
||||||
|
func (k Keeper) RemoveDelegatorWithdrawAddr(ctx sdk.Context, delAddr, withdrawAddr sdk.AccAddress) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
store.Delete(GetDelegatorWithdrawAddrKey(delAddr))
|
||||||
|
}
|
||||||
|
|
||||||
|
//___________________________________________________________________________________________
|
||||||
|
|
||||||
|
// withdraw all the rewards for a single delegation
|
||||||
|
func (k Keeper) WithdrawDelegationReward(ctx sdk.Context, delegatorAddr sdk.AccAddress,
|
||||||
|
validatorAddr sdk.ValAddress) {
|
||||||
|
|
||||||
|
height := ctx.BlockHeight()
|
||||||
|
bondedTokens := k.stakeKeeper.TotalPower(ctx)
|
||||||
|
feePool := k.GetFeePool(ctx)
|
||||||
|
delInfo := k.GetDelegationDistInfo(ctx, delegatorAddr, validatorAddr)
|
||||||
|
valInfo := k.GetValidatorDistInfo(ctx, validatorAddr)
|
||||||
|
validator := k.stakeKeeper.Validator(ctx, validatorAddr)
|
||||||
|
delegation := k.stakeKeeper.Delegation(ctx, delegatorAddr, validatorAddr)
|
||||||
|
|
||||||
|
delInfo, valInfo, feePool, withdraw := delInfo.WithdrawRewards(feePool, valInfo, height, bondedTokens,
|
||||||
|
validator.GetTokens(), validator.GetDelegatorShares(), delegation.GetShares(), validator.GetCommission())
|
||||||
|
|
||||||
|
k.SetFeePool(ctx, feePool)
|
||||||
|
k.SetValidatorDistInfo(ctx, valInfo)
|
||||||
|
k.SetDelegationDistInfo(ctx, delInfo)
|
||||||
|
withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, delegatorAddr)
|
||||||
|
_, _, err := k.bankKeeper.AddCoins(ctx, withdrawAddr, withdraw.TruncateDecimal())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//___________________________________________________________________________________________
|
||||||
|
|
||||||
|
// return all rewards for all delegations of a delegator
|
||||||
|
func (k Keeper) WithdrawDelegationRewardsAll(ctx sdk.Context, delegatorAddr sdk.AccAddress) {
|
||||||
|
height := ctx.BlockHeight()
|
||||||
|
withdraw := k.getDelegatorRewardsAll(ctx, delegatorAddr, height)
|
||||||
|
withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, delegatorAddr)
|
||||||
|
_, _, err := k.bankKeeper.AddCoins(ctx, withdrawAddr, withdraw.TruncateDecimal())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return all rewards for all delegations of a delegator
|
||||||
|
func (k Keeper) getDelegatorRewardsAll(ctx sdk.Context, delAddr sdk.AccAddress, height int64) types.DecCoins {
|
||||||
|
|
||||||
|
withdraw := types.DecCoins{}
|
||||||
|
bondedTokens := k.stakeKeeper.TotalPower(ctx)
|
||||||
|
feePool := k.GetFeePool(ctx)
|
||||||
|
|
||||||
|
// iterate over all the delegations
|
||||||
|
operationAtDelegation := func(_ int64, del sdk.Delegation) (stop bool) {
|
||||||
|
valAddr := del.GetValidator()
|
||||||
|
delInfo := k.GetDelegationDistInfo(ctx, delAddr, valAddr)
|
||||||
|
valInfo := k.GetValidatorDistInfo(ctx, valAddr)
|
||||||
|
validator := k.stakeKeeper.Validator(ctx, valAddr)
|
||||||
|
delegation := k.stakeKeeper.Delegation(ctx, delAddr, valAddr)
|
||||||
|
|
||||||
|
delInfo, valInfo, feePool, diWithdraw := delInfo.WithdrawRewards(feePool, valInfo, height, bondedTokens,
|
||||||
|
validator.GetTokens(), validator.GetDelegatorShares(), delegation.GetShares(), validator.GetCommission())
|
||||||
|
withdraw = withdraw.Plus(diWithdraw)
|
||||||
|
k.SetFeePool(ctx, feePool)
|
||||||
|
k.SetValidatorDistInfo(ctx, valInfo)
|
||||||
|
k.SetDelegationDistInfo(ctx, delInfo)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
k.stakeKeeper.IterateDelegations(ctx, delAddr, operationAtDelegation)
|
||||||
|
|
||||||
|
k.SetFeePool(ctx, feePool)
|
||||||
|
return withdraw
|
||||||
|
}
|
|
@ -0,0 +1,250 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWithdrawDelegationRewardBasic(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, 10)
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// delegate
|
||||||
|
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(90), amt.Int64())
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// withdraw delegation
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawDelegationReward(ctx, delAddr1, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
|
expRes := sdk.NewDec(90).Add(sdk.NewDec(100).Quo(sdk.NewDec(2))).TruncateInt() // 90 + 100 tokens * 10/20
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithdrawDelegationRewardWithCommission(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator with 10% commission
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr1, valConsPk1, 10, sdk.NewDecWithPrec(1, 1))
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// delegate
|
||||||
|
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(90), amt.Int64())
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// withdraw delegation
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawDelegationReward(ctx, delAddr1, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
|
expRes := sdk.NewDec(90).Add(sdk.NewDec(90).Quo(sdk.NewDec(2))).TruncateInt() // 90 + 100*90% tokens * 10/20
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithdrawDelegationRewardTwoDelegators(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator with 10% commission
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr1, valConsPk1, 10, sdk.NewDecWithPrec(1, 1))
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// delegate
|
||||||
|
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(90), amt.Int64())
|
||||||
|
|
||||||
|
msgDelegate = stake.NewTestMsgDelegate(delAddr2, valOpAddr1, 20)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr2).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(80), amt.Int64())
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// delegator 1 withdraw delegation
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawDelegationReward(ctx, delAddr1, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
|
expRes := sdk.NewDec(90).Add(sdk.NewDec(90).Quo(sdk.NewDec(4))).TruncateInt() // 90 + 100*90% tokens * 10/40
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
||||||
|
|
||||||
|
// this test demonstrates how two delegators with the same power can end up
|
||||||
|
// with different rewards in the end
|
||||||
|
func TestWithdrawDelegationRewardTwoDelegatorsUneven(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator with no commission
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr1, valConsPk1, 10, sdk.ZeroDec())
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// delegate
|
||||||
|
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(90), amt.Int64())
|
||||||
|
|
||||||
|
msgDelegate = stake.NewTestMsgDelegate(delAddr2, valOpAddr1, 10)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr2).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(90), amt.Int64())
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(90)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
|
||||||
|
// delegator 1 withdraw delegation early, delegator 2 just keeps it's accum
|
||||||
|
keeper.WithdrawDelegationReward(ctx, delAddr1, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
|
expRes1 := sdk.NewDec(90).Add(sdk.NewDec(90).Quo(sdk.NewDec(3))).TruncateInt() // 90 + 100 * 10/30
|
||||||
|
require.True(sdk.IntEq(t, expRes1, amt))
|
||||||
|
|
||||||
|
// allocate 200 denom of fees
|
||||||
|
feeInputs = sdk.NewInt(180)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
ctx = ctx.WithBlockHeight(2)
|
||||||
|
|
||||||
|
// delegator 2 now withdraws everything it's entitled to
|
||||||
|
keeper.WithdrawDelegationReward(ctx, delAddr2, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr2).GetCoins().AmountOf(denom)
|
||||||
|
// existingTokens + (100+200 * (10/(20+30))
|
||||||
|
withdrawnFromVal := sdk.NewDec(60 + 180).Mul(sdk.NewDec(2)).Quo(sdk.NewDec(5))
|
||||||
|
expRes2 := sdk.NewDec(90).Add(withdrawnFromVal).TruncateInt()
|
||||||
|
require.True(sdk.IntEq(t, expRes2, amt))
|
||||||
|
|
||||||
|
// finally delegator 1 withdraws the remainder of its reward
|
||||||
|
keeper.WithdrawDelegationReward(ctx, delAddr1, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
|
remainingInVal := sdk.NewDec(60 + 180).Sub(withdrawnFromVal)
|
||||||
|
expRes3 := sdk.NewDecFromInt(expRes1).Add(remainingInVal.Mul(sdk.NewDec(1)).Quo(sdk.NewDec(3))).TruncateInt()
|
||||||
|
require.True(sdk.IntEq(t, expRes3, amt))
|
||||||
|
|
||||||
|
// verify the final withdraw amounts are different
|
||||||
|
require.True(t, expRes2.GT(expRes3))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithdrawDelegationRewardsAll(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//make some validators with different commissions
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr1, valConsPk1, 10, sdk.NewDecWithPrec(1, 1))
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
|
||||||
|
msgCreateValidator = stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr2, valConsPk2, 50, sdk.NewDecWithPrec(2, 1))
|
||||||
|
got = stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
|
||||||
|
msgCreateValidator = stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr3, valConsPk3, 40, sdk.NewDecWithPrec(3, 1))
|
||||||
|
got = stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// delegate to all the validators
|
||||||
|
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||||
|
require.True(t, stakeHandler(ctx, msgDelegate).IsOK())
|
||||||
|
msgDelegate = stake.NewTestMsgDelegate(delAddr1, valOpAddr2, 20)
|
||||||
|
require.True(t, stakeHandler(ctx, msgDelegate).IsOK())
|
||||||
|
msgDelegate = stake.NewTestMsgDelegate(delAddr1, valOpAddr3, 30)
|
||||||
|
require.True(t, stakeHandler(ctx, msgDelegate).IsOK())
|
||||||
|
|
||||||
|
// 40 tokens left after delegating 60 of them
|
||||||
|
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(40), amt.Int64())
|
||||||
|
|
||||||
|
// total power of each validator:
|
||||||
|
// validator 1: 10 (self) + 10 (delegator) = 20
|
||||||
|
// validator 2: 50 (self) + 20 (delegator) = 70
|
||||||
|
// validator 3: 40 (self) + 30 (delegator) = 70
|
||||||
|
// grand total: 160
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(1000)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// withdraw delegation
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawDelegationRewardsAll(ctx, delAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
|
// orig-amount + fees *(1-proposerReward)* (val1Portion * delegatorPotion * (1-val1Commission) ... etc)
|
||||||
|
// + fees *(proposerReward) * (delegatorPotion * (1-val1Commission))
|
||||||
|
// 40 + 1000 *(1- 0.95)* (20/160 * 10/20 * 0.9 + 70/160 * 20/70 * 0.8 + 70/160 * 30/70 * 0.7)
|
||||||
|
// 40 + 1000 *( 0.05) * (10/20 * 0.9)
|
||||||
|
feesInNonProposer := sdk.NewDecFromInt(feeInputs).Mul(sdk.NewDecWithPrec(95, 2))
|
||||||
|
feesInProposer := sdk.NewDecFromInt(feeInputs).Mul(sdk.NewDecWithPrec(5, 2))
|
||||||
|
feesInVal1 := feesInNonProposer.Mul(sdk.NewDec(10).Quo(sdk.NewDec(160))).Mul(sdk.NewDecWithPrec(9, 1))
|
||||||
|
feesInVal2 := feesInNonProposer.Mul(sdk.NewDec(20).Quo(sdk.NewDec(160))).Mul(sdk.NewDecWithPrec(8, 1))
|
||||||
|
feesInVal3 := feesInNonProposer.Mul(sdk.NewDec(30).Quo(sdk.NewDec(160))).Mul(sdk.NewDecWithPrec(7, 1))
|
||||||
|
feesInVal1Proposer := feesInProposer.Mul(sdk.NewDec(10).Quo(sdk.NewDec(20))).Mul(sdk.NewDecWithPrec(9, 1))
|
||||||
|
expRes := sdk.NewDec(40).Add(feesInVal1).Add(feesInVal2).Add(feesInVal3).Add(feesInVal1Proposer).TruncateInt()
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get the set of all validator-distribution-info's with no limits, used during genesis dump
|
||||||
|
func (k Keeper) GetAllValidatorDistInfos(ctx sdk.Context) (vdis []types.ValidatorDistInfo) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
iterator := sdk.KVStorePrefixIterator(store, ValidatorDistInfoKey)
|
||||||
|
defer iterator.Close()
|
||||||
|
|
||||||
|
for ; iterator.Valid(); iterator.Next() {
|
||||||
|
var vdi types.ValidatorDistInfo
|
||||||
|
k.cdc.MustUnmarshalBinary(iterator.Value(), &vdi)
|
||||||
|
vdis = append(vdis, vdi)
|
||||||
|
}
|
||||||
|
return vdis
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the set of all delegator-distribution-info's with no limits, used during genesis dump
|
||||||
|
func (k Keeper) GetAllDelegationDistInfos(ctx sdk.Context) (ddis []types.DelegationDistInfo) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
iterator := sdk.KVStorePrefixIterator(store, DelegationDistInfoKey)
|
||||||
|
defer iterator.Close()
|
||||||
|
|
||||||
|
for ; iterator.Valid(); iterator.Next() {
|
||||||
|
var ddi types.DelegationDistInfo
|
||||||
|
k.cdc.MustUnmarshalBinary(iterator.Value(), &ddi)
|
||||||
|
ddis = append(ddis, ddi)
|
||||||
|
}
|
||||||
|
return ddis
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the set of all delegator-withdraw addresses with no limits, used during genesis dump
|
||||||
|
func (k Keeper) GetAllDelegatorWithdrawInfos(ctx sdk.Context) (dwis []types.DelegatorWithdrawInfo) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
iterator := sdk.KVStorePrefixIterator(store, DelegationDistInfoKey)
|
||||||
|
defer iterator.Close()
|
||||||
|
|
||||||
|
for ; iterator.Valid(); iterator.Next() {
|
||||||
|
dw := types.DelegatorWithdrawInfo{
|
||||||
|
DelegatorAddr: sdk.AccAddress(iterator.Key()),
|
||||||
|
WithdrawAddr: sdk.AccAddress(iterator.Value()),
|
||||||
|
}
|
||||||
|
dwis = append(dwis, dw)
|
||||||
|
}
|
||||||
|
return dwis
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create a new validator distribution record
|
||||||
|
func (k Keeper) onValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
|
||||||
|
height := ctx.BlockHeight()
|
||||||
|
vdi := types.ValidatorDistInfo{
|
||||||
|
OperatorAddr: addr,
|
||||||
|
FeePoolWithdrawalHeight: height,
|
||||||
|
Pool: types.DecCoins{},
|
||||||
|
PoolCommission: types.DecCoins{},
|
||||||
|
DelAccum: types.NewTotalAccum(height),
|
||||||
|
}
|
||||||
|
k.SetValidatorDistInfo(ctx, vdi)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Withdrawal all validator rewards
|
||||||
|
func (k Keeper) onValidatorCommissionChange(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
k.WithdrawValidatorRewardsAll(ctx, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Withdrawal all validator distribution rewards and cleanup the distribution record
|
||||||
|
func (k Keeper) onValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
k.RemoveValidatorDistInfo(ctx, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
//_________________________________________________________________________________________
|
||||||
|
|
||||||
|
// Create a new delegator distribution record
|
||||||
|
func (k Keeper) onDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||||
|
valAddr sdk.ValAddress) {
|
||||||
|
|
||||||
|
ddi := types.DelegationDistInfo{
|
||||||
|
DelegatorAddr: delAddr,
|
||||||
|
ValOperatorAddr: valAddr,
|
||||||
|
WithdrawalHeight: ctx.BlockHeight(),
|
||||||
|
}
|
||||||
|
k.SetDelegationDistInfo(ctx, ddi)
|
||||||
|
ctx.Logger().With("module", "x/distribution").Error(fmt.Sprintf("ddi created: %v", ddi))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Withdrawal all validator rewards
|
||||||
|
func (k Keeper) onDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||||
|
valAddr sdk.ValAddress) {
|
||||||
|
|
||||||
|
k.WithdrawDelegationReward(ctx, delAddr, valAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Withdrawal all validator distribution rewards and cleanup the distribution record
|
||||||
|
func (k Keeper) onDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||||
|
valAddr sdk.ValAddress) {
|
||||||
|
|
||||||
|
k.RemoveDelegationDistInfo(ctx, delAddr, valAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
//_________________________________________________________________________________________
|
||||||
|
|
||||||
|
// Wrapper struct
|
||||||
|
type Hooks struct {
|
||||||
|
k Keeper
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ sdk.StakingHooks = Hooks{}
|
||||||
|
|
||||||
|
// New Validator Hooks
|
||||||
|
func (k Keeper) Hooks() Hooks { return Hooks{k} }
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func (h Hooks) OnValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
h.k.onValidatorCreated(ctx, addr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnValidatorCommissionChange(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
h.k.onValidatorCommissionChange(ctx, addr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) {
|
||||||
|
h.k.onValidatorRemoved(ctx, addr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
|
h.k.onDelegationCreated(ctx, delAddr, valAddr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
|
h.k.onDelegationSharesModified(ctx, delAddr, valAddr)
|
||||||
|
}
|
||||||
|
func (h Hooks) OnDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||||
|
h.k.onDelegationRemoved(ctx, delAddr, valAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// nolint - unused hooks for interface
|
||||||
|
func (h Hooks) OnValidatorBonded(ctx sdk.Context, addr sdk.ConsAddress) {}
|
||||||
|
func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, addr sdk.ConsAddress) {}
|
|
@ -0,0 +1,129 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/params"
|
||||||
|
)
|
||||||
|
|
||||||
|
// keeper of the stake store
|
||||||
|
type Keeper struct {
|
||||||
|
storeKey sdk.StoreKey
|
||||||
|
cdc *codec.Codec
|
||||||
|
paramSpace params.Subspace
|
||||||
|
bankKeeper types.BankKeeper
|
||||||
|
stakeKeeper types.StakeKeeper
|
||||||
|
feeCollectionKeeper types.FeeCollectionKeeper
|
||||||
|
|
||||||
|
// codespace
|
||||||
|
codespace sdk.CodespaceType
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, paramSpace params.Subspace, ck types.BankKeeper,
|
||||||
|
sk types.StakeKeeper, fck types.FeeCollectionKeeper, codespace sdk.CodespaceType) Keeper {
|
||||||
|
|
||||||
|
keeper := Keeper{
|
||||||
|
storeKey: key,
|
||||||
|
cdc: cdc,
|
||||||
|
paramSpace: paramSpace.WithTypeTable(ParamTypeTable()),
|
||||||
|
bankKeeper: ck,
|
||||||
|
stakeKeeper: sk,
|
||||||
|
feeCollectionKeeper: fck,
|
||||||
|
codespace: codespace,
|
||||||
|
}
|
||||||
|
return keeper
|
||||||
|
}
|
||||||
|
|
||||||
|
//______________________________________________________________________
|
||||||
|
|
||||||
|
// get the global fee pool distribution info
|
||||||
|
func (k Keeper) GetFeePool(ctx sdk.Context) (feePool types.FeePool) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
b := store.Get(FeePoolKey)
|
||||||
|
if b == nil {
|
||||||
|
panic("Stored fee pool should not have been nil")
|
||||||
|
}
|
||||||
|
k.cdc.MustUnmarshalBinary(b, &feePool)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the global fee pool distribution info
|
||||||
|
func (k Keeper) SetFeePool(ctx sdk.Context, feePool types.FeePool) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
b := k.cdc.MustMarshalBinary(feePool)
|
||||||
|
store.Set(FeePoolKey, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
//______________________________________________________________________
|
||||||
|
|
||||||
|
// set the proposer public key for this block
|
||||||
|
func (k Keeper) GetPreviousProposerConsAddr(ctx sdk.Context) (consAddr sdk.ConsAddress) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
|
||||||
|
b := store.Get(ProposerKey)
|
||||||
|
if b == nil {
|
||||||
|
panic("Previous proposer not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
k.cdc.MustUnmarshalBinary(b, &consAddr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the proposer public key for this block
|
||||||
|
func (k Keeper) SetPreviousProposerConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
b := k.cdc.MustMarshalBinary(consAddr)
|
||||||
|
store.Set(ProposerKey, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
//______________________________________________________________________
|
||||||
|
// PARAM STORE
|
||||||
|
|
||||||
|
// Type declaration for parameters
|
||||||
|
func ParamTypeTable() params.TypeTable {
|
||||||
|
return params.NewTypeTable(
|
||||||
|
ParamStoreKeyCommunityTax, sdk.Dec{},
|
||||||
|
ParamStoreKeyBaseProposerReward, sdk.Dec{},
|
||||||
|
ParamStoreKeyBonusProposerReward, sdk.Dec{},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the current CommunityTax rate from the global param store
|
||||||
|
// nolint: errcheck
|
||||||
|
func (k Keeper) GetCommunityTax(ctx sdk.Context) sdk.Dec {
|
||||||
|
var percent sdk.Dec
|
||||||
|
k.paramSpace.Get(ctx, ParamStoreKeyCommunityTax, &percent)
|
||||||
|
return percent
|
||||||
|
}
|
||||||
|
|
||||||
|
// nolint: errcheck
|
||||||
|
func (k Keeper) SetCommunityTax(ctx sdk.Context, percent sdk.Dec) {
|
||||||
|
k.paramSpace.Set(ctx, ParamStoreKeyCommunityTax, &percent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the current BaseProposerReward rate from the global param store
|
||||||
|
// nolint: errcheck
|
||||||
|
func (k Keeper) GetBaseProposerReward(ctx sdk.Context) sdk.Dec {
|
||||||
|
var percent sdk.Dec
|
||||||
|
k.paramSpace.Get(ctx, ParamStoreKeyBaseProposerReward, &percent)
|
||||||
|
return percent
|
||||||
|
}
|
||||||
|
|
||||||
|
// nolint: errcheck
|
||||||
|
func (k Keeper) SetBaseProposerReward(ctx sdk.Context, percent sdk.Dec) {
|
||||||
|
k.paramSpace.Set(ctx, ParamStoreKeyBaseProposerReward, &percent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the current BaseProposerReward rate from the global param store
|
||||||
|
// nolint: errcheck
|
||||||
|
func (k Keeper) GetBonusProposerReward(ctx sdk.Context) sdk.Dec {
|
||||||
|
var percent sdk.Dec
|
||||||
|
k.paramSpace.Get(ctx, ParamStoreKeyBonusProposerReward, &percent)
|
||||||
|
return percent
|
||||||
|
}
|
||||||
|
|
||||||
|
// nolint: errcheck
|
||||||
|
func (k Keeper) SetBonusProposerReward(ctx sdk.Context, percent sdk.Dec) {
|
||||||
|
k.paramSpace.Set(ctx, ParamStoreKeyBonusProposerReward, &percent)
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSetGetPreviousProposerConsAddr(t *testing.T) {
|
||||||
|
ctx, _, keeper, _, _ := CreateTestInputDefault(t, false, 0)
|
||||||
|
|
||||||
|
keeper.SetPreviousProposerConsAddr(ctx, valConsAddr1)
|
||||||
|
res := keeper.GetPreviousProposerConsAddr(ctx)
|
||||||
|
require.True(t, res.Equals(valConsAddr1), "expected: %v got: %v", valConsAddr1.String(), res.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetGetCommunityTax(t *testing.T) {
|
||||||
|
ctx, _, keeper, _, _ := CreateTestInputDefault(t, false, 0)
|
||||||
|
|
||||||
|
someDec := sdk.NewDec(333)
|
||||||
|
keeper.SetCommunityTax(ctx, someDec)
|
||||||
|
res := keeper.GetCommunityTax(ctx)
|
||||||
|
require.True(sdk.DecEq(t, someDec, res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetGetFeePool(t *testing.T) {
|
||||||
|
ctx, _, keeper, _, _ := CreateTestInputDefault(t, false, 0)
|
||||||
|
|
||||||
|
fp := types.InitialFeePool()
|
||||||
|
fp.ValAccum.UpdateHeight = 777
|
||||||
|
|
||||||
|
keeper.SetFeePool(ctx, fp)
|
||||||
|
res := keeper.GetFeePool(ctx)
|
||||||
|
require.Equal(t, fp.ValAccum, res.ValAccum)
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// keys/key-prefixes
|
||||||
|
var (
|
||||||
|
FeePoolKey = []byte{0x00} // key for global distribution state
|
||||||
|
ValidatorDistInfoKey = []byte{0x01} // prefix for each key to a validator distribution
|
||||||
|
DelegationDistInfoKey = []byte{0x02} // prefix for each key to a delegation distribution
|
||||||
|
DelegatorWithdrawInfoKey = []byte{0x03} // prefix for each key to a delegator withdraw info
|
||||||
|
ProposerKey = []byte{0x04} // key for storing the proposer operator address
|
||||||
|
|
||||||
|
// params store
|
||||||
|
ParamStoreKeyCommunityTax = []byte("community-tax")
|
||||||
|
ParamStoreKeyBaseProposerReward = []byte("base-proposer-reward")
|
||||||
|
ParamStoreKeyBonusProposerReward = []byte("bonus-proposer-reward")
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// default paramspace for params keeper
|
||||||
|
DefaultParamspace = "distr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// gets the key for the validator distribution info from address
|
||||||
|
// VALUE: distribution/types.ValidatorDistInfo
|
||||||
|
func GetValidatorDistInfoKey(operatorAddr sdk.ValAddress) []byte {
|
||||||
|
return append(ValidatorDistInfoKey, operatorAddr.Bytes()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// gets the key for delegator distribution for a validator
|
||||||
|
// VALUE: distribution/types.DelegationDistInfo
|
||||||
|
func GetDelegationDistInfoKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
|
||||||
|
return append(GetDelegationDistInfosKey(delAddr), valAddr.Bytes()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// gets the prefix for a delegator's distributions across all validators
|
||||||
|
func GetDelegationDistInfosKey(delAddr sdk.AccAddress) []byte {
|
||||||
|
return append(DelegationDistInfoKey, delAddr.Bytes()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// gets the prefix for a delegator's withdraw info
|
||||||
|
func GetDelegatorWithdrawAddrKey(delAddr sdk.AccAddress) []byte {
|
||||||
|
return append(DelegatorWithdrawInfoKey, delAddr.Bytes()...)
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
"github.com/tendermint/tendermint/crypto"
|
||||||
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||||
|
dbm "github.com/tendermint/tendermint/libs/db"
|
||||||
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
"github.com/cosmos/cosmos-sdk/store"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/params"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
delPk1 = ed25519.GenPrivKey().PubKey()
|
||||||
|
delPk2 = ed25519.GenPrivKey().PubKey()
|
||||||
|
delPk3 = ed25519.GenPrivKey().PubKey()
|
||||||
|
delAddr1 = sdk.AccAddress(delPk1.Address())
|
||||||
|
delAddr2 = sdk.AccAddress(delPk2.Address())
|
||||||
|
delAddr3 = sdk.AccAddress(delPk3.Address())
|
||||||
|
|
||||||
|
valOpPk1 = ed25519.GenPrivKey().PubKey()
|
||||||
|
valOpPk2 = ed25519.GenPrivKey().PubKey()
|
||||||
|
valOpPk3 = ed25519.GenPrivKey().PubKey()
|
||||||
|
valOpAddr1 = sdk.ValAddress(valOpPk1.Address())
|
||||||
|
valOpAddr2 = sdk.ValAddress(valOpPk2.Address())
|
||||||
|
valOpAddr3 = sdk.ValAddress(valOpPk3.Address())
|
||||||
|
valAccAddr1 = sdk.AccAddress(valOpPk1.Address()) // generate acc addresses for these validator keys too
|
||||||
|
valAccAddr2 = sdk.AccAddress(valOpPk2.Address())
|
||||||
|
valAccAddr3 = sdk.AccAddress(valOpPk3.Address())
|
||||||
|
|
||||||
|
valConsPk1 = ed25519.GenPrivKey().PubKey()
|
||||||
|
valConsPk2 = ed25519.GenPrivKey().PubKey()
|
||||||
|
valConsPk3 = ed25519.GenPrivKey().PubKey()
|
||||||
|
valConsAddr1 = sdk.ConsAddress(valConsPk1.Address())
|
||||||
|
valConsAddr2 = sdk.ConsAddress(valConsPk2.Address())
|
||||||
|
valConsAddr3 = sdk.ConsAddress(valConsPk3.Address())
|
||||||
|
|
||||||
|
addrs = []sdk.AccAddress{
|
||||||
|
delAddr1, delAddr2, delAddr3,
|
||||||
|
valAccAddr1, valAccAddr2, valAccAddr3,
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyDelAddr sdk.AccAddress
|
||||||
|
emptyValAddr sdk.ValAddress
|
||||||
|
emptyPubkey crypto.PubKey
|
||||||
|
)
|
||||||
|
|
||||||
|
// create a codec used only for testing
|
||||||
|
func MakeTestCodec() *codec.Codec {
|
||||||
|
var cdc = codec.New()
|
||||||
|
bank.RegisterCodec(cdc)
|
||||||
|
stake.RegisterCodec(cdc)
|
||||||
|
auth.RegisterCodec(cdc)
|
||||||
|
sdk.RegisterCodec(cdc)
|
||||||
|
codec.RegisterCrypto(cdc)
|
||||||
|
|
||||||
|
types.RegisterCodec(cdc) // distr
|
||||||
|
return cdc
|
||||||
|
}
|
||||||
|
|
||||||
|
// test input with default values
|
||||||
|
func CreateTestInputDefault(t *testing.T, isCheckTx bool, initCoins int64) (
|
||||||
|
sdk.Context, auth.AccountMapper, Keeper, stake.Keeper, DummyFeeCollectionKeeper) {
|
||||||
|
|
||||||
|
communityTax := sdk.NewDecWithPrec(2, 2)
|
||||||
|
return CreateTestInputAdvanced(t, isCheckTx, initCoins, communityTax)
|
||||||
|
}
|
||||||
|
|
||||||
|
// hogpodge of all sorts of input required for testing
|
||||||
|
func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initCoins int64,
|
||||||
|
communityTax sdk.Dec) (
|
||||||
|
sdk.Context, auth.AccountMapper, Keeper, stake.Keeper, DummyFeeCollectionKeeper) {
|
||||||
|
|
||||||
|
keyDistr := sdk.NewKVStoreKey("distr")
|
||||||
|
keyStake := sdk.NewKVStoreKey("stake")
|
||||||
|
tkeyStake := sdk.NewTransientStoreKey("transient_stake")
|
||||||
|
keyAcc := sdk.NewKVStoreKey("acc")
|
||||||
|
keyFeeCollection := sdk.NewKVStoreKey("fee")
|
||||||
|
keyParams := sdk.NewKVStoreKey("params")
|
||||||
|
tkeyParams := sdk.NewTransientStoreKey("transient_params")
|
||||||
|
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
ms := store.NewCommitMultiStore(db)
|
||||||
|
|
||||||
|
ms.MountStoreWithDB(keyDistr, sdk.StoreTypeIAVL, db)
|
||||||
|
ms.MountStoreWithDB(tkeyStake, sdk.StoreTypeTransient, nil)
|
||||||
|
ms.MountStoreWithDB(keyStake, sdk.StoreTypeIAVL, db)
|
||||||
|
ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
|
||||||
|
ms.MountStoreWithDB(keyFeeCollection, sdk.StoreTypeIAVL, db)
|
||||||
|
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
|
||||||
|
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
|
||||||
|
|
||||||
|
err := ms.LoadLatestVersion()
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
cdc := MakeTestCodec()
|
||||||
|
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
|
||||||
|
|
||||||
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger())
|
||||||
|
accountMapper := auth.NewAccountMapper(cdc, keyAcc, auth.ProtoBaseAccount)
|
||||||
|
ck := bank.NewBaseKeeper(accountMapper)
|
||||||
|
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Subspace(stake.DefaultParamspace), stake.DefaultCodespace)
|
||||||
|
sk.SetPool(ctx, stake.InitialPool())
|
||||||
|
sk.SetParams(ctx, stake.DefaultParams())
|
||||||
|
sk.InitIntraTxCounter(ctx)
|
||||||
|
|
||||||
|
// fill all the addresses with some coins, set the loose pool tokens simultaneously
|
||||||
|
for _, addr := range addrs {
|
||||||
|
pool := sk.GetPool(ctx)
|
||||||
|
_, _, err := ck.AddCoins(ctx, addr, sdk.Coins{
|
||||||
|
{sk.GetParams(ctx).BondDenom, sdk.NewInt(initCoins)},
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
pool.LooseTokens = pool.LooseTokens.Add(sdk.NewDec(initCoins))
|
||||||
|
sk.SetPool(ctx, pool)
|
||||||
|
}
|
||||||
|
|
||||||
|
fck := DummyFeeCollectionKeeper{}
|
||||||
|
keeper := NewKeeper(cdc, keyDistr, pk.Subspace(DefaultParamspace), ck, sk, fck, types.DefaultCodespace)
|
||||||
|
|
||||||
|
// set the distribution hooks on staking
|
||||||
|
sk = sk.WithHooks(keeper.Hooks())
|
||||||
|
|
||||||
|
// set genesis items required for distribution
|
||||||
|
keeper.SetFeePool(ctx, types.InitialFeePool())
|
||||||
|
keeper.SetCommunityTax(ctx, communityTax)
|
||||||
|
keeper.SetBaseProposerReward(ctx, sdk.NewDecWithPrec(1, 2))
|
||||||
|
keeper.SetBonusProposerReward(ctx, sdk.NewDecWithPrec(4, 2))
|
||||||
|
|
||||||
|
return ctx, accountMapper, keeper, sk, fck
|
||||||
|
}
|
||||||
|
|
||||||
|
//__________________________________________________________________________________
|
||||||
|
// fee collection keeper used only for testing
|
||||||
|
type DummyFeeCollectionKeeper struct{}
|
||||||
|
|
||||||
|
var heldFees sdk.Coins
|
||||||
|
var _ types.FeeCollectionKeeper = DummyFeeCollectionKeeper{}
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func (fck DummyFeeCollectionKeeper) GetCollectedFees(_ sdk.Context) sdk.Coins {
|
||||||
|
return heldFees
|
||||||
|
}
|
||||||
|
func (fck DummyFeeCollectionKeeper) SetCollectedFees(in sdk.Coins) {
|
||||||
|
heldFees = in
|
||||||
|
}
|
||||||
|
func (fck DummyFeeCollectionKeeper) ClearCollectedFees(_ sdk.Context) {
|
||||||
|
heldFees = sdk.Coins{}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// get the validator distribution info
|
||||||
|
func (k Keeper) GetValidatorDistInfo(ctx sdk.Context,
|
||||||
|
operatorAddr sdk.ValAddress) (vdi types.ValidatorDistInfo) {
|
||||||
|
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
|
||||||
|
b := store.Get(GetValidatorDistInfoKey(operatorAddr))
|
||||||
|
if b == nil {
|
||||||
|
panic("Stored validator-distribution info should not have been nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
k.cdc.MustUnmarshalBinary(b, &vdi)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the validator distribution info
|
||||||
|
func (k Keeper) SetValidatorDistInfo(ctx sdk.Context, vdi types.ValidatorDistInfo) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
b := k.cdc.MustMarshalBinary(vdi)
|
||||||
|
store.Set(GetValidatorDistInfoKey(vdi.OperatorAddr), b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove a validator distribution info
|
||||||
|
func (k Keeper) RemoveValidatorDistInfo(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
store.Delete(GetValidatorDistInfoKey(valAddr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// withdrawal all the validator rewards including the commission
|
||||||
|
func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context, operatorAddr sdk.ValAddress) {
|
||||||
|
|
||||||
|
// withdraw self-delegation
|
||||||
|
height := ctx.BlockHeight()
|
||||||
|
validator := k.stakeKeeper.Validator(ctx, operatorAddr)
|
||||||
|
accAddr := sdk.AccAddress(operatorAddr.Bytes())
|
||||||
|
withdraw := k.getDelegatorRewardsAll(ctx, accAddr, height)
|
||||||
|
|
||||||
|
// withdrawal validator commission rewards
|
||||||
|
bondedTokens := k.stakeKeeper.TotalPower(ctx)
|
||||||
|
valInfo := k.GetValidatorDistInfo(ctx, operatorAddr)
|
||||||
|
feePool := k.GetFeePool(ctx)
|
||||||
|
valInfo, feePool, commission := valInfo.WithdrawCommission(feePool, height, bondedTokens,
|
||||||
|
validator.GetTokens(), validator.GetCommission())
|
||||||
|
withdraw = withdraw.Plus(commission)
|
||||||
|
k.SetValidatorDistInfo(ctx, valInfo)
|
||||||
|
k.SetFeePool(ctx, feePool)
|
||||||
|
|
||||||
|
withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, accAddr)
|
||||||
|
_, _, err := k.bankKeeper.AddCoins(ctx, withdrawAddr, withdraw.TruncateDecimal())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,192 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWithdrawValidatorRewardsAllNoDelegator(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, 10)
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// withdraw self-delegation reward
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawValidatorRewardsAll(ctx, valOpAddr1)
|
||||||
|
amt := accMapper.GetAccount(ctx, valAccAddr1).GetCoins().AmountOf(denom)
|
||||||
|
expRes := sdk.NewDec(90).Add(sdk.NewDec(100)).TruncateInt()
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithdrawValidatorRewardsAllDelegatorNoCommission(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, 10)
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// delegate
|
||||||
|
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(90), amt.Int64())
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// withdraw self-delegation reward
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawValidatorRewardsAll(ctx, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, valAccAddr1).GetCoins().AmountOf(denom)
|
||||||
|
expRes := sdk.NewDec(90).Add(sdk.NewDec(100).Quo(sdk.NewDec(2))).TruncateInt() // 90 + 100 tokens * 10/20
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithdrawValidatorRewardsAllDelegatorWithCommission(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator
|
||||||
|
commissionRate := sdk.NewDecWithPrec(1, 1)
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr1, valConsPk1, 10, commissionRate)
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// delegate
|
||||||
|
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(90), amt.Int64())
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// withdraw validator reward
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawValidatorRewardsAll(ctx, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, valAccAddr1).GetCoins().AmountOf(denom)
|
||||||
|
commissionTaken := sdk.NewDec(100).Mul(commissionRate)
|
||||||
|
afterCommission := sdk.NewDec(100).Sub(commissionTaken)
|
||||||
|
selfDelegationReward := afterCommission.Quo(sdk.NewDec(2))
|
||||||
|
expRes := sdk.NewDec(90).Add(commissionTaken).Add(selfDelegationReward).TruncateInt() // 90 + 100 tokens * 10/20
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithdrawValidatorRewardsAllMultipleValidator(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//make some validators with different commissions
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr1, valConsPk1, 10, sdk.NewDecWithPrec(1, 1))
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
|
||||||
|
msgCreateValidator = stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr2, valConsPk2, 50, sdk.NewDecWithPrec(2, 1))
|
||||||
|
got = stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
|
||||||
|
msgCreateValidator = stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr3, valConsPk3, 40, sdk.NewDecWithPrec(3, 1))
|
||||||
|
got = stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(1000)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// withdraw validator reward
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawValidatorRewardsAll(ctx, valOpAddr1)
|
||||||
|
amt := accMapper.GetAccount(ctx, valAccAddr1).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
|
feesInNonProposer := sdk.NewDecFromInt(feeInputs).Mul(sdk.NewDecWithPrec(95, 2))
|
||||||
|
feesInProposer := sdk.NewDecFromInt(feeInputs).Mul(sdk.NewDecWithPrec(5, 2))
|
||||||
|
expRes := sdk.NewDec(90). // orig tokens (100 - 10)
|
||||||
|
Add(feesInNonProposer.Quo(sdk.NewDec(10))). // validator 1 has 1/10 total power
|
||||||
|
Add(feesInProposer).
|
||||||
|
TruncateInt()
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithdrawValidatorRewardsAllMultipleDelegator(t *testing.T) {
|
||||||
|
ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||||
|
stakeHandler := stake.NewHandler(sk)
|
||||||
|
denom := sk.GetParams(ctx).BondDenom
|
||||||
|
|
||||||
|
//first make a validator with 10% commission
|
||||||
|
commissionRate := sdk.NewDecWithPrec(1, 1)
|
||||||
|
msgCreateValidator := stake.NewTestMsgCreateValidatorWithCommission(
|
||||||
|
valOpAddr1, valConsPk1, 10, sdk.NewDecWithPrec(1, 1))
|
||||||
|
got := stakeHandler(ctx, msgCreateValidator)
|
||||||
|
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||||
|
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
// delegate
|
||||||
|
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(90), amt.Int64())
|
||||||
|
|
||||||
|
msgDelegate = stake.NewTestMsgDelegate(delAddr2, valOpAddr1, 20)
|
||||||
|
got = stakeHandler(ctx, msgDelegate)
|
||||||
|
require.True(t, got.IsOK())
|
||||||
|
amt = accMapper.GetAccount(ctx, delAddr2).GetCoins().AmountOf(denom)
|
||||||
|
require.Equal(t, int64(80), amt.Int64())
|
||||||
|
|
||||||
|
// allocate 100 denom of fees
|
||||||
|
feeInputs := sdk.NewInt(100)
|
||||||
|
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||||
|
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||||
|
keeper.AllocateFees(ctx, sdk.OneDec(), valConsAddr1)
|
||||||
|
|
||||||
|
// withdraw validator reward
|
||||||
|
ctx = ctx.WithBlockHeight(1)
|
||||||
|
keeper.WithdrawValidatorRewardsAll(ctx, valOpAddr1)
|
||||||
|
amt = accMapper.GetAccount(ctx, valAccAddr1).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
|
commissionTaken := sdk.NewDec(100).Mul(commissionRate)
|
||||||
|
afterCommission := sdk.NewDec(100).Sub(commissionTaken)
|
||||||
|
expRes := sdk.NewDec(90).
|
||||||
|
Add(afterCommission.Quo(sdk.NewDec(4))).
|
||||||
|
Add(commissionTaken).
|
||||||
|
TruncateInt() // 90 + 100*90% tokens * 10/40
|
||||||
|
require.True(sdk.IntEq(t, expRes, amt))
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
// nolint
|
||||||
|
package tags
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ActionModifyWithdrawAddress = []byte("modify-withdraw-address")
|
||||||
|
ActionWithdrawDelegatorRewardsAll = []byte("withdraw-delegator-rewards-all")
|
||||||
|
ActionWithdrawDelegatorReward = []byte("withdraw-delegator-reward")
|
||||||
|
ActionWithdrawValidatorRewardsAll = []byte("withdraw-validator-rewards-all")
|
||||||
|
|
||||||
|
Action = sdk.TagAction
|
||||||
|
Validator = sdk.TagSrcValidator
|
||||||
|
Delegator = sdk.TagDelegator
|
||||||
|
)
|
|
@ -5,16 +5,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// distribution info for a delegation - used to determine entitled rewards
|
// distribution info for a delegation - used to determine entitled rewards
|
||||||
type DelegatorDistInfo struct {
|
type DelegationDistInfo struct {
|
||||||
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
|
||||||
ValOperatorAddr sdk.ValAddress `json:"val_operator_addr"`
|
ValOperatorAddr sdk.ValAddress `json:"val_operator_addr"`
|
||||||
WithdrawalHeight int64 `json:"withdrawal_height"` // last time this delegation withdrew rewards
|
WithdrawalHeight int64 `json:"withdrawal_height"` // last time this delegation withdrew rewards
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDelegatorDistInfo(delegatorAddr sdk.AccAddress, valOperatorAddr sdk.ValAddress,
|
func NewDelegationDistInfo(delegatorAddr sdk.AccAddress, valOperatorAddr sdk.ValAddress,
|
||||||
currentHeight int64) DelegatorDistInfo {
|
currentHeight int64) DelegationDistInfo {
|
||||||
|
|
||||||
return DelegatorDistInfo{
|
return DelegationDistInfo{
|
||||||
DelegatorAddr: delegatorAddr,
|
DelegatorAddr: delegatorAddr,
|
||||||
ValOperatorAddr: valOperatorAddr,
|
ValOperatorAddr: valOperatorAddr,
|
||||||
WithdrawalHeight: currentHeight,
|
WithdrawalHeight: currentHeight,
|
||||||
|
@ -22,9 +22,9 @@ func NewDelegatorDistInfo(delegatorAddr sdk.AccAddress, valOperatorAddr sdk.ValA
|
||||||
}
|
}
|
||||||
|
|
||||||
// withdraw rewards from delegator
|
// withdraw rewards from delegator
|
||||||
func (di DelegatorDistInfo) WithdrawRewards(fp FeePool, vi ValidatorDistInfo,
|
func (di DelegationDistInfo) WithdrawRewards(fp FeePool, vi ValidatorDistInfo,
|
||||||
height int64, totalBonded, vdTokens, totalDelShares, delegatorShares,
|
height int64, totalBonded, vdTokens, totalDelShares, delegatorShares,
|
||||||
commissionRate sdk.Dec) (DelegatorDistInfo, ValidatorDistInfo, FeePool, DecCoins) {
|
commissionRate sdk.Dec) (DelegationDistInfo, ValidatorDistInfo, FeePool, DecCoins) {
|
||||||
|
|
||||||
vi = vi.UpdateTotalDelAccum(height, totalDelShares)
|
vi = vi.UpdateTotalDelAccum(height, totalDelShares)
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,10 @@ func TestWithdrawRewards(t *testing.T) {
|
||||||
validatorDelShares := sdk.NewDec(10)
|
validatorDelShares := sdk.NewDec(10)
|
||||||
totalBondedTokens := validatorTokens.Add(sdk.NewDec(90)) // validator-1 is 10% of total power
|
totalBondedTokens := validatorTokens.Add(sdk.NewDec(90)) // validator-1 is 10% of total power
|
||||||
|
|
||||||
di1 := NewDelegatorDistInfo(delAddr1, valAddr1, height)
|
di1 := NewDelegationDistInfo(delAddr1, valAddr1, height)
|
||||||
di1Shares := sdk.NewDec(5) // this delegator has half the shares in the validator
|
di1Shares := sdk.NewDec(5) // this delegator has half the shares in the validator
|
||||||
|
|
||||||
di2 := NewDelegatorDistInfo(delAddr2, valAddr1, height)
|
di2 := NewDelegationDistInfo(delAddr2, valAddr1, height)
|
||||||
di2Shares := sdk.NewDec(5)
|
di2Shares := sdk.NewDec(5)
|
||||||
|
|
||||||
// simulate adding some stake for inflation
|
// simulate adding some stake for inflation
|
||||||
|
|
|
@ -12,16 +12,25 @@ type DelegatorWithdrawInfo struct {
|
||||||
// GenesisState - all distribution state that must be provided at genesis
|
// GenesisState - all distribution state that must be provided at genesis
|
||||||
type GenesisState struct {
|
type GenesisState struct {
|
||||||
FeePool FeePool `json:"fee_pool"`
|
FeePool FeePool `json:"fee_pool"`
|
||||||
|
CommunityTax sdk.Dec `json:"community_tax"`
|
||||||
|
BaseProposerReward sdk.Dec `json:"base_proposer_reward"`
|
||||||
|
BonusProposerReward sdk.Dec `json:"bonus_proposer_reward"`
|
||||||
ValidatorDistInfos []ValidatorDistInfo `json:"validator_dist_infos"`
|
ValidatorDistInfos []ValidatorDistInfo `json:"validator_dist_infos"`
|
||||||
DelegatorDistInfos []DelegatorDistInfo `json:"delegator_dist_infos"`
|
DelegationDistInfos []DelegationDistInfo `json:"delegator_dist_infos"`
|
||||||
DelegatorWithdrawInfos []DelegatorWithdrawInfo `json:"delegator_withdraw_infos"`
|
DelegatorWithdrawInfos []DelegatorWithdrawInfo `json:"delegator_withdraw_infos"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGenesisState(feePool FeePool, vdis []ValidatorDistInfo, ddis []DelegatorDistInfo) GenesisState {
|
func NewGenesisState(feePool FeePool, communityTax, baseProposerReward, bonusProposerReward sdk.Dec,
|
||||||
|
vdis []ValidatorDistInfo, ddis []DelegationDistInfo, dwis []DelegatorWithdrawInfo) GenesisState {
|
||||||
|
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
FeePool: feePool,
|
FeePool: feePool,
|
||||||
|
CommunityTax: communityTax,
|
||||||
|
BaseProposerReward: baseProposerReward,
|
||||||
|
BonusProposerReward: bonusProposerReward,
|
||||||
ValidatorDistInfos: vdis,
|
ValidatorDistInfos: vdis,
|
||||||
DelegatorDistInfos: ddis,
|
DelegationDistInfos: ddis,
|
||||||
|
DelegatorWithdrawInfos: dwis,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,5 +38,30 @@ func NewGenesisState(feePool FeePool, vdis []ValidatorDistInfo, ddis []Delegator
|
||||||
func DefaultGenesisState() GenesisState {
|
func DefaultGenesisState() GenesisState {
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
FeePool: InitialFeePool(),
|
FeePool: InitialFeePool(),
|
||||||
|
CommunityTax: sdk.NewDecWithPrec(2, 2), // 2%
|
||||||
|
BaseProposerReward: sdk.NewDecWithPrec(1, 2), // 1%
|
||||||
|
BonusProposerReward: sdk.NewDecWithPrec(4, 2), // 4%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// default genesis utility function, initialize for starting validator set
|
||||||
|
func DefaultGenesisWithValidators(valAddrs []sdk.ValAddress) GenesisState {
|
||||||
|
|
||||||
|
vdis := make([]ValidatorDistInfo, len(valAddrs))
|
||||||
|
ddis := make([]DelegationDistInfo, len(valAddrs))
|
||||||
|
|
||||||
|
for i, valAddr := range valAddrs {
|
||||||
|
vdis[i] = NewValidatorDistInfo(valAddr, 0)
|
||||||
|
accAddr := sdk.AccAddress(valAddr)
|
||||||
|
ddis[i] = NewDelegationDistInfo(accAddr, valAddr, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenesisState{
|
||||||
|
FeePool: InitialFeePool(),
|
||||||
|
CommunityTax: sdk.NewDecWithPrec(2, 2), // 2%
|
||||||
|
BaseProposerReward: sdk.NewDecWithPrec(1, 2), // 1%
|
||||||
|
BonusProposerReward: sdk.NewDecWithPrec(4, 2), // 4%
|
||||||
|
ValidatorDistInfos: vdis,
|
||||||
|
DelegationDistInfos: ddis,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ var (
|
||||||
valPk1 = ed25519.GenPrivKey().PubKey()
|
valPk1 = ed25519.GenPrivKey().PubKey()
|
||||||
valPk2 = ed25519.GenPrivKey().PubKey()
|
valPk2 = ed25519.GenPrivKey().PubKey()
|
||||||
valPk3 = ed25519.GenPrivKey().PubKey()
|
valPk3 = ed25519.GenPrivKey().PubKey()
|
||||||
valAddr1 = sdk.ValAddress(delPk1.Address())
|
valAddr1 = sdk.ValAddress(valPk1.Address())
|
||||||
valAddr2 = sdk.ValAddress(delPk2.Address())
|
valAddr2 = sdk.ValAddress(valPk2.Address())
|
||||||
valAddr3 = sdk.ValAddress(delPk3.Address())
|
valAddr3 = sdk.ValAddress(valPk3.Address())
|
||||||
emptyValAddr sdk.ValAddress
|
emptyValAddr sdk.ValAddress
|
||||||
|
|
||||||
emptyPubkey crypto.PubKey
|
emptyPubkey crypto.PubKey
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
common "github.com/tendermint/tendermint/libs/common"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
|
@ -81,7 +82,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
||||||
// Initially this is the same as the initial validator set
|
// Initially this is the same as the initial validator set
|
||||||
nextValidators := validators
|
nextValidators := validators
|
||||||
|
|
||||||
header := abci.Header{Height: 0, Time: timestamp}
|
header := abci.Header{Height: 0, Time: timestamp, ProposerAddress: randomProposer(r, validators)}
|
||||||
opCount := 0
|
opCount := 0
|
||||||
|
|
||||||
// Setup code to catch SIGTERM's
|
// Setup code to catch SIGTERM's
|
||||||
|
@ -150,6 +151,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
||||||
res := app.EndBlock(abci.RequestEndBlock{})
|
res := app.EndBlock(abci.RequestEndBlock{})
|
||||||
header.Height++
|
header.Height++
|
||||||
header.Time = header.Time.Add(time.Duration(minTimePerBlock) * time.Second).Add(time.Duration(int64(r.Intn(int(timeDiff)))) * time.Second)
|
header.Time = header.Time.Add(time.Duration(minTimePerBlock) * time.Second).Add(time.Duration(int64(r.Intn(int(timeDiff)))) * time.Second)
|
||||||
|
header.ProposerAddress = randomProposer(r, validators)
|
||||||
logWriter("EndBlock")
|
logWriter("EndBlock")
|
||||||
|
|
||||||
if testingMode {
|
if testingMode {
|
||||||
|
@ -318,6 +320,21 @@ func getKeys(validators map[string]mockValidator) []string {
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// randomProposer picks a random proposer from the current validator set
|
||||||
|
func randomProposer(r *rand.Rand, validators map[string]mockValidator) common.HexBytes {
|
||||||
|
keys := getKeys(validators)
|
||||||
|
if len(keys) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
key := keys[r.Intn(len(keys))]
|
||||||
|
proposer := validators[key].val
|
||||||
|
pk, err := tmtypes.PB2TM.PubKey(proposer.PubKey)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return pk.Address()
|
||||||
|
}
|
||||||
|
|
||||||
// RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction
|
// RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction
|
||||||
// nolint: unparam
|
// nolint: unparam
|
||||||
func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64,
|
func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64,
|
||||||
|
|
|
@ -16,7 +16,7 @@ func TestCannotUnjailUnlessJailed(t *testing.T) {
|
||||||
slh := NewHandler(keeper)
|
slh := NewHandler(keeper)
|
||||||
amtInt := int64(100)
|
amtInt := int64(100)
|
||||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||||
msg := newTestMsgCreateValidator(addr, val, amt)
|
msg := NewTestMsgCreateValidator(addr, val, amt)
|
||||||
got := stake.NewHandler(sk)(ctx, msg)
|
got := stake.NewHandler(sk)(ctx, msg)
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
|
@ -41,7 +41,7 @@ func TestJailedValidatorDelegations(t *testing.T) {
|
||||||
valPubKey, bondAmount := pks[0], sdk.NewInt(amount)
|
valPubKey, bondAmount := pks[0], sdk.NewInt(amount)
|
||||||
valAddr, consAddr := addrs[1], sdk.ConsAddress(addrs[0])
|
valAddr, consAddr := addrs[1], sdk.ConsAddress(addrs[0])
|
||||||
|
|
||||||
msgCreateVal := newTestMsgCreateValidator(valAddr, valPubKey, bondAmount)
|
msgCreateVal := NewTestMsgCreateValidator(valAddr, valPubKey, bondAmount)
|
||||||
got := stake.NewHandler(stakeKeeper)(ctx, msgCreateVal)
|
got := stake.NewHandler(stakeKeeper)(ctx, msgCreateVal)
|
||||||
require.True(t, got.IsOK(), "expected create validator msg to be ok, got: %v", got)
|
require.True(t, got.IsOK(), "expected create validator msg to be ok, got: %v", got)
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||||
sk = sk.WithHooks(keeper.Hooks())
|
sk = sk.WithHooks(keeper.Hooks())
|
||||||
amtInt := int64(100)
|
amtInt := int64(100)
|
||||||
operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt))
|
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(operatorAddr, val, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
keeper.AddValidators(ctx, validatorUpdates)
|
||||||
|
@ -75,7 +75,7 @@ func TestSlashingPeriodCap(t *testing.T) {
|
||||||
amtInt := int64(100)
|
amtInt := int64(100)
|
||||||
operatorAddr, amt := addrs[0], sdk.NewInt(amtInt)
|
operatorAddr, amt := addrs[0], sdk.NewInt(amtInt)
|
||||||
valConsPubKey, valConsAddr := pks[0], pks[0].Address()
|
valConsPubKey, valConsAddr := pks[0], pks[0].Address()
|
||||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(operatorAddr, valConsPubKey, amt))
|
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(operatorAddr, valConsPubKey, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||||
|
@ -142,7 +142,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||||
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))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
keeper.AddValidators(ctx, validatorUpdates)
|
||||||
|
@ -294,7 +294,7 @@ func TestHandleNewValidator(t *testing.T) {
|
||||||
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
|
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
|
||||||
addr, val, amt := addrs[0], pks[0], int64(100)
|
addr, val, amt := addrs[0], pks[0], int64(100)
|
||||||
sh := stake.NewHandler(sk)
|
sh := stake.NewHandler(sk)
|
||||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, sdk.NewInt(amt)))
|
got := sh(ctx, NewTestMsgCreateValidator(addr, val, sdk.NewInt(amt)))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
keeper.AddValidators(ctx, validatorUpdates)
|
||||||
|
@ -332,7 +332,7 @@ func TestHandleAlreadyJailed(t *testing.T) {
|
||||||
amtInt := int64(100)
|
amtInt := int64(100)
|
||||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||||
sh := stake.NewHandler(sk)
|
sh := stake.NewHandler(sk)
|
||||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, amt))
|
got := sh(ctx, NewTestMsgCreateValidator(addr, val, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
keeper.AddValidators(ctx, validatorUpdates)
|
||||||
|
|
|
@ -111,7 +111,7 @@ func testAddr(addr string) sdk.AccAddress {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) stake.MsgCreateValidator {
|
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) stake.MsgCreateValidator {
|
||||||
commission := stake.NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
commission := stake.NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
||||||
return stake.MsgCreateValidator{
|
return stake.MsgCreateValidator{
|
||||||
Description: stake.Description{},
|
Description: stake.Description{},
|
||||||
|
|
|
@ -18,7 +18,7 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags
|
||||||
tags = sdk.NewTags("height", heightBytes)
|
tags = sdk.NewTags("height", heightBytes)
|
||||||
|
|
||||||
// Iterate over all the validators which *should* have signed this block
|
// Iterate over all the validators which *should* have signed this block
|
||||||
// Store whether or not they have actually signed it and slash/unbond any
|
// store whether or not they have actually signed it and slash/unbond any
|
||||||
// which have missed too many blocks in a row (downtime slashing)
|
// which have missed too many blocks in a row (downtime slashing)
|
||||||
for _, voteInfo := range req.LastCommitInfo.GetVotes() {
|
for _, voteInfo := range req.LastCommitInfo.GetVotes() {
|
||||||
sk.handleValidatorSignature(ctx, voteInfo.Validator.Address, voteInfo.Validator.Power, voteInfo.SignedLastBlock)
|
sk.handleValidatorSignature(ctx, voteInfo.Validator.Address, voteInfo.Validator.Power, voteInfo.SignedLastBlock)
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||||
addr, pk, amt := addrs[2], pks[2], sdk.NewInt(100)
|
addr, pk, amt := addrs[2], pks[2], sdk.NewInt(100)
|
||||||
|
|
||||||
// bond the validator
|
// bond the validator
|
||||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, pk, amt))
|
got := stake.NewHandler(sk)(ctx, NewTestMsgCreateValidator(addr, pk, amt))
|
||||||
require.True(t, got.IsOK())
|
require.True(t, got.IsOK())
|
||||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||||
keeper.AddValidators(ctx, validatorUpdates)
|
keeper.AddValidators(ctx, validatorUpdates)
|
||||||
|
|
|
@ -10,24 +10,6 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/x/params"
|
"github.com/cosmos/cosmos-sdk/x/params"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
priv1 = ed25519.GenPrivKey()
|
|
||||||
addr1 = sdk.AccAddress(priv1.PubKey().Address())
|
|
||||||
priv2 = ed25519.GenPrivKey()
|
|
||||||
addr2 = sdk.AccAddress(priv2.PubKey().Address())
|
|
||||||
addr3 = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
|
|
||||||
priv4 = ed25519.GenPrivKey()
|
|
||||||
addr4 = sdk.AccAddress(priv4.PubKey().Address())
|
|
||||||
coins = sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(10))}
|
|
||||||
fee = auth.NewStdFee(
|
|
||||||
100000,
|
|
||||||
sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(0))}...,
|
|
||||||
)
|
|
||||||
|
|
||||||
commissionMsg = NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// getMockApp returns an initialized mock application for this module.
|
// getMockApp returns an initialized mock application for this module.
|
||||||
|
|
|
@ -42,10 +42,13 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [
|
||||||
// Manually set indices for the first time
|
// Manually set indices for the first time
|
||||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||||
keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool)
|
keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool)
|
||||||
|
|
||||||
|
keeper.OnValidatorCreated(ctx, validator.OperatorAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, bond := range data.Bonds {
|
for _, delegation := range data.Bonds {
|
||||||
keeper.SetDelegation(ctx, bond)
|
keeper.SetDelegation(ctx, delegation)
|
||||||
|
keeper.OnDelegationCreated(ctx, delegation.DelegatorAddr, delegation.ValidatorAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
res = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
res = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
|
@ -106,7 +106,7 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k
|
||||||
|
|
||||||
validator := NewValidator(msg.ValidatorAddr, msg.PubKey, msg.Description)
|
validator := NewValidator(msg.ValidatorAddr, msg.PubKey, msg.Description)
|
||||||
commission := NewCommissionWithTime(
|
commission := NewCommissionWithTime(
|
||||||
msg.Commission.Rate, msg.Commission.MaxChangeRate,
|
msg.Commission.Rate, msg.Commission.MaxRate,
|
||||||
msg.Commission.MaxChangeRate, ctx.BlockHeader().Time,
|
msg.Commission.MaxChangeRate, ctx.BlockHeader().Time,
|
||||||
)
|
)
|
||||||
validator, err := validator.SetInitialCommission(commission)
|
validator, err := validator.SetInitialCommission(commission)
|
||||||
|
|
|
@ -7,8 +7,6 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
keep "github.com/cosmos/cosmos-sdk/x/stake/keeper"
|
keep "github.com/cosmos/cosmos-sdk/x/stake/keeper"
|
||||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||||
|
@ -16,31 +14,6 @@ import (
|
||||||
|
|
||||||
//______________________________________________________________________
|
//______________________________________________________________________
|
||||||
|
|
||||||
func newTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt int64) MsgCreateValidator {
|
|
||||||
return types.NewMsgCreateValidator(
|
|
||||||
address, pubKey, sdk.NewCoin("steak", sdk.NewInt(amt)), Description{}, commissionMsg,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt int64) MsgDelegate {
|
|
||||||
return MsgDelegate{
|
|
||||||
DelegatorAddr: delAddr,
|
|
||||||
ValidatorAddr: valAddr,
|
|
||||||
Delegation: sdk.NewCoin("steak", sdk.NewInt(amt)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTestMsgCreateValidatorOnBehalfOf(delAddr sdk.AccAddress, valAddr sdk.ValAddress, valPubKey crypto.PubKey, amt int64) MsgCreateValidator {
|
|
||||||
return MsgCreateValidator{
|
|
||||||
Description: Description{},
|
|
||||||
Commission: commissionMsg,
|
|
||||||
DelegatorAddr: delAddr,
|
|
||||||
ValidatorAddr: valAddr,
|
|
||||||
PubKey: valPubKey,
|
|
||||||
Delegation: sdk.NewCoin("steak", sdk.NewInt(amt)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve params which are instant
|
// retrieve params which are instant
|
||||||
func setInstantUnbondPeriod(keeper keep.Keeper, ctx sdk.Context) types.Params {
|
func setInstantUnbondPeriod(keeper keep.Keeper, ctx sdk.Context) types.Params {
|
||||||
params := keeper.GetParams(ctx)
|
params := keeper.GetParams(ctx)
|
||||||
|
@ -59,7 +32,7 @@ func TestValidatorByPowerIndex(t *testing.T) {
|
||||||
_ = setInstantUnbondPeriod(keeper, ctx)
|
_ = setInstantUnbondPeriod(keeper, ctx)
|
||||||
|
|
||||||
// create validator
|
// create validator
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got)
|
||||||
|
|
||||||
|
@ -83,7 +56,7 @@ func TestValidatorByPowerIndex(t *testing.T) {
|
||||||
require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power))
|
require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power))
|
||||||
|
|
||||||
// create a second validator keep it bonded
|
// create a second validator keep it bonded
|
||||||
msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, keep.PKs[2], int64(1000000))
|
msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], int64(1000000))
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got)
|
||||||
|
|
||||||
|
@ -146,7 +119,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) {
|
||||||
addr1, addr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1])
|
addr1, addr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1])
|
||||||
pk1, pk2 := keep.PKs[0], keep.PKs[1]
|
pk1, pk2 := keep.PKs[0], keep.PKs[1]
|
||||||
|
|
||||||
msgCreateValidator1 := newTestMsgCreateValidator(addr1, pk1, 10)
|
msgCreateValidator1 := NewTestMsgCreateValidator(addr1, pk1, 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper)
|
||||||
require.True(t, got.IsOK(), "%v", got)
|
require.True(t, got.IsOK(), "%v", got)
|
||||||
|
|
||||||
|
@ -162,17 +135,17 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) {
|
||||||
assert.Equal(t, Description{}, validator.Description)
|
assert.Equal(t, Description{}, validator.Description)
|
||||||
|
|
||||||
// two validators can't have the same operator address
|
// two validators can't have the same operator address
|
||||||
msgCreateValidator2 := newTestMsgCreateValidator(addr1, pk2, 10)
|
msgCreateValidator2 := NewTestMsgCreateValidator(addr1, pk2, 10)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator2, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator2, keeper)
|
||||||
require.False(t, got.IsOK(), "%v", got)
|
require.False(t, got.IsOK(), "%v", got)
|
||||||
|
|
||||||
// two validators can't have the same pubkey
|
// two validators can't have the same pubkey
|
||||||
msgCreateValidator3 := newTestMsgCreateValidator(addr2, pk1, 10)
|
msgCreateValidator3 := NewTestMsgCreateValidator(addr2, pk1, 10)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator3, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator3, keeper)
|
||||||
require.False(t, got.IsOK(), "%v", got)
|
require.False(t, got.IsOK(), "%v", got)
|
||||||
|
|
||||||
// must have different pubkey and operator
|
// must have different pubkey and operator
|
||||||
msgCreateValidator4 := newTestMsgCreateValidator(addr2, pk2, 10)
|
msgCreateValidator4 := NewTestMsgCreateValidator(addr2, pk2, 10)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper)
|
||||||
require.True(t, got.IsOK(), "%v", got)
|
require.True(t, got.IsOK(), "%v", got)
|
||||||
|
|
||||||
|
@ -197,7 +170,7 @@ func TestDuplicatesMsgCreateValidatorOnBehalfOf(t *testing.T) {
|
||||||
validatorAddr := sdk.ValAddress(keep.Addrs[0])
|
validatorAddr := sdk.ValAddress(keep.Addrs[0])
|
||||||
delegatorAddr := keep.Addrs[1]
|
delegatorAddr := keep.Addrs[1]
|
||||||
pk := keep.PKs[0]
|
pk := keep.PKs[0]
|
||||||
msgCreateValidatorOnBehalfOf := newTestMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr, pk, 10)
|
msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr, pk, 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper)
|
||||||
require.True(t, got.IsOK(), "%v", got)
|
require.True(t, got.IsOK(), "%v", got)
|
||||||
|
|
||||||
|
@ -232,7 +205,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
delAddr := keep.Addrs[1]
|
delAddr := keep.Addrs[1]
|
||||||
|
|
||||||
// create validator
|
// create validator
|
||||||
msgCreateVal := newTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount)
|
msgCreateVal := NewTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateVal, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateVal, keeper)
|
||||||
require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got)
|
||||||
|
|
||||||
|
@ -248,7 +221,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
require.Equal(t, bondAmount, validator.BondedTokens().RoundInt64())
|
require.Equal(t, bondAmount, validator.BondedTokens().RoundInt64())
|
||||||
|
|
||||||
// delegate tokens to the validator
|
// delegate tokens to the validator
|
||||||
msgDelegate := newTestMsgDelegate(delAddr, valAddr, bondAmount)
|
msgDelegate := NewTestMsgDelegate(delAddr, valAddr, bondAmount)
|
||||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
|
||||||
|
|
||||||
|
@ -283,12 +256,12 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt64())
|
require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt64())
|
||||||
|
|
||||||
// verify a delegator cannot create a new delegation to the now jailed validator
|
// verify a delegator cannot create a new delegation to the now jailed validator
|
||||||
msgDelegate = newTestMsgDelegate(delAddr, valAddr, bondAmount)
|
msgDelegate = NewTestMsgDelegate(delAddr, valAddr, bondAmount)
|
||||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.False(t, got.IsOK(), "expected delegation to not be ok, got %v", got)
|
require.False(t, got.IsOK(), "expected delegation to not be ok, got %v", got)
|
||||||
|
|
||||||
// verify the validator can still self-delegate
|
// verify the validator can still self-delegate
|
||||||
msgSelfDelegate := newTestMsgDelegate(sdk.AccAddress(valAddr), valAddr, bondAmount)
|
msgSelfDelegate := NewTestMsgDelegate(sdk.AccAddress(valAddr), valAddr, bondAmount)
|
||||||
got = handleMsgDelegate(ctx, msgSelfDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgSelfDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected delegation to not be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected delegation to not be ok, got %v", got)
|
||||||
|
|
||||||
|
@ -302,7 +275,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
|
||||||
keeper.Unjail(ctx, valConsAddr)
|
keeper.Unjail(ctx, valConsAddr)
|
||||||
|
|
||||||
// verify the validator can now accept delegations
|
// verify the validator can now accept delegations
|
||||||
msgDelegate = newTestMsgDelegate(delAddr, valAddr, bondAmount)
|
msgDelegate = NewTestMsgDelegate(delAddr, valAddr, bondAmount)
|
||||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
|
||||||
|
|
||||||
|
@ -328,7 +301,7 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
||||||
validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
|
validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
|
||||||
|
|
||||||
// first create validator
|
// first create validator
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], bondAmount)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], bondAmount)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got)
|
||||||
|
|
||||||
|
@ -354,7 +327,7 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
||||||
require.Equal(t, bondAmount, pool.BondedTokens.RoundInt64())
|
require.Equal(t, bondAmount, pool.BondedTokens.RoundInt64())
|
||||||
|
|
||||||
// just send the same msgbond multiple times
|
// just send the same msgbond multiple times
|
||||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, bondAmount)
|
msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, bondAmount)
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
ctx = ctx.WithBlockHeight(int64(i))
|
ctx = ctx.WithBlockHeight(int64(i))
|
||||||
|
@ -402,14 +375,14 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
||||||
// create validator, delegate
|
// create validator, delegate
|
||||||
validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
|
validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
|
||||||
|
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got)
|
||||||
|
|
||||||
// initial balance
|
// initial balance
|
||||||
amt1 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom)
|
amt1 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom)
|
||||||
|
|
||||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, initBond)
|
msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, initBond)
|
||||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
|
require.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
|
||||||
|
|
||||||
|
@ -505,7 +478,7 @@ func TestMultipleMsgCreateValidator(t *testing.T) {
|
||||||
|
|
||||||
// bond them all
|
// bond them all
|
||||||
for i, validatorAddr := range validatorAddrs {
|
for i, validatorAddr := range validatorAddrs {
|
||||||
msgCreateValidatorOnBehalfOf := newTestMsgCreateValidatorOnBehalfOf(delegatorAddrs[i], validatorAddr, keep.PKs[i], 10)
|
msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidatorOnBehalfOf(delegatorAddrs[i], validatorAddr, keep.PKs[i], 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper)
|
||||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||||
|
|
||||||
|
@ -552,13 +525,13 @@ func TestMultipleMsgDelegate(t *testing.T) {
|
||||||
_ = setInstantUnbondPeriod(keeper, ctx)
|
_ = setInstantUnbondPeriod(keeper, ctx)
|
||||||
|
|
||||||
//first make a validator
|
//first make a validator
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
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)
|
||||||
|
|
||||||
// delegate multiple parties
|
// delegate multiple parties
|
||||||
for i, delegatorAddr := range delegatorAddrs {
|
for i, delegatorAddr := range delegatorAddrs {
|
||||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
||||||
got := handleMsgDelegate(ctx, msgDelegate, keeper)
|
got := handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||||
|
|
||||||
|
@ -590,12 +563,12 @@ func TestJailValidator(t *testing.T) {
|
||||||
_ = setInstantUnbondPeriod(keeper, ctx)
|
_ = setInstantUnbondPeriod(keeper, ctx)
|
||||||
|
|
||||||
// create the validator
|
// create the validator
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
// bond a delegator
|
// bond a delegator
|
||||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
||||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected ok, got %v", got)
|
require.True(t, got.IsOK(), "expected ok, got %v", got)
|
||||||
|
|
||||||
|
@ -639,12 +612,12 @@ func TestValidatorQueue(t *testing.T) {
|
||||||
keeper.SetParams(ctx, params)
|
keeper.SetParams(ctx, params)
|
||||||
|
|
||||||
// create the validator
|
// create the validator
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
// bond a delegator
|
// bond a delegator
|
||||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
||||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected ok, got %v", got)
|
require.True(t, got.IsOK(), "expected ok, got %v", got)
|
||||||
|
|
||||||
|
@ -689,7 +662,7 @@ func TestUnbondingPeriod(t *testing.T) {
|
||||||
keeper.SetParams(ctx, params)
|
keeper.SetParams(ctx, params)
|
||||||
|
|
||||||
// create the validator
|
// create the validator
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
|
@ -727,12 +700,12 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) {
|
||||||
validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
|
validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
|
||||||
|
|
||||||
// create the validator
|
// create the validator
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
// bond a delegator
|
// bond a delegator
|
||||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
||||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected ok, got %v", got)
|
require.True(t, got.IsOK(), "expected ok, got %v", got)
|
||||||
|
|
||||||
|
@ -774,7 +747,7 @@ func TestRedelegationPeriod(t *testing.T) {
|
||||||
keeper.SetParams(ctx, params)
|
keeper.SetParams(ctx, params)
|
||||||
|
|
||||||
// create the validators
|
// create the validators
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
||||||
|
|
||||||
// initial balance
|
// initial balance
|
||||||
amt1 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom)
|
amt1 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom)
|
||||||
|
@ -786,7 +759,7 @@ func TestRedelegationPeriod(t *testing.T) {
|
||||||
amt2 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom)
|
amt2 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom)
|
||||||
require.Equal(t, amt1.Sub(sdk.NewInt(10)).Int64(), amt2.Int64(), "expected coins to be subtracted")
|
require.Equal(t, amt1.Sub(sdk.NewInt(10)).Int64(), amt2.Int64(), "expected coins to be subtracted")
|
||||||
|
|
||||||
msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 10)
|
msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 10)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
|
@ -833,15 +806,15 @@ func TestTransitiveRedelegation(t *testing.T) {
|
||||||
keeper.SetParams(ctx, params)
|
keeper.SetParams(ctx, params)
|
||||||
|
|
||||||
// create the validators
|
// create the validators
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 10)
|
msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 10)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10)
|
msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
|
@ -918,21 +891,21 @@ func TestUnbondingWhenExcessValidators(t *testing.T) {
|
||||||
keeper.SetParams(ctx, params)
|
keeper.SetParams(ctx, params)
|
||||||
|
|
||||||
// add three validators
|
// add three validators
|
||||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr1, keep.PKs[0], 50)
|
msgCreateValidator := NewTestMsgCreateValidator(validatorAddr1, keep.PKs[0], 50)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
// apply TM updates
|
// apply TM updates
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
require.Equal(t, 1, len(keeper.GetValidatorsBonded(ctx)))
|
require.Equal(t, 1, len(keeper.GetValidatorsBonded(ctx)))
|
||||||
|
|
||||||
msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 30)
|
msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 30)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
// apply TM updates
|
// apply TM updates
|
||||||
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
require.Equal(t, 2, len(keeper.GetValidatorsBonded(ctx)))
|
require.Equal(t, 2, len(keeper.GetValidatorsBonded(ctx)))
|
||||||
|
|
||||||
msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10)
|
msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
// apply TM updates
|
// apply TM updates
|
||||||
|
@ -962,16 +935,16 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) {
|
||||||
valA, valB, del := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2]
|
valA, valB, del := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2]
|
||||||
consAddr0 := sdk.ConsAddress(keep.PKs[0].Address())
|
consAddr0 := sdk.ConsAddress(keep.PKs[0].Address())
|
||||||
|
|
||||||
msgCreateValidator := newTestMsgCreateValidator(valA, keep.PKs[0], 10)
|
msgCreateValidator := NewTestMsgCreateValidator(valA, keep.PKs[0], 10)
|
||||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
msgCreateValidator = newTestMsgCreateValidator(valB, keep.PKs[1], 10)
|
msgCreateValidator = NewTestMsgCreateValidator(valB, keep.PKs[1], 10)
|
||||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||||
|
|
||||||
// delegate 10 stake
|
// delegate 10 stake
|
||||||
msgDelegate := newTestMsgDelegate(del, valA, 10)
|
msgDelegate := NewTestMsgDelegate(del, valA, 10)
|
||||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||||
require.True(t, got.IsOK(), "expected no error on runMsgDelegate")
|
require.True(t, got.IsOK(), "expected no error on runMsgDelegate")
|
||||||
|
|
||||||
|
|
|
@ -380,8 +380,6 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Co
|
||||||
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.Dec, err sdk.Error) {
|
||||||
|
|
||||||
k.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
|
||||||
|
|
||||||
// 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 {
|
||||||
|
@ -389,6 +387,8 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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())
|
err = types.ErrNotEnoughDelegationShares(k.Codespace(), delegation.Shares.String())
|
||||||
|
@ -430,7 +430,6 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA
|
||||||
k.RemoveValidator(ctx, validator.OperatorAddr)
|
k.RemoveValidator(ctx, validator.OperatorAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
k.OnDelegationSharesModified(ctx, delegation.DelegatorAddr, validator.OperatorAddr)
|
|
||||||
return amount, nil
|
return amount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,9 @@ func TestDelegation(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
validators[2] = testingUpdateValidator(keeper, ctx, validators[2])
|
validators[2] = TestingUpdateValidator(keeper, ctx, validators[2])
|
||||||
|
|
||||||
// first add a validators[0] to delegate too
|
// first add a validators[0] to delegate too
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ func TestUnbondDelegation(t *testing.T) {
|
||||||
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
|
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
require.Equal(t, int64(10), pool.BondedTokens.RoundInt64())
|
require.Equal(t, int64(10), pool.BondedTokens.RoundInt64())
|
||||||
|
@ -226,7 +226,7 @@ func TestUndelegateSelfDelegation(t *testing.T) {
|
||||||
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
selfDelegation := types.Delegation{
|
selfDelegation := types.Delegation{
|
||||||
DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()),
|
DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()),
|
||||||
|
@ -240,7 +240,7 @@ func TestUndelegateSelfDelegation(t *testing.T) {
|
||||||
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
delegation := types.Delegation{
|
delegation := types.Delegation{
|
||||||
DelegatorAddr: addrDels[0],
|
DelegatorAddr: addrDels[0],
|
||||||
|
@ -274,7 +274,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) {
|
||||||
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
selfDelegation := types.Delegation{
|
selfDelegation := types.Delegation{
|
||||||
DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()),
|
DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()),
|
||||||
|
@ -288,7 +288,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) {
|
||||||
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
delegation := types.Delegation{
|
delegation := types.Delegation{
|
||||||
DelegatorAddr: addrDels[0],
|
DelegatorAddr: addrDels[0],
|
||||||
|
@ -350,7 +350,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) {
|
||||||
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||||
selfDelegation := types.Delegation{
|
selfDelegation := types.Delegation{
|
||||||
|
@ -365,7 +365,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) {
|
||||||
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
delegation := types.Delegation{
|
delegation := types.Delegation{
|
||||||
DelegatorAddr: addrDels[0],
|
DelegatorAddr: addrDels[0],
|
||||||
|
@ -512,7 +512,7 @@ func TestRedelegateSelfDelegation(t *testing.T) {
|
||||||
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||||
selfDelegation := types.Delegation{
|
selfDelegation := types.Delegation{
|
||||||
|
@ -528,14 +528,14 @@ func TestRedelegateSelfDelegation(t *testing.T) {
|
||||||
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.NewDec(10))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator2 = testingUpdateValidator(keeper, ctx, validator2)
|
validator2 = TestingUpdateValidator(keeper, ctx, validator2)
|
||||||
require.Equal(t, sdk.Bonded, validator2.Status)
|
require.Equal(t, sdk.Bonded, validator2.Status)
|
||||||
|
|
||||||
// create a second delegation to this validator
|
// create a second delegation to this validator
|
||||||
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
delegation := types.Delegation{
|
delegation := types.Delegation{
|
||||||
DelegatorAddr: addrDels[0],
|
DelegatorAddr: addrDels[0],
|
||||||
|
@ -569,7 +569,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) {
|
||||||
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||||
selfDelegation := types.Delegation{
|
selfDelegation := types.Delegation{
|
||||||
|
@ -584,7 +584,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) {
|
||||||
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
delegation := types.Delegation{
|
delegation := types.Delegation{
|
||||||
DelegatorAddr: addrDels[0],
|
DelegatorAddr: addrDels[0],
|
||||||
|
@ -599,7 +599,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) {
|
||||||
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())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator2 = testingUpdateValidator(keeper, ctx, validator2)
|
validator2 = TestingUpdateValidator(keeper, ctx, validator2)
|
||||||
|
|
||||||
header := ctx.BlockHeader()
|
header := ctx.BlockHeader()
|
||||||
blockHeight := int64(10)
|
blockHeight := int64(10)
|
||||||
|
@ -653,7 +653,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) {
|
||||||
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10))
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
|
||||||
selfDelegation := types.Delegation{
|
selfDelegation := types.Delegation{
|
||||||
|
@ -669,7 +669,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) {
|
||||||
validator.BondIntraTxCounter = 1
|
validator.BondIntraTxCounter = 1
|
||||||
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
require.Equal(t, int64(10), issuedShares.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
delegation := types.Delegation{
|
delegation := types.Delegation{
|
||||||
DelegatorAddr: addrDels[0],
|
DelegatorAddr: addrDels[0],
|
||||||
|
@ -684,7 +684,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) {
|
||||||
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())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator2 = testingUpdateValidator(keeper, ctx, validator2)
|
validator2 = TestingUpdateValidator(keeper, ctx, validator2)
|
||||||
require.Equal(t, sdk.Bonded, validator2.Status)
|
require.Equal(t, sdk.Bonded, validator2.Status)
|
||||||
|
|
||||||
ctx = ctx.WithBlockHeight(10)
|
ctx = ctx.WithBlockHeight(10)
|
||||||
|
|
|
@ -29,7 +29,7 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) {
|
||||||
validator.BondIntraTxCounter = int16(i)
|
validator.BondIntraTxCounter = int16(i)
|
||||||
pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(amt))
|
pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(amt))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||||
}
|
}
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
|
|
|
@ -211,7 +211,8 @@ func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) b
|
||||||
return store.Has(power)
|
return store.Has(power)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator) types.Validator {
|
// update validator for testing
|
||||||
|
func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator) types.Validator {
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
keeper.SetValidator(ctx, validator)
|
keeper.SetValidator(ctx, validator)
|
||||||
keeper.SetValidatorByPowerIndex(ctx, validator, pool)
|
keeper.SetValidatorByPowerIndex(ctx, validator, pool)
|
||||||
|
|
|
@ -84,7 +84,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) {
|
||||||
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.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
testingUpdateValidator(keeper, ctx, validator)
|
TestingUpdateValidator(keeper, ctx, validator)
|
||||||
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.RoundInt64(), "\nvalidator %v\npool %v", validator, pool)
|
||||||
|
@ -98,7 +98,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) {
|
||||||
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.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool) // update the pool
|
keeper.SetPool(ctx, pool) // update the pool
|
||||||
testingUpdateValidator(keeper, ctx, validator) // update the validator, possibly kicking it out
|
TestingUpdateValidator(keeper, ctx, validator) // update the validator, possibly kicking it out
|
||||||
require.False(t, validatorByPowerIndexExists(keeper, ctx, power))
|
require.False(t, validatorByPowerIndexExists(keeper, ctx, power))
|
||||||
|
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
|
@ -135,7 +135,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) {
|
||||||
val, pool, _ = val.AddTokensFromDel(pool, sdk.NewInt(int64((i+1)*10)))
|
val, pool, _ = val.AddTokensFromDel(pool, sdk.NewInt(int64((i+1)*10)))
|
||||||
|
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
val = testingUpdateValidator(keeper, ctx, val)
|
val = TestingUpdateValidator(keeper, ctx, val)
|
||||||
validators[i] = val
|
validators[i] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) {
|
||||||
keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal, pool)
|
keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal, pool)
|
||||||
nextCliffVal, pool, _ = nextCliffVal.RemoveDelShares(pool, sdk.NewDec(21))
|
nextCliffVal, pool, _ = nextCliffVal.RemoveDelShares(pool, sdk.NewDec(21))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
nextCliffVal = testingUpdateValidator(keeper, ctx, nextCliffVal)
|
nextCliffVal = TestingUpdateValidator(keeper, ctx, nextCliffVal)
|
||||||
|
|
||||||
expectedValStatus := map[int]sdk.BondStatus{
|
expectedValStatus := map[int]sdk.BondStatus{
|
||||||
9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded,
|
9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded,
|
||||||
|
@ -178,7 +178,7 @@ func TestSlashToZeroPowerRemoved(t *testing.T) {
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64())
|
require.Equal(t, int64(100), validator.Tokens.RoundInt64())
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
keeper.SetValidatorByConsAddr(ctx, validator)
|
keeper.SetValidatorByConsAddr(ctx, validator)
|
||||||
validator = testingUpdateValidator(keeper, ctx, validator)
|
validator = TestingUpdateValidator(keeper, ctx, validator)
|
||||||
require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool)
|
require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool)
|
||||||
|
|
||||||
// slash the validator by 100%
|
// slash the validator by 100%
|
||||||
|
@ -223,7 +223,7 @@ func TestValidatorBasics(t *testing.T) {
|
||||||
assert.True(sdk.DecEq(t, sdk.ZeroDec(), pool.BondedTokens))
|
assert.True(sdk.DecEq(t, sdk.ZeroDec(), pool.BondedTokens))
|
||||||
|
|
||||||
// set and retrieve a record
|
// set and retrieve a record
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
keeper.SetValidatorByConsAddr(ctx, validators[0])
|
keeper.SetValidatorByConsAddr(ctx, validators[0])
|
||||||
resVal, found := keeper.GetValidator(ctx, addrVals[0])
|
resVal, found := keeper.GetValidator(ctx, addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
@ -250,7 +250,7 @@ func TestValidatorBasics(t *testing.T) {
|
||||||
validators[0].Status = sdk.Bonded
|
validators[0].Status = sdk.Bonded
|
||||||
validators[0].Tokens = sdk.NewDec(10)
|
validators[0].Tokens = sdk.NewDec(10)
|
||||||
validators[0].DelegatorShares = sdk.NewDec(10)
|
validators[0].DelegatorShares = sdk.NewDec(10)
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
resVal, found = keeper.GetValidator(ctx, addrVals[0])
|
resVal, found = keeper.GetValidator(ctx, addrVals[0])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
assert.True(ValEq(t, validators[0], resVal))
|
assert.True(ValEq(t, validators[0], resVal))
|
||||||
|
@ -260,8 +260,8 @@ func TestValidatorBasics(t *testing.T) {
|
||||||
assert.True(ValEq(t, validators[0], resVals[0]))
|
assert.True(ValEq(t, validators[0], resVals[0]))
|
||||||
|
|
||||||
// add other validators
|
// add other validators
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
validators[2] = testingUpdateValidator(keeper, ctx, validators[2])
|
validators[2] = TestingUpdateValidator(keeper, ctx, validators[2])
|
||||||
resVal, found = keeper.GetValidator(ctx, addrVals[1])
|
resVal, found = keeper.GetValidator(ctx, addrVals[1])
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
assert.True(ValEq(t, validators[1], resVal))
|
assert.True(ValEq(t, validators[1], resVal))
|
||||||
|
@ -294,7 +294,7 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
validators[i].Status = sdk.Bonded
|
validators[i].Status = sdk.Bonded
|
||||||
validators[i].Tokens = sdk.NewDec(amt)
|
validators[i].Tokens = sdk.NewDec(amt)
|
||||||
validators[i].DelegatorShares = sdk.NewDec(amt)
|
validators[i].DelegatorShares = sdk.NewDec(amt)
|
||||||
testingUpdateValidator(keeper, ctx, validators[i])
|
TestingUpdateValidator(keeper, ctx, validators[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
// first make sure everything made it in to the gotValidator group
|
// first make sure everything made it in to the gotValidator group
|
||||||
|
@ -313,14 +313,14 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
|
|
||||||
// test a basic increase in voting power
|
// test a basic increase in voting power
|
||||||
validators[3].Tokens = sdk.NewDec(500)
|
validators[3].Tokens = sdk.NewDec(500)
|
||||||
testingUpdateValidator(keeper, ctx, validators[3])
|
TestingUpdateValidator(keeper, ctx, validators[3])
|
||||||
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.NewDec(300)
|
||||||
testingUpdateValidator(keeper, ctx, validators[3])
|
TestingUpdateValidator(keeper, ctx, validators[3])
|
||||||
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]))
|
||||||
|
@ -329,7 +329,7 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
// test equal voting power, different age
|
// test equal voting power, different age
|
||||||
validators[3].Tokens = sdk.NewDec(200)
|
validators[3].Tokens = sdk.NewDec(200)
|
||||||
ctx = ctx.WithBlockHeight(10)
|
ctx = ctx.WithBlockHeight(10)
|
||||||
testingUpdateValidator(keeper, ctx, validators[3])
|
TestingUpdateValidator(keeper, ctx, validators[3])
|
||||||
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]))
|
||||||
|
@ -339,7 +339,7 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
|
|
||||||
// no change in voting power - no change in sort
|
// no change in voting power - no change in sort
|
||||||
ctx = ctx.WithBlockHeight(20)
|
ctx = ctx.WithBlockHeight(20)
|
||||||
testingUpdateValidator(keeper, ctx, validators[4])
|
TestingUpdateValidator(keeper, ctx, validators[4])
|
||||||
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]))
|
||||||
|
@ -348,11 +348,11 @@ func GetValidatorSortingUnmixed(t *testing.T) {
|
||||||
// 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.NewDec(300)
|
||||||
validators[4].Tokens = sdk.NewDec(300)
|
validators[4].Tokens = sdk.NewDec(300)
|
||||||
testingUpdateValidator(keeper, ctx, validators[3])
|
TestingUpdateValidator(keeper, ctx, validators[3])
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, len(resValidators), n)
|
require.Equal(t, len(resValidators), n)
|
||||||
ctx = ctx.WithBlockHeight(30)
|
ctx = ctx.WithBlockHeight(30)
|
||||||
testingUpdateValidator(keeper, ctx, validators[4])
|
TestingUpdateValidator(keeper, ctx, validators[4])
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, len(resValidators), n, "%v", resValidators)
|
require.Equal(t, len(resValidators), n, "%v", resValidators)
|
||||||
assert.True(ValEq(t, validators[3], resValidators[0]))
|
assert.True(ValEq(t, validators[3], resValidators[0]))
|
||||||
|
@ -390,7 +390,7 @@ func GetValidatorSortingMixed(t *testing.T) {
|
||||||
validators[4].Tokens = sdk.NewDec(amts[4])
|
validators[4].Tokens = sdk.NewDec(amts[4])
|
||||||
|
|
||||||
for i := range amts {
|
for i := range amts {
|
||||||
testingUpdateValidator(keeper, ctx, validators[i])
|
TestingUpdateValidator(keeper, ctx, validators[i])
|
||||||
}
|
}
|
||||||
val0, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0]))
|
val0, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0]))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
|
@ -444,7 +444,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||||
validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt))
|
validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt))
|
||||||
validators[i].BondIntraTxCounter = int16(i)
|
validators[i].BondIntraTxCounter = int16(i)
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[i] = testingUpdateValidator(keeper, ctx, validators[i])
|
validators[i] = TestingUpdateValidator(keeper, ctx, validators[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range amts {
|
for i := range amts {
|
||||||
|
@ -460,7 +460,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||||
keeper.DeleteValidatorByPowerIndex(ctx, validators[0], pool)
|
keeper.DeleteValidatorByPowerIndex(ctx, validators[0], pool)
|
||||||
validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(500))
|
validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(500))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, nMax, uint16(len(resValidators)))
|
require.Equal(t, nMax, uint16(len(resValidators)))
|
||||||
assert.True(ValEq(t, validators[0], resValidators[0]))
|
assert.True(ValEq(t, validators[0], resValidators[0]))
|
||||||
|
@ -478,7 +478,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||||
keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool)
|
keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool)
|
||||||
validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1))
|
validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[3] = testingUpdateValidator(keeper, ctx, validators[3])
|
validators[3] = TestingUpdateValidator(keeper, ctx, validators[3])
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, nMax, uint16(len(resValidators)))
|
require.Equal(t, nMax, uint16(len(resValidators)))
|
||||||
assert.True(ValEq(t, validators[0], resValidators[0]))
|
assert.True(ValEq(t, validators[0], resValidators[0]))
|
||||||
|
@ -488,7 +488,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||||
keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool)
|
keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool)
|
||||||
validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201))
|
validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[3] = testingUpdateValidator(keeper, ctx, validators[3])
|
validators[3] = TestingUpdateValidator(keeper, ctx, validators[3])
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, nMax, uint16(len(resValidators)))
|
require.Equal(t, nMax, uint16(len(resValidators)))
|
||||||
assert.True(ValEq(t, validators[0], resValidators[0]))
|
assert.True(ValEq(t, validators[0], resValidators[0]))
|
||||||
|
@ -498,7 +498,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) {
|
||||||
keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool)
|
keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool)
|
||||||
validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200))
|
validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[3] = testingUpdateValidator(keeper, ctx, validators[3])
|
validators[3] = TestingUpdateValidator(keeper, ctx, validators[3])
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, nMax, uint16(len(resValidators)))
|
require.Equal(t, nMax, uint16(len(resValidators)))
|
||||||
assert.True(ValEq(t, validators[0], resValidators[0]))
|
assert.True(ValEq(t, validators[0], resValidators[0]))
|
||||||
|
@ -531,13 +531,13 @@ func TestValidatorBondHeight(t *testing.T) {
|
||||||
validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(100))
|
validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(100))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
|
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
// If two validators both increase to the same voting power in the same block,
|
// If two validators both increase to the same voting power in the same block,
|
||||||
// the one with the first transaction should become bonded
|
// the one with the first transaction should become bonded
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
validators[2] = testingUpdateValidator(keeper, ctx, validators[2])
|
validators[2] = TestingUpdateValidator(keeper, ctx, validators[2])
|
||||||
|
|
||||||
pool = keeper.GetPool(ctx)
|
pool = keeper.GetPool(ctx)
|
||||||
|
|
||||||
|
@ -551,10 +551,10 @@ func TestValidatorBondHeight(t *testing.T) {
|
||||||
validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50))
|
validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50))
|
||||||
validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50))
|
validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[2] = testingUpdateValidator(keeper, ctx, validators[2])
|
validators[2] = TestingUpdateValidator(keeper, ctx, validators[2])
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
require.Equal(t, params.MaxValidators, uint16(len(resValidators)))
|
require.Equal(t, params.MaxValidators, uint16(len(resValidators)))
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
assert.True(ValEq(t, validators[0], resValidators[0]))
|
assert.True(ValEq(t, validators[0], resValidators[0]))
|
||||||
assert.True(ValEq(t, validators[2], resValidators[1]))
|
assert.True(ValEq(t, validators[2], resValidators[1]))
|
||||||
}
|
}
|
||||||
|
@ -575,7 +575,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) {
|
||||||
validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt))
|
validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt))
|
||||||
validators[i].BondIntraTxCounter = int16(i)
|
validators[i].BondIntraTxCounter = int16(i)
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
testingUpdateValidator(keeper, ctx, validators[i])
|
TestingUpdateValidator(keeper, ctx, validators[i])
|
||||||
}
|
}
|
||||||
for i := range amts {
|
for i := range amts {
|
||||||
var found bool
|
var found bool
|
||||||
|
@ -596,7 +596,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) {
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(600))
|
validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(600))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
resValidators = keeper.GetBondedValidatorsByPower(ctx)
|
||||||
assert.Equal(t, max, len(resValidators))
|
assert.Equal(t, max, len(resValidators))
|
||||||
assert.True(ValEq(t, validators[0], resValidators[0]))
|
assert.True(ValEq(t, validators[0], resValidators[0]))
|
||||||
|
@ -647,14 +647,14 @@ func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) {
|
||||||
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)
|
||||||
}
|
}
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
||||||
|
|
||||||
// test identical,
|
// test identical,
|
||||||
// tendermintUpdate set: {} -> {}
|
// tendermintUpdate set: {} -> {}
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,15 +669,15 @@ func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) {
|
||||||
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)
|
||||||
}
|
}
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
||||||
|
|
||||||
// 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.NewDec(600)
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
|
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
|
|
||||||
|
@ -696,8 +696,8 @@ func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) {
|
||||||
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)
|
||||||
}
|
}
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
||||||
|
|
||||||
// test multiple value change
|
// test multiple value change
|
||||||
|
@ -706,8 +706,8 @@ func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) {
|
||||||
validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(190))
|
validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(190))
|
||||||
validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(80))
|
validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(80))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
|
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
require.Equal(t, 2, len(updates))
|
require.Equal(t, 2, len(updates))
|
||||||
|
@ -726,8 +726,8 @@ func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) {
|
||||||
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)
|
||||||
}
|
}
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
||||||
|
|
||||||
// test validtor added at the beginning
|
// test validtor added at the beginning
|
||||||
|
@ -775,13 +775,13 @@ func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) {
|
||||||
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)
|
||||||
}
|
}
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
||||||
|
|
||||||
// test validator added at the end but not inserted in the valset
|
// test validator added at the end but not inserted in the valset
|
||||||
// tendermintUpdate set: {} -> {}
|
// tendermintUpdate set: {} -> {}
|
||||||
testingUpdateValidator(keeper, ctx, validators[2])
|
TestingUpdateValidator(keeper, ctx, validators[2])
|
||||||
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||||
require.Equal(t, 0, len(updates))
|
require.Equal(t, 0, len(updates))
|
||||||
|
|
||||||
|
@ -813,8 +813,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) {
|
||||||
validators[i].BondIntraTxCounter = int16(i)
|
validators[i].BondIntraTxCounter = int16(i)
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
}
|
}
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx)))
|
||||||
|
|
||||||
// check initial power
|
// check initial power
|
||||||
|
@ -827,8 +827,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) {
|
||||||
validators[0], pool, _ = validators[0].RemoveDelShares(pool, sdk.NewDec(20))
|
validators[0], pool, _ = validators[0].RemoveDelShares(pool, sdk.NewDec(20))
|
||||||
validators[1], pool, _ = validators[1].RemoveDelShares(pool, sdk.NewDec(30))
|
validators[1], pool, _ = validators[1].RemoveDelShares(pool, sdk.NewDec(30))
|
||||||
keeper.SetPool(ctx, pool)
|
keeper.SetPool(ctx, pool)
|
||||||
validators[0] = testingUpdateValidator(keeper, ctx, validators[0])
|
validators[0] = TestingUpdateValidator(keeper, ctx, validators[0])
|
||||||
validators[1] = testingUpdateValidator(keeper, ctx, validators[1])
|
validators[1] = TestingUpdateValidator(keeper, ctx, validators[1])
|
||||||
|
|
||||||
// power has changed
|
// power has changed
|
||||||
require.Equal(t, sdk.NewDec(80).RoundInt64(), validators[0].GetPower().RoundInt64())
|
require.Equal(t, sdk.NewDec(80).RoundInt64(), validators[0].GetPower().RoundInt64())
|
||||||
|
|
|
@ -16,7 +16,9 @@ import (
|
||||||
// SimulateMsgCreateValidator
|
// SimulateMsgCreateValidator
|
||||||
func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||||
handler := stake.NewHandler(k)
|
handler := stake.NewHandler(k)
|
||||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
|
accs []simulation.Account, event func(string)) (
|
||||||
|
action string, fOp []simulation.FutureOperation, err error) {
|
||||||
|
|
||||||
denom := k.GetParams(ctx).BondDenom
|
denom := k.GetParams(ctx).BondDenom
|
||||||
description := stake.Description{
|
description := stake.Description{
|
||||||
|
@ -71,7 +73,9 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation
|
||||||
// SimulateMsgEditValidator
|
// SimulateMsgEditValidator
|
||||||
func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
||||||
handler := stake.NewHandler(k)
|
handler := stake.NewHandler(k)
|
||||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
|
accs []simulation.Account, event func(string)) (
|
||||||
|
action string, fOp []simulation.FutureOperation, err error) {
|
||||||
|
|
||||||
description := stake.Description{
|
description := stake.Description{
|
||||||
Moniker: simulation.RandStringOfLength(r, 10),
|
Moniker: simulation.RandStringOfLength(r, 10),
|
||||||
|
@ -109,7 +113,9 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
||||||
// SimulateMsgDelegate
|
// SimulateMsgDelegate
|
||||||
func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||||
handler := stake.NewHandler(k)
|
handler := stake.NewHandler(k)
|
||||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
|
accs []simulation.Account, event func(string)) (
|
||||||
|
action string, fOp []simulation.FutureOperation, err error) {
|
||||||
|
|
||||||
denom := k.GetParams(ctx).BondDenom
|
denom := k.GetParams(ctx).BondDenom
|
||||||
validatorAcc := simulation.RandomAcc(r, accs)
|
validatorAcc := simulation.RandomAcc(r, accs)
|
||||||
|
@ -145,7 +151,9 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operat
|
||||||
// SimulateMsgBeginUnbonding
|
// SimulateMsgBeginUnbonding
|
||||||
func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||||
handler := stake.NewHandler(k)
|
handler := stake.NewHandler(k)
|
||||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
|
accs []simulation.Account, event func(string)) (
|
||||||
|
action string, fOp []simulation.FutureOperation, err error) {
|
||||||
|
|
||||||
denom := k.GetParams(ctx).BondDenom
|
denom := k.GetParams(ctx).BondDenom
|
||||||
validatorAcc := simulation.RandomAcc(r, accs)
|
validatorAcc := simulation.RandomAcc(r, accs)
|
||||||
|
@ -181,7 +189,9 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.
|
||||||
// SimulateMsgBeginRedelegate
|
// SimulateMsgBeginRedelegate
|
||||||
func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||||
handler := stake.NewHandler(k)
|
handler := stake.NewHandler(k)
|
||||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
|
accs []simulation.Account, event func(string)) (
|
||||||
|
action string, fOp []simulation.FutureOperation, err error) {
|
||||||
|
|
||||||
denom := k.GetParams(ctx).BondDenom
|
denom := k.GetParams(ctx).BondDenom
|
||||||
sourceValidatorAcc := simulation.RandomAcc(r, accs)
|
sourceValidatorAcc := simulation.RandomAcc(r, accs)
|
||||||
|
|
|
@ -56,6 +56,7 @@ var (
|
||||||
GetREDsFromValSrcIndexKey = keeper.GetREDsFromValSrcIndexKey
|
GetREDsFromValSrcIndexKey = keeper.GetREDsFromValSrcIndexKey
|
||||||
GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey
|
GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey
|
||||||
GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey
|
GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey
|
||||||
|
TestingUpdateValidator = keeper.TestingUpdateValidator
|
||||||
|
|
||||||
DefaultParamspace = keeper.DefaultParamspace
|
DefaultParamspace = keeper.DefaultParamspace
|
||||||
KeyInflationRateChange = types.KeyInflationRateChange
|
KeyInflationRateChange = types.KeyInflationRateChange
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package stake
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tendermint/tendermint/crypto"
|
||||||
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
priv1 = ed25519.GenPrivKey()
|
||||||
|
addr1 = sdk.AccAddress(priv1.PubKey().Address())
|
||||||
|
priv2 = ed25519.GenPrivKey()
|
||||||
|
addr2 = sdk.AccAddress(priv2.PubKey().Address())
|
||||||
|
addr3 = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
|
||||||
|
priv4 = ed25519.GenPrivKey()
|
||||||
|
addr4 = sdk.AccAddress(priv4.PubKey().Address())
|
||||||
|
coins = sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(10))}
|
||||||
|
fee = auth.NewStdFee(
|
||||||
|
100000,
|
||||||
|
sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(0))}...,
|
||||||
|
)
|
||||||
|
|
||||||
|
commissionMsg = NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt int64) MsgCreateValidator {
|
||||||
|
return types.NewMsgCreateValidator(
|
||||||
|
address, pubKey, sdk.NewCoin("steak", sdk.NewInt(amt)), Description{}, commissionMsg,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestMsgCreateValidatorWithCommission(address sdk.ValAddress, pubKey crypto.PubKey,
|
||||||
|
amt int64, commissionRate sdk.Dec) MsgCreateValidator {
|
||||||
|
|
||||||
|
commission := NewCommissionMsg(commissionRate, sdk.OneDec(), sdk.ZeroDec())
|
||||||
|
|
||||||
|
return types.NewMsgCreateValidator(
|
||||||
|
address, pubKey, sdk.NewCoin("steak", sdk.NewInt(amt)), Description{}, commission,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt int64) MsgDelegate {
|
||||||
|
return MsgDelegate{
|
||||||
|
DelegatorAddr: delAddr,
|
||||||
|
ValidatorAddr: valAddr,
|
||||||
|
Delegation: sdk.NewCoin("steak", sdk.NewInt(amt)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestMsgCreateValidatorOnBehalfOf(delAddr sdk.AccAddress, valAddr sdk.ValAddress, valPubKey crypto.PubKey, amt int64) MsgCreateValidator {
|
||||||
|
return MsgCreateValidator{
|
||||||
|
Description: Description{},
|
||||||
|
Commission: commissionMsg,
|
||||||
|
DelegatorAddr: delAddr,
|
||||||
|
ValidatorAddr: valAddr,
|
||||||
|
PubKey: valPubKey,
|
||||||
|
Delegation: sdk.NewCoin("steak", sdk.NewInt(amt)),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue