diff --git a/apollo/prisma/schema.prisma b/apollo/prisma/schema.prisma index aeaaaaa2..50ac6ef5 100644 --- a/apollo/prisma/schema.prisma +++ b/apollo/prisma/schema.prisma @@ -46,17 +46,6 @@ model HistoryRecord { extData String? } -model DailyStatistics { - fromChain String - toChain String - bridge String - timestamp Int - token String - dailyVolume BigInt? - dailyCount BigInt? - @@unique([fromChain, toChain, bridge, timestamp, token], name: "daily_statistics_id") -} - model LnBridgeRelayInfo { id String @id version String diff --git a/apollo/src/account/account.graphql b/apollo/src/account/account.graphql deleted file mode 100644 index d39f8327..00000000 --- a/apollo/src/account/account.graphql +++ /dev/null @@ -1,7 +0,0 @@ -type Accounts { - total: Int! -} - -type Query { - accounts(chain: String): Accounts -} diff --git a/apollo/src/account/account.module.ts b/apollo/src/account/account.module.ts deleted file mode 100644 index 35405419..00000000 --- a/apollo/src/account/account.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Module } from '@nestjs/common'; -import { AccountResolver } from './account.resolver'; -import { AccountService } from './account.service'; - -@Module({ - providers: [AccountResolver, AccountService], - exports: [AccountService], -}) -export class AccountModule {} diff --git a/apollo/src/account/account.resolver.spec.ts b/apollo/src/account/account.resolver.spec.ts deleted file mode 100644 index f9f2b84b..00000000 --- a/apollo/src/account/account.resolver.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ConfigModule } from '@nestjs/config'; -import { Test, TestingModule } from '@nestjs/testing'; -import { AccountResolver } from './account.resolver'; -import { AccountService } from './account.service'; - -describe('AccountResolver', () => { - let resolver: AccountResolver; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [ConfigModule], - providers: [AccountResolver, AccountService], - }).compile(); - - resolver = module.get(AccountResolver); - }); - - it('should be defined', () => { - expect(resolver).toBeDefined(); - }); -}); diff --git a/apollo/src/account/account.resolver.ts b/apollo/src/account/account.resolver.ts deleted file mode 100644 index 025b9f97..00000000 --- a/apollo/src/account/account.resolver.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Args, Query, Resolver } from '@nestjs/graphql'; -import { AccountService } from './account.service'; - -@Resolver('accounts') -export class AccountResolver { - constructor(private accountService: AccountService) {} - - @Query() - async accounts(@Args('chain') chain: string) { - return this.accountService.getAccounts(chain); - } -} diff --git a/apollo/src/account/account.service.spec.ts b/apollo/src/account/account.service.spec.ts deleted file mode 100644 index 86786642..00000000 --- a/apollo/src/account/account.service.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ConfigModule } from '@nestjs/config'; -import { Test, TestingModule } from '@nestjs/testing'; -import { AccountService } from './account.service'; - -describe('AccountService', () => { - let service: AccountService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [ConfigModule], - providers: [AccountService], - }).compile(); - - service = module.get(AccountService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/apollo/src/account/account.service.ts b/apollo/src/account/account.service.ts deleted file mode 100644 index dcbb666c..00000000 --- a/apollo/src/account/account.service.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import axios from 'axios'; -import { Accounts } from '../graphql'; - -@Injectable() -export class AccountService { - private readonly subql = this.configService.get('SUBQL'); - private readonly subqlX = this.configService.get('SUBQL_X'); - private readonly subqlS = this.configService.get('SUBQL_S'); - - dispatchEndPoints = { - pangolin: this.subqlX + 'pchain', - 'pangolin-parachain': this.subqlX + 'ppchain', - pangoro: this.subqlS + 'pochain', - crab: this.subql + 'crab', - 'crab-parachain': this.subql + 'cpchain', - darwinia: this.subql + 'darwinia', - }; - - constructor(private configService: ConfigService) {} - - async getAccounts(chain?: string): Promise { - const query = (chain: string) => - axios.post(this.subql + chain, { - query: `query { accounts { totalCount } }`, - variables: null, - }); - - if (chain) { - const res = await query(chain); - - return { total: res.data.data.accounts.totalCount }; - } else { - const chains = - this.configService.get('CHAIN_TYPE') === 'test' - ? ['pangoro', 'pangolin'] - : ['darwinia', 'crab']; - const results = await Promise.all(chains.map((chain) => query(chain))); - - return { total: results.reduce((acc, cur) => acc + cur.data.data.accounts.totalCount, 0) }; - } - } -} diff --git a/apollo/src/aggregation/aggregation.history.graphql b/apollo/src/aggregation/aggregation.history.graphql index 37078a8a..714d9c4b 100644 --- a/apollo/src/aggregation/aggregation.history.graphql +++ b/apollo/src/aggregation/aggregation.history.graphql @@ -35,16 +35,6 @@ type HistoryRecord { extData: String } -type DailyStatistics { - fromChain: String! - toChain: String! - bridge: String! - timestamp: Int! - token: String! - dailyVolume: BigInt - dailyCount: BigInt -} - type HistoryRecords { total: Int! records: [HistoryRecord] @@ -106,7 +96,6 @@ type Query { historyRecordById(id: String): HistoryRecord historyRecordByTxHash(txHash: String): HistoryRecord firstHistoryRecord(fromChain: String, toChain: String, bridge: String, results: [Int], relayer: String, token: String, order: String, notsubmited: Boolean): HistoryRecord - queryDailyStatistics(timepast: Int!, first: Int, from: String, to: String, bridge: String, token: String): [DailyStatistics] historyRecords(sender: String, recipient: String, relayer: String, needWithdrawLiquidity: Boolean, fromChains: [String], toChains: [String], bridges: [String], row: Int, page: Int, results: [Int], recvTokenAddress: String, order: String): HistoryRecords checkLnBridgeExist(fromChainId: Int, toChainId: Int, fromToken: String, toToken: String, version: String): Boolean tasksHealthCheck(name: String): [HealthInfo] diff --git a/apollo/src/aggregation/aggregation.resolver.ts b/apollo/src/aggregation/aggregation.resolver.ts index 2cd2a28b..8a631e21 100644 --- a/apollo/src/aggregation/aggregation.resolver.ts +++ b/apollo/src/aggregation/aggregation.resolver.ts @@ -160,39 +160,6 @@ export class AggregationResolver { }); } - // daily statistics - @Query() - async queryDailyStatistics( - @Args('timepast') timepast: number, - @Args('first') take: number, - @Args('from') fromChain: string, - @Args('to') toChain: string, - @Args('bridge') bridge: string, - @Args('token') token: string - ) { - const filter = []; - if (fromChain) { - filter.push({ fromChain }); - } - if (toChain) { - filter.push({ toChain }); - } - if (bridge) { - filter.push({ bridge }); - } - if (token) { - filter.push({ token }); - } - - const now = Date.now() / 1000; - const timelimit = Math.floor(now - timepast); - const where = { AND: { timestamp: { gt: timelimit }, AND: filter } }; - return this.aggregationService.queryDailyStatistics({ - take, - where, - }); - } - /** * @deprecated instead, please use signConfirmedBlock **/ diff --git a/apollo/src/aggregation/aggregation.service.ts b/apollo/src/aggregation/aggregation.service.ts index 35d24882..3959535a 100644 --- a/apollo/src/aggregation/aggregation.service.ts +++ b/apollo/src/aggregation/aggregation.service.ts @@ -1,5 +1,5 @@ import { INestApplication, Injectable, Logger, OnModuleInit } from '@nestjs/common'; -import { DailyStatistics, HistoryRecord, Prisma, PrismaClient } from '@prisma/client'; +import { HistoryRecord, Prisma, PrismaClient } from '@prisma/client'; import { HistoryRecords, LnBridgeRelayInfo, LnBridgeRelayInfos } from '../graphql'; // export lnbridge service configure import { last } from 'lodash'; @@ -165,39 +165,6 @@ export class AggregationService extends PrismaClient implements OnModuleInit { return { total, records }; } - // daily statistics - async createDailyStatistics(data: Prisma.DailyStatisticsCreateInput): Promise { - return this.dailyStatistics.create({ - data, - }); - } - - async updateDailyStatistics(params: { - where: Prisma.DailyStatisticsWhereUniqueInput; - data: Prisma.DailyStatisticsUpdateInput; - }): Promise { - const { where, data } = params; - return this.dailyStatistics.update({ - data, - where, - }); - } - - async queryDailyStatistics(params: { - skip?: number; - take?: number; - where?: Prisma.DailyStatisticsWhereInput; - }): Promise { - const { skip, take, where } = params; - - return this.dailyStatistics.findMany({ - skip, - take, - where, - orderBy: { timestamp: 'desc' }, - }); - } - tasksHealthCheck() { return this.tasksService.queryHealthChecks(); } @@ -300,15 +267,6 @@ export class AggregationService extends PrismaClient implements OnModuleInit { } } - async queryDailyStatisticsFirst( - dailyStatisticsWhereInput: Prisma.DailyStatisticsWhereInput - ): Promise { - return this.dailyStatistics.findFirst({ - where: dailyStatisticsWhereInput, - orderBy: { timestamp: 'desc' }, - }); - } - async calculateLnBridgeRelayerPoint( token: string, amount: bigint, diff --git a/apollo/src/app.module.ts b/apollo/src/app.module.ts index 1233d391..deae0fb5 100644 --- a/apollo/src/app.module.ts +++ b/apollo/src/app.module.ts @@ -5,12 +5,10 @@ import { GraphQLModule, Scalar } from '@nestjs/graphql'; import { ScheduleModule } from '@nestjs/schedule'; import BigInt from 'apollo-type-bigint'; import { join } from 'path'; -import { AccountModule } from './account/account.module'; import { AggregationModule } from './aggregation/aggregation.module'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { TasksModule } from './tasks/tasks.module'; -import { StatisticModule } from './statistic/statistic.module'; import { Lnv2Module } from './lnv2/lnv2.module'; import { Lnv3Module } from './lnv3/lnv3.module'; @@ -29,7 +27,6 @@ export class BigIntScalar extends BigInt {} outputAs: 'class', }, }), - AccountModule, ConfigModule.forRoot({ envFilePath: ['.env', chainEnvFilePath], isGlobal: true, @@ -37,7 +34,6 @@ export class BigIntScalar extends BigInt {} ScheduleModule.forRoot(), TasksModule, AggregationModule, - StatisticModule, Lnv2Module, Lnv3Module, ], diff --git a/apollo/src/filter/http-exception.filter.ts b/apollo/src/filter/http-exception.filter.ts deleted file mode 100644 index bb7cf791..00000000 --- a/apollo/src/filter/http-exception.filter.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common'; -import { Request, Response } from 'express'; - -@Catch(HttpException) -export class HttpExceptionFilter implements ExceptionFilter { - catch(exception: HttpException, host: ArgumentsHost) { - const ctx = host.switchToHttp(); - const response = ctx.getResponse(); - const request = ctx.getRequest(); - const status = exception.getStatus(); - const message = exception.message; - - response.status(status).json({ - code: status, - msg: message, - timestamp: new Date().toISOString(), - path: request.url, - data: null, - }); - } -} diff --git a/apollo/src/graphql.ts b/apollo/src/graphql.ts index 1a6af1e2..58e39126 100644 --- a/apollo/src/graphql.ts +++ b/apollo/src/graphql.ts @@ -8,40 +8,6 @@ /* tslint:disable */ /* eslint-disable */ -export class Accounts { - total: number; -} - -export abstract class IQuery { - abstract accounts(chain?: Nullable): Nullable | Promise>; - - abstract historyRecordById(id?: Nullable): Nullable | Promise>; - - abstract historyRecordByTxHash(txHash?: Nullable): Nullable | Promise>; - - abstract firstHistoryRecord(fromChain?: Nullable, toChain?: Nullable, bridge?: Nullable, results?: Nullable[]>, relayer?: Nullable, token?: Nullable, order?: Nullable, notsubmited?: Nullable): Nullable | Promise>; - - abstract queryDailyStatistics(timepast: number, first?: Nullable, from?: Nullable, to?: Nullable, bridge?: Nullable, token?: Nullable): Nullable[]> | Promise[]>>; - - abstract historyRecords(sender?: Nullable, recipient?: Nullable, relayer?: Nullable, needWithdrawLiquidity?: Nullable, fromChains?: Nullable[]>, toChains?: Nullable[]>, bridges?: Nullable[]>, row?: Nullable, page?: Nullable, results?: Nullable[]>, recvTokenAddress?: Nullable, order?: Nullable): Nullable | Promise>; - - abstract checkLnBridgeExist(fromChainId?: Nullable, toChainId?: Nullable, fromToken?: Nullable, toToken?: Nullable, version?: Nullable): Nullable | Promise>; - - abstract tasksHealthCheck(name?: Nullable): Nullable[]> | Promise[]>>; - - abstract queryGuardNeedSignature(fromChain?: Nullable, toChain?: Nullable, bridge?: Nullable, guardAddress?: Nullable, row?: Nullable): Nullable | Promise>; - - abstract queryRelayRecords(fromChain?: Nullable, toChain?: Nullable, bridge?: Nullable, relayer?: Nullable, row?: Nullable): Nullable | Promise>; - - abstract queryLnBridgeRelayInfos(fromChain?: Nullable, toChain?: Nullable, version?: Nullable, bridge?: Nullable, relayer?: Nullable, row?: Nullable, page?: Nullable): Nullable | Promise>; - - abstract sortedLnBridgeRelayInfos(fromChain?: Nullable, toChain?: Nullable, version?: Nullable, bridge?: Nullable, token?: Nullable, row?: Nullable, amount?: Nullable, decimals?: Nullable): Nullable | Promise>; - - abstract queryLnBridgeSupportChains(tokenKey?: Nullable): Nullable[]> | Promise[]>>; - - abstract queryMaxTransfer(fromChain?: Nullable, toChain?: Nullable, bridge?: Nullable, token?: Nullable, balance?: Nullable): Nullable | Promise>; -} - export class HistoryRecord { id: string; fromChain: string; @@ -76,16 +42,6 @@ export class HistoryRecord { extData?: Nullable; } -export class DailyStatistics { - fromChain: string; - toChain: string; - bridge: string; - timestamp: number; - token: string; - dailyVolume?: Nullable; - dailyCount?: Nullable; -} - export class HistoryRecords { total: number; records?: Nullable[]>; @@ -143,9 +99,31 @@ export class HealthInfo { callTimes?: Nullable; } -export abstract class IMutation { - abstract addGuardSignature(id?: Nullable, dataHash?: Nullable, signature?: Nullable): Nullable | Promise>; +export abstract class IQuery { + abstract historyRecordById(id?: Nullable): Nullable | Promise>; + + abstract historyRecordByTxHash(txHash?: Nullable): Nullable | Promise>; + + abstract firstHistoryRecord(fromChain?: Nullable, toChain?: Nullable, bridge?: Nullable, results?: Nullable[]>, relayer?: Nullable, token?: Nullable, order?: Nullable, notsubmited?: Nullable): Nullable | Promise>; + + abstract historyRecords(sender?: Nullable, recipient?: Nullable, relayer?: Nullable, needWithdrawLiquidity?: Nullable, fromChains?: Nullable[]>, toChains?: Nullable[]>, bridges?: Nullable[]>, row?: Nullable, page?: Nullable, results?: Nullable[]>, recvTokenAddress?: Nullable, order?: Nullable): Nullable | Promise>; + + abstract checkLnBridgeExist(fromChainId?: Nullable, toChainId?: Nullable, fromToken?: Nullable, toToken?: Nullable, version?: Nullable): Nullable | Promise>; + + abstract tasksHealthCheck(name?: Nullable): Nullable[]> | Promise[]>>; + + abstract queryRelayRecords(fromChain?: Nullable, toChain?: Nullable, bridge?: Nullable, relayer?: Nullable, row?: Nullable): Nullable | Promise>; + + abstract queryLnBridgeRelayInfos(fromChain?: Nullable, toChain?: Nullable, version?: Nullable, bridge?: Nullable, relayer?: Nullable, row?: Nullable, page?: Nullable): Nullable | Promise>; + abstract sortedLnBridgeRelayInfos(fromChain?: Nullable, toChain?: Nullable, version?: Nullable, bridge?: Nullable, token?: Nullable, row?: Nullable, amount?: Nullable, decimals?: Nullable): Nullable | Promise>; + + abstract queryLnBridgeSupportChains(tokenKey?: Nullable): Nullable[]> | Promise[]>>; + + abstract queryMaxTransfer(fromChain?: Nullable, toChain?: Nullable, bridge?: Nullable, token?: Nullable, balance?: Nullable): Nullable | Promise>; +} + +export abstract class IMutation { abstract updateConfirmedBlock(id?: Nullable, block?: Nullable): Nullable | Promise>; abstract lnBridgeHeartBeat(fromChainId?: Nullable, toChainId?: Nullable, version?: Nullable, relayer?: Nullable, tokenAddress?: Nullable, softTransferLimit?: Nullable): Nullable | Promise>; diff --git a/apollo/src/interface/record.ts b/apollo/src/interface/record.ts deleted file mode 100644 index 61e010b2..00000000 --- a/apollo/src/interface/record.ts +++ /dev/null @@ -1,34 +0,0 @@ -// eslint-disable-next-line no-magic-numbers -export type Result = 0 | 1 | 2; // 0 TokenLocked 1 TokenLockedConfirmed success 2 TokenLockedConfirmed fail - -export interface ThegraphRecord { - id: string; - lane_id: string; - nonce: string; - request_transaction: string; - response_transaction: string; - sender: string; - recipient: string; - token: string; - amount: string; - result: Result; - start_timestamp: string; - end_timestamp: string; - fee: string; -} - -export interface SubqlRecord { - id: string; - laneId: string; - nonce: string; - requestTxHash: string; - responseTxHash: string; - senderId: string; - recipient: string; - token: string; - amount: string; - result: Result; - startTimestamp: string; - endTimestamp: string; - fee: string; -} diff --git a/apollo/src/statistic/statistic.module.ts b/apollo/src/statistic/statistic.module.ts deleted file mode 100644 index ccc7760f..00000000 --- a/apollo/src/statistic/statistic.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from '@nestjs/common'; -import { AggregationModule } from '../aggregation/aggregation.module'; -import { TasksModule } from '../tasks/tasks.module'; -import { StatisticService } from './statistic.service'; - -@Module({ - imports: [AggregationModule, TasksModule], - providers: [StatisticService], -}) -export class StatisticModule {} diff --git a/apollo/src/statistic/statistic.service.ts b/apollo/src/statistic/statistic.service.ts deleted file mode 100644 index 6cc5a281..00000000 --- a/apollo/src/statistic/statistic.service.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; -import { AggregationService } from '../aggregation/aggregation.service'; -import { TasksService } from '../tasks/tasks.service'; - -@Injectable() -export class StatisticService implements OnModuleInit { - private readonly logger = new Logger('statistic'); - // start at 2021-12-15 00:00:00 - private readonly startDay = 1639497600; - private readonly secondPerDay = 86400; - private readonly fetchDailyDataInterval = 60000; - private isWorking = false; - - private readonly bridges = [ - { from: 'crab-dvm', to: 'heco', bridge: 'cBridge-crab-dvm', token: 'xRING', decimals: 1e18 }, - { from: 'heco', to: 'crab-dvm', bridge: 'cBridge-heco', token: 'RING', decimals: 1e18 }, - { from: 'crab-dvm', to: 'polygon', bridge: 'cBridge-crab-dvm', token: 'xRING', decimals: 1e18 }, - { from: 'polygon', to: 'crab-dvm', bridge: 'cBridge-polygon', token: 'RING', decimals: 1e18 }, - { from: 'ethereum', to: 'polygon', bridge: 'cBridge-ethereum', token: 'RING', decimals: 1e18 }, - { from: 'polygon', to: 'ethereum', bridge: 'cBridge-polygon', token: 'RING', decimals: 1e18 }, - { from: 'heco', to: 'ethereum', bridge: 'cBridge-heco', token: 'RING', decimals: 1e18 }, - { from: 'ethereum', to: 'heco', bridge: 'cBridge-ethereum', token: 'RING', decimals: 1e18 }, - { - from: 'crab-dvm', - to: 'ethereum', - bridge: 'cBridge-crab-dvm', - token: 'xRING', - decimals: 1e18, - }, - { from: 'ethereum', to: 'crab-dvm', bridge: 'cBridge-ethereum', token: 'RING', decimals: 1e18 }, - ]; - private lastDays = new Array(this.bridges.length).fill(0); - - constructor(private aggregationService: AggregationService, private taskService: TasksService) {} - - async onModuleInit() { - this.taskService.addInterval(`daily-statistic`, this.fetchDailyDataInterval, async () => { - if (this.isWorking) { - return; - } - this.isWorking = true; - this.bridges.forEach(async (item, index) => { - await this.refreshStatistic( - item.from, - item.to, - item.bridge, - item.token, - global.BigInt(item.decimals), - index - ); - }); - this.isWorking = false; - }); - } - - async refreshStatistic( - from: string, - to: string, - bridge: string, - token: string, - decimals: bigint, - index: number - ) { - try { - let lastStatisticDay = this.lastDays[index]; - if (lastStatisticDay === 0) { - lastStatisticDay = await this.aggregationService - .queryDailyStatisticsFirst({ - fromChain: from, - toChain: to, - bridge: bridge, - token: token, - }) - .then((firstRecord) => (firstRecord ? firstRecord.timestamp : this.startDay)); - } - - const latestRecordDay = await this.aggregationService - .queryHistoryRecordFirst({ - fromChain: from, - toChain: to, - bridge: bridge, - sendToken: token, - }) - .then((firstRecord) => (firstRecord ? firstRecord.startTime : this.startDay)); - const nextStartTimestamp = lastStatisticDay + this.secondPerDay; - const nextEndTimestamp = nextStartTimestamp + this.secondPerDay; - const records = await this.aggregationService.queryHistoryRecords({ - where: { - fromChain: from, - toChain: to, - bridge: bridge, - sendToken: token, - startTime: { - gt: nextStartTimestamp, - lt: nextEndTimestamp, - }, - }, - }); - const count = records.total; - let volume = global.BigInt(0); - for (const record of records.records) { - volume = volume + global.BigInt(record.sendAmount); - } - volume = volume / decimals; - if (nextStartTimestamp < latestRecordDay) { - this.lastDays[index] = nextStartTimestamp; - if (count === 0) { - return; - } - await this.aggregationService.createDailyStatistics({ - fromChain: from, - toChain: to, - bridge: bridge, - timestamp: nextStartTimestamp, - token: token, - dailyVolume: volume, - dailyCount: global.BigInt(count), - }); - this.logger.log( - `add new statistics record, from ${from}, to ${to}, bridge ${bridge}, token ${token}, time ${nextStartTimestamp}` - ); - } else { - if (this.startDay !== lastStatisticDay) { - await this.aggregationService.updateDailyStatistics({ - where: { - daily_statistics_id: { - fromChain: from, - toChain: to, - bridge: bridge, - token: token, - timestamp: lastStatisticDay, - }, - }, - data: { - dailyVolume: volume, - dailyCount: global.BigInt(count), - }, - }); - } - } - } catch (e) { - this.logger.warn('[Statistics] update daily statistics failed', 'err', e); - } - } -}