Skip to content

Commit

Permalink
Merge pull request #1504 from multiversx/development
Browse files Browse the repository at this point in the history
Merge development into feat/sdk-core-v13
  • Loading branch information
claudiulataretu authored Oct 10, 2024
2 parents 32babcf + af9942c commit d7de8dd
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,26 @@ export class FeesCollectorSetterService extends GenericSetterService {
CacheTtlInfo.ContractInfo.localTtl,
);
}

async allTokens(tokens: string[]): Promise<string> {
return this.setData(
this.getCacheKey('allTokens'),
tokens,
CacheTtlInfo.ContractInfo.remoteTtl,
CacheTtlInfo.ContractInfo.localTtl,
);
}

async accumulatedFeesUntilNow(
scAddress: string,
week: number,
value: string,
): Promise<string> {
return this.setData(
this.getCacheKey('accumulatedFeesUntilNow', scAddress, week),
value,
CacheTtlInfo.ContractBalance.remoteTtl,
CacheTtlInfo.ContractBalance.localTtl,
);
}
}
23 changes: 19 additions & 4 deletions src/modules/staking/services/staking.compute.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,17 +141,24 @@ export class StakingComputeService {
async computeExtraRewardsBounded(
stakeAddress: string,
blockDifferenceBig: BigNumber,
): Promise<BigNumber> {
const extraRewardsAPRBoundedPerBlock =
await this.computeExtraRewardsAPRBoundedPerBlock(stakeAddress);

return extraRewardsAPRBoundedPerBlock.multipliedBy(blockDifferenceBig);
}

async computeExtraRewardsAPRBoundedPerBlock(
stakeAddress: string,
): Promise<BigNumber> {
const [farmTokenSupply, annualPercentageRewards] = await Promise.all([
this.stakingAbi.farmTokenSupply(stakeAddress),
this.stakingAbi.annualPercentageRewards(stakeAddress),
]);
const extraRewardsAPRBoundedPerBlock = new BigNumber(farmTokenSupply)
return new BigNumber(farmTokenSupply)
.multipliedBy(annualPercentageRewards)
.dividedBy(constantsConfig.MAX_PERCENT)
.dividedBy(constantsConfig.BLOCKS_IN_YEAR);

return extraRewardsAPRBoundedPerBlock.multipliedBy(blockDifferenceBig);
}

async farmingTokenPriceUSD(stakeAddress: string): Promise<string> {
Expand Down Expand Up @@ -325,10 +332,18 @@ export class StakingComputeService {
// 10 blocks per minute * 60 minutes per hour * 24 hours per day
const blocksInDay = 10 * 60 * 24;

const extraRewardsAPRBoundedPerBlock =
await this.computeExtraRewardsAPRBoundedPerBlock(stakeAddress);

const perBlockRewards = BigNumber.min(
extraRewardsAPRBoundedPerBlock,
perBlockRewardAmount,
);

return parseFloat(
new BigNumber(rewardsCapacity)
.minus(accumulatedRewards)
.dividedBy(perBlockRewardAmount)
.dividedBy(perBlockRewards)
.dividedBy(blocksInDay)
.toFixed(2),
);
Expand Down
13 changes: 13 additions & 0 deletions src/modules/staking/services/staking.setter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info';
import { GenericSetterService } from 'src/services/generics/generic.setter.service';
import { Logger } from 'winston';
import { EsdtTokenPayment } from '@multiversx/sdk-exchange';
import { BoostedYieldsFactors } from 'src/modules/farm/models/farm.v2.model';

@Injectable()
export class StakingSetterService extends GenericSetterService {
Expand Down Expand Up @@ -178,6 +179,18 @@ export class StakingSetterService extends GenericSetterService {
);
}

async setBoostedYieldsFactors(
stakeAddress: string,
value: BoostedYieldsFactors,
): Promise<string> {
return await this.setData(
this.getCacheKey('boostedYieldsFactors', stakeAddress),
value,
CacheTtlInfo.ContractState.remoteTtl,
CacheTtlInfo.ContractState.localTtl,
);
}

async setUserTotalStakePosition(
stakeAddress: string,
userAddress: string,
Expand Down
8 changes: 8 additions & 0 deletions src/services/cache.warmer.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ import { TokensCacheWarmerService } from './crons/tokens.cache.warmer.service';
import { FarmModuleV2 } from 'src/modules/farm/v2/farm.v2.module';
import { EscrowCacheWarmerService } from './crons/escrow.cache.warmer.service';
import { EscrowModule } from 'src/modules/escrow/escrow.module';
import { FeesCollectorCacheWarmerService } from './crons/fees.collector.cache.warmer.service';
import { FeesCollectorModule } from 'src/modules/fees-collector/fees-collector.module';
import { WeekTimekeepingModule } from 'src/submodules/week-timekeeping/week-timekeeping.module';
import { WeeklyRewardsSplittingModule } from 'src/submodules/weekly-rewards-splitting/weekly-rewards-splitting.module';

@Module({
imports: [
Expand Down Expand Up @@ -66,6 +70,9 @@ import { EscrowModule } from 'src/modules/escrow/escrow.module';
GovernanceModule,
DynamicModuleUtils.getCacheModule(),
EscrowModule,
FeesCollectorModule,
WeekTimekeepingModule,
WeeklyRewardsSplittingModule,
],
controllers: [],
providers: [
Expand All @@ -85,6 +92,7 @@ import { EscrowModule } from 'src/modules/escrow/escrow.module';
ElasticService,
TokensCacheWarmerService,
EscrowCacheWarmerService,
FeesCollectorCacheWarmerService,
],
})
export class CacheWarmerModule {}
157 changes: 157 additions & 0 deletions src/services/crons/fees.collector.cache.warmer.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { Inject, Injectable } from '@nestjs/common';
import { PUB_SUB } from '../redis.pubSub.module';
import { RedisPubSub } from 'graphql-redis-subscriptions';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { Cron, CronExpression } from '@nestjs/schedule';
import { PerformanceProfiler } from '@multiversx/sdk-nestjs-monitoring';
import { FeesCollectorAbiService } from 'src/modules/fees-collector/services/fees-collector.abi.service';
import { WeekTimekeepingAbiService } from 'src/submodules/week-timekeeping/services/week-timekeeping.abi.service';
import { constantsConfig, scAddress } from 'src/config';
import { FeesCollectorSetterService } from 'src/modules/fees-collector/services/fees-collector.setter.service';
import { WeeklyRewardsSplittingAbiService } from 'src/submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.abi.service';
import { FeesCollectorComputeService } from 'src/modules/fees-collector/services/fees-collector.compute.service';
import { WeeklyRewardsSplittingSetterService } from 'src/submodules/weekly-rewards-splitting/services/weekly.rewarrds.splitting.setter.service';
import { Lock } from '@multiversx/sdk-nestjs-common';

@Injectable()
export class FeesCollectorCacheWarmerService {
constructor(
@Inject(PUB_SUB) private pubSub: RedisPubSub,
@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
private readonly feesCollectorAbi: FeesCollectorAbiService,
private readonly feesCollectorCompute: FeesCollectorComputeService,
private readonly feesCollectorSetter: FeesCollectorSetterService,
private readonly weekTimekeepingAbi: WeekTimekeepingAbiService,
private readonly weeklyRewardsSplittingAbi: WeeklyRewardsSplittingAbiService,
private readonly weeklyRewardsSplittingSetter: WeeklyRewardsSplittingSetterService,
) {}

@Cron(CronExpression.EVERY_MINUTE)
@Lock({ name: 'cacheFeesCollector', verbose: true })
async cacheFeesCollector(): Promise<void> {
this.logger.info('Start refresh fees collector data', {
context: 'CacheFeesCollector',
});

const profiler = new PerformanceProfiler();

const [allTokens, currentWeek] = await Promise.all([
this.feesCollectorAbi.allTokens(),
this.weekTimekeepingAbi.currentWeek(scAddress.feesCollector),
]);

const accumulatedFeesUntilNow =
await this.feesCollectorCompute.computeAccumulatedFeesUntilNow(
scAddress.feesCollector,
currentWeek,
);

const cachedKeys = await Promise.all([
this.feesCollectorSetter.allTokens(allTokens),
this.feesCollectorSetter.accumulatedFeesUntilNow(
scAddress.feesCollector,
currentWeek,
accumulatedFeesUntilNow,
),
]);

const tokensAccumulatedFeesCacheKeys =
await this.cacheTokensAccumulatedFees(allTokens, currentWeek);

const claimWeeksCacheKeys = await this.cacheClaimWeeksData(
currentWeek,
scAddress.feesCollector,
);

cachedKeys.push(...tokensAccumulatedFeesCacheKeys);
cachedKeys.push(...claimWeeksCacheKeys);

await this.deleteCacheKeys(cachedKeys);

profiler.stop();
this.logger.info(
`Finish refresh fees collector data in ${profiler.duration}`,
{
context: 'CacheFeesCollector',
},
);
}

private async cacheTokensAccumulatedFees(
allTokens: string[],
week: number,
): Promise<string[]> {
const cachedKeys = [];
for (const token of allTokens) {
const accumulatedFees =
await this.feesCollectorAbi.getAccumulatedFeesRaw(week, token);

const cacheKey = await this.feesCollectorSetter.accumulatedFees(
week,
token,
accumulatedFees,
);

cachedKeys.push(cacheKey);
}

return cachedKeys;
}

private async cacheClaimWeeksData(
currentWeek: number,
feesCollectorScAddress: string,
): Promise<string[]> {
const cachedKeys = [];
const startWeek = currentWeek - constantsConfig.USER_MAX_CLAIM_WEEKS;

for (let week = startWeek; week <= currentWeek; week++) {
if (week < 1) {
continue;
}

const totalEnergyForWeek =
await this.weeklyRewardsSplittingAbi.totalEnergyForWeekRaw(
feesCollectorScAddress,
week,
);
const totalRewardsForWeek =
await this.weeklyRewardsSplittingAbi.totalRewardsForWeekRaw(
feesCollectorScAddress,
week,
);
const totalLockedTokensForWeek =
await this.weeklyRewardsSplittingAbi.totalLockedTokensForWeekRaw(
feesCollectorScAddress,
week,
);

const keys = await Promise.all([
this.weeklyRewardsSplittingSetter.totalEnergyForWeek(
feesCollectorScAddress,
week,
totalEnergyForWeek,
),
this.weeklyRewardsSplittingSetter.totalRewardsForWeek(
feesCollectorScAddress,
week,
totalRewardsForWeek,
),
this.weeklyRewardsSplittingSetter.totalLockedTokensForWeek(
feesCollectorScAddress,
week,
totalLockedTokensForWeek,
),
]);

cachedKeys.push(...keys);
}

return cachedKeys;
}

private async deleteCacheKeys(invalidatedKeys: string[]) {
await this.pubSub.publish('deleteCacheKeys', invalidatedKeys);
}
}
6 changes: 6 additions & 0 deletions src/services/crons/staking.cache.warmer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ export class StakingCacheWarmerService {
minUnboundEpochs,
divisionSafetyConstant,
state,
boostedYieldsFactors,
apr,
] = await Promise.all([
this.stakingAbi.getAnnualPercentageRewardsRaw(address),
this.stakingAbi.getMinUnbondEpochsRaw(address),
this.stakingAbi.getDivisionSafetyConstantRaw(address),
this.stakingAbi.getStateRaw(address),
this.stakingAbi.getBoostedYieldsFactorsRaw(address),
this.stakeCompute.computeStakeFarmAPR(address),
]);

Expand All @@ -78,6 +80,10 @@ export class StakingCacheWarmerService {
divisionSafetyConstant,
),
this.stakeSetterService.setState(address, state),
this.stakeSetterService.setBoostedYieldsFactors(
address,
boostedYieldsFactors,
),
this.stakeSetterService.setStakeFarmAPR(address, apr),
]);

Expand Down

0 comments on commit d7de8dd

Please sign in to comment.