-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: tests for distribution,gov module balances at genesis
- Loading branch information
1 parent
882b546
commit 61a28aa
Showing
3 changed files
with
282 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
package distribution_test | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
|
||
corestore "cosmossdk.io/core/store" | ||
coretesting "cosmossdk.io/core/testing" | ||
"cosmossdk.io/depinject" | ||
"cosmossdk.io/log" | ||
sdkmath "cosmossdk.io/math" | ||
"cosmossdk.io/x/distribution/keeper" | ||
"cosmossdk.io/x/distribution/types" | ||
stakingkeeper "cosmossdk.io/x/staking/keeper" | ||
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1" | ||
"github.com/cosmos/cosmos-sdk/codec" | ||
"github.com/cosmos/cosmos-sdk/runtime" | ||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/stretchr/testify/suite" | ||
|
||
bankkeeper "cosmossdk.io/x/bank/keeper" | ||
_ "github.com/cosmos/cosmos-sdk/x/auth" | ||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" | ||
) | ||
|
||
type ImportExportSuite struct { | ||
suite.Suite | ||
|
||
cdc codec.Codec | ||
app *runtime.App | ||
addrs []sdk.AccAddress | ||
AccountKeeper authkeeper.AccountKeeper | ||
BankKeeper bankkeeper.Keeper | ||
DistributionKeeper keeper.Keeper | ||
StakingKeeper *stakingkeeper.Keeper | ||
appBuilder *runtime.AppBuilder | ||
} | ||
|
||
func TestDistributionImportExport(t *testing.T) { | ||
suite.Run(t, new(ImportExportSuite)) | ||
} | ||
|
||
func (s *ImportExportSuite) SetupTest() { | ||
var err error | ||
valTokens := sdk.TokensFromConsensusPower(42, sdk.DefaultPowerReduction) | ||
s.app, err = simtestutil.SetupWithConfiguration( | ||
depinject.Configs( | ||
AppConfig, | ||
depinject.Supply(log.NewNopLogger()), | ||
), | ||
simtestutil.DefaultStartUpConfig(), | ||
&s.AccountKeeper, &s.BankKeeper, &s.DistributionKeeper, &s.StakingKeeper, | ||
&s.cdc, &s.appBuilder, | ||
) | ||
s.Require().NoError(err) | ||
|
||
ctx := s.app.BaseApp.NewContext(false) | ||
s.addrs = simtestutil.AddTestAddrs(s.BankKeeper, s.StakingKeeper, ctx, 1, valTokens) | ||
|
||
_, err = s.app.FinalizeBlock(&abci.FinalizeBlockRequest{ | ||
Height: s.app.LastBlockHeight() + 1, | ||
}) | ||
s.Require().NoError(err) | ||
} | ||
|
||
func (s *ImportExportSuite) TestHappyPath() { | ||
ctx := s.app.NewContext(true) | ||
// Imagine a situation where rewards were, e.g. 100 / 3 = 33, but the fee collector sent 100 to the distribution module. | ||
// There're 99 tokens in rewards, but 100 in the module; let's simulate a situation where there are 34 tokens left in the module, | ||
// and a single validator has 33 tokens of rewards. | ||
rewards := sdk.NewDecCoinsFromCoins(sdk.NewCoin("stake", sdkmath.NewInt(33))) | ||
|
||
// We'll pretend s.addrs[0] is the fee collector module. | ||
err := s.BankKeeper.SendCoinsFromAccountToModule(ctx, s.addrs[0], types.ModuleName, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(34)))) | ||
s.Require().NoError(err) | ||
|
||
validators, err := s.StakingKeeper.GetAllValidators(ctx) | ||
s.Require().NoError(err) | ||
val := validators[0] | ||
|
||
err = s.DistributionKeeper.AllocateTokensToValidator(ctx, val, rewards) | ||
s.Require().NoError(err) | ||
|
||
_, err = s.app.FinalizeBlock(&abci.FinalizeBlockRequest{ | ||
Height: s.app.LastBlockHeight() + 1, | ||
}) | ||
s.Require().NoError(err) | ||
|
||
valBz, err := s.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator()) | ||
s.Require().NoError(err) | ||
outstanding, err := s.DistributionKeeper.ValidatorOutstandingRewards.Get(ctx, valBz) | ||
s.Require().NoError(err) | ||
s.Require().Equal(rewards, outstanding.Rewards) | ||
|
||
genesisState, err := s.app.ModuleManager.ExportGenesis(ctx) | ||
s.Require().NoError(err) | ||
stateBytes, err := json.MarshalIndent(genesisState, "", " ") | ||
s.Require().NoError(err) | ||
|
||
db := coretesting.NewMemDB() | ||
conf2 := simtestutil.DefaultStartUpConfig() | ||
conf2.DB = db | ||
app2, err := simtestutil.SetupWithConfiguration( | ||
depinject.Configs( | ||
AppConfig, | ||
depinject.Supply(log.NewNopLogger()), | ||
), | ||
conf2, | ||
) | ||
|
||
s.clearDB(db) | ||
err = app2.CommitMultiStore().LoadLatestVersion() | ||
s.Require().NoError(err) | ||
|
||
_, err = app2.InitChain( | ||
&abci.InitChainRequest{ | ||
Validators: []abci.ValidatorUpdate{}, | ||
ConsensusParams: simtestutil.DefaultConsensusParams, | ||
AppStateBytes: stateBytes, | ||
}, | ||
) | ||
s.Require().NoError(err) | ||
} | ||
|
||
func (s *ImportExportSuite) TestInsufficientFunds() { | ||
ctx := s.app.NewContext(true) | ||
rewards := sdk.NewCoin("stake", sdkmath.NewInt(35)) | ||
|
||
validators, err := s.StakingKeeper.GetAllValidators(ctx) | ||
s.Require().NoError(err) | ||
|
||
err = s.DistributionKeeper.AllocateTokensToValidator(ctx, validators[0], sdk.NewDecCoinsFromCoins(rewards)) | ||
s.Require().NoError(err) | ||
|
||
// We'll pretend s.addrs[0] is the fee collector module. | ||
err = s.BankKeeper.SendCoinsFromAccountToModule(ctx, s.addrs[0], types.ModuleName, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(34)))) | ||
s.Require().NoError(err) | ||
|
||
_, err = s.app.FinalizeBlock(&abci.FinalizeBlockRequest{ | ||
Height: s.app.LastBlockHeight() + 1, | ||
}) | ||
s.Require().NoError(err) | ||
|
||
genesisState, err := s.app.ModuleManager.ExportGenesis(ctx) | ||
s.Require().NoError(err) | ||
stateBytes, err := json.MarshalIndent(genesisState, "", " ") | ||
s.Require().NoError(err) | ||
|
||
db := coretesting.NewMemDB() | ||
conf2 := simtestutil.DefaultStartUpConfig() | ||
conf2.DB = db | ||
app2, err := simtestutil.SetupWithConfiguration( | ||
depinject.Configs( | ||
AppConfig, | ||
depinject.Supply(log.NewNopLogger()), | ||
), | ||
conf2, | ||
) | ||
|
||
s.clearDB(db) | ||
err = app2.CommitMultiStore().LoadLatestVersion() | ||
s.Require().NoError(err) | ||
|
||
_, err = app2.InitChain( | ||
&abci.InitChainRequest{ | ||
Validators: []abci.ValidatorUpdate{}, | ||
ConsensusParams: simtestutil.DefaultConsensusParams, | ||
AppStateBytes: stateBytes, | ||
}, | ||
) | ||
s.Require().ErrorContains(err, "distribution module balance is less than module holdings") | ||
} | ||
|
||
func (s *ImportExportSuite) clearDB(db corestore.KVStoreWithBatch) { | ||
iter, err := db.Iterator(nil, nil) | ||
s.Require().NoError(err) | ||
defer iter.Close() | ||
|
||
var keys [][]byte | ||
for ; iter.Valid(); iter.Next() { | ||
keys = append(keys, iter.Key()) | ||
} | ||
|
||
for _, k := range keys { | ||
s.Require().NoError(db.Delete(k)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters