Fix x/bank genesis non-determinism (#6940)

* Sort coins in x/bank genesis

* Sort address before looping

* GetAccountsBalances

Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
SaReN 2020-08-06 14:40:07 +05:30 committed by GitHub
parent e3391ff447
commit ba140c90f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 22 deletions

View File

@ -35,26 +35,10 @@ func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
// ExportGenesis returns the bank module's genesis state.
func (k BaseKeeper) ExportGenesis(ctx sdk.Context) types.GenesisState {
balancesSet := make(map[string]sdk.Coins)
k.IterateAllBalances(ctx, func(addr sdk.AccAddress, balance sdk.Coin) bool {
balancesSet[addr.String()] = balancesSet[addr.String()].Add(balance)
return false
})
balances := []types.Balance{}
for addrStr, coins := range balancesSet {
addr, err := sdk.AccAddressFromBech32(addrStr)
if err != nil {
panic(fmt.Errorf("failed to convert address from string: %w", err))
}
balances = append(balances, types.Balance{
Address: addr,
Coins: coins,
})
}
return types.NewGenesisState(k.GetParams(ctx), balances, k.GetSupply(ctx).GetTotal(), k.GetAllDenomMetaData(ctx))
return types.NewGenesisState(
k.GetParams(ctx),
k.GetAccountsBalances(ctx),
k.GetSupply(ctx).GetTotal(),
k.GetAllDenomMetaData(ctx),
)
}

View File

@ -22,6 +22,7 @@ type ViewKeeper interface {
HasBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coin) bool
GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
GetAccountsBalances(ctx sdk.Context) []types.Balance
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
@ -67,6 +68,32 @@ func (k BaseViewKeeper) GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk
return balances.Sort()
}
// GetAccountsBalances returns all the accounts balances from the store.
func (k BaseViewKeeper) GetAccountsBalances(ctx sdk.Context) []types.Balance {
balances := make([]types.Balance, 0)
mapAddressToBalancesIdx := make(map[string]int)
k.IterateAllBalances(ctx, func(addr sdk.AccAddress, balance sdk.Coin) bool {
idx, ok := mapAddressToBalancesIdx[addr.String()]
if ok {
// address is already on the set of accounts balances
balances[idx].Coins = balances[idx].Coins.Add(balance)
balances[idx].Coins.Sort()
return false
}
accountBalance := types.Balance{
Address: addr,
Coins: sdk.NewCoins(balance),
}
balances = append(balances, accountBalance)
mapAddressToBalancesIdx[addr.String()] = len(balances) - 1
return false
})
return balances
}
// GetBalance returns the balance of a specific denomination for a given account
// by address.
func (k BaseViewKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {