Skip to content

Commit

Permalink
Speedup CL: TickToPrice (#7539) (#7546)
Browse files Browse the repository at this point in the history
* Speedup CL: TickToPrice

* Speedup PriceToTick

* Address Matt's comment

(cherry picked from commit a80c00e)

Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>
  • Loading branch information
mergify[bot] and ValarDragon authored Feb 19, 2024
1 parent 523dbe0 commit 42904f7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
19 changes: 14 additions & 5 deletions osmomath/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ func NewBigDecFromBigIntWithPrec(i *big.Int, prec int64) BigDec {
}
}

// returns a BigDec, built using a mutated copy of the passed in bigint.
// CONTRACT: prec <= BigDecPrecision
func NewBigDecFromBigIntMutWithPrec(i *big.Int, prec int64) BigDec {
return BigDec{
i.Mul(i, precisionMultiplier(prec)),
}
}

// create a new BigDec from big integer assuming whole numbers
// CONTRACT: prec <= BigDecPrecision
func NewBigDecFromInt(i BigInt) BigDec {
Expand Down Expand Up @@ -358,7 +366,8 @@ func (d BigDec) MulInt(i BigInt) BigDec {

// MulInt64 - multiplication with int64
func (d BigDec) MulInt64(i int64) BigDec {
mul := new(big.Int).Mul(d.i, big.NewInt(i))
bi := big.NewInt(i)
mul := bi.Mul(d.i, bi)

if mul.BitLen() > maxDecBitLen {
panic("Int overflow")
Expand Down Expand Up @@ -668,21 +677,21 @@ func (d BigDec) DecRoundUp() Dec {
// BigDecFromDec returns the BigDec representation of an Dec.
// Values in any additional decimal places are truncated.
func BigDecFromDec(d Dec) BigDec {
return NewBigDecFromBigIntWithPrec(d.BigInt(), DecPrecision)
return NewBigDecFromBigIntMutWithPrec(d.BigInt(), DecPrecision)
}

// BigDecFromSDKInt returns the BigDec representation of an sdkInt.
// Values in any additional decimal places are truncated.
func BigDecFromSDKInt(i Int) BigDec {
return NewBigDecFromBigIntWithPrec(i.BigInt(), 0)
return NewBigDecFromBigIntWithPrec(i.BigIntMut(), 0)
}

// BigDecFromDecSlice returns the []BigDec representation of an []Dec.
// Values in any additional decimal places are truncated.
func BigDecFromDecSlice(ds []Dec) []BigDec {
result := make([]BigDec, len(ds))
for i, d := range ds {
result[i] = NewBigDecFromBigIntWithPrec(d.BigInt(), DecPrecision)
result[i] = NewBigDecFromBigIntMutWithPrec(d.BigInt(), DecPrecision)
}
return result
}
Expand All @@ -692,7 +701,7 @@ func BigDecFromDecSlice(ds []Dec) []BigDec {
func BigDecFromDecCoinSlice(ds []sdk.DecCoin) []BigDec {
result := make([]BigDec, len(ds))
for i, d := range ds {
result[i] = NewBigDecFromBigIntWithPrec(d.Amount.BigInt(), DecPrecision)
result[i] = NewBigDecFromBigIntMutWithPrec(d.Amount.BigInt(), DecPrecision)
}
return result
}
Expand Down
11 changes: 6 additions & 5 deletions x/concentrated-liquidity/math/tick.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ func TickToPrice(tickIndex int64) (osmomath.BigDec, error) {
currentAdditiveIncrementInTicks := powTenBigDec(exponentAtCurrentTick)

// Now, starting at the minimum tick of the current increment, we calculate how many ticks in the current geometricExponent we have passed
numAdditiveTicks := osmomath.NewBigDec(tickIndex - (geometricExponentDelta * geometricExponentIncrementDistanceInTicks))
numAdditiveTicks := tickIndex - (geometricExponentDelta * geometricExponentIncrementDistanceInTicks)
additiveSpacing := currentAdditiveIncrementInTicks.MulInt64(numAdditiveTicks)

var price osmomath.BigDec

Expand All @@ -111,9 +112,9 @@ func TickToPrice(tickIndex int64) (osmomath.BigDec, error) {
// For the newly extended range of [MinInitializedTickV2, MinInitializedTick), we use the new math
// based on 36 precision decimal.
if tickIndex < types.MinInitializedTick {
price = powTenBigDec(geometricExponentDelta).Add(numAdditiveTicks.Mul(currentAdditiveIncrementInTicks))
price = additiveSpacing.AddMut(powTenBigDec(geometricExponentDelta))
} else {
price = osmomath.BigDecFromDec(PowTenInternal(geometricExponentDelta).Add(numAdditiveTicks.Mul(currentAdditiveIncrementInTicks).Dec()))
price = osmomath.BigDecFromDec(PowTenInternal(geometricExponentDelta).Add(additiveSpacing.Dec()))
}

// defense in depth, this logic would not be reached due to use having checked if given tick is in between
Expand Down Expand Up @@ -189,7 +190,7 @@ func CalculatePriceToTick(price osmomath.BigDec) (tickIndex int64, err error) {
if price.IsNegative() {
return 0, fmt.Errorf("price must be greater than zero")
}
if price.GT(osmomath.BigDecFromDec(types.MaxSpotPrice)) || price.LT(types.MinSpotPriceV2) {
if price.GT(types.MaxSpotPriceBigDec) || price.LT(types.MinSpotPriceV2) {
return 0, types.PriceBoundError{ProvidedPrice: price, MinSpotPrice: types.MinSpotPriceV2, MaxSpotPrice: types.MaxSpotPrice}
}
if price.Equal(osmomathBigOneDec) {
Expand Down Expand Up @@ -230,7 +231,7 @@ func CalculatePriceToTick(price osmomath.BigDec) (tickIndex int64, err error) {
// The number of ticks that need to be filled by our current spacing is
// (price - geoSpacing.initialPrice) / geoSpacing.additiveIncrementPerTick
priceInThisExponent := price.Sub(geoSpacing.initialPrice)
ticksFilledByCurrentSpacing := priceInThisExponent.Quo(geoSpacing.additiveIncrementPerTick)
ticksFilledByCurrentSpacing := priceInThisExponent.QuoMut(geoSpacing.additiveIncrementPerTick)
// we get the bucket index by:
// * taking the bucket index of the smallest price in this tick
// * adding to it the number of ticks filled by the current spacing
Expand Down

0 comments on commit 42904f7

Please sign in to comment.