From 1bd70a238da3dbbed41e0dc9690afcc3216a42c7 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Tue, 7 May 2019 13:10:35 -0400 Subject: [PATCH] Merge PR #4281: Fix addGenesisAccount --- .pending/bugfixes/sdk/4271-Fix-addGenesisA | 1 + .pending/features/sdk/4271-Implement-Coins | 1 + cmd/gaia/init/genesis_accts.go | 2 +- cmd/gaia/init/genesis_accts_test.go | 15 +++++++++++++- types/coin.go | 23 ++++++++++++++++++++++ types/coin_test.go | 19 ++++++++++++++++++ 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 .pending/bugfixes/sdk/4271-Fix-addGenesisA create mode 100644 .pending/features/sdk/4271-Implement-Coins diff --git a/.pending/bugfixes/sdk/4271-Fix-addGenesisA b/.pending/bugfixes/sdk/4271-Fix-addGenesisA new file mode 100644 index 0000000000..71e66aa97e --- /dev/null +++ b/.pending/bugfixes/sdk/4271-Fix-addGenesisA @@ -0,0 +1 @@ +#4271 Fix addGenesisAccount by using Coins#IsAnyGT for vesting amount validation. diff --git a/.pending/features/sdk/4271-Implement-Coins b/.pending/features/sdk/4271-Implement-Coins new file mode 100644 index 0000000000..ebe16878b8 --- /dev/null +++ b/.pending/features/sdk/4271-Implement-Coins @@ -0,0 +1 @@ +#4271 Implement Coins#IsAnyGT diff --git a/cmd/gaia/init/genesis_accts.go b/cmd/gaia/init/genesis_accts.go index 79748f1ea0..ca568227ad 100644 --- a/cmd/gaia/init/genesis_accts.go +++ b/cmd/gaia/init/genesis_accts.go @@ -116,7 +116,7 @@ func addGenesisAccount( EndTime: vestingEnd, } - if bvacc.OriginalVesting.IsAllGT(acc.Coins) { + if bvacc.OriginalVesting.IsAnyGT(acc.Coins) { return appState, fmt.Errorf("vesting amount cannot be greater than total amount") } if vestingStart >= vestingEnd { diff --git a/cmd/gaia/init/genesis_accts_test.go b/cmd/gaia/init/genesis_accts_test.go index 74af5a42b6..d0af91ae83 100644 --- a/cmd/gaia/init/genesis_accts_test.go +++ b/cmd/gaia/init/genesis_accts_test.go @@ -75,14 +75,27 @@ func TestAddGenesisAccount(t *testing.T) { }, true, }, + { + "invalid vesting amount with multi coins", + args{ + app.GenesisState{}, + addr1, + sdk.NewCoins(sdk.NewInt64Coin("uatom", 50), sdk.NewInt64Coin("eth", 50)), + sdk.NewCoins(sdk.NewInt64Coin("uatom", 100), sdk.NewInt64Coin("eth", 20)), + 0, + 1, + }, + true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := addGenesisAccount( cdc, tt.args.appState, tt.args.addr, tt.args.coins, tt.args.vestingAmt, tt.args.vestingStart, tt.args.vestingEnd, ) - require.Equal(t, tt.wantErr, (err != nil)) + require.Equal(t, tt.wantErr, err != nil) }) } } diff --git a/types/coin.go b/types/coin.go index 4c6ef53f7f..4cc1312f4f 100644 --- a/types/coin.go +++ b/types/coin.go @@ -368,6 +368,29 @@ func (coins Coins) IsAllLTE(coinsB Coins) bool { return coinsB.IsAllGTE(coins) } +// IsAnyGT returns true iff for any denom in coins, the denom is present at a +// greater amount in coinsB. +// +// e.g. +// {2A, 3B}.IsAnyGT{A} = true +// {2A, 3B}.IsAnyGT{5C} = false +// {}.IsAnyGT{5C} = false +// {2A, 3B}.IsAnyGT{} = false +func (coins Coins) IsAnyGT(coinsB Coins) bool { + if len(coinsB) == 0 { + return false + } + + for _, coin := range coins { + amt := coinsB.AmountOf(coin.Denom) + if coin.Amount.GT(amt) && !amt.IsZero() { + return true + } + } + + return false +} + // IsAnyGTE returns true iff coins contains at least one denom that is present // at a greater or equal amount in coinsB; it returns false otherwise. // diff --git a/types/coin_test.go b/types/coin_test.go index a9ebdad966..0a81ce7b95 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -574,3 +574,22 @@ func TestNewCoins(t *testing.T) { }) } } + +func TestCoinsIsAnyGT(t *testing.T) { + twoAtom := NewInt64Coin("atom", 2) + fiveAtom := NewInt64Coin("atom", 5) + threeEth := NewInt64Coin("eth", 3) + sixEth := NewInt64Coin("eth", 6) + twoBtc := NewInt64Coin("btc", 2) + + require.False(t, Coins{}.IsAnyGT(Coins{})) + + require.False(t, Coins{fiveAtom}.IsAnyGT(Coins{})) + require.False(t, Coins{}.IsAnyGT(Coins{fiveAtom})) + require.True(t, Coins{fiveAtom}.IsAnyGT(Coins{twoAtom})) + require.False(t, Coins{twoAtom}.IsAnyGT(Coins{fiveAtom})) + + require.True(t, Coins{twoAtom, sixEth}.IsAnyGT(Coins{twoBtc, fiveAtom, threeEth})) + require.False(t, Coins{twoBtc, twoAtom, threeEth}.IsAnyGT(Coins{fiveAtom, sixEth})) + require.False(t, Coins{twoAtom, sixEth}.IsAnyGT(Coins{twoBtc, fiveAtom})) +}