From a81da975a293a8cfb6176b0de5ca837e5a6cc639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pr=C3=A9vost?= <998369+prevostc@users.noreply.github.com> Date: Sat, 17 Feb 2024 18:09:05 +0100 Subject: [PATCH] Add timestamp query, ensure we indexed all blocks before the requested block --- src/api/route/private/protocol/beefy.ts | 17 ++++++++++------- src/api/service/protocol/beefy-vault.ts | 11 +++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/api/route/private/protocol/beefy.ts b/src/api/route/private/protocol/beefy.ts index 85e08959..fbb56b96 100644 --- a/src/api/route/private/protocol/beefy.ts +++ b/src/api/route/private/protocol/beefy.ts @@ -13,10 +13,9 @@ export default async function (instance: FastifyInstance, opts: FastifyPluginOpt .prop("chain", chainSchema.required().description("Only include products for this chain")) .prop("contract_address", addressSchema.required().description("The product contract address")) .prop("block_number", S.number().required().description("The block number to fetch the balances at")), - querystring: S.object().prop( - "block_datetime", - S.string().format("date-time").description("The block datetime, can be provided to speed up this endpoint."), - ), + querystring: S.object() + .prop("block_datetime", S.string().format("date-time").description("The block datetime. Can be provided to speed up this endpoint.")) + .prop("block_timestamp", S.number().description("The block timestamp (utc epoch. Can be provided to speed up this endpoint.")), tags: ["beefy"], summary: "Fetch all investor balances for a specific product at a specific block", description: "This endpoint returns all investor balances for a specific product at a specific block", @@ -26,14 +25,18 @@ export default async function (instance: FastifyInstance, opts: FastifyPluginOpt }; type TRoute = { Params: { chain: Chain; contract_address: string; block_number: number }; - Querystring: { block_datetime?: string }; + Querystring: { block_datetime?: string; block_timestamp?: number }; }; instance.get("/product/:chain/:contract_address/balances_at/:block_number", merge({}, opts.routeOpts, { schema }), async (req, reply) => { const { chain, contract_address, block_number } = req.params; - const { block_datetime: block_datetime_str } = req.query; + const { block_datetime: block_datetime_str, block_timestamp } = req.query; - const block_datetime = block_datetime_str ? new Date(block_datetime_str) : null; + if (block_datetime_str && block_timestamp) { + return reply.code(400).send({ error: "Only provide either block_datetime or block_timestamp" }); + } + + const block_datetime = block_datetime_str ? new Date(block_datetime_str) : block_timestamp ? new Date(block_timestamp * 1000) : null; const product = await instance.diContainer.cradle.product.getProductByChainAndContractAddress(chain, contract_address); if (!product) { diff --git a/src/api/service/protocol/beefy-vault.ts b/src/api/service/protocol/beefy-vault.ts index f1a5f37a..41620cb0 100644 --- a/src/api/service/protocol/beefy-vault.ts +++ b/src/api/service/protocol/beefy-vault.ts @@ -68,10 +68,21 @@ export class BeefyVaultService { } logger.debug({ importState }, "import state"); + if (importState.importData.contractCreatedAtBlock > blockNumber) { + throw new Error("This block is before the contract creation."); + } + if (importState.importData.chainLatestBlockNumber < blockNumber) { throw new Error("This block is not yet indexed. Please try again later. Last indexed block: " + importState.importData.chainLatestBlockNumber); } + // ensure all the blocks are indexed + importState.importData.ranges.toRetry.forEach((range) => { + if (range.from < blockNumber) { + throw new Error("Some previous block was not indexed. Please try again later."); + } + }); + const contractCreationDate = importState.importData.contractCreationDate; const block_datetime = blockDatetime ?? (await this.services.rpc.getBlockDatetime(product.chain, blockNumber));