Skip to content

Commit

Permalink
perf: Refactor Coins/Validate to avoid unnecessary map (#14163)
Browse files Browse the repository at this point in the history
* Refactor (coins Coins) Validate() to avoid unnecessary map

and add a few tests

* Add CHANGELOG entry

Co-authored-by: Marko <[email protected]>
Co-authored-by: Julien Robert <[email protected]>
Co-authored-by: Aleksandr Bezobchuk <[email protected]>
  • Loading branch information
4 people authored Dec 6, 2022
1 parent 66dd2be commit 9fd1825
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Improvements

* (types) [#14163](https://github.com/cosmos/cosmos-sdk/pull/14163) Refactor `(coins Coins) Validate()` to avoid unnecessary map.
* (signing) [#14087](https://github.com/cosmos/cosmos-sdk/pull/14087) Add SignModeHandlerWithContext interface with a new `GetSignBytesWithContext` to get the sign bytes using `context.Context` as an argument to access state.
* (server) [#14062](https://github.com/cosmos/cosmos-sdk/pull/14062) Remove rosetta from server start.
* [13882] (https://github.com/cosmos/cosmos-sdk/pull/13882) Add tx `encode` and `decode` endpoints to amino tx service.
Expand Down
11 changes: 4 additions & 7 deletions types/coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,26 +247,23 @@ func (coins Coins) Validate() error {
}

lowDenom := coins[0].Denom
seenDenoms := make(map[string]bool)
seenDenoms[lowDenom] = true

for _, coin := range coins[1:] {
if seenDenoms[coin.Denom] {
return fmt.Errorf("duplicate denomination %s", coin.Denom)
}
if err := ValidateDenom(coin.Denom); err != nil {
return err
}
if coin.Denom <= lowDenom {
if coin.Denom < lowDenom {
return fmt.Errorf("denomination %s is not sorted", coin.Denom)
}
if coin.Denom == lowDenom {
return fmt.Errorf("duplicate denomination %s", coin.Denom)
}
if !coin.IsPositive() {
return fmt.Errorf("coin %s amount is not positive", coin.Denom)
}

// we compare each coin against the last denom
lowDenom = coin.Denom
seenDenoms[coin.Denom] = true
}

return nil
Expand Down
29 changes: 28 additions & 1 deletion types/coin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,15 @@ func (s *coinTestSuite) TestCoins_Validate() {
},
false,
},
{
"bad sort (3)",
sdk.Coins{
{"gas", math.OneInt()},
{"tree", math.OneInt()},
{"gas", math.OneInt()},
},
false,
},
{
"non-positive amount (1)",
sdk.Coins{
Expand All @@ -797,14 +806,32 @@ func (s *coinTestSuite) TestCoins_Validate() {
false,
},
{
"duplicate denomination",
"duplicate denomination (1)",
sdk.Coins{
{"gas", math.OneInt()},
{"gas", math.OneInt()},
{"mineral", math.OneInt()},
},
false,
},
{
"duplicate denomination (2)",
sdk.Coins{
{"gold", math.OneInt()},
{"gold", math.OneInt()},
},
false,
},
{
"duplicate denomination (3)",
sdk.Coins{
{"gas", math.OneInt()},
{"mineral", math.OneInt()},
{"silver", math.OneInt()},
{"silver", math.OneInt()},
},
false,
},
}

for _, tc := range testCases {
Expand Down

0 comments on commit 9fd1825

Please sign in to comment.