Skip to content

Commit

Permalink
Show the spending tx of outpoints with electrum 1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Pantamis committed Aug 9, 2021
1 parent a32d68f commit 07ef92f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
29 changes: 29 additions & 0 deletions app/api/electrumAddressApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,34 @@ function lookupTxBlockHash(txid) {
});
}

// Lookup the spending transaction and height of a given transaction output. Only works with Electrum 1.5 protocol, ElectRS 0.9.0 does not implement subscriptions
// but can return the transaction spending the given outpoint

function lookupOutpointTx(txid, vout) {
if (electrumClients.length == 0) {
return Promise.reject({ error: "Not supported by Electrum 1.4", userText: noConnectionsErrorText });
}

return runOnAllServers(function(electrumClient) {
return electrumClient.request('blockchain.outpoint.subscribe', [txid, vout]);
}).then(function(results) {
var spend_infos = results[0].result;
runOnAllServers(function(electrumClient) {
return electrumClient.request('blockchain.outpoint.unsubscribe', [txid, vout]) //will fail until subscriptions for outpoint are implemented in ElectRS
});
if (results.slice(1).every(({ result }) => result == spend_infos)) {
if (spend_infos.length < 2) {
return false;
} else {
return spend_infos;
}
} 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};
Expand Down Expand Up @@ -380,5 +408,6 @@ module.exports = {
connectToServers: connectToServers,
getAddressDetails: getAddressDetails,
lookupTxBlockHash: lookupTxBlockHash,
lookupOutpointTx: lookupOutpointTx,
};

20 changes: 20 additions & 0 deletions routes/baseRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const coins = require("./../app/coins.js");
const config = require("./../app/config.js");
const coreApi = require("./../app/api/coreApi.js");
const addressApi = require("./../app/api/addressApi.js");
const electrumAddressApi = require("./../app/api/electrumAddressApi.js");
const rpcApi = require("./../app/api/rpcApi.js");
const btcQuotes = require("./../app/coins/btcQuotes.js");

Expand Down Expand Up @@ -1423,6 +1424,25 @@ router.get("/tx/:transactionId", asyncHandler(async (req, res, next) => {

await Promise.all(promises);

// Electrs 0.9.0 support spending transaction lookup for an outpoint
if ((config.addressApi == "electrum" || config.addressApi == "electrumx") && config.electrumTxIndex) {
let spending_promises = [];
for (const vout in tx.vout) {
spending_promises.push(new Promise(async (resolve, reject) => {
if (res.locals.utxos[vout] == null) {
const spent = await electrumAddressApi.lookupOutpointTx(txid, parseInt(vout));
resolve(spent);
} else {
resolve(false);
}
}));
}

await Promise.all(spending_promises).then((outpoint_results) => {
res.locals.spendings = outpoint_results;
});
}

if (global.specialTransactions && global.specialTransactions[txid]) {
let funInfo = global.specialTransactions[txid];

Expand Down
14 changes: 13 additions & 1 deletion views/includes/transaction-io-details.pug
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ mixin outputValueDisplay(vout, voutIndex)
if (utxos[voutIndex])
span(title="This output remains unspent (a valid UTXO)." data-bs-toggle="tooltip")
i.far.fa-check-circle.fa-sm.text-success.ms-2

else if (utxos[voutIndex] == null)
span(title="This output has been spent (destroyed)." data-bs-toggle="tooltip")
i.far.fa-times-circle.fa-sm.text-danger.ms-2
Expand Down Expand Up @@ -290,10 +290,22 @@ mixin outputValueDisplay(vout, voutIndex)
+darkBadge
span(title=`Output Type: ${utils.outputTypeName(vout.scriptPubKey.type)}`, data-bs-toggle="tooltip") #{utils.outputTypeAbbreviation(vout.scriptPubKey.type)}

if (spendings)
- var spending_txid = spendings[voutIndex].spender_txhash;
if (spending_txid)
span.mt-1 spent by
a(href=`./tx/${spending_txid}`) #{utils.ellipsizeMiddle(spendings[voutIndex].spender_txhash,9)}
if (spendings[voutIndex].spender_height > 0 && spendings[voutIndex].spender_height > spendings[voutIndex].height)
span #{spendings[voutIndex].spender_height - spendings[voutIndex].height} blocks later
else if (spendings[voutIndex].spender_height <= 0)
span in the mempool
else if (spendings[voutIndex].spender_height == spendings[voutIndex].height)
span in the same block

span.ms-2.float-end
+outputValueDisplay(vout, voutIndex)


if (vout && vout.scriptPubKey.asm && !vout.scriptPubKey.asm.startsWith("OP_RETURN "))
if (voutAddresses.length == 0)
.my-2.d-none.d-sm-block
Expand Down

0 comments on commit 07ef92f

Please sign in to comment.