Correctly error handle getTransaction and set 404 status when not found.

This commit is contained in:
softsimon 2021-01-24 02:51:22 +07:00
parent fb41f58f7c
commit 5b268794af
No known key found for this signature in database
GPG Key ID: 488D7DCFB5A430D7
7 changed files with 55 additions and 55 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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;

View File

@ -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);