Skip to content

Commit

Permalink
Export/import wei balance
Browse files Browse the repository at this point in the history
  • Loading branch information
codchen committed May 7, 2024
1 parent a0b1d4a commit c6753d0
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 13 deletions.
33 changes: 29 additions & 4 deletions x/bank/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,46 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank/types"
)

// this denom is only used within the context of import/export
const GenesisWeiDenom = "genesis-wei"

// InitGenesis initializes the bank module's state from a given genesis state.
func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) {
k.SetParams(ctx, genState.Params)

totalSupply := sdk.Coins{}
totalWeiBalance := sdk.ZeroInt()

genState.Balances = types.SanitizeGenesisBalances(genState.Balances)
for _, balance := range genState.Balances {
addr := balance.GetAddress()
coins := balance.Coins
if amt := coins.AmountOf(GenesisWeiDenom); !amt.IsZero() {
if err := k.AddWei(ctx, addr, amt); err != nil {
panic(fmt.Errorf("error on setting wei %w", err))
}
coins = coins.Sub(sdk.NewCoins(sdk.NewCoin(GenesisWeiDenom, amt)))
totalWeiBalance = totalWeiBalance.Add(amt)
}

if err := k.initBalances(ctx, addr, balance.Coins); err != nil {
if err := k.initBalances(ctx, addr, coins); err != nil {
panic(fmt.Errorf("error on setting balances %w", err))
}

totalSupply = totalSupply.Add(balance.Coins...)
totalSupply = totalSupply.Add(coins...)
}
weiInUsei, weiRemainder := SplitUseiWeiAmount(totalWeiBalance)
if !weiRemainder.IsZero() {
panic(fmt.Errorf("non-zero wei remainder %s", weiRemainder))
}
totalSupply = totalSupply.Add(sdk.NewCoin(sdk.MustGetBaseDenom(), weiInUsei))

if !genState.Supply.Empty() && !genState.Supply.IsEqual(totalSupply) {
panic(fmt.Errorf("genesis supply is incorrect, expected %v, got %v", genState.Supply, totalSupply))
}

for _, supply := range totalSupply {
k.setSupply(ctx, supply)
k.SetSupply(ctx, supply)
}

for _, meta := range genState.DenomMetadata {
Expand All @@ -44,10 +61,18 @@ func (k BaseKeeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
if err != nil {
panic(fmt.Errorf("unable to fetch total supply %v", err))
}
balances := k.GetAccountsBalances(ctx)
balancesWithWei := make([]types.Balance, len(balances))
for i, balance := range balances {
if amt := k.GetWeiBalance(ctx, balance.GetAddress()); !amt.IsZero() {
balance.Coins = balance.Coins.Add(sdk.NewCoin(GenesisWeiDenom, amt))
}
balancesWithWei[i] = balance
}

return types.NewGenesisState(
k.GetParams(ctx),
k.GetAccountsBalances(ctx),
balancesWithWei,
totalSupply,
k.GetAllDenomMetaData(ctx),
)
Expand Down
17 changes: 12 additions & 5 deletions x/bank/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper_test
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/cosmos/cosmos-sdk/x/bank/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
)
Expand All @@ -26,13 +27,19 @@ func (suite *IntegrationTestSuite) TestExportGenesis() {
Require().
NoError(app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, accAddr, expectedBalances[i].Coins))
}
suite.
Require().
NoError(
app.BankKeeper.SendCoinsAndWei(ctx, expectedBalances[0].GetAddress(), expectedBalances[1].GetAddress(), sdk.ZeroInt(), sdk.OneInt()))
app.BankKeeper.SetParams(ctx, types.DefaultParams())

exportGenesis := app.BankKeeper.ExportGenesis(ctx)

suite.Require().Len(exportGenesis.Params.SendEnabled, 0)
suite.Require().Equal(types.DefaultParams().DefaultSendEnabled, exportGenesis.Params.DefaultSendEnabled)
suite.Require().Equal(totalSupply, exportGenesis.Supply)
expectedBalances[0].Coins = expectedBalances[0].Coins.Sub(sdk.NewCoins(sdk.NewCoin(sdk.MustGetBaseDenom(), sdk.OneInt()))).Add(sdk.NewCoin(keeper.GenesisWeiDenom, keeper.OneUseiInWei.Sub(sdk.OneInt())))
expectedBalances[1].Coins = expectedBalances[1].Coins.Add(sdk.NewCoin(keeper.GenesisWeiDenom, sdk.OneInt()))
suite.Require().Equal(expectedBalances, exportGenesis.Balances)
suite.Require().Equal(expectedMetadata, exportGenesis.DenomMetadata)
}
Expand All @@ -41,7 +48,7 @@ func (suite *IntegrationTestSuite) getTestBalancesAndSupply() ([]types.Balance,
addr2, _ := sdk.AccAddressFromBech32("cosmos1f9xjhxm0plzrh9cskf4qee4pc2xwp0n0556gh0")
addr1, _ := sdk.AccAddressFromBech32("cosmos1t5u0jfg3ljsjrh2m9e47d4ny2hea7eehxrzdgd")
addr1Balance := sdk.Coins{sdk.NewInt64Coin("testcoin3", 10)}
addr2Balance := sdk.Coins{sdk.NewInt64Coin("testcoin1", 32), sdk.NewInt64Coin("testcoin2", 34)}
addr2Balance := sdk.Coins{sdk.NewInt64Coin("test", 2), sdk.NewInt64Coin("testcoin1", 32), sdk.NewInt64Coin("testcoin2", 34)}

totalSupply := addr1Balance
totalSupply = totalSupply.Add(addr2Balance...)
Expand All @@ -68,11 +75,11 @@ func (suite *IntegrationTestSuite) TestTotalSupply() {
// Prepare some test data.
defaultGenesis := types.DefaultGenesisState()
balances := []types.Balance{
{Coins: sdk.NewCoins(sdk.NewCoin("foocoin", sdk.NewInt(1))), Address: "cosmos1f9xjhxm0plzrh9cskf4qee4pc2xwp0n0556gh0"},
{Coins: sdk.NewCoins(sdk.NewCoin("foocoin", sdk.NewInt(1)), sdk.NewCoin(keeper.GenesisWeiDenom, sdk.OneInt())), Address: "cosmos1f9xjhxm0plzrh9cskf4qee4pc2xwp0n0556gh0"},
{Coins: sdk.NewCoins(sdk.NewCoin("barcoin", sdk.NewInt(1))), Address: "cosmos1t5u0jfg3ljsjrh2m9e47d4ny2hea7eehxrzdgd"},
{Coins: sdk.NewCoins(sdk.NewCoin("foocoin", sdk.NewInt(10)), sdk.NewCoin("barcoin", sdk.NewInt(20))), Address: "cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q"},
{Coins: sdk.NewCoins(sdk.NewCoin("foocoin", sdk.NewInt(10)), sdk.NewCoin("barcoin", sdk.NewInt(20)), sdk.NewCoin(keeper.GenesisWeiDenom, keeper.OneUseiInWei.Sub(sdk.OneInt()))), Address: "cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q"},
}
totalSupply := sdk.NewCoins(sdk.NewCoin("foocoin", sdk.NewInt(11)), sdk.NewCoin("barcoin", sdk.NewInt(21)))
totalSupply := sdk.NewCoins(sdk.NewCoin("foocoin", sdk.NewInt(11)), sdk.NewCoin("barcoin", sdk.NewInt(21)), sdk.NewCoin("test", sdk.OneInt()))

testcases := []struct {
name string
Expand All @@ -84,7 +91,7 @@ func (suite *IntegrationTestSuite) TestTotalSupply() {
{
"calculation NOT matching genesis Supply field",
types.NewGenesisState(defaultGenesis.Params, balances, sdk.NewCoins(sdk.NewCoin("wrongcoin", sdk.NewInt(1))), defaultGenesis.DenomMetadata),
nil, true, "genesis supply is incorrect, expected 1wrongcoin, got 21barcoin,11foocoin",
nil, true, "genesis supply is incorrect, expected 1wrongcoin, got 21barcoin,11foocoin,1test",
},
{
"calculation matches genesis Supply field",
Expand Down
9 changes: 5 additions & 4 deletions x/bank/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Keeper interface {

GetSupply(ctx sdk.Context, denom string) sdk.Coin
HasSupply(ctx sdk.Context, denom string) bool
SetSupply(ctx sdk.Context, coin sdk.Coin)
GetPaginatedTotalSupply(ctx sdk.Context, pagination *query.PageRequest) (sdk.Coins, *query.PageResponse, error)
IterateTotalSupply(ctx sdk.Context, cb func(sdk.Coin) bool)
GetDenomMetaData(ctx sdk.Context, denom string) (types.Metadata, bool)
Expand Down Expand Up @@ -548,7 +549,7 @@ func (k BaseKeeper) createCoins(ctx sdk.Context, moduleName string, amounts sdk.
for _, amount := range amounts {
supply := k.GetSupply(ctx, amount.GetDenom())
supply = supply.Add(amount)
k.setSupply(ctx, supply)
k.SetSupply(ctx, supply)
}

logger := k.Logger(ctx)
Expand Down Expand Up @@ -598,7 +599,7 @@ func (k BaseKeeper) destroyCoins(ctx sdk.Context, moduleName string, amounts sdk
for _, amount := range amounts {
supply := k.GetSupply(ctx, amount.GetDenom())
supply = supply.Sub(amount)
k.setSupply(ctx, supply)
k.SetSupply(ctx, supply)
}

logger := k.Logger(ctx)
Expand Down Expand Up @@ -627,8 +628,8 @@ func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amounts sdk.Co
return nil
}

// setSupply sets the supply for the given coin
func (k BaseKeeper) setSupply(ctx sdk.Context, coin sdk.Coin) {
// SetSupply sets the supply for the given coin
func (k BaseKeeper) SetSupply(ctx sdk.Context, coin sdk.Coin) {
intBytes, err := coin.Amount.Marshal()
if err != nil {
panic(fmt.Errorf("unable to marshal amount value %v", err))
Expand Down
1 change: 1 addition & 0 deletions x/bank/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (suite *IntegrationTestSuite) initKeepersWithmAccPerms(blockedAddrs map[str
}

func (suite *IntegrationTestSuite) SetupTest() {
sdk.RegisterDenom("test", sdk.OneDec())
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()})

Expand Down

0 comments on commit c6753d0

Please sign in to comment.