Browse Source

new tool for browsing unconfirmed tx

fix-133-memory-crash
Dan Janosik 7 years ago
parent
commit
2051d4da53
  1. 58
      app/api/coreApi.js
  2. 6
      app/config.js
  3. 34
      routes/baseActionsRouter.js
  4. 2
      views/includes/tools-card.pug
  5. 54
      views/unconfirmed-transactions.pug

58
app/api/coreApi.js

@ -158,6 +158,61 @@ function getPeerSummary() {
});
}
function getMempoolDetails(start, count) {
return new Promise(function(resolve, reject) {
tryCacheThenRpcApi(miscCache, "getRawMempool", 1000, rpcApi.getRawMempool).then(function(result) {
var txids = [];
var txidIndex = 0;
for (var txid in result) {
if (txidIndex >= start && (txidIndex < (start + count))) {
txids.push(txid);
}
txidIndex++;
}
getRawTransactions(txids).then(function(transactions) {
var maxInputsTracked = 10;
var vinTxids = [];
for (var i = 0; i < transactions.length; i++) {
var transaction = transactions[i];
if (transaction && transaction.vin) {
for (var j = 0; j < Math.min(maxInputsTracked, transaction.vin.length); j++) {
if (transaction.vin[j].txid) {
vinTxids.push(transaction.vin[j].txid);
}
}
}
}
var txInputsByTransaction = {};
getRawTransactions(vinTxids).then(function(vinTransactions) {
var vinTxById = {};
vinTransactions.forEach(function(tx) {
vinTxById[tx.txid] = tx;
});
transactions.forEach(function(tx) {
txInputsByTransaction[tx.txid] = [];
if (tx && tx.vin) {
for (var i = 0; i < Math.min(maxInputsTracked, tx.vin.length); i++) {
if (vinTxById[tx.vin[i].txid]) {
txInputsByTransaction[tx.txid].push(vinTxById[tx.vin[i].txid]);
}
}
}
});
resolve({ txCount:txidIndex, transactions:transactions, txInputsByTransaction:txInputsByTransaction });
});
});
});
});
}
function getMempoolStats() {
return new Promise(function(resolve, reject) {
tryCacheThenRpcApi(miscCache, "getRawMempool", 5000, rpcApi.getRawMempool).then(function(result) {
@ -600,5 +655,6 @@ module.exports = {
getAddress: getAddress,
logCacheSizes: logCacheSizes,
getPeerSummary: getPeerSummary,
getChainTxStats: getChainTxStats
getChainTxStats: getChainTxStats,
getMempoolDetails: getMempoolDetails
};

6
app/config.js

@ -49,10 +49,12 @@ module.exports = {
{name:"Browse Blocks", url:"/blocks", desc:"Browse all blocks in the blockchain.", fontawesome:"fas fa-cubes"},
{name:"Transaction Stats", url:"/tx-stats", desc:"See graphs of total transaction volume and transaction rates.", fontawesome:"fas fa-chart-bar"},
{name:"Mempool Summary", url:"/mempool-summary", desc:"Detailed summary of the current mempool for this node.", fontawesome:"fas fa-clipboard-list"},
{name:"Unconfirmed Transactions", url:"/unconfirmed-tx", desc:"Browse unconfirmed/pending transactions.", fontawesome:"fas fa-unlock-alt"},
{name:"RPC Browser", url:"/rpc-browser", desc:"Browse the RPC functionality of this node. See docs and execute commands.", fontawesome:"fas fa-book"},
{name:"RPC Terminal", url:"/rpc-terminal", desc:"Directly execute RPCs against this node.", fontawesome:"fas fa-terminal"},
{name:"Mempool Summary", url:"/mempool-summary", desc:"Detailed summary of the current mempool for this node.", fontawesome:"fas fa-clipboard-list"},
{name:(coins[currentCoin].name + " Fun"), url:"/fun", desc:"See fun/interesting historical blockchain data.", fontawesome:"fas fa-certificate"}
],

34
routes/baseActionsRouter.js

@ -707,6 +707,40 @@ router.get("/rpc-browser", function(req, res) {
});
});
router.get("/unconfirmed-tx", function(req, res) {
var limit = config.site.browseBlocksPageSize;
var offset = 0;
var sort = "desc";
if (req.query.limit) {
limit = parseInt(req.query.limit);
}
if (req.query.offset) {
offset = parseInt(req.query.offset);
}
if (req.query.sort) {
sort = req.query.sort;
}
res.locals.limit = limit;
res.locals.offset = offset;
res.locals.sort = sort;
res.locals.paginationBaseUrl = "/unconfirmed-tx";
coreApi.getMempoolDetails(offset, limit).then(function(mempoolDetails) {
res.locals.mempoolDetails = mempoolDetails;
res.render("unconfirmed-transactions");
}).catch(function(err) {
res.locals.userMessage = "Error: " + err;
res.render("unconfirmed-transactions");
});
});
router.get("/tx-stats", function(req, res) {
var dataPoints = 150;

2
views/includes/tools-card.pug

@ -3,7 +3,7 @@ div(class="card mb-3")
h2(class="h6 mb-0") Tools
div(class="card-body")
div(class="row")
each item, index in [[0, 1, 6], [2, 3, 7], [4, 5]]
each item, index in [[0, 1, 2], [4, 3, 5], [6, 7, 8]]
div(class="col-md-4")
ul(style="list-style-type: none;", class="pl-0")
each toolIndex, toolIndexIndex in item

54
views/unconfirmed-transactions.pug

@ -0,0 +1,54 @@
extends layout
block headContent
title Unconfirmed Transactions
block content
h1(class="h2") Unconfirmed Transactions
hr
if (false)
pre
code #{JSON.stringify(mempoolDetails.txCount, null, 4)}
if (mempoolDetails)
- var txCount = mempoolDetails.txCount;
div(class="card")
div(class="card-header")
span(class="h6")
if (txCount == 1)
span 1 Transaction
else
span #{txCount.toLocaleString()} Transactions
div(class="card-body")
each tx, txIndex in mempoolDetails.transactions
div(class="xcard mb-3")
div(class="card-header")
if (tx && tx.txid)
strong ##{(txIndex + offset).toLocaleString()}
span &ndash;
a(href=("/tx/" + tx.txid), class="monospace") #{tx.txid}
div(class="card-body")
- var txInputs = mempoolDetails.txInputsByTransaction[tx.txid];
- var blockHeight = -1;
include includes/transaction-io-details.pug
if (txCount > limit)
- var pageNumber = offset / limit + 1;
- var pageCount = Math.floor(txCount / limit);
- if (pageCount * limit < txCount) {
- pageCount++;
- }
- var paginationUrlFunction = function(x) {
- return paginationBaseUrl + "?limit=" + limit + "&offset=" + ((x - 1) * limit + "&sort=" + sort);
- }
hr
include includes/pagination.pug
else
p No unconfirmed transactions found
Loading…
Cancel
Save