From a56e59f090bc6edc0e0235efd79fb2c02ad895ee Mon Sep 17 00:00:00 2001 From: Fuxing Loh <4266087+fuxingloh@users.noreply.github.com> Date: Thu, 5 Aug 2021 11:45:31 +0800 Subject: [PATCH] MainDfTxIndexer to log error instead of crashing to prevent indexer stall for DfTx (#318) --- src/module.indexer/model/dftx.indexer.ts | 41 ++++++++++++++---------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/module.indexer/model/dftx.indexer.ts b/src/module.indexer/model/dftx.indexer.ts index d76e2a0a6..634315aab 100644 --- a/src/module.indexer/model/dftx.indexer.ts +++ b/src/module.indexer/model/dftx.indexer.ts @@ -6,11 +6,12 @@ import { AppointOracleIndexer } from '@src/module.indexer/model/dftx/appoint.ora import { RemoveOracleIndexer } from '@src/module.indexer/model/dftx/remove.oracle' import { UpdateOracleIndexer } from '@src/module.indexer/model/dftx/update.oracle' import { SetOracleDataIndexer } from '@src/module.indexer/model/dftx/set.oracle.data' -import { Injectable } from '@nestjs/common' +import { Injectable, Logger } from '@nestjs/common' import { DfTxIndexer, DfTxTransaction } from '@src/module.indexer/model/dftx/_abstract' @Injectable() export class MainDfTxIndexer extends Indexer { + private readonly logger = new Logger(MainDfTxIndexer.name) private readonly indexers: Array> constructor ( @@ -29,7 +30,7 @@ export class MainDfTxIndexer extends Indexer { } async index (block: RawBlock): Promise { - const transactions = getDfTxTransactions(block) + const transactions = this.getDfTxTransactions(block) for (const indexer of this.indexers) { const filtered = transactions.filter(value => value.dftx.type === indexer.OP_CODE) @@ -38,31 +39,37 @@ export class MainDfTxIndexer extends Indexer { } async invalidate (block: RawBlock): Promise { - const transactions = getDfTxTransactions(block) + const transactions = this.getDfTxTransactions(block) for (const indexer of this.indexers) { const filtered = transactions.filter(value => value.dftx.type === indexer.OP_CODE) await indexer.invalidate(block, filtered) } } -} -export function getDfTxTransactions (block: RawBlock): Array> { - const transactions: Array> = [] + private getDfTxTransactions (block: RawBlock): Array> { + const transactions: Array> = [] - for (const txn of block.tx) { - for (const vout of txn.vout) { - if (!vout.scriptPubKey.asm.startsWith('OP_RETURN 44665478')) { - continue - } + for (const txn of block.tx) { + for (const vout of txn.vout) { + if (!vout.scriptPubKey.asm.startsWith('OP_RETURN 44665478')) { + continue + } - const stack: OPCode[] = toOPCodes(SmartBuffer.fromBuffer(Buffer.from(vout.scriptPubKey.hex, 'hex'))) - if (stack[1].type !== 'OP_DEFI_TX') { - continue + try { + const stack: OPCode[] = toOPCodes(SmartBuffer.fromBuffer(Buffer.from(vout.scriptPubKey.hex, 'hex'))) + if (stack[1].type !== 'OP_DEFI_TX') { + continue + } + transactions.push({ txn: txn, dftx: (stack[1] as OP_DEFI_TX).tx }) + } catch (err) { + // TODO(fuxingloh): we can improve on this design by having separated indexing pipeline where + // a failed pipeline won't affect another indexer pipeline. + this.logger.error(`Failed to parse a DfTx Transaction with txid: ${txn.txid}`, err) + } } - transactions.push({ txn: txn, dftx: (stack[1] as OP_DEFI_TX).tx }) } - } - return transactions + return transactions + } }