From a0c064a941787840b5088ae74a9aa58b8ae02bf7 Mon Sep 17 00:00:00 2001 From: Alex Megalokonomos Date: Tue, 12 Oct 2021 12:11:14 +0300 Subject: [PATCH 1/3] fix: null guard for tx fee amounts (#10327) ## Description It is possible to submit a TX with a fees object containing a Coin with a nil amount. This results in a rather cryptic redacted panic response when the basic validation checks fee Coins for negative amounts. This PR adds an additional check for nil to provide a friendlier error message. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification (note: No issue exists) - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) (note: First PR against the SDK so please comment with what needs to be done) - [x] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) (cherry picked from commit 96e162b8a3939c7999c0c12c39d196698594306c) # Conflicts: # CHANGELOG.md --- CHANGELOG.md | 12 ++++++++++++ types/coin.go | 18 ++++++++++++++++++ types/coin_test.go | 27 +++++++++++++++++++++++++++ types/tx/types.go | 7 +++++++ 4 files changed, 64 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 196e70fb806e..e71592e32859 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,19 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +<<<<<<< HEAD * (store) [\#10040](https://github.com/cosmos/cosmos-sdk/pull/10040) Bump IAVL to v0.17.1 which includes performance improvements on a batch load. +======= +* [\#10327](https://github.com/cosmos/cosmos-sdk/pull/10327) Add null guard for possible nil `Amount` in tx fee `Coins` +* [\#9780](https://github.com/cosmos/cosmos-sdk/pull/9780) Remove gogoproto `moretags` YAML annotations and add `sigs.k8s.io/yaml` for YAML marshalling. +* (x/bank) [\#10134](https://github.com/cosmos/cosmos-sdk/pull/10134) Add `HasDenomMetadata` function to bank `Keeper` to check if a client coin denom metadata exists in state. +* (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. +* (types) [\#10076](https://github.com/cosmos/cosmos-sdk/pull/10076) Significantly speedup and lower allocations for `Coins.String()`. +* (x/bank) [\#10022](https://github.com/cosmos/cosmos-sdk/pull/10022) `BankKeeper.SendCoins` now takes less execution time. +* (deps) [\#9987](https://github.com/cosmos/cosmos-sdk/pull/9987) Bump Go version minimum requirement to `1.17` +* (deps) [\#9956](https://github.com/cosmos/cosmos-sdk/pull/9956) Bump Tendermint to [v0.34.12](https://github.com/tendermint/tendermint/releases/tag/v0.34.12). +* (cli) [\#9856](https://github.com/cosmos/cosmos-sdk/pull/9856) Overwrite `--sequence` and `--account-number` flags with default flag values when used with `offline=false` in `sign-batch` command. +>>>>>>> 96e162b8a (fix: null guard for tx fee amounts (#10327)) * (types) [\#10021](https://github.com/cosmos/cosmos-sdk/pull/10021) Speedup coins.AmountOf(), by removing many intermittent regex calls. * [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance. * (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. diff --git a/types/coin.go b/types/coin.go index e8fe7a5f8781..185f8b28e4c4 100644 --- a/types/coin.go +++ b/types/coin.go @@ -144,6 +144,11 @@ func (coin Coin) IsNegative() bool { return coin.Amount.Sign() == -1 } +// IsNil returns true if the coin amount is nil and false otherwise. +func (coin Coin) IsNil() bool { + return coin.Amount.i == nil +} + //----------------------------------------------------------------------------- // Coins @@ -585,6 +590,19 @@ func (coins Coins) IsAnyNegative() bool { return false } +// IsAnyNil returns true if there is at least one coin whose amount +// is nil; returns false otherwise. It returns false if the coin set +// is empty too. +func (coins Coins) IsAnyNil() bool { + for _, coin := range coins { + if coin.IsNil() { + return true + } + } + + return false +} + // negative returns a set of coins with all amount negative. // // TODO: Remove once unsigned integers are used. diff --git a/types/coin_test.go b/types/coin_test.go index 9a5d83fea9c3..240b15d11de0 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -282,6 +282,20 @@ func (s *coinTestSuite) TestCoinIsZero() { s.Require().False(res) } +func (s *coinTestSuite) TestCoinIsNil() { + coin := sdk.Coin{} + res := coin.IsNil() + s.Require().True(res) + + coin = sdk.Coin{Denom: "uatom"} + res = coin.IsNil() + s.Require().True(res) + + coin = sdk.NewInt64Coin(testDenom1, 1) + res = coin.IsNil() + s.Require().False(res) +} + func (s *coinTestSuite) TestFilteredZeroCoins() { cases := []struct { name string @@ -944,6 +958,19 @@ func (s *coinTestSuite) TestCoinsIsAnyGT() { } } +func (s *coinTestSuite) TestCoinsIsAnyNil() { + twoAtom := sdk.NewInt64Coin("atom", 2) + fiveAtom := sdk.NewInt64Coin("atom", 5) + threeEth := sdk.NewInt64Coin("eth", 3) + nilAtom := sdk.Coin{Denom: "atom"} + + s.Require().True(sdk.Coins{twoAtom, fiveAtom, threeEth, nilAtom}.IsAnyNil()) + s.Require().True(sdk.Coins{twoAtom, nilAtom, fiveAtom, threeEth}.IsAnyNil()) + s.Require().True(sdk.Coins{nilAtom, twoAtom, fiveAtom, threeEth}.IsAnyNil()) + s.Require().False(sdk.Coins{twoAtom, fiveAtom, threeEth}.IsAnyNil()) + +} + func (s *coinTestSuite) TestMarshalJSONCoins() { cdc := codec.NewLegacyAmino() sdk.RegisterLegacyAminoCodec(cdc) diff --git a/types/tx/types.go b/types/tx/types.go index 84ce81edcbf8..3aa8bbbb5e55 100644 --- a/types/tx/types.go +++ b/types/tx/types.go @@ -62,6 +62,13 @@ func (t *Tx) ValidateBasic() error { ) } + if fee.Amount.IsAnyNil() { + return sdkerrors.Wrapf( + sdkerrors.ErrInsufficientFee, + "invalid fee provided: null", + ) + } + if fee.Amount.IsAnyNegative() { return sdkerrors.Wrapf( sdkerrors.ErrInsufficientFee, From a8ce7227e239970a23c643c82fb2cbec50dc45de Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Tue, 12 Oct 2021 11:29:30 +0200 Subject: [PATCH 2/3] solve conflicts --- CHANGELOG.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e71592e32859..38b51d7850c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,19 +53,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements -<<<<<<< HEAD * (store) [\#10040](https://github.com/cosmos/cosmos-sdk/pull/10040) Bump IAVL to v0.17.1 which includes performance improvements on a batch load. -======= * [\#10327](https://github.com/cosmos/cosmos-sdk/pull/10327) Add null guard for possible nil `Amount` in tx fee `Coins` -* [\#9780](https://github.com/cosmos/cosmos-sdk/pull/9780) Remove gogoproto `moretags` YAML annotations and add `sigs.k8s.io/yaml` for YAML marshalling. -* (x/bank) [\#10134](https://github.com/cosmos/cosmos-sdk/pull/10134) Add `HasDenomMetadata` function to bank `Keeper` to check if a client coin denom metadata exists in state. -* (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. -* (types) [\#10076](https://github.com/cosmos/cosmos-sdk/pull/10076) Significantly speedup and lower allocations for `Coins.String()`. -* (x/bank) [\#10022](https://github.com/cosmos/cosmos-sdk/pull/10022) `BankKeeper.SendCoins` now takes less execution time. -* (deps) [\#9987](https://github.com/cosmos/cosmos-sdk/pull/9987) Bump Go version minimum requirement to `1.17` -* (deps) [\#9956](https://github.com/cosmos/cosmos-sdk/pull/9956) Bump Tendermint to [v0.34.12](https://github.com/tendermint/tendermint/releases/tag/v0.34.12). -* (cli) [\#9856](https://github.com/cosmos/cosmos-sdk/pull/9856) Overwrite `--sequence` and `--account-number` flags with default flag values when used with `offline=false` in `sign-batch` command. ->>>>>>> 96e162b8a (fix: null guard for tx fee amounts (#10327)) * (types) [\#10021](https://github.com/cosmos/cosmos-sdk/pull/10021) Speedup coins.AmountOf(), by removing many intermittent regex calls. * [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance. * (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions. From 39cdc82e2993e864b1becf9141bc07fddb7f60d3 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Tue, 12 Oct 2021 11:34:06 +0200 Subject: [PATCH 3/3] move sections --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38b51d7850c9..c1509b1e44e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements * [\#10262](https://github.com/cosmos/cosmos-sdk/pull/10262) Remove unnecessary logging in `x/feegrant` simulation. +* [\#10327](https://github.com/cosmos/cosmos-sdk/pull/10327) Add null guard for possible nil `Amount` in tx fee `Coins` ### Bug Fixes @@ -54,7 +55,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements * (store) [\#10040](https://github.com/cosmos/cosmos-sdk/pull/10040) Bump IAVL to v0.17.1 which includes performance improvements on a batch load. -* [\#10327](https://github.com/cosmos/cosmos-sdk/pull/10327) Add null guard for possible nil `Amount` in tx fee `Coins` * (types) [\#10021](https://github.com/cosmos/cosmos-sdk/pull/10021) Speedup coins.AmountOf(), by removing many intermittent regex calls. * [\#10077](https://github.com/cosmos/cosmos-sdk/pull/10077) Remove telemetry on `GasKV` and `CacheKV` store Get/Set operations, significantly improving their performance. * (store) [\#10026](https://github.com/cosmos/cosmos-sdk/pull/10026) Improve CacheKVStore datastructures / algorithms, to no longer take O(N^2) time when interleaving iterators and insertions.