Skip to content

Commit 84140d5

Browse files
committed
feat: added validators info endpoint
fix: fixed cache refill ether parsing, fixed validators balances case
1 parent c50af3e commit 84140d5

File tree

10 files changed

+111
-8
lines changed

10 files changed

+111
-8
lines changed

src/http/http.constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export const HTTP_PATHS = {
22
1: {
33
nft: 'nft',
4+
validators: 'validators',
45
'request-time': 'request-time',
56
'estimate-gas': 'estimate-gas',
67
},

src/http/http.module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ import { CacheModule, CacheControlHeadersInterceptor } from './common/cache';
1212
import { RequestTimeModule } from './request-time';
1313
import { NFTModule } from './nft';
1414
import { EstimateModule } from './estimate';
15+
import { ValidatorsModule } from './validators';
1516

1617
@Module({
17-
imports: [RequestTimeModule, NFTModule, EstimateModule, CacheModule, ThrottlerModule],
18+
imports: [RequestTimeModule, NFTModule, EstimateModule, ValidatorsModule, CacheModule, ThrottlerModule],
1819
providers: [
1920
{ provide: APP_GUARD, useClass: ThrottlerBehindProxyGuard },
2021
{ provide: APP_INTERCEPTOR, useClass: CacheControlHeadersInterceptor },

src/http/validators/dto/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './validators.dto';
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
3+
export class ValidatorsDto {
4+
@ApiProperty({
5+
example: 1658650005,
6+
description: 'ms time when data was last updated at',
7+
})
8+
lastUpdatedAt: number;
9+
10+
@ApiProperty({
11+
example: 1724856617,
12+
description: 'max exit epoch over all CL network',
13+
})
14+
maxExitEpoch: number;
15+
16+
@ApiProperty({
17+
example: '{}',
18+
description: 'sum of balances Lido validators with withdrawable_epoch by frame',
19+
})
20+
frameBalances: Record<string, string>;
21+
22+
@ApiProperty({
23+
example: 100000,
24+
description: 'total number of validators in network',
25+
})
26+
totalValidators: number;
27+
}

src/http/validators/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './validators.controller';
2+
export * from './validators.module';
3+
export * from './validators.service';
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {
2+
ClassSerializerInterceptor,
3+
Controller,
4+
Get,
5+
HttpStatus,
6+
UseInterceptors,
7+
Version,
8+
CacheTTL,
9+
} from '@nestjs/common';
10+
import { ApiResponse, ApiTags } from '@nestjs/swagger';
11+
import { HTTP_PATHS } from 'http/http.constants';
12+
import { ValidatorsService } from './validators.service';
13+
import { ValidatorsDto } from './dto';
14+
15+
@Controller(HTTP_PATHS[1].validators)
16+
@ApiTags('Validators')
17+
@UseInterceptors(ClassSerializerInterceptor)
18+
export class ValidatorsController {
19+
constructor(protected readonly validatorsService: ValidatorsService) {}
20+
21+
@Version('1')
22+
@Get('/')
23+
@CacheTTL(20 * 1000)
24+
@ApiResponse({ status: HttpStatus.OK, type: ValidatorsDto })
25+
async validatorsV1(): Promise<ValidatorsDto> {
26+
return this.validatorsService.getAllValidatorsInfo();
27+
}
28+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Module } from '@nestjs/common';
2+
import { ConfigModule } from 'common/config';
3+
import { ValidatorsController } from './validators.controller';
4+
import { ValidatorsService } from './validators.service';
5+
import { ValidatorsStorageModule } from '../../storage';
6+
7+
@Module({
8+
imports: [ConfigModule, ValidatorsStorageModule],
9+
controllers: [ValidatorsController],
10+
providers: [ValidatorsService],
11+
})
12+
export class ValidatorsModule {}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { ConfigService } from 'common/config';
3+
import { ValidatorsStorageService } from '../../storage';
4+
5+
@Injectable()
6+
export class ValidatorsService {
7+
constructor(
8+
protected readonly configService: ConfigService,
9+
protected readonly validatorsServiceStorage: ValidatorsStorageService,
10+
) {}
11+
12+
getAllValidatorsInfo() {
13+
const lastUpdatedAt = this.validatorsServiceStorage.getLastUpdate();
14+
const maxExitEpoch = Number(this.validatorsServiceStorage.getMaxExitEpoch());
15+
const frameBalancesBigNumber = this.validatorsServiceStorage.getFrameBalances();
16+
const totalValidators = this.validatorsServiceStorage.getTotal();
17+
18+
const frameBalances = Object.keys(frameBalancesBigNumber).reduce((acc, item) => {
19+
acc[item] = frameBalancesBigNumber[item].toString();
20+
return acc;
21+
}, {} as Record<string, string>);
22+
23+
return {
24+
lastUpdatedAt,
25+
maxExitEpoch,
26+
frameBalances,
27+
totalValidators,
28+
};
29+
}
30+
}

src/storage/validators/validators-cache.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import * as path from 'path';
44
import { LOGGER_PROVIDER, LoggerService } from '../../common/logger';
55
import { ValidatorsStorageService } from './validators.service';
66
import { BigNumber } from '@ethersproject/bignumber';
7-
import { parseEther } from '@ethersproject/units';
87

98
@Injectable()
109
export class ValidatorsCacheService {
@@ -97,7 +96,7 @@ export class ValidatorsCacheService {
9796
protected parseFrameBalances(frameBalancesStr: string) {
9897
const frameBalances = JSON.parse(frameBalancesStr);
9998
return Object.keys(frameBalances).reduce((acc, key) => {
100-
return { ...acc, [key]: parseEther(frameBalances[key]) };
99+
return { ...acc, [key]: BigNumber.from(frameBalances[key]) };
101100
}, {});
102101
}
103102
}

src/waiting-time/utils/calculate-frame-by-validator-balances.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const calculateFrameByValidatorBalances = (args: calculateFrameByValidato
1717
let lastFrame = BigNumber.from(currentFrame);
1818

1919
const frames = Object.keys(frameBalances);
20-
let result = null;
20+
let result: BigNumber = null;
2121

2222
for (let i = 0; i < frames.length; i++) {
2323
const frame = frames[i];
@@ -43,8 +43,9 @@ export const calculateFrameByValidatorBalances = (args: calculateFrameByValidato
4343
const sweepingMean = calculateSweepingMean(totalValidators).toNumber();
4444
const framesOfSweepingMean = Math.ceil(sweepingMean / epochPerFrame);
4545

46-
const resultFrame = result.add(framesOfSweepingMean).toNumber();
47-
48-
// If withdrawable_epoch is less than current frame, should return next frame
49-
return resultFrame < currentFrame ? currentFrame + 1 : resultFrame;
46+
// todo: return back previous version of calculation after rework sweeping mean
47+
// If resulted withdrawable_epoch is less than current frame, should return next frame
48+
result = result.lt(currentFrame) ? BigNumber.from(currentFrame) : result;
49+
const resultWithSweep = result.add(framesOfSweepingMean).toNumber();
50+
return resultWithSweep;
5051
};

0 commit comments

Comments
 (0)