Browse Source

Improvements to mempool summary. Working on #28

fix-133-memory-crash
Dan Janosik 7 years ago
parent
commit
e952d9e56d
  1. 119
      app/rpcApi.js
  2. 149
      views/mempool-summary.pug

119
app/rpcApi.js

@ -104,73 +104,90 @@ function getMempoolStats() {
return;
}
var compiledResult = {};
compiledResult.count = 0;
compiledResult.fee_0_5 = 0;
compiledResult.fee_6_10 = 0;
compiledResult.fee_11_25 = 0;
compiledResult.fee_26_50 = 0;
compiledResult.fee_51_75 = 0;
compiledResult.fee_76_100 = 0;
compiledResult.fee_101_150 = 0;
compiledResult.fee_151_max = 0;
compiledResult.totalfee_0_5 = 0;
compiledResult.totalfee_6_10 = 0;
compiledResult.totalfee_11_25 = 0;
compiledResult.totalfee_26_50 = 0;
compiledResult.totalfee_51_75 = 0;
compiledResult.totalfee_76_100 = 0;
compiledResult.totalfee_101_150 = 0;
compiledResult.totalfee_151_max = 0;
var totalFee = 0;
var maxFee = 0;
var maxFeePerByte = 0;
for (var txid in result) {
var txMempoolInfo = result[txid];
totalFee += txMempoolInfo.modifiedfee;
var fee = txMempoolInfo.modifiedfee;
var feePerByte = txMempoolInfo.modifiedfee / txMempoolInfo.size;
var feeRate = Math.round(txMempoolInfo.modifiedfee * 100000000 / txMempoolInfo.size);
if (fee > maxFee) {
maxFee = txMempoolInfo.modifiedfee;
}
if (feePerByte > maxFeePerByte) {
maxFeePerByte = txMempoolInfo.modifiedfee / txMempoolInfo.size;
}
}
if (feeRate <= 5) {
compiledResult.fee_0_5++;
compiledResult.totalfee_0_5 += txMempoolInfo.modifiedfee;
var satoshiPerByteBucketMaxima = [1, 5, 10, 15, 20, 25, 50, 75, 100, 150];
var bucketCount = satoshiPerByteBucketMaxima.length + 1;
var satoshiPerByteBuckets = [];
var satoshiPerByteBucketLabels = [];
satoshiPerByteBucketLabels[0] = ("[0 - " + satoshiPerByteBucketMaxima[0] + ")");
for (var i = 0; i < bucketCount; i++) {
satoshiPerByteBuckets[i] = {"count":0, "totalFees":0, "totalBytes":0};
if (i > 0 && i < bucketCount - 1) {
satoshiPerByteBucketLabels[i] = ("[" + satoshiPerByteBucketMaxima[i - 1] + " - " + satoshiPerByteBucketMaxima[i] + ")");
}
}
} else if (feeRate <= 10) {
compiledResult.fee_6_10++;
compiledResult.totalfee_6_10 += txMempoolInfo.modifiedfee;
satoshiPerByteBucketLabels[bucketCount - 1] = (satoshiPerByteBucketMaxima[satoshiPerByteBucketMaxima.length - 1] + "+");
} else if (feeRate <= 25) {
compiledResult.fee_11_25++;
compiledResult.totalfee_11_25 += txMempoolInfo.modifiedfee;
var summary = {
"count":0,
"totalFees":0,
"totalBytes":0,
"satoshiPerByteBuckets":satoshiPerByteBuckets,
"satoshiPerByteBucketLabels":satoshiPerByteBucketLabels
};
} else if (feeRate <= 50) {
compiledResult.fee_26_50++;
compiledResult.totalfee_26_50 += txMempoolInfo.modifiedfee;
for (var txid in result) {
var txMempoolInfo = result[txid];
var fee = txMempoolInfo.modifiedfee;
var feePerByte = txMempoolInfo.modifiedfee / txMempoolInfo.size;
var satoshiPerByte = feePerByte * 100000000;
} else if (feeRate <= 75) {
compiledResult.fee_51_75++;
compiledResult.totalfee_51_75 += txMempoolInfo.modifiedfee;
var addedToBucket = false;
for (var i = 0; i < satoshiPerByteBucketMaxima.length; i++) {
if (satoshiPerByteBucketMaxima[i] > satoshiPerByte) {
satoshiPerByteBuckets[i]["count"]++;
satoshiPerByteBuckets[i]["totalFees"] += fee;
satoshiPerByteBuckets[i]["totalBytes"] += txMempoolInfo.size;
} else if (feeRate <= 100) {
compiledResult.fee_76_100++;
compiledResult.totalfee_76_100 += txMempoolInfo.modifiedfee;
addedToBucket = true;
} else if (feeRate <= 150) {
compiledResult.fee_101_150++;
compiledResult.totalfee_101_150 += txMempoolInfo.modifiedfee;
break;
}
}
} else {
compiledResult.fee_151_max++;
compiledResult.totalfee_151_max += txMempoolInfo.modifiedfee;
if (!addedToBucket) {
satoshiPerByteBuckets[bucketCount - 1]["count"]++;
satoshiPerByteBuckets[bucketCount - 1]["totalFees"] += fee;
satoshiPerByteBuckets[bucketCount - 1]["totalBytes"] += txMempoolInfo.size;
}
compiledResult.count++;
summary["count"]++;
summary["totalFees"] += txMempoolInfo.modifiedfee;
summary["totalBytes"] += txMempoolInfo.size;
}
compiledResult.totalFee = totalFee;
summary["averageFee"] = summary["totalFees"] / summary["count"];
summary["averageFeePerByte"] = summary["totalFees"] / summary["totalBytes"] / summary["count"];
summary["satoshiPerByteBucketMaxima"] = satoshiPerByteBucketMaxima;
summary["satoshiPerByteBucketCounts"] = [];
summary["satoshiPerByteBucketTotalFees"] = [];
for (var i = 0; i < bucketCount; i++) {
summary["satoshiPerByteBucketCounts"].push(summary["satoshiPerByteBuckets"][i]["count"]);
summary["satoshiPerByteBucketTotalFees"].push(summary["satoshiPerByteBuckets"][i]["totalFees"]);
}
resolve(compiledResult);
resolve(summary);
});
});
}

