Skip to content

Commit

Permalink
feat: implemented validator v2
Browse files Browse the repository at this point in the history
  • Loading branch information
tmrdlt committed Apr 18, 2024
1 parent 3ada121 commit 60e9b3e
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 6 deletions.
4 changes: 2 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ model PairLiquidityInfoHistoryError {
}

model PairLiquidityInfoHistoryV2 {
id Int @id @default(autoincrement())
id BigInt @id @default(autoincrement())
pair Pair @relation(fields: [pairId], references: [id])
pairId Int
eventType String
Expand All @@ -99,7 +99,7 @@ model PairLiquidityInfoHistoryV2 {
}

model PairLiquidityInfoHistoryV2Error {
id Int @id @default(autoincrement())
id BigInt @id @default(autoincrement())
pair Pair @relation(fields: [pairId], references: [id])
pairId Int
microBlockHash String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,27 @@ export class PairLiquidityInfoHistoryV2DbService {
],
});
}

getWithinHeightSorted(heightLimit: number) {
return this.prisma.pairLiquidityInfoHistoryV2.findMany({
where: {
height: {
gte: heightLimit,
},
},
orderBy: {
microBlockTime: 'asc',
},
});
}

deleteFromMicroBlockTime(microBlockTime: bigint) {
return this.prisma.pairLiquidityInfoHistoryV2.deleteMany({
where: {
microBlockTime: {
gte: microBlockTime,
},
},
});
}
}
7 changes: 7 additions & 0 deletions src/database/pair/pair-db.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ export class PairDbService {
});
}

get(pairId: number): Promise<PairWithTokens | null> {
return this.prisma.pair.findUnique({
where: { id: pairId },
include: { token0: true, token1: true },
});
}

getOne(address: string) {
return this.prisma.pair.findUnique({
where: { address },
Expand Down
2 changes: 1 addition & 1 deletion src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ export const bigIntToDecimal = (bigInt: bigint): Decimal =>
new Decimal(bigInt.toString());

export const decimalToBigInt = (decimal: Decimal): bigint =>
BigInt(decimal.toString());
BigInt(decimal.toFixed().toString());
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { Injectable, Logger } from '@nestjs/common';

Check warning on line 1 in src/tasks/pair-liquidity-info-history-validator/pair-liquidity-info-history-validator-v2.service.ts

View workflow job for this annotation

GitHub Actions / Lint

Run autofix to sort these imports!
import { groupBy, last, map } from 'lodash';

import { MdwHttpClientService } from '@/clients/mdw-http-client.service';
import {
ContractAddress,
contractAddrToAccountAddr,
} from '@/clients/sdk-client.model';
import { SdkClientService } from '@/clients/sdk-client.service';
import { PairLiquidityInfoHistoryV2DbService } from '@/database/pair-liquidity-info-history/pair-liquidity-info-history-v2-db.service';
import { PairDbService } from '@/database/pair/pair-db.service';
import { decimalToBigInt } from '@/lib/utils';

@Injectable()
export class PairLiquidityInfoHistoryValidatorV2Service {
constructor(
private pairLiquidityInfoHistoryDb: PairLiquidityInfoHistoryV2DbService,
private pairDb: PairDbService,
private mdwClient: MdwHttpClientService,
private sdkClient: SdkClientService,
) {}

readonly logger = new Logger(PairLiquidityInfoHistoryValidatorV2Service.name);

readonly VALIDATION_WINDOW_BLOCKS = 20;

async validate() {
this.logger.log(`Started validating pair liquidity info history.`);

// Get current height
const currentHeight = await this.sdkClient.getHeight();

// Get all liquidity entries greater or equal the current height minus VALIDATION_WINDOW_BLOCKS
// and take the last entry of every microBlock to get the final reserve in that microBlock
const liquidityEntriesWithinHeightSorted = map(
groupBy(
await this.pairLiquidityInfoHistoryDb.getWithinHeightSorted(
currentHeight - this.VALIDATION_WINDOW_BLOCKS,
),
'microBlockHash',
),
(group) => last(group)!,
);

// If the reserves of a local microBlock do not match with the data from the middleware or the block does not exist,
// delete this block and all newer entries
let numDeleted = 0;
for (const liquidityEntry of liquidityEntriesWithinHeightSorted) {
let isError = false;
let mdwReserve0: bigint | undefined;
let mdwReserve1: bigint | undefined;

const pairWithTokens = (await this.pairDb.get(liquidityEntry?.pairId))!;

try {
// reserve0 is the balance of the pair contract's account of token0
mdwReserve0 = BigInt(
(
await this.mdwClient.getAccountBalanceForContractAtMicroBlockHash(
pairWithTokens.token0.address as ContractAddress,
contractAddrToAccountAddr(
pairWithTokens.address as ContractAddress,
),
liquidityEntry.microBlockHash,
)
).amount,
);

// reserve1 is the balance of the pair contract's account of token1
mdwReserve1 = BigInt(
(
await this.mdwClient.getAccountBalanceForContractAtMicroBlockHash(
pairWithTokens.token1.address as ContractAddress,
contractAddrToAccountAddr(
pairWithTokens.address as ContractAddress,
),
liquidityEntry.microBlockHash,
)
).amount,
);
} catch (e) {
this.logger.error(e);
isError = true;
}
if (
isError ||
decimalToBigInt(liquidityEntry.reserve0) !== mdwReserve0 ||
decimalToBigInt(liquidityEntry.reserve1) !== mdwReserve1
) {
numDeleted = (
await this.pairLiquidityInfoHistoryDb.deleteFromMicroBlockTime(
liquidityEntry.microBlockTime,
)
).count;
break;
}
}

if (numDeleted > 0) {
this.logger.log(
`Found an inconsistency in pair liquidity info history. Deleted ${numDeleted} entries.`,
);
} else {
this.logger.log('No problems in pair liquidity info history found.');
}

this.logger.log('Finished validating pair liquidity info history.');
}
}
2 changes: 2 additions & 0 deletions src/tasks/tasks.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DatabaseModule } from '@/database/database.module';
import { PairLiquidityInfoHistoryImporterService } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer.service';
import { PairLiquidityInfoHistoryImporterV2Service } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service';
import { PairLiquidityInfoHistoryValidatorService } from '@/tasks/pair-liquidity-info-history-validator/pair-liquidity-info-history-validator.service';
import { PairLiquidityInfoHistoryValidatorV2Service } from '@/tasks/pair-liquidity-info-history-validator/pair-liquidity-info-history-validator-v2.service';
import { PairSyncService } from '@/tasks/pair-sync/pair-sync.service';
import { TasksService } from '@/tasks/tasks.service';

Expand All @@ -15,6 +16,7 @@ import { TasksService } from '@/tasks/tasks.service';
PairLiquidityInfoHistoryImporterService,
PairLiquidityInfoHistoryImporterV2Service,
PairLiquidityInfoHistoryValidatorService,
PairLiquidityInfoHistoryValidatorV2Service,
TasksService,
PairSyncService,
],
Expand Down
24 changes: 21 additions & 3 deletions src/tasks/tasks.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Cron, CronExpression } from '@nestjs/schedule';
import { PairLiquidityInfoHistoryImporterService } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer.service';
import { PairLiquidityInfoHistoryImporterV2Service } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service';
import { PairLiquidityInfoHistoryValidatorService } from '@/tasks/pair-liquidity-info-history-validator/pair-liquidity-info-history-validator.service';
import { PairLiquidityInfoHistoryValidatorV2Service } from '@/tasks/pair-liquidity-info-history-validator/pair-liquidity-info-history-validator-v2.service';

