feat(x/precisebank): Implement ExportGenesis (#1915)

This commit is contained in:
drklee3 2024-05-20 09:50:31 -07:00 committed by GitHub
parent 7990021431
commit dbc3ad7fd2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 85 additions and 43 deletions

View File

@ -47,11 +47,27 @@ func InitGenesis(
)) ))
} }
// TODO: After keeper methods are implemented // Set FractionalBalances in state
// - Set account FractionalBalances for _, bal := range gs.Balances {
addr := sdk.MustAccAddressFromBech32(bal.Address)
keeper.SetFractionalBalance(ctx, addr, bal.Amount)
}
// Set remainder amount in state
keeper.SetRemainderAmount(ctx, gs.Remainder)
} }
// ExportGenesis returns a GenesisState for a given context and keeper. // ExportGenesis returns a GenesisState for a given context and keeper.
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState { func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState {
return types.NewGenesisState(types.FractionalBalances{}, sdkmath.ZeroInt()) balances := types.FractionalBalances{}
keeper.IterateFractionalBalances(ctx, func(addr sdk.AccAddress, amount sdkmath.Int) bool {
balances = append(balances, types.NewFractionalBalance(addr.String(), amount))
return false
})
remainder := keeper.GetRemainderAmount(ctx)
return types.NewGenesisState(balances, remainder)
} }

View File

@ -7,6 +7,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/precisebank" "github.com/kava-labs/kava/x/precisebank"
"github.com/kava-labs/kava/x/precisebank/keeper"
"github.com/kava-labs/kava/x/precisebank/testutil" "github.com/kava-labs/kava/x/precisebank/testutil"
"github.com/kava-labs/kava/x/precisebank/types" "github.com/kava-labs/kava/x/precisebank/types"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
@ -163,34 +164,78 @@ func (suite *GenesisTestSuite) TestInitGenesis() {
"module account should be created & stored in account store", "module account should be created & stored in account store",
) )
// TODO: Check module state once implemented // Verify balances are set in state, get full list of balances in
// state to ensure they are set AND no extra balances are set
var bals []types.FractionalBalance
suite.Keeper.IterateFractionalBalances(suite.Ctx, func(addr sdk.AccAddress, bal sdkmath.Int) bool {
bals = append(bals, types.NewFractionalBalance(addr.String(), bal))
// Verify balances return false
// IterateBalances() or something })
// Ensure reserve balance matches sum of all fractional balances suite.Require().ElementsMatch(tc.genesisState.Balances, bals, "balances should be set in state")
// sum up IterateBalances()
// - etc remainder := suite.Keeper.GetRemainderAmount(suite.Ctx)
suite.Require().Equal(tc.genesisState.Remainder, remainder, "remainder should be set in state")
// Additional verification of state via invariants
invariantFn := keeper.AllInvariants(suite.Keeper)
msg, broken := invariantFn(suite.Ctx)
suite.Require().False(broken, "invariants should not be broken after InitGenesis")
suite.Require().Empty(msg, "invariants should not return a message after InitGenesis")
}) })
} }
} }
func (suite *GenesisTestSuite) TestExportGenesis_Valid() { func (suite *GenesisTestSuite) TestExportGenesis() {
// ExportGenesis(moduleState) should return a valid genesis state // ExportGenesis(InitGenesis(genesisState)) == genesisState
// Must also be valid.
tests := []struct { tests := []struct {
name string name string
maleate func() initGenesisState func() *types.GenesisState
}{ }{
{ {
"InitGenesis(DefaultGenesisState)", "InitGenesis(DefaultGenesisState)",
func() { func() *types.GenesisState {
precisebank.InitGenesis( return types.DefaultGenesisState()
},
},
{
"balances, no remainder",
func() *types.GenesisState {
err := suite.BankKeeper.MintCoins(
suite.Ctx, suite.Ctx,
suite.Keeper, types.ModuleName,
suite.AccountKeeper, sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdkmath.NewInt(1))),
suite.BankKeeper, )
types.DefaultGenesisState(), suite.Require().NoError(err)
return types.NewGenesisState(
types.FractionalBalances{
types.NewFractionalBalance(sdk.AccAddress{1}.String(), types.ConversionFactor().QuoRaw(2)),
types.NewFractionalBalance(sdk.AccAddress{2}.String(), types.ConversionFactor().QuoRaw(2)),
},
sdkmath.ZeroInt(),
)
},
},
{
"balances, remainder",
func() *types.GenesisState {
err := suite.BankKeeper.MintCoins(
suite.Ctx,
types.ModuleName,
sdk.NewCoins(sdk.NewCoin(types.IntegerCoinDenom, sdkmath.NewInt(1))),
)
suite.Require().NoError(err)
return types.NewGenesisState(
types.FractionalBalances{
types.NewFractionalBalance(sdk.AccAddress{1}.String(), types.ConversionFactor().QuoRaw(2)),
types.NewFractionalBalance(sdk.AccAddress{2}.String(), types.ConversionFactor().QuoRaw(2).SubRaw(1)),
},
sdkmath.OneInt(),
) )
}, },
}, },
@ -198,37 +243,18 @@ func (suite *GenesisTestSuite) TestExportGenesis_Valid() {
for _, tc := range tests { for _, tc := range tests {
suite.Run(tc.name, func() { suite.Run(tc.name, func() {
tc.maleate() // Reset state
suite.SetupTest()
genesisState := precisebank.ExportGenesis(suite.Ctx, suite.Keeper) initGs := tc.initGenesisState()
suite.Require().NoError(genesisState.Validate(), "exported genesis state should be valid")
})
}
}
func (suite *GenesisTestSuite) TestExportImportedState() {
// ExportGenesis(InitGenesis(genesisState)) == genesisState
tests := []struct {
name string
initGenesisState *types.GenesisState
}{
{
"InitGenesis(DefaultGenesisState)",
types.DefaultGenesisState(),
},
}
for _, tc := range tests {
suite.Run(tc.name, func() {
suite.Require().NotPanics(func() { suite.Require().NotPanics(func() {
precisebank.InitGenesis( precisebank.InitGenesis(
suite.Ctx, suite.Ctx,
suite.Keeper, suite.Keeper,
suite.AccountKeeper, suite.AccountKeeper,
suite.BankKeeper, suite.BankKeeper,
tc.initGenesisState, initGs,
) )
}) })
@ -236,7 +262,7 @@ func (suite *GenesisTestSuite) TestExportImportedState() {
suite.Require().NoError(genesisState.Validate(), "exported genesis state should be valid") suite.Require().NoError(genesisState.Validate(), "exported genesis state should be valid")
suite.Require().Equal( suite.Require().Equal(
tc.initGenesisState, initGs,
genesisState, genesisState,
"exported genesis state should equal initial genesis state", "exported genesis state should equal initial genesis state",
) )