@marinade.finance/scoring 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/computing/cluster.ts +102 -0
  2. package/computing/eligibility.ts +163 -0
  3. package/computing/score.ts +164 -0
  4. package/computing/stake.ts +246 -0
  5. package/computing/validators.ts +133 -0
  6. package/{src/dto → dto}/bonds.dto.ts +0 -2
  7. package/{src/dto → dto}/cluster.dto.ts +0 -1
  8. package/{src/dto → dto}/eligibility.dto.ts +0 -5
  9. package/{src/dto → dto}/jito.dto.ts +1 -2
  10. package/{src/dto → dto}/marinade.dto.ts +1 -1
  11. package/{src/dto → dto}/rewards.dto.ts +1 -3
  12. package/{src/dto → dto}/scoring.dto.ts +1 -7
  13. package/{src/dto → dto}/snapshots.dto.ts +0 -3
  14. package/{src/dto → dto}/stakes.dto.ts +0 -4
  15. package/{src/dto → dto}/validators.dto.ts +1 -37
  16. package/package.json +17 -13
  17. package/{src/providers → providers}/api-data.provider.ts +58 -58
  18. package/{src/providers → providers}/file-data.provider.ts +7 -15
  19. package/{src/utils → utils}/csv.ts +3 -3
  20. package/src/cluster/cluster.module.ts +0 -8
  21. package/src/cluster/cluster.service.ts +0 -108
  22. package/src/config/config.module.ts +0 -8
  23. package/src/config/config.service.ts +0 -136
  24. package/src/eligibility/eligibility.module.ts +0 -11
  25. package/src/eligibility/eligibility.service.ts +0 -183
  26. package/src/scoring/scoring.module.ts +0 -11
  27. package/src/scoring/scoring.service.ts +0 -184
  28. package/src/stake/stake.module.ts +0 -10
  29. package/src/stake/stake.service.ts +0 -242
  30. package/src/validators/validators.module.ts +0 -48
  31. package/src/validators/validators.service.ts +0 -177
  32. /package/{src/constants → constants}/marinade.json +0 -0
  33. /package/{src/errors → errors}/fetching.ts +0 -0
  34. /package/{src/interfaces → interfaces}/data-provider.interface.ts +0 -0
  35. /package/{src/utils → utils}/maths.ts +0 -0
  36. /package/{src/utils → utils}/solana.ts +0 -0
  37. /package/{src/utils → utils}/zip.ts +0 -0
