diff --git a/backend/src/api/bitcoin/bitcoin-api.ts b/backend/src/api/bitcoin/bitcoin-api.ts index 85d548f8e..8d7de3bf7 100644 --- a/backend/src/api/bitcoin/bitcoin-api.ts +++ b/backend/src/api/bitcoin/bitcoin-api.ts @@ -4,6 +4,7 @@ import { IBitcoinApi, SubmitPackageResult, TestMempoolAcceptResult } from './bit import { IEsploraApi } from './esplora-api.interface'; import blocks from '../blocks'; import mempool from '../mempool'; +import indexer from '../../indexer'; import { TransactionExtended } from '../../mempool.interfaces'; import transactionUtils from '../transaction-utils'; import { Common } from '../common'; @@ -235,15 +236,37 @@ class BitcoinApi implements AbstractBitcoinApi { async $getOutspends(txId: string): Promise { const outSpends: IEsploraApi.Outspend[] = []; const tx = await this.$getRawTransaction(txId, true, false); - for (let i = 0; i < tx.vout.length; i++) { - if (tx.status && tx.status.block_height === 0) { + if (indexer.isCoreIndexReady('txospenderindex') === null) { + for (let i = 0; i < tx.vout.length; i++) { + if (tx.status && tx.status.block_height === 0) { + outSpends.push({ + spent: false + }); + } else { + const txOut = await this.bitcoindClient.getTxOut(txId, i); + outSpends.push({ + spent: txOut === null, + }); + } + } + } else { + const batchedOutpoints = Array.from(Array(tx.vout.length).keys()).map(x =>({txid: txId, vout:x})); + const spendingsResume = await this.bitcoindClient.getTxSpendingPrevOut(batchedOutpoints); + for (const outpointStatus of spendingsResume) { + if (outpointStatus.spendingtxid === undefined) { + outSpends.push({spent: false}); + continue; + } + const spendingTx = await this.$getRawTransaction(outpointStatus.spendingtxid, true, false); + const inputIndex = spendingTx.vin.findIndex(x => x.txid === txId); outSpends.push({ - spent: false - }); - } else { - const txOut = await this.bitcoindClient.getTxOut(txId, i); - outSpends.push({ - spent: txOut === null, + spent: true, + txid: outpointStatus.spendingtxid, + vin: inputIndex, + status: { + confirmed: true, + } + }); } } diff --git a/backend/src/rpc-api/commands.ts b/backend/src/rpc-api/commands.ts index 475200fee..d4de8c513 100644 --- a/backend/src/rpc-api/commands.ts +++ b/backend/src/rpc-api/commands.ts @@ -52,6 +52,7 @@ module.exports = { getTxOut: 'gettxout', // bitcoind v0.7.0+ getTxOutProof: 'gettxoutproof', // bitcoind v0.11.0+ getTxOutSetInfo: 'gettxoutsetinfo', // bitcoind v0.7.0+ + getTxSpendingPrevOut: 'gettxspendingprevout', // bitcoind #24539 getUnconfirmedBalance: 'getunconfirmedbalance', // bitcoind v0.9.0+ getWalletInfo: 'getwalletinfo', // bitcoind v0.9.2+ help: 'help', diff --git a/backend/src/tasks/lightning/forensics.service.ts b/backend/src/tasks/lightning/forensics.service.ts index 7c6b6f6ac..bd8533af2 100644 --- a/backend/src/tasks/lightning/forensics.service.ts +++ b/backend/src/tasks/lightning/forensics.service.ts @@ -3,6 +3,7 @@ import logger from '../../logger'; import channelsApi from '../../api/explorer/channels.api'; import bitcoinApi from '../../api/bitcoin/bitcoin-api-factory'; import config from '../../config'; +import indexer from '../../indexer'; import { IEsploraApi } from '../../api/bitcoin/esplora-api.interface'; import { Common } from '../../api/common'; import { ILightningApi } from '../../api/lightning/lightning-api.interface'; @@ -28,7 +29,7 @@ class ForensicsService { try { logger.debug(`Running forensics scans`); - if (config.MEMPOOL.BACKEND === 'esplora') { + if (config.MEMPOOL.BACKEND === 'esplora' || indexer.isCoreIndexReady('txospenderindex')) { await this.$runClosedChannelsForensics(false); await this.$runOpenedChannelsForensics(); } @@ -64,9 +65,9 @@ class ForensicsService { └──────────────────┘ */ - public async $runClosedChannelsForensics(onlyNewChannels: boolean = false): Promise { +public async $runClosedChannelsForensics(onlyNewChannels: boolean = false): Promise { // Only Esplora backend can retrieve spent transaction outputs - if (config.MEMPOOL.BACKEND !== 'esplora') { + if (config.MEMPOOL.BACKEND !== 'esplora' && indexer.isCoreIndexReady('txospenderindex') !== null) { return; } diff --git a/contributors/pantamis.txt b/contributors/pantamis.txt new file mode 100644 index 000000000..94bb5c312 --- /dev/null +++ b/contributors/pantamis.txt @@ -0,0 +1,3 @@ +I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of 03 April, 2023. + +Signed: pantamis