From b29ef3e31820eadcb876278f0c8e9653d387a16b Mon Sep 17 00:00:00 2001 From: Rhys Bartels-Waller Date: Mon, 25 Jan 2021 19:01:54 +1100 Subject: [PATCH] fix: Replaces the time-based logic to determine sync progress and initialisation state Enabled by having direct access to cardano-node via cardano-cli, the node tip is used as the base value to determine the sync progress of cardano-db-sync. In addition, the initialisation state is now determined by asserting the most recent epoch in the table matches the tip's epochNo Fixes #248 --- packages/api-cardano-db-hasura/package.json | 1 - .../src/CardanoNodeClient.ts | 10 ++++++-- .../api-cardano-db-hasura/src/HasuraClient.ts | 23 +++++++++++-------- .../src/executableSchema.ts | 3 ++- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/packages/api-cardano-db-hasura/package.json b/packages/api-cardano-db-hasura/package.json index 3b2ab965..40a6d1cc 100644 --- a/packages/api-cardano-db-hasura/package.json +++ b/packages/api-cardano-db-hasura/package.json @@ -43,7 +43,6 @@ "apollo-server": "^2.15.1", "bignumber.js": "^9.0.1", "cross-fetch": "^3.0.4", - "dayjs": "^1.8.29", "graphql": "14.5.8", "graphql-bigint": "^1.0.0", "graphql-scalars": "^1.2.1", diff --git a/packages/api-cardano-db-hasura/src/CardanoNodeClient.ts b/packages/api-cardano-db-hasura/src/CardanoNodeClient.ts index 6d27392c..46b0e4cb 100644 --- a/packages/api-cardano-db-hasura/src/CardanoNodeClient.ts +++ b/packages/api-cardano-db-hasura/src/CardanoNodeClient.ts @@ -23,7 +23,7 @@ export class CardanoNodeClient { constructor ( private cardanoCli: CardanoCli, pollingInterval: number, - private currentEraFirstSlot: number, + readonly currentEraFirstSlot: number, private logger: Logger = dummyLogger ) { this.currentEraFirstSlot = currentEraFirstSlot @@ -35,10 +35,16 @@ export class CardanoNodeClient { ) } + public async getTip () { + const tip = this.cardanoCli.getTip() + this.logger.debug('getTip', { module: 'CardanoNodeClient', value: tip }) + return tip + } + public async initialize () { await pRetry(async () => { await fs.stat(process.env.CARDANO_NODE_SOCKET_PATH) - const { slotNo } = await this.cardanoCli.getTip() + const { slotNo } = await this.getTip() if (slotNo < this.currentEraFirstSlot) { this.logger.debug('cardano-node tip', { module: 'CardanoNodeClient', value: slotNo }) this.logger.debug('currentEraFirstSlot', { module: 'CardanoNodeClient', value: this.currentEraFirstSlot }) diff --git a/packages/api-cardano-db-hasura/src/HasuraClient.ts b/packages/api-cardano-db-hasura/src/HasuraClient.ts index fcbedab2..e26f63ac 100644 --- a/packages/api-cardano-db-hasura/src/HasuraClient.ts +++ b/packages/api-cardano-db-hasura/src/HasuraClient.ts @@ -3,8 +3,6 @@ import { createHttpLink } from 'apollo-link-http' import util, { DataFetcher } from '@cardano-graphql/util' import { exec } from 'child_process' import fetch from 'cross-fetch' -import dayjs from 'dayjs' -import utc from 'dayjs/plugin/utc' import { DocumentNode, GraphQLSchema, print } from 'graphql' import { introspectSchema, wrapSchema } from '@graphql-tools/wrap' import pRetry from 'p-retry' @@ -19,8 +17,6 @@ import { import { dummyLogger, Logger } from 'ts-log' import BigNumber from 'bignumber.js' -dayjs.extend(utc) - export class HasuraClient { private client: ApolloClient private applyingSchemaAndMetadata: boolean @@ -252,21 +248,30 @@ export class HasuraClient { } } - public async getMeta () { + public async getMeta (nodeTipBlockNumber: number) { const result = await this.client.query({ query: gql`query { + epochs (limit: 1, order_by: { number: desc }) { + number + } cardano { tip { + epoch { + number + } + number forgedAt } }}` }) const { tip } = result.data?.cardano[0] - const currentUtc = dayjs().utc() - const tipUtc = dayjs.utc(tip.forgedAt) + const lastEpoch = result.data?.epochs[0] return { - initialized: tipUtc.isAfter(currentUtc.subtract(120, 'second')), - syncPercentage: (tipUtc.valueOf() / currentUtc.valueOf()) * 100 + // cardano-db-sync writes the epoch record at the end of each epoch during times of bulk sync + // The initialization state can be determined by comparing the last epoch record against the + // tip + initialized: lastEpoch.number === tip.epoch.number, + syncPercentage: (tip.number / nodeTipBlockNumber) * 100 } } } diff --git a/packages/api-cardano-db-hasura/src/executableSchema.ts b/packages/api-cardano-db-hasura/src/executableSchema.ts index 0e5749db..07f9301a 100644 --- a/packages/api-cardano-db-hasura/src/executableSchema.ts +++ b/packages/api-cardano-db-hasura/src/executableSchema.ts @@ -126,7 +126,8 @@ export async function buildSchema ( }, cardanoDbMeta: async () => { try { - return hasuraClient.getMeta() + const tip = await cardanoNodeClient.getTip() + return hasuraClient.getMeta(tip.blockNo) } catch (error) { throw new ApolloError(error) }