From c1ecd45ef7de5efb1a217085d42122e678c19545 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Tue, 4 Feb 2025 10:38:20 +0000 Subject: [PATCH 1/5] add strict type checking --- api/test/test-helpers.js | 4 +++ backend/bin/deal-observer-backend.js | 14 ++++++-- backend/lib/deal-observer.js | 6 ++-- backend/lib/rpc-service/data-types.js | 9 ++++- backend/lib/rpc-service/service.js | 16 ++++++--- backend/lib/spark-api-submit-deals.js | 8 ++--- backend/lib/telemetry.js | 4 +++ backend/package.json | 2 ++ backend/test/deal-observer.test.js | 7 ++++ backend/test/piece-indexer.test.js | 16 ++++++++- backend/test/rpc-client.test.js | 10 ++++-- backend/test/spark-api-submit-deals.test.js | 20 ++++++----- backend/test/test-helpers.js | 4 +-- db/index.js | 6 +++- package-lock.json | 38 +++++++++++++++++++++ package.json | 1 + tsconfig.json | 3 +- 17 files changed, 137 insertions(+), 31 deletions(-) diff --git a/api/test/test-helpers.js b/api/test/test-helpers.js index f8c4075..0e3387a 100644 --- a/api/test/test-helpers.js +++ b/api/test/test-helpers.js @@ -1,5 +1,9 @@ import { AssertionError } from 'node:assert' +/** + * @param {Response} res + * @param {number} status + */ export const assertResponseStatus = async (res, status) => { if (res.status !== status) { throw new AssertionError({ diff --git a/backend/bin/deal-observer-backend.js b/backend/bin/deal-observer-backend.js index dba0640..222c5c1 100644 --- a/backend/bin/deal-observer-backend.js +++ b/backend/bin/deal-observer-backend.js @@ -11,6 +11,7 @@ import { fetchDealWithHighestActivatedEpoch, countStoredActiveDeals, observeBuil import { indexPieces } from '../lib/piece-indexer.js' import { findAndSubmitUnsubmittedDeals, submitDealsToSparkApi } from '../lib/spark-api-submit-deals.js' import { getDealPayloadCid } from '../lib/piece-indexer-service.js' +/** @import {Queryable} from '@filecoin-station/deal-observer-db' */ const { INFLUXDB_TOKEN, @@ -37,6 +38,10 @@ assert(finalityEpochs <= maxPastEpochs) const pgPool = await createPgPool() const { recordTelemetry } = createInflux(INFLUXDB_TOKEN) +/** + * @param {(method:string,params:any[]) => Promise} makeRpcRequest + * @param {Queryable} pgPool + */ const observeActorEventsLoop = async (makeRpcRequest, pgPool) => { const LOOP_NAME = 'Observe actor events' while (true) { @@ -46,7 +51,7 @@ const observeActorEventsLoop = async (makeRpcRequest, pgPool) => { const lastInsertedDeal = await fetchDealWithHighestActivatedEpoch(pgPool) const startEpoch = Math.max( currentChainHead.Height - maxPastEpochs, - (lastInsertedDeal?.activated_at_epoch + 1) || 0 + lastInsertedDeal ? (lastInsertedDeal.activated_at_epoch ?? -1) + 1 : 0 ) const endEpoch = currentChainHead.Height - finalityEpochs @@ -57,7 +62,7 @@ const observeActorEventsLoop = async (makeRpcRequest, pgPool) => { const numberOfStoredDeals = await countStoredActiveDeals(pgPool) if (INFLUXDB_TOKEN) { recordTelemetry('observed_deals_stats', point => { - point.intField('last_searched_epoch', newLastInsertedDeal.activated_at_epoch) + point.intField('last_searched_epoch', newLastInsertedDeal?.activated_at_epoch || 0) point.intField('number_of_stored_active_deals', numberOfStoredDeals) }) } @@ -126,6 +131,11 @@ const sparkApiSubmitDealsLoop = async (pgPool, { sparkApiBaseUrl, sparkApiToken, } } +/** + * @param {(method:string,params:object) => object} makeRpcRequest + * @param {(providerId:string,pieceCid:string) => Promise} getDealPayloadCid + * @param {*} pgPool + */ export const pieceIndexerLoop = async (makeRpcRequest, getDealPayloadCid, pgPool) => { const LOOP_NAME = 'Piece Indexer' while (true) { diff --git a/backend/lib/deal-observer.js b/backend/lib/deal-observer.js index 6299c1d..05d1c5a 100644 --- a/backend/lib/deal-observer.js +++ b/backend/lib/deal-observer.js @@ -9,7 +9,7 @@ import { convertBlockEventToActiveDealDbEntry } from './utils.js' /** * @param {number} blockHeight * @param {Queryable} pgPool - * @param {(method:string,params:object) => object} makeRpcRequest + * @param {(method:string,params:any[]) => Promise} makeRpcRequest * @returns {Promise} */ export async function observeBuiltinActorEvents (blockHeight, pgPool, makeRpcRequest) { @@ -94,11 +94,11 @@ export async function storeActiveDeals (activeDeals, pgPool) { /** * @param {Queryable} pgPool * @param {string} query - * @param {Array} args + * @param {Array} args * @returns {Promise>>} */ export async function loadDeals (pgPool, query, args = []) { - const result = (await pgPool.query(query, args)).rows.map(deal => { + const result = (await pgPool.query(query, args)).rows.map((/** @type {any} */ deal) => { // SQL used null, typebox needs undefined for null values Object.keys(deal).forEach(key => { if (deal[key] === null) { diff --git a/backend/lib/rpc-service/data-types.js b/backend/lib/rpc-service/data-types.js index 0a219d4..8c8e2e7 100644 --- a/backend/lib/rpc-service/data-types.js +++ b/backend/lib/rpc-service/data-types.js @@ -38,10 +38,17 @@ const RpcRespone = Type.Object({ result: Type.Any() }) +const ChainHead = Type.Object({ + Height: Type.Number(), + Blocks: Type.Any(), + Cids: Type.Any() +}) + export { ClaimEvent, Entry, RawActorEvent, BlockEvent, - RpcRespone + RpcRespone, + ChainHead } diff --git a/backend/lib/rpc-service/service.js b/backend/lib/rpc-service/service.js index cd5e37d..ee9a339 100644 --- a/backend/lib/rpc-service/service.js +++ b/backend/lib/rpc-service/service.js @@ -4,7 +4,7 @@ import { encode as cborEncode } from '@ipld/dag-cbor' import { rawEventEntriesToEvent } from './utils.js' import { Value } from '@sinclair/typebox/value' import * as util from 'node:util' -import { ClaimEvent, RawActorEvent, BlockEvent, RpcRespone } from './data-types.js' +import { ClaimEvent, RawActorEvent, BlockEvent, RpcRespone, ChainHead } from './data-types.js' import pRetry from 'p-retry' /** @import { Static } from '@sinclair/typebox' */ @@ -40,8 +40,9 @@ export const rpcRequest = async (method, params) => { } } /** - * @param {object} actorEventFilter + * @param {{fromHeight:number,toHeight:number,fields: any}} actorEventFilter * Returns actor events filtered by the given actorEventFilter + * @param {(method: string, params: any[]) => Promise} makeRpcRequest * @returns {Promise>>} */ export async function getActorEvents (actorEventFilter, makeRpcRequest) { @@ -52,7 +53,7 @@ export async function getActorEvents (actorEventFilter, makeRpcRequest) { } // TODO: handle reverted events // https://github.com/filecoin-station/deal-observer/issues/22 - const typedRawEventEntries = rawEvents.map((rawEvent) => Value.Parse(RawActorEvent, rawEvent)) + const typedRawEventEntries = rawEvents.map((/** @type {any} */ rawEvent) => Value.Parse(RawActorEvent, rawEvent)) // An emitted event contains the height at which it was emitted, the emitter and the event itself const emittedEvents = [] for (const typedEventEntries of typedRawEventEntries) { @@ -81,10 +82,15 @@ export async function getActorEvents (actorEventFilter, makeRpcRequest) { /** * @param {function} makeRpcRequest - * @returns {Promise} + * @returns {Promise>} */ export async function getChainHead (makeRpcRequest) { - return await makeRpcRequest('Filecoin.ChainHead', []) + const result = await makeRpcRequest('Filecoin.ChainHead', []) + try { + return Value.Parse(ChainHead, result) + } catch (e) { + throw Error(util.format('Failed to parse chain head: %o', result)) + } } /** diff --git a/backend/lib/spark-api-submit-deals.js b/backend/lib/spark-api-submit-deals.js index 0b10718..79ed78e 100644 --- a/backend/lib/spark-api-submit-deals.js +++ b/backend/lib/spark-api-submit-deals.js @@ -7,7 +7,7 @@ import * as Sentry from '@sentry/node' * * @param {PgPool} pgPool * @param {number} batchSize - * @param {(eligibleDeals: Array) => Promise<{ingested: number; skipped: number}>} submitDeals + * @param {(eligibleDeals: Array) => Promise<{ingested: number; skipped: number}>} submitDeals * @returns {Promise<{submitted: number; ingested: number; skipped: number;}>} Number of deals submitted, ingested and skipped */ export const findAndSubmitUnsubmittedDeals = async (pgPool, batchSize, submitDeals) => { @@ -45,7 +45,7 @@ export const findAndSubmitUnsubmittedDeals = async (pgPool, batchSize, submitDea * * @param {PgPool} pgPool * @param {number} batchSize - * @returns {AsyncGenerator} + * @returns {AsyncGenerator>} */ const findUnsubmittedDeals = async function * (pgPool, batchSize) { const client = await pgPool.connect() @@ -82,7 +82,7 @@ const findUnsubmittedDeals = async function * (pgPool, batchSize) { * Mark deals as submitted. * * @param {Queryable} pgPool - * @param {Array} eligibleDeals + * @param {Array} eligibleDeals */ const markDealsAsSubmitted = async (pgPool, eligibleDeals) => { await pgPool.query(` @@ -112,7 +112,7 @@ const markDealsAsSubmitted = async (pgPool, eligibleDeals) => { * * @param {string} sparkApiBaseURL * @param {string} sparkApiToken - * @param {Array} deals + * @param {Array} deals * @returns {Promise<{ingested: number; skipped: number}>} */ export const submitDealsToSparkApi = async (sparkApiBaseURL, sparkApiToken, deals) => { diff --git a/backend/lib/telemetry.js b/backend/lib/telemetry.js index db3dd08..04ce457 100644 --- a/backend/lib/telemetry.js +++ b/backend/lib/telemetry.js @@ -3,6 +3,10 @@ import createDebug from 'debug' const debug = createDebug('spark:deal-observer:telemetry') +/** + * @param {string | undefined} token + * @returns {{influx: InfluxDB,recordTelemetry: (name: string, fn: (p: Point) => void) => void}} + */ export const createInflux = token => { const influx = new InfluxDB({ url: 'https://eu-central-1-1.aws.cloud2.influxdata.com', diff --git a/backend/package.json b/backend/package.json index 82469e6..ef950e9 100644 --- a/backend/package.json +++ b/backend/package.json @@ -9,6 +9,8 @@ "test": "node --test --test-reporter=spec --test-concurrency=1" }, "devDependencies": { + "@types/debug": "^4.1.12", + "@types/pg-cursor": "^2.7.2", "standard": "^17.1.2" }, "dependencies": { diff --git a/backend/test/deal-observer.test.js b/backend/test/deal-observer.test.js index e9f3261..366751b 100644 --- a/backend/test/deal-observer.test.js +++ b/backend/test/deal-observer.test.js @@ -5,8 +5,12 @@ import { fetchDealWithHighestActivatedEpoch, countStoredActiveDeals, loadDeals, import { Value } from '@sinclair/typebox/value' import { BlockEvent } from '../lib/rpc-service/data-types.js' import { convertBlockEventToActiveDealDbEntry } from '../lib/utils.js' +/** @import {PgPool} from '@filecoin-station/deal-observer-db' */ describe('deal-observer-backend', () => { + /** + * @type {PgPool} + */ let pgPool before(async () => { pgPool = await createPgPool() @@ -74,6 +78,9 @@ describe('deal-observer-backend', () => { }) it('check number of stored deals', async () => { + /** + * @param {{id:number,provider:number,client:number,pieceCid:string,pieceSize:bigint,termStart:number,termMin:number,termMax:number,sector:bigint}} eventData + */ const storeBlockEvent = async (eventData) => { const event = Value.Parse(BlockEvent, { height: 1, event: eventData, emitter: 'f06' }) const dbEntry = convertBlockEventToActiveDealDbEntry(event) diff --git a/backend/test/piece-indexer.test.js b/backend/test/piece-indexer.test.js index aa285d1..5483f2a 100644 --- a/backend/test/piece-indexer.test.js +++ b/backend/test/piece-indexer.test.js @@ -8,20 +8,29 @@ import assert from 'assert' import { minerPeerIds } from './test_data/minerInfo.js' import { payloadCIDs } from './test_data/payloadCIDs.js' import { indexPieces } from '../lib/piece-indexer.js' +/** @import {PgPool} from '@filecoin-station/deal-observer-db' */ describe('deal-observer-backend piece indexer', () => { + /** + * @param {string} method + * @param {any[]} params + * @returns + */ const makeRpcRequest = async (method, params) => { switch (method) { case 'Filecoin.ChainHead': return parse(JSON.stringify(chainHeadTestData)) case 'Filecoin.GetActorEventsRaw': - return parse(JSON.stringify(rawActorEventTestData)).filter(e => e.height >= params[0].fromHeight && e.height <= params[0].toHeight) + return parse(JSON.stringify(rawActorEventTestData)).filter((/** @type {{ height: number; }} */ e) => e.height >= params[0].fromHeight && e.height <= params[0].toHeight) case 'Filecoin.StateMinerInfo': return minerPeerIds.get(params[0]) default: console.error('Unknown method') } } + /** + * @type {PgPool} + */ let pgPool before(async () => { pgPool = await createPgPool() @@ -46,6 +55,11 @@ describe('deal-observer-backend piece indexer', () => { it('piece indexer loop function fetches deals where there exists no payload yet and updates the database entry', async (t) => { const getDealPayloadCidCalls = [] + /** + * @param {number} providerId + * @param {string} pieceCid + * @returns {Promise} + */ const getDealPayloadCid = async (providerId, pieceCid) => { getDealPayloadCidCalls.push({ providerId, pieceCid }) const payloadCid = payloadCIDs.get(JSON.stringify({ minerId: providerId, pieceCid })) diff --git a/backend/test/rpc-client.test.js b/backend/test/rpc-client.test.js index 9ab57e6..1335c07 100644 --- a/backend/test/rpc-client.test.js +++ b/backend/test/rpc-client.test.js @@ -8,12 +8,17 @@ import { ClaimEvent } from '../lib/rpc-service/data-types.js' import { Value } from '@sinclair/typebox/value' describe('RpcApiClient', () => { + /** + * @param {string} method + * @param {any[]} params + * @returns + */ const makeRpcRequest = async (method, params) => { switch (method) { case 'Filecoin.ChainHead': return parse(JSON.stringify(chainHeadTestData)) case 'Filecoin.GetActorEventsRaw': - return parse(JSON.stringify(rawActorEventTestData)).filter(e => e.height >= params[0].fromHeight && e.height <= params[0].toHeight) + return parse(JSON.stringify(rawActorEventTestData)).filter((/** @type {{ height: number; }} */ e) => e.height >= params[0].fromHeight && e.height <= params[0].toHeight) default: console.error('Unknown method') } @@ -23,7 +28,8 @@ describe('RpcApiClient', () => { const chainHead = await getChainHead(makeRpcRequest) assert(chainHead) const expected = parse(JSON.stringify(chainHeadTestData)) - assert.deepStrictEqual(chainHead, expected) + assert(chainHead.Height) + assert.deepStrictEqual(expected.Height, chainHead.Height) }) for (let blockHeight = 4622129; blockHeight < 4622129 + 11; blockHeight++) { diff --git a/backend/test/spark-api-submit-deals.test.js b/backend/test/spark-api-submit-deals.test.js index 741980e..93c2c24 100644 --- a/backend/test/spark-api-submit-deals.test.js +++ b/backend/test/spark-api-submit-deals.test.js @@ -3,8 +3,13 @@ import { after, before, beforeEach, describe, it, mock } from 'node:test' import { createPgPool, migrateWithPgClient } from '@filecoin-station/deal-observer-db' import { calculateActiveDealEpochs, daysAgo, daysFromNow, today } from './test-helpers.js' import { findAndSubmitUnsubmittedDeals } from '../lib/spark-api-submit-deals.js' +/** @import {PgPool} from '@filecoin-station/deal-observer-db' */ +/** @import {Queryable} from '@filecoin-station/deal-observer-db' */ describe('Submit deals to spark-api', () => { + /** + * @type {PgPool} + */ let pgPool before(async () => { @@ -91,6 +96,10 @@ describe('Submit deals to spark-api', () => { }) }) +/** + * @param {Queryable} pgPool + * @param {*} param1 + */ const givenActiveDeal = async (pgPool, { createdAt, startsAt, expiresAt, minerId = 2, clientId = 3, pieceCid = 'cidone', payloadCid = null }) => { const { activatedAtEpoch, termStart, termMin, termMax } = calculateActiveDealEpochs(createdAt, startsAt, expiresAt) await pgPool.query( @@ -103,12 +112,7 @@ const givenActiveDeal = async (pgPool, { createdAt, startsAt, expiresAt, minerId // TODO: allow callers of this helper to define how many deals should be reported as skipped const createSubmitEligibleDealsMock = () => { - return mock.fn( - // original - unused param - () => {}, - // implementation - async (deals) => { - return { ingested: deals.length, skipped: 0 } - } - ) + return mock.fn(async (deals) => { + return { ingested: deals.length, skipped: 0 } + }) } diff --git a/backend/test/test-helpers.js b/backend/test/test-helpers.js index 84370ad..d8c5f06 100644 --- a/backend/test/test-helpers.js +++ b/backend/test/test-helpers.js @@ -14,8 +14,8 @@ export const getLocalDayAsISOString = (d) => { export const today = () => getLocalDayAsISOString(new Date()) export const yesterday = () => getLocalDayAsISOString(new Date(Date.now() - 24 * 60 * 60 * 1000)) -export const daysAgo = (n) => getLocalDayAsISOString(new Date(Date.now() - n * 24 * 60 * 60 * 1000)) -export const daysFromNow = (n) => getLocalDayAsISOString(new Date(Date.now() + n * 24 * 60 * 60 * 1000)) +export const daysAgo = (/** @type {number} */ n) => getLocalDayAsISOString(new Date(Date.now() - n * 24 * 60 * 60 * 1000)) +export const daysFromNow = (/** @type {number} */ n) => getLocalDayAsISOString(new Date(Date.now() + n * 24 * 60 * 60 * 1000)) /** * Calculates activated at, term start, term min, and term max. diff --git a/db/index.js b/db/index.js index 752f8dd..3f734e2 100644 --- a/db/index.js +++ b/db/index.js @@ -33,7 +33,11 @@ const poolConfig = { maxLifetimeSeconds: 60 } -const onError = err => { +/** + * @param {Error} err + * @returns {void} + */ +const onError = (err) => { // Prevent crashing the process on idle client errors, the pool will recover // itself. If all connections are lost, the process will still crash. // https://github.com/brianc/node-postgres/issues/1324#issuecomment-308778405 diff --git a/package-lock.json b/package-lock.json index 0c90e66..0bffcdc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "devDependencies": { "@types/mocha": "^10.0.10", "@types/pg": "^8.11.11", + "@types/slug": "^5.0.9", "prettier": "^3.4.2", "standard": "^17.1.2", "typescript": "^5.7.3" @@ -54,6 +55,8 @@ "slug": "^10.0.0" }, "devDependencies": { + "@types/debug": "^4.1.12", + "@types/pg-cursor": "^2.7.2", "standard": "^17.1.2" } }, @@ -1240,6 +1243,16 @@ "@types/node": "*" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1254,6 +1267,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mysql": { "version": "2.15.26", "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", @@ -1283,6 +1303,17 @@ "pg-types": "^4.0.1" } }, + "node_modules/@types/pg-cursor": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/pg-cursor/-/pg-cursor-2.7.2.tgz", + "integrity": "sha512-m3xT8bVFCvx98LuzbvXyuCdT/Hjdd/v8ml4jL4K1QF70Y8clOfCFdgoaEB1FWdcSwcpoFYZTJQaMD9/GQ27efQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/pg": "*" + } + }, "node_modules/@types/pg-pool": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", @@ -1304,6 +1335,13 @@ "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", "license": "MIT" }, + "node_modules/@types/slug": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@types/slug/-/slug-5.0.9.tgz", + "integrity": "sha512-6Yp8BSplP35Esa/wOG1wLNKiqXevpQTEF/RcL/NV6BBQaMmZh4YlDwCgrrFSoUE4xAGvnKd5c+lkQJmPrBAzfQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/tedious": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", diff --git a/package.json b/package.json index 3da2cf6..48ad857 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "devDependencies": { "@types/mocha": "^10.0.10", "@types/pg": "^8.11.11", + "@types/slug": "^5.0.9", "prettier": "^3.4.2", "standard": "^17.1.2", "typescript": "^5.7.3" diff --git a/tsconfig.json b/tsconfig.json index 04bbb8d..8af993b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,8 +12,7 @@ "isolatedModules": true, "verbatimModuleSyntax": true, - // TODO - // "strict": true, + "strict": true, "forceConsistentCasingInFileNames": true, "declaration": true, From f3621d6df03e8ad8e28d65d5edd56ee7f79001ec Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Tue, 4 Feb 2025 10:41:27 +0000 Subject: [PATCH 2/5] moved slug --- backend/package.json | 1 + package-lock.json | 2 +- package.json | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/package.json b/backend/package.json index ef950e9..a20b0ea 100644 --- a/backend/package.json +++ b/backend/package.json @@ -11,6 +11,7 @@ "devDependencies": { "@types/debug": "^4.1.12", "@types/pg-cursor": "^2.7.2", + "@types/slug": "^5.0.9", "standard": "^17.1.2" }, "dependencies": { diff --git a/package-lock.json b/package-lock.json index 0bffcdc..14d7689 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,6 @@ "devDependencies": { "@types/mocha": "^10.0.10", "@types/pg": "^8.11.11", - "@types/slug": "^5.0.9", "prettier": "^3.4.2", "standard": "^17.1.2", "typescript": "^5.7.3" @@ -57,6 +56,7 @@ "devDependencies": { "@types/debug": "^4.1.12", "@types/pg-cursor": "^2.7.2", + "@types/slug": "^5.0.9", "standard": "^17.1.2" } }, diff --git a/package.json b/package.json index 48ad857..3da2cf6 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "devDependencies": { "@types/mocha": "^10.0.10", "@types/pg": "^8.11.11", - "@types/slug": "^5.0.9", "prettier": "^3.4.2", "standard": "^17.1.2", "typescript": "^5.7.3" From ca64e6d4916081ef94639b9530c4638e478d7dcb Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Tue, 4 Feb 2025 10:57:35 +0000 Subject: [PATCH 3/5] fmt --- backend/lib/rpc-service/utils.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/lib/rpc-service/utils.js b/backend/lib/rpc-service/utils.js index 3d54b8e..75655d6 100644 --- a/backend/lib/rpc-service/utils.js +++ b/backend/lib/rpc-service/utils.js @@ -2,6 +2,10 @@ import { base64pad } from 'multiformats/bases/base64' import { decode as cborDecode } from '@ipld/dag-cbor' import * as util from 'node:util' +/** + * @param {string} data + * @returns + */ const decodeCborInBase64 = (data) => { return cborDecode(base64pad.baseDecode(data)) } @@ -14,6 +18,7 @@ const decodeCborInBase64 = (data) => { */ const rawEventEntriesToEvent = (rawEventEntries) => { // Each event is defined by a list of event entries which will parsed into a typed event + /** @type {Record} */ const event = {} let eventType for (const entry of rawEventEntries) { From a2f4e92b0589be1e71036c63cd252ad4ee5224a5 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Tue, 4 Feb 2025 12:59:17 +0000 Subject: [PATCH 4/5] use clam event --- backend/test/deal-observer.test.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/test/deal-observer.test.js b/backend/test/deal-observer.test.js index 366751b..3eb097b 100644 --- a/backend/test/deal-observer.test.js +++ b/backend/test/deal-observer.test.js @@ -3,9 +3,10 @@ import { after, before, beforeEach, describe, it } from 'node:test' import { createPgPool, migrateWithPgClient } from '@filecoin-station/deal-observer-db' import { fetchDealWithHighestActivatedEpoch, countStoredActiveDeals, loadDeals, storeActiveDeals } from '../lib/deal-observer.js' import { Value } from '@sinclair/typebox/value' -import { BlockEvent } from '../lib/rpc-service/data-types.js' +import { BlockEvent, ClaimEvent } from '../lib/rpc-service/data-types.js' import { convertBlockEventToActiveDealDbEntry } from '../lib/utils.js' /** @import {PgPool} from '@filecoin-station/deal-observer-db' */ +/** @import { Static } from '@sinclair/typebox' */ describe('deal-observer-backend', () => { /** @@ -79,14 +80,14 @@ describe('deal-observer-backend', () => { it('check number of stored deals', async () => { /** - * @param {{id:number,provider:number,client:number,pieceCid:string,pieceSize:bigint,termStart:number,termMin:number,termMax:number,sector:bigint}} eventData + * @param {Static} eventData */ const storeBlockEvent = async (eventData) => { const event = Value.Parse(BlockEvent, { height: 1, event: eventData, emitter: 'f06' }) const dbEntry = convertBlockEventToActiveDealDbEntry(event) await storeActiveDeals([dbEntry], pgPool) } - const data = { + const data = Value.Parse(ClaimEvent, { id: 1, provider: 2, client: 3, @@ -96,7 +97,7 @@ describe('deal-observer-backend', () => { termMin: 12340, termMax: 12340, sector: 6n - } + }) assert.strictEqual(await countStoredActiveDeals(pgPool), 0n) await storeBlockEvent(data) assert.strictEqual(await countStoredActiveDeals(pgPool), 1n) From 686113097a55be7a3c758730d3eb1ab247acec4e Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Wed, 5 Feb 2025 08:21:09 +0000 Subject: [PATCH 5/5] fmt --- backend/test/spark-api-submit-deals.test.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/test/spark-api-submit-deals.test.js b/backend/test/spark-api-submit-deals.test.js index 93c2c24..aa2a98e 100644 --- a/backend/test/spark-api-submit-deals.test.js +++ b/backend/test/spark-api-submit-deals.test.js @@ -98,7 +98,15 @@ describe('Submit deals to spark-api', () => { /** * @param {Queryable} pgPool - * @param {*} param1 + * @param {Object} activeDeal + * @param {string} activeDeal.createdAt + * @param {string} activeDeal.startsAt + * @param {string} activeDeal.expiresAt + * @param {number} [activeDeal.minerId=2] + * @param {number} [activeDeal.clientId=3] + * @param {string} [activeDeal.pieceCid='cidone'] + * @param {string | null} [activeDeal.payloadCid=null] + * @returns {Promise} */ const givenActiveDeal = async (pgPool, { createdAt, startsAt, expiresAt, minerId = 2, clientId = 3, pieceCid = 'cidone', payloadCid = null }) => { const { activatedAtEpoch, termStart, termMin, termMax } = calculateActiveDealEpochs(createdAt, startsAt, expiresAt)