import worker from "node:worker_threads";
import { Transfer, expose } from "@chainsafe/threads/worker";
import { chainConfigFromJson, createBeaconConfig } from "@lodestar/config";
import { LevelDbController } from "@lodestar/db/controller/level";
import { getNodeLogger } from "@lodestar/logger/node";
import { createPubkeyCache } from "@lodestar/state-transition";
import { BeaconDb } from "../../../db/index.js";
import { RegistryMetricCreator, collectNodeJSMetrics } from "../../../metrics/index.js";
import { JobFnQueue } from "../../../util/queue/fnQueue.js";
import { getHistoricalState } from "./getHistoricalState.js";
import { createHistoricalStateQueueMetrics, createHistoricalStateRegenMetrics, } from "./metrics.js";
// most of this setup copied from networkCoreWorker.ts
const workerData = worker.workerData;
const logger = getNodeLogger(workerData.loggerOpts);
logger.info("Historical state worker started");
const config = createBeaconConfig(chainConfigFromJson(workerData.chainConfigJson), workerData.genesisValidatorsRoot);
const db = new BeaconDb(config, await LevelDbController.create({ name: workerData.dbLocation }, { logger }));
const abortController = new AbortController();
// Set up metrics, nodejs, state transition, queue
const metricsRegister = workerData.metricsEnabled ? new RegistryMetricCreator() : null;
let historicalStateRegenMetrics;
let queueMetrics;
if (metricsRegister) {
    const closeMetrics = collectNodeJSMetrics(metricsRegister, "lodestar_historical_state_worker_");
    abortController.signal.addEventListener("abort", closeMetrics, { once: true });
    historicalStateRegenMetrics = createHistoricalStateRegenMetrics(metricsRegister);
    queueMetrics = createHistoricalStateQueueMetrics(metricsRegister);
}
const queue = new JobFnQueue({
    maxConcurrency: workerData.maxConcurrency,
    maxLength: workerData.maxLength,
    signal: abortController.signal,
}, queueMetrics);
const pubkeyCache = createPubkeyCache();
const api = {
    async close() {
        abortController.abort();
    },
    async scrapeMetrics() {
        return metricsRegister?.metrics() ?? "";
    },
    async getHistoricalState(slot) {
        historicalStateRegenMetrics?.regenRequestCount.inc();
        const stateBytes = await queue.push(() => getHistoricalState(slot, config, db, pubkeyCache, historicalStateRegenMetrics));
        const result = Transfer(stateBytes, [stateBytes.buffer]);
        historicalStateRegenMetrics?.regenSuccessCount.inc();
        return result;
    },
};
expose(api);
//# sourceMappingURL=worker.js.map