From 94ddeaf6591536dfa347a042e402af3c0d0fb673 Mon Sep 17 00:00:00 2001 From: Enzo Cioppettini Date: Fri, 24 Nov 2023 01:56:29 -0300 Subject: [PATCH] presync checkpointing for cardano cde --- .../engine/paima-runtime/src/runtime-loops.ts | 12 +++- packages/engine/paima-runtime/src/types.ts | 1 + .../engine/paima-sm/src/cde-cardano-pool.ts | 4 +- packages/engine/paima-sm/src/index.ts | 7 ++- packages/node-sdk/paima-db/migrations/up.sql | 3 +- .../node-sdk/paima-db/src/paima-tables.ts | 10 ++- .../src/sql/cde-tracking-cardano.queries.ts | 62 +++++-------------- .../paima-db/src/sql/cde-tracking-cardano.sql | 16 ++--- 8 files changed, 49 insertions(+), 66 deletions(-) diff --git a/packages/engine/paima-runtime/src/runtime-loops.ts b/packages/engine/paima-runtime/src/runtime-loops.ts index f3860766a..2df0fcede 100644 --- a/packages/engine/paima-runtime/src/runtime-loops.ts +++ b/packages/engine/paima-runtime/src/runtime-loops.ts @@ -89,7 +89,7 @@ async function runPresync( } // eslint-disable-next-line @typescript-eslint/no-loop-func - let newHeight = (await tx)(gameStateMachine.getReadWriteDbConn(), async dbTx => { + let newHeight = tx(gameStateMachine.getReadWriteDbConn(), async dbTx => { const chainFunnel = await funnelFactory.generateFunnel(dbTx); return await runPresyncRound( gameStateMachine, @@ -162,8 +162,16 @@ async function runPresyncRound( const filteredPresyncDataList = Object.values(latestPresyncDataList) .flatMap(data => (data !== FUNNEL_PRESYNC_FINISHED ? data : [])) .filter(unit => unit.extensionDatums.length > 0); + + const dbTx = chainFunnel.getDbTx(); + for (const presyncData of filteredPresyncDataList) { - await gameStateMachine.presyncProcess(chainFunnel.getDbTx(), presyncData); + await gameStateMachine.presyncProcess(dbTx, presyncData); + } + + const cardanoFrom = from.find(arg => arg.network === Network.CARDANO); + if (cardanoFrom) { + await gameStateMachine.markCardanoPresyncMilestone(dbTx, cardanoFrom.to); } return Object.fromEntries( diff --git a/packages/engine/paima-runtime/src/types.ts b/packages/engine/paima-runtime/src/types.ts index df82f1d6d..c3ff7d7bc 100644 --- a/packages/engine/paima-runtime/src/types.ts +++ b/packages/engine/paima-runtime/src/types.ts @@ -368,6 +368,7 @@ export interface GameStateMachine { process: (dbTx: PoolClient, chainData: ChainData) => Promise; presyncProcess: (dbTx: PoolClient, latestCdeData: PresyncChainData) => Promise; markPresyncMilestone: (blockHeight: number) => Promise; + markCardanoPresyncMilestone: (dbTx: PoolClient, slot: number) => Promise; dryRun: (gameInput: string, userAddress: string) => Promise; } diff --git a/packages/engine/paima-sm/src/cde-cardano-pool.ts b/packages/engine/paima-sm/src/cde-cardano-pool.ts index fba52ca07..866ae5cf9 100644 --- a/packages/engine/paima-sm/src/cde-cardano-pool.ts +++ b/packages/engine/paima-sm/src/cde-cardano-pool.ts @@ -1,6 +1,4 @@ -import type { Pool } from 'pg'; - -import { doLog, ENV } from '@paima/utils'; +import { ENV } from '@paima/utils'; import type { CdeCardanoPoolDatum } from '@paima/runtime'; import { createScheduledData, cdeCardanoPoolInsertData } from '@paima/db'; import type { SQLUpdate } from '@paima/db'; diff --git a/packages/engine/paima-sm/src/index.ts b/packages/engine/paima-sm/src/index.ts index 7ebe2c537..44da66a84 100644 --- a/packages/engine/paima-sm/src/index.ts +++ b/packages/engine/paima-sm/src/index.ts @@ -24,7 +24,7 @@ import { saveLastBlockHeight, markCdeBlockheightProcessed, getLatestProcessedCdeBlockheight, - getCardanoLatestProcessedCdeBlockheight, + getCardanoLatestProcessedCdeSlot, markCardanoCdeSlotProcessed, } from '@paima/db'; import Prando from '@paima/prando'; @@ -60,7 +60,7 @@ const SM: GameStateMachineInitializer = { getPresyncCardanoSlotHeight: async ( dbTx: PoolClient | Pool = readonlyDBConn ): Promise => { - const [b] = await getCardanoLatestProcessedCdeBlockheight.run(undefined, dbTx); + const [b] = await getCardanoLatestProcessedCdeSlot.run(undefined, dbTx); const slot = b?.slot ?? 0; return slot; }, @@ -108,6 +108,9 @@ const SM: GameStateMachineInitializer = { ): Promise => { await markCdeBlockheightProcessed.run({ block_height: blockHeight }, dbTx); }, + markCardanoPresyncMilestone: async (dbTx: PoolClient, slot: number): Promise => { + await markCardanoCdeSlotProcessed.run({ slot: slot }, dbTx); + }, dryRun: async ( gameInput: string, userAddress: string, diff --git a/packages/node-sdk/paima-db/migrations/up.sql b/packages/node-sdk/paima-db/migrations/up.sql index a6b514087..50750ccd3 100644 --- a/packages/node-sdk/paima-db/migrations/up.sql +++ b/packages/node-sdk/paima-db/migrations/up.sql @@ -27,7 +27,8 @@ CREATE TABLE cde_tracking ( ); CREATE TABLE cde_tracking_cardano ( - slot INTEGER PRIMARY KEY + id INTEGER PRIMARY KEY, + slot INTEGER NOT NULL ); CREATE TABLE chain_data_extensions ( diff --git a/packages/node-sdk/paima-db/src/paima-tables.ts b/packages/node-sdk/paima-db/src/paima-tables.ts index 17340eabb..02178a43b 100644 --- a/packages/node-sdk/paima-db/src/paima-tables.ts +++ b/packages/node-sdk/paima-db/src/paima-tables.ts @@ -97,14 +97,18 @@ const TABLE_DATA_CDE_TRACKING: TableData = { const QUERY_CREATE_TABLE_CDE_TRACKING_CARDANO = ` CREATE TABLE cde_tracking_cardano ( - slot INTEGER PRIMARY KEY + id INTEGER PRIMARY KEY, + slot INTEGER NOT NULL ); `; const TABLE_DATA_CDE_TRACKING_CARDANO: TableData = { tableName: 'cde_tracking_cardano', - primaryKeyColumns: ['slot'], - columnData: packTuples([['slot', 'integer', 'NO', '']]), + primaryKeyColumns: ['id'], + columnData: packTuples([ + ['id', 'integer', 'NO', ''], + ['slot', 'integer', 'NO', ''], + ]), serialColumns: [], creationQuery: QUERY_CREATE_TABLE_CDE_TRACKING_CARDANO, }; diff --git a/packages/node-sdk/paima-db/src/sql/cde-tracking-cardano.queries.ts b/packages/node-sdk/paima-db/src/sql/cde-tracking-cardano.queries.ts index 6d5a73801..1a8ad4abd 100644 --- a/packages/node-sdk/paima-db/src/sql/cde-tracking-cardano.queries.ts +++ b/packages/node-sdk/paima-db/src/sql/cde-tracking-cardano.queries.ts @@ -15,70 +15,42 @@ export interface IMarkCardanoCdeSlotProcessedQuery { result: IMarkCardanoCdeSlotProcessedResult; } -const markCardanoCdeSlotProcessedIR: any = {"usedParamSet":{"slot":true},"params":[{"name":"slot","required":true,"transform":{"type":"scalar"},"locs":[{"a":47,"b":52}]}],"statement":"INSERT INTO cde_tracking_cardano(slot)\nVALUES (:slot!)"}; +const markCardanoCdeSlotProcessedIR: any = {"usedParamSet":{"slot":true},"params":[{"name":"slot","required":true,"transform":{"type":"scalar"},"locs":[{"a":53,"b":58},{"a":100,"b":105}]}],"statement":"INSERT INTO cde_tracking_cardano(id,slot)\nVALUES (0, :slot!)\nON CONFLICT (id) \nDO UPDATE SET slot = :slot!"}; /** * Query generated from SQL: * ``` - * INSERT INTO cde_tracking_cardano(slot) - * VALUES (:slot!) + * INSERT INTO cde_tracking_cardano(id,slot) + * VALUES (0, :slot!) + * ON CONFLICT (id) + * DO UPDATE SET slot = :slot! * ``` */ export const markCardanoCdeSlotProcessed = new PreparedQuery(markCardanoCdeSlotProcessedIR); -/** 'GetCardanoSpecificCdeBlockheight' parameters type */ -export interface IGetCardanoSpecificCdeBlockheightParams { - slot: number; -} - -/** 'GetCardanoSpecificCdeBlockheight' return type */ -export interface IGetCardanoSpecificCdeBlockheightResult { - slot: number; -} +/** 'GetCardanoLatestProcessedCdeSlot' parameters type */ +export type IGetCardanoLatestProcessedCdeSlotParams = void; -/** 'GetCardanoSpecificCdeBlockheight' query type */ -export interface IGetCardanoSpecificCdeBlockheightQuery { - params: IGetCardanoSpecificCdeBlockheightParams; - result: IGetCardanoSpecificCdeBlockheightResult; -} - -const getCardanoSpecificCdeBlockheightIR: any = {"usedParamSet":{"slot":true},"params":[{"name":"slot","required":true,"transform":{"type":"scalar"},"locs":[{"a":48,"b":53}]}],"statement":"SELECT * FROM cde_tracking_cardano\nWHERE slot = :slot!"}; - -/** - * Query generated from SQL: - * ``` - * SELECT * FROM cde_tracking_cardano - * WHERE slot = :slot! - * ``` - */ -export const getCardanoSpecificCdeBlockheight = new PreparedQuery(getCardanoSpecificCdeBlockheightIR); - - -/** 'GetCardanoLatestProcessedCdeBlockheight' parameters type */ -export type IGetCardanoLatestProcessedCdeBlockheightParams = void; - -/** 'GetCardanoLatestProcessedCdeBlockheight' return type */ -export interface IGetCardanoLatestProcessedCdeBlockheightResult { - slot: number; +/** 'GetCardanoLatestProcessedCdeSlot' return type */ +export interface IGetCardanoLatestProcessedCdeSlotResult { + slot: number | null; } -/** 'GetCardanoLatestProcessedCdeBlockheight' query type */ -export interface IGetCardanoLatestProcessedCdeBlockheightQuery { - params: IGetCardanoLatestProcessedCdeBlockheightParams; - result: IGetCardanoLatestProcessedCdeBlockheightResult; +/** 'GetCardanoLatestProcessedCdeSlot' query type */ +export interface IGetCardanoLatestProcessedCdeSlotQuery { + params: IGetCardanoLatestProcessedCdeSlotParams; + result: IGetCardanoLatestProcessedCdeSlotResult; } -const getCardanoLatestProcessedCdeBlockheightIR: any = {"usedParamSet":{},"params":[],"statement":"SELECT * FROM cde_tracking_cardano\nORDER BY slot DESC\nLIMIT 1"}; +const getCardanoLatestProcessedCdeSlotIR: any = {"usedParamSet":{},"params":[],"statement":"SELECT slot FROM cde_tracking_cardano LIMIT 1"}; /** * Query generated from SQL: * ``` - * SELECT * FROM cde_tracking_cardano - * ORDER BY slot DESC - * LIMIT 1 + * SELECT slot FROM cde_tracking_cardano LIMIT 1 * ``` */ -export const getCardanoLatestProcessedCdeBlockheight = new PreparedQuery(getCardanoLatestProcessedCdeBlockheightIR); +export const getCardanoLatestProcessedCdeSlot = new PreparedQuery(getCardanoLatestProcessedCdeSlotIR); diff --git a/packages/node-sdk/paima-db/src/sql/cde-tracking-cardano.sql b/packages/node-sdk/paima-db/src/sql/cde-tracking-cardano.sql index 41866f3ec..4034af02b 100644 --- a/packages/node-sdk/paima-db/src/sql/cde-tracking-cardano.sql +++ b/packages/node-sdk/paima-db/src/sql/cde-tracking-cardano.sql @@ -1,12 +1,8 @@ /* @name markCardanoCdeSlotProcessed */ -INSERT INTO cde_tracking_cardano(slot) -VALUES (:slot!); +INSERT INTO cde_tracking_cardano(id,slot) +VALUES (0, :slot!) +ON CONFLICT (id) +DO UPDATE SET slot = :slot!; -/* @name getCardanoSpecificCdeBlockheight */ -SELECT * FROM cde_tracking_cardano -WHERE slot = :slot!; - -/* @name getCardanoLatestProcessedCdeBlockheight */ -SELECT * FROM cde_tracking_cardano -ORDER BY slot DESC -LIMIT 1; \ No newline at end of file +/* @name getCardanoLatestProcessedCdeSlot */ +SELECT slot FROM cde_tracking_cardano LIMIT 1; \ No newline at end of file