perf: Refactor Coins/Validate to avoid unnecessary map (#14163)

* Refactor (coins Coins) Validate() to avoid unnecessary map

and add a few tests

* Add CHANGELOG entry

Co-authored-by: Marko <marbar3778@yahoo.com>
Co-authored-by: Julien Robert <julien@rbrt.fr>
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
Simon Warta 2022-12-07 00:12:25 +01:00 committed by GitHub
parent 66dd2be12c
commit 9fd1825a90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 8 deletions

View File

@ -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.

View File

@ -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

View File

@ -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{
@ -797,7 +806,7 @@ func (s *coinTestSuite) TestCoins_Validate() {
false,
},
{
"duplicate denomination",
"duplicate denomination (1)",
sdk.Coins{
{"gas", math.OneInt()},
{"gas", math.OneInt()},
@ -805,6 +814,24 @@ func (s *coinTestSuite) TestCoins_Validate() {
},
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 {