cosmos-sdk/x/distribution/abci_test.go

108 lines
4.3 KiB
Go

package distribution_test
import (
"testing"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
const (
totalValidators = 6
lazyValidatorIdx = 2
power = 100 / totalValidators
)
var (
valTokens = sdk.TokensFromConsensusPower(50, sdk.DefaultPowerReduction)
validatorCommissionRates = stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec())
)
type validator struct {
addr sdk.ValAddress
pubkey cryptotypes.PubKey
votes []abci.VoteInfo
}
// Context in https://github.com/cosmos/cosmos-sdk/issues/9161
func TestVerifyProposerRewardAssignement(t *testing.T) {
app := simapp.Setup(t, false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
addrs := simapp.AddTestAddrsIncremental(app, ctx, totalValidators, valTokens)
tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper)
tstaking.Commission = validatorCommissionRates
// create validators
validators := make([]validator, totalValidators-1)
for i := range validators {
validators[i].addr = sdk.ValAddress(addrs[i])
validators[i].pubkey = ed25519.GenPrivKey().PubKey()
validators[i].votes = make([]abci.VoteInfo, totalValidators)
tstaking.CreateValidatorWithValPower(validators[i].addr, validators[i].pubkey, power, true)
}
app.EndBlock(abci.RequestEndBlock{})
require.NotEmpty(t, app.Commit())
// verify validators lists
require.Len(t, app.StakingKeeper.GetAllValidators(ctx), totalValidators)
for i, val := range validators {
// verify all validator exists
require.NotNil(t, app.StakingKeeper.ValidatorByConsAddr(ctx, sdk.GetConsAddress(val.pubkey)))
// populate last commit info
voteInfos := []abci.VoteInfo{}
for _, val2 := range validators {
voteInfos = append(voteInfos, abci.VoteInfo{
Validator: abci.Validator{
Address: sdk.GetConsAddress(val2.pubkey),
Power: power,
},
SignedLastBlock: true,
})
}
// have this validator only submit the minimum amount of pre-commits
if i == lazyValidatorIdx {
for j := totalValidators * 2 / 3; j < len(voteInfos); j++ {
voteInfos[j].SignedLastBlock = false
}
}
validators[i].votes = voteInfos
}
// previous block submitted by validator n-1 (with 100% previous commits) and proposed by lazy validator
app.BeginBlock(abci.RequestBeginBlock{
Header: tmproto.Header{Height: app.LastBlockHeight() + 1, ProposerAddress: sdk.GetConsAddress(validators[lazyValidatorIdx].pubkey)},
LastCommitInfo: abci.LastCommitInfo{Votes: validators[lazyValidatorIdx-1].votes},
})
require.NotEmpty(t, app.Commit())
// previous block submitted by lazy validator (with 67% previous commits) and proposed by validator n+1
app.BeginBlock(abci.RequestBeginBlock{
Header: tmproto.Header{Height: app.LastBlockHeight() + 1, ProposerAddress: sdk.GetConsAddress(validators[lazyValidatorIdx+1].pubkey)},
LastCommitInfo: abci.LastCommitInfo{Votes: validators[lazyValidatorIdx].votes},
})
require.NotEmpty(t, app.Commit())
// previous block submitted by validator n+1 (with 100% previous commits) and proposed by validator n+2
app.BeginBlock(abci.RequestBeginBlock{
Header: tmproto.Header{Height: app.LastBlockHeight() + 1, ProposerAddress: sdk.GetConsAddress(validators[lazyValidatorIdx+2].pubkey)},
LastCommitInfo: abci.LastCommitInfo{Votes: validators[lazyValidatorIdx+1].votes},
})
require.NotEmpty(t, app.Commit())
rewardsValidatorBeforeLazyValidator := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, validators[lazyValidatorIdx+1].addr)
rewardsLazyValidator := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, validators[lazyValidatorIdx].addr)
rewardsValidatorAfterLazyValidator := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, validators[lazyValidatorIdx+1].addr)
require.True(t, rewardsLazyValidator[0].Amount.LT(rewardsValidatorAfterLazyValidator[0].Amount))
require.Equal(t, rewardsValidatorBeforeLazyValidator, rewardsValidatorAfterLazyValidator)
}