From d6a896f4c96bd00bce8c8be340277c9385731485 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 14 Dec 2022 11:47:19 -0500 Subject: [PATCH] refactor(osmoutils): use Dec for additive tolerance instead of Int (#3711) * refactor(osmoutils): use Dec for additive tolerance instead of Int * changelog (cherry picked from commit 5ab7ebf66ba187fbcde3f51f2ee5600dc70c8b17) # Conflicts: # CHANGELOG.md # osmomath/binary_search.go # x/gamm/pool-models/balancer/pool_test.go # x/gamm/pool-models/internal/cfmm_common/lp.go # x/gamm/pool-models/stableswap/amm.go # x/gamm/pool-models/stableswap/amm_test.go --- CHANGELOG.md | 4 +++ osmomath/binary_search.go | 10 +++++-- osmomath/binary_search_test.go | 30 +++++++++---------- x/gamm/pool-models/balancer/pool_test.go | 5 ++++ x/gamm/pool-models/internal/cfmm_common/lp.go | 4 +++ x/gamm/pool-models/stableswap/amm.go | 4 +++ x/gamm/pool-models/stableswap/amm_test.go | 5 ++++ 7 files changed, 44 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 258a630e761..5d0f375f6f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,8 +79,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#3611](https://github.com/osmosis-labs/osmosis/pull/3611),[#3647](https://github.com/osmosis-labs/osmosis/pull/3647) Introduce osmocli, to automate thousands of lines of CLI boilerplate * [#3634](https://github.com/osmosis-labs/osmosis/pull/3634) (Makefile) Ensure correct golang version in make build and make install. (Thank you @jhernandezb ) +<<<<<<< HEAD * [#3712](https://github.com/osmosis-labs/osmosis/pull/3712) replace `osmomath.BigDec` `Power` with `PowerInteger` +======= +* [#3711](https://github.com/osmosis-labs/osmosis/pull/3711) Use Dec instead of Int for additive `ErrTolerace` in `osmoutils`. +>>>>>>> 5ab7ebf6 (refactor(osmoutils): use Dec for additive tolerance instead of Int (#3711)) ## v13.0.0 diff --git a/osmomath/binary_search.go b/osmomath/binary_search.go index 53888ce77a1..c9ba059da25 100644 --- a/osmomath/binary_search.go +++ b/osmomath/binary_search.go @@ -21,7 +21,7 @@ import ( // RoundingDir = RoundUnconstrained. // Note that if AdditiveTolerance == 0, then this is equivalent to a standard compare. type ErrTolerance struct { - AdditiveTolerance sdk.Int + AdditiveTolerance sdk.Dec MultiplicativeTolerance sdk.Dec RoundingDir RoundingDirection } @@ -31,7 +31,7 @@ type ErrTolerance struct { // returns 1 if not, and expected > actual. // returns -1 if not, and expected < actual func (e ErrTolerance) Compare(expected sdk.Int, actual sdk.Int) int { - diff := expected.Sub(actual).Abs() + diff := expected.ToDec().Sub(actual.ToDec()).Abs() comparisonSign := 0 if expected.GT(actual) { @@ -69,7 +69,7 @@ func (e ErrTolerance) Compare(expected sdk.Int, actual sdk.Int) int { } // Check multiplicative tolerance equations if !e.MultiplicativeTolerance.IsNil() && !e.MultiplicativeTolerance.IsZero() { - errTerm := diff.ToDec().Quo(sdk.MinInt(expected.Abs(), actual.Abs()).ToDec()) + errTerm := diff.Quo(sdk.MinInt(expected.Abs(), actual.Abs()).ToDec()) if errTerm.GT(e.MultiplicativeTolerance) { return comparisonSign } @@ -115,7 +115,11 @@ func (e ErrTolerance) CompareBigDec(expected BigDec, actual BigDec) int { } } +<<<<<<< HEAD:osmomath/binary_search.go if diff.GT(BigDecFromSDKDec(e.AdditiveTolerance.ToDec())) { +======= + if diff.GT(osmomath.BigDecFromSDKDec(e.AdditiveTolerance)) { +>>>>>>> 5ab7ebf6 (refactor(osmoutils): use Dec for additive tolerance instead of Int (#3711)):osmoutils/binary_search.go return comparisonSign } } diff --git a/osmomath/binary_search_test.go b/osmomath/binary_search_test.go index c46af6789f0..88b3a916845 100644 --- a/osmomath/binary_search_test.go +++ b/osmomath/binary_search_test.go @@ -10,7 +10,7 @@ import ( ) var ( - withinOne = ErrTolerance{AdditiveTolerance: sdk.OneInt()} + withinOne = ErrTolerance{AdditiveTolerance: sdk.OneDec()} withinFactor8 = ErrTolerance{MultiplicativeTolerance: sdk.NewDec(8)} zero = ZeroDec() ) @@ -27,10 +27,10 @@ func TestBinarySearch(t *testing.T) { output := sdk.Int(result) return output, nil } - noErrTolerance := ErrTolerance{AdditiveTolerance: sdk.ZeroInt()} - testErrToleranceAdditive := ErrTolerance{AdditiveTolerance: sdk.NewInt(1 << 20)} - testErrToleranceMultiplicative := ErrTolerance{AdditiveTolerance: sdk.ZeroInt(), MultiplicativeTolerance: sdk.NewDec(10)} - testErrToleranceBoth := ErrTolerance{AdditiveTolerance: sdk.NewInt(1 << 20), MultiplicativeTolerance: sdk.NewDec(1 << 3)} + noErrTolerance := ErrTolerance{AdditiveTolerance: sdk.ZeroDec()} + testErrToleranceAdditive := ErrTolerance{AdditiveTolerance: sdk.NewDec(1 << 20)} + testErrToleranceMultiplicative := ErrTolerance{AdditiveTolerance: sdk.ZeroDec(), MultiplicativeTolerance: sdk.NewDec(10)} + testErrToleranceBoth := ErrTolerance{AdditiveTolerance: sdk.NewDec(1 << 20), MultiplicativeTolerance: sdk.NewDec(1 << 3)} tests := map[string]struct { f func(sdk.Int) (sdk.Int, error) lowerbound sdk.Int @@ -155,9 +155,9 @@ var fnMap = map[string]searchFn{"line": lineF, "cubic": cubicF, "neg_cubic": neg // This function tests that any value in a given range can be reached within expected num iterations. func TestIterationDepthRandValue(t *testing.T) { tests := map[string]binarySearchTestCase{} - exactEqual := ErrTolerance{AdditiveTolerance: sdk.ZeroInt()} - withinOne := ErrTolerance{AdditiveTolerance: sdk.OneInt()} - within32 := ErrTolerance{AdditiveTolerance: sdk.OneInt().MulRaw(32)} + exactEqual := ErrTolerance{AdditiveTolerance: sdk.ZeroDec()} + withinOne := ErrTolerance{AdditiveTolerance: sdk.OneDec()} + within32 := ErrTolerance{AdditiveTolerance: sdk.OneDec().Mul(sdk.NewDec(32))} createRandInput := func(fnName string, lowerbound, upperbound int64, errTolerance ErrTolerance, maxNumIters int, errToleranceName string) { @@ -229,8 +229,8 @@ func runBinarySearchTestCases(t *testing.T, tests map[string]binarySearchTestCas } func TestBinarySearchBigDec(t *testing.T) { - testErrToleranceAdditive := ErrTolerance{AdditiveTolerance: sdk.NewInt(1 << 30)} - errToleranceBoth := ErrTolerance{AdditiveTolerance: sdk.NewInt(1 << 30), MultiplicativeTolerance: sdk.NewDec(1 << 3)} + testErrToleranceAdditive := ErrTolerance{AdditiveTolerance: sdk.NewDec(1 << 30)} + errToleranceBoth := ErrTolerance{AdditiveTolerance: sdk.NewDec(1 << 30), MultiplicativeTolerance: sdk.NewDec(1 << 3)} twoTo50 := NewBigDec(1 << 50) twoTo25PlusOne := NewBigDec(1 + (1 << 25)) @@ -281,7 +281,7 @@ func TestBinarySearchBigDec(t *testing.T) { } func TestBinarySearchRoundingBehavior(t *testing.T) { - withinTwoTo30 := ErrTolerance{AdditiveTolerance: sdk.NewInt(1 << 30)} + withinTwoTo30 := ErrTolerance{AdditiveTolerance: sdk.NewDec(1 << 30)} twoTo50 := NewBigDec(1 << 50) // twoTo25PlusOne := NewBigDec(1 + (1 << 25)) @@ -320,10 +320,10 @@ func TestBinarySearchRoundingBehavior(t *testing.T) { } func TestErrTolerance_Compare(t *testing.T) { - ZeroErrTolerance := ErrTolerance{AdditiveTolerance: sdk.ZeroInt(), MultiplicativeTolerance: sdk.Dec{}} - NonZeroErrAdditive := ErrTolerance{AdditiveTolerance: sdk.NewInt(10), MultiplicativeTolerance: sdk.Dec{}} - NonZeroErrMultiplicative := ErrTolerance{AdditiveTolerance: sdk.Int{}, MultiplicativeTolerance: sdk.NewDec(10)} - NonZeroErrBoth := ErrTolerance{AdditiveTolerance: sdk.NewInt(1), MultiplicativeTolerance: sdk.NewDec(10)} + ZeroErrTolerance := ErrTolerance{AdditiveTolerance: sdk.ZeroDec(), MultiplicativeTolerance: sdk.Dec{}} + NonZeroErrAdditive := ErrTolerance{AdditiveTolerance: sdk.NewDec(10), MultiplicativeTolerance: sdk.Dec{}} + NonZeroErrMultiplicative := ErrTolerance{AdditiveTolerance: sdk.Dec{}, MultiplicativeTolerance: sdk.NewDec(10)} + NonZeroErrBoth := ErrTolerance{AdditiveTolerance: sdk.NewDec(1), MultiplicativeTolerance: sdk.NewDec(10)} tests := []struct { name string tol ErrTolerance diff --git a/x/gamm/pool-models/balancer/pool_test.go b/x/gamm/pool-models/balancer/pool_test.go index eee85cebc7f..bdfe9b11e0e 100644 --- a/x/gamm/pool-models/balancer/pool_test.go +++ b/x/gamm/pool-models/balancer/pool_test.go @@ -574,8 +574,13 @@ func (suite *BalancerTestSuite) TestBalancerCalculateAmountOutAndIn_InverseRelat pool := createTestPool(suite.T(), swapFeeDec, exitFeeDec, poolAssetOut, poolAssetIn) suite.Require().NotNil(pool) +<<<<<<< HEAD errTolerance := osmomath.ErrTolerance{ AdditiveTolerance: sdk.OneInt(), MultiplicativeTolerance: sdk.Dec{}} +======= + errTolerance := osmoutils.ErrTolerance{ + AdditiveTolerance: sdk.OneDec(), MultiplicativeTolerance: sdk.Dec{}} +>>>>>>> 5ab7ebf6 (refactor(osmoutils): use Dec for additive tolerance instead of Int (#3711)) sut := func() { test_helpers.TestCalculateAmountOutAndIn_InverseRelationship(suite.T(), ctx, pool, poolAssetIn.Token.Denom, poolAssetOut.Token.Denom, tc.initialCalcOut, swapFeeDec, errTolerance) } diff --git a/x/gamm/pool-models/internal/cfmm_common/lp.go b/x/gamm/pool-models/internal/cfmm_common/lp.go index 76dc92df6c7..9ccbba3b58b 100644 --- a/x/gamm/pool-models/internal/cfmm_common/lp.go +++ b/x/gamm/pool-models/internal/cfmm_common/lp.go @@ -154,7 +154,11 @@ func BinarySearchSingleAssetJoin( } // We accept an additive tolerance of 1 LP share error and round down +<<<<<<< HEAD errTolerance := osmomath.ErrTolerance{AdditiveTolerance: sdk.OneInt(), MultiplicativeTolerance: sdk.Dec{}, RoundingDir: osmomath.RoundDown} +======= + errTolerance := osmoutils.ErrTolerance{AdditiveTolerance: sdk.OneDec(), MultiplicativeTolerance: sdk.Dec{}, RoundingDir: osmomath.RoundDown} +>>>>>>> 5ab7ebf6 (refactor(osmoutils): use Dec for additive tolerance instead of Int (#3711)) numLPShares, err = osmomath.BinarySearch( estimateCoinOutGivenShares, diff --git a/x/gamm/pool-models/stableswap/amm.go b/x/gamm/pool-models/stableswap/amm.go index 49930f3551c..c3ae8c4118f 100644 --- a/x/gamm/pool-models/stableswap/amm.go +++ b/x/gamm/pool-models/stableswap/amm.go @@ -326,7 +326,11 @@ func solveCFMMBinarySearchMulti(xReserve, yReserve, wSumSquares, yIn osmomath.Bi maxIterations := 256 // we use a geometric error tolerance that guarantees approximately 10^-12 precision on outputs +<<<<<<< HEAD errTolerance := osmomath.ErrTolerance{AdditiveTolerance: sdk.Int{}, MultiplicativeTolerance: sdk.NewDecWithPrec(1, 12)} +======= + errTolerance := osmoutils.ErrTolerance{AdditiveTolerance: sdk.Dec{}, MultiplicativeTolerance: sdk.NewDecWithPrec(1, 12)} +>>>>>>> 5ab7ebf6 (refactor(osmoutils): use Dec for additive tolerance instead of Int (#3711)) // if yIn is positive, we want to under-estimate the amount of xOut. // This means, we want x_out to be rounded down, as x_out = x_init - x_final, for x_init > x_final. diff --git a/x/gamm/pool-models/stableswap/amm_test.go b/x/gamm/pool-models/stableswap/amm_test.go index ce8c7f31cdd..f1a3ea7cc57 100644 --- a/x/gamm/pool-models/stableswap/amm_test.go +++ b/x/gamm/pool-models/stableswap/amm_test.go @@ -725,8 +725,13 @@ func (suite *StableSwapTestSuite) Test_StableSwap_CalculateAmountOutAndIn_Invers // TODO: add scaling factors into inverse relationship tests pool := createTestPool(suite.T(), tc.poolLiquidity, swapFeeDec, exitFeeDec, tc.scalingFactors) suite.Require().NotNil(pool) +<<<<<<< HEAD errTolerance := osmomath.ErrTolerance{ AdditiveTolerance: sdk.Int{}, MultiplicativeTolerance: sdk.NewDecWithPrec(1, 12)} +======= + errTolerance := osmoutils.ErrTolerance{ + AdditiveTolerance: sdk.Dec{}, MultiplicativeTolerance: sdk.NewDecWithPrec(1, 12)} +>>>>>>> 5ab7ebf6 (refactor(osmoutils): use Dec for additive tolerance instead of Int (#3711)) test_helpers.TestCalculateAmountOutAndIn_InverseRelationship(suite.T(), ctx, pool, tc.denomIn, tc.denomOut, tc.initialCalcOut, swapFeeDec, errTolerance) }) }