Merge Pr #5642: Remove x/mock
This commit is contained in:
parent
e44f914893
commit
05c21a534a
|
@ -16,6 +16,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
)
|
||||
|
||||
|
@ -43,9 +44,9 @@ func Setup(isCheckTx bool) *SimApp {
|
|||
return app
|
||||
}
|
||||
|
||||
// SetupWithGenesisAccounts initializes a new SimApp with the passed in
|
||||
// genesis accounts.
|
||||
func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount) *SimApp {
|
||||
// SetupWithGenesisAccounts initializes a new SimApp with the provided genesis
|
||||
// accounts and possible balances.
|
||||
func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances ...bank.Balance) *SimApp {
|
||||
db := dbm.NewMemDB()
|
||||
app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0)
|
||||
|
||||
|
@ -53,15 +54,16 @@ func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount) *SimApp {
|
|||
genesisState := NewDefaultGenesisState()
|
||||
|
||||
authGenesis := auth.NewGenesisState(auth.DefaultParams(), genAccs)
|
||||
genesisStateBz := app.Codec().MustMarshalJSON(authGenesis)
|
||||
genesisState[auth.ModuleName] = genesisStateBz
|
||||
genesisState[auth.ModuleName] = app.Codec().MustMarshalJSON(authGenesis)
|
||||
|
||||
bankGenesis := bank.NewGenesisState(bank.DefaultGenesisState().SendEnabled, balances)
|
||||
genesisState[bank.ModuleName] = app.Codec().MustMarshalJSON(bankGenesis)
|
||||
|
||||
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Initialize the chain
|
||||
app.InitChain(
|
||||
abci.RequestInitChain{
|
||||
Validators: []abci.ValidatorUpdate{},
|
||||
|
@ -91,6 +93,9 @@ func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sd
|
|||
|
||||
// fill all the addresses with some coins, set the loose pool tokens simultaneously
|
||||
for _, addr := range testAddrs {
|
||||
acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr)
|
||||
app.AccountKeeper.SetAccount(ctx, acc)
|
||||
|
||||
_, err := app.BankKeeper.AddCoins(ctx, addr, initCoins)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package gov
|
||||
package gov_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
@ -7,35 +7,38 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
keep "github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
)
|
||||
|
||||
func TestTickExpiredDepositPeriod(t *testing.T) {
|
||||
input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
|
||||
|
||||
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
govHandler := NewHandler(input.keeper)
|
||||
govHandler := gov.NewHandler(app.GovKeeper)
|
||||
|
||||
inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
newProposalMsg := NewMsgSubmitProposal(
|
||||
ContentFromProposalType("test", "test", ProposalTypeText),
|
||||
newProposalMsg := gov.NewMsgSubmitProposal(
|
||||
gov.ContentFromProposalType("test", "test", gov.ProposalTypeText),
|
||||
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
|
||||
input.addrs[0],
|
||||
addrs[0],
|
||||
)
|
||||
|
||||
res, err := govHandler(ctx, newProposalMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
|
@ -43,49 +46,50 @@ func TestTickExpiredDepositPeriod(t *testing.T) {
|
|||
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
newHeader = ctx.BlockHeader()
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod)
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.True(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
EndBlocker(ctx, input.keeper)
|
||||
gov.EndBlocker(ctx, app.GovKeeper)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
}
|
||||
|
||||
func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
|
||||
input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
|
||||
|
||||
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
govHandler := NewHandler(input.keeper)
|
||||
govHandler := gov.NewHandler(app.GovKeeper)
|
||||
|
||||
inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
newProposalMsg := NewMsgSubmitProposal(
|
||||
ContentFromProposalType("test", "test", ProposalTypeText),
|
||||
newProposalMsg := gov.NewMsgSubmitProposal(
|
||||
gov.ContentFromProposalType("test", "test", gov.ProposalTypeText),
|
||||
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
|
||||
input.addrs[0],
|
||||
addrs[0],
|
||||
)
|
||||
|
||||
res, err := govHandler(ctx, newProposalMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
|
@ -93,14 +97,14 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
|
|||
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(2) * time.Second)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
newProposalMsg2 := NewMsgSubmitProposal(
|
||||
ContentFromProposalType("test2", "test2", ProposalTypeText),
|
||||
newProposalMsg2 := gov.NewMsgSubmitProposal(
|
||||
gov.ContentFromProposalType("test2", "test2", gov.ProposalTypeText),
|
||||
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
|
||||
input.addrs[0],
|
||||
addrs[0],
|
||||
)
|
||||
|
||||
res, err = govHandler(ctx, newProposalMsg2)
|
||||
|
@ -108,14 +112,16 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
|
|||
require.NotNil(t, res)
|
||||
|
||||
newHeader = ctx.BlockHeader()
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(time.Duration(-1) * time.Second)
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(time.Duration(-1) * time.Second)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.True(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
EndBlocker(ctx, input.keeper)
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
|
||||
gov.EndBlocker(ctx, app.GovKeeper)
|
||||
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
|
@ -123,44 +129,47 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
|
|||
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(5) * time.Second)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.True(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
EndBlocker(ctx, input.keeper)
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
|
||||
gov.EndBlocker(ctx, app.GovKeeper)
|
||||
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
}
|
||||
|
||||
func TestTickPassedDepositPeriod(t *testing.T) {
|
||||
input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
|
||||
|
||||
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
govHandler := NewHandler(input.keeper)
|
||||
govHandler := gov.NewHandler(app.GovKeeper)
|
||||
|
||||
inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
activeQueue := input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
activeQueue := app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, activeQueue.Valid())
|
||||
activeQueue.Close()
|
||||
|
||||
newProposalMsg := NewMsgSubmitProposal(
|
||||
ContentFromProposalType("test2", "test2", ProposalTypeText),
|
||||
newProposalMsg := gov.NewMsgSubmitProposal(
|
||||
gov.ContentFromProposalType("test2", "test2", gov.ProposalTypeText),
|
||||
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
|
||||
input.addrs[0],
|
||||
addrs[0],
|
||||
)
|
||||
|
||||
res, err := govHandler(ctx, newProposalMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
|
||||
proposalID := GetProposalIDFromBytes(res.Data)
|
||||
proposalID := gov.GetProposalIDFromBytes(res.Data)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
|
@ -168,168 +177,173 @@ func TestTickPassedDepositPeriod(t *testing.T) {
|
|||
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
newDepositMsg := NewMsgDeposit(input.addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)})
|
||||
newDepositMsg := gov.NewMsgDeposit(addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)})
|
||||
|
||||
res, err = govHandler(ctx, newDepositMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
|
||||
activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
activeQueue = app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, activeQueue.Valid())
|
||||
activeQueue.Close()
|
||||
}
|
||||
|
||||
func TestTickPassedVotingPeriod(t *testing.T) {
|
||||
input := getMockApp(t, 10, GenesisState{}, nil, ProposalHandler)
|
||||
SortAddresses(input.addrs)
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
|
||||
|
||||
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
SortAddresses(addrs)
|
||||
|
||||
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
govHandler := NewHandler(input.keeper)
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
inactiveQueue := input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
govHandler := gov.NewHandler(app.GovKeeper)
|
||||
|
||||
inactiveQueue := app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
activeQueue := input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
activeQueue := app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, activeQueue.Valid())
|
||||
activeQueue.Close()
|
||||
|
||||
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(5))}
|
||||
newProposalMsg := NewMsgSubmitProposal(keep.TestProposal, proposalCoins, input.addrs[0])
|
||||
newProposalMsg := gov.NewMsgSubmitProposal(keep.TestProposal, proposalCoins, addrs[0])
|
||||
|
||||
res, err := govHandler(ctx, newProposalMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
|
||||
proposalID := GetProposalIDFromBytes(res.Data)
|
||||
proposalID := gov.GetProposalIDFromBytes(res.Data)
|
||||
|
||||
newHeader := ctx.BlockHeader()
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
newDepositMsg := NewMsgDeposit(input.addrs[1], proposalID, proposalCoins)
|
||||
newDepositMsg := gov.NewMsgDeposit(addrs[1], proposalID, proposalCoins)
|
||||
|
||||
res, err = govHandler(ctx, newDepositMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
|
||||
newHeader = ctx.BlockHeader()
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(app.GovKeeper.GetVotingParams(ctx).VotingPeriod)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
inactiveQueue = input.keeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
inactiveQueue = app.GovKeeper.InactiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, inactiveQueue.Valid())
|
||||
inactiveQueue.Close()
|
||||
|
||||
activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
activeQueue = app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.True(t, activeQueue.Valid())
|
||||
|
||||
activeProposalID := GetProposalIDFromBytes(activeQueue.Value())
|
||||
proposal, ok := input.keeper.GetProposal(ctx, activeProposalID)
|
||||
activeProposalID := gov.GetProposalIDFromBytes(activeQueue.Value())
|
||||
proposal, ok := app.GovKeeper.GetProposal(ctx, activeProposalID)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, StatusVotingPeriod, proposal.Status)
|
||||
require.Equal(t, gov.StatusVotingPeriod, proposal.Status)
|
||||
|
||||
activeQueue.Close()
|
||||
|
||||
EndBlocker(ctx, input.keeper)
|
||||
gov.EndBlocker(ctx, app.GovKeeper)
|
||||
|
||||
activeQueue = input.keeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
activeQueue = app.GovKeeper.ActiveProposalQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
require.False(t, activeQueue.Valid())
|
||||
activeQueue.Close()
|
||||
}
|
||||
|
||||
func TestProposalPassedEndblocker(t *testing.T) {
|
||||
input := getMockApp(t, 1, GenesisState{}, nil, ProposalHandler)
|
||||
SortAddresses(input.addrs)
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||
addrs := simapp.AddTestAddrs(app, ctx, 10, valTokens)
|
||||
|
||||
handler := NewHandler(input.keeper)
|
||||
stakingHandler := staking.NewHandler(input.sk)
|
||||
SortAddresses(addrs)
|
||||
|
||||
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
handler := gov.NewHandler(app.GovKeeper)
|
||||
stakingHandler := staking.NewHandler(app.StakingKeeper)
|
||||
|
||||
valAddr := sdk.ValAddress(input.addrs[0])
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
valAddr := sdk.ValAddress(addrs[0])
|
||||
|
||||
createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10})
|
||||
staking.EndBlocker(ctx, input.sk)
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
|
||||
macc := input.keeper.GetGovernanceAccount(ctx)
|
||||
macc := app.GovKeeper.GetGovernanceAccount(ctx)
|
||||
require.NotNil(t, macc)
|
||||
initialModuleAccCoins := input.bk.GetAllBalances(ctx, macc.GetAddress())
|
||||
initialModuleAccCoins := app.BankKeeper.GetAllBalances(ctx, macc.GetAddress())
|
||||
|
||||
proposal, err := input.keeper.SubmitProposal(ctx, keep.TestProposal)
|
||||
proposal, err := app.GovKeeper.SubmitProposal(ctx, keep.TestProposal)
|
||||
require.NoError(t, err)
|
||||
|
||||
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10))}
|
||||
newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
|
||||
newDepositMsg := gov.NewMsgDeposit(addrs[0], proposal.ProposalID, proposalCoins)
|
||||
|
||||
res, err := handler(ctx, newDepositMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
|
||||
macc = input.keeper.GetGovernanceAccount(ctx)
|
||||
macc = app.GovKeeper.GetGovernanceAccount(ctx)
|
||||
require.NotNil(t, macc)
|
||||
moduleAccCoins := input.bk.GetAllBalances(ctx, macc.GetAddress())
|
||||
moduleAccCoins := app.BankKeeper.GetAllBalances(ctx, macc.GetAddress())
|
||||
|
||||
deposits := initialModuleAccCoins.Add(proposal.TotalDeposit...).Add(proposalCoins...)
|
||||
require.True(t, moduleAccCoins.IsEqual(deposits))
|
||||
|
||||
err = input.keeper.AddVote(ctx, proposal.ProposalID, input.addrs[0], OptionYes)
|
||||
err = app.GovKeeper.AddVote(ctx, proposal.ProposalID, addrs[0], gov.OptionYes)
|
||||
require.NoError(t, err)
|
||||
|
||||
newHeader := ctx.BlockHeader()
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(app.GovKeeper.GetVotingParams(ctx).VotingPeriod)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
EndBlocker(ctx, input.keeper)
|
||||
gov.EndBlocker(ctx, app.GovKeeper)
|
||||
|
||||
macc = input.keeper.GetGovernanceAccount(ctx)
|
||||
macc = app.GovKeeper.GetGovernanceAccount(ctx)
|
||||
require.NotNil(t, macc)
|
||||
require.True(t, input.bk.GetAllBalances(ctx, macc.GetAddress()).IsEqual(initialModuleAccCoins))
|
||||
require.True(t, app.BankKeeper.GetAllBalances(ctx, macc.GetAddress()).IsEqual(initialModuleAccCoins))
|
||||
}
|
||||
|
||||
func TestEndBlockerProposalHandlerFailed(t *testing.T) {
|
||||
// hijack the router to one that will fail in a proposal's handler
|
||||
input := getMockApp(t, 1, GenesisState{}, nil, badProposalHandler)
|
||||
SortAddresses(input.addrs)
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||
addrs := simapp.AddTestAddrs(app, ctx, 1, valTokens)
|
||||
|
||||
handler := NewHandler(input.keeper)
|
||||
stakingHandler := staking.NewHandler(input.sk)
|
||||
SortAddresses(addrs)
|
||||
|
||||
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
handler := gov.NewHandler(app.GovKeeper)
|
||||
stakingHandler := staking.NewHandler(app.StakingKeeper)
|
||||
|
||||
valAddr := sdk.ValAddress(input.addrs[0])
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
valAddr := sdk.ValAddress(addrs[0])
|
||||
|
||||
createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10})
|
||||
staking.EndBlocker(ctx, input.sk)
|
||||
staking.EndBlocker(ctx, app.StakingKeeper)
|
||||
|
||||
// Create a proposal where the handler will pass for the test proposal
|
||||
// because the value of contextKeyBadProposal is true.
|
||||
ctx = ctx.WithValue(contextKeyBadProposal, true)
|
||||
proposal, err := input.keeper.SubmitProposal(ctx, keep.TestProposal)
|
||||
proposal, err := app.GovKeeper.SubmitProposal(ctx, keep.TestProposal)
|
||||
require.NoError(t, err)
|
||||
|
||||
proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)))
|
||||
newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
|
||||
newDepositMsg := gov.NewMsgDeposit(addrs[0], proposal.ProposalID, proposalCoins)
|
||||
|
||||
res, err := handler(ctx, newDepositMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
|
||||
err = input.keeper.AddVote(ctx, proposal.ProposalID, input.addrs[0], OptionYes)
|
||||
err = app.GovKeeper.AddVote(ctx, proposal.ProposalID, addrs[0], gov.OptionYes)
|
||||
require.NoError(t, err)
|
||||
|
||||
newHeader := ctx.BlockHeader()
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(app.GovKeeper.GetDepositParams(ctx).MaxDepositPeriod).Add(app.GovKeeper.GetVotingParams(ctx).VotingPeriod)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
// Set the contextKeyBadProposal value to false so that the handler will fail
|
||||
|
@ -337,5 +351,5 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
|
|||
ctx = ctx.WithValue(contextKeyBadProposal, false)
|
||||
|
||||
// validate that the proposal fails/has been rejected
|
||||
EndBlocker(ctx, input.keeper)
|
||||
gov.EndBlocker(ctx, app.GovKeeper)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package gov_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
keep "github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
)
|
||||
|
||||
var (
|
||||
valTokens = sdk.TokensFromConsensusPower(42)
|
||||
)
|
||||
|
||||
// SortAddresses - Sorts Addresses
|
||||
func SortAddresses(addrs []sdk.AccAddress) {
|
||||
byteAddrs := make([][]byte, len(addrs))
|
||||
|
||||
for i, addr := range addrs {
|
||||
byteAddrs[i] = addr.Bytes()
|
||||
}
|
||||
|
||||
SortByteArrays(byteAddrs)
|
||||
|
||||
for i, byteAddr := range byteAddrs {
|
||||
addrs[i] = byteAddr
|
||||
}
|
||||
}
|
||||
|
||||
// implement `Interface` in sort package.
|
||||
type sortByteArrays [][]byte
|
||||
|
||||
func (b sortByteArrays) Len() int {
|
||||
return len(b)
|
||||
}
|
||||
|
||||
func (b sortByteArrays) Less(i, j int) bool {
|
||||
// bytes package already implements Comparable for []byte.
|
||||
switch bytes.Compare(b[i], b[j]) {
|
||||
case -1:
|
||||
return true
|
||||
case 0, 1:
|
||||
return false
|
||||
default:
|
||||
log.Panic("not fail-able with `bytes.Comparable` bounded [-1, 1].")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (b sortByteArrays) Swap(i, j int) {
|
||||
b[j], b[i] = b[i], b[j]
|
||||
}
|
||||
|
||||
// SortByteArrays - sorts the provided byte array
|
||||
func SortByteArrays(src [][]byte) [][]byte {
|
||||
sorted := sortByteArrays(src)
|
||||
sort.Sort(sorted)
|
||||
return sorted
|
||||
}
|
||||
|
||||
const contextKeyBadProposal = "contextKeyBadProposal"
|
||||
|
||||
var (
|
||||
pubkeys = []crypto.PubKey{
|
||||
ed25519.GenPrivKey().PubKey(),
|
||||
ed25519.GenPrivKey().PubKey(),
|
||||
ed25519.GenPrivKey().PubKey(),
|
||||
}
|
||||
)
|
||||
|
||||
func createValidators(t *testing.T, stakingHandler sdk.Handler, ctx sdk.Context, addrs []sdk.ValAddress, powerAmt []int64) {
|
||||
require.True(t, len(addrs) <= len(pubkeys), "Not enough pubkeys specified at top of file.")
|
||||
|
||||
for i := 0; i < len(addrs); i++ {
|
||||
|
||||
valTokens := sdk.TokensFromConsensusPower(powerAmt[i])
|
||||
valCreateMsg := staking.NewMsgCreateValidator(
|
||||
addrs[i], pubkeys[i], sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
|
||||
keep.TestDescription, keep.TestCommissionRates, sdk.OneInt(),
|
||||
)
|
||||
|
||||
res, err := stakingHandler(ctx, valCreateMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
}
|
||||
}
|
|
@ -1,95 +1,126 @@
|
|||
package gov
|
||||
package gov_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
keep "github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
keep "github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
||||
)
|
||||
|
||||
func TestImportExportQueues(t *testing.T) {
|
||||
// Generate mock app and keepers
|
||||
input := getMockApp(t, 2, GenesisState{}, nil, ProposalHandler)
|
||||
SortAddresses(input.addrs)
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||
addrs := simapp.AddTestAddrs(app, ctx, 2, valTokens)
|
||||
|
||||
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
SortAddresses(addrs)
|
||||
|
||||
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
ctx = app.BaseApp.NewContext(false, abci.Header{})
|
||||
|
||||
// Create two proposals, put the second into the voting period
|
||||
proposal := keep.TestProposal
|
||||
proposal1, err := input.keeper.SubmitProposal(ctx, proposal)
|
||||
proposal1, err := app.GovKeeper.SubmitProposal(ctx, proposal)
|
||||
require.NoError(t, err)
|
||||
proposalID1 := proposal1.ProposalID
|
||||
|
||||
proposal2, err := input.keeper.SubmitProposal(ctx, proposal)
|
||||
proposal2, err := app.GovKeeper.SubmitProposal(ctx, proposal)
|
||||
require.NoError(t, err)
|
||||
proposalID2 := proposal2.ProposalID
|
||||
|
||||
votingStarted, err := input.keeper.AddDeposit(ctx, proposalID2, input.addrs[0], input.keeper.GetDepositParams(ctx).MinDeposit)
|
||||
votingStarted, err := app.GovKeeper.AddDeposit(ctx, proposalID2, addrs[0], app.GovKeeper.GetDepositParams(ctx).MinDeposit)
|
||||
require.NoError(t, err)
|
||||
require.True(t, votingStarted)
|
||||
|
||||
proposal1, ok := input.keeper.GetProposal(ctx, proposalID1)
|
||||
proposal1, ok := app.GovKeeper.GetProposal(ctx, proposalID1)
|
||||
require.True(t, ok)
|
||||
proposal2, ok = input.keeper.GetProposal(ctx, proposalID2)
|
||||
proposal2, ok = app.GovKeeper.GetProposal(ctx, proposalID2)
|
||||
require.True(t, ok)
|
||||
require.True(t, proposal1.Status == StatusDepositPeriod)
|
||||
require.True(t, proposal2.Status == StatusVotingPeriod)
|
||||
require.True(t, proposal1.Status == gov.StatusDepositPeriod)
|
||||
require.True(t, proposal2.Status == gov.StatusVotingPeriod)
|
||||
|
||||
genAccs := input.mApp.AccountKeeper.GetAllAccounts(ctx)
|
||||
authGenState := auth.ExportGenesis(ctx, app.AccountKeeper)
|
||||
|
||||
// Export the state and import it into a new Mock App
|
||||
genState := ExportGenesis(ctx, input.keeper)
|
||||
input2 := getMockApp(t, 2, genState, genAccs, ProposalHandler)
|
||||
// export the state and import it into a new app
|
||||
govGenState := gov.ExportGenesis(ctx, app.GovKeeper)
|
||||
|
||||
header = abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input2.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
db := dbm.NewMemDB()
|
||||
app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0)
|
||||
genesisState := simapp.NewDefaultGenesisState()
|
||||
|
||||
ctx2 := input2.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
genesisState[auth.ModuleName] = app.Codec().MustMarshalJSON(authGenState)
|
||||
genesisState[gov.ModuleName] = app.Codec().MustMarshalJSON(govGenState)
|
||||
|
||||
stateBytes, err := codec.MarshalJSONIndent(app2.Codec(), genesisState)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
app2.InitChain(
|
||||
abci.RequestInitChain{
|
||||
Validators: []abci.ValidatorUpdate{},
|
||||
AppStateBytes: stateBytes,
|
||||
},
|
||||
)
|
||||
|
||||
app2.Commit()
|
||||
app2.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: app2.LastBlockHeight() + 1}})
|
||||
|
||||
header = abci.Header{Height: app2.LastBlockHeight() + 1}
|
||||
app2.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
ctx2 := app2.BaseApp.NewContext(false, abci.Header{})
|
||||
|
||||
// Jump the time forward past the DepositPeriod and VotingPeriod
|
||||
ctx2 = ctx2.WithBlockTime(ctx2.BlockHeader().Time.Add(input2.keeper.GetDepositParams(ctx2).MaxDepositPeriod).Add(input2.keeper.GetVotingParams(ctx2).VotingPeriod))
|
||||
ctx2 = ctx2.WithBlockTime(ctx2.BlockHeader().Time.Add(app2.GovKeeper.GetDepositParams(ctx2).MaxDepositPeriod).Add(app2.GovKeeper.GetVotingParams(ctx2).VotingPeriod))
|
||||
|
||||
// Make sure that they are still in the DepositPeriod and VotingPeriod respectively
|
||||
proposal1, ok = input2.keeper.GetProposal(ctx2, proposalID1)
|
||||
proposal1, ok = app2.GovKeeper.GetProposal(ctx2, proposalID1)
|
||||
require.True(t, ok)
|
||||
proposal2, ok = input2.keeper.GetProposal(ctx2, proposalID2)
|
||||
proposal2, ok = app2.GovKeeper.GetProposal(ctx2, proposalID2)
|
||||
require.True(t, ok)
|
||||
require.True(t, proposal1.Status == StatusDepositPeriod)
|
||||
require.True(t, proposal2.Status == StatusVotingPeriod)
|
||||
require.True(t, proposal1.Status == gov.StatusDepositPeriod)
|
||||
require.True(t, proposal2.Status == gov.StatusVotingPeriod)
|
||||
|
||||
macc := input2.keeper.GetGovernanceAccount(ctx2)
|
||||
require.Equal(t, input2.keeper.GetDepositParams(ctx2).MinDeposit, input2.bk.GetAllBalances(ctx2, macc.GetAddress()))
|
||||
macc := app2.GovKeeper.GetGovernanceAccount(ctx2)
|
||||
require.Equal(t, app2.GovKeeper.GetDepositParams(ctx2).MinDeposit, app2.BankKeeper.GetAllBalances(ctx2, macc.GetAddress()))
|
||||
|
||||
// Run the endblocker. Check to make sure that proposal1 is removed from state, and proposal2 is finished VotingPeriod.
|
||||
EndBlocker(ctx2, input2.keeper)
|
||||
gov.EndBlocker(ctx2, app2.GovKeeper)
|
||||
|
||||
proposal1, ok = input2.keeper.GetProposal(ctx2, proposalID1)
|
||||
proposal1, ok = app2.GovKeeper.GetProposal(ctx2, proposalID1)
|
||||
require.False(t, ok)
|
||||
proposal2, ok = input2.keeper.GetProposal(ctx2, proposalID2)
|
||||
|
||||
proposal2, ok = app2.GovKeeper.GetProposal(ctx2, proposalID2)
|
||||
require.True(t, ok)
|
||||
require.True(t, proposal2.Status == StatusRejected)
|
||||
require.True(t, proposal2.Status == gov.StatusRejected)
|
||||
}
|
||||
|
||||
func TestEqualProposals(t *testing.T) {
|
||||
// Generate mock app and keepers
|
||||
input := getMockApp(t, 2, GenesisState{}, nil, ProposalHandler)
|
||||
SortAddresses(input.addrs)
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, abci.Header{})
|
||||
addrs := simapp.AddTestAddrs(app, ctx, 2, valTokens)
|
||||
|
||||
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
SortAddresses(addrs)
|
||||
|
||||
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
// Submit two proposals
|
||||
proposal := keep.TestProposal
|
||||
proposal1, err := input.keeper.SubmitProposal(ctx, proposal)
|
||||
proposal1, err := app.GovKeeper.SubmitProposal(ctx, proposal)
|
||||
require.NoError(t, err)
|
||||
proposal2, err := input.keeper.SubmitProposal(ctx, proposal)
|
||||
|
||||
proposal2, err := app.GovKeeper.SubmitProposal(ctx, proposal)
|
||||
require.NoError(t, err)
|
||||
|
||||
// They are similar but their IDs should be different
|
||||
|
@ -97,8 +128,8 @@ func TestEqualProposals(t *testing.T) {
|
|||
require.False(t, keep.ProposalEqual(proposal1, proposal2))
|
||||
|
||||
// Now create two genesis blocks
|
||||
state1 := GenesisState{Proposals: []Proposal{proposal1}}
|
||||
state2 := GenesisState{Proposals: []Proposal{proposal2}}
|
||||
state1 := gov.GenesisState{Proposals: []gov.Proposal{proposal1}}
|
||||
state2 := gov.GenesisState{Proposals: []gov.Proposal{proposal2}}
|
||||
require.NotEqual(t, state1, state2)
|
||||
require.False(t, state1.Equal(state2))
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package gov
|
||||
package gov_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
)
|
||||
|
||||
func TestInvalidMsg(t *testing.T) {
|
||||
k := Keeper{}
|
||||
h := NewHandler(k)
|
||||
k := gov.Keeper{}
|
||||
h := gov.NewHandler(k)
|
||||
|
||||
res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg())
|
||||
require.Error(t, err)
|
||||
|
|
|
@ -1,239 +0,0 @@
|
|||
// nolint
|
||||
// DONTCOVER
|
||||
package gov
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"log"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported"
|
||||
keep "github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported"
|
||||
)
|
||||
|
||||
var (
|
||||
valTokens = sdk.TokensFromConsensusPower(42)
|
||||
initTokens = sdk.TokensFromConsensusPower(100000)
|
||||
valCoins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, valTokens))
|
||||
initCoins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
|
||||
)
|
||||
|
||||
type testInput struct {
|
||||
mApp *mock.App
|
||||
keeper keep.Keeper
|
||||
router types.Router
|
||||
bk bank.Keeper
|
||||
sk staking.Keeper
|
||||
addrs []sdk.AccAddress
|
||||
pubKeys []crypto.PubKey
|
||||
privKeys []crypto.PrivKey
|
||||
}
|
||||
|
||||
func getMockApp(
|
||||
t *testing.T, numGenAccs int, genState types.GenesisState, genAccs []authexported.Account,
|
||||
handler func(ctx sdk.Context, c types.Content) error,
|
||||
) testInput {
|
||||
|
||||
mApp := mock.NewApp()
|
||||
|
||||
staking.RegisterCodec(mApp.Cdc)
|
||||
types.RegisterCodec(mApp.Cdc)
|
||||
supply.RegisterCodec(mApp.Cdc)
|
||||
|
||||
keyStaking := sdk.NewKVStoreKey(staking.StoreKey)
|
||||
keyGov := sdk.NewKVStoreKey(types.StoreKey)
|
||||
keySupply := sdk.NewKVStoreKey(supply.StoreKey)
|
||||
|
||||
govAcc := supply.NewEmptyModuleAccount(types.ModuleName, supply.Burner)
|
||||
notBondedPool := supply.NewEmptyModuleAccount(staking.NotBondedPoolName, supply.Burner, supply.Staking)
|
||||
bondPool := supply.NewEmptyModuleAccount(staking.BondedPoolName, supply.Burner, supply.Staking)
|
||||
|
||||
blacklistedAddrs := make(map[string]bool)
|
||||
blacklistedAddrs[govAcc.GetAddress().String()] = true
|
||||
blacklistedAddrs[notBondedPool.GetAddress().String()] = true
|
||||
blacklistedAddrs[bondPool.GetAddress().String()] = true
|
||||
|
||||
rtr := types.NewRouter().AddRoute(types.RouterKey, handler)
|
||||
maccPerms := map[string][]string{
|
||||
types.ModuleName: {supply.Burner},
|
||||
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
|
||||
staking.BondedPoolName: {supply.Burner, supply.Staking},
|
||||
}
|
||||
|
||||
pk := mApp.ParamsKeeper
|
||||
bk := mApp.BankKeeper
|
||||
supplyKeeper := supply.NewKeeper(mApp.Cdc, keySupply, mApp.AccountKeeper, bk, maccPerms)
|
||||
sk := staking.NewKeeper(
|
||||
staking.ModuleCdc, keyStaking, bk, supplyKeeper, pk.Subspace(staking.DefaultParamspace),
|
||||
)
|
||||
|
||||
keeper := keep.NewKeeper(
|
||||
mApp.Cdc, keyGov, pk.Subspace(DefaultParamspace).WithKeyTable(ParamKeyTable()), supplyKeeper, sk, rtr,
|
||||
)
|
||||
|
||||
mApp.Router().AddRoute(types.RouterKey, NewHandler(keeper))
|
||||
mApp.QueryRouter().AddRoute(types.QuerierRoute, keep.NewQuerier(keeper))
|
||||
|
||||
mApp.SetEndBlocker(getEndBlocker(keeper))
|
||||
mApp.SetInitChainer(getInitChainer(mApp, bk, keeper, sk, supplyKeeper, genAccs, genState,
|
||||
[]supplyexported.ModuleAccountI{govAcc, notBondedPool, bondPool}))
|
||||
|
||||
require.NoError(t, mApp.CompleteSetup(keyStaking, keyGov, keySupply))
|
||||
|
||||
var (
|
||||
genBalances []bankexported.GenesisBalance
|
||||
addrs []sdk.AccAddress
|
||||
pubKeys []crypto.PubKey
|
||||
privKeys []crypto.PrivKey
|
||||
)
|
||||
|
||||
if genAccs == nil || len(genAccs) == 0 {
|
||||
genAccs, genBalances, addrs, pubKeys, privKeys = mock.CreateGenAccounts(numGenAccs, valCoins)
|
||||
}
|
||||
|
||||
mock.SetGenesis(mApp, genAccs, genBalances)
|
||||
|
||||
return testInput{mApp, keeper, rtr, bk, sk, addrs, pubKeys, privKeys}
|
||||
}
|
||||
|
||||
// gov and staking endblocker
|
||||
func getEndBlocker(keeper Keeper) sdk.EndBlocker {
|
||||
return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
EndBlocker(ctx, keeper)
|
||||
return abci.ResponseEndBlock{}
|
||||
}
|
||||
}
|
||||
|
||||
// gov and staking initchainer
|
||||
func getInitChainer(mapp *mock.App, bk types.BankKeeper, keeper Keeper, stakingKeeper staking.Keeper, supplyKeeper supply.Keeper, accs []authexported.Account, genState GenesisState,
|
||||
blacklistedAddrs []supplyexported.ModuleAccountI) sdk.InitChainer {
|
||||
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||
mapp.InitChainer(ctx, req)
|
||||
|
||||
stakingGenesis := staking.DefaultGenesisState()
|
||||
|
||||
totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(mapp.GenesisAccounts)))))
|
||||
supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
|
||||
|
||||
// set module accounts
|
||||
for _, macc := range blacklistedAddrs {
|
||||
supplyKeeper.SetModuleAccount(ctx, macc)
|
||||
}
|
||||
|
||||
validators := staking.InitGenesis(ctx, stakingKeeper, mapp.AccountKeeper, bk, supplyKeeper, stakingGenesis)
|
||||
if genState.IsEmpty() {
|
||||
InitGenesis(ctx, bk, supplyKeeper, keeper, types.DefaultGenesisState())
|
||||
} else {
|
||||
InitGenesis(ctx, bk, supplyKeeper, keeper, genState)
|
||||
}
|
||||
return abci.ResponseInitChain{
|
||||
Validators: validators,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SortAddresses - Sorts Addresses
|
||||
func SortAddresses(addrs []sdk.AccAddress) {
|
||||
var byteAddrs [][]byte
|
||||
for _, addr := range addrs {
|
||||
byteAddrs = append(byteAddrs, addr.Bytes())
|
||||
}
|
||||
SortByteArrays(byteAddrs)
|
||||
for i, byteAddr := range byteAddrs {
|
||||
addrs[i] = byteAddr
|
||||
}
|
||||
}
|
||||
|
||||
// implement `Interface` in sort package.
|
||||
type sortByteArrays [][]byte
|
||||
|
||||
func (b sortByteArrays) Len() int {
|
||||
return len(b)
|
||||
}
|
||||
|
||||
func (b sortByteArrays) Less(i, j int) bool {
|
||||
// bytes package already implements Comparable for []byte.
|
||||
switch bytes.Compare(b[i], b[j]) {
|
||||
case -1:
|
||||
return true
|
||||
case 0, 1:
|
||||
return false
|
||||
default:
|
||||
log.Panic("not fail-able with `bytes.Comparable` bounded [-1, 1].")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (b sortByteArrays) Swap(i, j int) {
|
||||
b[j], b[i] = b[i], b[j]
|
||||
}
|
||||
|
||||
// SortByteArrays - sorts the provided byte array
|
||||
func SortByteArrays(src [][]byte) [][]byte {
|
||||
sorted := sortByteArrays(src)
|
||||
sort.Sort(sorted)
|
||||
return sorted
|
||||
}
|
||||
|
||||
const contextKeyBadProposal = "contextKeyBadProposal"
|
||||
|
||||
// badProposalHandler implements a governance proposal handler that is identical
|
||||
// to the actual handler except this fails if the context doesn't contain a value
|
||||
// for the key contextKeyBadProposal or if the value is false.
|
||||
func badProposalHandler(ctx sdk.Context, c types.Content) error {
|
||||
switch c.ProposalType() {
|
||||
case types.ProposalTypeText:
|
||||
v := ctx.Value(contextKeyBadProposal)
|
||||
|
||||
if v == nil || !v.(bool) {
|
||||
return errors.New("proposal failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
default:
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized gov proposal type: %s", c.ProposalType())
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
pubkeys = []crypto.PubKey{
|
||||
ed25519.GenPrivKey().PubKey(),
|
||||
ed25519.GenPrivKey().PubKey(),
|
||||
ed25519.GenPrivKey().PubKey(),
|
||||
}
|
||||
)
|
||||
|
||||
func createValidators(t *testing.T, stakingHandler sdk.Handler, ctx sdk.Context, addrs []sdk.ValAddress, powerAmt []int64) {
|
||||
require.True(t, len(addrs) <= len(pubkeys), "Not enough pubkeys specified at top of file.")
|
||||
|
||||
for i := 0; i < len(addrs); i++ {
|
||||
|
||||
valTokens := sdk.TokensFromConsensusPower(powerAmt[i])
|
||||
valCreateMsg := staking.NewMsgCreateValidator(
|
||||
addrs[i], pubkeys[i], sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
|
||||
keep.TestDescription, keep.TestCommissionRates, sdk.OneInt(),
|
||||
)
|
||||
|
||||
res, err := stakingHandler(ctx, valCreateMsg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
}
|
||||
}
|
339
x/mock/app.go
339
x/mock/app.go
|
@ -1,339 +0,0 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
const chainID = ""
|
||||
|
||||
// App extends an ABCI application, but with most of its parameters exported.
|
||||
// They are exported for convenience in creating helper functions, as object
|
||||
// capabilities aren't needed for testing.
|
||||
type App struct {
|
||||
*bam.BaseApp
|
||||
Cdc *codec.Codec // Cdc is public since the codec is passed into the module anyways
|
||||
KeyMain *sdk.KVStoreKey
|
||||
KeyAccount *sdk.KVStoreKey
|
||||
KeyBank *sdk.KVStoreKey
|
||||
KeyParams *sdk.KVStoreKey
|
||||
TKeyParams *sdk.TransientStoreKey
|
||||
|
||||
// TODO: Abstract this out from not needing to be auth specifically
|
||||
AccountKeeper auth.AccountKeeper
|
||||
BankKeeper bank.Keeper
|
||||
ParamsKeeper params.Keeper
|
||||
|
||||
GenesisAccounts []authexported.Account
|
||||
GenesisBalances []bankexported.GenesisBalance
|
||||
TotalCoinsSupply sdk.Coins
|
||||
}
|
||||
|
||||
// NewApp partially constructs a new app on the memstore for module and genesis
|
||||
// testing.
|
||||
func NewApp() *App {
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
||||
db := dbm.NewMemDB()
|
||||
|
||||
// Create the cdc with some standard codecs
|
||||
cdc := createCodec()
|
||||
|
||||
// Create your application object
|
||||
app := &App{
|
||||
BaseApp: bam.NewBaseApp("mock", logger, db, auth.DefaultTxDecoder(cdc)),
|
||||
Cdc: cdc,
|
||||
KeyMain: sdk.NewKVStoreKey(bam.MainStoreKey),
|
||||
KeyAccount: sdk.NewKVStoreKey(auth.StoreKey),
|
||||
KeyBank: sdk.NewKVStoreKey(bank.StoreKey),
|
||||
KeyParams: sdk.NewKVStoreKey("params"),
|
||||
TKeyParams: sdk.NewTransientStoreKey("transient_params"),
|
||||
TotalCoinsSupply: sdk.NewCoins(),
|
||||
}
|
||||
|
||||
app.ParamsKeeper = params.NewKeeper(params.ModuleCdc, app.KeyParams, app.TKeyParams)
|
||||
app.AccountKeeper = auth.NewAccountKeeper(
|
||||
app.Cdc,
|
||||
app.KeyAccount,
|
||||
app.ParamsKeeper.Subspace(auth.DefaultParamspace),
|
||||
auth.ProtoBaseAccount,
|
||||
)
|
||||
app.BankKeeper = bank.NewBaseKeeper(
|
||||
app.Cdc,
|
||||
app.KeyBank,
|
||||
app.AccountKeeper,
|
||||
app.ParamsKeeper.Subspace(bank.DefaultParamspace),
|
||||
make(map[string]bool),
|
||||
)
|
||||
supplyKeeper := NewDummySupplyKeeper(app.AccountKeeper, app.BankKeeper)
|
||||
|
||||
// Initialize the app. The chainers and blockers can be overwritten before
|
||||
// calling complete setup.
|
||||
app.SetInitChainer(app.InitChainer)
|
||||
app.SetAnteHandler(auth.NewAnteHandler(app.AccountKeeper, supplyKeeper, auth.DefaultSigVerificationGasConsumer))
|
||||
|
||||
// not sealing for custom extension
|
||||
return app
|
||||
}
|
||||
|
||||
// CompleteSetup completes the application setup after the routes have been
|
||||
// registered.
|
||||
func (app *App) CompleteSetup(newKeys ...sdk.StoreKey) error {
|
||||
newKeys = append(
|
||||
newKeys,
|
||||
app.KeyMain, app.KeyAccount, app.KeyBank, app.KeyParams, app.TKeyParams,
|
||||
)
|
||||
|
||||
for _, key := range newKeys {
|
||||
switch key.(type) {
|
||||
case *sdk.KVStoreKey:
|
||||
app.MountStore(key, sdk.StoreTypeIAVL)
|
||||
|
||||
case *sdk.TransientStoreKey:
|
||||
app.MountStore(key, sdk.StoreTypeTransient)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported StoreKey: %+v", key)
|
||||
}
|
||||
}
|
||||
|
||||
err := app.LoadLatestVersion(app.KeyMain)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// InitChainer performs custom logic for initialization.
|
||||
func (app *App) InitChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain {
|
||||
for _, genacc := range app.GenesisAccounts {
|
||||
acc := app.AccountKeeper.NewAccountWithAddress(ctx, genacc.GetAddress())
|
||||
app.AccountKeeper.SetAccount(ctx, acc)
|
||||
}
|
||||
|
||||
for _, balance := range app.GenesisBalances {
|
||||
app.BankKeeper.SetBalances(ctx, balance.GetAddress(), balance.GetCoins())
|
||||
}
|
||||
|
||||
auth.InitGenesis(ctx, app.AccountKeeper, auth.DefaultGenesisState())
|
||||
bank.InitGenesis(ctx, app.BankKeeper, bank.DefaultGenesisState())
|
||||
|
||||
return abci.ResponseInitChain{}
|
||||
}
|
||||
|
||||
// Type that combines an Address with the privKey and pubKey to that address
|
||||
type AddrKeys struct {
|
||||
Address sdk.AccAddress
|
||||
PubKey crypto.PubKey
|
||||
PrivKey crypto.PrivKey
|
||||
}
|
||||
|
||||
func NewAddrKeys(address sdk.AccAddress, pubKey crypto.PubKey,
|
||||
privKey crypto.PrivKey) AddrKeys {
|
||||
|
||||
return AddrKeys{
|
||||
Address: address,
|
||||
PubKey: pubKey,
|
||||
PrivKey: privKey,
|
||||
}
|
||||
}
|
||||
|
||||
// implement `Interface` in sort package.
|
||||
type AddrKeysSlice []AddrKeys
|
||||
|
||||
func (b AddrKeysSlice) Len() int {
|
||||
return len(b)
|
||||
}
|
||||
|
||||
// Sorts lexographically by Address
|
||||
func (b AddrKeysSlice) Less(i, j int) bool {
|
||||
// bytes package already implements Comparable for []byte.
|
||||
switch bytes.Compare(b[i].Address.Bytes(), b[j].Address.Bytes()) {
|
||||
case -1:
|
||||
return true
|
||||
case 0, 1:
|
||||
return false
|
||||
default:
|
||||
panic("not fail-able with `bytes.Comparable` bounded [-1, 1].")
|
||||
}
|
||||
}
|
||||
|
||||
func (b AddrKeysSlice) Swap(i, j int) {
|
||||
b[j], b[i] = b[i], b[j]
|
||||
}
|
||||
|
||||
// CreateGenAccounts generates genesis accounts loaded with coins, and returns
|
||||
// their addresses, pubkeys, and privkeys.
|
||||
func CreateGenAccounts(numAccs int, genCoins sdk.Coins) (
|
||||
genAccs []authexported.Account, genBalances []bankexported.GenesisBalance,
|
||||
addrs []sdk.AccAddress, pubKeys []crypto.PubKey, privKeys []crypto.PrivKey,
|
||||
) {
|
||||
|
||||
addrKeysSlice := AddrKeysSlice{}
|
||||
|
||||
for i := 0; i < numAccs; i++ {
|
||||
privKey := secp256k1.GenPrivKey()
|
||||
pubKey := privKey.PubKey()
|
||||
addr := sdk.AccAddress(pubKey.Address())
|
||||
|
||||
addrKeysSlice = append(addrKeysSlice, NewAddrKeys(addr, pubKey, privKey))
|
||||
}
|
||||
|
||||
sort.Sort(addrKeysSlice)
|
||||
|
||||
for i := range addrKeysSlice {
|
||||
addrs = append(addrs, addrKeysSlice[i].Address)
|
||||
pubKeys = append(pubKeys, addrKeysSlice[i].PubKey)
|
||||
privKeys = append(privKeys, addrKeysSlice[i].PrivKey)
|
||||
genAccs = append(genAccs, &auth.BaseAccount{
|
||||
Address: addrKeysSlice[i].Address,
|
||||
})
|
||||
genBalances = append(genBalances, bank.Balance{
|
||||
Address: addrKeysSlice[i].Address,
|
||||
Coins: genCoins,
|
||||
})
|
||||
}
|
||||
|
||||
return // nolint
|
||||
}
|
||||
|
||||
// SetGenesis sets the mock app genesis accounts.
|
||||
func SetGenesis(app *App, accs []authexported.Account, balances []bankexported.GenesisBalance) {
|
||||
// Pass the accounts in via the application (lazy) instead of through
|
||||
// RequestInitChain.
|
||||
app.GenesisAccounts = accs
|
||||
app.GenesisBalances = balances
|
||||
|
||||
app.InitChain(abci.RequestInitChain{})
|
||||
app.Commit()
|
||||
}
|
||||
|
||||
// GenTx generates a signed mock transaction.
|
||||
func GenTx(msgs []sdk.Msg, accnums []uint64, seq []uint64, priv ...crypto.PrivKey) auth.StdTx {
|
||||
// Make the transaction free
|
||||
fee := auth.StdFee{
|
||||
Amount: sdk.NewCoins(sdk.NewInt64Coin("foocoin", 0)),
|
||||
Gas: 100000,
|
||||
}
|
||||
|
||||
sigs := make([]auth.StdSignature, len(priv))
|
||||
memo := "testmemotestmemo"
|
||||
|
||||
for i, p := range priv {
|
||||
sig, err := p.Sign(auth.StdSignBytes(chainID, accnums[i], seq[i], fee, msgs, memo))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sigs[i] = auth.StdSignature{
|
||||
PubKey: p.PubKey(),
|
||||
Signature: sig,
|
||||
}
|
||||
}
|
||||
|
||||
return auth.NewStdTx(msgs, fee, sigs, memo)
|
||||
}
|
||||
|
||||
// GeneratePrivKeys generates a total n secp256k1 private keys.
|
||||
func GeneratePrivKeys(n int) (keys []crypto.PrivKey) {
|
||||
// TODO: Randomize this between ed25519 and secp256k1
|
||||
keys = make([]crypto.PrivKey, n)
|
||||
for i := 0; i < n; i++ {
|
||||
keys[i] = secp256k1.GenPrivKey()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GeneratePrivKeyAddressPairs generates a total of n private key, address
|
||||
// pairs.
|
||||
func GeneratePrivKeyAddressPairs(n int) (keys []crypto.PrivKey, addrs []sdk.AccAddress) {
|
||||
keys = make([]crypto.PrivKey, n)
|
||||
addrs = make([]sdk.AccAddress, n)
|
||||
for i := 0; i < n; i++ {
|
||||
if rand.Int63()%2 == 0 {
|
||||
keys[i] = secp256k1.GenPrivKey()
|
||||
} else {
|
||||
keys[i] = ed25519.GenPrivKey()
|
||||
}
|
||||
addrs[i] = sdk.AccAddress(keys[i].PubKey().Address())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GeneratePrivKeyAddressPairsFromRand generates a total of n private key, address
|
||||
// pairs using the provided randomness source.
|
||||
func GeneratePrivKeyAddressPairsFromRand(rand *rand.Rand, n int) (keys []crypto.PrivKey, addrs []sdk.AccAddress) {
|
||||
keys = make([]crypto.PrivKey, n)
|
||||
addrs = make([]sdk.AccAddress, n)
|
||||
for i := 0; i < n; i++ {
|
||||
secret := make([]byte, 32)
|
||||
_, err := rand.Read(secret)
|
||||
if err != nil {
|
||||
panic("Could not read randomness")
|
||||
}
|
||||
if rand.Int63()%2 == 0 {
|
||||
keys[i] = secp256k1.GenPrivKeySecp256k1(secret)
|
||||
} else {
|
||||
keys[i] = ed25519.GenPrivKeyFromSecret(secret)
|
||||
}
|
||||
addrs[i] = sdk.AccAddress(keys[i].PubKey().Address())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RandomSetGenesis set genesis accounts with random coin values using the
|
||||
// provided addresses and coin denominations.
|
||||
func RandomSetGenesis(r *rand.Rand, app *App, addrs []sdk.AccAddress, denoms []string) {
|
||||
accounts := make([]authexported.Account, len(addrs))
|
||||
balances := make([]bankexported.GenesisBalance, len(addrs))
|
||||
randCoinIntervals := []BigInterval{
|
||||
{sdk.NewIntWithDecimal(1, 0), sdk.NewIntWithDecimal(1, 1)},
|
||||
{sdk.NewIntWithDecimal(1, 2), sdk.NewIntWithDecimal(1, 3)},
|
||||
{sdk.NewIntWithDecimal(1, 40), sdk.NewIntWithDecimal(1, 50)},
|
||||
}
|
||||
|
||||
for i := 0; i < len(accounts); i++ {
|
||||
coins := make([]sdk.Coin, len(denoms))
|
||||
|
||||
// generate a random coin for each denomination
|
||||
for j := 0; j < len(denoms); j++ {
|
||||
coins[j] = sdk.Coin{Denom: denoms[j],
|
||||
Amount: RandFromBigInterval(r, randCoinIntervals),
|
||||
}
|
||||
}
|
||||
|
||||
app.TotalCoinsSupply = app.TotalCoinsSupply.Add(coins...)
|
||||
baseAcc := auth.NewBaseAccountWithAddress(addrs[i])
|
||||
|
||||
accounts[i] = &baseAcc
|
||||
balances[i] = bank.Balance{Address: addrs[i], Coins: coins}
|
||||
}
|
||||
|
||||
app.GenesisAccounts = accounts
|
||||
app.GenesisBalances = balances
|
||||
}
|
||||
|
||||
func createCodec() *codec.Codec {
|
||||
cdc := codec.New()
|
||||
sdk.RegisterCodec(cdc)
|
||||
codec.RegisterCrypto(cdc)
|
||||
auth.RegisterCodec(cdc)
|
||||
return cdc
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply/exported"
|
||||
)
|
||||
|
||||
const msgRoute = "testMsg"
|
||||
|
||||
var (
|
||||
numAccts = 2
|
||||
genCoins = sdk.Coins{sdk.NewInt64Coin("foocoin", 77)}
|
||||
accs, balances, addrs, _, privKeys = CreateGenAccounts(numAccts, genCoins)
|
||||
)
|
||||
|
||||
// testMsg is a mock transaction that has a validation which can fail.
|
||||
type testMsg struct {
|
||||
signers []sdk.AccAddress
|
||||
positiveNum int64
|
||||
}
|
||||
|
||||
func (tx testMsg) Route() string { return msgRoute }
|
||||
func (tx testMsg) Type() string { return "test" }
|
||||
func (tx testMsg) GetMsg() sdk.Msg { return tx }
|
||||
func (tx testMsg) GetMemo() string { return "" }
|
||||
func (tx testMsg) GetSignBytes() []byte { return nil }
|
||||
func (tx testMsg) GetSigners() []sdk.AccAddress { return tx.signers }
|
||||
func (tx testMsg) GetSignatures() []auth.StdSignature { return nil }
|
||||
func (tx testMsg) ValidateBasic() error {
|
||||
if tx.positiveNum >= 0 {
|
||||
return nil
|
||||
}
|
||||
return sdkerrors.Wrap(sdkerrors.ErrTxDecode, "positiveNum should be a non-negative integer")
|
||||
}
|
||||
|
||||
// getMockApp returns an initialized mock application.
|
||||
func getMockApp(t *testing.T) *App {
|
||||
mApp := NewApp()
|
||||
|
||||
mApp.Router().AddRoute(msgRoute, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
||||
return &sdk.Result{}, nil
|
||||
})
|
||||
require.NoError(t, mApp.CompleteSetup())
|
||||
|
||||
return mApp
|
||||
}
|
||||
|
||||
func TestCheckAndDeliverGenTx(t *testing.T) {
|
||||
mApp := getMockApp(t)
|
||||
mApp.Cdc.RegisterConcrete(testMsg{}, "mock/testMsg", nil)
|
||||
mApp.Cdc.RegisterInterface((*exported.ModuleAccountI)(nil), nil)
|
||||
|
||||
SetGenesis(mApp, accs, balances)
|
||||
ctxCheck := mApp.BaseApp.NewContext(true, abci.Header{})
|
||||
|
||||
msg := testMsg{signers: []sdk.AccAddress{addrs[0]}, positiveNum: 1}
|
||||
|
||||
acct := mApp.AccountKeeper.GetAccount(ctxCheck, addrs[0])
|
||||
require.Equal(t, accs[0], acct.(*auth.BaseAccount))
|
||||
|
||||
header := abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
SignCheckDeliver(
|
||||
t, mApp.Cdc, mApp.BaseApp, header, []sdk.Msg{msg},
|
||||
[]uint64{accs[0].GetAccountNumber()}, []uint64{accs[0].GetSequence()},
|
||||
true, true, privKeys[0],
|
||||
)
|
||||
|
||||
// Signing a tx with the wrong privKey should result in an auth error
|
||||
header = abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
_, _, err := SignCheckDeliver(
|
||||
t, mApp.Cdc, mApp.BaseApp, header, []sdk.Msg{msg},
|
||||
[]uint64{accs[1].GetAccountNumber()}, []uint64{accs[1].GetSequence() + 1},
|
||||
true, false, privKeys[1],
|
||||
)
|
||||
|
||||
// Will fail on SetPubKey decorator
|
||||
space, code, log := sdkerrors.ABCIInfo(err, false)
|
||||
require.Equal(t, sdkerrors.ErrInvalidPubKey.ABCICode(), code, log)
|
||||
require.Equal(t, sdkerrors.ErrInvalidPubKey.Codespace(), space)
|
||||
|
||||
// Resigning the tx with the correct privKey should result in an OK result
|
||||
header = abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
SignCheckDeliver(
|
||||
t, mApp.Cdc, mApp.BaseApp, header, []sdk.Msg{msg},
|
||||
[]uint64{accs[0].GetAccountNumber()}, []uint64{accs[0].GetSequence() + 1},
|
||||
true, true, privKeys[0],
|
||||
)
|
||||
}
|
||||
|
||||
func TestCheckGenTx(t *testing.T) {
|
||||
mApp := getMockApp(t)
|
||||
mApp.Cdc.RegisterConcrete(testMsg{}, "mock/testMsg", nil)
|
||||
mApp.Cdc.RegisterInterface((*exported.ModuleAccountI)(nil), nil)
|
||||
|
||||
SetGenesis(mApp, accs, balances)
|
||||
|
||||
msg1 := testMsg{signers: []sdk.AccAddress{addrs[0]}, positiveNum: 1}
|
||||
CheckGenTx(
|
||||
t, mApp.BaseApp, []sdk.Msg{msg1},
|
||||
[]uint64{accs[0].GetAccountNumber()}, []uint64{accs[0].GetSequence()},
|
||||
true, privKeys[0],
|
||||
)
|
||||
|
||||
msg2 := testMsg{signers: []sdk.AccAddress{addrs[0]}, positiveNum: -1}
|
||||
CheckGenTx(
|
||||
t, mApp.BaseApp, []sdk.Msg{msg2},
|
||||
[]uint64{accs[0].GetAccountNumber()}, []uint64{accs[0].GetSequence()},
|
||||
false, privKeys[0],
|
||||
)
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
/*
|
||||
Package mock provides utility methods to ease writing tests.
|
||||
*/
|
||||
package mock
|
|
@ -1,113 +0,0 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// BigInterval is a representation of the interval [lo, hi), where
|
||||
// lo and hi are both of type sdk.Int
|
||||
type BigInterval struct {
|
||||
lo sdk.Int
|
||||
hi sdk.Int
|
||||
}
|
||||
|
||||
// RandFromBigInterval chooses an interval uniformly from the provided list of
|
||||
// BigIntervals, and then chooses an element from an interval uniformly at random.
|
||||
func RandFromBigInterval(r *rand.Rand, intervals []BigInterval) sdk.Int {
|
||||
if len(intervals) == 0 {
|
||||
return sdk.ZeroInt()
|
||||
}
|
||||
|
||||
interval := intervals[r.Intn(len(intervals))]
|
||||
|
||||
lo := interval.lo
|
||||
hi := interval.hi
|
||||
|
||||
diff := hi.Sub(lo)
|
||||
result := sdk.NewIntFromBigInt(new(big.Int).Rand(r, diff.BigInt()))
|
||||
result = result.Add(lo)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// CheckBalance checks the balance of an account.
|
||||
func CheckBalance(t *testing.T, app *App, addr sdk.AccAddress, balance sdk.Coins) {
|
||||
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
|
||||
require.Equal(t, balance, app.BankKeeper.GetAllBalances(ctxCheck, addr))
|
||||
}
|
||||
|
||||
// CheckGenTx checks a generated signed transaction. The result of the check is
|
||||
// compared against the parameter 'expPass'. A test assertion is made using the
|
||||
// parameter 'expPass' against the result. A corresponding result is returned.
|
||||
func CheckGenTx(
|
||||
t *testing.T, app *baseapp.BaseApp, msgs []sdk.Msg, accNums []uint64,
|
||||
seq []uint64, expPass bool, priv ...crypto.PrivKey,
|
||||
) (sdk.GasInfo, *sdk.Result, error) {
|
||||
tx := GenTx(msgs, accNums, seq, priv...)
|
||||
gInfo, res, err := app.Check(tx)
|
||||
|
||||
if expPass {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
require.Nil(t, res)
|
||||
}
|
||||
|
||||
return gInfo, res, err
|
||||
}
|
||||
|
||||
// SignCheckDeliver checks a generated signed transaction and simulates a
|
||||
// block commitment with the given transaction. A test assertion is made using
|
||||
// the parameter 'expPass' against the result. A corresponding result is
|
||||
// returned.
|
||||
func SignCheckDeliver(
|
||||
t *testing.T, cdc *codec.Codec, app *baseapp.BaseApp, header abci.Header, msgs []sdk.Msg,
|
||||
accNums, seq []uint64, expSimPass, expPass bool, priv ...crypto.PrivKey,
|
||||
) (sdk.GasInfo, *sdk.Result, error) {
|
||||
|
||||
tx := GenTx(msgs, accNums, seq, priv...)
|
||||
|
||||
txBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Must simulate now as CheckTx doesn't run Msgs anymore
|
||||
_, res, err := app.Simulate(txBytes, tx)
|
||||
|
||||
if expSimPass {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
require.Nil(t, res)
|
||||
}
|
||||
|
||||
// Simulate a sending a transaction and committing a block
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
gInfo, res, err := app.Deliver(tx)
|
||||
|
||||
if expPass {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
require.Nil(t, res)
|
||||
}
|
||||
|
||||
app.EndBlock(abci.RequestEndBlock{})
|
||||
app.Commit()
|
||||
|
||||
return gInfo, res, err
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply/exported"
|
||||
)
|
||||
|
||||
// DummySupplyKeeper defines a supply keeper used only for testing to avoid
|
||||
// circle dependencies
|
||||
type DummySupplyKeeper struct {
|
||||
ak auth.AccountKeeper
|
||||
bk bank.Keeper
|
||||
}
|
||||
|
||||
// NewDummySupplyKeeper creates a DummySupplyKeeper instance
|
||||
func NewDummySupplyKeeper(ak auth.AccountKeeper, bk bank.Keeper) DummySupplyKeeper {
|
||||
return DummySupplyKeeper{ak, bk}
|
||||
}
|
||||
|
||||
// SendCoinsFromAccountToModule for the dummy supply keeper
|
||||
func (sk DummySupplyKeeper) SendCoinsFromAccountToModule(ctx sdk.Context, fromAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error {
|
||||
fromAcc := sk.ak.GetAccount(ctx, fromAddr)
|
||||
moduleAcc := sk.GetModuleAccount(ctx, recipientModule)
|
||||
fromBalances := sk.bk.GetAllBalances(ctx, fromAcc.GetAddress())
|
||||
|
||||
newFromCoins, hasNeg := fromBalances.SafeSub(amt)
|
||||
if hasNeg {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, fromBalances.String())
|
||||
}
|
||||
|
||||
toBalances := sk.bk.GetAllBalances(ctx, moduleAcc.GetAddress())
|
||||
newToCoins := toBalances.Add(amt...)
|
||||
|
||||
if err := sk.bk.SetBalances(ctx, fromAcc.GetAddress(), newFromCoins); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sk.bk.SetBalances(ctx, moduleAcc.GetAddress(), newToCoins); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sk.ak.SetAccount(ctx, fromAcc)
|
||||
sk.ak.SetAccount(ctx, moduleAcc)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetModuleAccount for dummy supply keeper
|
||||
func (sk DummySupplyKeeper) GetModuleAccount(ctx sdk.Context, moduleName string) exported.ModuleAccountI {
|
||||
addr := sk.GetModuleAddress(moduleName)
|
||||
|
||||
acc := sk.ak.GetAccount(ctx, addr)
|
||||
if acc != nil {
|
||||
macc, ok := acc.(exported.ModuleAccountI)
|
||||
if ok {
|
||||
return macc
|
||||
}
|
||||
}
|
||||
|
||||
moduleAddress := sk.GetModuleAddress(moduleName)
|
||||
baseAcc := auth.NewBaseAccountWithAddress(moduleAddress)
|
||||
|
||||
// create a new module account
|
||||
macc := &supply.ModuleAccount{
|
||||
BaseAccount: &baseAcc,
|
||||
Name: moduleName,
|
||||
Permissions: nil,
|
||||
}
|
||||
|
||||
maccI := (sk.ak.NewAccount(ctx, macc)).(exported.ModuleAccountI)
|
||||
sk.ak.SetAccount(ctx, maccI)
|
||||
return maccI
|
||||
}
|
||||
|
||||
// GetModuleAddress for dummy supply keeper
|
||||
func (sk DummySupplyKeeper) GetModuleAddress(moduleName string) sdk.AccAddress {
|
||||
return sdk.AccAddress(crypto.AddressHash([]byte(moduleName)))
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
package slashing
|
||||
package slashing_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/internal/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
)
|
||||
|
||||
func TestBeginBlocker(t *testing.T) {
|
||||
ctx, bk, sk, _, keeper := slashingkeeper.CreateTestInput(t, DefaultParams())
|
||||
ctx, bk, sk, _, keeper := slashingkeeper.CreateTestInput(t, slashing.DefaultParams())
|
||||
power := int64(100)
|
||||
amt := sdk.TokensFromConsensusPower(power)
|
||||
addr, pk := slashingkeeper.Addrs[2], slashingkeeper.Pks[2]
|
||||
|
@ -45,7 +45,8 @@ func TestBeginBlocker(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
}
|
||||
BeginBlocker(ctx, req, keeper)
|
||||
|
||||
slashing.BeginBlocker(ctx, req, keeper)
|
||||
|
||||
info, found := keeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(pk.Address()))
|
||||
require.True(t, found)
|
||||
|
@ -67,7 +68,8 @@ func TestBeginBlocker(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
}
|
||||
BeginBlocker(ctx, req, keeper)
|
||||
|
||||
slashing.BeginBlocker(ctx, req, keeper)
|
||||
}
|
||||
|
||||
// for 500 blocks, mark the validator as having not signed
|
||||
|
@ -81,7 +83,8 @@ func TestBeginBlocker(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
}
|
||||
BeginBlocker(ctx, req, keeper)
|
||||
|
||||
slashing.BeginBlocker(ctx, req, keeper)
|
||||
}
|
||||
|
||||
// end block
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// nolint
|
||||
// DONTCOVER
|
||||
package slashing
|
||||
package slashing_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
@ -10,16 +8,13 @@ import (
|
|||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -28,101 +23,21 @@ var (
|
|||
coins = sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
|
||||
)
|
||||
|
||||
// initialize the mock application for this module
|
||||
func getMockApp(t *testing.T) (*mock.App, staking.Keeper, Keeper) {
|
||||
mapp := mock.NewApp()
|
||||
|
||||
RegisterCodec(mapp.Cdc)
|
||||
staking.RegisterCodec(mapp.Cdc)
|
||||
supply.RegisterCodec(mapp.Cdc)
|
||||
|
||||
keyStaking := sdk.NewKVStoreKey(staking.StoreKey)
|
||||
keySlashing := sdk.NewKVStoreKey(StoreKey)
|
||||
keySupply := sdk.NewKVStoreKey(supply.StoreKey)
|
||||
|
||||
feeCollector := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
|
||||
notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking)
|
||||
bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking)
|
||||
|
||||
blacklistedAddrs := make(map[string]bool)
|
||||
blacklistedAddrs[feeCollector.GetAddress().String()] = true
|
||||
blacklistedAddrs[notBondedPool.GetAddress().String()] = true
|
||||
blacklistedAddrs[bondPool.GetAddress().String()] = true
|
||||
|
||||
maccPerms := map[string][]string{
|
||||
auth.FeeCollectorName: nil,
|
||||
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
|
||||
staking.BondedPoolName: {supply.Burner, supply.Staking},
|
||||
}
|
||||
supplyKeeper := supply.NewKeeper(mapp.Cdc, keySupply, mapp.AccountKeeper, mapp.BankKeeper, maccPerms)
|
||||
stakingKeeper := staking.NewKeeper(staking.ModuleCdc, keyStaking, mapp.BankKeeper, supplyKeeper, mapp.ParamsKeeper.Subspace(staking.DefaultParamspace))
|
||||
keeper := NewKeeper(mapp.Cdc, keySlashing, stakingKeeper, mapp.ParamsKeeper.Subspace(DefaultParamspace))
|
||||
mapp.Router().AddRoute(staking.RouterKey, staking.NewHandler(stakingKeeper))
|
||||
mapp.Router().AddRoute(RouterKey, NewHandler(keeper))
|
||||
|
||||
mapp.SetEndBlocker(getEndBlocker(stakingKeeper))
|
||||
mapp.SetInitChainer(
|
||||
getInitChainer(
|
||||
mapp, stakingKeeper, mapp.AccountKeeper, mapp.BankKeeper, supplyKeeper,
|
||||
[]supplyexported.ModuleAccountI{feeCollector, notBondedPool, bondPool},
|
||||
),
|
||||
)
|
||||
|
||||
require.NoError(t, mapp.CompleteSetup(keyStaking, keySupply, keySlashing))
|
||||
|
||||
return mapp, stakingKeeper, keeper
|
||||
}
|
||||
|
||||
// staking endblocker
|
||||
func getEndBlocker(keeper staking.Keeper) sdk.EndBlocker {
|
||||
return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
validatorUpdates := staking.EndBlocker(ctx, keeper)
|
||||
return abci.ResponseEndBlock{
|
||||
ValidatorUpdates: validatorUpdates,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite the mock init chainer
|
||||
func getInitChainer(
|
||||
mapp *mock.App, keeper staking.Keeper, accountKeeper types.AccountKeeper, bk types.BankKeeper,
|
||||
supplyKeeper types.SupplyKeeper, blacklistedAddrs []supplyexported.ModuleAccountI,
|
||||
) sdk.InitChainer {
|
||||
|
||||
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||
// set module accounts
|
||||
for _, macc := range blacklistedAddrs {
|
||||
supplyKeeper.SetModuleAccount(ctx, macc)
|
||||
}
|
||||
|
||||
mapp.InitChainer(ctx, req)
|
||||
stakingGenesis := staking.DefaultGenesisState()
|
||||
validators := staking.InitGenesis(ctx, keeper, accountKeeper, bk, supplyKeeper, stakingGenesis)
|
||||
return abci.ResponseInitChain{
|
||||
Validators: validators,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkValidator(t *testing.T, mapp *mock.App, keeper staking.Keeper,
|
||||
addr sdk.AccAddress, expFound bool) staking.Validator {
|
||||
ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{})
|
||||
validator, found := keeper.GetValidator(ctxCheck, sdk.ValAddress(addr1))
|
||||
func checkValidator(t *testing.T, app *simapp.SimApp, addr sdk.AccAddress, expFound bool) staking.Validator {
|
||||
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
|
||||
validator, found := app.StakingKeeper.GetValidator(ctxCheck, sdk.ValAddress(addr1))
|
||||
require.Equal(t, expFound, found)
|
||||
return validator
|
||||
}
|
||||
|
||||
func checkValidatorSigningInfo(t *testing.T, mapp *mock.App, keeper Keeper,
|
||||
addr sdk.ConsAddress, expFound bool) ValidatorSigningInfo {
|
||||
ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{})
|
||||
signingInfo, found := keeper.GetValidatorSigningInfo(ctxCheck, addr)
|
||||
func checkValidatorSigningInfo(t *testing.T, app *simapp.SimApp, addr sdk.ConsAddress, expFound bool) slashing.ValidatorSigningInfo {
|
||||
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
|
||||
signingInfo, found := app.SlashingKeeper.GetValidatorSigningInfo(ctxCheck, addr)
|
||||
require.Equal(t, expFound, found)
|
||||
return signingInfo
|
||||
}
|
||||
|
||||
func TestSlashingMsgs(t *testing.T) {
|
||||
mapp, stakingKeeper, keeper := getMockApp(t)
|
||||
|
||||
genTokens := sdk.TokensFromConsensusPower(42)
|
||||
bondTokens := sdk.TokensFromConsensusPower(10)
|
||||
genCoin := sdk.NewCoin(sdk.DefaultBondDenom, genTokens)
|
||||
|
@ -131,14 +46,16 @@ func TestSlashingMsgs(t *testing.T) {
|
|||
acc1 := &auth.BaseAccount{
|
||||
Address: addr1,
|
||||
}
|
||||
accs := []authexported.Account{acc1}
|
||||
balances := []bankexported.GenesisBalance{
|
||||
bank.Balance{
|
||||
accs := authexported.GenesisAccounts{acc1}
|
||||
balances := []bank.Balance{
|
||||
{
|
||||
Address: addr1,
|
||||
Coins: sdk.Coins{genCoin},
|
||||
},
|
||||
}
|
||||
mock.SetGenesis(mapp, accs, balances)
|
||||
|
||||
app := simapp.SetupWithGenesisAccounts(accs, balances...)
|
||||
simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin})
|
||||
|
||||
description := staking.NewDescription("foo_moniker", "", "", "", "")
|
||||
commission := staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
||||
|
@ -147,26 +64,25 @@ func TestSlashingMsgs(t *testing.T) {
|
|||
sdk.ValAddress(addr1), priv1.PubKey(), bondCoin, description, commission, sdk.OneInt(),
|
||||
)
|
||||
|
||||
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, header, []sdk.Msg{createValidatorMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
mock.CheckBalance(t, mapp, addr1, sdk.Coins{genCoin.Sub(bondCoin)})
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, []sdk.Msg{createValidatorMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin.Sub(bondCoin)})
|
||||
|
||||
header = abci.Header{Height: mapp.LastBlockHeight() + 1}
|
||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
header = abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
validator := checkValidator(t, mapp, stakingKeeper, addr1, true)
|
||||
validator := checkValidator(t, app, addr1, true)
|
||||
require.Equal(t, sdk.ValAddress(addr1), validator.OperatorAddress)
|
||||
require.Equal(t, sdk.Bonded, validator.Status)
|
||||
require.True(sdk.IntEq(t, bondTokens, validator.BondedTokens()))
|
||||
unjailMsg := MsgUnjail{ValidatorAddr: sdk.ValAddress(validator.GetConsPubKey().Address())}
|
||||
unjailMsg := slashing.MsgUnjail{ValidatorAddr: sdk.ValAddress(validator.GetConsPubKey().Address())}
|
||||
|
||||
// no signing info yet
|
||||
checkValidatorSigningInfo(t, mapp, keeper, sdk.ConsAddress(addr1), false)
|
||||
checkValidatorSigningInfo(t, app, sdk.ConsAddress(addr1), true)
|
||||
|
||||
// unjail should fail with unknown validator
|
||||
header = abci.Header{Height: mapp.LastBlockHeight() + 1}
|
||||
_, res, err := mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, header, []sdk.Msg{unjailMsg}, []uint64{0}, []uint64{1}, false, false, priv1)
|
||||
header = abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
_, res, err := simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, []sdk.Msg{unjailMsg}, []uint64{0}, []uint64{1}, false, false, priv1)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, res)
|
||||
require.True(t, errors.Is(ErrValidatorNotJailed, err))
|
||||
require.True(t, errors.Is(slashing.ErrValidatorNotJailed, err))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package slashing
|
||||
package slashing_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
@ -10,6 +10,7 @@ import (
|
|||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/internal/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/internal/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
|
@ -17,8 +18,8 @@ import (
|
|||
|
||||
func TestCannotUnjailUnlessJailed(t *testing.T) {
|
||||
// initial setup
|
||||
ctx, bk, sk, _, keeper := slashingkeeper.CreateTestInput(t, DefaultParams())
|
||||
slh := NewHandler(keeper)
|
||||
ctx, bk, sk, _, keeper := slashingkeeper.CreateTestInput(t, slashing.DefaultParams())
|
||||
slh := slashing.NewHandler(keeper)
|
||||
amt := sdk.TokensFromConsensusPower(100)
|
||||
addr, val := slashingkeeper.Addrs[0], slashingkeeper.Pks[0]
|
||||
|
||||
|
@ -36,16 +37,16 @@ func TestCannotUnjailUnlessJailed(t *testing.T) {
|
|||
require.Equal(t, amt, sk.Validator(ctx, addr).GetBondedTokens())
|
||||
|
||||
// assert non-jailed validator can't be unjailed
|
||||
res, err = slh(ctx, NewMsgUnjail(addr))
|
||||
res, err = slh(ctx, slashing.NewMsgUnjail(addr))
|
||||
require.Error(t, err)
|
||||
require.Nil(t, res)
|
||||
require.True(t, errors.Is(ErrValidatorNotJailed, err))
|
||||
require.True(t, errors.Is(slashing.ErrValidatorNotJailed, err))
|
||||
}
|
||||
|
||||
func TestCannotUnjailUnlessMeetMinSelfDelegation(t *testing.T) {
|
||||
// initial setup
|
||||
ctx, bk, sk, _, keeper := slashingkeeper.CreateTestInput(t, DefaultParams())
|
||||
slh := NewHandler(keeper)
|
||||
ctx, bk, sk, _, keeper := slashingkeeper.CreateTestInput(t, slashing.DefaultParams())
|
||||
slh := slashing.NewHandler(keeper)
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := slashingkeeper.Addrs[0], slashingkeeper.Pks[0], sdk.TokensFromConsensusPower(amtInt)
|
||||
msg := slashingkeeper.NewTestMsgCreateValidator(addr, val, amt)
|
||||
|
@ -71,14 +72,14 @@ func TestCannotUnjailUnlessMeetMinSelfDelegation(t *testing.T) {
|
|||
require.True(t, sk.Validator(ctx, addr).IsJailed())
|
||||
|
||||
// assert non-jailed validator can't be unjailed
|
||||
res, err = slh(ctx, NewMsgUnjail(addr))
|
||||
res, err = slh(ctx, slashing.NewMsgUnjail(addr))
|
||||
require.Error(t, err)
|
||||
require.Nil(t, res)
|
||||
require.True(t, errors.Is(ErrSelfDelegationTooLowToUnjail, err))
|
||||
require.True(t, errors.Is(slashing.ErrSelfDelegationTooLowToUnjail, err))
|
||||
}
|
||||
|
||||
func TestJailedValidatorDelegations(t *testing.T) {
|
||||
ctx, _, stakingKeeper, _, slashingKeeper := slashingkeeper.CreateTestInput(t, DefaultParams())
|
||||
ctx, _, stakingKeeper, _, slashingKeeper := slashingkeeper.CreateTestInput(t, slashing.DefaultParams())
|
||||
|
||||
stakingParams := stakingKeeper.GetParams(ctx)
|
||||
stakingKeeper.SetParams(ctx, stakingParams)
|
||||
|
@ -97,7 +98,7 @@ func TestJailedValidatorDelegations(t *testing.T) {
|
|||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// set dummy signing info
|
||||
newInfo := NewValidatorSigningInfo(consAddr, 0, 0, time.Unix(0, 0), false, 0)
|
||||
newInfo := slashing.NewValidatorSigningInfo(consAddr, 0, 0, time.Unix(0, 0), false, 0)
|
||||
slashingKeeper.SetValidatorSigningInfo(ctx, consAddr, newInfo)
|
||||
|
||||
// delegate tokens to the validator
|
||||
|
@ -124,7 +125,7 @@ func TestJailedValidatorDelegations(t *testing.T) {
|
|||
require.True(t, validator.IsJailed())
|
||||
|
||||
// verify the validator cannot unjail itself
|
||||
res, err = NewHandler(slashingKeeper)(ctx, NewMsgUnjail(valAddr))
|
||||
res, err = slashing.NewHandler(slashingKeeper)(ctx, slashing.NewMsgUnjail(valAddr))
|
||||
require.Error(t, err)
|
||||
require.Nil(t, res)
|
||||
|
||||
|
@ -135,14 +136,14 @@ func TestJailedValidatorDelegations(t *testing.T) {
|
|||
require.NotNil(t, res)
|
||||
|
||||
// verify the validator can now unjail itself
|
||||
res, err = NewHandler(slashingKeeper)(ctx, NewMsgUnjail(valAddr))
|
||||
res, err = slashing.NewHandler(slashingKeeper)(ctx, slashing.NewMsgUnjail(valAddr))
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
}
|
||||
|
||||
func TestInvalidMsg(t *testing.T) {
|
||||
k := Keeper{}
|
||||
h := NewHandler(k)
|
||||
k := slashing.Keeper{}
|
||||
h := slashing.NewHandler(k)
|
||||
|
||||
res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg())
|
||||
require.Error(t, err)
|
||||
|
@ -159,7 +160,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
|||
amt := sdk.TokensFromConsensusPower(power)
|
||||
addr, val := slashingkeeper.Addrs[0], slashingkeeper.Pks[0]
|
||||
sh := staking.NewHandler(sk)
|
||||
slh := NewHandler(keeper)
|
||||
slh := slashing.NewHandler(keeper)
|
||||
|
||||
res, err := sh(ctx, slashingkeeper.NewTestMsgCreateValidator(addr, val, amt))
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package staking
|
||||
package staking_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
@ -6,111 +6,29 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
)
|
||||
|
||||
// getMockApp returns an initialized mock application for this module.
|
||||
func getMockApp(t *testing.T) (*mock.App, Keeper) {
|
||||
mApp := mock.NewApp()
|
||||
|
||||
RegisterCodec(mApp.Cdc)
|
||||
supply.RegisterCodec(mApp.Cdc)
|
||||
|
||||
keyStaking := sdk.NewKVStoreKey(StoreKey)
|
||||
keySupply := sdk.NewKVStoreKey(supply.StoreKey)
|
||||
|
||||
feeCollector := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
|
||||
notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking)
|
||||
bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking)
|
||||
|
||||
blacklistedAddrs := make(map[string]bool)
|
||||
blacklistedAddrs[feeCollector.GetAddress().String()] = true
|
||||
blacklistedAddrs[notBondedPool.GetAddress().String()] = true
|
||||
blacklistedAddrs[bondPool.GetAddress().String()] = true
|
||||
|
||||
maccPerms := map[string][]string{
|
||||
auth.FeeCollectorName: nil,
|
||||
types.NotBondedPoolName: {supply.Burner, supply.Staking},
|
||||
types.BondedPoolName: {supply.Burner, supply.Staking},
|
||||
}
|
||||
supplyKeeper := supply.NewKeeper(mApp.Cdc, keySupply, mApp.AccountKeeper, mApp.BankKeeper, maccPerms)
|
||||
keeper := NewKeeper(ModuleCdc, keyStaking, mApp.BankKeeper, supplyKeeper, mApp.ParamsKeeper.Subspace(DefaultParamspace))
|
||||
|
||||
mApp.Router().AddRoute(RouterKey, NewHandler(keeper))
|
||||
mApp.SetEndBlocker(getEndBlocker(keeper))
|
||||
mApp.SetInitChainer(
|
||||
getInitChainer(
|
||||
mApp, keeper, mApp.AccountKeeper, mApp.BankKeeper, supplyKeeper,
|
||||
[]supplyexported.ModuleAccountI{feeCollector, notBondedPool, bondPool},
|
||||
),
|
||||
)
|
||||
|
||||
require.NoError(t, mApp.CompleteSetup(keyStaking, keySupply))
|
||||
return mApp, keeper
|
||||
}
|
||||
|
||||
// getEndBlocker returns a staking endblocker.
|
||||
func getEndBlocker(keeper Keeper) sdk.EndBlocker {
|
||||
return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
validatorUpdates := EndBlocker(ctx, keeper)
|
||||
|
||||
return abci.ResponseEndBlock{
|
||||
ValidatorUpdates: validatorUpdates,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getInitChainer initializes the chainer of the mock app and sets the genesis
|
||||
// state. It returns an empty ResponseInitChain.
|
||||
func getInitChainer(
|
||||
mapp *mock.App, keeper Keeper, ak types.AccountKeeper, bk types.BankKeeper,
|
||||
sk types.SupplyKeeper, blacklistedAddrs []supplyexported.ModuleAccountI,
|
||||
) sdk.InitChainer {
|
||||
|
||||
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||
mapp.InitChainer(ctx, req)
|
||||
|
||||
// set module accounts
|
||||
for _, macc := range blacklistedAddrs {
|
||||
sk.SetModuleAccount(ctx, macc)
|
||||
}
|
||||
|
||||
stakingGenesis := DefaultGenesisState()
|
||||
validators := InitGenesis(ctx, keeper, ak, bk, sk, stakingGenesis)
|
||||
|
||||
return abci.ResponseInitChain{
|
||||
Validators: validators,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//__________________________________________________________________________________________
|
||||
|
||||
func checkValidator(t *testing.T, mapp *mock.App, keeper Keeper,
|
||||
addr sdk.ValAddress, expFound bool) Validator {
|
||||
|
||||
ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{})
|
||||
validator, found := keeper.GetValidator(ctxCheck, addr)
|
||||
func checkValidator(t *testing.T, app *simapp.SimApp, addr sdk.ValAddress, expFound bool) staking.Validator {
|
||||
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
|
||||
validator, found := app.StakingKeeper.GetValidator(ctxCheck, addr)
|
||||
|
||||
require.Equal(t, expFound, found)
|
||||
return validator
|
||||
}
|
||||
|
||||
func checkDelegation(
|
||||
t *testing.T, mapp *mock.App, keeper Keeper, delegatorAddr sdk.AccAddress,
|
||||
t *testing.T, app *simapp.SimApp, delegatorAddr sdk.AccAddress,
|
||||
validatorAddr sdk.ValAddress, expFound bool, expShares sdk.Dec,
|
||||
) {
|
||||
|
||||
ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{})
|
||||
delegation, found := keeper.GetDelegation(ctxCheck, delegatorAddr, validatorAddr)
|
||||
ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
|
||||
delegation, found := app.StakingKeeper.GetDelegation(ctxCheck, delegatorAddr, validatorAddr)
|
||||
if expFound {
|
||||
require.True(t, found)
|
||||
require.True(sdk.DecEq(t, expShares, delegation.Shares))
|
||||
|
@ -122,8 +40,6 @@ func checkDelegation(
|
|||
}
|
||||
|
||||
func TestStakingMsgs(t *testing.T) {
|
||||
mApp, keeper := getMockApp(t)
|
||||
|
||||
genTokens := sdk.TokensFromConsensusPower(42)
|
||||
bondTokens := sdk.TokensFromConsensusPower(10)
|
||||
genCoin := sdk.NewCoin(sdk.DefaultBondDenom, genTokens)
|
||||
|
@ -131,8 +47,8 @@ func TestStakingMsgs(t *testing.T) {
|
|||
|
||||
acc1 := &auth.BaseAccount{Address: addr1}
|
||||
acc2 := &auth.BaseAccount{Address: addr2}
|
||||
accs := []authexported.Account{acc1, acc2}
|
||||
balances := []bankexported.GenesisBalance{
|
||||
accs := authexported.GenesisAccounts{acc1, acc2}
|
||||
balances := []bank.Balance{
|
||||
bank.Balance{
|
||||
Address: addr1,
|
||||
Coins: sdk.Coins{genCoin},
|
||||
|
@ -143,58 +59,58 @@ func TestStakingMsgs(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
mock.SetGenesis(mApp, accs, balances)
|
||||
mock.CheckBalance(t, mApp, addr1, sdk.Coins{genCoin})
|
||||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin})
|
||||
app := simapp.SetupWithGenesisAccounts(accs, balances...)
|
||||
simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin})
|
||||
simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin})
|
||||
|
||||
// create validator
|
||||
description := NewDescription("foo_moniker", "", "", "", "")
|
||||
createValidatorMsg := NewMsgCreateValidator(
|
||||
description := staking.NewDescription("foo_moniker", "", "", "", "")
|
||||
createValidatorMsg := staking.NewMsgCreateValidator(
|
||||
sdk.ValAddress(addr1), priv1.PubKey(), bondCoin, description, commissionRates, sdk.OneInt(),
|
||||
)
|
||||
|
||||
header := abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, header, []sdk.Msg{createValidatorMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
mock.CheckBalance(t, mApp, addr1, sdk.Coins{genCoin.Sub(bondCoin)})
|
||||
header := abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, []sdk.Msg{createValidatorMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin.Sub(bondCoin)})
|
||||
|
||||
header = abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
header = abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
validator := checkValidator(t, mApp, keeper, sdk.ValAddress(addr1), true)
|
||||
validator := checkValidator(t, app, sdk.ValAddress(addr1), true)
|
||||
require.Equal(t, sdk.ValAddress(addr1), validator.OperatorAddress)
|
||||
require.Equal(t, sdk.Bonded, validator.Status)
|
||||
require.True(sdk.IntEq(t, bondTokens, validator.BondedTokens()))
|
||||
|
||||
header = abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
header = abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
// edit the validator
|
||||
description = NewDescription("bar_moniker", "", "", "", "")
|
||||
editValidatorMsg := NewMsgEditValidator(sdk.ValAddress(addr1), description, nil, nil)
|
||||
description = staking.NewDescription("bar_moniker", "", "", "", "")
|
||||
editValidatorMsg := staking.NewMsgEditValidator(sdk.ValAddress(addr1), description, nil, nil)
|
||||
|
||||
header = abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, header, []sdk.Msg{editValidatorMsg}, []uint64{0}, []uint64{1}, true, true, priv1)
|
||||
header = abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, []sdk.Msg{editValidatorMsg}, []uint64{0}, []uint64{1}, true, true, priv1)
|
||||
|
||||
validator = checkValidator(t, mApp, keeper, sdk.ValAddress(addr1), true)
|
||||
validator = checkValidator(t, app, sdk.ValAddress(addr1), true)
|
||||
require.Equal(t, description, validator.Description)
|
||||
|
||||
// delegate
|
||||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin})
|
||||
delegateMsg := NewMsgDelegate(addr2, sdk.ValAddress(addr1), bondCoin)
|
||||
simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin})
|
||||
delegateMsg := staking.NewMsgDelegate(addr2, sdk.ValAddress(addr1), bondCoin)
|
||||
|
||||
header = abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, header, []sdk.Msg{delegateMsg}, []uint64{1}, []uint64{0}, true, true, priv2)
|
||||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin.Sub(bondCoin)})
|
||||
checkDelegation(t, mApp, keeper, addr2, sdk.ValAddress(addr1), true, bondTokens.ToDec())
|
||||
header = abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, []sdk.Msg{delegateMsg}, []uint64{1}, []uint64{0}, true, true, priv2)
|
||||
simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin.Sub(bondCoin)})
|
||||
checkDelegation(t, app, addr2, sdk.ValAddress(addr1), true, bondTokens.ToDec())
|
||||
|
||||
// begin unbonding
|
||||
beginUnbondingMsg := NewMsgUndelegate(addr2, sdk.ValAddress(addr1), bondCoin)
|
||||
header = abci.Header{Height: mApp.LastBlockHeight() + 1}
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, header, []sdk.Msg{beginUnbondingMsg}, []uint64{1}, []uint64{1}, true, true, priv2)
|
||||
beginUnbondingMsg := staking.NewMsgUndelegate(addr2, sdk.ValAddress(addr1), bondCoin)
|
||||
header = abci.Header{Height: app.LastBlockHeight() + 1}
|
||||
simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, []sdk.Msg{beginUnbondingMsg}, []uint64{1}, []uint64{1}, true, true, priv2)
|
||||
|
||||
// delegation should exist anymore
|
||||
checkDelegation(t, mApp, keeper, addr2, sdk.ValAddress(addr1), false, sdk.Dec{})
|
||||
checkDelegation(t, app, addr2, sdk.ValAddress(addr1), false, sdk.Dec{})
|
||||
|
||||
// balance should be the same because bonding not yet complete
|
||||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin.Sub(bondCoin)})
|
||||
simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin.Sub(bondCoin)})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package staking_test
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// nolint:deadcode,unused,varcheck
|
||||
var (
|
||||
priv1 = secp256k1.GenPrivKey()
|
||||
addr1 = sdk.AccAddress(priv1.PubKey().Address())
|
||||
priv2 = secp256k1.GenPrivKey()
|
||||
addr2 = sdk.AccAddress(priv2.PubKey().Address())
|
||||
addr3 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
|
||||
priv4 = secp256k1.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))},
|
||||
)
|
||||
|
||||
commissionRates = staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
||||
)
|
||||
|
||||
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator {
|
||||
return types.NewMsgCreateValidator(
|
||||
address, pubKey, sdk.NewCoin(sdk.DefaultBondDenom, amt), staking.Description{}, commissionRates, sdk.OneInt(),
|
||||
)
|
||||
}
|
||||
|
||||
func NewTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk.Int) staking.MsgDelegate {
|
||||
amount := sdk.NewCoin(sdk.DefaultBondDenom, amt)
|
||||
return staking.NewMsgDelegate(delAddr, valAddr, amount)
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,57 +0,0 @@
|
|||
package staking
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// nolint:deadcode,unused,varcheck
|
||||
var (
|
||||
priv1 = secp256k1.GenPrivKey()
|
||||
addr1 = sdk.AccAddress(priv1.PubKey().Address())
|
||||
priv2 = secp256k1.GenPrivKey()
|
||||
addr2 = sdk.AccAddress(priv2.PubKey().Address())
|
||||
addr3 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
|
||||
priv4 = secp256k1.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))},
|
||||
)
|
||||
|
||||
commissionRates = NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
|
||||
)
|
||||
|
||||
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) MsgCreateValidator {
|
||||
return types.NewMsgCreateValidator(
|
||||
address, pubKey, sdk.NewCoin(sdk.DefaultBondDenom, amt), Description{}, commissionRates, sdk.OneInt(),
|
||||
)
|
||||
}
|
||||
|
||||
func NewTestMsgCreateValidatorWithCommission(address sdk.ValAddress, pubKey crypto.PubKey,
|
||||
amt sdk.Int, commissionRate sdk.Dec) MsgCreateValidator {
|
||||
|
||||
commission := NewCommissionRates(commissionRate, sdk.OneDec(), sdk.ZeroDec())
|
||||
|
||||
return types.NewMsgCreateValidator(
|
||||
address, pubKey, sdk.NewCoin(sdk.DefaultBondDenom, amt), Description{}, commission, sdk.OneInt(),
|
||||
)
|
||||
}
|
||||
|
||||
func NewTestMsgCreateValidatorWithMinSelfDelegation(address sdk.ValAddress, pubKey crypto.PubKey,
|
||||
amt sdk.Int, minSelfDelegation sdk.Int) MsgCreateValidator {
|
||||
|
||||
return types.NewMsgCreateValidator(
|
||||
address, pubKey, sdk.NewCoin(sdk.DefaultBondDenom, amt), Description{}, commissionRates, minSelfDelegation,
|
||||
)
|
||||
}
|
||||
|
||||
func NewTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk.Int) MsgDelegate {
|
||||
amount := sdk.NewCoin(sdk.DefaultBondDenom, amt)
|
||||
return NewMsgDelegate(delAddr, valAddr, amount)
|
||||
}
|
Loading…
Reference in New Issue