From 7042434c61468580ebe7cd85f60c00a38a1b6a73 Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Tue, 26 Sep 2023 12:36:44 -0700 Subject: [PATCH] Take into account bank events when converting time parameters to blocks. --- src/core/utils/block.ts | 63 +++++++++++++++++++++++++++ src/core/utils/index.ts | 1 + src/server/routes/indexer/computer.ts | 56 ++++-------------------- 3 files changed, 73 insertions(+), 47 deletions(-) create mode 100644 src/core/utils/block.ts diff --git a/src/core/utils/block.ts b/src/core/utils/block.ts new file mode 100644 index 00000000..2661a0e9 --- /dev/null +++ b/src/core/utils/block.ts @@ -0,0 +1,63 @@ +import { Op } from 'sequelize' + +import { BankStateEvent, WasmStateEvent } from '@/db' + +import { Block } from '../types' + +export const getBlockForTime = async ( + blockTimeUnixMs: bigint +): Promise => { + const [wasmEvent, bankEvent] = await Promise.all([ + await WasmStateEvent.findOne({ + where: { + blockTimeUnixMs: { + [Op.gt]: 0, + [Op.lte]: blockTimeUnixMs, + }, + }, + order: [['blockTimeUnixMs', 'DESC']], + }), + await BankStateEvent.findOne({ + where: { + blockTimeUnixMs: { + [Op.gt]: 0, + [Op.lte]: blockTimeUnixMs, + }, + }, + order: [['blockTimeUnixMs', 'DESC']], + }), + ]) + + // Choose latest block. + return [ + ...(wasmEvent ? [wasmEvent.block] : []), + ...(bankEvent ? [bankEvent.block] : []), + ].sort((a, b) => Number(b.height - a.height))[0] +} + +export const getFirstBlock = async (): Promise => { + const [wasmEvent, bankEvent] = await Promise.all([ + await WasmStateEvent.findOne({ + where: { + blockTimeUnixMs: { + [Op.gt]: 0, + }, + }, + order: [['blockTimeUnixMs', 'ASC']], + }), + await BankStateEvent.findOne({ + where: { + blockTimeUnixMs: { + [Op.gt]: 0, + }, + }, + order: [['blockTimeUnixMs', 'ASC']], + }), + ]) + + // Choose latest block. + return [ + ...(wasmEvent ? [wasmEvent.block] : []), + ...(bankEvent ? [bankEvent.block] : []), + ].sort((a, b) => Number(b.height - a.height))[0] +} diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index 6839c4b0..322d738a 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -7,6 +7,7 @@ import { DependentKeyNamespace } from '@/db' import { Block, FormulaType, SerializedBlock } from '../types' +export * from './block' export * from './chain' export * from './objectMatchesStructure' diff --git a/src/server/routes/indexer/computer.ts b/src/server/routes/indexer/computer.ts index 4506bba4..4af18f1d 100644 --- a/src/server/routes/indexer/computer.ts +++ b/src/server/routes/indexer/computer.ts @@ -7,6 +7,8 @@ import { FormulaTypeValues, compute, computeRange, + getBlockForTime, + getFirstBlock, loadConfig, typeIsFormulaType, validateBlockString, @@ -19,7 +21,6 @@ import { Contract, State, Validator, - WasmStateEvent, } from '@/db' import { captureSentryException } from '../../sentry' @@ -208,9 +209,9 @@ export const computer: Router.Middleware = async (ctx) => { // TODO: Calculate start and end block with times some other way. Or don't use // start and end blocks at all and use block or time depending on which is - // passed? Right now, the block is retrieved by checking `WasmEvent`s, but - // there are many times of events now and any formula can use any event type. - // This needs a better solution. + // passed? Right now, the block is retrieved by checking `WasmStateEvent`s, + // but there are many times of events now and any formula can use any event + // type. This needs a better solution. // If times passed, validate that it's a range with either a start or a // start/end pair. @@ -336,17 +337,7 @@ export const computer: Router.Middleware = async (ctx) => { time += BigInt(state.latestBlockTimeUnixMs) } - block = ( - await WasmStateEvent.findOne({ - where: { - blockTimeUnixMs: { - [Op.gt]: 0, - [Op.lte]: time, - }, - }, - order: [['blockTimeUnixMs', 'DESC']], - }) - )?.block + block = await getBlockForTime(time) } // If times passed, compute blocks that correlate with those times. @@ -360,41 +351,12 @@ export const computer: Router.Middleware = async (ctx) => { } const startBlock = - ( - await WasmStateEvent.findOne({ - where: { - blockTimeUnixMs: { - [Op.gt]: 0, - [Op.lte]: times[0], - }, - }, - order: [['blockTimeUnixMs', 'DESC']], - }) - )?.block ?? + (await getBlockForTime(times[0])) ?? // Use first block if no event exists before start time. - ( - await WasmStateEvent.findOne({ - where: { - blockTimeUnixMs: { - [Op.gt]: 0, - }, - }, - order: [['blockTimeUnixMs', 'ASC']], - }) - )?.block + (await getFirstBlock()) // Use latest block if no end time exists. const endBlock = times[1] - ? ( - await WasmStateEvent.findOne({ - where: { - blockTimeUnixMs: { - [Op.gt]: 0, - [Op.lte]: times[1], - }, - }, - order: [['blockTimeUnixMs', 'DESC']], - }) - )?.block + ? await getBlockForTime(times[1]) : state.latestBlock if (startBlock && endBlock) {