Skip to content

Commit 8b52137

Browse files
committed
feat: added strict block number for requests, added min rewards for week
1 parent 0cafc40 commit 8b52137

File tree

2 files changed

+84
-64
lines changed

2 files changed

+84
-64
lines changed

src/events/rewards/rewards.service.ts

Lines changed: 71 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export class RewardsService {
6161
}
6262

6363
protected async updateRewards(): Promise<void> {
64-
const rewardsPerFrame = await this.getLastTotalRewardsPerFrame();
64+
const rewardsPerFrame = await this.getMinLastTotalRewardsPerFrame();
6565

6666
if (!rewardsPerFrame) {
6767
return;
@@ -72,15 +72,11 @@ export class RewardsService {
7272
this.rewardsStorage.setElRewardsPerFrame(rewardsPerFrame.elRewards);
7373
}
7474

75-
public async getLastTotalRewardsPerFrame(): Promise<{
76-
clRewards: BigNumber;
77-
elRewards: BigNumber;
78-
allRewards: BigNumber;
79-
} | null> {
80-
const framesFromLastReport = await this.getFramesFromLastReport();
81-
if (framesFromLastReport === null) {
75+
public async getMinLastTotalRewardsPerFrame() {
76+
const framesFromLastReports = await this.getFramesFromLastReports();
77+
if (framesFromLastReports === null) {
8278
this.logger.warn(
83-
'last rewards was not updated because last TokenRebase events were not found during last 48 hours.',
79+
'last reward reports were not found because last TokenRebase events were not found during last week.',
8480
{ service: RewardsService.SERVICE_LOG_NAME },
8581
);
8682
return {
@@ -90,41 +86,57 @@ export class RewardsService {
9086
};
9187
}
9288

93-
const { blockNumber, frames } = framesFromLastReport;
89+
const rewards = await Promise.all(
90+
framesFromLastReports.map(async ({ blockNumber, frames }) => {
91+
const { clRewards, elRewards } = await this.getRewardsByBlockNumber(blockNumber, frames);
9492

95-
if (frames.eq(0)) {
96-
this.logger.warn('last rewards set to 0 because frames passed from last event is 0.', {
97-
service: RewardsService.SERVICE_LOG_NAME,
98-
});
99-
return {
100-
clRewards: BigNumber.from(0),
101-
elRewards: BigNumber.from(0),
102-
allRewards: BigNumber.from(0),
103-
};
104-
}
93+
return {
94+
clRewards: clRewards,
95+
elRewards: elRewards,
96+
};
97+
}),
98+
);
10599

106-
const { preCLBalance, postCLBalance } = await this.getEthDistributed(blockNumber);
107-
const elRewards = (await this.getElRewards(blockNumber)) ?? BigNumber.from(0);
108-
const withdrawalsReceived = (await this.getWithdrawalsReceived(blockNumber)) ?? BigNumber.from(0);
100+
let minCL = rewards[0].clRewards;
101+
let minEL = rewards[0].elRewards;
109102

110-
const clValidatorsBalanceDiff = postCLBalance.sub(preCLBalance);
111-
const clRewards = clValidatorsBalanceDiff.add(withdrawalsReceived);
103+
rewards.forEach((r) => {
104+
if (minCL.lt(r.clRewards)) {
105+
minCL = r.clRewards;
106+
}
107+
108+
if (minEL.lt(r.elRewards)) {
109+
minEL = r.elRewards;
110+
}
111+
});
112+
113+
const allRewards = minEL.add(minEL);
112114

113-
const allRewards = clRewards.add(elRewards).div(frames);
114115
this.logger.log(`rewardsPerFrame are updated to ${allRewards.toString()}`, {
115116
service: RewardsService.SERVICE_LOG_NAME,
116117
});
117118

118119
return {
119-
clRewards: clRewards.div(frames),
120-
elRewards: elRewards.div(frames),
120+
clRewards: minCL,
121+
elRewards: minEL,
121122
allRewards,
122123
};
123124
}
124125

125-
protected async get48HoursAgoBlock() {
126+
protected async getRewardsByBlockNumber(blockNumber: number, framesPassed: BigNumber) {
127+
const { preCLBalance, postCLBalance } = await this.getEthDistributed(blockNumber);
128+
const elRewards = (await this.getElRewards(blockNumber)) ?? BigNumber.from(0);
129+
const withdrawalsReceived = (await this.getWithdrawalsReceived(blockNumber)) ?? BigNumber.from(0);
130+
131+
const clValidatorsBalanceDiff = postCLBalance.sub(preCLBalance);
132+
const clRewards = clValidatorsBalanceDiff.add(withdrawalsReceived);
133+
134+
return { clRewards: clRewards.div(framesPassed), elRewards: elRewards.div(framesPassed) };
135+
}
136+
137+
protected async getHoursAgoBlock(hours: number) {
126138
const currentBlock = await this.provider.getBlockNumber();
127-
return currentBlock - Math.ceil((2 * 24 * 60 * 60) / SECONDS_PER_SLOT);
139+
return currentBlock - Math.ceil((hours * 60 * 60) / SECONDS_PER_SLOT);
128140
}
129141

130142
protected async getElRewards(fromBlock: number): Promise<BigNumber> {
@@ -135,7 +147,7 @@ export class RewardsService {
135147
fromBlock,
136148
address: res.address,
137149
});
138-
const lastLog = logs[logs.length - 1];
150+
const lastLog = logs[0];
139151

140152
if (!lastLog) {
141153
return BigNumber.from(0);
@@ -166,7 +178,7 @@ export class RewardsService {
166178

167179
this.logger.log('ETHDistributed event logs', { service: RewardsService.SERVICE_LOG_NAME, logsCount: logs.length });
168180

169-
const lastLog = logs[logs.length - 1];
181+
const lastLog = logs[0];
170182

171183
if (!lastLog) {
172184
this.logger.warn('ETHDistributed event is not found for CL balance.', {
@@ -215,7 +227,7 @@ export class RewardsService {
215227
logsCount: logs.length,
216228
});
217229

218-
const lastLog = logs[logs.length - 1];
230+
const lastLog = logs[0];
219231
if (!lastLog) {
220232
return BigNumber.from(0);
221233
}
@@ -233,11 +245,8 @@ export class RewardsService {
233245
}
234246

235247
// reports can be skipped, so we need timeElapsed (time from last report)
236-
protected async getFramesFromLastReport(): Promise<{
237-
blockNumber: number;
238-
frames: BigNumber;
239-
} | null> {
240-
const last48HoursAgoBlock = await this.get48HoursAgoBlock();
248+
protected async getFramesFromLastReports() {
249+
const weekAgoBlock = await this.getHoursAgoBlock(24 * 7);
241250

242251
const res = this.contractLido.filters.TokenRebased();
243252

@@ -246,51 +255,55 @@ export class RewardsService {
246255
{
247256
topics: res.topics,
248257
toBlock: 'latest',
249-
fromBlock: last48HoursAgoBlock,
258+
fromBlock: weekAgoBlock,
250259
address: res.address,
251260
},
252261
this.logger,
253262
'TokenRebased',
254263
);
255264

256-
this.logger.log('TokenRebase event logs for last 48 hours', {
265+
this.logger.log('TokenRebase event logs for last week', {
257266
service: RewardsService.SERVICE_LOG_NAME,
258267
logsCount: logs.length,
259268
});
260269

261270
if (logs.length === 0) {
262-
this.logger.warn('TokenRebase events are not found for last 48 hours.', {
271+
this.logger.warn('TokenRebase events are not found for last week.', {
263272
service: RewardsService.SERVICE_LOG_NAME,
264273
});
265274

266275
return null;
267276
}
268277

269-
const lastLog = logs[logs.length - 1];
270-
const parser = new Interface([LIDO_TOKEN_REBASED_EVENT]);
271-
const parsedData = parser.parseLog(lastLog);
278+
const rewardsBlocks = logs.map((log) => {
279+
const parser = new Interface([LIDO_TOKEN_REBASED_EVENT]);
280+
const parsedData = parser.parseLog(log);
272281

273-
this.logger.log('last TokenRebase event for last 48 hours', {
282+
return {
283+
blockNumber: log.blockNumber,
284+
frames: BigNumber.from(parsedData.args.getValue('timeElapsed')).div(
285+
SECONDS_PER_SLOT * SLOTS_PER_EPOCH * this.contractConfig.getEpochsPerFrame(),
286+
),
287+
};
288+
});
289+
290+
this.logger.log('last TokenRebase events for last week', {
274291
service: RewardsService.SERVICE_LOG_NAME,
275-
args: parsedData.args,
276-
timeElapsed: parsedData.args.getValue('timeElapsed'),
277-
blockNumber: lastLog.blockNumber,
292+
rewardsBlocks,
278293
});
279294

280-
return {
281-
blockNumber: lastLog.blockNumber,
282-
frames: BigNumber.from(parsedData.args.getValue('timeElapsed')).div(
283-
SECONDS_PER_SLOT * SLOTS_PER_EPOCH * this.contractConfig.getEpochsPerFrame(),
284-
),
285-
};
295+
return rewardsBlocks;
286296
}
287297

288298
// it includes WithdrawalVault balance and diff between rewards and cached rewards from previous report
289-
async getVaultsBalance() {
299+
async getVaultsBalance(blockNumber: number) {
290300
const chainId = this.configService.get('CHAIN_ID');
291-
const withdrawalVaultAddress = await this.lidoLocator.withdrawalVault();
292-
const withdrawalVaultBalance = await this.provider.getBalance(withdrawalVaultAddress);
293-
const rewardsVaultBalance = await this.provider.getBalance(EXECUTION_REWARDS_VAULT_CONTRACT_ADDRESSES[chainId]);
301+
const withdrawalVaultAddress = await this.lidoLocator.withdrawalVault({ blockTag: blockNumber });
302+
const withdrawalVaultBalance = await this.provider.getBalance(withdrawalVaultAddress, blockNumber);
303+
const rewardsVaultBalance = await this.provider.getBalance(
304+
EXECUTION_REWARDS_VAULT_CONTRACT_ADDRESSES[chainId],
305+
blockNumber,
306+
);
294307
const elRewards = this.rewardsStorage.getElRewardsPerFrame();
295308
const clRewards = this.rewardsStorage.getClRewardsPerFrame();
296309

src/waiting-time/waiting-time.service.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
GetWaitingTimeInfoV2Args,
3939
GetWaitingTimeInfoV2Result,
4040
} from './waiting-time.types';
41+
import { SimpleFallbackJsonRpcBatchProvider } from '@lido-nestjs/execution';
4142

4243
@Injectable()
4344
export class WaitingTimeService {
@@ -51,6 +52,7 @@ export class WaitingTimeService {
5152
protected readonly genesisTimeService: GenesisTimeService,
5253
protected readonly rewardsService: RewardsService,
5354
protected readonly queueInfo: QueueInfoStorageService,
55+
protected readonly provider: SimpleFallbackJsonRpcBatchProvider,
5456
) {}
5557

5658
// preparing all needed number for calculation withdrawal time
@@ -60,12 +62,14 @@ export class WaitingTimeService {
6062
// nextCalculationAt not needed anymore due to runtime queries to contract
6163
const nextCalculationAt = this.queueInfo.getNextUpdate().toISOString();
6264
const validatorsLastUpdate = this.validators.getLastUpdate();
65+
const block = await this.provider.getBlock('safe');
66+
const blockNumber = block.number;
6367

6468
const [unfinalized, buffer, vaultsBalance] = !cached
6569
? await Promise.all([
66-
this.contractWithdrawal.unfinalizedStETH(),
67-
this.contractLido.getBufferedEther(),
68-
this.rewardsService.getVaultsBalance(),
70+
this.contractWithdrawal.unfinalizedStETH({ blockTag: blockNumber }),
71+
this.contractLido.getBufferedEther({ blockTag: blockNumber }),
72+
this.rewardsService.getVaultsBalance(blockNumber),
6973
])
7074
: [cached.unfinalized, cached.buffer, cached.vaultsBalance];
7175

@@ -296,10 +300,13 @@ export class WaitingTimeService {
296300
}
297301

298302
public async calculateRequestsTime(ids: string[]) {
303+
const block = await this.provider.getBlock('safe');
304+
const blockNumber = block.number;
305+
299306
const [unfinalized, buffer, vaultsBalance] = await Promise.all([
300-
this.contractWithdrawal.unfinalizedStETH(),
301-
this.contractLido.getBufferedEther(),
302-
this.rewardsService.getVaultsBalance(),
307+
this.contractWithdrawal.unfinalizedStETH({ blockTag: blockNumber }),
308+
this.contractLido.getBufferedEther({ blockTag: blockNumber }),
309+
this.rewardsService.getVaultsBalance(blockNumber),
303310
]);
304311

305312
return Promise.all(

0 commit comments

Comments
 (0)