149
views/mempool-summary.pug

@ -7,10 +7,11 @@ block content
h1(class="h2") Mempool Summary
hr
if (getmempoolinfo)
p Data from RPC command
a(href="/rpc-browser?method=getmempoolinfo") getmempoolinfo
if (false)
pre
code #{JSON.stringify(mempoolstats, null, 4)}
if (true)
table(class="table")
tr
th(class="table-active properties-header") Transaction Count
@ -20,85 +21,95 @@ block content
td(class="monospace")
span #{utils.formatBytes(getmempoolinfo.usage)}
span(class="text-muted") (virtual size: #{utils.formatBytes(getmempoolinfo.bytes)})
tr
th(class="table-active properties-header") Max Size
td(class="monospace") #{utils.formatBytes(getmempoolinfo.maxmempool)}
tr
th(class="table-active properties-header") Min Fee
td(class="monospace") #{getmempoolinfo.mempoolminfee.toLocaleString()}
tr
th(class="table-active properties-header") Total Fees
td(class="monospace") #{utils.formatCurrencyAmount(mempoolstats.totalFee, currencyFormatType)}
td(class="monospace") #{utils.formatCurrencyAmount(mempoolstats["totalFees"], currencyFormatType)}
if (global.exchangeRate)
span
span(data-toggle="tooltip", title=utils.formatExchangedCurrency(mempoolstats["totalFees"]))
i(class="fas fa-exchange-alt")
tr
th(class="table-active properties-header") Average Fee
td(class="monospace") #{utils.formatCurrencyAmount(mempoolstats["averageFee"], currencyFormatType)}
if (global.exchangeRate)
span
span(data-toggle="tooltip", title=utils.formatExchangedCurrency(mempoolstats.totalFee))
span(data-toggle="tooltip", title=utils.formatExchangedCurrency(mempoolstats["averageFee"]))
i(class="fas fa-exchange-alt")
tr
th(class="table-active properties-header") Average Fee per Byte
td(class="monospace") #{(mempoolstats["averageFeePerByte"] * 100000000).toFixed(6)} sat/B
h4 Transaction count by fee level
h4 Transactions by fee rate
hr
if (false)
#{JSON.stringify(mempoolstats)}
- var feeBucketLabels = [ "0 - 5 sat/B", "6 - 10 sat/B", "11 - 25 sat/B", "26 - 50 sat/B", "51 - 75 sat/B", "76 - 100 sat/B", "101 - 150 sat/B", "151+ sat/B" ];
- var feeBucketTxCounts = [ mempoolstats.fee_0_5, mempoolstats.fee_6_10, mempoolstats.fee_11_25, mempoolstats.fee_26_50, mempoolstats.fee_51_75, mempoolstats.fee_76_100, mempoolstats.fee_101_150, mempoolstats.fee_151_max ];
- var totalfeeBuckets = [ mempoolstats.totalfee_0_5, mempoolstats.totalfee_6_10, mempoolstats.totalfee_11_25, mempoolstats.totalfee_26_50, mempoolstats.totalfee_51_75, mempoolstats.totalfee_76_100, mempoolstats.totalfee_101_150, mempoolstats.totalfee_151_max ];
- var bgColors = [ "bg-primary", "bg-success", "bg-info", "bg-warning", "bg-danger", "bg-primary progress-bar-striped", "bg-success progress-bar-striped", "bg-info progress-bar-striped" ];
if (true)
- var feeBucketLabels = [("[0 - " + mempoolstats["satoshiPerByteBucketMaxima"][0] + ")")];
each item, index in mempoolstats["satoshiPerByteBuckets"]
if (index > 0 && index < mempoolstats["satoshiPerByteBuckets"].length - 1)
- feeBucketLabels.push(("[" + mempoolstats["satoshiPerByteBucketMaxima"][index - 1] + " - " + mempoolstats["satoshiPerByteBucketMaxima"][index] + ")"));
- feeBucketLabels.push((mempoolstats.satoshiPerByteBucketMaxima[mempoolstats.satoshiPerByteBucketMaxima.length - 1] + "+"));
- var feeBucketTxCounts = mempoolstats["satoshiPerByteBucketCounts"];
- var totalfeeBuckets = mempoolstats["satoshiPerByteBucketTotalFees"];
canvas(id="mempoolBarChart", height="100", class="mb-4")
script(src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js")
canvas(id="mempoolBarChart", height="100")
script var feeBucketLabels = [];
script var bgColors = [];
each feeBucketLabel, index in feeBucketLabels
- var percentTx = Math.round(100 * feeBucketTxCounts[index] / getmempoolinfo.size).toLocaleString();
script feeBucketLabels.push(["#{feeBucketLabel}","#{feeBucketTxCounts[index]} tx (#{percentTx}%)"]);
script bgColors.push("hsl(#{(333 * index / feeBucketLabels.length)}, 100%, 50%)");
script(src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js")
script var feeBucketTxCounts = [#{feeBucketTxCounts}];
script var feeBucketLabels = [];
each feeBucketLabel, index in feeBucketLabels
- var percentTx = Math.round(100 * feeBucketTxCounts[index] / getmempoolinfo.size).toLocaleString();
script feeBucketLabels.push(["#{feeBucketLabel}","#{feeBucketTxCounts[index]} tx (#{percentTx}%)","#{utils.formatCurrencyAmount(totalfeeBuckets[index], currencyFormatType)}"]);
script.
var ctx = document.getElementById("mempoolBarChart").getContext('2d');
var mempoolBarChart = new Chart(ctx, {
type: 'bar',
data: {
labels: feeBucketLabels,
datasets: [{
data: feeBucketTxCounts,
backgroundColor: bgColors
}]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
script var feeBucketTxCounts = [#{feeBucketTxCounts}];
table(class="table table-striped table-responsive-sm")
thead
tr
th Fee Rate
th(class="text-right") Tx Count
th(class="text-right") Total Fees
th(class="text-right") Average Fee Rate
tbody
each item, index in mempoolstats["satoshiPerByteBuckets"]
tr
td #{mempoolstats["satoshiPerByteBucketLabels"][index]}
td(class="text-right monospace") #{item["count"].toLocaleString()}
td(class="text-right monospace") #{utils.formatCurrencyAmount(item["totalFees"], currencyFormatType)}
script.
var ctx = document.getElementById("mempoolBarChart").getContext('2d');
var mempoolBarChart = new Chart(ctx, {
type: 'bar',
data: {
labels: feeBucketLabels,
datasets: [{
data: feeBucketTxCounts,
backgroundColor: [
'rgba(255, 99, 132, 0.3)',
'rgba(255, 159, 64, 0.3)',
'rgba(255, 206, 86, 0.3)',
'rgba(55, 212, 140, 0.3)',
'rgba(75, 192, 192, 0.3)',
'rgba(54, 162, 235, 0.3)',
'rgba(153, 102, 255, 0.3)',
'rgba(0, 0, 0, 0.3)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(255, 159, 64, 1)',
'rgba(255, 206, 86, 1)',
'rgba(55, 212, 140, 1)',
'rgba(75, 192, 192, 1)',
'rgba(54, 162, 235, 1)',
'rgba(153, 102, 255, 1)',
'rgba(0, 0, 0, 1)',
],
borderWidth: 2
}]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
- var avgFeeRate = item["totalFees"] * 100000000 / item["totalBytes"];
td(class="text-right monospace") #{avgFeeRate.toFixed(2)} sat/B
Loading…
Cancel
Save