Skip to content

Commit

Permalink
feat(osmoutils): coin math helpers (backport #6427) (#6430)
Browse files Browse the repository at this point in the history
* feat(osmoutils): coin math helpers (backport #6427)

* go mod

* updates

---------

Co-authored-by: roman <[email protected]>
  • Loading branch information
mergify[bot] and p0mvn authored Sep 20, 2023
1 parent 7bd815e commit 4718007
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

* [#6427](https://github.com/osmosis-labs/osmosis/pull/6427) sdk.Coins Mul and Quo helpers in osmoutils
* [#6416](https://github.com/osmosis-labs/osmosis/pull/6416) feat[CL]: add num initialized ticks query

### Bug Fixes
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ require (
github.com/mattn/go-sqlite3 v1.14.17
github.com/ory/dockertest/v3 v3.10.0
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230907220438-2f6dd779bc6d
github.com/osmosis-labs/osmosis/osmoutils v0.0.6
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920004639-8744f48ee5fa
github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20230920012324-f1a1ca887bd2
github.com/osmosis-labs/osmosis/x/epochs v0.0.2
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.8
github.com/pkg/errors v0.9.1
Expand Down Expand Up @@ -56,7 +56,7 @@ require (
github.com/alingse/asasalint v0.0.11 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/butuzov/mirror v1.1.0 // indirect
github.com/bytedance/sonic v1.10.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/cosmos/gogoproto v1.4.6 // indirect
github.com/cosmos/iavl v0.19.5 // indirect
github.com/creachadair/taskgroup v0.3.2 // indirect
Expand Down
9 changes: 4 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc=
github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
Expand Down Expand Up @@ -964,10 +963,10 @@ github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230913192254-a2075590d5a3 h1:
github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230913192254-a2075590d5a3/go.mod h1:mFGH2RJhuZa6vBuFMNe4JN85fGtIhROtdeQIyIw9isA=
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 h1:YlmchqTmlwdWSmrRmXKR+PcU96ntOd8u10vTaTZdcNY=
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3/go.mod h1:lV6KnqXYD/ayTe7310MHtM3I2q8Z6bBfMAi+bhwPYtI=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230907220438-2f6dd779bc6d h1:b8Bz31kbzTbcSNsBOcvc2CRVJz5C3cGOQB7JqWDzdfA=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230907220438-2f6dd779bc6d/go.mod h1:Jj4zQ/IA8iPuHF+Hc/dTFJqAis5WYX3EcO7Xg70fAd8=
github.com/osmosis-labs/osmosis/osmoutils v0.0.6 h1:VI4wPzxXpdg5XEUaBugY9lADwxzw3H6lEJ0D+TZc4oE=
github.com/osmosis-labs/osmosis/osmoutils v0.0.6/go.mod h1:Pl8Nzx6O6ow/+aqfMoMSz4hX+zz6RrnDYsooptECGxM=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920004639-8744f48ee5fa h1:FE36Ul8OgnUJn06DqxyVHrMJcjgvf+/PfGtuahhbPxY=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230920004639-8744f48ee5fa/go.mod h1:oBmsOov8oxuWoI/yMQwyKGA6QfP0cBxylLt75gFbT8s=
github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20230920012324-f1a1ca887bd2 h1:A1Z6/SpM31atGBVyrgcgG0g50G9wHcfBxx8gIgQT9IQ=
github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20230920012324-f1a1ca887bd2/go.mod h1:ukjFgxfR9obDrMd8ZsxKcp3HWL7+boYORVL7Bt7YOZM=
github.com/osmosis-labs/osmosis/x/epochs v0.0.2 h1:aEeXHGCSJMgMtAvCucsD2RSaWZ8lISFLD5u4MyF9KPc=
github.com/osmosis-labs/osmosis/x/epochs v0.0.2/go.mod h1:8dvJFHTpu6SIxmOaSaEw0tHnQ/Z9blf5qsF/ZJnMVHo=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.8 h1:BUGowctYQT0vdPgULrvwraEsW+sS6DnbzndTLKLmWVY=
Expand Down
138 changes: 138 additions & 0 deletions osmoutils/coins/coin_math.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package coins

import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/osmosis-labs/osmosis/osmomath"
)

// Mutative helpers that mutate the input coins

// MulIntMut multiplies the coins by the given integer
// Mutates the input coins
func MulIntMut(coins sdk.Coins, num osmomath.Int) {
for i := range coins {
coins[i].Amount = coins[i].Amount.Mul(num)
}
}

// MulRawMut multiplies the coins by the given integer
// Mutates the input coins
func MulRawMut(coins sdk.Coins, num int64) sdk.Coins {
for i := range coins {
coins[i].Amount = coins[i].Amount.MulRaw(num)
}
return coins
}

// MulDecMut multiplies the coins by the given decimal
// Mutates the input coins
func MulDecMut(coins sdk.Coins, num osmomath.Dec) {
for i := range coins {
coins[i].Amount = coins[i].Amount.ToLegacyDec().Mul(num).TruncateInt()
}
}

// QuoIntMut divides the coins by the given integer
// Mutates the input coins
func QuoIntMut(coins sdk.Coins, num osmomath.Int) {
for i := range coins {
coins[i].Amount = coins[i].Amount.Quo(num)
}
}

// QuoRawMut divides the coins by the given integer
// Mutates the input coins
func QuoRawMut(coins sdk.Coins, num int64) {
for i := range coins {
coins[i].Amount = coins[i].Amount.QuoRaw(num)
}
}

// QuoIntMut divides the coins by the given decimal
// Mutates the input coins
func QuoDecMut(coins sdk.Coins, num osmomath.Dec) {
for i := range coins {
coins[i].Amount = coins[i].Amount.ToLegacyDec().Quo(num).TruncateInt()
}
}

// Non-mutative coin helpers that reallocate and return new coins

// MulInt multiplies the coins by the given integer
// Does not mutate the input coins and returns new coins.
func MulInt(coins sdk.Coins, num osmomath.Int) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.Mul(num)
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// MulRaw multiplies the coins by the given integer
// Does not mutate the input coins and returns new coins.
func MulRaw(coins sdk.Coins, num int64) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.MulRaw(num)
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// MulDec multiplies the coins by the given decimal
// Does not mutate the input coins and returns new coins.
func MulDec(coins sdk.Coins, num osmomath.Dec) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.ToLegacyDec().Mul(num).TruncateInt()
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// QuoInt divides the coins by the given integer
// Does not mutate the input coins and returns new coins.
func QuoInt(coins sdk.Coins, num osmomath.Int) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.Quo(num)
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// QuoRaw divides the coins by the given integer
// Does not mutate the input coins and returns new coins.
func QuoRaw(coins sdk.Coins, num int64) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.QuoRaw(num)
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}

// QuoDec divides the coins by the given integer
// Does not mutate the input coins and returns new coins.
func QuoDec(coins sdk.Coins, num osmomath.Dec) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))

for i := range coins {
newCoins[i].Amount = coins[i].Amount.ToLegacyDec().Quo(num).TruncateInt()
newCoins[i].Denom = coins[i].Denom
}

return newCoins
}
135 changes: 135 additions & 0 deletions osmoutils/coins/coin_math_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package coins_test

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/osmosis-labs/osmosis/osmomath"
"github.com/osmosis-labs/osmosis/osmoutils/coins"
)

