Fix IsAnyGTE (#3265)

This commit is contained in:
Alexander Bezobchuk 2019-01-09 15:31:03 -05:00 committed by Jack Zampolin
parent d1e769391a
commit 03bdd3f870
3 changed files with 54 additions and 88 deletions

View File

@ -45,23 +45,22 @@ func TestGaiaCLIMinimumFees(t *testing.T) {
require.False(f.T, success)
tests.WaitForNextNBlocksTM(1, f.Port)
// TODO: Make this work
// // Ensure tx w/ correct fees (stake) pass
// txFees := fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(denom, 23))
// success = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(denom, 10), txFees)
// require.True(f.T, success)
// tests.WaitForNextNBlocksTM(1, f.Port)
//
// // Ensure tx w/ correct fees (feetoken) pass
// txFees = fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(feeDenom, 23))
// success = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(feeDenom, 10), txFees)
// require.True(f.T, success)
// tests.WaitForNextNBlocksTM(1, f.Port)
//
// // Ensure tx w/ improper fees (footoken) fails
// txFees = fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(fooDenom, 23))
// success = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(fooDenom, 10), txFees)
// require.False(f.T, success)
// Ensure tx w/ correct fees (stake) pass
txFees := fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(denom, 23))
success, _, _ = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(denom, 10), txFees)
require.True(f.T, success)
tests.WaitForNextNBlocksTM(1, f.Port)
// Ensure tx w/ correct fees (feetoken) pass
txFees = fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(feeDenom, 23))
success, _, _ = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(feeDenom, 10), txFees)
require.True(f.T, success)
tests.WaitForNextNBlocksTM(1, f.Port)
// Ensure tx w/ improper fees (footoken) fails
txFees = fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(fooDenom, 23))
success, _, _ = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(fooDenom, 10), txFees)
require.False(f.T, success)
// Cleanup testing directories
f.Cleanup()

View File

@ -265,28 +265,6 @@ func (coins Coins) SafeMinus(coinsB Coins) (Coins, bool) {
return diff, !diff.IsNotNegative()
}
// IsAnyGT returns true if coins contains at least one denom
// that is present at a smaller amount in coinsB; it
// returns false otherwise.
func (coins Coins) IsAnyGT(coinsB Coins) bool {
intersection := coins.intersect(coinsB)
if intersection.Empty() {
return false
}
diff, _ := intersection.SafeMinus(coinsB)
if len(diff) == 0 {
return false
}
for _, coin := range diff {
if coin.IsPositive() {
return true
}
}
return false
}
// IsAllGT returns true if for every denom in coins, the denom is present at a
// greater amount in coinsB.
func (coins Coins) IsAllGT(coinsB Coins) bool {
@ -298,28 +276,6 @@ func (coins Coins) IsAllGT(coinsB Coins) bool {
return diff.IsPositive()
}
// IsAnyGT returns true if coins contains at least one denom
// that is present at a smaller or equal amount in coinsB; it
// returns false otherwise.
func (coins Coins) IsAnyGTE(coinsB Coins) bool {
intersection := coins.intersect(coinsB)
if intersection.Empty() {
return false
}
diff, _ := intersection.SafeMinus(coinsB)
if len(diff) == 0 || len(diff) < len(intersection) { // zero diff is removed from the diff set
return true
}
for _, coin := range diff {
if coin.IsNotNegative() {
return true
}
}
return false
}
// IsAllGTE returns true iff for every denom in coins, the denom is present at
// an equal or greater amount in coinsB.
func (coins Coins) IsAllGTE(coinsB Coins) bool {
@ -343,6 +299,41 @@ func (coins Coins) IsAllLTE(coinsB Coins) bool {
return coinsB.IsAllGTE(coins)
}
// 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.
//
// NOTE: IsAnyGTE operates under the invariant that coins are sorted by
// denominations.
func (coins Coins) IsAnyGTE(coinsB Coins) bool {
if len(coinsB) == 0 {
return false
}
j := 0
for _, coin := range coins {
searchOther := true // terminator in case coins breaks the sorted invariant
for j < len(coinsB) && searchOther {
switch strings.Compare(coin.Denom, coinsB[j].Denom) {
case -1:
// coin denom in less than the current other coin, so move to next coin
searchOther = false
case 0:
if coin.IsGTE(coinsB[j]) {
return true
}
fallthrough // skip to next other coin
case 1:
// coin denom is greater than the current other coin, so move to next other coin
j++
}
}
}
return false
}
// IsZero returns true if there are no coins or all coins are zero.
func (coins Coins) IsZero() bool {
for _, coin := range coins {
@ -474,20 +465,6 @@ func removeZeroCoins(coins Coins) Coins {
return coins[:i]
}
func (coins Coins) intersect(coinsB Coins) Coins {
intersection := Coins{}
for _, coin := range coins {
for _, bCoin := range coinsB {
if coin.Denom == bCoin.Denom {
intersection = append(intersection, coin)
break
}
}
}
return intersection
}
//-----------------------------------------------------------------------------
// Sort interface

View File

@ -368,28 +368,18 @@ func TestCoinsLTE(t *testing.T) {
assert.True(t, Coins{}.IsAllLTE(Coins{{"a", one}}))
}
func TestCoinsIsAnyGT(t *testing.T) {
one := NewInt(1)
two := NewInt(2)
assert.False(t, Coins{}.IsAnyGT(Coins{}))
assert.False(t, Coins{{"a", one}}.IsAnyGT(Coins{}))
assert.False(t, Coins{}.IsAnyGT(Coins{{"a", one}}))
assert.False(t, Coins{{"a", one}}.IsAnyGT(Coins{{"a", one}}))
assert.False(t, Coins{{"a", one}}.IsAnyGT(Coins{{"a", two}}))
assert.True(t, Coins{{"a", two}}.IsAnyGT(Coins{{"a", one}}))
assert.True(t, Coins{{"a", one}, {"b", two}}.IsAnyGT(Coins{{"a", one}, {"b", one}}))
assert.True(t, Coins{{"a", two}, {"b", one}}.IsAnyGT(Coins{{"a", one}, {"b", two}}))
}
func TestCoinsIsAnyGTE(t *testing.T) {
one := NewInt(1)
two := NewInt(2)
assert.False(t, Coins{}.IsAnyGTE(Coins{}))
assert.False(t, Coins{{"a", one}}.IsAnyGTE(Coins{}))
assert.False(t, Coins{}.IsAnyGTE(Coins{{"a", one}}))
assert.False(t, Coins{{"a", one}}.IsAnyGTE(Coins{{"a", two}}))
assert.True(t, Coins{{"a", one}, {"b", two}}.IsAnyGTE(Coins{{"a", two}, {"b", one}}))
assert.True(t, Coins{{"a", one}}.IsAnyGTE(Coins{{"a", one}}))
assert.True(t, Coins{{"a", two}}.IsAnyGTE(Coins{{"a", one}}))
assert.True(t, Coins{{"a", one}}.IsAnyGTE(Coins{{"a", one}, {"b", two}}))
assert.True(t, Coins{{"a", one}, {"b", two}}.IsAnyGTE(Coins{{"a", one}, {"b", one}}))
assert.True(t, Coins{{"a", one}, {"b", one}}.IsAnyGTE(Coins{{"a", one}, {"b", two}}))
}