Skip to content
This repository was archived by the owner on Jan 20, 2026. It is now read-only.

Commit 20cdc9e

Browse files
committed
Fix quadratic balance query (#573)
## Describe your changes and provide context Previously `GetAllBalances` would perform slice copy operation for each iterator `Next` call due to how `Coin::Add` is implemented. The reason for the copy is because `Coin:Add` needs to sort the resulting slice. However this is unnecessary because at the end of `GetAllBalances` the slice would sorted again anyway. This PR changes the iterator operation to be a simple append, so that the total time complexity would be O(n) instead of O(n^2) ## Testing performed to validate your change unit test
1 parent 9fb9a4f commit 20cdc9e

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

x/bank/keeper/keeper_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,27 @@ func (suite *IntegrationTestSuite) TestMintCoinRestrictions() {
19391939
}
19401940
}
19411941

1942+
func (suite *IntegrationTestSuite) TestKeeperGetAllBalances() {
1943+
app, ctx := suite.app, suite.ctx
1944+
addr := sdk.AccAddress([]byte("addr1_______________"))
1945+
cnt := 1000000
1946+
allDenoms := make(sdk.Coins, cnt)
1947+
for i := 0; i < cnt; i++ {
1948+
d := fmt.Sprintf("d%d", i+10) // denom must be at least 3 chars.
1949+
app.BankKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.Coin{
1950+
Denom: d, Amount: sdk.OneInt(),
1951+
}}, false)
1952+
allDenoms[i] = sdk.Coin{Denom: d}
1953+
}
1954+
allDenoms = allDenoms.Sort()
1955+
balances := app.BankKeeper.GetAllBalances(ctx, addr)
1956+
suite.Require().Len(balances, cnt)
1957+
for i := 0; i < cnt; i++ {
1958+
suite.Require().Equal(allDenoms[i].Denom, balances[i].Denom)
1959+
suite.Require().Equal(sdk.OneInt(), balances[i].Amount)
1960+
}
1961+
}
1962+
19421963
func TestKeeperTestSuite(t *testing.T) {
19431964
suite.Run(t, new(IntegrationTestSuite))
19441965
}

x/bank/keeper/view.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (k BaseViewKeeper) HasBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk
6464
func (k BaseViewKeeper) GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins {
6565
balances := sdk.NewCoins()
6666
k.IterateAccountBalances(ctx, addr, func(balance sdk.Coin) bool {
67-
balances = balances.Add(balance)
67+
balances = append(balances, balance)
6868
return false
6969
})
7070

0 commit comments

Comments
 (0)