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

feat: speedup epoch distribution, superfluid component (backport #2214) #2260

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

* [2260](https://github.com/osmosis-labs/osmosis/pull/2260) feat: speedup epoch distribution, superfluid component (backport #2214)

## [v7.3.0](https://github.com/osmosis-labs/osmosis/releases/tag/v7.3.0)

### Bug Fixes
Expand Down
78 changes: 26 additions & 52 deletions x/incentives/keeper/distribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,65 +224,39 @@ func (k Keeper) doDistributionSends(ctx sdk.Context, distrs *distributionInfo) e
// locks is expected to be the correct set of lock recipients for this gauge.
// TODO: Make this code have way more re-use with distribute internal (post-v7)
func (k Keeper) distributeSyntheticInternal(
ctx sdk.Context, gauge types.Gauge, locks []lockuptypes.PeriodLock, distrInfo *distributionInfo) (sdk.Coins, error) {
totalDistrCoins := sdk.NewCoins()
denom := gauge.DistributeTo.Denom

qualifiedLocks := make([]lockuptypes.PeriodLock, 0, len(locks))
ctx sdk.Context, gauge types.Gauge, locks []lockuptypes.PeriodLock, distrInfo *distributionInfo,
) (sdk.Coins, error) {
qualifiedLocks := k.lk.GetLocksLongerThanDurationDenom(ctx, gauge.DistributeTo.Denom, gauge.DistributeTo.Duration)

// map from lockID to present index in resultant list
// to be state compatible with what we had before, we iterate over locks, to get qualified locks
// to be in the same order as what is present in locks.
// in a future release, we can just use qualified locks directly.
type lockIndexPair struct {
lock lockuptypes.PeriodLock
index int
}
qualifiedLocksMap := make(map[uint64]lockIndexPair, len(qualifiedLocks))
for _, lock := range qualifiedLocks {
qualifiedLocksMap[lock.ID] = lockIndexPair{lock, -1}
}
curIndex := 0
for _, lock := range locks {
// See if this lock has a synthetic lockup. If so, err == nil, and we add to qualifiedLocks
// otherwise it does not, and we continue.
_, err := k.lk.GetSyntheticLockup(ctx, lock.ID, denom)
if err != nil {
continue
if v, ok := qualifiedLocksMap[lock.ID]; ok {
qualifiedLocksMap[lock.ID] = lockIndexPair{v.lock, curIndex}
curIndex += 1
}
qualifiedLocks = append(qualifiedLocks, lock)
}

lockSum := lockuptypes.SumLocksByDenom(qualifiedLocks, lockuptypes.NativeDenom(denom))

if lockSum.IsZero() {
return nil, nil
}

remainCoins := gauge.Coins.Sub(gauge.DistributedCoins)
remainEpochs := uint64(1)
if !gauge.IsPerpetual { // set remain epochs when it's not perpetual gauge
remainEpochs = gauge.NumEpochsPaidOver - gauge.FilledEpochs
}

for _, lock := range qualifiedLocks {
distrCoins := sdk.Coins{}
for _, coin := range remainCoins {
lockedCoin, err := lock.SingleCoin()
if err != nil {
k.Logger(ctx).Error(err.Error())
continue
}
// distribution amount = gauge_size * denom_lock_amount / (total_denom_lock_amount * remain_epochs)
// check if the synthlock is qualified for GetLocksToDistribution
amt := coin.Amount.Mul(lockedCoin.Amount).Quo(lockSum.Mul(sdk.NewIntFromUint64(remainEpochs)))
if amt.IsPositive() {
newlyDistributedCoin := sdk.Coin{Denom: coin.Denom, Amount: amt}
distrCoins = distrCoins.Add(newlyDistributedCoin)
}
}
distrCoins = distrCoins.Sort()
if distrCoins.Empty() {
sortedAndTrimmedQualifiedLocks := make([]lockuptypes.PeriodLock, curIndex)
for _, v := range qualifiedLocksMap {
if v.index < 0 {
continue
}
// Update the amount for that address
err := distrInfo.addLockRewards(lock.Owner, distrCoins)
if err != nil {
return nil, err
}

totalDistrCoins = totalDistrCoins.Add(distrCoins...)
sortedAndTrimmedQualifiedLocks[v.index] = v.lock
}

// increase filled epochs after distribution
err := k.updateGaugePostDistribute(ctx, gauge, totalDistrCoins)
return totalDistrCoins, err
return k.distributeInternal(ctx, gauge, sortedAndTrimmedQualifiedLocks, distrInfo)
}

// distributeInternal runs the distribution logic for a gauge, and adds the sends to
Expand All @@ -291,7 +265,7 @@ func (k Keeper) distributeSyntheticInternal(
func (k Keeper) distributeInternal(
ctx sdk.Context, gauge types.Gauge, locks []lockuptypes.PeriodLock, distrInfo *distributionInfo) (sdk.Coins, error) {
totalDistrCoins := sdk.NewCoins()
denom := gauge.DistributeTo.Denom
denom := lockuptypes.NativeDenom(gauge.DistributeTo.Denom)
lockSum := lockuptypes.SumLocksByDenom(locks, denom)

if lockSum.IsZero() {
Expand Down