108 lines
4.3 KiB
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)
|
||
|
}
|