From 2442c09e131689311aed1820908bc21db73b0b4f Mon Sep 17 00:00:00 2001 From: pierregee Date: Sat, 16 Sep 2023 13:03:41 +0800 Subject: [PATCH 01/11] fix(whale-api): skip null txid used by evmtx --- apps/whale-api/src/module.indexer/constants.ts | 1 + .../src/module.indexer/model/script.activity.ts | 8 ++++++-- .../module.indexer/model/script.aggregation.ts | 13 +++++++++++-- .../src/module.indexer/model/script.unspent.ts | 15 ++++++++++----- .../src/module.indexer/model/transaction.vin.ts | 7 ++++++- 5 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 apps/whale-api/src/module.indexer/constants.ts diff --git a/apps/whale-api/src/module.indexer/constants.ts b/apps/whale-api/src/module.indexer/constants.ts new file mode 100644 index 0000000000..ca9c4bf7cf --- /dev/null +++ b/apps/whale-api/src/module.indexer/constants.ts @@ -0,0 +1 @@ +export const NULL_TX_ID = '0000000000000000000000000000000000000000000000000000000000000000' diff --git a/apps/whale-api/src/module.indexer/model/script.activity.ts b/apps/whale-api/src/module.indexer/model/script.activity.ts index 255ab9568c..85cbc0314f 100644 --- a/apps/whale-api/src/module.indexer/model/script.activity.ts +++ b/apps/whale-api/src/module.indexer/model/script.activity.ts @@ -5,6 +5,7 @@ import { HexEncoder } from '../../module.model/_hex.encoder' import { TransactionVout } from '../../module.model/transaction.vout' import { VoutFinder } from './_vout_finder' import { NotFoundIndexerError } from '../error' +import { NULL_TX_ID } from '../constants' @Injectable() export class ScriptActivityIndexer extends Indexer { @@ -21,10 +22,13 @@ export class ScriptActivityIndexer extends Indexer { if (vin.coinbase !== undefined) { continue } - const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - throw new NotFoundIndexerError('index', 'TransactionVout', `${vin.txid} - ${vin.vout}`) + if (vin.txid === NULL_TX_ID) { + continue + } + + throw new NotFoundIndexerError('index', 'TransactionVout - activity', `${vin.txid} - ${vin.vout}`) } await this.mapper.put(this.mapVin(block, txn, vin, vout)) } diff --git a/apps/whale-api/src/module.indexer/model/script.aggregation.ts b/apps/whale-api/src/module.indexer/model/script.aggregation.ts index 6abdd43c6e..d1da22bb54 100644 --- a/apps/whale-api/src/module.indexer/model/script.aggregation.ts +++ b/apps/whale-api/src/module.indexer/model/script.aggregation.ts @@ -5,6 +5,7 @@ import { VoutFinder } from './_vout_finder' import { HexEncoder } from '../../module.model/_hex.encoder' import BigNumber from 'bignumber.js' import { NotFoundIndexerError } from '../error' +import { NULL_TX_ID } from '../constants' @Injectable() export class ScriptAggregationIndexer extends Indexer { @@ -34,7 +35,11 @@ export class ScriptAggregationIndexer extends Indexer { const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - throw new NotFoundIndexerError('index', 'TransactionVout', `${vin.txid} - ${vin.vout}`) + if (vin.txid === NULL_TX_ID) { + continue + } + + throw new NotFoundIndexerError('index', 'TransactionVout - aggregation', `${vin.txid} - ${vin.vout}`) } // Spent (REMOVE) @@ -83,7 +88,11 @@ export class ScriptAggregationIndexer extends Indexer { const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - throw new NotFoundIndexerError('invalidate', 'TransactionVout', `${vin.txid} - ${vin.vout}`) + if (vin.txid === NULL_TX_ID) { + continue + } + + throw new NotFoundIndexerError('invalidate', 'TransactionVout3', `${vin.txid} - ${vin.vout}`) } hidList.add(HexEncoder.asSHA256(vout.script.hex)) } diff --git a/apps/whale-api/src/module.indexer/model/script.unspent.ts b/apps/whale-api/src/module.indexer/model/script.unspent.ts index 36c2d3911c..ab2f9a2296 100644 --- a/apps/whale-api/src/module.indexer/model/script.unspent.ts +++ b/apps/whale-api/src/module.indexer/model/script.unspent.ts @@ -5,6 +5,7 @@ import { HexEncoder } from '../../module.model/_hex.encoder' import { TransactionVout, TransactionVoutMapper } from '../../module.model/transaction.vout' import { Transaction, TransactionMapper } from '../../module.model/transaction' import { NotFoundIndexerError } from '../error' +import { NULL_TX_ID } from '../constants' @Injectable() export class ScriptUnspentIndexer extends Indexer { @@ -32,8 +33,8 @@ export class ScriptUnspentIndexer extends Indexer { } async invalidate (block: RawBlock): Promise { - for (const txn of block.tx) { - for (const vin of txn.vin) { + for (const blockTxn of block.tx) { + for (const vin of blockTxn.vin) { if (vin.coinbase !== undefined) { continue } @@ -41,16 +42,20 @@ export class ScriptUnspentIndexer extends Indexer { const txn = await this.transactionMapper.get(vin.txid) const vout = await this.voutMapper.get(vin.txid, vin.vout) if (txn === undefined) { + if (vin.txid === NULL_TX_ID) { + continue + } + throw new NotFoundIndexerError('invalidate', 'Transaction', vin.txid) } if (vout === undefined) { - throw new NotFoundIndexerError('invalidate', 'TransactionVout', `${vin.txid} - ${vin.vout}`) + throw new NotFoundIndexerError('invalidate', 'TransactionVout - unspent', `${vin.txid} - ${vin.vout}`) } await this.unspentMapper.put(this.mapInvalidated(txn, vout)) } - for (const vout of txn.vout) { - await this.unspentMapper.delete(txn.txid + HexEncoder.encodeVoutIndex(vout.n)) + for (const vout of blockTxn.vout) { + await this.unspentMapper.delete(blockTxn.txid + HexEncoder.encodeVoutIndex(vout.n)) } } } diff --git a/apps/whale-api/src/module.indexer/model/transaction.vin.ts b/apps/whale-api/src/module.indexer/model/transaction.vin.ts index 20a3840f08..1548c141de 100644 --- a/apps/whale-api/src/module.indexer/model/transaction.vin.ts +++ b/apps/whale-api/src/module.indexer/model/transaction.vin.ts @@ -5,6 +5,7 @@ import { TransactionVout } from '../../module.model/transaction.vout' import { HexEncoder } from '../../module.model/_hex.encoder' import { VoutFinder } from './_vout_finder' import { NotFoundIndexerError } from '../error' +import { NULL_TX_ID } from '../constants' @Injectable() export class TransactionVinIndexer extends Indexer { @@ -23,7 +24,11 @@ export class TransactionVinIndexer extends Indexer { } else { const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - throw new NotFoundIndexerError('index', 'TransactionVout', `${vin.txid} - ${vin.vout}`) + if (vin.txid === NULL_TX_ID) { + continue + } + + throw new NotFoundIndexerError('index', 'TransactionVout - vin', `${vin.txid} - ${vin.vout}`) } await this.vinMapper.put(this.map(txn, vin, vout)) } From 642f36d838cf38e5c1dbece8eeb84c94c0efd3e4 Mon Sep 17 00:00:00 2001 From: pierregee Date: Mon, 18 Sep 2023 11:55:36 +0800 Subject: [PATCH 02/11] check if 2 null vins and skip --- .../module.indexer/model/script.activity.ts | 8 +++----- .../model/script.aggregation.ts | 16 ++++++--------- .../module.indexer/model/script.unspent.ts | 20 +++++++++---------- .../module.indexer/model/transaction.vin.ts | 8 +++----- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/apps/whale-api/src/module.indexer/model/script.activity.ts b/apps/whale-api/src/module.indexer/model/script.activity.ts index 85cbc0314f..95458eb623 100644 --- a/apps/whale-api/src/module.indexer/model/script.activity.ts +++ b/apps/whale-api/src/module.indexer/model/script.activity.ts @@ -18,16 +18,14 @@ export class ScriptActivityIndexer extends Indexer { async index (block: RawBlock): Promise { for (const txn of block.tx) { + const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + for (const vin of txn.vin) { - if (vin.coinbase !== undefined) { + if (vin.coinbase !== undefined || isEvmTx) { continue } const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - if (vin.txid === NULL_TX_ID) { - continue - } - throw new NotFoundIndexerError('index', 'TransactionVout - activity', `${vin.txid} - ${vin.vout}`) } await this.mapper.put(this.mapVin(block, txn, vin, vout)) diff --git a/apps/whale-api/src/module.indexer/model/script.aggregation.ts b/apps/whale-api/src/module.indexer/model/script.aggregation.ts index d1da22bb54..33f300309a 100644 --- a/apps/whale-api/src/module.indexer/model/script.aggregation.ts +++ b/apps/whale-api/src/module.indexer/model/script.aggregation.ts @@ -28,17 +28,15 @@ export class ScriptAggregationIndexer extends Indexer { } for (const txn of block.tx) { + const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + for (const vin of txn.vin) { - if (vin.coinbase !== undefined) { + if (vin.coinbase !== undefined || isEvmTx) { continue } const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - if (vin.txid === NULL_TX_ID) { - continue - } - throw new NotFoundIndexerError('index', 'TransactionVout - aggregation', `${vin.txid} - ${vin.vout}`) } @@ -81,17 +79,15 @@ export class ScriptAggregationIndexer extends Indexer { const hidList = new Set() for (const txn of block.tx) { + const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + for (const vin of txn.vin) { - if (vin.coinbase !== undefined) { + if (vin.coinbase !== undefined || isEvmTx) { continue } const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - if (vin.txid === NULL_TX_ID) { - continue - } - throw new NotFoundIndexerError('invalidate', 'TransactionVout3', `${vin.txid} - ${vin.vout}`) } hidList.add(HexEncoder.asSHA256(vout.script.hex)) diff --git a/apps/whale-api/src/module.indexer/model/script.unspent.ts b/apps/whale-api/src/module.indexer/model/script.unspent.ts index ab2f9a2296..64f4a5b315 100644 --- a/apps/whale-api/src/module.indexer/model/script.unspent.ts +++ b/apps/whale-api/src/module.indexer/model/script.unspent.ts @@ -19,8 +19,10 @@ export class ScriptUnspentIndexer extends Indexer { async index (block: RawBlock): Promise { for (const txn of block.tx) { + const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + for (const vin of txn.vin) { - if (vin.coinbase !== undefined) { + if (vin.coinbase !== undefined || isEvmTx) { continue } await this.unspentMapper.delete(vin.txid + HexEncoder.encodeVoutIndex(vin.vout)) @@ -33,19 +35,17 @@ export class ScriptUnspentIndexer extends Indexer { } async invalidate (block: RawBlock): Promise { - for (const blockTxn of block.tx) { - for (const vin of blockTxn.vin) { - if (vin.coinbase !== undefined) { + for (const txn of block.tx) { + const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + + for (const vin of txn.vin) { + if (vin.coinbase !== undefined || isEvmTx) { continue } const txn = await this.transactionMapper.get(vin.txid) const vout = await this.voutMapper.get(vin.txid, vin.vout) if (txn === undefined) { - if (vin.txid === NULL_TX_ID) { - continue - } - throw new NotFoundIndexerError('invalidate', 'Transaction', vin.txid) } if (vout === undefined) { @@ -54,8 +54,8 @@ export class ScriptUnspentIndexer extends Indexer { await this.unspentMapper.put(this.mapInvalidated(txn, vout)) } - for (const vout of blockTxn.vout) { - await this.unspentMapper.delete(blockTxn.txid + HexEncoder.encodeVoutIndex(vout.n)) + for (const vout of txn.vout) { + await this.unspentMapper.delete(txn.txid + HexEncoder.encodeVoutIndex(vout.n)) } } } diff --git a/apps/whale-api/src/module.indexer/model/transaction.vin.ts b/apps/whale-api/src/module.indexer/model/transaction.vin.ts index 1548c141de..7c01d85e22 100644 --- a/apps/whale-api/src/module.indexer/model/transaction.vin.ts +++ b/apps/whale-api/src/module.indexer/model/transaction.vin.ts @@ -18,16 +18,14 @@ export class TransactionVinIndexer extends Indexer { async index (block: RawBlock): Promise { for (const txn of block.tx) { + const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + for (const vin of txn.vin) { - if (vin.coinbase !== undefined) { + if (vin.coinbase !== undefined || isEvmTx) { await this.vinMapper.put(this.map(txn, vin, undefined)) } else { const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - if (vin.txid === NULL_TX_ID) { - continue - } - throw new NotFoundIndexerError('index', 'TransactionVout - vin', `${vin.txid} - ${vin.vout}`) } await this.vinMapper.put(this.map(txn, vin, vout)) From 361fcd4b5594649f34c5adffeeed00061ac29c0b Mon Sep 17 00:00:00 2001 From: pierregee Date: Mon, 18 Sep 2023 11:58:04 +0800 Subject: [PATCH 03/11] remove logging changes --- apps/whale-api/src/module.indexer/model/script.aggregation.ts | 2 +- apps/whale-api/src/module.indexer/model/script.unspent.ts | 2 +- apps/whale-api/src/module.indexer/model/transaction.vin.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/whale-api/src/module.indexer/model/script.aggregation.ts b/apps/whale-api/src/module.indexer/model/script.aggregation.ts index 33f300309a..caf39dab77 100644 --- a/apps/whale-api/src/module.indexer/model/script.aggregation.ts +++ b/apps/whale-api/src/module.indexer/model/script.aggregation.ts @@ -88,7 +88,7 @@ export class ScriptAggregationIndexer extends Indexer { const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - throw new NotFoundIndexerError('invalidate', 'TransactionVout3', `${vin.txid} - ${vin.vout}`) + throw new NotFoundIndexerError('invalidate', 'TransactionVout', `${vin.txid} - ${vin.vout}`) } hidList.add(HexEncoder.asSHA256(vout.script.hex)) } diff --git a/apps/whale-api/src/module.indexer/model/script.unspent.ts b/apps/whale-api/src/module.indexer/model/script.unspent.ts index 64f4a5b315..0b5f6d1581 100644 --- a/apps/whale-api/src/module.indexer/model/script.unspent.ts +++ b/apps/whale-api/src/module.indexer/model/script.unspent.ts @@ -49,7 +49,7 @@ export class ScriptUnspentIndexer extends Indexer { throw new NotFoundIndexerError('invalidate', 'Transaction', vin.txid) } if (vout === undefined) { - throw new NotFoundIndexerError('invalidate', 'TransactionVout - unspent', `${vin.txid} - ${vin.vout}`) + throw new NotFoundIndexerError('invalidate', 'TransactionVout', `${vin.txid} - ${vin.vout}`) } await this.unspentMapper.put(this.mapInvalidated(txn, vout)) } diff --git a/apps/whale-api/src/module.indexer/model/transaction.vin.ts b/apps/whale-api/src/module.indexer/model/transaction.vin.ts index 7c01d85e22..5cea24407b 100644 --- a/apps/whale-api/src/module.indexer/model/transaction.vin.ts +++ b/apps/whale-api/src/module.indexer/model/transaction.vin.ts @@ -26,7 +26,7 @@ export class TransactionVinIndexer extends Indexer { } else { const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - throw new NotFoundIndexerError('index', 'TransactionVout - vin', `${vin.txid} - ${vin.vout}`) + throw new NotFoundIndexerError('index', 'TransactionVout', `${vin.txid} - ${vin.vout}`) } await this.vinMapper.put(this.map(txn, vin, vout)) } From c94b8f7f6dd845ce95c4296c9b34c84a3efc9a5f Mon Sep 17 00:00:00 2001 From: pierregee Date: Mon, 18 Sep 2023 13:56:27 +0800 Subject: [PATCH 04/11] add helper to remove duplicate code --- apps/whale-api/src/module.indexer/helper.ts | 10 ++++++++++ .../src/module.indexer/model/script.activity.ts | 4 ++-- .../src/module.indexer/model/script.aggregation.ts | 6 +++--- .../src/module.indexer/model/script.unspent.ts | 6 +++--- .../src/module.indexer/model/transaction.vin.ts | 4 ++-- 5 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 apps/whale-api/src/module.indexer/helper.ts diff --git a/apps/whale-api/src/module.indexer/helper.ts b/apps/whale-api/src/module.indexer/helper.ts new file mode 100644 index 0000000000..6f074b24a1 --- /dev/null +++ b/apps/whale-api/src/module.indexer/helper.ts @@ -0,0 +1,10 @@ +import { blockchain } from '@defichain/jellyfish-api-core' +import { NULL_TX_ID } from './constants' + +function checkIfEvmTx (txn: blockchain.Transaction): boolean { + return txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) +} + +export { + checkIfEvmTx +} diff --git a/apps/whale-api/src/module.indexer/model/script.activity.ts b/apps/whale-api/src/module.indexer/model/script.activity.ts index 95458eb623..09fad3b30f 100644 --- a/apps/whale-api/src/module.indexer/model/script.activity.ts +++ b/apps/whale-api/src/module.indexer/model/script.activity.ts @@ -5,7 +5,7 @@ import { HexEncoder } from '../../module.model/_hex.encoder' import { TransactionVout } from '../../module.model/transaction.vout' import { VoutFinder } from './_vout_finder' import { NotFoundIndexerError } from '../error' -import { NULL_TX_ID } from '../constants' +import { checkIfEvmTx } from '../helper' @Injectable() export class ScriptActivityIndexer extends Indexer { @@ -18,7 +18,7 @@ export class ScriptActivityIndexer extends Indexer { async index (block: RawBlock): Promise { for (const txn of block.tx) { - const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + const isEvmTx = checkIfEvmTx(txn) for (const vin of txn.vin) { if (vin.coinbase !== undefined || isEvmTx) { diff --git a/apps/whale-api/src/module.indexer/model/script.aggregation.ts b/apps/whale-api/src/module.indexer/model/script.aggregation.ts index caf39dab77..258fe1a257 100644 --- a/apps/whale-api/src/module.indexer/model/script.aggregation.ts +++ b/apps/whale-api/src/module.indexer/model/script.aggregation.ts @@ -5,7 +5,7 @@ import { VoutFinder } from './_vout_finder' import { HexEncoder } from '../../module.model/_hex.encoder' import BigNumber from 'bignumber.js' import { NotFoundIndexerError } from '../error' -import { NULL_TX_ID } from '../constants' +import { checkIfEvmTx } from '../helper' @Injectable() export class ScriptAggregationIndexer extends Indexer { @@ -28,7 +28,7 @@ export class ScriptAggregationIndexer extends Indexer { } for (const txn of block.tx) { - const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + const isEvmTx = checkIfEvmTx(txn) for (const vin of txn.vin) { if (vin.coinbase !== undefined || isEvmTx) { @@ -79,7 +79,7 @@ export class ScriptAggregationIndexer extends Indexer { const hidList = new Set() for (const txn of block.tx) { - const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + const isEvmTx = checkIfEvmTx(txn) for (const vin of txn.vin) { if (vin.coinbase !== undefined || isEvmTx) { diff --git a/apps/whale-api/src/module.indexer/model/script.unspent.ts b/apps/whale-api/src/module.indexer/model/script.unspent.ts index 0b5f6d1581..5c979d60c6 100644 --- a/apps/whale-api/src/module.indexer/model/script.unspent.ts +++ b/apps/whale-api/src/module.indexer/model/script.unspent.ts @@ -5,7 +5,7 @@ import { HexEncoder } from '../../module.model/_hex.encoder' import { TransactionVout, TransactionVoutMapper } from '../../module.model/transaction.vout' import { Transaction, TransactionMapper } from '../../module.model/transaction' import { NotFoundIndexerError } from '../error' -import { NULL_TX_ID } from '../constants' +import { checkIfEvmTx } from '../helper' @Injectable() export class ScriptUnspentIndexer extends Indexer { @@ -19,7 +19,7 @@ export class ScriptUnspentIndexer extends Indexer { async index (block: RawBlock): Promise { for (const txn of block.tx) { - const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + const isEvmTx = checkIfEvmTx(txn) for (const vin of txn.vin) { if (vin.coinbase !== undefined || isEvmTx) { @@ -36,7 +36,7 @@ export class ScriptUnspentIndexer extends Indexer { async invalidate (block: RawBlock): Promise { for (const txn of block.tx) { - const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + const isEvmTx = checkIfEvmTx(txn) for (const vin of txn.vin) { if (vin.coinbase !== undefined || isEvmTx) { diff --git a/apps/whale-api/src/module.indexer/model/transaction.vin.ts b/apps/whale-api/src/module.indexer/model/transaction.vin.ts index 5cea24407b..abb3e7df2b 100644 --- a/apps/whale-api/src/module.indexer/model/transaction.vin.ts +++ b/apps/whale-api/src/module.indexer/model/transaction.vin.ts @@ -5,7 +5,7 @@ import { TransactionVout } from '../../module.model/transaction.vout' import { HexEncoder } from '../../module.model/_hex.encoder' import { VoutFinder } from './_vout_finder' import { NotFoundIndexerError } from '../error' -import { NULL_TX_ID } from '../constants' +import { checkIfEvmTx } from '../helper' @Injectable() export class TransactionVinIndexer extends Indexer { @@ -18,7 +18,7 @@ export class TransactionVinIndexer extends Indexer { async index (block: RawBlock): Promise { for (const txn of block.tx) { - const isEvmTx = txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + const isEvmTx = checkIfEvmTx(txn) for (const vin of txn.vin) { if (vin.coinbase !== undefined || isEvmTx) { From 0fa0dd8f0efbc4432ee1e7e6376d6cd0c527c1bc Mon Sep 17 00:00:00 2001 From: pierregee Date: Mon, 18 Sep 2023 15:03:55 +0800 Subject: [PATCH 05/11] remove log changes --- apps/whale-api/src/module.indexer/model/script.activity.ts | 2 +- apps/whale-api/src/module.indexer/model/script.aggregation.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/whale-api/src/module.indexer/model/script.activity.ts b/apps/whale-api/src/module.indexer/model/script.activity.ts index 09fad3b30f..cc9ed743ec 100644 --- a/apps/whale-api/src/module.indexer/model/script.activity.ts +++ b/apps/whale-api/src/module.indexer/model/script.activity.ts @@ -26,7 +26,7 @@ export class ScriptActivityIndexer extends Indexer { } const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - throw new NotFoundIndexerError('index', 'TransactionVout - activity', `${vin.txid} - ${vin.vout}`) + throw new NotFoundIndexerError('index', 'TransactionVout', `${vin.txid} - ${vin.vout}`) } await this.mapper.put(this.mapVin(block, txn, vin, vout)) } diff --git a/apps/whale-api/src/module.indexer/model/script.aggregation.ts b/apps/whale-api/src/module.indexer/model/script.aggregation.ts index 258fe1a257..79bf845f53 100644 --- a/apps/whale-api/src/module.indexer/model/script.aggregation.ts +++ b/apps/whale-api/src/module.indexer/model/script.aggregation.ts @@ -37,7 +37,7 @@ export class ScriptAggregationIndexer extends Indexer { const vout = await this.voutFinder.findVout(block, vin.txid, vin.vout) if (vout === undefined) { - throw new NotFoundIndexerError('index', 'TransactionVout - aggregation', `${vin.txid} - ${vin.vout}`) + throw new NotFoundIndexerError('index', 'TransactionVout', `${vin.txid} - ${vin.vout}`) } // Spent (REMOVE) From 31bf3155ba455aaf19475a9eb7f6121d730116e9 Mon Sep 17 00:00:00 2001 From: pierregee Date: Mon, 18 Sep 2023 15:05:55 +0800 Subject: [PATCH 06/11] add checking on invalidate --- apps/whale-api/src/module.indexer/model/script.activity.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/whale-api/src/module.indexer/model/script.activity.ts b/apps/whale-api/src/module.indexer/model/script.activity.ts index cc9ed743ec..7c08ad0e11 100644 --- a/apps/whale-api/src/module.indexer/model/script.activity.ts +++ b/apps/whale-api/src/module.indexer/model/script.activity.ts @@ -42,8 +42,10 @@ export class ScriptActivityIndexer extends Indexer { async invalidate (block: RawBlock): Promise { for (const txn of block.tx) { + const isEvmTx = checkIfEvmTx(txn) + for (const vin of txn.vin) { - if (vin.coinbase !== undefined) { + if (vin.coinbase !== undefined || isEvmTx) { continue } From fa82107b45933ec08eb6ed10dd4e31c70bfd31ed Mon Sep 17 00:00:00 2001 From: pierregee Date: Mon, 18 Sep 2023 16:59:13 +0800 Subject: [PATCH 07/11] remove constant --- apps/whale-api/src/module.indexer/constants.ts | 1 - apps/whale-api/src/module.indexer/helper.ts | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 apps/whale-api/src/module.indexer/constants.ts diff --git a/apps/whale-api/src/module.indexer/constants.ts b/apps/whale-api/src/module.indexer/constants.ts deleted file mode 100644 index ca9c4bf7cf..0000000000 --- a/apps/whale-api/src/module.indexer/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const NULL_TX_ID = '0000000000000000000000000000000000000000000000000000000000000000' diff --git a/apps/whale-api/src/module.indexer/helper.ts b/apps/whale-api/src/module.indexer/helper.ts index 6f074b24a1..23114c2a9b 100644 --- a/apps/whale-api/src/module.indexer/helper.ts +++ b/apps/whale-api/src/module.indexer/helper.ts @@ -1,8 +1,7 @@ import { blockchain } from '@defichain/jellyfish-api-core' -import { NULL_TX_ID } from './constants' function checkIfEvmTx (txn: blockchain.Transaction): boolean { - return txn.vin.length === 2 && txn.vin.every(vin => vin.txid === NULL_TX_ID) + return txn.vin.length === 2 && txn.vin.every(vin => vin.txid === '0000000000000000000000000000000000000000000000000000000000000000') } export { From b55ca42a249804c6c96d985018f70716cdfa828a Mon Sep 17 00:00:00 2001 From: pierregee Date: Mon, 18 Sep 2023 17:10:13 +0800 Subject: [PATCH 08/11] add comment --- apps/whale-api/src/module.indexer/helper.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/whale-api/src/module.indexer/helper.ts b/apps/whale-api/src/module.indexer/helper.ts index 23114c2a9b..eb7bb93364 100644 --- a/apps/whale-api/src/module.indexer/helper.ts +++ b/apps/whale-api/src/module.indexer/helper.ts @@ -1,6 +1,7 @@ import { blockchain } from '@defichain/jellyfish-api-core' function checkIfEvmTx (txn: blockchain.Transaction): boolean { + // To identify that the transaction is evmtx, it has to have exactly 2 null transaction ids return txn.vin.length === 2 && txn.vin.every(vin => vin.txid === '0000000000000000000000000000000000000000000000000000000000000000') } From 36ecd7b387ae2b27b845e27e23fa7bcc9eff328a Mon Sep 17 00:00:00 2001 From: Harsh Date: Mon, 18 Sep 2023 15:12:28 +0530 Subject: [PATCH 09/11] feature(e2e): added e2e to check indexing of evmTx txn block --- .../module.indexer/model/transaction.e2e.ts | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/apps/whale-api/src/module.indexer/model/transaction.e2e.ts b/apps/whale-api/src/module.indexer/model/transaction.e2e.ts index 818ffa77d0..28954fa234 100644 --- a/apps/whale-api/src/module.indexer/model/transaction.e2e.ts +++ b/apps/whale-api/src/module.indexer/model/transaction.e2e.ts @@ -5,6 +5,9 @@ import { TransactionVinMapper } from '../../module.model/transaction.vin' import { TransactionVoutMapper } from '../../module.model/transaction.vout' import { NestFastifyApplication } from '@nestjs/platform-fastify' import { createTestingApp, stopTestingApp, waitForIndexedHeight } from '../../e2e.module' +import { Testing } from '@defichain/jellyfish-testing' +import { TransferDomainType } from '@defichain/jellyfish-api-core/dist/category/account' +import BigNumber from 'bignumber.js' const container = new MasterNodeRegTestContainer() let app: NestFastifyApplication @@ -73,3 +76,85 @@ it('should wait for block 20', async () => { await expectTransactions(block!.hash, block!.transactionCount) }) + +describe('EVM txn indexing', () => { + const testing = Testing.create(container) + let dfiAddress: string, ethAddress: string, toEthAddress: string + const amount = { + ONE: 1, + HUNDRED: 100 + } + const txGas = { + gasPrice: 21, + gasLimit: 21000 + } + beforeAll(async () => { + await container.generate(100) + await waitForIndexedHeight(app, 100) + await testing.rpc.masternode.setGov({ + ATTRIBUTES: { + // Enable evm + 'v0/params/feature/evm': 'true', + 'v0/params/feature/transferdomain': 'true', + 'v0/transferdomain/dvm-evm/enabled': 'true', + 'v0/transferdomain/evm-dvm/enabled': 'true', + 'v0/transferdomain/dvm-evm/dat-enabled': 'true', + 'v0/transferdomain/evm-dvm/dat-enabled': 'true', + 'v0/transferdomain/dvm-evm/src-formats': ['p2pkh', 'bech32'], + 'v0/transferdomain/dvm-evm/dest-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/src-formats': ['erc55'], + 'v0/transferdomain/evm-dvm/auth-formats': ['bech32-erc55'], + 'v0/transferdomain/evm-dvm/dest-formats': ['p2pkh', 'bech32'] + } + }) + await container.generate(2) + dfiAddress = await container.call('getnewaddress', ['', 'legacy']) + await container.call('utxostoaccount', [{ [dfiAddress]: '105@DFI' }]) + await container.generate(1) + ethAddress = await container.call('getnewaddress', ['', 'erc55']) + toEthAddress = await container.call('getnewaddress', ['', 'erc55']) + }) + + it('should index evm txn', async () => { + const dvmToEvmTransfer = [ + { + src: { + address: dfiAddress, + amount: `${amount.HUNDRED}@DFI`, + domain: TransferDomainType.DVM + }, + dst: { + address: ethAddress, + amount: `${amount.HUNDRED}@DFI`, + domain: TransferDomainType.EVM + } + } + ] + await container.call('transferdomain', [dvmToEvmTransfer]) + await container.generate(1) + const evmTxHash = await testing.rpc.evm.evmtx({ + from: ethAddress, + to: toEthAddress, + value: new BigNumber(amount.ONE), + nonce: 0, + ...txGas + }) + await container.generate(1) + const blockHash: string = await testing.rpc.blockchain.getBestBlockHash() + const blockDetails = await testing.rpc.blockchain.getBlock(blockHash, 1) + expect(blockDetails.tx[1]).toStrictEqual(evmTxHash) + await container.generate(1) + await waitForIndexedHeight(app, blockDetails.height) + + const blockMapper = app.get(BlockMapper) + const block = await blockMapper.getByHeight(blockDetails.height) + await expectTransactions(block!.hash, block!.transactionCount) + + // Wait for next block to get indexed + await container.generate(1) + const newBlockHash: string = await testing.rpc.blockchain.getBestBlockHash() + const newBlockDetails = await testing.rpc.blockchain.getBlock(newBlockHash, 1) + await container.generate(1) + await waitForIndexedHeight(app, newBlockDetails.height) + }) +}) From 4ea1736d135ee77cee6bc54d52b65519d3cfa623 Mon Sep 17 00:00:00 2001 From: Harsh Date: Mon, 18 Sep 2023 21:31:56 +0530 Subject: [PATCH 10/11] updated e2e to check multiple txn --- .../module.indexer/model/transaction.e2e.ts | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/apps/whale-api/src/module.indexer/model/transaction.e2e.ts b/apps/whale-api/src/module.indexer/model/transaction.e2e.ts index 28954fa234..549c4f4f9c 100644 --- a/apps/whale-api/src/module.indexer/model/transaction.e2e.ts +++ b/apps/whale-api/src/module.indexer/model/transaction.e2e.ts @@ -84,10 +84,7 @@ describe('EVM txn indexing', () => { ONE: 1, HUNDRED: 100 } - const txGas = { - gasPrice: 21, - gasLimit: 21000 - } + beforeAll(async () => { await container.generate(100) await waitForIndexedHeight(app, 100) @@ -132,23 +129,39 @@ describe('EVM txn indexing', () => { ] await container.call('transferdomain', [dvmToEvmTransfer]) await container.generate(1) - const evmTxHash = await testing.rpc.evm.evmtx({ - from: ethAddress, - to: toEthAddress, - value: new BigNumber(amount.ONE), - nonce: 0, - ...txGas - }) + + const tx4 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 4 }) + const tx0 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 0 }) + const tx2 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 2 }) + const tx1 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 1 }) + const tx3 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 3 }) + await container.generate(1) const blockHash: string = await testing.rpc.blockchain.getBestBlockHash() const blockDetails = await testing.rpc.blockchain.getBlock(blockHash, 1) - expect(blockDetails.tx[1]).toStrictEqual(evmTxHash) + + // validate sorted txn list + expect(blockDetails.tx[1]).toStrictEqual(tx0) + expect(blockDetails.tx[2]).toStrictEqual(tx1) + expect(blockDetails.tx[3]).toStrictEqual(tx2) + expect(blockDetails.tx[4]).toStrictEqual(tx3) + expect(blockDetails.tx[5]).toStrictEqual(tx4) + await container.generate(1) await waitForIndexedHeight(app, blockDetails.height) + const transactionMapper = app.get(TransactionMapper) const blockMapper = app.get(BlockMapper) const block = await blockMapper.getByHeight(blockDetails.height) await expectTransactions(block!.hash, block!.transactionCount) + const transactions = await transactionMapper.queryByBlockHash(block!.hash, 100) + + // validate mapped txn list + expect(transactions[1].id).toStrictEqual(tx0) + expect(transactions[2].id).toStrictEqual(tx1) + expect(transactions[3].id).toStrictEqual(tx2) + expect(transactions[4].id).toStrictEqual(tx3) + expect(transactions[5].id).toStrictEqual(tx4) // Wait for next block to get indexed await container.generate(1) @@ -158,3 +171,20 @@ describe('EVM txn indexing', () => { await waitForIndexedHeight(app, newBlockDetails.height) }) }) + +async function evmTx ({ testing, from, to, value, nonce }: { + testing: Testing + from: string + to: string + value: number + nonce: number +}): Promise { + return await testing.rpc.evm.evmtx({ + from, + to, + nonce, + gasPrice: 21, + gasLimit: 21000, + value: new BigNumber(value) + }) +} From 020e7a2d7bbead674c40277ea98b848de26cdaee Mon Sep 17 00:00:00 2001 From: Harsh Date: Mon, 18 Sep 2023 21:34:29 +0530 Subject: [PATCH 11/11] updated function name --- .../src/module.indexer/model/transaction.e2e.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/whale-api/src/module.indexer/model/transaction.e2e.ts b/apps/whale-api/src/module.indexer/model/transaction.e2e.ts index 549c4f4f9c..cbee3e495c 100644 --- a/apps/whale-api/src/module.indexer/model/transaction.e2e.ts +++ b/apps/whale-api/src/module.indexer/model/transaction.e2e.ts @@ -130,11 +130,11 @@ describe('EVM txn indexing', () => { await container.call('transferdomain', [dvmToEvmTransfer]) await container.generate(1) - const tx4 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 4 }) - const tx0 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 0 }) - const tx2 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 2 }) - const tx1 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 1 }) - const tx3 = await evmTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 3 }) + const tx4 = await createEVMTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 4 }) + const tx0 = await createEVMTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 0 }) + const tx2 = await createEVMTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 2 }) + const tx1 = await createEVMTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 1 }) + const tx3 = await createEVMTx({ testing, from: ethAddress, to: toEthAddress, value: amount.ONE, nonce: 3 }) await container.generate(1) const blockHash: string = await testing.rpc.blockchain.getBestBlockHash() @@ -172,7 +172,7 @@ describe('EVM txn indexing', () => { }) }) -async function evmTx ({ testing, from, to, value, nonce }: { +async function createEVMTx ({ testing, from, to, value, nonce }: { testing: Testing from: string to: string