You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
366 lines
13 KiB
366 lines
13 KiB
extends layout
|
|
|
|
block headContent
|
|
title Mining Summary
|
|
|
|
block content
|
|
h1.h3 Mining Summary
|
|
hr
|
|
|
|
div.card.shadow-sm.mb-3
|
|
div.card-body
|
|
h3.h6.mb-0 Block Range
|
|
hr
|
|
|
|
div.clearfix
|
|
div.float-left.mr-4
|
|
div(id="time-range-buttons")
|
|
h3.h6 Latest N Blocks
|
|
div.btn-group
|
|
a.btn.btn-primary.block-count-btn(href="javascript:void(0)", data-blockCount="144") 144
|
|
small.ml-2 (~1d)
|
|
a.btn.btn-outline-primary.block-count-btn(href="javascript:void(0)", data-blockCount="432") 432
|
|
small.ml-2 (~3d)
|
|
a.btn.btn-outline-primary.block-count-btn(href="javascript:void(0)", data-blockCount="1008") 1,008
|
|
small.ml-2 (~7d)
|
|
a.btn.btn-outline-primary.block-count-btn(href="javascript:void(0)", data-blockCount="4320") 4,320
|
|
small.ml-2 (~30d)
|
|
|
|
div.float-left.mr-4
|
|
div(id="block-selections-buttons")
|
|
h3.h6 Preconfigured
|
|
|
|
div.dropdown
|
|
button.btn.btn-outline-primary.dropdown-toggle(type="button", id="preconfigured-dropdown", data-toggle="dropdown", aria-haspopup="true", aria-expanded="false") Selections
|
|
div.dropdown-menu(aria-labelledby="preconfigured-dropdown")
|
|
a.dropdown-item(href="javascript:void(0)", data-blocks="0-199") First 200 Blocks
|
|
a.dropdown-item(href="javascript:void(0)", data-blocks="209900-210100") First Halving ±100
|
|
a.dropdown-item(href="javascript:void(0)", data-blocks="419900-420100") Second Halving ±100
|
|
a.dropdown-item(href="javascript:void(0)", data-blocks="481724-481924") SegWit Activation ±100
|
|
|
|
div.float-left
|
|
div(id="time-range-buttons")
|
|
h3.h6 Custom Range
|
|
|
|
form.form-inline.mr-3(id="custom-range-form")
|
|
div.input-group
|
|
input.form-control(type="text", id="custom-range-start", placeholder="min height", style="width: 125px;")
|
|
input.form-control(type="text", id="custom-range-end", placeholder="max height", style="width: 125px;")
|
|
div.input-group-append
|
|
button.btn.btn-primary(type="submit") Go
|
|
|
|
div#progress-wrapper
|
|
div.card.shadow-sm.mb-3
|
|
div.card-body
|
|
h4.h6 Loading blocks:
|
|
span(id="block-progress-text")
|
|
div.progress(id="progress-bar", style="height: 7px;")
|
|
div.progress-bar(id="data-progress", role="progressbar", aria-valuenow="0", aria-valuemin="0" ,aria-valuemax="100")
|
|
|
|
|
|
div.card.shadow-sm.mb-3(id="summary-table", style="display: none;")
|
|
div.card-body
|
|
div.table-responsive
|
|
table.table.table-striped.mb-0
|
|
thead
|
|
tr
|
|
th.data-header Miner
|
|
th.data-header.text-right Blocks
|
|
th.data-header.text-right Transactions
|
|
th.data-header.text-right Block Rewards
|
|
th.data-header.text-right Fees Collected
|
|
|
|
tbody(id="summary-table-body")
|
|
tr(id="miner-summary-prototype", style="display: none;")
|
|
td.data-cell.text-monospace.miner-name
|
|
td.data-cell.text-monospace.text-right
|
|
span.miner-block-count
|
|
small.text-muted.miner-block-percent.ml-2
|
|
td.data-cell.text-monospace.text-right
|
|
span.miner-tx-count
|
|
small.text-muted.miner-tx-percent.ml-2
|
|
td.data-cell.text-monospace.text-right
|
|
span.miner-subsidy
|
|
small.text-muted.miner-subsidy-percent.ml-2
|
|
//- var currencyValue = new Decimal(summary.totalSubsidiesCollected);
|
|
//include ./includes/value-display.pug
|
|
td.data-cell.text-monospace.text-right
|
|
span.miner-fees
|
|
small.text-muted.miner-fees-percent
|
|
//- var currencyValue = new Decimal(summary.totalFeesCollected);
|
|
//include ./includes/value-display.pug
|
|
|
|
tr(id="miner-summary-totals", style="display: none;")
|
|
th.data-cell.text-monospace.miner-name Total
|
|
th.data-cell.text-monospace.text-right
|
|
span.miner-block-count
|
|
small.text-muted.miner-block-percent.ml-2 (100%)
|
|
th.data-cell.text-monospace.text-right
|
|
span.miner-tx-count
|
|
small.text-muted.miner-tx-percent.ml-2 (100%)
|
|
th.data-cell.text-monospace.text-right
|
|
span.miner-subsidy
|
|
//- var currencyValue = new Decimal(summary.totalSubsidiesCollected);
|
|
//include ./includes/value-display.pug
|
|
th.data-cell.text-monospace.text-right
|
|
span.miner-fees
|
|
//- var currencyValue = new Decimal(summary.totalFeesCollected);
|
|
//include ./includes/value-display.pug
|
|
|
|
if (false)
|
|
pre
|
|
code.json #{JSON.stringify(summariesByMiner, null, 4)}
|
|
|
|
block endOfBody
|
|
script(src='/js/decimal.js')
|
|
script.
|
|
var currentBlockHeight = !{currentBlockHeight};
|
|
$(document).ready(function() {
|
|
$("#time-range-buttons .block-count-btn").on("click", function() {
|
|
// highlight current selection
|
|
$("#time-range-buttons .block-count-btn").removeClass("btn-primary").addClass("btn-outline-primary");
|
|
$(this).addClass("btn-primary").removeClass("btn-outline-primary");
|
|
$("#preconfigured-dropdown").removeClass("btn-primary").addClass("btn-outline-primary");
|
|
|
|
var blockCount = parseInt($(this).attr("data-blockCount"));
|
|
|
|
$(".miner-summary-row").remove();
|
|
|
|
$("#data-progress").css("width", "0%");
|
|
$("#block-progress-text").text("");
|
|
|
|
$("#summary-table").hide();
|
|
$("#progress-wrapper").show();
|
|
|
|
getData(currentBlockHeight, blockCount, 15);
|
|
});
|
|
|
|
$("#block-selections-buttons .dropdown-item").on("click", function() {
|
|
// highlight current selection
|
|
$("#time-range-buttons .block-count-btn").removeClass("btn-primary").addClass("btn-outline-primary");
|
|
$("#preconfigured-dropdown").removeClass("btn-outline-primary").addClass("btn-primary");
|
|
|
|
var blocks = $(this).attr("data-blocks");
|
|
var bStartEnd = blocks.split("-");
|
|
var bStart = parseInt(bStartEnd[0]);
|
|
var bEnd = parseInt(bStartEnd[1]);
|
|
|
|
$(".miner-summary-row").remove();
|
|
|
|
$("#data-progress").css("width", "0%");
|
|
$("#block-progress-text").text("");
|
|
|
|
$("#main-content").hide();
|
|
$("#progress-wrapper").show();
|
|
|
|
getData(bEnd, bEnd - bStart + 1, 15);
|
|
});
|
|
|
|
$("#custom-range-form").on("submit", function() {
|
|
// highlight current selection
|
|
$("#time-range-buttons .block-count-btn").removeClass("btn-primary").addClass("btn-outline-primary");
|
|
$("#preconfigured-dropdown").removeClass("btn-primary").addClass("btn-outline-primary");
|
|
|
|
var bStart = parseInt($("#custom-range-start").val());
|
|
var bEnd = parseInt($("#custom-range-end").val());
|
|
|
|
$(".miner-summary-row").remove();
|
|
|
|
$("#data-progress").css("width", "0%");
|
|
$("#block-progress-text").text("");
|
|
|
|
$("#main-content").hide();
|
|
$("#progress-wrapper").show();
|
|
|
|
getData(bEnd, bEnd - bStart + 1, 15);
|
|
|
|
return false;
|
|
});
|
|
|
|
getData(currentBlockHeight, 144, 15);
|
|
});
|
|
|
|
function getData(blockStart, count, chunkSize) {
|
|
$("#time-range-buttons .block-count-btn").addClass("disabled");
|
|
$("#block-selections-buttons .dropdown-item").addClass("disabled");
|
|
|
|
var chunks = [];
|
|
var blockIndex = blockStart;
|
|
while (blockIndex > blockStart - count) {
|
|
var chunk = [];
|
|
for (var i = blockIndex; (i > (blockIndex - chunkSize) && i > (blockStart - count)); i--) {
|
|
chunk.push(i);
|
|
}
|
|
|
|
blockIndex -= chunkSize;
|
|
chunks.push(chunk);
|
|
}
|
|
|
|
console.log(JSON.stringify(chunks));
|
|
//alert(JSON.stringify(chunks));
|
|
|
|
var results = [];
|
|
|
|
var statusCallback = function(chunkIndexDone, chunkCount) {
|
|
console.log("Done: " + Math.min(((chunkIndexDone + 1) * chunkSize), count) + " of " + count);
|
|
|
|
var wPercent = `${parseInt(100 * (chunkIndexDone + 1) / parseFloat(chunkCount))}%`;
|
|
|
|
$("#data-progress").css("width", wPercent);
|
|
$("#block-progress-text").text(`${Math.min(((chunkIndexDone + 1) * chunkSize), count).toLocaleString()} of ${count.toLocaleString()} (${wPercent})`);
|
|
};
|
|
|
|
var finishedCallback = function() {
|
|
$("#time-range-buttons .block-count-btn").removeClass("disabled");
|
|
$("#block-selections-buttons .dropdown-item").removeClass("disabled");
|
|
|
|
//console.log(JSON.stringify(results));
|
|
|
|
var summary = summarizeBlockData(results);
|
|
|
|
|
|
for (var i = 0; i < summary.minerNamesSortedByBlockCount.length; i++) {
|
|
var minerName = summary.minerNamesSortedByBlockCount[i];
|
|
var minerSummary = summary.summariesByMiner[minerName];
|
|
|
|
var row = $("#miner-summary-prototype").clone();
|
|
row.attr("id", null);
|
|
row.addClass("miner-summary-row");
|
|
|
|
row.find(".miner-name").text(minerName);
|
|
|
|
row.find(".miner-block-count").text(minerSummary.blockCount.toLocaleString());
|
|
row.find(".miner-block-percent").text(`(${new Decimal(minerSummary.blockCount).dividedBy(summary.overallSummary.blockCount).times(100).toDecimalPlaces(1)}%)`);
|
|
|
|
row.find(".miner-tx-count").text(minerSummary.transactionCount.toLocaleString());
|
|
row.find(".miner-tx-percent").text(`(${new Decimal(minerSummary.transactionCount).dividedBy(summary.overallSummary.transactionCount).times(100).toDecimalPlaces(1)}%)`);
|
|
|
|
row.find(".miner-subsidy").text(minerSummary.totalSubsidiesCollected.toLocaleString());
|
|
row.find(".miner-subsidy-percent").text(`(${new Decimal(minerSummary.totalSubsidiesCollected).dividedBy(summary.overallSummary.totalSubsidiesCollected).times(100).toDecimalPlaces(1)}%)`);
|
|
|
|
row.find(".miner-fees").text(minerSummary.totalFeesCollected.toLocaleString());
|
|
|
|
if (summary.overallSummary.totalFeesCollected > 0) {
|
|
row.find(".miner-fees-percent").text(` (${new Decimal(minerSummary.totalFeesCollected).dividedBy(summary.overallSummary.totalFeesCollected).times(100).toDecimalPlaces(1)}%)`);
|
|
}
|
|
|
|
|
|
updateCurrencyValue(row.find(".miner-subsidy"), minerSummary.totalSubsidiesCollected);
|
|
updateCurrencyValue(row.find(".miner-fees"), minerSummary.totalFeesCollected);
|
|
|
|
|
|
row.show();
|
|
|
|
$("#summary-table-body").append(row);
|
|
}
|
|
|
|
|
|
var totalsRow = $("#miner-summary-totals");
|
|
totalsRow.find(".miner-block-count").text(summary.overallSummary.blockCount.toLocaleString());
|
|
totalsRow.find(".miner-tx-count").text(summary.overallSummary.transactionCount.toLocaleString());
|
|
totalsRow.find(".miner-subsidy").text(summary.overallSummary.totalSubsidiesCollected.toLocaleString());
|
|
totalsRow.find(".miner-fees").text(summary.overallSummary.totalFeesCollected.toLocaleString());
|
|
|
|
var parent = totalsRow.parent();
|
|
parent.remove(totalsRow);
|
|
parent.append(totalsRow);
|
|
|
|
totalsRow.show();
|
|
|
|
$("#summary-table").show();
|
|
$("#progress-wrapper").hide();
|
|
};
|
|
|
|
getBlockData(results, chunks, 0, statusCallback, finishedCallback);
|
|
}
|
|
|
|
function getBlockData(results, chunks, chunkIndex, statusCallback, finishedCallback) {
|
|
if (chunkIndex > chunks.length - 1) {
|
|
finishedCallback();
|
|
|
|
return;
|
|
}
|
|
|
|
var url = `/api/blocks-by-height/${chunks[chunkIndex]}`;
|
|
|
|
//console.log(url);
|
|
|
|
$.ajax({
|
|
url: url
|
|
|
|
}).done(function(result) {
|
|
for (var i = 0; i < result.length; i++) {
|
|
results.push(result[i]);
|
|
}
|
|
|
|
statusCallback(chunkIndex, chunks.length);
|
|
|
|
getBlockData(results, chunks, chunkIndex + 1, statusCallback, finishedCallback);
|
|
});
|
|
}
|
|
|
|
function summarizeBlockData(blocks) {
|
|
var summariesByMiner = {};
|
|
var minerNamesSortedByBlockCount = [];
|
|
|
|
var overallSummary = {};
|
|
overallSummary.blockCount = 0;
|
|
overallSummary.transactionCount = 0;
|
|
overallSummary.totalSubsidiesCollected = new Decimal(0);
|
|
overallSummary.totalFeesCollected = new Decimal(0);
|
|
overallSummary.blockSizeTotal = 0;
|
|
|
|
for (var i = 0; i < blocks.length; i++) {
|
|
var block = blocks[i];
|
|
|
|
var miner = block.miner;
|
|
if (!miner) {
|
|
miner = {name:"Unknown"};
|
|
}
|
|
|
|
if (!summariesByMiner[miner.name]) {
|
|
minerNamesSortedByBlockCount.push(miner.name);
|
|
|
|
summariesByMiner[miner.name] = {};
|
|
summariesByMiner[miner.name].miner = miner;
|
|
|
|
summariesByMiner[miner.name].blockCount = 0;
|
|
summariesByMiner[miner.name].transactionCount = 0;
|
|
summariesByMiner[miner.name].totalSubsidiesCollected = new Decimal(0);
|
|
summariesByMiner[miner.name].totalFeesCollected = new Decimal(0);
|
|
summariesByMiner[miner.name].blockSizeTotal = 0;
|
|
|
|
|
|
if (blocks[0].weight) {
|
|
summariesByMiner[miner.name].blockWeightTotal = 0;
|
|
}
|
|
}
|
|
|
|
summariesByMiner[miner.name].blockCount++;
|
|
summariesByMiner[miner.name].transactionCount += block.tx.length;
|
|
summariesByMiner[miner.name].totalSubsidiesCollected = summariesByMiner[miner.name].totalSubsidiesCollected.add(new Decimal(block.subsidy));
|
|
summariesByMiner[miner.name].totalFeesCollected = summariesByMiner[miner.name].totalFeesCollected.add(new Decimal(block.totalFees));
|
|
summariesByMiner[miner.name].blockSizeTotal += block.size;
|
|
|
|
if (blocks[0].weight) {
|
|
summariesByMiner[miner.name].blockWeightTotal += block.weight;
|
|
}
|
|
|
|
|
|
overallSummary.blockCount++;
|
|
overallSummary.transactionCount += block.tx.length;
|
|
overallSummary.totalSubsidiesCollected = overallSummary.totalSubsidiesCollected.add(new Decimal(block.subsidy));
|
|
overallSummary.totalFeesCollected = overallSummary.totalFeesCollected.add(new Decimal(block.totalFees));
|
|
overallSummary.blockSizeTotal += block.size;
|
|
|
|
if (blocks[0].weight) {
|
|
overallSummary.blockWeightTotal += block.weight;
|
|
}
|
|
}
|
|
|
|
minerNamesSortedByBlockCount.sort(function(a, b) {
|
|
return ((summariesByMiner[a].blockCount > summariesByMiner[b].blockCount) ? -1 : 1);
|
|
});
|
|
|
|
return {summariesByMiner:summariesByMiner, minerNamesSortedByBlockCount:minerNamesSortedByBlockCount, overallSummary:overallSummary};
|
|
}
|