From bea32a6af572087b7b2799856f25c5bf4086b5b3 Mon Sep 17 00:00:00 2001 From: Nadav Ivgi Date: Fri, 19 Feb 2021 15:46:38 +0200 Subject: [PATCH] Lookup txid in external Electrum txindex This only works with Electrs and requires enabling BTCEXP_ELECTRUM_TXINDEX. See: https://github.com/romanz/electrs/commit/a0a3d4f9392e21f9e92fdc274c88fed6d0634794 --- .env-sample | 3 +++ app/api/electrumAddressApi.js | 22 +++++++++++++++++++++- app/api/rpcApi.js | 11 +++++++++++ app/config.js | 4 +++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/.env-sample b/.env-sample index fa08d6460..ee5a3d2c2 100644 --- a/.env-sample +++ b/.env-sample @@ -44,6 +44,9 @@ # used if BTCEXP_ADDRESS_API=electrumx #BTCEXP_ELECTRUMX_SERVERS=tls://electrumx.server.com:50002,tcp://127.0.0.1:50001,... +# Use the Electrumx server as an external txindex. This is only available in Electrs. +#BTCEXP_ELECTRUM_TXINDEX=true + # Set number of concurrent RPC requests. Should be lower than your node's "rpcworkqueue" value. # Note that Bitcoin Core's default rpcworkqueue=16. # Default: 10 diff --git a/app/api/electrumAddressApi.js b/app/api/electrumAddressApi.js index d55e5c888..ed1dbbf40 100644 --- a/app/api/electrumAddressApi.js +++ b/app/api/electrumAddressApi.js @@ -323,6 +323,25 @@ function getAddressBalance(addrScripthash) { }); } +// Lookup the confirming block hash of a given txid. This only works with Electrs. +// https://github.com/romanz/electrs/commit/a0a3d4f9392e21f9e92fdc274c88fed6d0634794 +function lookupTxBlockHash(txid) { + if (electrumClients.length == 0) { + return Promise.reject({ error: "No ElectrumX Connection", userText: noConnectionsErrorText }); + } + + return runOnAllServers(function(electrumClient) { + return electrumClient.request('blockchain.transaction.get_confirmed_blockhash', [txid]); + }).then(function(results) { + var blockhash = results[0].result; + if (results.slice(1).every(({ result }) => result == blockhash)) { + return blockhash; + } else { + return Promise.reject({conflictedResults:results}); + } + }); +} + function logStats(cmd, dt, success) { if (!global.electrumStats.rpc[cmd]) { global.electrumStats.rpc[cmd] = {count:0, time:0, successes:0, failures:0}; @@ -341,6 +360,7 @@ function logStats(cmd, dt, success) { module.exports = { connectToServers: connectToServers, - getAddressDetails: getAddressDetails + getAddressDetails: getAddressDetails, + lookupTxBlockHash: lookupTxBlockHash, }; diff --git a/app/api/rpcApi.js b/app/api/rpcApi.js index 7f16e4c42..5335cd5ee 100644 --- a/app/api/rpcApi.js +++ b/app/api/rpcApi.js @@ -268,6 +268,17 @@ function getRawTransaction(txid, blockhash) { } async function noTxIndexTransactionLookup(txid) { + // Try looking up with an external Electrum server, using 'get_confirmed_blockhash'. + // This is only available in Electrs and requires enabling BTCEXP_ELECTRUM_TXINDEX. + if (config.addressApi == "electrumx" && config.electrumTxIndex) { + try { + var blockhash = await electrumAddressApi.lookupTxBlockHash(txid); + return await getRawTransaction(txid, blockhash); + } catch (err) { + debugLog(`Electrs blockhash lookup failed for ${txid}:`, err); + } + } + // Try looking up in wallet transactions for (var wallet of await listWallets()) { try { return await getWalletTransaction(wallet, txid); } diff --git a/app/config.js b/app/config.js index daef33a03..48fbecfe7 100644 --- a/app/config.js +++ b/app/config.js @@ -49,7 +49,8 @@ for (var i = 0; i < electrumXServerUriStrings.length; i++) { "BTCEXP_DEMO", "BTCEXP_PRIVACY_MODE", "BTCEXP_NO_INMEMORY_RPC_CACHE", - "BTCEXP_RPC_ALLOWALL" + "BTCEXP_RPC_ALLOWALL", + "BTCEXP_ELECTRUM_TXINDEX", ].forEach(function(item) { if (process.env[item] === undefined) { @@ -170,6 +171,7 @@ module.exports = { ], addressApi:process.env.BTCEXP_ADDRESS_API, + electrumTxIndex:process.env.BTCEXP_ELECTRUM_TXINDEX != "false", electrumXServers:electrumXServers, redisUrl:process.env.BTCEXP_REDIS_URL,