var (
defaultCoins = sdk.NewCoins(
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("bar", sdk.NewInt(200)),
)

defaultMultiplier = osmomath.NewInt(2)

defaultMulExpectedResult = sdk.NewCoins(
sdk.NewCoin(defaultCoins[0].Denom, defaultCoins[0].Amount.Mul(defaultMultiplier)),
sdk.NewCoin(defaultCoins[1].Denom, defaultCoins[1].Amount.Mul(defaultMultiplier)),
)

defaultQuoExpectedResult = sdk.NewCoins(
sdk.NewCoin(defaultCoins[0].Denom, defaultCoins[0].Amount.Quo(defaultMultiplier)),
sdk.NewCoin(defaultCoins[1].Denom, defaultCoins[1].Amount.Quo(defaultMultiplier)),
)
)

// makes a deep copy to avoid accidentally mutating the input to a test.
func deepCopy(coins sdk.Coins) sdk.Coins {
newCoins := make(sdk.Coins, len(coins))
for i := range coins {
newCoins[i].Amount = coins[i].Amount
newCoins[i].Denom = coins[i].Denom
}
return newCoins
}

// Basic multiplication test.
func TestMul(t *testing.T) {
t.Run("test mutative multiplication", func(t *testing.T) {
t.Run("MulIntMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.MulIntMut(defaulCoins, defaultMultiplier)
require.Equal(t, defaultMulExpectedResult, defaulCoins)
})

t.Run("MulIntRawMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.MulRawMut(defaulCoins, defaultMultiplier.Int64())
require.Equal(t, defaultMulExpectedResult, defaulCoins)
})

t.Run("MulDecMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.MulDecMut(defaulCoins, osmomath.NewDecFromInt(defaultMultiplier))
require.Equal(t, defaultMulExpectedResult, defaulCoins)
})
})