@@ -1,177 +0,0 @@
1
- import { AggregatedValidator, AggregatedValidators, ValidatorDto } from '../dto/validators.dto';
2
- import { IDataProvider } from '../interfaces/data-provider.interface';
3
- import { JitoValidatorDto } from '../dto/jito.dto';
4
- import { Inject } from '@nestjs/common';
5
- import { mean, sum } from '../utils/maths';
6
- import { ClusterInfo } from '../dto/cluster.dto';
7
- import { Votes } from '../dto/snapshots.dto';
8
- import { Bonds } from '../dto/bonds.dto';
9
- import { Rewards } from '../dto/rewards.dto';
10
- import { TvlStats } from '../dto/marinade.dto';
11
-
12
- export class ValidatorsService {
13
- constructor (@Inject('IDataProvider') private dataProvider: IDataProvider) { }
14
-
15
- aggregateValidatorData (
16
- validator: ValidatorDto,
17
- mevRecord: JitoValidatorDto,
18
- blacklist: Set<string>,
19
- firstEpoch: number,
20
- lastEpoch: number
21
- ): AggregatedValidator {
22
- const currentMarinadeStake = Number(validator.epochStats[lastEpoch]?.marinade_native_stake || 0) / 1e9 + Number(validator.epochStats[lastEpoch]?.marinade_stake || 0) / 1e9;
23
- const voteAccount = validator.vote_account;
24
- const name = validator.info_name || 'Unknown';
25
- const epochs: number[] = [];
26
- const commission: number[] = [];
27
- const stake: number[] = [];
28
- const externalStake: number[] = [];
29
- const credits: number[] = [];
30
- const blocksProduced: number[] = [];
31
- const leaderSlots: number[] = [];
32
- const dataAvailable: boolean[] = [];
33
-
34
- const currentStake = Number(validator.epochStats[lastEpoch]?.activated_stake || 0) / 1e9;
35
-
36
- const blacklisted = blacklist.has(voteAccount);
37
-
38
- for (let epoch = lastEpoch; epoch >= firstEpoch; epoch--) {
39
- const epochStat = validator.epochStats?.[epoch];
40
-
41
- epochs.push(epoch);
42
- commission.push(epochStat?.commission_max_observed || epochStat?.commission_advertised || 0);
43
- stake.push(Number(epochStat?.activated_stake || 0) / 1e9);
44
- externalStake.push(Number(epochStat?.activated_stake || 0) / 1e9 - Number(epochStat?.marinade_stake || 0) / 1e9 - Number(epochStat?.marinade_native_stake || 0) / 1e9);
45
- credits.push(epochStat?.credits || 0);
46
- blocksProduced.push(epochStat?.blocks_produced || 0);
47
- leaderSlots.push(epochStat?.leader_slots || 0);
48
- dataAvailable.push(!!epochStat);
49
- }
50
-
51
- const mevCommission = mevRecord?.running_jito ? mevRecord.mev_commission_bps / 100 : 100;
52
- return {
53
- voteAccount,
54
- name,
55
- epochs,
56
- currentMarinadeStake,
57
- currentStake,
58
- commission,
59
- stake,
60
- externalStake,
61
- credits,
62
- blocksProduced,
63
- leaderSlots,
64
- dataAvailable,
65
- mevCommission,
66
- country: validator.dc_country || 'Unknown',
67
- city: validator.dc_full_city || 'Unknown',
68
- aso: validator.dc_aso || 'Unknown',
69
- blacklisted,
70
- version: validator.version
71
- };
72
- }
73
-
74
- async fetchTvlStats (withSnapshot: boolean): Promise<TvlStats> {
75
- return await this.dataProvider.fetchTvl(withSnapshot);
76
- }
77
-
78
- async fetchValidators (epochsToFetch: number, withSnapshot: boolean): Promise<ValidatorDto[]> {
79
- return this.dataProvider.fetchValidators(epochsToFetch, withSnapshot);
80
- }
81
-
82
- async fetchMsolVotes (withSnapshot: boolean): Promise<Votes> {
83
- return await this.dataProvider.fetchMSolVotes(withSnapshot);
84
- }
85
-
86
- async fetchRewards (epochs:number, withSnapshot: boolean): Promise<Rewards> {
87
- return await this.dataProvider.fetchRewards(epochs, withSnapshot);
88
- }
89
-
90
- async fetchVeMndeVotes (withSnapshot: boolean): Promise<Votes> {
91
- return await this.dataProvider.fetchVeMndeVotes(withSnapshot);
92
- }
93
-
94
- async fetchBonds (withSnapshot: boolean): Promise<Bonds> {
95
- return this.dataProvider.fetchBonds(withSnapshot);
96
- }
97
-
98
- async aggregateValidatorsData (
99
- validators: ValidatorDto[],
100
- basicEligibilityEpochs: number,
101
- bonusEligibilityExtraEpochs: number
102
- ): Promise<AggregatedValidators> {
103
- const lastEpoch = this.getMaxEpoch(validators);
104
- const firstEpoch = lastEpoch - basicEligibilityEpochs - bonusEligibilityExtraEpochs;
105
-
106
- const jitoMevRecords: Record<string, JitoValidatorDto> = await this.dataProvider.fetchValidatorsJitoMEV(true);
107
- const blacklist: Set<string> = await this.dataProvider.fetchBlacklist(true);
108
-
109
- const result: { [voteAccount: string]: AggregatedValidator } = {};
110
-
111
- for (const validator of validators) {
112
- const mevRecord = jitoMevRecords[validator.vote_account] ?? {
113
- vote_account: validator.vote_account,
114
- mev_commission_bps: 100,
115
- running_jito: false,
116
- active_stake: Number(validator.activated_stake)
117
- } as JitoValidatorDto;
118
-
119
- if (mevRecord) {
120
- const aggregatedData = this.aggregateValidatorData(validator, mevRecord, blacklist, firstEpoch, lastEpoch);
121
- result[validator.vote_account] = aggregatedData;
122
- }
123
- }
124
-
125
- return result;
126
- }
127
-
128
- getMaxEpoch (validators: ValidatorDto[]): number {
129
- return validators.reduce((maxEpoch, validator) => {
130
- const validatorMaxEpoch = validator.epoch_stats.reduce((max, { epoch }) => {
131
- return Math.max(epoch, max);
132
- }, 0);
133
- return Math.max(maxEpoch, validatorMaxEpoch);
134
- }, 0);
135
- }
136
-
137
- selectExternalStakeMin (validator: AggregatedValidator, fullEpochs: number): number {
138
- if (validator.externalStake.length === 0) {
139
- throw new Error('Validator has no external stake data.');
140
- }
141
- return Math.min(...validator.externalStake.slice(0, fullEpochs + 1));
142
- }
143
-
144
- selectCreditsPctMean (validator: AggregatedValidator, clusterInfo: ClusterInfo, fullEpochs: number): number {
145
- return mean(validator.epochs.slice(1, fullEpochs + 1).map((epoch, fullEpochIndex) =>
146
- (validator.credits[fullEpochIndex + 1] ?? 0) / (clusterInfo.targetCreditsByEpoch.get(epoch) ?? 1)));
147
- }
148
-
149
- selectBlockProductionMean (validator: AggregatedValidator, fullEpochs: number): number {
150
- const leaderSlots = sum(validator.leaderSlots.slice(1, fullEpochs + 1));
151
- return leaderSlots === 0 ? 1 : sum(validator.blocksProduced.slice(1, fullEpochs + 1)) / leaderSlots;
152
- }
153
-
154
- selectCommissonInflationMax (validator: AggregatedValidator, epochs: number): number {
155
- return Math.max(...validator.commission.slice(0, epochs));
156
- }
157
-
158
- selectCommissonMEV (validator: AggregatedValidator): number {
159
- return validator.mevCommission;
160
- }
161
-
162
- selectCountryStakeConcentration (validator: AggregatedValidator, clusterInfo: ClusterInfo): number {
163
- return clusterInfo.country.get(validator.country ?? '???') ?? 0;
164
- }
165
-
166
- selectCityStakeConcentration (validator: AggregatedValidator, clusterInfo: ClusterInfo): number {
167
- return clusterInfo.city.get(validator.city ?? '???') ?? 0;
168
- }
169
-
170
- selectASOStakeConcentration (validator: AggregatedValidator, clusterInfo: ClusterInfo): number {
171
- return clusterInfo.aso.get(validator.aso ?? '???') ?? 0;
172
- }
173
-
174
- selectNodeStake (validator: AggregatedValidator): number {
175
- return validator.stake[0] ?? 0;
176
- }
177
- }
File without changes
File without changes
File without changes
File without changes
File without changes