From fe9ebec3d6e862df30c2838fea943edd80a40540 Mon Sep 17 00:00:00 2001 From: "jaeseung.bae" Date: Wed, 27 Mar 2024 20:12:34 +0900 Subject: [PATCH] fix: correctly coalesce coins even with repeated denominations --- client/keys/delete.go | 3 +- client/keys/delete_test.go | 3 +- simapp/test_helpers.go | 2 +- store/rootmulti/store.go | 10 ++- store/rootmulti/store_test.go | 75 ++++++++++++++++ types/coin.go | 74 +++++---------- types/coin_test.go | 94 ++++++++++++-------- types/dec_coin.go | 13 ++- types/dec_coin_test.go | 2 +- x/auth/legacy/v043/store_test.go | 4 +- x/auth/vesting/types/vesting_account.go | 4 +- x/auth/vesting/types/vesting_account_test.go | 12 +-- x/bank/keeper/genesis.go | 2 +- x/bank/keeper/grpc_query_test.go | 2 +- x/bank/keeper/invariants.go | 2 +- x/bank/keeper/querier_test.go | 4 +- x/bank/types/genesis.go | 2 +- x/bank/types/msgs.go | 2 +- x/distribution/keeper/delegation.go | 2 +- x/distribution/keeper/genesis.go | 2 +- x/distribution/keeper/invariants.go | 2 +- x/foundation/keeper/internal/invariants.go | 2 +- x/gov/abci_test.go | 4 +- x/gov/genesis.go | 2 +- x/gov/keeper/deposit_test.go | 2 +- x/gov/keeper/invariants.go | 2 +- x/gov/types/params.go | 4 +- x/mint/types/minter_test.go | 2 +- x/staking/genesis.go | 4 +- x/staking/types/msg_test.go | 2 +- 30 files changed, 204 insertions(+), 136 deletions(-) diff --git a/client/keys/delete.go b/client/keys/delete.go index b9e182a4c6..532e14edd0 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -37,7 +37,8 @@ private keys stored in a ledger device cannot be deleted with the CLI. for _, name := range args { info, err := clientCtx.Keyring.Key(name) if err != nil { - return err + cmd.PrintErrf("key %s not found\n", name) + continue } // confirm deletion, unless -y is passed diff --git a/client/keys/delete_test.go b/client/keys/delete_test.go index afb1c0fb0f..2a4bf397fd 100644 --- a/client/keys/delete_test.go +++ b/client/keys/delete_test.go @@ -51,8 +51,7 @@ func Test_runDeleteCmd(t *testing.T) { ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) err = cmd.ExecuteContext(ctx) - require.Error(t, err) - require.EqualError(t, err, "blah.info: key not found") + require.NoError(t, err) // User confirmation missing cmd.SetArgs([]string{ diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 8c5e2f0e88..07332825c7 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -370,7 +370,7 @@ func TestAddr(addr, bech string) (sdk.AccAddress, error) { func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) { t.Helper() ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) - require.True(t, balances.IsEqual(app.BankKeeper.GetAllBalances(ctxCheck, addr))) + require.True(t, balances.Equal(app.BankKeeper.GetAllBalances(ctxCheck, addr))) } // SignCheckDeliver checks a generated signed transaction and simulates a diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 3aef50bcca..61063a0da0 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -984,8 +984,16 @@ func commitStores(version int64, storeMap map[types.StoreKey]types.CommitKVStore storeInfos := make([]types.StoreInfo, 0, len(storeMap)) for key, store := range storeMap { - commitID := store.Commit() + last := store.LastCommitID() + // If a commit event execution is interrupted, a new iavl store's version will be larger than the rootmulti's metadata, when the block is replayed, we should avoid committing that iavl store again. + var commitID types.CommitID + if last.Version >= version { + last.Version = version + commitID = last + } else { + commitID = store.Commit() + } if store.GetStoreType() == types.StoreTypeTransient { continue } diff --git a/store/rootmulti/store_test.go b/store/rootmulti/store_test.go index da1c90842a..944075c803 100644 --- a/store/rootmulti/store_test.go +++ b/store/rootmulti/store_test.go @@ -858,3 +858,78 @@ func TestSetIAVLDIsableFastNode(t *testing.T) { multi.SetIAVLDisableFastNode(false) require.Equal(t, multi.iavlDisableFastNode, false) } + +type commitKVStoreStub struct { + types.CommitKVStore + Committed int +} + +func (stub *commitKVStoreStub) Commit() types.CommitID { + commitID := stub.CommitKVStore.Commit() + stub.Committed += 1 + return commitID +} + +func prepareStoreMap() map[types.StoreKey]types.CommitKVStore { + var db dbm.DB = dbm.NewMemDB() + store := NewStore(db, log.NewNopLogger()) + store.MountStoreWithDB(types.NewKVStoreKey("iavl1"), types.StoreTypeIAVL, nil) + store.MountStoreWithDB(types.NewKVStoreKey("iavl2"), types.StoreTypeIAVL, nil) + store.MountStoreWithDB(types.NewTransientStoreKey("trans1"), types.StoreTypeTransient, nil) + err := store.LoadLatestVersion() + if err != nil { + panic(err) + } + return map[types.StoreKey]types.CommitKVStore{ + testStoreKey1: &commitKVStoreStub{ + CommitKVStore: store.GetStoreByName("iavl1").(types.CommitKVStore), + }, + testStoreKey2: &commitKVStoreStub{ + CommitKVStore: store.GetStoreByName("iavl2").(types.CommitKVStore), + }, + testStoreKey3: &commitKVStoreStub{ + CommitKVStore: store.GetStoreByName("trans1").(types.CommitKVStore), + }, + } +} + +func TestCommitStores(t *testing.T) { + testCases := []struct { + name string + committed int + exptectCommit int + }{ + { + "when upgrade not get interrupted", + 0, + 1, + }, + { + "when upgrade get interrupted once", + 1, + 0, + }, + { + "when upgrade get interrupted twice", + 2, + 0, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + storeMap := prepareStoreMap() + store := storeMap[testStoreKey1].(*commitKVStoreStub) + for i := tc.committed; i > 0; i-- { + store.Commit() + } + store.Committed = 0 + var version int64 = 1 + res := commitStores(version, storeMap) + for _, s := range res.StoreInfos { + require.Equal(t, version, s.CommitId.Version) + } + require.Equal(t, version, res.Version) + require.Equal(t, tc.exptectCommit, store.Committed) + }) + } +} diff --git a/types/coin.go b/types/coin.go index 85d4c405da..1c86b46a9a 100644 --- a/types/coin.go +++ b/types/coin.go @@ -87,12 +87,9 @@ func (coin Coin) IsLT(other Coin) bool { } // IsEqual returns true if the two sets of Coins have the same value +// Deprecated: Use Coin.Equal instead. func (coin Coin) IsEqual(other Coin) bool { - if coin.Denom != other.Denom { - panic(fmt.Sprintf("invalid coin denominations; %s, %s", coin.Denom, other.Denom)) - } - - return coin.Amount.Equal(other.Amount) + return coin.Equal(other) } // Add adds amounts of two coins with same denom. If the coins differ in denom then @@ -295,7 +292,7 @@ func (coins Coins) Add(coinsB ...Coin) Coins { // denomination and addition only occurs when the denominations match, otherwise // the coin is simply added to the sum assuming it's not zero. // The function panics if `coins` or `coinsB` are not sorted (ascending). -func (coins Coins) safeAdd(coinsB Coins) Coins { +func (coins Coins) safeAdd(coinsB Coins) (coalesced Coins) { // probably the best way will be to make Coins and interface and hide the structure // definition (type alias) if !coins.isSorted() { @@ -305,51 +302,24 @@ func (coins Coins) safeAdd(coinsB Coins) Coins { panic("Wrong argument: coins must be sorted") } - sum := ([]Coin)(nil) - indexA, indexB := 0, 0 - lenA, lenB := len(coins), len(coinsB) - - for { - if indexA == lenA { - if indexB == lenB { - // return nil coins if both sets are empty - return sum - } - - // return set B (excluding zero coins) if set A is empty - return append(sum, removeZeroCoins(coinsB[indexB:])...) - } else if indexB == lenB { - // return set A (excluding zero coins) if set B is empty - return append(sum, removeZeroCoins(coins[indexA:])...) + uniqCoins := make(map[string]Coins, len(coins)+len(coinsB)) + // Traverse all the coins for each of the coins and coinsB. + for _, cL := range []Coins{coins, coinsB} { + for _, c := range cL { + uniqCoins[c.Denom] = append(uniqCoins[c.Denom], c) } + } - coinA, coinB := coins[indexA], coinsB[indexB] - - switch strings.Compare(coinA.Denom, coinB.Denom) { - case -1: // coin A denom < coin B denom - if !coinA.IsZero() { - sum = append(sum, coinA) - } - - indexA++ - - case 0: // coin A denom == coin B denom - res := coinA.Add(coinB) - if !res.IsZero() { - sum = append(sum, res) - } - - indexA++ - indexB++ - - case 1: // coin A denom > coin B denom - if !coinB.IsZero() { - sum = append(sum, coinB) - } - - indexB++ + for denom, cL := range uniqCoins { + comboCoin := Coin{Denom: denom, Amount: NewInt(0)} + for _, c := range cL { + comboCoin = comboCoin.Add(c) + } + if !comboCoin.IsZero() { + coalesced = append(coalesced, comboCoin) } } + return coalesced.Sort() } // DenomsSubsetOf returns true if receiver's denom set @@ -404,7 +374,7 @@ func (coins Coins) SafeSub(coinsB Coins) (Coins, bool) { // a.IsAllLTE(a.Max(b)) // b.IsAllLTE(a.Max(b)) // a.IsAllLTE(c) && b.IsAllLTE(c) == a.Max(b).IsAllLTE(c) -// a.Add(b...).IsEqual(a.Min(b).Add(a.Max(b)...)) +// a.Add(b...).Equal(a.Min(b).Add(a.Max(b)...)) // // E.g. // {1A, 3B, 2C}.Max({4A, 2B, 2C} == {4A, 3B, 2C}) @@ -450,7 +420,7 @@ func (coins Coins) Max(coinsB Coins) Coins { // a.Min(b).IsAllLTE(a) // a.Min(b).IsAllLTE(b) // c.IsAllLTE(a) && c.IsAllLTE(b) == c.IsAllLTE(a.Min(b)) -// a.Add(b...).IsEqual(a.Min(b).Add(a.Max(b)...)) +// a.Add(b...).Equal(a.Min(b).Add(a.Max(b)...)) // // E.g. // {1A, 3B, 2C}.Min({4A, 2B, 2C} == {1A, 2B, 2C}) @@ -593,8 +563,8 @@ func (coins Coins) IsZero() bool { return true } -// IsEqual returns true if the two sets of Coins have the same value -func (coins Coins) IsEqual(coinsB Coins) bool { +// Equal returns true if the two sets of Coins have the same value +func (coins Coins) Equal(coinsB Coins) bool { if len(coins) != len(coinsB) { return false } @@ -603,7 +573,7 @@ func (coins Coins) IsEqual(coinsB Coins) bool { coinsB = coinsB.Sort() for i := 0; i < len(coins); i++ { - if !coins[i].IsEqual(coinsB[i]) { + if !coins[i].Equal(coinsB[i]) { return false } } diff --git a/types/coin_test.go b/types/coin_test.go index bb5eee2cc6..4af7a46e00 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -5,6 +5,7 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "github.com/Finschia/finschia-sdk/codec" @@ -56,21 +57,15 @@ func (s *coinTestSuite) TestIsEqualCoin() { 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(testDenom2, 1), false, true}, - {sdk.NewInt64Coin("stake", 1), sdk.NewInt64Coin("stake", 10), false, false}, + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt64Coin(testDenom1, 1), true}, + {sdk.NewInt64Coin(testDenom1, 1), sdk.NewInt64Coin(testDenom2, 1), false}, + {sdk.NewInt64Coin("stake", 1), sdk.NewInt64Coin("stake", 10), false}, } for tcIndex, tc := range cases { - tc := tc - if tc.panics { - s.Require().Panics(func() { tc.inputOne.IsEqual(tc.inputTwo) }) - } else { - res := tc.inputOne.IsEqual(tc.inputTwo) - s.Require().Equal(tc.expected, res, "coin equality relation is incorrect, tc #%d", tcIndex) - } + res := tc.inputOne.IsEqual(tc.inputTwo) + s.Require().Equal(tc.expected, res, "coin equality relation is incorrect, tc #%d", tcIndex) } } @@ -405,45 +400,68 @@ func (s *coinTestSuite) TestEqualCoins() { inputOne sdk.Coins inputTwo sdk.Coins expected bool - panics bool }{ - {sdk.Coins{}, sdk.Coins{}, true, false}, - {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, true, false}, - {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, true, false}, - {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, sdk.Coins{sdk.NewInt64Coin(testDenom2, 0)}, false, true}, - {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 1)}, false, false}, - {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, false, false}, - {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, true, false}, + {sdk.Coins{}, sdk.Coins{}, true}, + {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, true}, + {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, true}, + {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, sdk.Coins{sdk.NewInt64Coin(testDenom2, 0)}, false}, + {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 1)}, false}, + {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, false}, + {sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, sdk.Coins{sdk.NewInt64Coin(testDenom1, 0), sdk.NewInt64Coin(testDenom2, 1)}, true}, } for tcnum, tc := range cases { - tc := tc - if tc.panics { - s.Require().Panics(func() { tc.inputOne.IsEqual(tc.inputTwo) }) - } else { - res := tc.inputOne.IsEqual(tc.inputTwo) - s.Require().Equal(tc.expected, res, "Equality is differed from exported. tc #%d, expected %b, actual %b.", tcnum, tc.expected, res) - } + res := tc.inputOne.Equal(tc.inputTwo) + s.Require().Equal(tc.expected, res, "Equality is differed from exported. tc #%d, expected %b, actual %b.", tcnum, tc.expected, res) } } func (s *coinTestSuite) TestAddCoins() { cases := []struct { + name string inputOne sdk.Coins inputTwo sdk.Coins expected sdk.Coins }{ - {sdk.Coins{s.ca1, s.cm1}, sdk.Coins{s.ca1, s.cm1}, sdk.Coins{s.ca2, s.cm2}}, - {sdk.Coins{s.ca0, s.cm1}, sdk.Coins{s.ca0, s.cm0}, sdk.Coins{s.cm1}}, - {sdk.Coins{s.ca2}, sdk.Coins{s.cm0}, sdk.Coins{s.ca2}}, - {sdk.Coins{s.ca1}, sdk.Coins{s.ca1, s.cm2}, sdk.Coins{s.ca2, s.cm2}}, - {sdk.Coins{s.ca0, s.cm0}, sdk.Coins{s.ca0, s.cm0}, sdk.Coins(nil)}, + {"{1atom,1muon}+{1atom,1muon}", sdk.Coins{s.ca1, s.cm1}, sdk.Coins{s.ca1, s.cm1}, sdk.Coins{s.ca2, s.cm2}}, + {"{0atom,1muon}+{0atom,0muon}", sdk.Coins{s.ca0, s.cm1}, sdk.Coins{s.ca0, s.cm0}, sdk.Coins{s.cm1}}, + {"{2atom}+{0muon}", sdk.Coins{s.ca2}, sdk.Coins{s.cm0}, sdk.Coins{s.ca2}}, + {"{1atom}+{1atom,2muon}", sdk.Coins{s.ca1}, sdk.Coins{s.ca1, s.cm2}, sdk.Coins{s.ca2, s.cm2}}, + {"{0atom,0muon}+{0atom,0muon}", sdk.Coins{s.ca0, s.cm0}, sdk.Coins{s.ca0, s.cm0}, sdk.Coins(nil)}, } - for tcIndex, tc := range cases { - res := tc.inputOne.Add(tc.inputTwo...) - s.Require().True(res.IsValid()) - s.Require().Equal(tc.expected, res, "sum of coins is incorrect, tc #%d", tcIndex) + for _, tc := range cases { + s.T().Run(tc.name, func(t *testing.T) { + res := tc.inputOne.Add(tc.inputTwo...) + require.True(t, res.IsValid(), fmt.Sprintf("%s + %s = %s", tc.inputOne, tc.inputTwo, res)) + require.Equal(t, tc.expected, res, "sum of coins is incorrect") + }) + } +} + +// Tests that even if coins with repeated denominations are passed into .Add that they +// are correctly coalesced. Please see issue https://github.com/cosmos/cosmos-sdk/issues/13234 +func TestCoinsAddCoalescesDuplicateDenominations(t *testing.T) { + A := sdk.Coins{ + {"den", sdk.NewInt(2)}, + {"den", sdk.NewInt(3)}, + } + B := sdk.Coins{ + {"den", sdk.NewInt(3)}, + {"den", sdk.NewInt(2)}, + {"den", sdk.NewInt(1)}, + } + + A = A.Sort() + B = B.Sort() + got := A.Add(B...) + + want := sdk.Coins{ + {"den", sdk.NewInt(11)}, + } + + if !got.Equal(want) { + t.Fatalf("Wrong result\n\tGot: %s\n\tWant: %s", got, want) } } @@ -684,8 +702,8 @@ func (s *coinTestSuite) TestMinMax() { for _, tc := range cases { min := tc.input1.Min(tc.input2) max := tc.input1.Max(tc.input2) - s.Require().True(min.IsEqual(tc.min), tc.name) - s.Require().True(max.IsEqual(tc.max), tc.name) + s.Require().True(min.Equal(tc.min), tc.name) + s.Require().True(max.Equal(tc.max), tc.name) } } @@ -961,7 +979,7 @@ func (s *coinTestSuite) TestNewCoins() { continue } got := sdk.NewCoins(tt.coins...) - s.Require().True(got.IsEqual(tt.want)) + s.Require().True(got.Equal(tt.want)) } } diff --git a/types/dec_coin.go b/types/dec_coin.go index 10856d0fe2..86b53f1607 100644 --- a/types/dec_coin.go +++ b/types/dec_coin.go @@ -79,12 +79,9 @@ func (coin DecCoin) IsLT(other DecCoin) bool { } // IsEqual returns true if the two sets of Coins have the same value. +// Deprecated: Use DecCoin.Equal instead. func (coin DecCoin) IsEqual(other DecCoin) bool { - if coin.Denom != other.Denom { - panic(fmt.Sprintf("invalid coin denominations; %s, %s", coin.Denom, other.Denom)) - } - - return coin.Amount.Equal(other.Amount) + return coin.Equal(other) } // Add adds amounts of two decimal coins with same denom. @@ -480,8 +477,8 @@ func (coins DecCoins) AmountOf(denom string) Dec { } } -// IsEqual returns true if the two sets of DecCoins have the same value. -func (coins DecCoins) IsEqual(coinsB DecCoins) bool { +// Equal returns true if the two sets of DecCoins have the same value. +func (coins DecCoins) Equal(coinsB DecCoins) bool { if len(coins) != len(coinsB) { return false } @@ -490,7 +487,7 @@ func (coins DecCoins) IsEqual(coinsB DecCoins) bool { coinsB = coinsB.Sort() for i := 0; i < len(coins); i++ { - if !coins[i].IsEqual(coinsB[i]) { + if !coins[i].Equal(coinsB[i]) { return false } } diff --git a/types/dec_coin_test.go b/types/dec_coin_test.go index e2c3ba9028..71673f9815 100644 --- a/types/dec_coin_test.go +++ b/types/dec_coin_test.go @@ -445,7 +445,7 @@ func (s *decCoinTestSuite) TestDecCoinsIntersect() { s.Require().NoError(err, "unexpected parse error in %v", i) exr, err := sdk.ParseDecCoins(tc.expectedResult) s.Require().NoError(err, "unexpected parse error in %v", i) - s.Require().True(in1.Intersect(in2).IsEqual(exr), "in1.cap(in2) != exr in %v", i) + s.Require().True(in1.Intersect(in2).Equal(exr), "in1.cap(in2) != exr in %v", i) } } diff --git a/x/auth/legacy/v043/store_test.go b/x/auth/legacy/v043/store_test.go index c9c07574a5..2d72024791 100644 --- a/x/auth/legacy/v043/store_test.go +++ b/x/auth/legacy/v043/store_test.go @@ -595,8 +595,8 @@ func trackingCorrected(t *testing.T, ctx sdk.Context, ak authkeeper.AccountKeepe vDA, ok := baseAccount.(exported.VestingAccount) require.True(t, ok) - vestedOk := expDelVesting.IsEqual(vDA.GetDelegatedVesting()) - freeOk := expDelFree.IsEqual(vDA.GetDelegatedFree()) + vestedOk := expDelVesting.Equal(vDA.GetDelegatedVesting()) + freeOk := expDelFree.Equal(vDA.GetDelegatedFree()) require.True(t, vestedOk, vDA.GetDelegatedVesting().String()) require.True(t, freeOk, vDA.GetDelegatedFree().String()) } diff --git a/x/auth/vesting/types/vesting_account.go b/x/auth/vesting/types/vesting_account.go index d3e385cab6..c25882316b 100644 --- a/x/auth/vesting/types/vesting_account.go +++ b/x/auth/vesting/types/vesting_account.go @@ -4,7 +4,7 @@ import ( "errors" "time" - yaml "gopkg.in/yaml.v2" + "gopkg.in/yaml.v2" cryptotypes "github.com/Finschia/finschia-sdk/crypto/types" sdk "github.com/Finschia/finschia-sdk/types" @@ -419,7 +419,7 @@ func (pva PeriodicVestingAccount) Validate() error { if endTime != pva.EndTime { return errors.New("vesting end time does not match length of all vesting periods") } - if !originalVesting.IsEqual(pva.OriginalVesting) { + if !originalVesting.Equal(pva.OriginalVesting) { return errors.New("original vesting coins does not match the sum of all coins in vesting periods") } diff --git a/x/auth/vesting/types/vesting_account_test.go b/x/auth/vesting/types/vesting_account_test.go index 3f94a17caf..26cbbcdeb7 100644 --- a/x/auth/vesting/types/vesting_account_test.go +++ b/x/auth/vesting/types/vesting_account_test.go @@ -209,7 +209,7 @@ func TestSpendableCoinsDelVestingAcc(t *testing.T) { // schedule dva := types.NewDelayedVestingAccount(bacc, origCoins, endTime.Unix()) lockedCoins := dva.LockedCoins(now) - require.True(t, lockedCoins.IsEqual(origCoins)) + require.True(t, lockedCoins.Equal(origCoins)) // require that all coins are spendable after the maturation of the vesting // schedule @@ -218,14 +218,14 @@ func TestSpendableCoinsDelVestingAcc(t *testing.T) { // require that all coins are still vesting after some time lockedCoins = dva.LockedCoins(now.Add(12 * time.Hour)) - require.True(t, lockedCoins.IsEqual(origCoins)) + require.True(t, lockedCoins.Equal(origCoins)) // delegate some locked coins // require that locked is reduced delegatedAmount := sdk.NewCoins(sdk.NewInt64Coin(stakeDenom, 50)) dva.TrackDelegation(now.Add(12*time.Hour), origCoins, delegatedAmount) lockedCoins = dva.LockedCoins(now.Add(12 * time.Hour)) - require.True(t, lockedCoins.IsEqual(origCoins.Sub(delegatedAmount))) + require.True(t, lockedCoins.Equal(origCoins.Sub(delegatedAmount))) } func TestTrackDelegationDelVestingAcc(t *testing.T) { @@ -573,18 +573,18 @@ func TestSpendableCoinsPermLockedVestingAcc(t *testing.T) { // schedule plva := types.NewPermanentLockedAccount(bacc, origCoins) lockedCoins := plva.LockedCoins(now) - require.True(t, lockedCoins.IsEqual(origCoins)) + require.True(t, lockedCoins.Equal(origCoins)) // require that all coins are still locked at end time lockedCoins = plva.LockedCoins(endTime) - require.True(t, lockedCoins.IsEqual(origCoins)) + require.True(t, lockedCoins.Equal(origCoins)) // delegate some locked coins // require that locked is reduced delegatedAmount := sdk.NewCoins(sdk.NewInt64Coin(stakeDenom, 50)) plva.TrackDelegation(now.Add(12*time.Hour), origCoins, delegatedAmount) lockedCoins = plva.LockedCoins(now.Add(12 * time.Hour)) - require.True(t, lockedCoins.IsEqual(origCoins.Sub(delegatedAmount))) + require.True(t, lockedCoins.Equal(origCoins.Sub(delegatedAmount))) } func TestTrackDelegationPermLockedVestingAcc(t *testing.T) { diff --git a/x/bank/keeper/genesis.go b/x/bank/keeper/genesis.go index e957112c12..fe680e04ee 100644 --- a/x/bank/keeper/genesis.go +++ b/x/bank/keeper/genesis.go @@ -25,7 +25,7 @@ func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) { totalSupply = totalSupply.Add(balance.Coins...) } - if !genState.Supply.Empty() && !genState.Supply.IsEqual(totalSupply) { + if !genState.Supply.Empty() && !genState.Supply.Equal(totalSupply) { panic(fmt.Errorf("genesis supply is incorrect, expected %v, got %v", genState.Supply, totalSupply)) } diff --git a/x/bank/keeper/grpc_query_test.go b/x/bank/keeper/grpc_query_test.go index 62cd3c701f..398e2ead13 100644 --- a/x/bank/keeper/grpc_query_test.go +++ b/x/bank/keeper/grpc_query_test.go @@ -41,7 +41,7 @@ func (suite *IntegrationTestSuite) TestQueryBalance() { res, err = queryClient.Balance(gocontext.Background(), req) suite.Require().NoError(err) suite.Require().NotNil(res) - suite.True(res.Balance.IsEqual(newFooCoin(50))) + suite.True(res.Balance.Equal(newFooCoin(50))) } func (suite *IntegrationTestSuite) TestQueryAllBalances() { diff --git a/x/bank/keeper/invariants.go b/x/bank/keeper/invariants.go index 361ba8b4c1..2191104db4 100644 --- a/x/bank/keeper/invariants.go +++ b/x/bank/keeper/invariants.go @@ -62,7 +62,7 @@ func TotalSupply(k Keeper) sdk.Invariant { return false }) - broken := !expectedTotal.IsEqual(supply) + broken := !expectedTotal.Equal(supply) return sdk.FormatInvariant(types.ModuleName, "total supply", fmt.Sprintf( diff --git a/x/bank/keeper/querier_test.go b/x/bank/keeper/querier_test.go index a47865d061..cde8f83df6 100644 --- a/x/bank/keeper/querier_test.go +++ b/x/bank/keeper/querier_test.go @@ -48,7 +48,7 @@ func (suite *IntegrationTestSuite) TestQuerier_QueryBalance() { suite.Require().NoError(err) suite.Require().NotNil(res) suite.Require().NoError(legacyAmino.UnmarshalJSON(res, &balance)) - suite.True(balance.IsEqual(newFooCoin(50))) + suite.True(balance.Equal(newFooCoin(50))) } func (suite *IntegrationTestSuite) TestQuerier_QueryAllBalances() { @@ -84,7 +84,7 @@ func (suite *IntegrationTestSuite) TestQuerier_QueryAllBalances() { suite.Require().NoError(err) suite.Require().NotNil(res) suite.Require().NoError(legacyAmino.UnmarshalJSON(res, &balances)) - suite.True(balances.IsEqual(origCoins)) + suite.True(balances.Equal(origCoins)) } func (suite *IntegrationTestSuite) TestQuerier_QueryTotalSupply() { diff --git a/x/bank/types/genesis.go b/x/bank/types/genesis.go index 2ee0f7612f..a343af7144 100644 --- a/x/bank/types/genesis.go +++ b/x/bank/types/genesis.go @@ -53,7 +53,7 @@ func (gs GenesisState) Validate() error { return err } - if !gs.Supply.IsEqual(totalSupply) { + if !gs.Supply.Equal(totalSupply) { return fmt.Errorf("genesis supply is incorrect, expected %v, got %v", gs.Supply, totalSupply) } } diff --git a/x/bank/types/msgs.go b/x/bank/types/msgs.go index ec4f4f07c4..7b1848e357 100644 --- a/x/bank/types/msgs.go +++ b/x/bank/types/msgs.go @@ -185,7 +185,7 @@ func ValidateInputsOutputs(inputs []Input, outputs []Output) error { } // make sure inputs and outputs match - if !totalIn.IsEqual(totalOut) { + if !totalIn.Equal(totalOut) { return ErrInputOutputMismatch } diff --git a/x/distribution/keeper/delegation.go b/x/distribution/keeper/delegation.go index 8dbb1c6034..8318c1b5d4 100644 --- a/x/distribution/keeper/delegation.go +++ b/x/distribution/keeper/delegation.go @@ -150,7 +150,7 @@ func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val stakingtypes.Vali // defensive edge case may happen on the very final digits // of the decCoins due to operation order of the distribution mechanism. rewards := rewardsRaw.Intersect(outstanding) - if !rewards.IsEqual(rewardsRaw) { + if !rewards.Equal(rewardsRaw) { logger := k.Logger(ctx) logger.Info( "rounding error withdrawing rewards from validator", diff --git a/x/distribution/keeper/genesis.go b/x/distribution/keeper/genesis.go index e78a51539a..02082070ea 100644 --- a/x/distribution/keeper/genesis.go +++ b/x/distribution/keeper/genesis.go @@ -90,7 +90,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { if balances.IsZero() { k.authKeeper.SetModuleAccount(ctx, moduleAcc) } - if !balances.IsEqual(moduleHoldingsInt) { + if !balances.Equal(moduleHoldingsInt) { panic(fmt.Sprintf("distribution module balance does not match the module holdings: %s <-> %s", balances, moduleHoldingsInt)) } } diff --git a/x/distribution/keeper/invariants.go b/x/distribution/keeper/invariants.go index c3b9c3a2e2..ee638c3f27 100644 --- a/x/distribution/keeper/invariants.go +++ b/x/distribution/keeper/invariants.go @@ -147,7 +147,7 @@ func ModuleAccountInvariant(k Keeper) sdk.Invariant { macc := k.GetDistributionAccount(ctx) balances := k.bankKeeper.GetAllBalances(ctx, macc.GetAddress()) - broken := !balances.IsEqual(expectedInt) + broken := !balances.Equal(expectedInt) return sdk.FormatInvariant( types.ModuleName, "ModuleAccount coins", fmt.Sprintf("\texpected ModuleAccount coins: %s\n"+ diff --git a/x/foundation/keeper/internal/invariants.go b/x/foundation/keeper/internal/invariants.go index b2abf2e0ea..40104a848b 100644 --- a/x/foundation/keeper/internal/invariants.go +++ b/x/foundation/keeper/internal/invariants.go @@ -30,7 +30,7 @@ func ModuleAccountInvariant(k Keeper) sdk.Invariant { treasury := k.GetTreasury(ctx) msg := fmt.Sprintf("coins in the treasury; expected %s, got %s\n", treasury, balance) - broken := !treasury.IsEqual(sdk.NewDecCoinsFromCoins(balance...)) + broken := !treasury.Equal(sdk.NewDecCoinsFromCoins(balance...)) return sdk.FormatInvariant(foundation.ModuleName, moduleAccountInvariant, msg), broken } diff --git a/x/gov/abci_test.go b/x/gov/abci_test.go index d593d63eb3..f9332a3e80 100644 --- a/x/gov/abci_test.go +++ b/x/gov/abci_test.go @@ -305,7 +305,7 @@ func TestProposalPassedEndblocker(t *testing.T) { moduleAccCoins := app.BankKeeper.GetAllBalances(ctx, macc.GetAddress()) deposits := initialModuleAccCoins.Add(proposal.TotalDeposit...).Add(proposalCoins...) - require.True(t, moduleAccCoins.IsEqual(deposits)) + require.True(t, moduleAccCoins.Equal(deposits)) err = app.GovKeeper.AddVote(ctx, proposal.ProposalId, addrs[0], types.NewNonSplitVoteOption(types.OptionYes)) require.NoError(t, err) @@ -318,7 +318,7 @@ func TestProposalPassedEndblocker(t *testing.T) { macc = app.GovKeeper.GetGovernanceAccount(ctx) require.NotNil(t, macc) - require.True(t, app.BankKeeper.GetAllBalances(ctx, macc.GetAddress()).IsEqual(initialModuleAccCoins)) + require.True(t, app.BankKeeper.GetAllBalances(ctx, macc.GetAddress()).Equal(initialModuleAccCoins)) } func TestEndBlockerProposalHandlerFailed(t *testing.T) { diff --git a/x/gov/genesis.go b/x/gov/genesis.go index 4b9e7974be..a4333a7fb3 100644 --- a/x/gov/genesis.go +++ b/x/gov/genesis.go @@ -48,7 +48,7 @@ func InitGenesis(ctx sdk.Context, ak types.AccountKeeper, bk types.BankKeeper, k } // check if total deposits equals balance, if it doesn't panic because there were export/import errors - if !balance.IsEqual(totalDeposits) { + if !balance.Equal(totalDeposits) { panic(fmt.Sprintf("expected module account was %s but we got %s", balance.String(), totalDeposits.String())) } } diff --git a/x/gov/keeper/deposit_test.go b/x/gov/keeper/deposit_test.go index 96f0a0f058..65cf29e116 100644 --- a/x/gov/keeper/deposit_test.go +++ b/x/gov/keeper/deposit_test.go @@ -28,7 +28,7 @@ func TestDeposits(t *testing.T) { addr0Initial := app.BankKeeper.GetAllBalances(ctx, TestAddrs[0]) addr1Initial := app.BankKeeper.GetAllBalances(ctx, TestAddrs[1]) - require.True(t, proposal.TotalDeposit.IsEqual(sdk.NewCoins())) + require.True(t, proposal.TotalDeposit.Equal(sdk.NewCoins())) // Check no deposits at beginning _, found := app.GovKeeper.GetDeposit(ctx, proposalID, TestAddrs[1]) diff --git a/x/gov/keeper/invariants.go b/x/gov/keeper/invariants.go index 0325887873..3270c5e35e 100644 --- a/x/gov/keeper/invariants.go +++ b/x/gov/keeper/invariants.go @@ -34,7 +34,7 @@ func ModuleAccountInvariant(keeper Keeper, bk types.BankKeeper) sdk.Invariant { macc := keeper.GetGovernanceAccount(ctx) balances := bk.GetAllBalances(ctx, macc.GetAddress()) - broken := !balances.IsEqual(expectedDeposits) + broken := !balances.Equal(expectedDeposits) return sdk.FormatInvariant(types.ModuleName, "deposits", fmt.Sprintf("\tgov ModuleAccount coins: %s\n\tsum of deposit amounts: %s\n", diff --git a/x/gov/types/params.go b/x/gov/types/params.go index c433fa8f63..115bf413c0 100644 --- a/x/gov/types/params.go +++ b/x/gov/types/params.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - yaml "gopkg.in/yaml.v2" + "gopkg.in/yaml.v2" sdk "github.com/Finschia/finschia-sdk/types" paramtypes "github.com/Finschia/finschia-sdk/x/params/types" @@ -63,7 +63,7 @@ func (dp DepositParams) String() string { // Equal checks equality of DepositParams func (dp DepositParams) Equal(dp2 DepositParams) bool { - return dp.MinDeposit.IsEqual(dp2.MinDeposit) && dp.MaxDepositPeriod == dp2.MaxDepositPeriod + return dp.MinDeposit.Equal(dp2.MinDeposit) && dp.MaxDepositPeriod == dp2.MaxDepositPeriod } func validateDepositParams(i interface{}) error { diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go index b5849379dc..bb32d58a63 100644 --- a/x/mint/types/minter_test.go +++ b/x/mint/types/minter_test.go @@ -80,7 +80,7 @@ func TestBlockProvision(t *testing.T) { expProvisions := sdk.NewCoin(params.MintDenom, sdk.NewInt(tc.expProvisions)) - require.True(t, expProvisions.IsEqual(provisions), + require.True(t, expProvisions.Equal(provisions), "test: %v\n\tExp: %v\n\tGot: %v\n", i, tc.expProvisions, provisions) } diff --git a/x/staking/genesis.go b/x/staking/genesis.go index 4efd550b95..1bb11cac1f 100644 --- a/x/staking/genesis.go +++ b/x/staking/genesis.go @@ -110,7 +110,7 @@ func InitGenesis( accountKeeper.SetModuleAccount(ctx, bondedPool) } // if balance is different from bonded coins panic because genesis is most likely malformed - if !bondedBalance.IsEqual(bondedCoins) { + if !bondedBalance.Equal(bondedCoins) { panic(fmt.Sprintf("bonded pool balance is different from bonded coins: %s <-> %s", bondedBalance, bondedCoins)) } notBondedPool := keeper.GetNotBondedPool(ctx) @@ -123,7 +123,7 @@ func InitGenesis( accountKeeper.SetModuleAccount(ctx, notBondedPool) } // if balance is different from non bonded coins panic because genesis is most likely malformed - if !notBondedBalance.IsEqual(notBondedCoins) { + if !notBondedBalance.Equal(notBondedCoins) { panic(fmt.Sprintf("not bonded pool balance is different from not bonded coins: %s <-> %s", notBondedBalance, notBondedCoins)) } // don't need to run Tendermint updates if we exported diff --git a/x/staking/types/msg_test.go b/x/staking/types/msg_test.go index 2981c0d7be..328c0b4102 100644 --- a/x/staking/types/msg_test.go +++ b/x/staking/types/msg_test.go @@ -47,7 +47,7 @@ func TestMsgDecode(t *testing.T) { require.NoError(t, err) msg2, ok := msgUnmarshaled.(*types.MsgCreateValidator) require.True(t, ok) - require.True(t, msg.Value.IsEqual(msg2.Value)) + require.True(t, msg.Value.Equal(msg2.Value)) require.True(t, msg.Pubkey.Equal(msg2.Pubkey)) }