const EVERY_5_MINUTES_STARTING_AT_02_30 = '30 2-57/5 * * * *';

Expand All @@ -13,6 +14,7 @@ export class TasksService {
private pairLiquidityInfoHistoryImporterService: PairLiquidityInfoHistoryImporterService,
private pairLiquidityInfoHistoryImporterV2Service: PairLiquidityInfoHistoryImporterV2Service,
private pairLiquidityInfoHistoryValidatorService: PairLiquidityInfoHistoryValidatorService,
private pairLiquidityInfoHistoryValidatorV2Service: PairLiquidityInfoHistoryValidatorV2Service,
) {}

private _isRunning = false;
Expand Down Expand Up @@ -57,16 +59,32 @@ export class TasksService {
}
}

// @Cron(EVERY_5_MINUTES_STARTING_AT_02_30)
// async runPairLiquidityInfoHistoryValidator() {
// try {
// if (!this.isRunning) {
// this.setIsRunning(true);
// await this.pairLiquidityInfoHistoryValidatorService.validate();
// this.setIsRunning(false);
// }
// } catch (error) {
// this.pairLiquidityInfoHistoryValidatorService.logger.error(
// `Validation failed. ${error}`,
// );
// this.setIsRunning(false);
// }
// }

@Cron(EVERY_5_MINUTES_STARTING_AT_02_30)
async runPairLiquidityInfoHistoryValidator() {
async runPairLiquidityInfoHistoryValidatorV2() {
try {
if (!this.isRunning) {
this.setIsRunning(true);
await this.pairLiquidityInfoHistoryValidatorService.validate();
await this.pairLiquidityInfoHistoryValidatorV2Service.validate();
this.setIsRunning(false);
}
} catch (error) {
this.pairLiquidityInfoHistoryValidatorService.logger.error(
this.pairLiquidityInfoHistoryValidatorV2Service.logger.error(
`Validation failed. ${error}`,
);
this.setIsRunning(false);
Expand Down

0 comments on commit 60e9b3e

Please sign in to comment.