From f62b086e15c2450957851072c17cb50ae48b9b33 Mon Sep 17 00:00:00 2001 From: Enzo Cioppettini <48031343+ecioppettini@users.noreply.github.com> Date: Mon, 22 Apr 2024 22:47:50 -0300 Subject: [PATCH] add timestamp checkpointing event --- .../paima-funnel/src/funnels/mina/funnel.ts | 39 +++++++++-- packages/engine/paima-sm/src/index.ts | 10 +++ packages/engine/paima-sm/src/types.ts | 7 +- packages/node-sdk/paima-db/migrations/up.sql | 6 ++ packages/node-sdk/paima-db/src/index.ts | 2 + .../node-sdk/paima-db/src/paima-tables.ts | 20 ++++++ .../src/sql/mina-checkpoints.queries.ts | 64 +++++++++++++++++++ .../paima-db/src/sql/mina-checkpoints.sql | 13 ++++ .../paima-sdk/paima-utils/src/constants.ts | 1 + 9 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 packages/node-sdk/paima-db/src/sql/mina-checkpoints.queries.ts create mode 100644 packages/node-sdk/paima-db/src/sql/mina-checkpoints.sql diff --git a/packages/engine/paima-funnel/src/funnels/mina/funnel.ts b/packages/engine/paima-funnel/src/funnels/mina/funnel.ts index b2ea34e9..f6e3f5f5 100644 --- a/packages/engine/paima-funnel/src/funnels/mina/funnel.ts +++ b/packages/engine/paima-funnel/src/funnels/mina/funnel.ts @@ -1,4 +1,11 @@ -import { doLog, logError, ChainDataExtensionType, delay, ENV } from '@paima/utils'; +import { + doLog, + logError, + ChainDataExtensionType, + delay, + ENV, + InternalEventType, +} from '@paima/utils'; import type { ChainFunnel, ReadPresyncDataFrom } from '@paima/runtime'; import type { ChainData, @@ -11,7 +18,7 @@ import { BaseFunnel } from '../BaseFunnel.js'; import type { FunnelSharedData } from '../BaseFunnel.js'; import type { PoolClient } from 'pg'; import { FUNNEL_PRESYNC_FINISHED, ConfigNetworkType } from '@paima/utils'; -import { getPaginationCursors } from '@paima/db'; +import { getMinaCheckpoint, getPaginationCursors } from '@paima/db'; import { getActionCdeData, getEventCdeData } from '../../cde/minaGeneric.js'; import type { MinaConfig } from '@paima/utils'; import { MinaFunnelCacheEntry } from '../FunnelCache.js'; @@ -86,8 +93,10 @@ export class MinaFunnel extends BaseFunnel implements ChainFunnel { await delay(delayForWaitingForFinalityLoop); } - const fromTimestamp = - this.cache.getState().lastPoint?.timestamp || cachedState.startingSlotTimestamp; + const lastRoundTimestamp = this.cache.getState().lastPoint?.timestamp; + const fromTimestamp = lastRoundTimestamp + ? lastRoundTimestamp + 1 + : cachedState.startingSlotTimestamp; const toTimestamp = maxBaseTimestamp; @@ -159,6 +168,23 @@ export class MinaFunnel extends BaseFunnel implements ChainFunnel { const composed = composeChainData(baseData, grouped); + for (const chainData of composed) { + if (!chainData.internalEvents) { + chainData.internalEvents = []; + } + + chainData.internalEvents.push({ + type: InternalEventType.MinaLastTimestamp, + + timestamp: baseChainTimestampToMina( + chainData.timestamp, + this.config.confirmationDepth, + this.config.slotDuration + ).toString(), + network: this.chainName, + }); + } + return composed; } @@ -347,6 +373,11 @@ export class MinaFunnel extends BaseFunnel implements ChainFunnel { }); }); + const checkpoint = await getMinaCheckpoint.run({ network: chainName }, dbTx); + if (checkpoint.length > 0) { + newEntry.updateLastPoint(Number.parseInt(checkpoint[0].timestamp, 10)); + } + return newEntry; })(); diff --git a/packages/engine/paima-sm/src/index.ts b/packages/engine/paima-sm/src/index.ts index bd4d143d..c34b2df2 100644 --- a/packages/engine/paima-sm/src/index.ts +++ b/packages/engine/paima-sm/src/index.ts @@ -29,6 +29,7 @@ import { NO_USER_ID, updateCardanoEpoch, updatePaginationCursor, + updateMinaCheckpoint, } from '@paima/db'; import Prando from '@paima/prando'; @@ -488,6 +489,15 @@ async function processInternalEvents( dbTx ); break; + case InternalEventType.MinaLastTimestamp: + await updateMinaCheckpoint.run( + { + timestamp: event.timestamp, + network: event.network, + }, + dbTx + ); + break; default: assertNever(event); } diff --git a/packages/engine/paima-sm/src/types.ts b/packages/engine/paima-sm/src/types.ts index ecdf2fb7..b8f705c9 100644 --- a/packages/engine/paima-sm/src/types.ts +++ b/packages/engine/paima-sm/src/types.ts @@ -35,13 +35,18 @@ export interface ChainData { internalEvents?: InternalEvent[]; } -export type InternalEvent = CardanoEpochEvent | EvmLastBlockEvent; +export type InternalEvent = CardanoEpochEvent | EvmLastBlockEvent | MinaLastTimestampEvent; export type CardanoEpochEvent = { type: InternalEventType.CardanoBestEpoch; epoch: number }; export type EvmLastBlockEvent = { type: InternalEventType.EvmLastBlock; block: number; network: string; }; +export type MinaLastTimestampEvent = { + type: InternalEventType.MinaLastTimestamp; + timestamp: string; + network: string; +}; export interface EvmPresyncChainData { network: string; diff --git a/packages/node-sdk/paima-db/migrations/up.sql b/packages/node-sdk/paima-db/migrations/up.sql index ebee57cc..f1eb0dd3 100644 --- a/packages/node-sdk/paima-db/migrations/up.sql +++ b/packages/node-sdk/paima-db/migrations/up.sql @@ -241,3 +241,9 @@ CREATE TABLE cde_cardano_mint_burn( output_addresses JSONB NOT NULL, PRIMARY KEY (cde_id, tx_id) ); + +CREATE TABLE mina_checkpoint ( + timestamp TEXT NOT NULL, + network TEXT NOT NULL, + PRIMARY KEY (network) +); diff --git a/packages/node-sdk/paima-db/src/index.ts b/packages/node-sdk/paima-db/src/index.ts index c398c26f..e2f1f3cf 100644 --- a/packages/node-sdk/paima-db/src/index.ts +++ b/packages/node-sdk/paima-db/src/index.ts @@ -53,6 +53,8 @@ export type * from './sql/cde-cursor-tracking-pagination.queries.js'; export * from './sql/cde-cardano-transfer.queries.js'; export type * from './sql/cde-cardano-transfer.queries.js'; export { cdeCardanoMintBurnInsert } from './sql/cde-cardano-mint-burn.queries.js'; +export type * from './sql/mina-checkpoints.queries.js'; +export * from './sql/mina-checkpoints.queries.js'; export { tx, diff --git a/packages/node-sdk/paima-db/src/paima-tables.ts b/packages/node-sdk/paima-db/src/paima-tables.ts index 52161aa3..9b197d1c 100644 --- a/packages/node-sdk/paima-db/src/paima-tables.ts +++ b/packages/node-sdk/paima-db/src/paima-tables.ts @@ -576,6 +576,25 @@ const TABLE_DATA_DELEGATIONS: TableData = { creationQuery: QUERY_CREATE_TABLE_DELEGATIONS, }; +const QUERY_CREATE_TABLE_MINA_CHECKPOINT = ` +CREATE TABLE mina_checkpoint ( + timestamp TEXT NOT NULL, + network TEXT NOT NULL, + PRIMARY KEY (network) +); +`; + +const TABLE_DATA_MINA_CHECKPOINT: TableData = { + tableName: 'mina_checkpoint', + primaryKeyColumns: ['network'], + columnData: packTuples([ + ['timestamp', 'text', 'NO', ''], + ['network', 'text', 'NO', ''], + ]), + serialColumns: [], + creationQuery: QUERY_CREATE_TABLE_MINA_CHECKPOINT, +}; + const FUNCTION_NOTIFY_WALLET_CONNECT: string = ` create or replace function public.notify_wallet_connect() returns trigger @@ -663,4 +682,5 @@ export const TABLES: TableData[] = [ TABLE_DATA_CDE_TRACKING_CURSOR_PAGINATION, TABLE_DATA_CDE_CARDANO_TRANSFER, TABLE_DATA_CDE_CARDANO_MINT_BURN, + TABLE_DATA_MINA_CHECKPOINT, ]; diff --git a/packages/node-sdk/paima-db/src/sql/mina-checkpoints.queries.ts b/packages/node-sdk/paima-db/src/sql/mina-checkpoints.queries.ts new file mode 100644 index 00000000..0c61c3d6 --- /dev/null +++ b/packages/node-sdk/paima-db/src/sql/mina-checkpoints.queries.ts @@ -0,0 +1,64 @@ +/** Types generated for queries found in "src/sql/mina-checkpoints.sql" */ +import { PreparedQuery } from '@pgtyped/runtime'; + +/** 'UpdateMinaCheckpoint' parameters type */ +export interface IUpdateMinaCheckpointParams { + network: string; + timestamp: string; +} + +/** 'UpdateMinaCheckpoint' return type */ +export type IUpdateMinaCheckpointResult = void; + +/** 'UpdateMinaCheckpoint' query type */ +export interface IUpdateMinaCheckpointQuery { + params: IUpdateMinaCheckpointParams; + result: IUpdateMinaCheckpointResult; +} + +const updateMinaCheckpointIR: any = {"usedParamSet":{"timestamp":true,"network":true},"params":[{"name":"timestamp","required":true,"transform":{"type":"scalar"},"locs":[{"a":71,"b":81},{"a":149,"b":159}]},{"name":"network","required":true,"transform":{"type":"scalar"},"locs":[{"a":88,"b":96}]}],"statement":"INSERT INTO mina_checkpoint(\n timestamp,\n network\n) VALUES (\n :timestamp!,\n :network!\n) \nON CONFLICT (network) DO\nUPDATE SET timestamp = :timestamp!"}; + +/** + * Query generated from SQL: + * ``` + * INSERT INTO mina_checkpoint( + * timestamp, + * network + * ) VALUES ( + * :timestamp!, + * :network! + * ) + * ON CONFLICT (network) DO + * UPDATE SET timestamp = :timestamp! + * ``` + */ +export const updateMinaCheckpoint = new PreparedQuery(updateMinaCheckpointIR); + + +/** 'GetMinaCheckpoint' parameters type */ +export interface IGetMinaCheckpointParams { + network: string; +} + +/** 'GetMinaCheckpoint' return type */ +export interface IGetMinaCheckpointResult { + timestamp: string; +} + +/** 'GetMinaCheckpoint' query type */ +export interface IGetMinaCheckpointQuery { + params: IGetMinaCheckpointParams; + result: IGetMinaCheckpointResult; +} + +const getMinaCheckpointIR: any = {"usedParamSet":{"network":true},"params":[{"name":"network","required":true,"transform":{"type":"scalar"},"locs":[{"a":54,"b":62}]}],"statement":"SELECT timestamp FROM mina_checkpoint WHERE network = :network! LIMIT 1"}; + +/** + * Query generated from SQL: + * ``` + * SELECT timestamp FROM mina_checkpoint WHERE network = :network! LIMIT 1 + * ``` + */ +export const getMinaCheckpoint = new PreparedQuery(getMinaCheckpointIR); + + diff --git a/packages/node-sdk/paima-db/src/sql/mina-checkpoints.sql b/packages/node-sdk/paima-db/src/sql/mina-checkpoints.sql new file mode 100644 index 00000000..da8f6e9e --- /dev/null +++ b/packages/node-sdk/paima-db/src/sql/mina-checkpoints.sql @@ -0,0 +1,13 @@ +/* @name updateMinaCheckpoint */ +INSERT INTO mina_checkpoint( + timestamp, + network +) VALUES ( + :timestamp!, + :network! +) +ON CONFLICT (network) DO +UPDATE SET timestamp = :timestamp!; + +/* @name getMinaCheckpoint */ +SELECT timestamp FROM mina_checkpoint WHERE network = :network! LIMIT 1; diff --git a/packages/paima-sdk/paima-utils/src/constants.ts b/packages/paima-sdk/paima-utils/src/constants.ts index 90ac1df2..0751ed41 100644 --- a/packages/paima-sdk/paima-utils/src/constants.ts +++ b/packages/paima-sdk/paima-utils/src/constants.ts @@ -50,4 +50,5 @@ export const FUNNEL_PRESYNC_FINISHED = 'finished'; export const enum InternalEventType { CardanoBestEpoch, EvmLastBlock, + MinaLastTimestamp, }