diff --git a/CHANGELOG.md b/CHANGELOG.md index 56d13262093c..56a6aaae84e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features -* (x/upgrade) [\#11116](https://github.com/cosmos/cosmos-sdk/pull/11116) `MsgSoftwareUpgrade` and has been added to support v1beta2 msgs-based gov proposals. +* [\#11441](https://github.com/cosmos/cosmos-sdk/pull/11441) Added a new method, `IsLTE`, for `types.Coin`. This method is used to check if a `types.Coin` is less than or equal to another `types.Coin`. +* (x/upgrade) [\#11116](https://github.com/cosmos/cosmos-sdk/pull/11116) `MsgSoftwareUpgrade` and has been added to support v1beta2 msgs-based gov proposals. * [\#11308](https://github.com/cosmos/cosmos-sdk/pull/11308) Added a mandatory metadata field to Vote in x/gov v1beta2. * [\#10977](https://github.com/cosmos/cosmos-sdk/pull/10977) Now every cosmos message protobuf definition must be extended with a ``cosmos.msg.v1.signer`` option to signal the signer fields in a language agnostic way. * [\#10710](https://github.com/cosmos/cosmos-sdk/pull/10710) Chain-id shouldn't be required for creating a transaction with both --generate-only and --offline flags. diff --git a/types/coin.go b/types/coin.go index 69e77cdbdab9..d523c806154a 100644 --- a/types/coin.go +++ b/types/coin.go @@ -81,6 +81,16 @@ func (coin Coin) IsLT(other Coin) bool { return coin.Amount.LT(other.Amount) } +// IsLTE returns true if they are the same type and the receiver is +// an equal or smaller value +func (coin Coin) IsLTE(other Coin) bool { + if coin.Denom != other.Denom { + panic(fmt.Sprintf("invalid coin denominations; %s, %s", coin.Denom, other.Denom)) + } + + return !coin.Amount.GT(other.Amount) +} + // IsEqual returns true if the two sets of Coins have the same value func (coin Coin) IsEqual(other Coin) bool { if coin.Denom != other.Denom { diff --git a/types/coin_test.go b/types/coin_test.go index f82b581aa691..8252b0f1b462 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -233,6 +233,7 @@ func (s *coinTestSuite) TestIsGTECoin() { }{ {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt64Coin(testDenom1, 1), true, false}, {sdk.NewInt64Coin(testDenom1, 2), sdk.NewInt64Coin(testDenom1, 1), true, false}, + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt64Coin(testDenom1, 2), false, false}, {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt64Coin(testDenom2, 1), false, true}, } @@ -247,6 +248,30 @@ func (s *coinTestSuite) TestIsGTECoin() { } } +func (s *coinTestSuite) TestIsLTECoin() { + cases := []struct { + inputOne sdk.Coin + inputTwo sdk.Coin + expected bool + panics bool + }{ + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt64Coin(testDenom1, 1), true, false}, + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt64Coin(testDenom1, 2), true, false}, + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt64Coin(testDenom2, 1), false, true}, + {sdk.NewInt64Coin(testDenom1, 2), sdk.NewInt64Coin(testDenom1, 1), false, false}, + } + + for tcIndex, tc := range cases { + tc := tc + if tc.panics { + s.Require().Panics(func() { tc.inputOne.IsLTE(tc.inputTwo) }) + } else { + res := tc.inputOne.IsLTE(tc.inputTwo) + s.Require().Equal(tc.expected, res, "coin LTE relation is incorrect, tc #%d", tcIndex) + } + } +} + func (s *coinTestSuite) TestIsLTCoin() { cases := []struct { inputOne sdk.Coin