mirror of
https://github.com/mempool/mempool.git
synced 2025-03-28 02:31:49 +01:00
Correctly error handle getTransaction and set 404 status when not found.
This commit is contained in:
parent
fb41f58f7c
commit
5b268794af
@ -5,7 +5,6 @@ import { AbstractBitcoinApi } from './bitcoin-api-abstract-factory';
|
||||
import { IBitcoinApi } from './bitcoin-api.interface';
|
||||
import { IEsploraApi } from './esplora-api.interface';
|
||||
import blocks from '../blocks';
|
||||
import bitcoinBaseApi from './bitcoin-base.api';
|
||||
import mempool from '../mempool';
|
||||
import { TransactionExtended } from '../../mempool.interfaces';
|
||||
|
||||
@ -202,12 +201,12 @@ class BitcoinApi implements AbstractBitcoinApi {
|
||||
}
|
||||
let mempoolEntry: IBitcoinApi.MempoolEntry;
|
||||
if (!mempool.isInSync() && !this.rawMempoolCache) {
|
||||
this.rawMempoolCache = await bitcoinBaseApi.$getRawMempoolVerbose();
|
||||
this.rawMempoolCache = await this.$getRawMempoolVerbose();
|
||||
}
|
||||
if (this.rawMempoolCache && this.rawMempoolCache[transaction.txid]) {
|
||||
mempoolEntry = this.rawMempoolCache[transaction.txid];
|
||||
} else {
|
||||
mempoolEntry = await bitcoinBaseApi.$getMempoolEntry(transaction.txid);
|
||||
mempoolEntry = await this.$getMempoolEntry(transaction.txid);
|
||||
}
|
||||
transaction.fee = mempoolEntry.fees.base * 100000000;
|
||||
return transaction;
|
||||
@ -238,6 +237,14 @@ class BitcoinApi implements AbstractBitcoinApi {
|
||||
return this.bitcoindClient.validateAddress(address);
|
||||
}
|
||||
|
||||
private $getMempoolEntry(txid: string): Promise<IBitcoinApi.MempoolEntry> {
|
||||
return this.bitcoindClient.getMempoolEntry(txid);
|
||||
}
|
||||
|
||||
private $getRawMempoolVerbose(): Promise<IBitcoinApi.RawMempool> {
|
||||
return this.bitcoindClient.getRawMemPool(true);
|
||||
}
|
||||
|
||||
private async $calculateFeeFromInputs(transaction: IEsploraApi.Transaction, addPrevout: boolean): Promise<IEsploraApi.Transaction> {
|
||||
if (transaction.vin[0].is_coinbase) {
|
||||
transaction.fee = 0;
|
||||
|
@ -40,19 +40,6 @@ class BitcoinBaseApi {
|
||||
}
|
||||
return this.bitcoindClient.getMempoolInfo();
|
||||
}
|
||||
|
||||
$getRawTransaction(txId: string): Promise<IBitcoinApi.Transaction> {
|
||||
return this.bitcoindClient.getRawTransaction(txId, true);
|
||||
}
|
||||
|
||||
$getMempoolEntry(txid: string): Promise<IBitcoinApi.MempoolEntry> {
|
||||
return this.bitcoindClient.getMempoolEntry(txid);
|
||||
}
|
||||
|
||||
$getRawMempoolVerbose(): Promise<IBitcoinApi.RawMempool> {
|
||||
return this.bitcoindClient.getRawMemPool(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new BitcoinBaseApi();
|
||||
|
@ -73,11 +73,12 @@ class Blocks {
|
||||
let findCoinbaseTxTries = 0;
|
||||
// It takes Electrum Server a few seconds to index the transaction after a block is found
|
||||
while (findCoinbaseTxTries < 5 && !txFound) {
|
||||
const tx = await transactionUtils.$getTransactionExtended(txIds[i]);
|
||||
if (tx) {
|
||||
try {
|
||||
const tx = await transactionUtils.$getTransactionExtended(txIds[i]);
|
||||
txFound = true;
|
||||
transactions.push(tx);
|
||||
} else {
|
||||
} catch (e) {
|
||||
logger.debug('Coinbase transaction fetch error: ' + e.message || e);
|
||||
await Common.sleep(1000);
|
||||
findCoinbaseTxTries++;
|
||||
}
|
||||
@ -88,9 +89,11 @@ class Blocks {
|
||||
transactionsFound++;
|
||||
} else if (config.MEMPOOL.BACKEND === 'esplora' || memPool.isInSync()) {
|
||||
logger.debug(`Fetching block tx ${i} of ${txIds.length}`);
|
||||
const tx = await transactionUtils.$getTransactionExtended(txIds[i]);
|
||||
if (tx) {
|
||||
try {
|
||||
const tx = await transactionUtils.$getTransactionExtended(txIds[i]);
|
||||
transactions.push(tx);
|
||||
} catch (e) {
|
||||
logger.debug('Error fetching block tx: ' + e.message || e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,8 +103,8 @@ class Mempool {
|
||||
|
||||
for (const txid of transactions) {
|
||||
if (!this.mempoolCache[txid]) {
|
||||
const transaction = await transactionUtils.$getTransactionExtended(txid, true);
|
||||
if (transaction) {
|
||||
try {
|
||||
const transaction = await transactionUtils.$getTransactionExtended(txid, true);
|
||||
this.mempoolCache[txid] = transaction;
|
||||
txCount++;
|
||||
if (this.inSync) {
|
||||
@ -121,8 +121,8 @@ class Mempool {
|
||||
logger.debug('Fetched transaction ' + txCount);
|
||||
}
|
||||
newTransactions.push(transaction);
|
||||
} else {
|
||||
logger.debug('Error finding transaction in mempool.');
|
||||
} catch (e) {
|
||||
logger.debug('Error finding transaction in mempool: ' + e.message || e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,20 +20,14 @@ class TransactionUtils {
|
||||
};
|
||||
}
|
||||
|
||||
public async $getTransactionExtended(txId: string, forceBitcoind = false, addPrevouts = false): Promise<TransactionExtended | null> {
|
||||
try {
|
||||
let transaction: IEsploraApi.Transaction;
|
||||
if (forceBitcoind) {
|
||||
transaction = await bitcoinApi.$getRawTransactionBitcoind(txId, false, addPrevouts);
|
||||
} else {
|
||||
transaction = await bitcoinApi.$getRawTransaction(txId, false, addPrevouts);
|
||||
}
|
||||
return this.extendTransaction(transaction);
|
||||
} catch (e) {
|
||||
logger.debug('getTransactionExtended error: ' + (e.message || e));
|
||||
logger.debug(JSON.stringify(e));
|
||||
return null;
|
||||
public async $getTransactionExtended(txId: string, forceBitcoind = false, addPrevouts = false): Promise<TransactionExtended> {
|
||||
let transaction: IEsploraApi.Transaction;
|
||||
if (forceBitcoind) {
|
||||
transaction = await bitcoinApi.$getRawTransactionBitcoind(txId, false, addPrevouts);
|
||||
} else {
|
||||
transaction = await bitcoinApi.$getRawTransaction(txId, false, addPrevouts);
|
||||
}
|
||||
return this.extendTransaction(transaction);
|
||||
}
|
||||
|
||||
private extendTransaction(transaction: IEsploraApi.Transaction): TransactionExtended {
|
||||
|
@ -219,9 +219,11 @@ class WebsocketHandler {
|
||||
const tx = newTransactions.find((t) => t.txid === client['track-mempool-tx']);
|
||||
if (tx) {
|
||||
if (config.MEMPOOL.BACKEND !== 'esplora') {
|
||||
const fullTx = await transactionUtils.$getTransactionExtended(tx.txid, false, true);
|
||||
if (fullTx) {
|
||||
try {
|
||||
const fullTx = await transactionUtils.$getTransactionExtended(tx.txid, false, true);
|
||||
response['tx'] = fullTx;
|
||||
} catch (e) {
|
||||
logger.debug('Error finding transaction in mempool: ' + e.message || e);
|
||||
}
|
||||
} else {
|
||||
response['tx'] = tx;
|
||||
@ -237,9 +239,11 @@ class WebsocketHandler {
|
||||
const someVin = tx.vin.some((vin) => !!vin.prevout && vin.prevout.scriptpubkey_address === client['track-address']);
|
||||
if (someVin) {
|
||||
if (config.MEMPOOL.BACKEND !== 'esplora') {
|
||||
const fullTx = await transactionUtils.$getTransactionExtended(tx.txid, false, true);
|
||||
if (fullTx) {
|
||||
try {
|
||||
const fullTx = await transactionUtils.$getTransactionExtended(tx.txid, false, true);
|
||||
foundTransactions.push(fullTx);
|
||||
} catch (e) {
|
||||
logger.debug('Error finding transaction in mempool: ' + e.message || e);
|
||||
}
|
||||
} else {
|
||||
foundTransactions.push(tx);
|
||||
@ -249,9 +253,11 @@ class WebsocketHandler {
|
||||
const someVout = tx.vout.some((vout) => vout.scriptpubkey_address === client['track-address']);
|
||||
if (someVout) {
|
||||
if (config.MEMPOOL.BACKEND !== 'esplora') {
|
||||
const fullTx = await transactionUtils.$getTransactionExtended(tx.txid, false, true);
|
||||
if (fullTx) {
|
||||
try {
|
||||
const fullTx = await transactionUtils.$getTransactionExtended(tx.txid, false, true);
|
||||
foundTransactions.push(fullTx);
|
||||
} catch (e) {
|
||||
logger.debug('Error finding transaction in mempool: ' + e.message || e);
|
||||
}
|
||||
} else {
|
||||
foundTransactions.push(tx);
|
||||
@ -298,9 +304,11 @@ class WebsocketHandler {
|
||||
if (client['track-tx'] === rbfTransaction) {
|
||||
const rbfTx = rbfTransactions[rbfTransaction];
|
||||
if (config.MEMPOOL.BACKEND !== 'esplora') {
|
||||
const fullTx = await transactionUtils.$getTransactionExtended(rbfTransaction, false, true);
|
||||
if (fullTx) {
|
||||
try {
|
||||
const fullTx = await transactionUtils.$getTransactionExtended(rbfTransaction, false, true);
|
||||
response['rbfTransaction'] = fullTx;
|
||||
} catch (e) {
|
||||
logger.debug('Error finding transaction in mempool: ' + e.message || e);
|
||||
}
|
||||
} else {
|
||||
response['rbfTransaction'] = rbfTx;
|
||||
|
@ -532,14 +532,13 @@ class Routes {
|
||||
public async getTransaction(req: Request, res: Response) {
|
||||
try {
|
||||
const transaction = await transactionUtils.$getTransactionExtended(req.params.txId, false, true);
|
||||
|
||||
if (transaction) {
|
||||
res.json(transaction);
|
||||
} else {
|
||||
res.status(500).send('Error fetching transaction.');
|
||||
}
|
||||
res.json(transaction);
|
||||
} catch (e) {
|
||||
res.status(500).send(e.message || e);
|
||||
let statusCode = 500;
|
||||
if (e.message && e.message.indexOf('No such mempool or blockchain transaction') > -1) {
|
||||
statusCode = 404;
|
||||
}
|
||||
res.status(statusCode).send(e.message || e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,10 +598,12 @@ class Routes {
|
||||
|
||||
const endIndex = Math.min(startingIndex + 10, txIds.length);
|
||||
for (let i = startingIndex; i < endIndex; i++) {
|
||||
const transaction = await transactionUtils.$getTransactionExtended(txIds[i], false, true);
|
||||
if (transaction) {
|
||||
try {
|
||||
const transaction = await transactionUtils.$getTransactionExtended(txIds[i], false, true);
|
||||
transactions.push(transaction);
|
||||
loadingIndicators.setProgress('blocktxs-' + req.params.hash, (i + 1) / endIndex * 100);
|
||||
} catch (e) {
|
||||
logger.debug('getBlockTransactions error: ' + e.message || e);
|
||||
}
|
||||
}
|
||||
res.json(transactions);
|
||||
|
Loading…
x
Reference in New Issue
Block a user