From a6feb838cde72091a478faf90f3379e603b2eb74 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 5 Nov 2024 11:53:48 -0500 Subject: [PATCH] feat(benchmark): add very basic benchmarking Signed-off-by: david --- packages/benchmark/.mocharc.json | 10 ++ packages/benchmark/README.md | 29 +++++ packages/benchmark/eslint.config.js | 6 + packages/benchmark/package.json | 43 +++++++ packages/benchmark/src/aggregate.ts | 0 packages/benchmark/src/benchmark.test.ts | 43 +++++++ packages/benchmark/src/benchmark.ts | 113 ++++++++++++++++++ packages/benchmark/src/index.ts | 1 + packages/benchmark/tsconfig.json | 6 + packages/indexer/package.json | 3 +- .../service/AcrossIndexerManager.ts | 26 +++- packages/indexer/src/main.ts | 43 ++++++- packages/indexer/src/parseEnv.ts | 8 +- .../src/services/spokePoolProcessor.ts | 51 +++++--- packages/indexer/src/utils/benchmarks.ts | 56 +++++++++ packages/indexer/src/utils/contractUtils.ts | 2 +- .../indexer/src/web3/RetryProvidersFactory.ts | 1 - pnpm-lock.yaml | 86 ++++++++++--- 18 files changed, 485 insertions(+), 42 deletions(-) create mode 100644 packages/benchmark/.mocharc.json create mode 100644 packages/benchmark/README.md create mode 100644 packages/benchmark/eslint.config.js create mode 100644 packages/benchmark/package.json create mode 100644 packages/benchmark/src/aggregate.ts create mode 100644 packages/benchmark/src/benchmark.test.ts create mode 100644 packages/benchmark/src/benchmark.ts create mode 100644 packages/benchmark/src/index.ts create mode 100644 packages/benchmark/tsconfig.json create mode 100644 packages/indexer/src/utils/benchmarks.ts diff --git a/packages/benchmark/.mocharc.json b/packages/benchmark/.mocharc.json new file mode 100644 index 00000000..f56d1f99 --- /dev/null +++ b/packages/benchmark/.mocharc.json @@ -0,0 +1,10 @@ +{ + "extension": [ + "ts" + ], + "spec": "**/*.test.ts", + "require": [ + "ts-node/register" + ], + "recursive": true +} diff --git a/packages/benchmark/README.md b/packages/benchmark/README.md new file mode 100644 index 00000000..2f888b01 --- /dev/null +++ b/packages/benchmark/README.md @@ -0,0 +1,29 @@ +# Package Name +This is meant to be a template for quickly adding new package libraries. Replace this readme with relevant information for your package. + +## Adding a new package +1. go into the package folder in this repo. +2. cp -r template your_package_name +3. Edit the package.json file renaming the "name" property. +4. add dependencies as needed. + +## Template features +This template will set you up with typescript, eslint, prettier, some basic scripts, and a main file entry point. + +### Scripts +- build - typescript build and output to dist +- watch - build watching for changes +- format - prettier code fixing +- lint - eslint code fixing +- fix - eslint and prettier code fixing +- lint:check - eslint code checking ( no changes ) +- format:check - prettier code checking ( no changes ) +- build:check - run type check without emitting files +- check - eslint and prettier and typescript code checking ( no changes ) +- test - run mocha testing +- test:watch - run mocha testing +- coverage - see testing coverage + +### Adding tests +Add a `example.test.ts` file to any folder and mocha will find it. +** note: chai v5 breaks typescript support, so we explicitly use chai 4 ** diff --git a/packages/benchmark/eslint.config.js b/packages/benchmark/eslint.config.js new file mode 100644 index 00000000..3f2bce22 --- /dev/null +++ b/packages/benchmark/eslint.config.js @@ -0,0 +1,6 @@ + // .eslintrc.js in the new package +module.exports = { + root:true, + extends: ['@repo/eslint-config/library.js'], +}; + diff --git a/packages/benchmark/package.json b/packages/benchmark/package.json new file mode 100644 index 00000000..10f0ddc5 --- /dev/null +++ b/packages/benchmark/package.json @@ -0,0 +1,43 @@ +{ + "name": "@repo/benchmark", + "version": "0.0.1", + "description": "", + "main": "index.js", + "scripts": { + "build": "tsc -b", + "build:check": "tsc --noEmit", + "watch": "tsc -b --watch", + "fix": "pnpm format && pnpm lint", + "format": "prettier --write src", + "format:check": "prettier src --check", + "lint": "eslint --fix", + "lint:check": "eslint", + "check": "pnpm format:check && pnpm lint:check && pnpm build:check", + "test": "mocha", + "coverage": "nyc mocha", + "test:watch": "mocha --watch" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + }, +"exports": { + ".": "./dist/index.js" + }, + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "^1.0.2", + "@repo/eslint-config": "workspace:*", + "@repo/typescript-config": "workspace:*", + "@types/chai": "^4.3.17", + "@types/mocha": "^10.0.7", + "chai": "^4.5.0", + "eslint": "^8.57.0", + "mocha": "^10.7.0", + "nyc": "^17.0.0", + "prettier": "^3.3.3", + "source-map-support": "^0.5.21", + "ts-node": "^10.9.2", + "typescript": "^5.5.4" + } +} diff --git a/packages/benchmark/src/aggregate.ts b/packages/benchmark/src/aggregate.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/benchmark/src/benchmark.test.ts b/packages/benchmark/src/benchmark.test.ts new file mode 100644 index 00000000..ff3dc7df --- /dev/null +++ b/packages/benchmark/src/benchmark.test.ts @@ -0,0 +1,43 @@ +import { expect } from "chai"; +import { Benchmark } from "./benchmark"; + +describe("Benchmark", () => { + let benchmark: Benchmark; + + beforeEach(() => { + benchmark = new Benchmark(); + }); + + it("should start and end a benchmark event correctly", async () => { + benchmark.start("testEvent", 0); + const duration = benchmark.end("testEvent", 1); + expect(duration).to.be.a("number"); + expect(duration).to.be.greaterThan(0); + }); + + it("should throw an error if end is called without start", () => { + expect(() => benchmark.end("nonExistentEvent")).to.throw( + Error, + 'Benchmark for event "nonExistentEvent" not started. Call start() before end().', + ); + }); + + it("should handle multiple events independently", () => { + benchmark.start("event1", 0); + benchmark.start("event2", 0); + + const duration1 = benchmark.end("event1", 1); + expect(duration1).to.be.a("number"); + expect(duration1).to.be.greaterThan(0); + + const duration2 = benchmark.end("event2", 1); + expect(duration2).to.be.a("number"); + expect(duration2).to.be.greaterThan(0); + }); + + it("should throw an error if the same event is started twice without ending", () => { + benchmark.start("duplicateEvent"); + expect(() => benchmark.start("duplicateEvent")).to.not.throw(); + expect(() => benchmark.end("duplicateEvent")).to.not.throw(); + }); +}); diff --git a/packages/benchmark/src/benchmark.ts b/packages/benchmark/src/benchmark.ts new file mode 100644 index 00000000..e0fdae3b --- /dev/null +++ b/packages/benchmark/src/benchmark.ts @@ -0,0 +1,113 @@ +/** + * A class to benchmark events by tracking their start and end times. + */ +export class Benchmark { + private events: Map; + + /** + * Initializes a new instance of the Benchmark class. + */ + constructor() { + this.events = new Map(); + } + + /** + * Starts tracking an event by storing its start time. + * + * @param {string} eventName - The name of the event to start tracking. + * @param {number} [now=Date.now()] - The current time in milliseconds. Defaults to the current time. + */ + start(eventName: string, now: number = Date.now()) { + this.events.set(eventName, now); + } + + /** + * Ends tracking an event and calculates its duration. + * + * @param {string} eventName - The name of the event to end tracking. + * @param {number} [now=Date.now()] - The current time in milliseconds. Defaults to the current time. + * @returns {number | undefined} The duration of the event in milliseconds, or undefined if the event was not started. + * @throws Will throw an error if the event was not started before calling this method. + */ + end(eventName: string, now: number = Date.now()): number | undefined { + const startTime = this.events.get(eventName); + if (startTime === undefined) { + throw new Error( + `Benchmark for event "${eventName}" not started. Call start() before end().`, + ); + } + const endTime = now; + const duration = endTime - startTime; + this.events.delete(eventName); + return duration; + } + + /** + * Clears events that are older than the specified age. + * + * @param {number} age - The age in milliseconds. Events older than this will be cleared. + * @param {number} [now=Date.now()] - The current time in milliseconds. Defaults to the current time. + */ + clear(age: number, now: number = Date.now()) { + for (const [eventName, startTime] of this.events.entries()) { + if (now - startTime > age) { + this.events.delete(eventName); + } + } + } + + /** + * Provides statistics about the currently tracked events. + * + * @param {number} [now=Date.now()] - The current time in milliseconds. Defaults to the current time. + * @returns {object} An object containing statistics about the events. + */ + getStats(now: number = Date.now()): { + total: number; + oldest: number | null; + newest: number | null; + average: number | null; + fastest: number | null; + slowest: number | null; + } { + const eventTimes = Array.from(this.events.values()); + const total = eventTimes.length; + + if (total === 0) { + return { + total, + oldest: null, + newest: null, + average: null, + fastest: null, + slowest: null, + }; + } + + let oldest = Number.MAX_VALUE; + let newest = Number.MIN_VALUE; + let totalAge = 0; + let fastest = Number.MAX_VALUE; + let slowest = Number.MIN_VALUE; + + for (const time of eventTimes) { + const age = now - time; + totalAge += age; + if (age < fastest) fastest = age; + if (age > slowest) slowest = age; + if (age < oldest) oldest = age; + if (age > newest) newest = age; + } + + const average = totalAge / total; + + return { + total, + oldest, + newest, + average, + fastest, + slowest, + }; + } +} diff --git a/packages/benchmark/src/index.ts b/packages/benchmark/src/index.ts new file mode 100644 index 00000000..765a23c9 --- /dev/null +++ b/packages/benchmark/src/index.ts @@ -0,0 +1 @@ +export * from "./benchmark"; diff --git a/packages/benchmark/tsconfig.json b/packages/benchmark/tsconfig.json new file mode 100644 index 00000000..4cf9c4aa --- /dev/null +++ b/packages/benchmark/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends":"@repo/typescript-config/base.json", + "compilerOptions": { + "outDir": "./dist" /* Specify an output folder for all emitted files. */ + } +} diff --git a/packages/indexer/package.json b/packages/indexer/package.json index 0bf4814e..df899c5c 100644 --- a/packages/indexer/package.json +++ b/packages/indexer/package.json @@ -31,7 +31,8 @@ "lodash": "^4.17.21", "redis": "^4.7.0", "superstruct": "^2.0.3-1", - "winston": "^3.13.1" + "winston": "^3.13.1", + "@repo/benchmark": "workspace:*" }, "exports": { ".": "./dist/index.js" diff --git a/packages/indexer/src/data-indexing/service/AcrossIndexerManager.ts b/packages/indexer/src/data-indexing/service/AcrossIndexerManager.ts index 38d9aa0c..16c7d4c9 100644 --- a/packages/indexer/src/data-indexing/service/AcrossIndexerManager.ts +++ b/packages/indexer/src/data-indexing/service/AcrossIndexerManager.ts @@ -8,7 +8,10 @@ import { RedisCache } from "../../redis/redisCache"; import { RetryProvidersFactory } from "../../web3/RetryProvidersFactory"; import { SpokePoolRepository } from "../../database/SpokePoolRepository"; import { IndexerQueuesService } from "../../messaging/service"; -import { SpokePoolProcessor } from "../../services/spokePoolProcessor"; +import { + SpokePoolProcessor, + SpokePoolEventParams, +} from "../../services/spokePoolProcessor"; import { HubPoolIndexerDataHandler } from "./HubPoolIndexerDataHandler"; import { SpokePoolIndexerDataHandler } from "./SpokePoolIndexerDataHandler"; @@ -41,10 +44,12 @@ export class AcrossIndexerManager { private indexerQueuesService: IndexerQueuesService, ) {} - public async start() { + public async start( + callback?: (chainId: number, events: SpokePoolEventParams) => void, + ) { return Promise.all([ this.startHubPoolIndexer(), - this.startSpokePoolIndexers(), + this.startSpokePoolIndexers(callback), ]); } @@ -81,7 +86,9 @@ export class AcrossIndexerManager { return this.hubPoolIndexer.start(); } - private async startSpokePoolIndexers() { + private async startSpokePoolIndexers( + callback?: (chainId: number, events: SpokePoolEventParams) => void, + ) { const spokePoolIndexers = this.config.spokePoolChainsEnabled.map( (chainId) => { const spokePoolIndexerDataHandler = new SpokePoolIndexerDataHandler( @@ -93,7 +100,16 @@ export class AcrossIndexerManager { this.hubPoolClientFactory, this.spokePoolClientFactory, this.spokePoolRepository, - new SpokePoolProcessor(this.postgres, this.logger, chainId), + new SpokePoolProcessor( + this.postgres, + this.logger, + chainId, + (events: SpokePoolEventParams) => { + if (callback) { + callback(chainId, events); + } + }, + ), this.indexerQueuesService, ); const spokePoolIndexer = new Indexer( diff --git a/packages/indexer/src/main.ts b/packages/indexer/src/main.ts index 0d9edf53..59e83546 100644 --- a/packages/indexer/src/main.ts +++ b/packages/indexer/src/main.ts @@ -1,6 +1,7 @@ import winston from "winston"; import Redis from "ioredis"; import * as across from "@across-protocol/sdk"; +import { providers } from "ethers"; import { connectToDatabase } from "./database/database.provider"; import * as parseEnv from "./parseEnv"; @@ -8,6 +9,7 @@ import { RetryProvidersFactory } from "./web3/RetryProvidersFactory"; import { RedisCache } from "./redis/redisCache"; import { HubPoolRepository } from "./database/HubPoolRepository"; import { SpokePoolRepository } from "./database/SpokePoolRepository"; +import { SpokePoolEventParams } from "./services/spokePoolProcessor"; import { ConfigStoreClientFactory, HubPoolClientFactory, @@ -18,6 +20,8 @@ import { IndexerQueuesService } from "./messaging/service"; import { IntegratorIdWorker } from "./messaging/IntegratorIdWorker"; import { AcrossIndexerManager } from "./data-indexing/service/AcrossIndexerManager"; import { BundleServicesManager } from "./services/BundleServicesManager"; +import { Benchmark } from "@repo/benchmark"; +import { listenForDeposits } from "./utils/benchmarks"; async function initializeRedis( config: parseEnv.RedisConfig, @@ -53,6 +57,16 @@ export async function Main(config: parseEnv.Config, logger: winston.Logger) { const redis = await initializeRedis(redisConfig, logger); const redisCache = new RedisCache(redis); const postgres = await connectToDatabase(postgresConfig, logger); + + // Instantiate Benchmark and listen for deposits using all SpokePool providers + const depositBenchmark = new Benchmark(); + const providerChainIds = config.allProviderConfigs + .filter(([_, chainId]) => config.spokePoolChainsEnabled.includes(chainId)) + .map(([providerUrl, chainId]) => ({ + provider: new providers.JsonRpcProvider(providerUrl), + chainId: Number(chainId), + })); + // Retry providers factory const retryProvidersFactory = new RetryProvidersFactory( redisCache, @@ -108,6 +122,7 @@ export async function Main(config: parseEnv.Config, logger: winston.Logger) { retryProvidersFactory, ); + listenForDeposits(depositBenchmark, providerChainIds, logger); let exitRequested = false; process.on("SIGINT", () => { if (!exitRequested) { @@ -127,16 +142,42 @@ export async function Main(config: parseEnv.Config, logger: winston.Logger) { across.utils.delay(5).finally(() => process.exit()); } }); + // print benchmarks + setInterval(() => { + const stats = depositBenchmark.getStats(); + logger.info({ + at: "Indexer#Main", + message: "Benchmark Stats", + stats: { + totalEvents: stats.total, + oldestEventAge: stats.oldest, + newestEventAge: stats.newest, + averageEventDuration: stats.average, + fastestEventDuration: stats.fastest, + slowestEventDuration: stats.slowest, + }, + }); + const oneHourInMilliseconds = 60 * 60 * 1000; + depositBenchmark.clear(oneHourInMilliseconds); + }, 60000); logger.info({ message: "Running indexers", at: "Indexer#Main", }); + // start all indexers in parallel, will wait for them to complete, but they all loop independently const [bundleServicesManagerResults, acrossIndexerManagerResult] = await Promise.allSettled([ bundleServicesManager.start(), - acrossIndexerManager.start(), + acrossIndexerManager.start( + (chainId: number, events: SpokePoolEventParams) => { + events.deposits.forEach((deposit) => { + const uniqueId = `${chainId}-${deposit.depositId}`; + depositBenchmark.end(uniqueId); + }); + }, + ), ]); logger.info({ diff --git a/packages/indexer/src/parseEnv.ts b/packages/indexer/src/parseEnv.ts index 0ba792bd..9dc462a0 100644 --- a/packages/indexer/src/parseEnv.ts +++ b/packages/indexer/src/parseEnv.ts @@ -11,6 +11,7 @@ export type Config = { enableHubPoolIndexer: boolean; enableBundleEventsProcessor: boolean; enableBundleBuilder: boolean; + allProviderConfigs: ProviderConfig[]; }; export type RedisConfig = { host: string; @@ -66,7 +67,7 @@ function parsePostgresConfig( }; } -function parseProviderConfigs(env: Env): ProviderConfig[] { +export function parseProviderConfigs(env: Env = process.env): ProviderConfig[] { const results: ProviderConfig[] = []; for (const [key, value] of Object.entries(process.env)) { const match = key.match(/^RPC_PROVIDER_URLS_(\d+)$/); @@ -83,9 +84,9 @@ function parseProviderConfigs(env: Env): ProviderConfig[] { return results; } -export function parseProvidersUrls() { +export function parseProvidersUrls(env: Env = process.env) { const results: Map = new Map(); - for (const [key, value] of Object.entries(process.env)) { + for (const [key, value] of Object.entries(env)) { const match = key.match(/^RPC_PROVIDER_URLS_(\d+)$/); if (match) { const chainId = match[1] ? parseNumber(match[1]) : undefined; @@ -185,5 +186,6 @@ export function envToConfig(env: Env): Config { enableHubPoolIndexer, enableBundleEventsProcessor, enableBundleBuilder, + allProviderConfigs, }; } diff --git a/packages/indexer/src/services/spokePoolProcessor.ts b/packages/indexer/src/services/spokePoolProcessor.ts index cc2f0c21..19157b4f 100644 --- a/packages/indexer/src/services/spokePoolProcessor.ts +++ b/packages/indexer/src/services/spokePoolProcessor.ts @@ -9,42 +9,66 @@ enum SpokePoolEvents { RequestedV3SlowFill = "RequestedV3SlowFill", } +export type SpokePoolEventParams = { + deposits: entities.V3FundsDeposited[]; + fills: entities.FilledV3Relay[]; + slowFillRequests: entities.RequestedV3SlowFill[]; + executedRefundRoots: entities.ExecutedRelayerRefundRoot[]; +}; + +type SpokePoolEventsCallback = (events: SpokePoolEventParams) => void; + export class SpokePoolProcessor { private queryBatchSize = 100; + private callback: SpokePoolEventsCallback | null; constructor( private readonly postgres: DataSource, private readonly logger: winston.Logger, private readonly chainId: number, - ) {} - - public async process(events: { - deposits: entities.V3FundsDeposited[]; - fills: entities.FilledV3Relay[]; - slowFillRequests: entities.RequestedV3SlowFill[]; - executedRefundRoots: entities.ExecutedRelayerRefundRoot[]; - }) { - if (events.deposits.length > 0) + callback?: SpokePoolEventsCallback, + ) { + this.callback = callback || null; + } + + public async process(events: SpokePoolEventParams) { + if (events.deposits.length > 0) { await this.assignSpokeEventsToRelayHashInfo( SpokePoolEvents.V3FundsDeposited, events.deposits, ); - if (events.slowFillRequests.length > 0) + } + if (events.slowFillRequests.length > 0) { await this.assignSpokeEventsToRelayHashInfo( SpokePoolEvents.RequestedV3SlowFill, events.slowFillRequests, ); - if (events.fills.length > 0) + } + if (events.fills.length > 0) { await this.assignSpokeEventsToRelayHashInfo( SpokePoolEvents.FilledV3Relay, events.fills, ); + } await this.updateExpiredRelays(); await this.updateRefundedDepositsStatus(); + + if (this.callback) { + try { + this.callback(events); + } catch (error) { + this.logger.error({ + at: "SpokePoolProcessor#process", + message: "Error in callback execution", + error, + }); + } + } } /** * Updates relayHashInfo table to include recently stored events + * @param eventType The type of event being processed. * @param events An array of already stored deposits, fills or slow fill requests * @returns A void promise */ @@ -152,7 +176,6 @@ export class SpokePoolProcessor { let updatedRows = 0; for (const expiredDeposit of expiredDeposits) { - // Check if this deposited is associated with a bundle const refundBundleEvent = await bundleEventsRepository .createQueryBuilder("be") .leftJoinAndSelect("bundle", "bundle", "be.bundleId = bundle.id") @@ -165,10 +188,8 @@ export class SpokePoolProcessor { .getOne(); if (!refundBundleEvent) continue; - // Get the relayerRefundRoot that included this refund const relayerRefundRoot = refundBundleEvent.bundle.relayerRefundRoot; - // Look for a relayed root bundle event that matches the relayerRefundRoot const relayRootBundleRepo = this.postgres.getRepository( entities.RelayedRootBundle, ); @@ -182,7 +203,6 @@ export class SpokePoolProcessor { .getOne(); if (!relayedRootBundleEvent) continue; - // Look for the execution of the relayer refund root using the rootBundleId const rootBundleId = relayedRootBundleEvent.rootBundleId; const executedRelayerRefundRepo = this.postgres.getRepository( entities.ExecutedRelayerRefundRoot, @@ -196,7 +216,6 @@ export class SpokePoolProcessor { .getOne(); if (!executedRelayerRefundRootEvent) continue; - // If we found the execution of the relayer refund root, we can update the relay status await relayHashInfoRepository .createQueryBuilder() .update() diff --git a/packages/indexer/src/utils/benchmarks.ts b/packages/indexer/src/utils/benchmarks.ts new file mode 100644 index 00000000..6a711ca4 --- /dev/null +++ b/packages/indexer/src/utils/benchmarks.ts @@ -0,0 +1,56 @@ +import { Contract, ethers, providers } from "ethers"; +import { Benchmark } from "@repo/benchmark"; +import winston from "winston"; +import { + getDeployedAddress, + getDeployedBlockNumber, + SpokePool__factory as SpokePoolFactory, +} from "@across-protocol/contracts"; +import { getAddress } from "./contractUtils"; + +export type GetSpokeClientParams = { + provider: providers.Provider; + address: string; +}; + +export function getSpokepoolContract(params: GetSpokeClientParams) { + return SpokePoolFactory.connect(params.address, params.provider); +} +export type ProviderChainId = { + provider: providers.Provider; + chainId: number; +}; + +export function listenForDeposits( + benchmark: Benchmark, + chains: ProviderChainId[], + logger: winston.Logger, +) { + const spokeClients = chains.map(({ provider, chainId }) => { + const address = getAddress("SpokePool", chainId); + return getSpokepoolContract({ provider, address }); + }); + spokeClients.forEach((spokeClient) => { + spokeClient.on( + "V3FundsDeposited", + ( + inputToken, + outputToken, + inputAmount, + outputAmount, + destinationChainId, + depositId, + quoteTimestamp, + fillDeadline, + exclusivityDeadline, + depositor, + recipient, + exclusiveRelayer, + message, + ) => { + const uniqueId = `${spokeClient.chainId}-${depositId}`; + benchmark.start(uniqueId); + }, + ); + }); +} diff --git a/packages/indexer/src/utils/contractUtils.ts b/packages/indexer/src/utils/contractUtils.ts index 47916666..73dc6c94 100644 --- a/packages/indexer/src/utils/contractUtils.ts +++ b/packages/indexer/src/utils/contractUtils.ts @@ -22,7 +22,7 @@ export type GetSpokeClientParams = { hubPoolClient: across.clients.HubPoolClient; }; -function getAddress(contractName: string, chainId: number): string { +export function getAddress(contractName: string, chainId: number): string { const address = getDeployedAddress(contractName, chainId); if (!address) { throw new Error( diff --git a/packages/indexer/src/web3/RetryProvidersFactory.ts b/packages/indexer/src/web3/RetryProvidersFactory.ts index 9c37a895..5c9b1a61 100644 --- a/packages/indexer/src/web3/RetryProvidersFactory.ts +++ b/packages/indexer/src/web3/RetryProvidersFactory.ts @@ -15,7 +15,6 @@ export class RetryProvidersFactory { public initializeProviders(): RetryProvidersFactory { const providersUrls = parseProvidersUrls(); - for (const [chainId, providerUrls] of providersUrls.entries()) { const retryProviderEnvs = parseRetryProviderEnvs(chainId); if (!providerUrls || providerUrls.length === 0) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e0074ca..02724583 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -64,6 +64,48 @@ importers: specifier: ^5.5.4 version: 5.5.4 + packages/benchmark: + devDependencies: + '@istanbuljs/nyc-config-typescript': + specifier: ^1.0.2 + version: 1.0.2(nyc@17.0.0) + '@repo/eslint-config': + specifier: workspace:* + version: link:../eslint-config + '@repo/typescript-config': + specifier: workspace:* + version: link:../typescript-config + '@types/chai': + specifier: ^4.3.17 + version: 4.3.17 + '@types/mocha': + specifier: ^10.0.7 + version: 10.0.7 + chai: + specifier: ^4.5.0 + version: 4.5.0 + eslint: + specifier: ^8.57.0 + version: 8.57.0 + mocha: + specifier: ^10.7.0 + version: 10.7.0 + nyc: + specifier: ^17.0.0 + version: 17.0.0 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + source-map-support: + specifier: ^0.5.21 + version: 0.5.21 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@22.7.3)(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 + packages/eslint-config: devDependencies: '@typescript-eslint/eslint-plugin': @@ -99,6 +141,9 @@ importers: '@across-protocol/sdk': specifier: ^3.2.2 version: 3.2.2(@babel/core@7.25.2)(@eth-optimism/contracts@0.6.0(bufferutil@4.0.8)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@ethersproject/abi@5.7.0)(@ethersproject/hardware-wallets@5.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(bufferutil@4.0.8)(encoding@0.1.13)(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typechain@4.0.3(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) + '@repo/benchmark': + specifier: workspace:* + version: link:../benchmark '@types/lodash': specifier: ^4.17.7 version: 4.17.7 @@ -8040,6 +8085,25 @@ snapshots: '@across-protocol/constants@3.1.16': {} + '@across-protocol/contracts@0.1.4(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10)': + dependencies: + '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@openzeppelin/contracts': 4.1.0 + '@uma/core': 2.59.1(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) @@ -9502,7 +9566,7 @@ snapshots: '@pinata/sdk@2.1.0': dependencies: - axios: 0.21.4 + axios: 0.21.4(debug@4.3.6) form-data: 2.5.1 is-ipfs: 0.6.3 path: 0.12.7 @@ -10309,7 +10373,7 @@ snapshots: '@uma/common@2.37.1(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) '@ethersproject/address': 5.7.0 '@ethersproject/bignumber': 5.7.0 '@ethersproject/bytes': 5.7.0 @@ -10418,9 +10482,9 @@ snapshots: '@ethersproject/constants': 5.7.0 '@google-cloud/kms': 3.8.0(encoding@0.1.13) '@google-cloud/storage': 6.12.0(encoding@0.1.13) - '@nomicfoundation/hardhat-verify': 1.1.1(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomiclabs/hardhat-web3': 2.0.0(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-verify': 1.1.1(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) + '@nomiclabs/hardhat-web3': 2.0.0(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@truffle/contract': 4.6.17(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) '@truffle/hdwallet-provider': 1.5.1-alpha.1(@babel/core@7.25.2)(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) '@types/ethereum-protocol': 1.0.5 @@ -10434,7 +10498,7 @@ snapshots: dotenv: 9.0.2 eth-crypto: 2.6.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) hardhat-deploy: 0.9.1(@ethersproject/hardware-wallets@5.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - hardhat-gas-reporter: 1.0.10(bufferutil@4.0.8)(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + hardhat-gas-reporter: 1.0.10(bufferutil@4.0.8)(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) hardhat-typechain: 0.3.5(hardhat@2.22.12(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.7.3)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4)) lodash.uniqby: 4.7.0 minimist: 1.2.8 @@ -11038,12 +11102,6 @@ snapshots: axe-core@4.10.0: {} - axios@0.21.4: - dependencies: - follow-redirects: 1.15.9(debug@4.3.7) - transitivePeerDependencies: - - debug - axios@0.21.4(debug@4.3.6): dependencies: follow-redirects: 1.15.9(debug@4.3.6) @@ -11052,14 +11110,14 @@ snapshots: axios@0.27.2: dependencies: - follow-redirects: 1.15.9(debug@4.3.7) + follow-redirects: 1.15.9(debug@4.3.6) form-data: 4.0.0 transitivePeerDependencies: - debug axios@1.7.7: dependencies: - follow-redirects: 1.15.9(debug@4.3.7) + follow-redirects: 1.15.9(debug@4.3.6) form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: