Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | 42x 42x 42x 42x 42x 42x 524x 131x 42x 42x 127x 128x 127x 127x 1x 1x 42x 126x 127x 127x 6x 126x 132x 132x 1x 1x 131x 131x 131x | import { BigIntMath } from '@cardano-sdk/util'; import { Cardano, Reward } from '@cardano-sdk/core'; import { KeyValueStore } from '../../persistence'; import { Logger } from 'ts-log'; import { Observable, concat, map, of, switchMap, tap } from 'rxjs'; import { RetryBackoffConfig } from 'backoff-rxjs'; import { RewardsHistory } from '../types'; import { TrackedRewardsProvider } from '../ProviderTracker'; import { pollProvider } from '../util'; import flatten from 'lodash/flatten.js'; import sortBy from 'lodash/sortBy.js'; const sumRewards = (arrayOfRewards: Reward[]) => BigIntMath.sum(arrayOfRewards.map(({ rewards }) => rewards)); const avgReward = (arrayOfRewards: Reward[]) => sumRewards(arrayOfRewards) / BigInt(arrayOfRewards.length); export const createRewardsHistoryProvider = (rewardsProvider: TrackedRewardsProvider, retryBackoffConfig: RetryBackoffConfig) => ( rewardAccounts: Cardano.RewardAccount[], lowerBound: Cardano.EpochNo | null, epoch$: Observable<Cardano.EpochNo>, logger: Logger ): Observable<Map<Cardano.RewardAccount, Reward[]>> => { if (lowerBound) { return pollProvider({ logger, retryBackoffConfig, sample: () => rewardsProvider.rewardsHistory({ epochs: { lowerBound }, rewardAccounts }), trigger$: epoch$ }); } rewardsProvider.setStatInitialized(rewardsProvider.stats.rewardsHistory$); return of(new Map()); }; export type RewardsHistoryProvider = ReturnType<typeof createRewardsHistoryProvider>; export const createRewardsHistoryTracker = ( rewardAccounts$: Observable<Cardano.RewardAccount[]>, epoch$: Observable<Cardano.EpochNo>, rewardsHistoryProvider: RewardsHistoryProvider, rewardsHistoryStore: KeyValueStore<Cardano.RewardAccount, Reward[]>, logger: Logger ): Observable<RewardsHistory> => rewardAccounts$ .pipe( tap((rewardsAccounts) => logger.debug(`Fetching rewards for ${rewardsAccounts.length} accounts`)), switchMap((rewardAccounts) => concat( rewardsHistoryStore .getValues(rewardAccounts) .pipe(map((rewards) => new Map(rewardAccounts.map((rewardAccount, i) => [rewardAccount, rewards[i]])))), // this could be optimized to fetch rewards > last local reward within stability window rewardsHistoryProvider(rewardAccounts, Cardano.EpochNo(1), epoch$, logger).pipe( tap((allRewards) => rewardsHistoryStore.setAll([...allRewards.entries()].map(([key, value]) => ({ key, value }))) ) ) ) ) ) .pipe( map((rewardsByAccount) => { const all = sortBy(flatten([...rewardsByAccount.values()]), 'epoch'); if (all.length === 0) { logger.debug('No rewards found'); return { all: [], avgReward: null, lastReward: null, lifetimeRewards: 0n } as RewardsHistory; } const rewardsHistory: RewardsHistory = { all, avgReward: avgReward(all), lastReward: all[all.length - 1], lifetimeRewards: sumRewards(all) }; logger.debug( `Rewards between epochs ${rewardsHistory.all[0].epoch} and ${ rewardsHistory.all[rewardsHistory.all.length - 1].epoch }`, `average:${rewardsHistory.avgReward}`, `lastRewards:${rewardsHistory.lastReward}`, `lifetimeRewards:${rewardsHistory.lifetimeRewards}` ); return rewardsHistory; }) ); |