Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speedup CL: TickToPrice #7539

Merged
merged 3 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions osmomath/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,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 @@ -357,7 +365,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 @@ -667,21 +676,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 @@ -691,7 +700,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
13 changes: 8 additions & 5 deletions x/concentrated-liquidity/math/tick.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/osmosis-labs/osmosis/v23/x/concentrated-liquidity/types"
)

var maxSpotPriceBigDec = osmomath.BigDecFromDec(types.MaxSpotPrice)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: let's move this to types


// TicksToSqrtPrice returns the sqrtPrice for the lower and upper ticks by
// individually calling `TickToSqrtPrice` method.
// Returns error if fails to calculate price.
Expand Down Expand Up @@ -101,7 +103,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 +114,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 +192,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(maxSpotPriceBigDec) || price.LT(types.MinSpotPriceV2) {
ValarDragon marked this conversation as resolved.
Show resolved Hide resolved
return 0, types.PriceBoundError{ProvidedPrice: price, MinSpotPrice: types.MinSpotPriceV2, MaxSpotPrice: types.MaxSpotPrice}
}
if price.Equal(osmomathBigOneDec) {
Expand Down Expand Up @@ -230,7 +233,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