diff --git a/blockchain-watcher/src/infrastructure/repositories/evm/ArbitrumEvmJsonRPCBlockRepository.ts b/blockchain-watcher/src/infrastructure/repositories/evm/ArbitrumEvmJsonRPCBlockRepository.ts index 0b55be37..ea79f018 100644 --- a/blockchain-watcher/src/infrastructure/repositories/evm/ArbitrumEvmJsonRPCBlockRepository.ts +++ b/blockchain-watcher/src/infrastructure/repositories/evm/ArbitrumEvmJsonRPCBlockRepository.ts @@ -1,6 +1,6 @@ -import { EvmTag } from "../../../domain/entities"; import { MetadataRepository } from "../../../domain/repositories"; import { HttpClientError } from "../../errors/HttpClientError"; +import { EvmTag } from "../../../domain/entities"; import winston from "../../log"; import { EvmJsonRPCBlockRepository, @@ -9,13 +9,11 @@ import { } from "./EvmJsonRPCBlockRepository"; const FINALIZED = "finalized"; -const ETHEREUM = "ethereum"; export class ArbitrumEvmJsonRPCBlockRepository extends EvmJsonRPCBlockRepository { override readonly logger = winston.child({ module: "ArbitrumEvmJsonRPCBlockRepository" }); private latestL2Finalized: number; private metadataRepo: MetadataRepository; - private latestEthTime: number; constructor( cfg: EvmJsonRPCBlockRepositoryCfg, @@ -25,7 +23,6 @@ export class ArbitrumEvmJsonRPCBlockRepository extends EvmJsonRPCBlockRepository super(cfg, pools); this.metadataRepo = metadataRepo; this.latestL2Finalized = 0; - this.latestEthTime = 0; } async getBlockHeight(chain: string, finality: EvmTag): Promise { @@ -56,32 +53,28 @@ export class ArbitrumEvmJsonRPCBlockRepository extends EvmJsonRPCBlockRepository if (!l2Logs || !l1BlockNumber || !l2Number) throw new Error(`[getBlockHeight] Unable to parse result for latest block on ${chain}`); - const associatedL1Block: number = parseInt(l1BlockNumber, 16); - const l2BlockNumber: number = parseInt(l2Number, 16); + const associatedL1ArbBlock: number = parseInt(l1BlockNumber, 16); + const l2BlockArbNumber: number = parseInt(l2Number, 16); const persistedBlocks: PersistedBlock[] = (await this.metadataRepo.get(metadataFileName)) ?? []; const auxPersistedBlocks = this.removeDuplicates(persistedBlocks); // Only update the persisted block list, if the L2 block number is newer - this.saveAssociatedL1Block(auxPersistedBlocks, associatedL1Block, l2BlockNumber); + this.saveAssociatedL1Block(auxPersistedBlocks, associatedL1ArbBlock, l2BlockArbNumber); - // Only check every 30 seconds - const now = Date.now(); - if (now - this.latestEthTime < 30_000) { - return BigInt(this.latestL2Finalized); - } - this.latestEthTime = now; - - // Get the latest finalized L1 block number - const latestL1BlockNumber: bigint = await super.getBlockHeight(ETHEREUM, FINALIZED); + // Get the latest finalized L1 block ethereum number + const latestL1BlockEthNumber: bigint = await super.getBlockHeight( + this.getL1Chain(chain), + FINALIZED + ); // Search in the persisted list looking for finalized L2 block number - this.searchFinalizedBlock(auxPersistedBlocks, latestL1BlockNumber); + this.searchFinalizedBlock(auxPersistedBlocks, latestL1BlockEthNumber); await this.metadataRepo.save(metadataFileName, [...auxPersistedBlocks]); this.logger.info( - `[${chain}] Blocks status: [PersistedBlocksLength: ${auxPersistedBlocks?.length}][LatestL2Finalized: ${this.latestL2Finalized}]` + `[${chain}] Blocks status: [PersistedBlocksLength: ${auxPersistedBlocks?.length}][Latest l2 arb: ${l2BlockArbNumber} {Latest l1 arb: ${associatedL1ArbBlock} - Latest l1 eth: ${latestL1BlockEthNumber}}, Latest l2 processed: ${this.latestL2Finalized}]` ); const latestL2FinalizedToBigInt = this.latestL2Finalized; @@ -99,39 +92,62 @@ export class ArbitrumEvmJsonRPCBlockRepository extends EvmJsonRPCBlockRepository private saveAssociatedL1Block( auxPersistedBlocks: PersistedBlock[], - associatedL1Block: number, - l2BlockNumber: number + associatedL1ArbBlock: number, + l2BlockArbNumber: number ): void { const findAssociatedL1Block = auxPersistedBlocks.find( - (block) => block.associatedL1Block == associatedL1Block - )?.associatedL1Block; + (block) => block.associatedL1ArbBlock == associatedL1ArbBlock + )?.associatedL1ArbBlock; - if (!findAssociatedL1Block || findAssociatedL1Block < l2BlockNumber) { - auxPersistedBlocks.push({ associatedL1Block, l2BlockNumber }); + if (!findAssociatedL1Block || findAssociatedL1Block < l2BlockArbNumber) { + auxPersistedBlocks.push({ + associatedL1ArbBlock, + l2BlockArbNumber, + latestL2Finalized: this.latestL2Finalized, + }); } } private searchFinalizedBlock( auxPersistedBlocks: PersistedBlock[], - latestL1BlockNumber: bigint + latestL1BlockEthNumber: bigint ): void { - const latestL1BlockNumberToNumber = Number(latestL1BlockNumber); + const latestL1BlockEthNumberToNumber = Number(latestL1BlockEthNumber); + const previusLatestL2Finalized = this.latestL2Finalized; for (let index = auxPersistedBlocks.length - 1; index >= 0; index--) { - const associatedL1Block = auxPersistedBlocks[index].associatedL1Block; + const associatedL1ArbBlock = auxPersistedBlocks[index].associatedL1ArbBlock; - if (associatedL1Block <= latestL1BlockNumberToNumber) { - const l2BlockNumber = auxPersistedBlocks[index].l2BlockNumber; - this.latestL2Finalized = l2BlockNumber; + if (associatedL1ArbBlock <= latestL1BlockEthNumberToNumber) { + const l2BlockArbNumber = auxPersistedBlocks[index].l2BlockArbNumber; + + if (l2BlockArbNumber <= previusLatestL2Finalized) { + auxPersistedBlocks.splice(index, 1); + break; + } + + this.latestL2Finalized = l2BlockArbNumber; auxPersistedBlocks.splice(index, 1); } } + + // If the latestL2Finalized is 0 or the previusLatestL2Finalized is equal to the latestL2Finalized, update the latestL2Finalized + if (this.latestL2Finalized == 0 || previusLatestL2Finalized == this.latestL2Finalized) { + const l2BlockArbNumber = auxPersistedBlocks[auxPersistedBlocks.length - 1].l2BlockArbNumber; + this.latestL2Finalized = l2BlockArbNumber; + auxPersistedBlocks.splice(0, 1); + } + } + + private getL1Chain(chain: string): string { + return chain === "arbitrum" ? "ethereum" : "ethereum-sepolia"; } } type PersistedBlock = { - associatedL1Block: number; - l2BlockNumber: number; + associatedL1ArbBlock: number; + l2BlockArbNumber: number; + latestL2Finalized: number; }; type BlockByNumberResult = { diff --git a/deploy/blockchain-watcher/workers/source-events-1.yaml b/deploy/blockchain-watcher/workers/source-events-1.yaml index d1453fc4..37aeeef5 100644 --- a/deploy/blockchain-watcher/workers/source-events-1.yaml +++ b/deploy/blockchain-watcher/workers/source-events-1.yaml @@ -495,7 +495,7 @@ data: "source": { "action": "PollEvm", "config": { - "blockBatchSize": 100, + "blockBatchSize": 1000, "commitment": "latest", "interval": 5000, "addresses": ["0xa5f208e072434bC67592E4C49C1B991BA79BCA46"], diff --git a/deploy/blockchain-watcher/workers/target-events.yaml b/deploy/blockchain-watcher/workers/target-events.yaml index cd039c74..fbc5bcfb 100644 --- a/deploy/blockchain-watcher/workers/target-events.yaml +++ b/deploy/blockchain-watcher/workers/target-events.yaml @@ -492,9 +492,9 @@ data: "action": "PollEvm", "records": "GetEvmTransactions", "config": { - "blockBatchSize": 100, + "blockBatchSize": 1000, "commitment": "latest", - "interval": 10000, + "interval": 5000, "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x19330d10D9Cc8751218eaf51E8885D058642E08A", "0x0b2402144bb366a632d14b83f244d2e0e21bd39c", "0x48fa7528bfd6164ddf09df0ed22451cf59c84130", "0xf3f04555f8fda510bfc77820fd6eb8446f59e72d"], "chain": "arbitrum", "chainId": 23,