// Make a deep copy of the default coins for the input.
// Validate that the copy input coins are not mutated.
t.Run("test non-mutative multiplication", func(t *testing.T) {
t.Run("MulInt", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.MulInt(defaulCoinsCopy, defaultMultiplier)
require.Equal(t, defaultMulExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})

t.Run("MulIntRaw", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.MulRaw(defaulCoinsCopy, defaultMultiplier.Int64())
require.Equal(t, defaultMulExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})

t.Run("MulDec", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.MulDec(defaulCoinsCopy, osmomath.NewDecFromInt(defaultMultiplier))
require.Equal(t, defaultMulExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})
})
}

func TestQuo(t *testing.T) {
t.Run("test mutative division", func(t *testing.T) {
t.Run("QuoIntMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.QuoIntMut(defaulCoins, defaultMultiplier)
require.Equal(t, defaultQuoExpectedResult, defaulCoins)
})

t.Run("QuoIntRawMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.QuoRawMut(defaulCoins, defaultMultiplier.Int64())
require.Equal(t, defaultQuoExpectedResult, defaulCoins)
})

t.Run("QuoDecMut", func(t *testing.T) {
defaulCoins := deepCopy(defaultCoins)
coins.QuoDecMut(defaulCoins, osmomath.NewDecFromInt(defaultMultiplier))
require.Equal(t, defaultQuoExpectedResult, defaulCoins)
})
})

// Make a deep copy of the default coins for the input.
// Validate that the copy input coins are not mutated.
t.Run("test non-mutative division", func(t *testing.T) {
t.Run("QuoInt", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.QuoInt(defaulCoinsCopy, defaultMultiplier)
require.Equal(t, defaultQuoExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})

t.Run("QuoIntRaw", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.QuoRaw(defaulCoinsCopy, defaultMultiplier.Int64())
require.Equal(t, defaultQuoExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})

t.Run("QuoDec", func(t *testing.T) {
defaulCoinsCopy := deepCopy(defaultCoins)
result := coins.QuoDec(defaulCoinsCopy, osmomath.NewDecFromInt(defaultMultiplier))
require.Equal(t, defaultQuoExpectedResult, result)
require.Equal(t, defaultCoins, defaulCoinsCopy)
})
})
}
3 changes: 3 additions & 0 deletions osmoutils/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04=
cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0=
cosmossdk.io/math v1.1.3-rc.0 h1:lut7IbQGuqog4vEIHSB7ivtwwIr6rHrt5yoVowmtoDs=
cosmossdk.io/math v1.1.3-rc.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
Expand Down Expand Up @@ -148,6 +149,7 @@ github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc=
github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
Expand Down Expand Up @@ -706,6 +708,7 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230913192254-a2075590d5a3 h1:kRNCIZn9NU8BBObAsFj0Zp05QQo/4iLDfRiXgtXF//I=
github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230913192254-a2075590d5a3/go.mod h1:mFGH2RJhuZa6vBuFMNe4JN85fGtIhROtdeQIyIw9isA=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230907220438-2f6dd779bc6d h1:b8Bz31kbzTbcSNsBOcvc2CRVJz5C3cGOQB7JqWDzdfA=
github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20230907220438-2f6dd779bc6d/go.mod h1:Jj4zQ/IA8iPuHF+Hc/dTFJqAis5WYX3EcO7Xg70fAd8=
github.com/osmosis-labs/osmosis/v19 v19.0.0 h1:gqcas/XfxtEuZXsWGTO9vNMHiY78Qs09FBQw73djIVM=
Expand Down

0 comments on commit 4718007

Please sign in to comment.