From 24722cd37cfc4412413d0731f287fe2f4f056b41 Mon Sep 17 00:00:00 2001 From: Harvey Date: Fri, 21 Jun 2024 15:04:27 +0900 Subject: [PATCH] fix: submission-interval (#42) * fix update * fix typo --- src/lib/query.ts | 2 +- src/worker/bridgeExecutor/monitor/l2.ts | 90 ++++++++++++++------ src/worker/bridgeExecutor/monitor/monitor.ts | 2 +- src/worker/challenger/challenger.ts | 3 +- src/worker/common/name.ts | 10 +-- 5 files changed, 73 insertions(+), 34 deletions(-) diff --git a/src/lib/query.ts b/src/lib/query.ts index 9eccb2d..406ed00 100644 --- a/src/lib/query.ts +++ b/src/lib/query.ts @@ -75,4 +75,4 @@ export async function getLatestOutputFromExecutor(): Promise { const axiosInstance = AxiosSingleton.getInstance() const res = await axiosInstance.get(url) return res.data -} \ No newline at end of file +} diff --git a/src/worker/bridgeExecutor/monitor/l2.ts b/src/worker/bridgeExecutor/monitor/l2.ts index a2eeb51..e20dca3 100644 --- a/src/worker/bridgeExecutor/monitor/l2.ts +++ b/src/worker/bridgeExecutor/monitor/l2.ts @@ -1,7 +1,7 @@ import { ExecutorOutputEntity, ExecutorWithdrawalTxEntity } from '../../../orm' import { Monitor } from './monitor' import { EntityManager } from 'typeorm' -import { BlockInfo } from 'initia-l2' +import { BlockInfo, OutputInfo } from 'initia-l2' import { getDB } from '../db' import { RPCClient } from '../../../lib/rpc' import winston from 'winston' @@ -115,40 +115,77 @@ export class L2Monitor extends Monitor { return true } - async checkSubmissionInterval(): Promise { - const lastOutputSubmitted = await getLastOutputInfo(this.bridgeId) - if (lastOutputSubmitted) { - const lastOutputSubmittedTime = - lastOutputSubmitted.output_proposal.l1_block_time - const bridgeInfo = await getBridgeInfo(this.bridgeId) - const submissionInterval = - bridgeInfo.bridge_config.submission_interval.seconds.toNumber() - if ( - this.getCurTimeSec() < - this.dateToSeconds(lastOutputSubmittedTime) + - Math.floor(submissionInterval * config.SUBMISSION_THRESHOLD) + async checkSubmissionInterval( + lastOutputSubmitted: OutputInfo | null, + lastOutputFromDB: ExecutorOutputEntity | null + ): Promise { + // if no output from DB, create output (first output) + if (!lastOutputFromDB) { + this.logger.info( + `[checkSubmissionInterval - ${this.name()}] No output from DB` ) - return false + return true } - return true - } - async handleOutput(manager: EntityManager): Promise { - if (!(await this.checkSubmissionInterval())) { - if (this.currentHeight % 10 === 0) + // if no output submitted, wait for submission + if (!lastOutputSubmitted) return false + + // if output index from db is greater, wait for submission + if (lastOutputSubmitted.output_index < lastOutputFromDB.outputIndex) { + this.logger.info( + `[checkSubmissionInterval - ${this.name()}] Output index not matched` + ) + return false + } + + const lastOutputSubmittedTime = + lastOutputSubmitted.output_proposal.l1_block_time + const bridgeInfo = await getBridgeInfo(this.bridgeId) + const submissionInterval = + bridgeInfo.bridge_config.submission_interval.seconds.toNumber() + const targetTimeSec = + this.dateToSeconds(lastOutputSubmittedTime) + + Math.floor(submissionInterval * config.SUBMISSION_THRESHOLD) + + // if submission interval not reached, wait for submission + if (this.getCurTimeSec() < targetTimeSec) { + if (this.currentHeight % 10 === 0) { this.logger.info( - `[handleOutput - ${this.name()}] Submission interval not reached` + `[checkSubmissionInterval - ${this.name()}] need to wait for submission interval ${targetTimeSec - this.getCurTimeSec()} seconds` ) - return + } + + return false } - const lastOutput = await this.helper.getLastOutputFromDB( + // if submission interval reached, create output + this.logger.info( + `[checkSubmissionInterval - ${this.name()}] Submission interval reached! try to create output...` + ) + return true + } + + async handleOutput(manager: EntityManager): Promise { + const lastOutputSubmitted = await getLastOutputInfo(this.bridgeId) + const lastOutputFromDB = await this.helper.getLastOutputFromDB( manager, ExecutorOutputEntity ) - const lastOutputEndBlockNumber = lastOutput ? lastOutput.endBlockNumber : 0 - const lastOutputIndex = lastOutput ? lastOutput.outputIndex : 0 + if ( + !(await this.checkSubmissionInterval( + lastOutputSubmitted, + lastOutputFromDB + )) + ) + return + + const lastOutputEndBlockNumber = lastOutputSubmitted + ? lastOutputSubmitted.output_proposal.l2_block_number + : 0 + const lastOutputIndex = lastOutputSubmitted + ? lastOutputSubmitted.output_index + : 0 const startBlockNumber = lastOutputEndBlockNumber + 1 const endBlockNumber = this.currentHeight @@ -156,7 +193,7 @@ export class L2Monitor extends Monitor { if (startBlockNumber > endBlockNumber) { this.logger.info( - `[handleOutput - ${this.name()}] No new block to process` + `[handleOutput - ${this.name()}] No new block to process ${startBlockNumber - endBlockNumber} block remaining...` ) return } @@ -186,6 +223,9 @@ export class L2Monitor extends Monitor { endBlockNumber ) + this.logger.info( + `output entity created: block height (${startBlockNumber} - ${endBlockNumber})` + ) await this.helper.saveEntity(manager, ExecutorOutputEntity, outputEntity) } diff --git a/src/worker/bridgeExecutor/monitor/monitor.ts b/src/worker/bridgeExecutor/monitor/monitor.ts index 192c272..8a6d96a 100644 --- a/src/worker/bridgeExecutor/monitor/monitor.ts +++ b/src/worker/bridgeExecutor/monitor/monitor.ts @@ -53,7 +53,7 @@ export abstract class Monitor { }) this.syncedHeight = state?.height || 0 - + if (!state) { if (this.name() === BOT_NAME.EXECUTOR_L1_MONITOR) { this.syncedHeight = config.EXECUTOR_L1_MONITOR_HEIGHT diff --git a/src/worker/challenger/challenger.ts b/src/worker/challenger/challenger.ts index da9ec04..269b54d 100644 --- a/src/worker/challenger/challenger.ts +++ b/src/worker/challenger/challenger.ts @@ -200,13 +200,12 @@ export class Challenger { : (await getOutputInfoByIndex(this.bridgeId, outputIndex - 1)) .output_proposal.l2_block_number + 1 const endBlockNumber = output.output_proposal.l2_block_number - + const state = await manager.getRepository(StateEntity).findOne({ where: { name: 'challenger_l2_monitor' } }) if (!state || state.height < endBlockNumber) return null - const blockInfo = await config.l2lcd.tendermint.blockInfo(endBlockNumber) const txEntities = await this.helper.getWithdrawalTxs( diff --git a/src/worker/common/name.ts b/src/worker/common/name.ts index fce7c65..68ec037 100644 --- a/src/worker/common/name.ts +++ b/src/worker/common/name.ts @@ -1,6 +1,6 @@ export const BOT_NAME = { - EXECUTOR_L1_MONITOR: 'executor_l1_monitor', - EXECUTOR_L2_MONITOR: 'executor_l2_monitor', - CHALLENGER_L1_MONITOR: 'challenger_l1_monitor', - CHALLENGER_L2_MONITOR: 'challenger_l2_monitor', -} \ No newline at end of file + EXECUTOR_L1_MONITOR: 'executor_l1_monitor', + EXECUTOR_L2_MONITOR: 'executor_l2_monitor', + CHALLENGER_L1_MONITOR: 'challenger_l1_monitor', + CHALLENGER_L2_MONITOR: 'challenger_l2_monitor' +}