From cf7b03efcdbe041d1bd37dbbf4a643ff94da6634 Mon Sep 17 00:00:00 2001 From: Hanjun Kim Date: Wed, 14 Apr 2021 00:01:21 +0900 Subject: [PATCH] add AddAmount/SubAmount methods to sdk.Coin (#9091) Co-authored-by: Marko Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- CHANGELOG.md | 1 + types/coin.go | 15 +++++++++++++++ types/coin_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63275b512..6a96d38f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * updated the keyring display structure (it uses protobuf JSON serialization) - the output is more verbose. * Renamed `MarshalAny` and `UnmarshalAny` to `MarshalInterface` and `UnmarshalInterface` respectively. These functions must take an interface as parameter (not a concrete type nor `Any` object). Underneath they use `Any` wrapping for correct protobuf serialization. * CLI: removed `--text` flag from `show-node-id` command; the text format for public keys is not used any more - instead we use ProtoJSON. +* (types) [\#9079](https://github.com/cosmos/cosmos-sdk/issues/9079) Add `AddAmount`/`SubAmount` methods to `sdk.Coin`. ### API Breaking Changes diff --git a/types/coin.go b/types/coin.go index b86cff518..352dcf6ac 100644 --- a/types/coin.go +++ b/types/coin.go @@ -100,6 +100,11 @@ func (coin Coin) Add(coinB Coin) Coin { return Coin{coin.Denom, coin.Amount.Add(coinB.Amount)} } +// AddAmount adds an amount to the Coin. +func (coin Coin) AddAmount(amount Int) Coin { + return Coin{coin.Denom, coin.Amount.Add(amount)} +} + // Sub subtracts amounts of two coins with same denom. If the coins differ in denom // then it panics. func (coin Coin) Sub(coinB Coin) Coin { @@ -115,6 +120,16 @@ func (coin Coin) Sub(coinB Coin) Coin { return res } +// SubAmount subtracts an amount from the Coin. +func (coin Coin) SubAmount(amount Int) Coin { + res := Coin{coin.Denom, coin.Amount.Sub(amount)} + if res.IsNegative() { + panic("negative coin amount") + } + + return res +} + // IsPositive returns true if coin amount is positive. // // TODO: Remove once unsigned integers are used. diff --git a/types/coin_test.go b/types/coin_test.go index ab69f16a1..fad7f2f52 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -145,6 +145,21 @@ func (s *coinTestSuite) TestAddCoin() { } } +func (s *coinTestSuite) TestAddCoinAmount() { + cases := []struct { + coin sdk.Coin + amount sdk.Int + expected sdk.Coin + }{ + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt(1), sdk.NewInt64Coin(testDenom1, 2)}, + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt(0), sdk.NewInt64Coin(testDenom1, 1)}, + } + for i, tc := range cases { + res := tc.coin.AddAmount(tc.amount) + s.Require().Equal(tc.expected, res, "result of addition is incorrect, tc #%d", i) + } +} + func (s *coinTestSuite) TestSubCoin() { cases := []struct { inputOne sdk.Coin @@ -178,6 +193,30 @@ func (s *coinTestSuite) TestSubCoin() { s.Require().Equal(tc.expected, res.Amount.Int64()) } +func (s *coinTestSuite) TestSubCoinAmount() { + cases := []struct { + coin sdk.Coin + amount sdk.Int + expected sdk.Coin + shouldPanic bool + }{ + {sdk.NewInt64Coin(testDenom1, 2), sdk.NewInt(1), sdk.NewInt64Coin(testDenom1, 1), false}, + {sdk.NewInt64Coin(testDenom1, 10), sdk.NewInt(1), sdk.NewInt64Coin(testDenom1, 9), false}, + {sdk.NewInt64Coin(testDenom1, 5), sdk.NewInt(3), sdk.NewInt64Coin(testDenom1, 2), false}, + {sdk.NewInt64Coin(testDenom1, 5), sdk.NewInt(0), sdk.NewInt64Coin(testDenom1, 5), false}, + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt(5), sdk.Coin{}, true}, + } + + for i, tc := range cases { + if tc.shouldPanic { + s.Require().Panics(func() { tc.coin.SubAmount(tc.amount) }) + } else { + res := tc.coin.SubAmount(tc.amount) + s.Require().Equal(tc.expected, res, "result of subtraction is incorrect, tc #%d", i) + } + } +} + func (s *coinTestSuite) TestIsGTECoin() { cases := []struct { inputOne sdk.Coin