@eclesia/indexer-engine 2.13.0 → 2.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,12 @@
1
1
  const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
2
  const require_constants = require('../constants.cjs');
3
3
  const require_index = require('../emitter/index.cjs');
4
- const require_index$1 = require('../metrics/index.cjs');
5
- const require_index$2 = require('../promise-queue/index.cjs');
4
+ const require_index$1 = require('../errors/index.cjs');
5
+ const require_index$2 = require('../metrics/index.cjs');
6
+ const require_index$3 = require('../promise-queue/index.cjs');
6
7
  const require_text = require('../utils/text.cjs');
7
8
  require('../utils/index.cjs');
8
- const require_index$4 = require('../validation/index.cjs');
9
+ const require_index$5 = require('../validation/index.cjs');
9
10
  let crypto = require("crypto");
10
11
  let fs = require("fs");
11
12
  fs = require_rolldown_runtime.__toESM(fs);
@@ -95,13 +96,13 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
95
96
  */
96
97
  constructor(config) {
97
98
  super();
98
- require_index$4.validateUrl(config.rpcUrl, "rpcUrl");
99
- require_index$4.validatePositiveInteger(config.batchSize, "batchSize");
100
- if (config.genesisPath) require_index$4.validateFilePath(config.genesisPath, "genesisPath");
101
- if (config.healthCheckPort !== void 0) require_index$4.validatePort(config.healthCheckPort, "healthCheckPort");
102
- if (config.prometheusPort !== void 0) require_index$4.validatePort(config.prometheusPort, "prometheusPort");
103
- if (config.startHeight !== void 0) require_index$4.validatePositiveInteger(config.startHeight, "startHeight");
104
- if (config.pollingInterval !== void 0) require_index$4.validatePositiveInteger(config.pollingInterval, "pollingInterval");
99
+ require_index$5.validateUrl(config.rpcUrl, "rpcUrl");
100
+ require_index$5.validatePositiveInteger(config.batchSize, "batchSize");
101
+ if (config.genesisPath) require_index$5.validateFilePath(config.genesisPath, "genesisPath");
102
+ if (config.healthCheckPort !== void 0) require_index$5.validatePort(config.healthCheckPort, "healthCheckPort");
103
+ if (config.prometheusPort !== void 0) require_index$5.validatePort(config.prometheusPort, "prometheusPort");
104
+ if (config.startHeight !== void 0) require_index$5.validatePositiveInteger(config.startHeight, "startHeight");
105
+ if (config.pollingInterval !== void 0) require_index$5.validatePositiveInteger(config.pollingInterval, "pollingInterval");
105
106
  this.config = {
106
107
  ...defaultIndexerConfig,
107
108
  ...config
@@ -126,8 +127,8 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
126
127
  this.prometheus?.recordError("rpc");
127
128
  this.log.error("Error enqueueing block data: " + e);
128
129
  };
129
- if (this.config.minimal) this.blockQueue = new require_index$2.CircularBuffer(this.config.batchSize, queueErrorHandler);
130
- else this.blockQueue = new require_index$2.CircularBuffer(this.config.batchSize, queueErrorHandler);
130
+ if (this.config.minimal) this.blockQueue = new require_index$3.CircularBuffer(this.config.batchSize, queueErrorHandler);
131
+ else this.blockQueue = new require_index$3.CircularBuffer(this.config.batchSize, queueErrorHandler);
131
132
  this.on("_unhandled", (msg) => {
132
133
  if (msg.uuid) {
133
134
  this.log.verbose("Unhandled event: " + msg.type);
@@ -138,7 +139,7 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
138
139
  }
139
140
  });
140
141
  if (this.config.enablePrometheus) {
141
- this.prometheus = new require_index$1.IndexerMetrics();
142
+ this.prometheus = new require_index$2.IndexerMetrics();
142
143
  this.prometheusServer = (0, fastify.default)({ logger: false });
143
144
  this.prometheusServer.get("/metrics", async (_req, res) => {
144
145
  res.header("Content-Type", this.prometheus.registry.contentType);
@@ -199,9 +200,12 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
199
200
  this.blockClient.disconnect();
200
201
  this.log.verbose("Disconnected from RPC");
201
202
  }
202
- this.client = await (0, __cosmjs_tendermint_rpc.connectComet)(this.config.rpcUrl);
203
+ const connectTimeoutPromise = new Promise((resolve, reject) => {
204
+ setTimeout(reject, require_constants.CONNECT_TIMEOUT_MS, []);
205
+ });
206
+ this.client = await Promise.race([(0, __cosmjs_tendermint_rpc.connectComet)(this.config.rpcUrl), connectTimeoutPromise]);
203
207
  this.log.info("Connected to RPC for ad hoc queries");
204
- this.blockClient = await (0, __cosmjs_tendermint_rpc.connectComet)(this.config.rpcUrl);
208
+ this.blockClient = await Promise.race([(0, __cosmjs_tendermint_rpc.connectComet)(this.config.rpcUrl), connectTimeoutPromise]);
205
209
  this.log.info("Connected to RPC for block & validator info");
206
210
  return true;
207
211
  } catch (error) {
@@ -211,15 +215,7 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
211
215
  return false;
212
216
  }
213
217
  }
214
- stop() {
215
- this.started = false;
216
- }
217
- async start() {
218
- this.started = true;
219
- if (this.blockQueue) {
220
- this.blockQueue.clear();
221
- this.log.verbose("Starting, clearing block queue");
222
- }
218
+ async initialize() {
223
219
  if (!this.initialized) {
224
220
  try {
225
221
  if (this.config.init) await this.config.init();
@@ -239,18 +235,32 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
239
235
  }
240
236
  this.initialized = true;
241
237
  }
238
+ }
239
+ stop() {
240
+ this.started = false;
241
+ }
242
+ clearBlockQueue() {
243
+ if (this.blockQueue) {
244
+ this.blockQueue.clear();
245
+ this.log.verbose("Starting, clearing block queue");
246
+ }
247
+ }
248
+ async setupBlockListening() {
249
+ if (!await this.connect()) {
250
+ this.setStatus("FAILED");
251
+ throw new require_index$1.RPCError("Failed to connect to RPC");
252
+ }
242
253
  try {
243
- const connectTimeoutPromise = new Promise((resolve, reject) => {
244
- setTimeout(reject, require_constants.QUEUE_DEQUEUE_TIMEOUT_MS, []);
245
- });
246
- await Promise.race([this.connect(), connectTimeoutPromise]);
247
254
  if (!this.config.usePolling && this.subscription) {
248
255
  this.subscription.removeListener(this.blockListener);
249
256
  this.subscription = null;
250
257
  this.log.verbose("Removed existing block listener and subscription");
251
258
  }
252
259
  if (!this.config.usePolling) this.subscription = this.client.subscribeNewBlock ? this.client.subscribeNewBlock() : null;
253
- this.latestHeight = (await this.client.status()).syncInfo.latestBlockHeight;
260
+ const statusPromise = new Promise((resolve, reject) => {
261
+ setTimeout(reject, require_constants.RPC_TIMEOUT_MS, false);
262
+ });
263
+ this.latestHeight = (await Promise.race([this.client.status(), statusPromise])).syncInfo.latestBlockHeight;
254
264
  this.log.info("Current chain height: " + this.latestHeight);
255
265
  this.heightToProcess = await this.config.getNextHeight();
256
266
  if (this.config.usePolling) this.pollForBlock();
@@ -265,19 +275,24 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
265
275
  this.setStatus("FAILED");
266
276
  throw e;
267
277
  }
268
- this.log.debug("Starting main processing loop");
269
- this.tryToRecover = false;
270
- this.fetcher().catch((e) => {
271
- this.setStatus("FAILED");
272
- this.prometheus?.recordError("rpc");
273
- throw new Error("Error in fetching service: " + e);
274
- });
275
- const hrTime = process.hrtime();
276
- let ms = hrTime[0] * 1e6 + hrTime[1] / 1e3;
277
- while (this.blockQueue.size() > 0 && !this.tryToRecover && this.started && (this.config.endHeight === void 0 || this.heightToProcess <= this.config.endHeight)) {
278
- if (this.config.enablePrometheus) this.prometheus.updateRetryCount(this.retryCount);
278
+ }
279
+ async start() {
280
+ this.started = true;
281
+ this.clearBlockQueue();
282
+ await this.initialize();
283
+ try {
284
+ await this.setupBlockListening();
285
+ this.log.debug("Starting main processing loop");
286
+ this.tryToRecover = false;
287
+ this.fetcher().catch((e) => {
288
+ this.setStatus("FAILED");
289
+ this.prometheus?.recordError("rpc");
290
+ throw new Error("Error in fetching service: " + e);
291
+ });
292
+ } catch (_e) {}
293
+ while (this.started && !this.tryToRecover && (this.config.endHeight === void 0 || this.heightToProcess <= this.config.endHeight) && this.blockQueue.size() > 0) {
279
294
  try {
280
- if (this.tryToRecover) throw new Error("Exiting processing loop. Attempting to recover indexer");
295
+ this.prometheus?.updateRetryCount(this.retryCount);
281
296
  await this.config.beginTransaction();
282
297
  this.log.silly("Started db tx");
283
298
  let height, timestamp;
@@ -287,10 +302,7 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
287
302
  });
288
303
  const toProcess = await Promise.race([this.blockQueue.dequeue(), timeoutPromise]);
289
304
  this.log.silly("Retrieved block data");
290
- if (!toProcess || !toProcess[0] || !toProcess[1]) {
291
- this.prometheus?.recordError("rpc");
292
- throw new Error("Could not fetch block");
293
- }
305
+ if (!toProcess || !toProcess[0] || !toProcess[1]) throw new require_index$1.RPCError("Could not fetch block(minimal)");
294
306
  height = toProcess[0].block.header.height;
295
307
  timestamp = (0, __cosmjs_tendermint_rpc.toRfc3339WithNanoseconds)(toProcess[0].block.header.time);
296
308
  await this.processBlock(toProcess[0], toProcess[1]);
@@ -300,34 +312,23 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
300
312
  });
301
313
  const toProcess = await Promise.race([this.blockQueue.dequeue(), timeoutPromise]);
302
314
  this.log.silly("Retrieved block data");
303
- if (!toProcess || !toProcess[0] || !toProcess[1] || !toProcess[2]) {
304
- this.prometheus?.recordError("rpc");
305
- throw new Error("Could not fetch block");
306
- }
315
+ if (!toProcess || !toProcess[0] || !toProcess[1] || !toProcess[2]) throw new require_index$1.RPCError("Could not fetch block(full)");
307
316
  this.log.silly("Decoded block");
308
317
  height = toProcess[0].block.header.height;
309
318
  timestamp = (0, __cosmjs_tendermint_rpc.toRfc3339WithNanoseconds)(toProcess[0].block.header.time);
310
319
  await this.processBlock(toProcess[0], toProcess[1], cosmjs_types_cosmos_staking_v1beta1_query_js.QueryValidatorsResponse.decode(toProcess[2]).validators);
311
320
  }
312
- if (height % require_constants.PERIODIC_INTERVALS.LARGE == 0) {
313
- const hrTime$1 = process.hrtime();
314
- const newms = hrTime$1[0] * 1e6 + hrTime$1[1] / 1e3;
315
- const duration = newms - ms;
316
- ms = newms;
317
- const rate = 1e9 / duration;
318
- this.log.info("Processing:" + rate.toFixed(2) + "blocks/sec");
319
- await this.asyncEmit("periodic/1000", {
320
- value: null,
321
- height,
322
- timestamp
323
- });
324
- }
325
- if (height % require_constants.PERIODIC_INTERVALS.MEDIUM == 0) await this.asyncEmit("periodic/100", {
321
+ if (height % require_constants.PERIODIC_INTERVALS.LARGE == 0) await this.asyncEmit("periodic/large", {
326
322
  value: null,
327
323
  height,
328
324
  timestamp
329
325
  });
330
- if (height % require_constants.PERIODIC_INTERVALS.SMALL == 0) await this.asyncEmit("periodic/50", {
326
+ if (height % require_constants.PERIODIC_INTERVALS.MEDIUM == 0) await this.asyncEmit("periodic/medium", {
327
+ value: null,
328
+ height,
329
+ timestamp
330
+ });
331
+ if (height % require_constants.PERIODIC_INTERVALS.SMALL == 0) await this.asyncEmit("periodic/small", {
331
332
  value: null,
332
333
  height,
333
334
  timestamp
@@ -352,12 +353,18 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
352
353
  this.retryCount = 0;
353
354
  this.setStatus("OK");
354
355
  }
356
+ if (!this.started) {
357
+ this.log.info("Indexer manually stopped.");
358
+ return;
359
+ }
355
360
  if (this.config.endHeight !== void 0 && this.heightToProcess >= this.config.endHeight) {
356
361
  this.log.info("Reached configured end height. Stopping indexer.");
357
362
  this.stop();
363
+ return;
358
364
  }
359
- if (this.started) if (this.retryCount < 3) {
365
+ if (this.retryCount < 3) {
360
366
  this.log.debug("Indexer retryCount: " + this.retryCount);
367
+ this.retryCount++;
361
368
  this.log.info("Indexer is restarting");
362
369
  setTimeout(() => this.start(), this.retryCount * 5e3);
363
370
  } else {
@@ -390,10 +397,7 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
390
397
  return prom;
391
398
  };
392
399
  async processBlock(block, block_results, validators) {
393
- let processStart = [0, 0];
394
- if (this.config.logLevel == "silly") processStart = process.hrtime();
395
- let endTimer;
396
- if (this.config.enablePrometheus) endTimer = this.prometheus.timeBlockProcessing();
400
+ const endTimer = this.prometheus?.timeBlockProcessing();
397
401
  const height = block.block.header.height;
398
402
  this.heightToProcess = height;
399
403
  this.log.debug("Processing block: %d", height);
@@ -500,28 +504,23 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
500
504
  }
501
505
  }
502
506
  this.log.silly("Modules handled msg events");
503
- if (this.config.enablePrometheus) this.prometheus.recordTransactions(block.block.txs.length);
507
+ this.prometheus?.recordTransactions(block.block.txs.length);
504
508
  await this.asyncEmit("end_block", {
505
509
  value: endBlockEvents,
506
510
  height,
507
511
  timestamp
508
512
  });
509
513
  this.log.silly("Modules handled end_block events");
510
- if (this.config.logLevel == "silly") {
511
- const processEnd = process.hrtime(processStart);
512
- const processTime = processEnd[0] * 1e3 + processEnd[1] / 1e6;
513
- this.log.silly("Processed block %d in %d ms", height, processTime.toFixed(2));
514
- }
515
- if (this.config.enablePrometheus) endTimer();
516
- if (this.config.enablePrometheus) this.prometheus.updateBlockMetrics(height, this.latestHeight, this.blockQueue.size());
514
+ endTimer?.();
515
+ this.prometheus?.updateBlockMetrics(height, this.latestHeight, this.blockQueue.size());
517
516
  }
518
517
  async fetcher() {
519
518
  for (let i = this.heightToProcess; i <= this.latestHeight; i++) {
520
- this.log.debug("Fetching: " + i);
521
519
  if (this.tryToRecover) {
522
520
  this.log.verbose("Exiting fetcher loop. Attempting to recover indexer");
523
521
  break;
524
522
  }
523
+ this.log.debug("Fetching: " + i);
525
524
  try {
526
525
  if (this.isMinimal(this.blockQueue)) {
527
526
  const timeoutPromise = new Promise((resolve, reject) => {
@@ -551,15 +550,15 @@ var EcleciaIndexer = class extends require_index.EclesiaEmitter {
551
550
  });
552
551
  this.blockQueue.enqueue(toIndex);
553
552
  }
554
- await this.blockQueue.continue();
555
- if (this.tryToRecover) {
556
- this.retryCount++;
557
- throw new Error("RPC not responding");
558
- }
559
553
  } catch (e) {
560
554
  this.log.error("Fetching error: " + e);
561
555
  break;
562
556
  }
557
+ await this.blockQueue.continue();
558
+ if (this.tryToRecover) {
559
+ this.log.verbose("Exiting fetcher loop. Attempting to recover indexer");
560
+ break;
561
+ }
563
562
  }
564
563
  if (!this.tryToRecover) {
565
564
  this.blockQueue.setSynced();
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["DEFAULT_START_HEIGHT","DEFAULT_BATCH_SIZE","DEFAULT_POLLING_INTERVAL_MS","DEFAULT_HEALTH_CHECK_PORT","DEFAULT_PROMETHEUS_PORT","EclesiaEmitter","CircularBuffer","IndexerMetrics","connectTimeoutPromise: ReturnType<typeof this.connect>","QUEUE_DEQUEUE_TIMEOUT_MS","timeoutPromise: ReturnType<typeof this.blockQueue.dequeue>","QueryValidatorsResponse","PERIODIC_INTERVALS","hrTime","processStart: [number, number]","beginBlockEvents: readonly Event[] | readonly Event38[]","endBlockEvents: readonly Event[] | readonly Event38[]","decodeAttr","Tx","events: Array<{\n msg_index?: number\n events: (Event | Event38)[]\n }>","eventsToAdd: typeof events","MsgExec","events","timeoutPromise: Promise<[BlockResponse, BlockResultsResponse]>","RPC_TIMEOUT_MS","timeoutPromise: Promise<[BlockResponse, BlockResultsResponse, Uint8Array]>","QueryValidatorsRequest","PAGINATION_LIMITS","Parser","Pick","StreamArray","Batch","GENESIS_BATCH_SIZE","StreamValues"],"sources":["../../src/indexer/index.ts"],"sourcesContent":["/* eslint-disable @stylistic/no-multi-spaces */\n/* eslint-disable max-lines */\nimport {\n createHash,\n} from \"node:crypto\";\nimport * as fs from \"node:fs\";\n\nimport {\n BlockResponse, BlockResultsResponse, CometClient, connectComet, Event, toRfc3339WithNanoseconds,\n} from \"@cosmjs/tendermint-rpc\";\nimport {\n BlockResultsResponse as BlockResultsResponse38, Event as Event38,\n} from \"@cosmjs/tendermint-rpc/build/comet38/responses.js\";\nimport {\n MsgExec,\n} from \"cosmjs-types/cosmos/authz/v1beta1/tx.js\";\nimport {\n QueryValidatorsRequest,\n QueryValidatorsResponse,\n} from \"cosmjs-types/cosmos/staking/v1beta1/query.js\";\nimport {\n Validator,\n} from \"cosmjs-types/cosmos/staking/v1beta1/staking.js\";\nimport {\n Tx,\n} from \"cosmjs-types/cosmos/tx/v1beta1/tx.js\";\nimport Fastify, {\n FastifyInstance,\n} from \"fastify\";\nimport {\n chain,\n} from \"stream-chain\";\nimport Parser from \"stream-json\";\nimport Pick from \"stream-json/filters/Pick.js\";\nimport StreamArray from \"stream-json/streamers/StreamArray.js\";\nimport StreamValues from \"stream-json/streamers/StreamValues.js\";\nimport Batch from \"stream-json/utils/Batch.js\";\nimport {\n v4 as uuidv4,\n} from \"uuid\";\nimport * as winston from \"winston\";\n\nimport {\n DEFAULT_BATCH_SIZE, DEFAULT_HEALTH_CHECK_PORT, DEFAULT_POLLING_INTERVAL_MS, DEFAULT_PROMETHEUS_PORT, DEFAULT_START_HEIGHT,\n GENESIS_BATCH_SIZE, PAGINATION_LIMITS, PERIODIC_INTERVALS, QUEUE_DEQUEUE_TIMEOUT_MS, RPC_TIMEOUT_MS,\n} from \"../constants.js\";\nimport {\n EclesiaEmitter,\n} from \"../emitter/index.js\";\nimport {\n IndexerMetrics,\n} from \"../metrics/index.js\";\nimport {\n CircularBuffer,\n} from \"../promise-queue/index.js\";\nimport {\n BlockQueue, EcleciaIndexerConfig, EmitFunc, MinimalBlockQueue,\n UUIDEvent, WithHeightAndUUID,\n} from \"../types/index.js\";\nimport {\n decodeAttr,\n} from \"../utils/index.js\";\nimport {\n validateFilePath, validatePort, validatePositiveInteger, validateUrl,\n} from \"../validation/index.js\";\n\n/** Default configuration for the Eclesia indexer */\nexport const defaultIndexerConfig = {\n startHeight: DEFAULT_START_HEIGHT, // Start indexing from block 1\n batchSize: DEFAULT_BATCH_SIZE, // Process blocks in batches of 500\n modules: [], // No modules enabled by default\n getNextHeight: () => DEFAULT_START_HEIGHT, // Default height retrieval function\n logLevel: \"info\" as EcleciaIndexerConfig[\"logLevel\"], // Default log level\n usePolling: false, // Use WebSocket subscription by default\n pollingInterval: DEFAULT_POLLING_INTERVAL_MS, // Poll every 5 seconds when polling enabled\n shouldProcessGenesis: () => false, // Skip genesis processing by default\n minimal: true, // Use minimal indexing by default\n enableHealthcheck: true, // Enable health check server by default\n healthCheckPort: DEFAULT_HEALTH_CHECK_PORT, // Default health check port\n enablePrometheus: false, // Disable Prometheus metrics server by default\n prometheusPort: DEFAULT_PROMETHEUS_PORT, // Default Prometheus metrics server port\n init: () => Promise.resolve(), // No-op initialization function\n beginTransaction: () => Promise.resolve(), // No-op transaction begin function\n endTransaction: (_status: boolean) => Promise.resolve(), // No-op transaction end function\n};\n\n/**\n * Core blockchain indexer that connects to Tendermint RPC and processes blocks\n * Extends EclesiaEmitter to provide event-driven architecture for modules\n */\nexport class EcleciaIndexer extends EclesiaEmitter {\n /** Indexer configuration settings */\n public config: EcleciaIndexerConfig;\n\n /** Fastify HTTP server for health checks */\n private fastify: FastifyInstance | null = null;\n\n /** Prometheus HTTP server instance */\n private prometheusServer: FastifyInstance | null = null;\n\n /** Indicates if the indexer has started */\n private started: boolean = false;\n\n /** Queue for managing block processing pipeline */\n private blockQueue: BlockQueue;\n\n /** Latest block height from the chain */\n private latestHeight!: number;\n\n /** Next block height to process */\n public heightToProcess!: number;\n\n /** Whether the indexer has been initialized */\n private initialized = false;\n\n /** Prometheus metrics server instance */\n public prometheus: IndexerMetrics | null = null;\n\n /** Number of retry attempts for error recovery */\n private retryCount = 0;\n\n /** CometBFT client for ad-hoc queries */\n public client!: CometClient;\n\n /** CometBFT client for block and validator queries */\n public blockClient!: CometClient;\n\n /** Winston logger instance */\n public log: winston.Logger;\n\n /** Flag indicating if indexer should attempt recovery */\n private tryToRecover: boolean = false;\n\n /** Health check status for monitoring */\n private healthCheck = {\n status: \"CONNECTING\",\n };\n\n /** WebSocket subscription for new block notifications */\n private subscription: ReturnType<CometClient[\"subscribeNewBlock\"]> | null = null;\n\n /** Timeout handler for block reception */\n private blockTimeout: NodeJS.Timeout | null = null;\n\n /**\n * Creates a new Eclesia indexer instance\n * @param config - Indexer configuration options\n */\n constructor(config: EcleciaIndexerConfig) {\n super();\n\n // Validate required configuration\n validateUrl(config.rpcUrl, \"rpcUrl\");\n validatePositiveInteger(config.batchSize, \"batchSize\");\n\n // Validate optional genesis path if processing genesis\n if (config.genesisPath) {\n validateFilePath(config.genesisPath, \"genesisPath\");\n }\n\n // Validate health check port if provided\n if (config.healthCheckPort !== undefined) {\n validatePort(config.healthCheckPort, \"healthCheckPort\");\n }\n\n // Validate prometheus port if provided\n if (config.prometheusPort !== undefined) {\n validatePort(config.prometheusPort, \"prometheusPort\");\n }\n\n // Validate start height if provided\n if (config.startHeight !== undefined) {\n validatePositiveInteger(config.startHeight, \"startHeight\");\n }\n\n // Validate polling interval if provided\n if (config.pollingInterval !== undefined) {\n validatePositiveInteger(config.pollingInterval, \"pollingInterval\");\n }\n\n this.config = {\n ...defaultIndexerConfig,\n ...config,\n };\n\n // Initialize logger first so it can be used by queue error handler\n const {\n printf,\n } = winston.format;\n\n const eclesiaFormat = printf(({\n level, message, timestamp,\n }) => {\n return `${timestamp} [${level.toUpperCase()}]:\\t${message}`;\n });\n this.log = winston.createLogger({\n level: this.config.logLevel,\n defaultMeta: {\n service: \"Eclesia Indexer\",\n },\n transports: [\n new winston.transports.File({\n filename: \"error.log\",\n level: \"error\",\n }),\n new winston.transports.File({\n filename: \"combined.log\",\n }),\n new winston.transports.Console({\n format: winston.format.combine(winston.format.splat(),\n winston.format.timestamp(),\n eclesiaFormat,\n winston.format.colorize({\n all: true,\n })),\n }),\n ],\n });\n\n // Initialize block queue based on minimal or full indexing mode\n // Pass error handler that uses the logger\n const queueErrorHandler = (e: unknown) => {\n this.prometheus?.recordError(\"rpc\");\n this.log.error(\"Error enqueueing block data: \" + e);\n };\n\n if (this.config.minimal) {\n // Minimal mode: only store block and block results\n this.blockQueue = new CircularBuffer<[BlockResponse, BlockResultsResponse]>(this.config.batchSize, queueErrorHandler);\n }\n else {\n // Full mode: also store validator information\n this.blockQueue = new CircularBuffer<[BlockResponse, BlockResultsResponse, Uint8Array]>(this.config.batchSize, queueErrorHandler);\n }\n\n this.on(\"_unhandled\",\n (msg) => {\n if (msg.uuid) {\n this.log.verbose(\"Unhandled event: \" + msg.type);\n this.emit(\"uuid\",\n {\n status: true,\n uuid: msg.uuid,\n });\n }\n });\n if (this.config.enablePrometheus) {\n this.prometheus = new IndexerMetrics();\n this.prometheusServer = Fastify({\n logger: false,\n });\n this.prometheusServer.get(\"/metrics\",\n async (_req, res) => {\n res.header(\"Content-Type\", this.prometheus!.registry.contentType);\n res.send(await this.prometheus!.getMetrics());\n },\n );\n\n const prometheusPort = this.config.prometheusPort\n ?? (process.env.PROMETHEUS_PORT ? parseInt(process.env.PROMETHEUS_PORT, 10) : DEFAULT_PROMETHEUS_PORT);\n this.prometheusServer.listen({\n port: prometheusPort,\n host: \"0.0.0.0\",\n },\n (err) => {\n if (err) {\n this.log.error(\"Prometheus error: \" + err);\n this.prometheus?.recordError(\"metrics_server\");\n this.emit(\"fatal-error\", {\n error: err,\n message: \"Failed to start metrics server\",\n });\n }\n });\n }\n if (this.config.enableHealthcheck) {\n this.fastify = Fastify({\n logger: false,\n });\n this.fastify.get(\"/health\",\n async (_request, reply) => {\n const code = this.healthCheck.status == \"OK\"\n ? 200\n : 503;\n reply.code(code).send(this.healthCheck);\n });\n const healthPort = this.config.healthCheckPort\n ?? (process.env.HEALTH_CHECK_PORT ? parseInt(process.env.HEALTH_CHECK_PORT, 10) : DEFAULT_HEALTH_CHECK_PORT);\n this.fastify.listen({\n port: healthPort,\n host: \"0.0.0.0\",\n },\n (err) => {\n if (err) {\n this.log.error(\"Health check server error: \" + err);\n this.prometheus?.recordError(\"health_check_server\");\n this.emit(\"fatal-error\", {\n error: err,\n message: \"Failed to start health check server\",\n });\n }\n });\n }\n }\n\n private setStatus(status: string) {\n this.healthCheck.status = status;\n }\n\n private blockListener = {\n next: (data: {\n header: {\n height: number\n }\n }) => {\n this.newBlockReceived(data.header.height);\n },\n };\n\n private isMinimal(_blockqueue: BlockQueue): _blockqueue is MinimalBlockQueue {\n if (this.config.minimal) {\n return true;\n }\n else {\n return false;\n }\n }\n\n public async connect() {\n try {\n if (this.client && this.tryToRecover) {\n this.log.verbose(\"Recover from error. Attempting to disconnect from RPC\");\n this.client.disconnect();\n this.blockClient.disconnect();\n this.log.verbose(\"Disconnected from RPC\");\n }\n this.client = await connectComet(this.config.rpcUrl);\n this.log.info(\"Connected to RPC for ad hoc queries\");\n\n this.blockClient = await connectComet(this.config.rpcUrl);\n this.log.info(\"Connected to RPC for block & validator info\");\n\n return true;\n }\n catch (error) {\n this.log.error(\"RPC connection error: \" + error);\n this.prometheus?.recordError(\"rpc\");\n this.tryToRecover = true;\n return false;\n }\n }\n\n public stop() {\n this.started = false;\n }\n\n public async start() {\n this.started = true;\n if (this.blockQueue) {\n this.blockQueue.clear();\n this.log.verbose(\"Starting, clearing block queue\");\n }\n if (!this.initialized) {\n try {\n if (this.config.init) {\n await this.config.init();\n }\n }\n catch (e) {\n this.log.error(\"Failed to initialize indexer: \" + e);\n\n this.prometheus?.recordError(\"init_error\");\n this.setStatus(\"FAILED\");\n throw e;\n }\n if (await this.config.shouldProcessGenesis()) {\n try {\n if (this.config.genesisPath) {\n await this.parseGenesis();\n }\n }\n catch (e) {\n this.log.error(\"Failed to parse genesis: \" + e);\n\n this.prometheus?.recordError(\"genesis_error\");\n this.setStatus(\"FAILED\");\n throw e;\n }\n }\n this.initialized = true;\n }\n try {\n const connectTimeoutPromise: ReturnType<typeof this.connect> = new Promise((resolve, reject) => {\n setTimeout(reject, QUEUE_DEQUEUE_TIMEOUT_MS, []);\n });\n await Promise.race([this.connect(), connectTimeoutPromise]);\n if (!this.config.usePolling && this.subscription) {\n this.subscription.removeListener(this.blockListener);\n this.subscription = null;\n this.log.verbose(\"Removed existing block listener and subscription\");\n }\n if (!this.config.usePolling) {\n this.subscription = this.client.subscribeNewBlock\n ? this.client.subscribeNewBlock()\n : null;\n }\n const status = await this.client.status();\n this.latestHeight = status.syncInfo.latestBlockHeight;\n this.log.info(\"Current chain height: \" + this.latestHeight);\n\n this.heightToProcess = await this.config.getNextHeight();\n if (this.config.usePolling) {\n this.pollForBlock();\n }\n else {\n if (this.subscription) {\n this.subscription.addListener(this.blockListener);\n }\n else {\n this.prometheus?.recordError(\"rpc\");\n throw new Error(\"Could not subscribe to new blocks\");\n }\n }\n }\n catch (e) {\n this.log.error(\"Failed to set up block listening: \" + e);\n this.prometheus?.recordError(\"rpc\");\n this.setStatus(\"FAILED\");\n throw e;\n }\n this.log.debug(\"Starting main processing loop\");\n this.tryToRecover = false;\n this.fetcher().catch((e) => {\n this.setStatus(\"FAILED\");\n\n this.prometheus?.recordError(\"rpc\");\n throw new Error(\"Error in fetching service: \" + e);\n });\n\n const hrTime = process.hrtime();\n let ms = hrTime[0] * 1000000 + hrTime[1] / 1000;\n while (this.blockQueue.size() > 0 && !this.tryToRecover && this.started && (this.config.endHeight === undefined || this.heightToProcess <= this.config.endHeight)) {\n if (this.config.enablePrometheus) {\n this.prometheus!.updateRetryCount(this.retryCount);\n }\n // await the dequeued promise is essentially awaiting fetched data for that block\n try {\n if (this.tryToRecover) {\n throw new Error(\"Exiting processing loop. Attempting to recover indexer\");\n }\n // Index block inside a db transaction to ensure data consistency\n await this.config.beginTransaction();\n this.log.silly(\"Started db tx\");\n let height, timestamp;\n if (this.isMinimal(this.blockQueue)) {\n const timeoutPromise: ReturnType<typeof this.blockQueue.dequeue> = new Promise((resolve, reject) => {\n setTimeout(reject, QUEUE_DEQUEUE_TIMEOUT_MS, []);\n });\n const toProcess = await Promise.race([this.blockQueue.dequeue(), timeoutPromise]);\n this.log.silly(\"Retrieved block data\");\n if (!toProcess || !toProcess[0] || !toProcess[1]) {\n this.prometheus?.recordError(\"rpc\");\n throw new Error(\"Could not fetch block\");\n }\n height = toProcess[0].block.header.height;\n timestamp = toRfc3339WithNanoseconds(toProcess[0].block.header.time);\n await this.processBlock(toProcess[0],\n toProcess[1]);\n }\n else {\n const timeoutPromise: ReturnType<typeof this.blockQueue.dequeue> = new Promise((resolve, reject) => {\n setTimeout(reject, QUEUE_DEQUEUE_TIMEOUT_MS, []);\n });\n const toProcess = await Promise.race([this.blockQueue.dequeue(), timeoutPromise]);\n this.log.silly(\"Retrieved block data\");\n if (!toProcess || !toProcess[0] || !toProcess[1] || !toProcess[2]) {\n this.prometheus?.recordError(\"rpc\");\n throw new Error(\"Could not fetch block\");\n }\n\n this.log.silly(\"Decoded block\");\n height = toProcess[0].block.header.height;\n timestamp = toRfc3339WithNanoseconds(toProcess[0].block.header.time);\n await this.processBlock(toProcess[0],\n toProcess[1],\n QueryValidatorsResponse.decode(toProcess[2]).validators);\n }\n // Emit events to trigger periodic operations every 50, 100 and 1000 blocks\n if (height % PERIODIC_INTERVALS.LARGE == 0) {\n const hrTime = process.hrtime();\n const newms = hrTime[0] * 1000000 + hrTime[1] / 1000;\n const duration = newms - ms;\n ms = newms;\n const rate = 1000000000 / duration;\n this.log.info(\"Processing:\" + rate.toFixed(2) + \"blocks/sec\");\n await this.asyncEmit(\"periodic/1000\",\n {\n value: null,\n height,\n timestamp,\n });\n }\n if (height % PERIODIC_INTERVALS.MEDIUM == 0) {\n await this.asyncEmit(\"periodic/100\",\n {\n value: null,\n height,\n timestamp,\n });\n }\n if (height % PERIODIC_INTERVALS.SMALL == 0) {\n await this.asyncEmit(\"periodic/50\",\n {\n value: null,\n height,\n timestamp,\n });\n }\n this.log.silly(\"Handled periodic events\");\n\n await this.config.endTransaction(true);\n\n this.log.silly(\"Committed db tx\");\n }\n catch (e) {\n this.prometheus?.recordError(\"block\");\n this.log.error(\"Block processing error: \" + e);\n this.setStatus(\"FAILED\");\n try {\n await this.config.endTransaction(false);\n }\n catch (dbe) {\n this.prometheus?.recordError(\"database\");\n this.log.error(\"Error ending transaction. Must be a DB error: \" + dbe);\n }\n this.tryToRecover = true;\n this.retryCount++;\n break;\n }\n this.retryCount = 0;\n this.setStatus(\"OK\");\n }\n if (this.config.endHeight !== undefined && this.heightToProcess >= this.config.endHeight!) {\n this.log.info(\"Reached configured end height. Stopping indexer.\");\n this.stop();\n }\n if (this.started) {\n if (this.retryCount < 3) {\n this.log.debug(\"Indexer retryCount: \" + this.retryCount);\n this.log.info(\"Indexer is restarting\");\n setTimeout(() => this.start(),\n this.retryCount * 5000);\n }\n else {\n this.log.info(\"Indexer failed too many times. Exiting.\");\n this.emit(\"fatal-error\", {\n error: new Error(\"Max retry attempts exceeded\"),\n message: \"Indexer failed too many times\",\n retryCount: this.retryCount,\n });\n }\n }\n }\n\n public asyncEmit: EmitFunc<keyof WithHeightAndUUID<EventMap>> = async (\n type,\n event,\n ) => {\n event.uuid = uuidv4();\n\n /*\n * More than 1 listener can be registered for an event type\n * Fortunately these are all set up during module init() so we have a consistent count\n * so we can count responses to resolve when complete\n * values are irrelevant as promise resolution is only used for flow control\n */\n let listenerCount = this.handled.get(type);\n if (!listenerCount) {\n // Setting listenerCount to 1 (the unhandled listener)\n listenerCount = 1;\n }\n let listenersResponded = 0;\n const prom = new Promise<void>((resolve, reject) => {\n const returnFunc = (ev: UUIDEvent) => {\n if (ev.uuid == event.uuid) {\n if (ev.status) {\n listenersResponded++;\n if (listenersResponded == listenerCount) {\n // All listeners have done their thing so we can remove listener, resolve and continue execution\n this.off(\"uuid\",\n returnFunc);\n resolve();\n }\n }\n else {\n // At least 1 listener is reporting an error. Reject and handle exception at the original asyncEmit location\n reject(ev.error);\n }\n }\n };\n this.on(\"uuid\",\n returnFunc);\n });\n this.emit(type,\n event);\n\n return prom;\n };\n\n private async processBlock(block: BlockResponse, block_results: BlockResultsResponse | BlockResultsResponse38, validators?: Validator[]) {\n let processStart: [number, number] = [0, 0];\n if (this.config.logLevel == \"silly\") {\n processStart = process.hrtime();\n }\n let endTimer;\n if (this.config.enablePrometheus) {\n endTimer = this.prometheus!.timeBlockProcessing();\n }\n const height = block.block.header.height;\n this.heightToProcess = height;\n this.log.debug(\"Processing block: %d\",\n height);\n // Initialize height & timestamp to be used for this block-processing run\n const timestamp = toRfc3339WithNanoseconds(block.block.header.time);\n\n // Use & await asyncEmit to ensure db insertions in order\n\n /*\n * Emit block information to any interested modules.\n * Primarily the required block module listens to this\n */\n await this.asyncEmit(\"block\",\n {\n value: {\n block,\n block_results,\n },\n height,\n timestamp,\n });\n this.log.silly(\"Modules handled block event\");\n\n let beginBlockEvents: readonly Event[] | readonly Event38[];\n let endBlockEvents: readonly Event[] | readonly Event38[];\n if ((block_results as BlockResultsResponse38).finalizeBlockEvents) {\n beginBlockEvents = (block_results as BlockResultsResponse38).finalizeBlockEvents.filter(x => x.attributes.find(a => decodeAttr(a.key) == \"mode\" && decodeAttr(a.value) == \"begin_block\")) as readonly Event38[];\n endBlockEvents = (block_results as BlockResultsResponse38).finalizeBlockEvents.filter(x => x.attributes.find(a => decodeAttr(a.key) == \"mode\" && decodeAttr(a.value) == \"end_block\")) as readonly Event38[];\n }\n else {\n beginBlockEvents = (block_results as BlockResultsResponse).beginBlockEvents;\n endBlockEvents = (block_results as BlockResultsResponse).endBlockEvents;\n }\n // Deal with begin_block events first\n await this.asyncEmit(\"begin_block\",\n {\n value: {\n events: beginBlockEvents!,\n validators,\n },\n height,\n timestamp,\n });\n\n this.log.silly(\"Modules handled begin_block events\");\n\n // Then individual tx_events\n await this.asyncEmit(\"tx_events\",\n {\n value: block_results.results,\n height,\n timestamp,\n });\n this.log.silly(\"Modules handled tx events\");\n\n // Emit details and result for each tx msg separately\n for (let t = 0; t < block.block.txs.length; t++) {\n const tx = Tx.decode(block.block.txs[t]);\n\n const result = block_results.results[t].code;\n const txlog = block_results.results[t].log;\n\n if (result != 0) {\n // Tx failed. Ignore\n continue;\n }\n if (tx.body && tx.body.memo != \"\") {\n const txHash = createHash(\"sha256\").update(block.block.txs[t])\n .digest(\"hex\");\n await this.asyncEmit(\"tx_memo\",\n {\n value: {\n txHash,\n txBody: tx.body,\n },\n height,\n timestamp,\n });\n }\n // parsing log rather than using events directly in order to have msg_index available to filter appropriate events for each msg\n let events: Array<{\n msg_index?: number\n events: (Event | Event38)[]\n }> = txlog\n ? JSON.parse(txlog)\n : [];\n if (events.length == 0) {\n const eventsToAdd: typeof events = [];\n this.log.silly(\"No events found in tx log. Parsing events for msg_index\");\n for (let m = 0; m < block_results.results[t].events.length; m++) {\n if (block_results.results[t].events[m].attributes.find(a => decodeAttr(a.key) == \"msg_index\")) {\n const mi = decodeAttr(block_results.results[t].events[m].attributes.find(a => decodeAttr(a.key) == \"msg_index\")?.value ?? \"\");\n if (mi != \"\") {\n const miNum = parseInt(mi);\n let ev = eventsToAdd.find(x => x.msg_index == miNum);\n if (!ev) {\n ev = {\n msg_index: miNum,\n events: [block_results.results[t].events[m]],\n };\n eventsToAdd.push(ev);\n }\n else {\n ev.events.push(block_results.results[t].events[m] as Event);\n }\n }\n }\n }\n events = events.concat(eventsToAdd);\n }\n const msgs = tx.body?.messages;\n\n if (msgs) {\n for (let i = 0; i < msgs.length; i++) {\n this.log.silly(\"Indexer broadcasting msg for handling: \" + msgs[i].typeUrl);\n const msgevents\n = msgs.length > 1\n ? events.find(x => x.msg_index == i)?.events\n : events[0].events;\n await this.asyncEmit(msgs[i].typeUrl as never,\n {\n value: {\n tx: msgs[i].value as never,\n events: msgevents,\n } as never,\n height,\n timestamp,\n });\n if (msgs[i].typeUrl == \"/cosmos.authz.v1beta1.MsgExec\") {\n const authzMsgs = MsgExec.decode(msgs[i].value).msgs;\n if (authzMsgs) {\n for (let r = 0; r < authzMsgs.length; r++) {\n this.log.silly(\"Indexer broadcasting msg for handling: \" + authzMsgs[r].typeUrl);\n const authzMsgEvents = msgevents?.reduce((events, evt) => {\n if (evt.attributes.filter(x => decodeAttr(x.key) == \"authz_msg_index\" && decodeAttr(x.value) == \"\" + r).length > 0) {\n events.push(evt);\n }\n return events;\n },\n [] as (Event | Event38)[]);\n await this.asyncEmit(authzMsgs[r].typeUrl as never,\n {\n value: {\n tx: authzMsgs[r].value as never,\n events: authzMsgEvents,\n } as never,\n height,\n timestamp,\n });\n }\n }\n }\n }\n }\n }\n this.log.silly(\"Modules handled msg events\");\n if (this.config.enablePrometheus) {\n this.prometheus!.recordTransactions(block.block.txs.length);\n }\n // Then deal with end_block events\n await this.asyncEmit(\"end_block\",\n {\n value: endBlockEvents!,\n height,\n timestamp,\n });\n this.log.silly(\"Modules handled end_block events\");\n if (this.config.logLevel == \"silly\") {\n const processEnd = process.hrtime(processStart);\n const processTime = processEnd[0] * 1000 + processEnd[1] / 1000000;\n this.log.silly(\"Processed block %d in %d ms\",\n height,\n processTime.toFixed(2));\n }\n\n if (this.config.enablePrometheus) {\n endTimer!();\n }\n if (this.config.enablePrometheus) {\n this.prometheus!.updateBlockMetrics(height, this.latestHeight, this.blockQueue.size());\n }\n }\n\n private async fetcher() {\n for (let i = this.heightToProcess; i <= this.latestHeight; i++) {\n this.log.debug(\"Fetching: \" + i);\n if (this.tryToRecover) {\n this.log.verbose(\"Exiting fetcher loop. Attempting to recover indexer\");\n break;\n }\n try {\n if (this.isMinimal(this.blockQueue)) {\n const timeoutPromise: Promise<[BlockResponse, BlockResultsResponse]> = new Promise((resolve, reject) => {\n setTimeout(reject,\n RPC_TIMEOUT_MS,\n false);\n });\n const toIndex = Promise.race([Promise.all([this.blockClient.block(i) as Promise<BlockResponse>, this.blockClient.blockResults(i) as Promise<BlockResultsResponse>]), timeoutPromise]).catch((e) => {\n this.log.error(\"Error fetching block: \" + i + \" : \" + e);\n this.prometheus?.recordError(\"rpc\");\n this.tryToRecover = true;\n return Promise.resolve([]);\n }) as Promise<[BlockResponse, BlockResultsResponse]>;\n this.blockQueue.enqueue(toIndex);\n }\n else {\n const timeoutPromise: Promise<[BlockResponse, BlockResultsResponse, Uint8Array]> = new Promise((resolve, reject) => {\n setTimeout(reject,\n RPC_TIMEOUT_MS,\n false);\n });\n const q = QueryValidatorsRequest.fromPartial({\n pagination: {\n limit: PAGINATION_LIMITS.VALIDATORS,\n },\n });\n const vals = QueryValidatorsRequest.encode(q).finish();\n const toIndex = Promise.race([\n Promise.all([\n this.blockClient.block(i) as Promise<BlockResponse>,\n this.blockClient.blockResults(i) as Promise<BlockResultsResponse>,\n this.callABCI(\"/cosmos.staking.v1beta1.Query/Validators\",\n vals,\n i,\n false),\n ]),\n timeoutPromise,\n ]).catch((e) => {\n this.log.error(\"Error fetching block: \" + i + \" : \" + e);\n this.tryToRecover = true;\n return Promise.resolve([]);\n }) as Promise<[BlockResponse, BlockResultsResponse, Uint8Array]>;\n this.blockQueue.enqueue(toIndex);\n }\n await this.blockQueue.continue();\n if (this.tryToRecover) {\n this.retryCount++;\n throw new Error(\"RPC not responding\");\n }\n }\n catch (e) {\n this.log.error(\"Fetching error: \" + e);\n break;\n }\n }\n if (!this.tryToRecover) {\n this.blockQueue.setSynced();\n this.log.info(\"Synced to latest height\");\n }\n }\n\n public async callABCI(path: string, data: Uint8Array, height?: number, adHoc: boolean = true): Promise<Uint8Array> {\n try {\n const endTimer = this.prometheus?.timeRpcCall(path) ?? void 0;\n const abciq = await\n (adHoc\n ? this.client\n : this.blockClient).abciQuery({\n path,\n data,\n height: height,\n });\n endTimer?.();\n if (abciq) {\n return abciq.value;\n }\n else {\n this.tryToRecover = true;\n this.setStatus(\"FAILED\");\n this.prometheus?.recordError(\"rpc\");\n throw new Error(\"RPC not responding. Query at: \" + path);\n }\n }\n catch (_e) {\n this.tryToRecover = true;\n this.setStatus(\"FAILED\");\n this.retryCount++;\n throw new Error(\"RPC not responding. Query at: \" + path);\n }\n }\n\n private newBlockReceived(height: number): void {\n if (this.blockTimeout) {\n clearTimeout(this.blockTimeout);\n }\n this.blockTimeout = setTimeout(() => {\n this.tryToRecover = true;\n }, 30000);\n this.log.info(\"Received new block: %d\",\n height);\n if (height == this.latestHeight) {\n return;\n }\n // If we are synced, add to end of queue\n if (this.blockQueue.synced && !this.tryToRecover) {\n this.latestHeight = height;\n if (this.blockQueue.size() + 1 == this.config.batchSize) {\n this.prometheus?.recordError(\"block\");\n this.log.error(\"Block queue is full. Cannot add new block\");\n this.tryToRecover = true;\n this.retryCount++;\n return;\n }\n try {\n if (this.isMinimal(this.blockQueue)) {\n this.blockQueue.enqueue(Promise.all([this.client.block(height) as Promise<BlockResponse>, this.client.blockResults(height) as Promise<BlockResultsResponse>]).catch((e) => {\n this.log.error(\"Error fetching block: \" + height + \" : \" + e);\n\n return Promise.resolve([]);\n }) as Promise<[BlockResponse, BlockResultsResponse]>);\n }\n else {\n const q = QueryValidatorsRequest.fromPartial({\n pagination: {\n limit: 1000n,\n },\n });\n const vals = QueryValidatorsRequest.encode(q).finish();\n this.blockQueue.enqueue(Promise.all([\n this.client.block(height) as Promise<BlockResponse>,\n this.client.blockResults(height) as Promise<BlockResultsResponse>,\n this.callABCI(\"/cosmos.staking.v1beta1.Query/Validators\",\n vals,\n height,\n false),\n ]).catch((e) => {\n this.log.error(\"Error fetching block: \" + height + \" : \" + e);\n return Promise.resolve([]);\n }) as Promise<[BlockResponse, BlockResultsResponse, Uint8Array]>);\n }\n }\n catch (e) {\n this.log.error(\"New Block Received error: \" + e);\n }\n }\n else {\n this.latestHeight = height;\n }\n }\n\n private async pollForBlock() {\n try {\n const status = await this.client.status();\n if (status.syncInfo.latestBlockHeight > this.latestHeight) {\n while (this.latestHeight < status.syncInfo.latestBlockHeight) {\n this.newBlockReceived(this.latestHeight + 1);\n }\n }\n setTimeout(() => {\n this.pollForBlock();\n },\n this.config.pollingInterval);\n }\n catch (e) {\n this.log.error(\"Error polling for new block: \" + e);\n this.tryToRecover = true;\n this.retryCount++;\n }\n }\n\n private readGenesis(): Parser.Parser {\n if (this.config.genesisPath) {\n return fs.createReadStream(this.config.genesisPath).pipe(Parser.parser());\n }\n else {\n throw new Error(\"Genesis path not set\");\n }\n }\n\n private async setArrayReader(path: string, processor: (chunk: unknown) => Promise<void>): Promise<boolean> {\n const readPromise = new Promise<boolean>((resolve, reject) => {\n try {\n const filters = path.split(\".\");\n const pickers = filters.map(filter => Pick.pick({\n filter,\n }));\n let counter = 0;\n let chunkCounter = 0;\n\n // Wrapper processor that handles transaction chunking\n const chunkProcessor = async (data: unknown) => {\n chunkCounter++;\n this.log.debug(`Processing genesis chunk ${chunkCounter}`);\n\n await processor(data);\n\n // Commit and restart transaction every 5 chunks (5000 entries)\n // This prevents timeout on large genesis files\n if (chunkCounter % 5 === 0) {\n this.log.debug(`Committing transaction after chunk ${chunkCounter}`);\n await this.config.endTransaction(true);\n await this.config.beginTransaction();\n }\n };\n\n chain([\n this.readGenesis(),\n ...pickers,\n StreamArray.streamArray(),\n Batch.batch({\n batchSize: GENESIS_BATCH_SIZE,\n }),\n chunkProcessor,\n ])\n .on(\"data\",\n (data) => {\n if (data && Array.isArray(data)) {\n counter = counter + data.length;\n }\n })\n .on(\"end\",\n () => {\n this.log.info(`Processed ${counter} entries in ${chunkCounter} chunks`);\n resolve(true);\n });\n }\n catch (_e) {\n this.log.verbose(\"Error in setArrayReader: \" + _e);\n reject();\n }\n });\n\n return readPromise;\n }\n\n private async setValueReader(path: string, processor: (chunk: unknown) => Promise<void>): Promise<boolean> {\n const readPromise = new Promise<boolean>((resolve, reject) => {\n try {\n const filters = path.split(\".\");\n const pickers = filters.map(filter => Pick.pick({\n filter,\n }));\n\n let counter = 0;\n chain([this.readGenesis(), ...pickers, StreamValues.streamValues(), processor])\n .on(\"data\",\n (_data) => {\n counter++;\n })\n .on(\"end\",\n () => {\n this.log.info(`Processed ${counter} entries`);\n resolve(true);\n });\n }\n catch (_e) {\n reject();\n }\n });\n\n return readPromise;\n }\n\n private async parseGenesis() {\n this.log.info(\"Parsing genesis\");\n await this.config.beginTransaction();\n try {\n this.log.info(\"Starting genesis import\");\n this.log.debug(\"Importing genesis file...\");\n\n for (const [key, _value] of this.handled) {\n if (key.startsWith(\"genesis/\")) {\n const genesisEntry = key.split(\"/\");\n\n this.log.verbose(\"Importing \" + key + \"...\");\n if (genesisEntry[1] == \"array\") {\n await this.setArrayReader(genesisEntry[2],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async (data: any) => {\n await this.asyncEmit(key as never,\n {\n value: data.map((x: {\n value: never\n }) => x.value),\n } as never);\n return data;\n });\n }\n else {\n await this.setValueReader(genesisEntry[2],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async (data: any) => {\n await this.asyncEmit(key as never,\n {\n value: data.value,\n } as never);\n return data;\n });\n }\n }\n }\n\n this.log.info(\"Importing gen TXs...\");\n\n await this.setArrayReader(\"app_state.genutil.gen_txs\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async (data: any) => {\n for (let j = 0; j < data.length; j++) {\n const gentx = data[j].value;\n for (let i = 0; i < gentx.body.messages.length; i++) {\n const msg = gentx.body.messages[i];\n await this.asyncEmit((\"gentx\" + msg[\"@type\"]) as never,\n {\n value: msg,\n } as never);\n }\n }\n return data;\n });\n await this.config.endTransaction(true);\n\n this.log.info(\"Finished importing\");\n }\n catch (e) {\n try {\n await this.config.endTransaction(false);\n }\n catch (dbe) {\n this.prometheus?.recordError(\"database\");\n this.log.error(\"Error ending transaction. Must be a DB error: \" + dbe);\n }\n this.log.error(\"Failed to import genesis\");\n throw e;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["DEFAULT_START_HEIGHT","DEFAULT_BATCH_SIZE","DEFAULT_POLLING_INTERVAL_MS","DEFAULT_HEALTH_CHECK_PORT","DEFAULT_PROMETHEUS_PORT","EclesiaEmitter","CircularBuffer","IndexerMetrics","CONNECT_TIMEOUT_MS","RPCError","statusPromise: Promise<StatusResponse>","RPC_TIMEOUT_MS","timeoutPromise: ReturnType<typeof this.blockQueue.dequeue>","QUEUE_DEQUEUE_TIMEOUT_MS","QueryValidatorsResponse","PERIODIC_INTERVALS","beginBlockEvents: readonly Event[] | readonly Event38[]","endBlockEvents: readonly Event[] | readonly Event38[]","decodeAttr","Tx","events: Array<{\n msg_index?: number\n events: (Event | Event38)[]\n }>","eventsToAdd: typeof events","MsgExec","events","timeoutPromise: Promise<[BlockResponse, BlockResultsResponse]>","timeoutPromise: Promise<[BlockResponse, BlockResultsResponse, Uint8Array]>","QueryValidatorsRequest","PAGINATION_LIMITS","Parser","Pick","StreamArray","Batch","GENESIS_BATCH_SIZE","StreamValues"],"sources":["../../src/indexer/index.ts"],"sourcesContent":["/* eslint-disable @stylistic/no-multi-spaces */\n/* eslint-disable max-lines */\nimport {\n createHash,\n} from \"node:crypto\";\nimport * as fs from \"node:fs\";\n\nimport {\n BlockResponse, BlockResultsResponse, CometClient, connectComet, Event, StatusResponse, toRfc3339WithNanoseconds,\n} from \"@cosmjs/tendermint-rpc\";\nimport {\n BlockResultsResponse as BlockResultsResponse38, Event as Event38,\n} from \"@cosmjs/tendermint-rpc/build/comet38/responses.js\";\nimport {\n MsgExec,\n} from \"cosmjs-types/cosmos/authz/v1beta1/tx.js\";\nimport {\n QueryValidatorsRequest,\n QueryValidatorsResponse,\n} from \"cosmjs-types/cosmos/staking/v1beta1/query.js\";\nimport {\n Validator,\n} from \"cosmjs-types/cosmos/staking/v1beta1/staking.js\";\nimport {\n Tx,\n} from \"cosmjs-types/cosmos/tx/v1beta1/tx.js\";\nimport Fastify, {\n FastifyInstance,\n} from \"fastify\";\nimport {\n chain,\n} from \"stream-chain\";\nimport Parser from \"stream-json\";\nimport Pick from \"stream-json/filters/Pick.js\";\nimport StreamArray from \"stream-json/streamers/StreamArray.js\";\nimport StreamValues from \"stream-json/streamers/StreamValues.js\";\nimport Batch from \"stream-json/utils/Batch.js\";\nimport {\n v4 as uuidv4,\n} from \"uuid\";\nimport * as winston from \"winston\";\n\nimport {\n CONNECT_TIMEOUT_MS,\n DEFAULT_BATCH_SIZE, DEFAULT_HEALTH_CHECK_PORT, DEFAULT_POLLING_INTERVAL_MS, DEFAULT_PROMETHEUS_PORT, DEFAULT_START_HEIGHT,\n GENESIS_BATCH_SIZE, PAGINATION_LIMITS, PERIODIC_INTERVALS, QUEUE_DEQUEUE_TIMEOUT_MS, RPC_TIMEOUT_MS,\n} from \"../constants.js\";\nimport {\n EclesiaEmitter,\n} from \"../emitter/index.js\";\nimport {\n RPCError,\n} from \"../errors/index.js\";\nimport {\n IndexerMetrics,\n} from \"../metrics/index.js\";\nimport {\n CircularBuffer,\n} from \"../promise-queue/index.js\";\nimport {\n BlockQueue, EcleciaIndexerConfig, EmitFunc, MinimalBlockQueue,\n UUIDEvent, WithHeightAndUUID,\n} from \"../types/index.js\";\nimport {\n decodeAttr,\n} from \"../utils/index.js\";\nimport {\n validateFilePath, validatePort, validatePositiveInteger, validateUrl,\n} from \"../validation/index.js\";\n\n/** Default configuration for the Eclesia indexer */\nexport const defaultIndexerConfig = {\n startHeight: DEFAULT_START_HEIGHT, // Start indexing from block 1\n batchSize: DEFAULT_BATCH_SIZE, // Process blocks in batches of 500\n modules: [], // No modules enabled by default\n getNextHeight: () => DEFAULT_START_HEIGHT, // Default height retrieval function\n logLevel: \"info\" as EcleciaIndexerConfig[\"logLevel\"], // Default log level\n usePolling: false, // Use WebSocket subscription by default\n pollingInterval: DEFAULT_POLLING_INTERVAL_MS, // Poll every 5 seconds when polling enabled\n shouldProcessGenesis: () => false, // Skip genesis processing by default\n minimal: true, // Use minimal indexing by default\n enableHealthcheck: true, // Enable health check server by default\n healthCheckPort: DEFAULT_HEALTH_CHECK_PORT, // Default health check port\n enablePrometheus: false, // Disable Prometheus metrics server by default\n prometheusPort: DEFAULT_PROMETHEUS_PORT, // Default Prometheus metrics server port\n init: () => Promise.resolve(), // No-op initialization function\n beginTransaction: () => Promise.resolve(), // No-op transaction begin function\n endTransaction: (_status: boolean) => Promise.resolve(), // No-op transaction end function\n};\n\n/**\n * Core blockchain indexer that connects to Tendermint RPC and processes blocks\n * Extends EclesiaEmitter to provide event-driven architecture for modules\n */\nexport class EcleciaIndexer extends EclesiaEmitter {\n /** Indexer configuration settings */\n public config: EcleciaIndexerConfig;\n\n /** Fastify HTTP server for health checks */\n private fastify: FastifyInstance | null = null;\n\n /** Prometheus HTTP server instance */\n private prometheusServer: FastifyInstance | null = null;\n\n /** Indicates if the indexer has started */\n private started: boolean = false;\n\n /** Queue for managing block processing pipeline */\n private blockQueue: BlockQueue;\n\n /** Latest block height from the chain */\n private latestHeight!: number;\n\n /** Next block height to process */\n public heightToProcess!: number;\n\n /** Whether the indexer has been initialized */\n private initialized = false;\n\n /** Prometheus metrics server instance */\n public prometheus: IndexerMetrics | null = null;\n\n /** Number of retry attempts for error recovery */\n private retryCount = 0;\n\n /** CometBFT client for ad-hoc queries */\n public client!: CometClient;\n\n /** CometBFT client for block and validator queries */\n public blockClient!: CometClient;\n\n /** Winston logger instance */\n public log: winston.Logger;\n\n /** Flag indicating if indexer should attempt recovery */\n private tryToRecover: boolean = false;\n\n /** Health check status for monitoring */\n private healthCheck = {\n status: \"CONNECTING\",\n };\n\n /** WebSocket subscription for new block notifications */\n private subscription: ReturnType<CometClient[\"subscribeNewBlock\"]> | null = null;\n\n /** Timeout handler for block reception */\n private blockTimeout: NodeJS.Timeout | null = null;\n\n /**\n * Creates a new Eclesia indexer instance\n * @param config - Indexer configuration options\n */\n constructor(config: EcleciaIndexerConfig) {\n super();\n\n // Validate required configuration\n validateUrl(config.rpcUrl, \"rpcUrl\");\n validatePositiveInteger(config.batchSize, \"batchSize\");\n\n // Validate optional genesis path if processing genesis\n if (config.genesisPath) {\n validateFilePath(config.genesisPath, \"genesisPath\");\n }\n\n // Validate health check port if provided\n if (config.healthCheckPort !== undefined) {\n validatePort(config.healthCheckPort, \"healthCheckPort\");\n }\n\n // Validate prometheus port if provided\n if (config.prometheusPort !== undefined) {\n validatePort(config.prometheusPort, \"prometheusPort\");\n }\n\n // Validate start height if provided\n if (config.startHeight !== undefined) {\n validatePositiveInteger(config.startHeight, \"startHeight\");\n }\n\n // Validate polling interval if provided\n if (config.pollingInterval !== undefined) {\n validatePositiveInteger(config.pollingInterval, \"pollingInterval\");\n }\n\n this.config = {\n ...defaultIndexerConfig,\n ...config,\n };\n\n // Initialize logger first so it can be used by queue error handler\n const {\n printf,\n } = winston.format;\n\n const eclesiaFormat = printf(({\n level, message, timestamp,\n }) => {\n return `${timestamp} [${level.toUpperCase()}]:\\t${message}`;\n });\n this.log = winston.createLogger({\n level: this.config.logLevel,\n defaultMeta: {\n service: \"Eclesia Indexer\",\n },\n transports: [\n new winston.transports.File({\n filename: \"error.log\",\n level: \"error\",\n }),\n new winston.transports.File({\n filename: \"combined.log\",\n }),\n new winston.transports.Console({\n format: winston.format.combine(winston.format.splat(),\n winston.format.timestamp(),\n eclesiaFormat,\n winston.format.colorize({\n all: true,\n })),\n }),\n ],\n });\n\n // Initialize block queue based on minimal or full indexing mode\n // Pass error handler that uses the logger\n const queueErrorHandler = (e: unknown) => {\n this.prometheus?.recordError(\"rpc\");\n this.log.error(\"Error enqueueing block data: \" + e);\n };\n\n if (this.config.minimal) {\n // Minimal mode: only store block and block results\n this.blockQueue = new CircularBuffer<[BlockResponse, BlockResultsResponse]>(this.config.batchSize, queueErrorHandler);\n }\n else {\n // Full mode: also store validator information\n this.blockQueue = new CircularBuffer<[BlockResponse, BlockResultsResponse, Uint8Array]>(this.config.batchSize, queueErrorHandler);\n }\n\n this.on(\"_unhandled\",\n (msg) => {\n if (msg.uuid) {\n this.log.verbose(\"Unhandled event: \" + msg.type);\n this.emit(\"uuid\",\n {\n status: true,\n uuid: msg.uuid,\n });\n }\n });\n if (this.config.enablePrometheus) {\n this.prometheus = new IndexerMetrics();\n this.prometheusServer = Fastify({\n logger: false,\n });\n this.prometheusServer.get(\"/metrics\",\n async (_req, res) => {\n res.header(\"Content-Type\", this.prometheus!.registry.contentType);\n res.send(await this.prometheus!.getMetrics());\n },\n );\n\n const prometheusPort = this.config.prometheusPort\n ?? (process.env.PROMETHEUS_PORT ? parseInt(process.env.PROMETHEUS_PORT, 10) : DEFAULT_PROMETHEUS_PORT);\n this.prometheusServer.listen({\n port: prometheusPort,\n host: \"0.0.0.0\",\n },\n (err) => {\n if (err) {\n this.log.error(\"Prometheus error: \" + err);\n this.prometheus?.recordError(\"metrics_server\");\n this.emit(\"fatal-error\", {\n error: err,\n message: \"Failed to start metrics server\",\n });\n }\n });\n }\n if (this.config.enableHealthcheck) {\n this.fastify = Fastify({\n logger: false,\n });\n this.fastify.get(\"/health\",\n async (_request, reply) => {\n const code = this.healthCheck.status == \"OK\"\n ? 200\n : 503;\n reply.code(code).send(this.healthCheck);\n });\n const healthPort = this.config.healthCheckPort\n ?? (process.env.HEALTH_CHECK_PORT ? parseInt(process.env.HEALTH_CHECK_PORT, 10) : DEFAULT_HEALTH_CHECK_PORT);\n this.fastify.listen({\n port: healthPort,\n host: \"0.0.0.0\",\n },\n (err) => {\n if (err) {\n this.log.error(\"Health check server error: \" + err);\n this.prometheus?.recordError(\"health_check_server\");\n this.emit(\"fatal-error\", {\n error: err,\n message: \"Failed to start health check server\",\n });\n }\n });\n }\n }\n\n private setStatus(status: string) {\n this.healthCheck.status = status;\n }\n\n private blockListener = {\n next: (data: {\n header: {\n height: number\n }\n }) => {\n this.newBlockReceived(data.header.height);\n },\n };\n\n private isMinimal(_blockqueue: BlockQueue): _blockqueue is MinimalBlockQueue {\n if (this.config.minimal) {\n return true;\n }\n else {\n return false;\n }\n }\n\n public async connect() {\n try {\n if (this.client && this.tryToRecover) {\n this.log.verbose(\"Recover from error. Attempting to disconnect from RPC\");\n this.client.disconnect();\n this.blockClient.disconnect();\n this.log.verbose(\"Disconnected from RPC\");\n }\n const connectTimeoutPromise = new Promise<ReturnType<typeof connectComet>>((resolve, reject) => {\n setTimeout(reject, CONNECT_TIMEOUT_MS, []);\n });\n this.client = await Promise.race([connectComet(this.config.rpcUrl), connectTimeoutPromise]);\n this.log.info(\"Connected to RPC for ad hoc queries\");\n this.blockClient = await Promise.race([connectComet(this.config.rpcUrl), connectTimeoutPromise]);\n this.log.info(\"Connected to RPC for block & validator info\");\n\n return true;\n }\n catch (error) {\n this.log.error(\"RPC connection error: \" + error);\n this.prometheus?.recordError(\"rpc\");\n this.tryToRecover = true;\n return false;\n }\n }\n\n private async initialize() {\n if (!this.initialized) {\n try {\n if (this.config.init) {\n await this.config.init();\n }\n }\n catch (e) {\n this.log.error(\"Failed to initialize indexer: \" + e);\n\n this.prometheus?.recordError(\"init_error\");\n this.setStatus(\"FAILED\");\n throw e;\n }\n if (await this.config.shouldProcessGenesis()) {\n try {\n if (this.config.genesisPath) {\n await this.parseGenesis();\n }\n }\n catch (e) {\n this.log.error(\"Failed to parse genesis: \" + e);\n\n this.prometheus?.recordError(\"genesis_error\");\n this.setStatus(\"FAILED\");\n throw e;\n }\n }\n this.initialized = true;\n }\n }\n\n public stop() {\n this.started = false;\n }\n\n private clearBlockQueue() {\n if (this.blockQueue) {\n this.blockQueue.clear();\n this.log.verbose(\"Starting, clearing block queue\");\n }\n }\n\n private async setupBlockListening() {\n const connected = await this.connect();\n if (!connected) {\n this.setStatus(\"FAILED\");\n throw new RPCError(\"Failed to connect to RPC\");\n }\n\n try {\n if (!this.config.usePolling && this.subscription) {\n this.subscription.removeListener(this.blockListener);\n this.subscription = null;\n this.log.verbose(\"Removed existing block listener and subscription\");\n }\n if (!this.config.usePolling) {\n this.subscription = this.client.subscribeNewBlock\n ? this.client.subscribeNewBlock()\n : null;\n }\n const statusPromise: Promise<StatusResponse> = new Promise((resolve, reject) => {\n setTimeout(reject,\n RPC_TIMEOUT_MS,\n false);\n });\n const status = await Promise.race([this.client.status(), statusPromise]);\n this.latestHeight = status.syncInfo.latestBlockHeight;\n this.log.info(\"Current chain height: \" + this.latestHeight);\n\n this.heightToProcess = await this.config.getNextHeight();\n if (this.config.usePolling) {\n this.pollForBlock();\n }\n else {\n if (this.subscription) {\n this.subscription.addListener(this.blockListener);\n }\n else {\n this.prometheus?.recordError(\"rpc\");\n throw new Error(\"Could not subscribe to new blocks\");\n }\n }\n }\n catch (e) {\n this.log.error(\"Failed to set up block listening: \" + e);\n this.prometheus?.recordError(\"rpc\");\n this.setStatus(\"FAILED\");\n throw e;\n }\n }\n\n public async start() {\n this.started = true;\n this.clearBlockQueue();\n await this.initialize();\n try {\n await this.setupBlockListening();\n this.log.debug(\"Starting main processing loop\");\n this.tryToRecover = false;\n this.fetcher().catch((e) => {\n this.setStatus(\"FAILED\");\n this.prometheus?.recordError(\"rpc\");\n throw new Error(\"Error in fetching service: \" + e);\n });\n }\n catch (_e) {\n // Continue and attempt to recover\n }\n\n while (\n this.started // break out when stopped\n && !this.tryToRecover // break out for recoverable errors\n && (this.config.endHeight === undefined || this.heightToProcess <= this.config.endHeight) // break out if end height configured and reached\n && this.blockQueue.size() > 0 // break out if no blocks to process\n ) {\n // await the dequeued promise is essentially awaiting fetched data for that block\n try {\n this.prometheus?.updateRetryCount(this.retryCount);\n // Index block inside a db transaction to ensure data consistency\n await this.config.beginTransaction();\n this.log.silly(\"Started db tx\");\n let height, timestamp;\n\n // Main block processing (minimal)\n if (this.isMinimal(this.blockQueue)) {\n const timeoutPromise: ReturnType<typeof this.blockQueue.dequeue> = new Promise((resolve, reject) => {\n setTimeout(reject, QUEUE_DEQUEUE_TIMEOUT_MS, []);\n });\n const toProcess = await Promise.race([this.blockQueue.dequeue(), timeoutPromise]);\n this.log.silly(\"Retrieved block data\");\n if (!toProcess || !toProcess[0] || !toProcess[1]) {\n throw new RPCError(\"Could not fetch block(minimal)\");\n }\n height = toProcess[0].block.header.height;\n timestamp = toRfc3339WithNanoseconds(toProcess[0].block.header.time);\n await this.processBlock(toProcess[0],\n toProcess[1]);\n }\n // Main block processing (full)\n else {\n const timeoutPromise: ReturnType<typeof this.blockQueue.dequeue> = new Promise((resolve, reject) => {\n setTimeout(reject, QUEUE_DEQUEUE_TIMEOUT_MS, []);\n });\n const toProcess = await Promise.race([this.blockQueue.dequeue(), timeoutPromise]);\n this.log.silly(\"Retrieved block data\");\n if (!toProcess || !toProcess[0] || !toProcess[1] || !toProcess[2]) {\n throw new RPCError(\"Could not fetch block(full)\");\n }\n\n this.log.silly(\"Decoded block\");\n height = toProcess[0].block.header.height;\n timestamp = toRfc3339WithNanoseconds(toProcess[0].block.header.time);\n await this.processBlock(toProcess[0],\n toProcess[1],\n QueryValidatorsResponse.decode(toProcess[2]).validators);\n }\n\n // Emit events to trigger periodic operations every 50, 100 and 1000 blocks\n if (height % PERIODIC_INTERVALS.LARGE == 0) {\n await this.asyncEmit(\"periodic/large\",\n {\n value: null,\n height,\n timestamp,\n });\n }\n if (height % PERIODIC_INTERVALS.MEDIUM == 0) {\n await this.asyncEmit(\"periodic/medium\",\n {\n value: null,\n height,\n timestamp,\n });\n }\n if (height % PERIODIC_INTERVALS.SMALL == 0) {\n await this.asyncEmit(\"periodic/small\",\n {\n value: null,\n height,\n timestamp,\n });\n }\n this.log.silly(\"Handled periodic events\");\n\n await this.config.endTransaction(true);\n\n this.log.silly(\"Committed db tx\");\n }\n catch (e) {\n // any error here is likely recoverable (e.g. RPC timeout, DB error)\n this.prometheus?.recordError(\"block\");\n this.log.error(\"Block processing error: \" + e);\n this.setStatus(\"FAILED\");\n try {\n await this.config.endTransaction(false);\n }\n catch (dbe) {\n this.prometheus?.recordError(\"database\");\n this.log.error(\"Error ending transaction. Must be a DB error: \" + dbe);\n }\n this.tryToRecover = true;\n this.retryCount++;\n // Exit processing loop to attempt recovery\n break;\n }\n // Reset retry count and status on successful block processing\n this.retryCount = 0;\n this.setStatus(\"OK\");\n }\n\n // Normal exit from processing loop\n if (!this.started) {\n this.log.info(\"Indexer manually stopped.\");\n return;\n }\n if (this.config.endHeight !== undefined && this.heightToProcess >= this.config.endHeight!) {\n this.log.info(\"Reached configured end height. Stopping indexer.\");\n this.stop();\n return;\n }\n\n // Abnormal exit\n if (this.retryCount < 3) {\n this.log.debug(\"Indexer retryCount: \" + this.retryCount);\n this.retryCount++;\n this.log.info(\"Indexer is restarting\");\n // Attempt recovery after brief delay\n setTimeout(() => this.start(),\n this.retryCount * 5000);\n }\n else {\n this.log.info(\"Indexer failed too many times. Exiting.\");\n this.emit(\"fatal-error\", {\n error: new Error(\"Max retry attempts exceeded\"),\n message: \"Indexer failed too many times\",\n retryCount: this.retryCount,\n });\n }\n }\n\n public asyncEmit: EmitFunc<keyof WithHeightAndUUID<EventMap>> = async (\n type,\n event,\n ) => {\n event.uuid = uuidv4();\n\n /*\n * More than 1 listener can be registered for an event type\n * Fortunately these are all set up during module init() so we have a consistent count\n * so we can count responses to resolve when complete\n * values are irrelevant as promise resolution is only used for flow control\n */\n let listenerCount = this.handled.get(type);\n if (!listenerCount) {\n // Setting listenerCount to 1 (the unhandled listener)\n listenerCount = 1;\n }\n let listenersResponded = 0;\n const prom = new Promise<void>((resolve, reject) => {\n const returnFunc = (ev: UUIDEvent) => {\n if (ev.uuid == event.uuid) {\n if (ev.status) {\n listenersResponded++;\n if (listenersResponded == listenerCount) {\n // All listeners have done their thing so we can remove listener, resolve and continue execution\n this.off(\"uuid\",\n returnFunc);\n resolve();\n }\n }\n else {\n // At least 1 listener is reporting an error. Reject and handle exception at the original asyncEmit location\n reject(ev.error);\n }\n }\n };\n this.on(\"uuid\",\n returnFunc);\n });\n this.emit(type,\n event);\n\n return prom;\n };\n\n private async processBlock(block: BlockResponse, block_results: BlockResultsResponse | BlockResultsResponse38, validators?: Validator[]) {\n const endTimer = this.prometheus?.timeBlockProcessing();\n const height = block.block.header.height;\n this.heightToProcess = height;\n this.log.debug(\"Processing block: %d\",\n height);\n // Initialize height & timestamp to be used for this block-processing run\n const timestamp = toRfc3339WithNanoseconds(block.block.header.time);\n\n // Use & await asyncEmit to ensure db insertions in order\n\n /*\n * Emit block information to any interested modules.\n * Primarily the required block module listens to this\n */\n await this.asyncEmit(\"block\",\n {\n value: {\n block,\n block_results,\n },\n height,\n timestamp,\n });\n this.log.silly(\"Modules handled block event\");\n\n let beginBlockEvents: readonly Event[] | readonly Event38[];\n let endBlockEvents: readonly Event[] | readonly Event38[];\n if ((block_results as BlockResultsResponse38).finalizeBlockEvents) {\n beginBlockEvents = (block_results as BlockResultsResponse38).finalizeBlockEvents.filter(x => x.attributes.find(a => decodeAttr(a.key) == \"mode\" && decodeAttr(a.value) == \"begin_block\")) as readonly Event38[];\n endBlockEvents = (block_results as BlockResultsResponse38).finalizeBlockEvents.filter(x => x.attributes.find(a => decodeAttr(a.key) == \"mode\" && decodeAttr(a.value) == \"end_block\")) as readonly Event38[];\n }\n else {\n beginBlockEvents = (block_results as BlockResultsResponse).beginBlockEvents;\n endBlockEvents = (block_results as BlockResultsResponse).endBlockEvents;\n }\n // Deal with begin_block events first\n await this.asyncEmit(\"begin_block\",\n {\n value: {\n events: beginBlockEvents!,\n validators,\n },\n height,\n timestamp,\n });\n\n this.log.silly(\"Modules handled begin_block events\");\n\n // Then individual tx_events\n await this.asyncEmit(\"tx_events\",\n {\n value: block_results.results,\n height,\n timestamp,\n });\n this.log.silly(\"Modules handled tx events\");\n\n // Emit details and result for each tx msg separately\n for (let t = 0; t < block.block.txs.length; t++) {\n const tx = Tx.decode(block.block.txs[t]);\n\n const result = block_results.results[t].code;\n const txlog = block_results.results[t].log;\n\n if (result != 0) {\n // Tx failed. Ignore\n continue;\n }\n if (tx.body && tx.body.memo != \"\") {\n const txHash = createHash(\"sha256\").update(block.block.txs[t])\n .digest(\"hex\");\n await this.asyncEmit(\"tx_memo\",\n {\n value: {\n txHash,\n txBody: tx.body,\n },\n height,\n timestamp,\n });\n }\n // parsing log rather than using events directly in order to have msg_index available to filter appropriate events for each msg\n let events: Array<{\n msg_index?: number\n events: (Event | Event38)[]\n }> = txlog\n ? JSON.parse(txlog)\n : [];\n if (events.length == 0) {\n const eventsToAdd: typeof events = [];\n this.log.silly(\"No events found in tx log. Parsing events for msg_index\");\n for (let m = 0; m < block_results.results[t].events.length; m++) {\n if (block_results.results[t].events[m].attributes.find(a => decodeAttr(a.key) == \"msg_index\")) {\n const mi = decodeAttr(block_results.results[t].events[m].attributes.find(a => decodeAttr(a.key) == \"msg_index\")?.value ?? \"\");\n if (mi != \"\") {\n const miNum = parseInt(mi);\n let ev = eventsToAdd.find(x => x.msg_index == miNum);\n if (!ev) {\n ev = {\n msg_index: miNum,\n events: [block_results.results[t].events[m]],\n };\n eventsToAdd.push(ev);\n }\n else {\n ev.events.push(block_results.results[t].events[m] as Event);\n }\n }\n }\n }\n events = events.concat(eventsToAdd);\n }\n const msgs = tx.body?.messages;\n\n if (msgs) {\n for (let i = 0; i < msgs.length; i++) {\n this.log.silly(\"Indexer broadcasting msg for handling: \" + msgs[i].typeUrl);\n const msgevents\n = msgs.length > 1\n ? events.find(x => x.msg_index == i)?.events\n : events[0].events;\n await this.asyncEmit(msgs[i].typeUrl as never,\n {\n value: {\n tx: msgs[i].value as never,\n events: msgevents,\n } as never,\n height,\n timestamp,\n });\n if (msgs[i].typeUrl == \"/cosmos.authz.v1beta1.MsgExec\") {\n const authzMsgs = MsgExec.decode(msgs[i].value).msgs;\n if (authzMsgs) {\n for (let r = 0; r < authzMsgs.length; r++) {\n this.log.silly(\"Indexer broadcasting msg for handling: \" + authzMsgs[r].typeUrl);\n const authzMsgEvents = msgevents?.reduce((events, evt) => {\n if (evt.attributes.filter(x => decodeAttr(x.key) == \"authz_msg_index\" && decodeAttr(x.value) == \"\" + r).length > 0) {\n events.push(evt);\n }\n return events;\n },\n [] as (Event | Event38)[]);\n await this.asyncEmit(authzMsgs[r].typeUrl as never,\n {\n value: {\n tx: authzMsgs[r].value as never,\n events: authzMsgEvents,\n } as never,\n height,\n timestamp,\n });\n }\n }\n }\n }\n }\n }\n this.log.silly(\"Modules handled msg events\");\n this.prometheus?.recordTransactions(block.block.txs.length);\n // Then deal with end_block events\n await this.asyncEmit(\"end_block\",\n {\n value: endBlockEvents!,\n height,\n timestamp,\n });\n this.log.silly(\"Modules handled end_block events\");\n\n endTimer?.();\n this.prometheus?.updateBlockMetrics(height, this.latestHeight, this.blockQueue.size());\n }\n\n private async fetcher() {\n for (let i = this.heightToProcess; i <= this.latestHeight; i++) {\n // If some other async process triggers recovery, exit the fetching loop\n if (this.tryToRecover) {\n this.log.verbose(\"Exiting fetcher loop. Attempting to recover indexer\");\n break;\n }\n this.log.debug(\"Fetching: \" + i);\n try {\n // Main fetching logic for minimal indexer\n if (this.isMinimal(this.blockQueue)) {\n const timeoutPromise: Promise<[BlockResponse, BlockResultsResponse]> = new Promise((resolve, reject) => {\n setTimeout(reject,\n RPC_TIMEOUT_MS,\n false);\n });\n // We do not await here so that multiple fetches can be in-flight\n const toIndex = Promise.race([Promise.all([this.blockClient.block(i) as Promise<BlockResponse>, this.blockClient.blockResults(i) as Promise<BlockResultsResponse>]), timeoutPromise]).catch((e) => {\n this.log.error(\"Error fetching block: \" + i + \" : \" + e);\n this.prometheus?.recordError(\"rpc\");\n this.tryToRecover = true;\n return Promise.resolve([]);\n }) as Promise<[BlockResponse, BlockResultsResponse]>;\n this.blockQueue.enqueue(toIndex);\n }\n else {\n // Main fetching logic for minimal indexer\n const timeoutPromise: Promise<[BlockResponse, BlockResultsResponse, Uint8Array]> = new Promise((resolve, reject) => {\n setTimeout(reject,\n RPC_TIMEOUT_MS,\n false);\n });\n const q = QueryValidatorsRequest.fromPartial({\n pagination: {\n limit: PAGINATION_LIMITS.VALIDATORS,\n },\n });\n const vals = QueryValidatorsRequest.encode(q).finish();\n // We do not await here so that multiple fetches can be in-flight\n const toIndex = Promise.race([\n Promise.all([\n this.blockClient.block(i) as Promise<BlockResponse>,\n this.blockClient.blockResults(i) as Promise<BlockResultsResponse>,\n this.callABCI(\"/cosmos.staking.v1beta1.Query/Validators\",\n vals,\n i,\n false),\n ]),\n timeoutPromise,\n ]).catch((e) => {\n this.log.error(\"Error fetching block: \" + i + \" : \" + e);\n this.tryToRecover = true;\n return Promise.resolve([]);\n }) as Promise<[BlockResponse, BlockResultsResponse, Uint8Array]>;\n this.blockQueue.enqueue(toIndex);\n }\n }\n catch (e) {\n this.log.error(\"Fetching error: \" + e);\n break;\n }\n await this.blockQueue.continue();\n if (this.tryToRecover) {\n this.log.verbose(\"Exiting fetcher loop. Attempting to recover indexer\");\n break;\n }\n }\n // If we exit the fetching loop without errors, we are synced\n if (!this.tryToRecover) {\n this.blockQueue.setSynced();\n this.log.info(\"Synced to latest height\");\n }\n }\n\n public async callABCI(path: string, data: Uint8Array, height?: number, adHoc: boolean = true): Promise<Uint8Array> {\n try {\n const endTimer = this.prometheus?.timeRpcCall(path) ?? void 0;\n const abciq = await\n (adHoc\n ? this.client\n : this.blockClient).abciQuery({\n path,\n data,\n height: height,\n });\n endTimer?.();\n if (abciq) {\n return abciq.value;\n }\n else {\n this.tryToRecover = true;\n this.setStatus(\"FAILED\");\n this.prometheus?.recordError(\"rpc\");\n throw new Error(\"RPC not responding. Query at: \" + path);\n }\n }\n catch (_e) {\n this.tryToRecover = true;\n this.setStatus(\"FAILED\");\n this.retryCount++;\n throw new Error(\"RPC not responding. Query at: \" + path);\n }\n }\n\n private newBlockReceived(height: number): void {\n if (this.blockTimeout) {\n clearTimeout(this.blockTimeout);\n }\n this.blockTimeout = setTimeout(() => {\n this.tryToRecover = true;\n }, 30000);\n this.log.info(\"Received new block: %d\",\n height);\n if (height == this.latestHeight) {\n return;\n }\n // If we are synced, add to end of queue\n if (this.blockQueue.synced && !this.tryToRecover) {\n this.latestHeight = height;\n if (this.blockQueue.size() + 1 == this.config.batchSize) {\n this.prometheus?.recordError(\"block\");\n this.log.error(\"Block queue is full. Cannot add new block\");\n this.tryToRecover = true;\n this.retryCount++;\n return;\n }\n try {\n if (this.isMinimal(this.blockQueue)) {\n this.blockQueue.enqueue(Promise.all([this.client.block(height) as Promise<BlockResponse>, this.client.blockResults(height) as Promise<BlockResultsResponse>]).catch((e) => {\n this.log.error(\"Error fetching block: \" + height + \" : \" + e);\n\n return Promise.resolve([]);\n }) as Promise<[BlockResponse, BlockResultsResponse]>);\n }\n else {\n const q = QueryValidatorsRequest.fromPartial({\n pagination: {\n limit: 1000n,\n },\n });\n const vals = QueryValidatorsRequest.encode(q).finish();\n this.blockQueue.enqueue(Promise.all([\n this.client.block(height) as Promise<BlockResponse>,\n this.client.blockResults(height) as Promise<BlockResultsResponse>,\n this.callABCI(\"/cosmos.staking.v1beta1.Query/Validators\",\n vals,\n height,\n false),\n ]).catch((e) => {\n this.log.error(\"Error fetching block: \" + height + \" : \" + e);\n return Promise.resolve([]);\n }) as Promise<[BlockResponse, BlockResultsResponse, Uint8Array]>);\n }\n }\n catch (e) {\n this.log.error(\"New Block Received error: \" + e);\n }\n }\n else {\n this.latestHeight = height;\n }\n }\n\n private async pollForBlock() {\n try {\n const status = await this.client.status();\n if (status.syncInfo.latestBlockHeight > this.latestHeight) {\n while (this.latestHeight < status.syncInfo.latestBlockHeight) {\n this.newBlockReceived(this.latestHeight + 1);\n }\n }\n setTimeout(() => {\n this.pollForBlock();\n },\n this.config.pollingInterval);\n }\n catch (e) {\n this.log.error(\"Error polling for new block: \" + e);\n this.tryToRecover = true;\n this.retryCount++;\n }\n }\n\n private readGenesis(): Parser.Parser {\n if (this.config.genesisPath) {\n return fs.createReadStream(this.config.genesisPath).pipe(Parser.parser());\n }\n else {\n throw new Error(\"Genesis path not set\");\n }\n }\n\n private async setArrayReader(path: string, processor: (chunk: unknown) => Promise<void>): Promise<boolean> {\n const readPromise = new Promise<boolean>((resolve, reject) => {\n try {\n const filters = path.split(\".\");\n const pickers = filters.map(filter => Pick.pick({\n filter,\n }));\n let counter = 0;\n let chunkCounter = 0;\n\n // Wrapper processor that handles transaction chunking\n const chunkProcessor = async (data: unknown) => {\n chunkCounter++;\n this.log.debug(`Processing genesis chunk ${chunkCounter}`);\n\n await processor(data);\n\n // Commit and restart transaction every 5 chunks (5000 entries)\n // This prevents timeout on large genesis files\n if (chunkCounter % 5 === 0) {\n this.log.debug(`Committing transaction after chunk ${chunkCounter}`);\n await this.config.endTransaction(true);\n await this.config.beginTransaction();\n }\n };\n\n chain([\n this.readGenesis(),\n ...pickers,\n StreamArray.streamArray(),\n Batch.batch({\n batchSize: GENESIS_BATCH_SIZE,\n }),\n chunkProcessor,\n ])\n .on(\"data\",\n (data) => {\n if (data && Array.isArray(data)) {\n counter = counter + data.length;\n }\n })\n .on(\"end\",\n () => {\n this.log.info(`Processed ${counter} entries in ${chunkCounter} chunks`);\n resolve(true);\n });\n }\n catch (_e) {\n this.log.verbose(\"Error in setArrayReader: \" + _e);\n reject();\n }\n });\n\n return readPromise;\n }\n\n private async setValueReader(path: string, processor: (chunk: unknown) => Promise<void>): Promise<boolean> {\n const readPromise = new Promise<boolean>((resolve, reject) => {\n try {\n const filters = path.split(\".\");\n const pickers = filters.map(filter => Pick.pick({\n filter,\n }));\n\n let counter = 0;\n chain([this.readGenesis(), ...pickers, StreamValues.streamValues(), processor])\n .on(\"data\",\n (_data) => {\n counter++;\n })\n .on(\"end\",\n () => {\n this.log.info(`Processed ${counter} entries`);\n resolve(true);\n });\n }\n catch (_e) {\n reject();\n }\n });\n\n return readPromise;\n }\n\n private async parseGenesis() {\n this.log.info(\"Parsing genesis\");\n await this.config.beginTransaction();\n try {\n this.log.info(\"Starting genesis import\");\n this.log.debug(\"Importing genesis file...\");\n\n for (const [key, _value] of this.handled) {\n if (key.startsWith(\"genesis/\")) {\n const genesisEntry = key.split(\"/\");\n\n this.log.verbose(\"Importing \" + key + \"...\");\n if (genesisEntry[1] == \"array\") {\n await this.setArrayReader(genesisEntry[2],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async (data: any) => {\n await this.asyncEmit(key as never,\n {\n value: data.map((x: {\n value: never\n }) => x.value),\n } as never);\n return data;\n });\n }\n else {\n await this.setValueReader(genesisEntry[2],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async (data: any) => {\n await this.asyncEmit(key as never,\n {\n value: data.value,\n } as never);\n return data;\n });\n }\n }\n }\n\n this.log.info(\"Importing gen TXs...\");\n\n await this.setArrayReader(\"app_state.genutil.gen_txs\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async (data: any) => {\n for (let j = 0; j < data.length; j++) {\n const gentx = data[j].value;\n for (let i = 0; i < gentx.body.messages.length; i++) {\n const msg = gentx.body.messages[i];\n await this.asyncEmit((\"gentx\" + msg[\"@type\"]) as never,\n {\n value: msg,\n } as never);\n }\n }\n return data;\n });\n await this.config.endTransaction(true);\n\n this.log.info(\"Finished importing\");\n }\n catch (e) {\n try {\n await this.config.endTransaction(false);\n }\n catch (dbe) {\n this.prometheus?.recordError(\"database\");\n this.log.error(\"Error ending transaction. Must be a DB error: \" + dbe);\n }\n this.log.error(\"Failed to import genesis\");\n throw e;\n }\n }\n}\n"],"mappings":"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"}
@@ -72,7 +72,10 @@ declare class EcleciaIndexer extends EclesiaEmitter {
72
72
  private blockListener;
73
73
  private isMinimal;
74
74
  connect(): Promise<boolean>;
75
+ private initialize;
75
76
  stop(): void;
77
+ private clearBlockQueue;
78
+ private setupBlockListening;
76
79
  start(): Promise<void>;
77
80
  asyncEmit: EmitFunc<keyof WithHeightAndUUID<EventMap>>;
78
81
  private processBlock;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/indexer/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAmEa;EAAA,WAAA,EAAA,MAAA;EAKS,SAAA,EAAA,MAAA;;;EAWa,QAAA,EAXb,oBAWa,CAAA,UAAA,CAAA;EAAA,UAAA,EAAA,OAAA;EAOtB,eAAA,EAAe,MAAA;EAEX,oBAAA,EAAA,GAAA,GAAA,OAAA;EAwBI,OAAA,EAAA,OAAA;EAMH,iBAAA,EAAA,OAAA;EAGK,eAAA,EAAA,MAAA;EAGT,gBAAQ,EAAA,OAAA;EAoBA,cAAA,EAAA,MAAA;EAoLA,IAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EA4BF,gBAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EAgNiC,cAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,GAjelB,OAiekB,CAAA,IAAA,CAAA;CAAlB;;;;;AA1dC,cAAvB,cAAA,SAAuB,cAAA,CAAA;EAAc;UAEjC;;;;;;;;;;;;;;;;cAwBI;;;;UAMH;;eAGK;;OAGT,OAAA,CAAQ;;;;;;;;;;;;;sBAoBA;;;;aAoLA;;WA4BF;aAgNA,eAAe,kBAAkB;;;+BAkTT,+CAAqD,QAAQ"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/indexer/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAuEa;EAAA,WAAA,EAAA,MAAA;EAKS,SAAA,EAAA,MAAA;;;EAWa,QAAA,EAXb,oBAWa,CAAA,UAAA,CAAA;EAAA,UAAA,EAAA,OAAA;EAOtB,eAAA,EAAe,MAAA;EAEX,oBAAA,EAAA,GAAA,GAAA,OAAA;EAwBI,OAAA,EAAA,OAAA;EAMH,iBAAA,EAAA,OAAA;EAGK,eAAA,EAAA,MAAA;EAGT,gBAAQ,EAAA,OAAA;EAoBA,cAAA,EAAA,MAAA;EAoLA,IAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EAsHF,gBAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EAqJiC,cAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,GAhgBlB,OAggBkB,CAAA,IAAA,CAAA;CAAlB;;;;;AAzfC,cAAvB,cAAA,SAAuB,cAAA,CAAA;EAAc;UAEjC;;;;;;;;;;;;;;;;cAwBI;;;;UAMH;;eAGK;;OAGT,OAAA,CAAQ;;;;;;;;;;;;;sBAoBA;;;;aAoLA;;;;;WAsHF;aAqJA,eAAe,kBAAkB;;;+BAoST,+CAAqD,QAAQ"}
@@ -72,7 +72,10 @@ declare class EcleciaIndexer extends EclesiaEmitter {
72
72
  private blockListener;
73
73
  private isMinimal;
74
74
  connect(): Promise<boolean>;
75
+ private initialize;
75
76
  stop(): void;
77
+ private clearBlockQueue;
78
+ private setupBlockListening;
76
79
  start(): Promise<void>;
77
80
  asyncEmit: EmitFunc<keyof WithHeightAndUUID<EventMap>>;
78
81
  private processBlock;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/indexer/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAmEa;EAAA,WAAA,EAAA,MAAA;EAKS,SAAA,EAAA,MAAA;;;EAWa,QAAA,EAXb,oBAWa,CAAA,UAAA,CAAA;EAAA,UAAA,EAAA,OAAA;EAOtB,eAAA,EAAe,MAAA;EAEX,oBAAA,EAAA,GAAA,GAAA,OAAA;EAwBI,OAAA,EAAA,OAAA;EAMH,iBAAA,EAAA,OAAA;EAGK,eAAA,EAAA,MAAA;EAGT,gBAAQ,EAAA,OAAA;EAoBA,cAAA,EAAA,MAAA;EAoLA,IAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EA4BF,gBAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EAgNiC,cAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,GAjelB,OAiekB,CAAA,IAAA,CAAA;CAAlB;;;;;AA1dC,cAAvB,cAAA,SAAuB,cAAA,CAAA;EAAc;UAEjC;;;;;;;;;;;;;;;;cAwBI;;;;UAMH;;eAGK;;OAGT,OAAA,CAAQ;;;;;;;;;;;;;sBAoBA;;;;aAoLA;;WA4BF;aAgNA,eAAe,kBAAkB;;;+BAkTT,+CAAqD,QAAQ"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/indexer/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAuEa;EAAA,WAAA,EAAA,MAAA;EAKS,SAAA,EAAA,MAAA;;;EAWa,QAAA,EAXb,oBAWa,CAAA,UAAA,CAAA;EAAA,UAAA,EAAA,OAAA;EAOtB,eAAA,EAAe,MAAA;EAEX,oBAAA,EAAA,GAAA,GAAA,OAAA;EAwBI,OAAA,EAAA,OAAA;EAMH,iBAAA,EAAA,OAAA;EAGK,eAAA,EAAA,MAAA;EAGT,gBAAQ,EAAA,OAAA;EAoBA,cAAA,EAAA,MAAA;EAoLA,IAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EAsHF,gBAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EAqJiC,cAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,GAhgBlB,OAggBkB,CAAA,IAAA,CAAA;CAAlB;;;;;AAzfC,cAAvB,cAAA,SAAuB,cAAA,CAAA;EAAc;UAEjC;;;;;;;;;;;;;;;;cAwBI;;;;UAMH;;eAGK;;OAGT,OAAA,CAAQ;;;;;;;;;;;;;sBAoBA;;;;aAoLA;;;;;WAsHF;aAqJA,eAAe,kBAAkB;;;+BAoST,+CAAqD,QAAQ"}