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.
 
 
 

244 lines
6.1 KiB

extends layout
block headContent
title Difficulty History
block content
h1.h3 Difficulty History
hr
div.card.shadow-sm.mb-3
div.card-body
h3.h6.mb-0 Explanation
hr
ul.mb-0
li Mining difficulty adjusts automatically every #{coinConfig.difficultyAdjustmentBlockCount.toLocaleString()} blocks.
li The adjustment aims to maintain an average block-mining time of #{coinConfig.targetBlockTimeMinutes} minutes.
li A growth in the difficulty indicates that the average block-mining time during the previous adjustment epoch was less than #{coinConfig.targetBlockTimeMinutes} minutes (due to more miners joining the network and searching for blocks).
li A drop in difficulty indicates miners have left the network so finding each block is adjusted to be easier for the smaller number remaining.
li The numeric Difficulty is a multiple of the difficulty of finding the easiest block (Block #0) - e.g. blocks in BTC mainnet epoch 308 are over 16 trillion times harder to mine than those in epoch 0.
div#progress-wrapper.mb-huge
div.card.shadow-sm.mb-3
div.card-body
h4.h6 Loading data:
span(id="progress-text")
div.progress.mt-2(id="progress-bar", style="height: 7px;")
div.progress-bar(id="data-progress", role="progressbar", aria-valuenow="0", aria-valuemin="0" ,aria-valuemax="100")
div#main-content(style="display: none;")
div.row
div.col
div.card.shadow-sm.mb-3
div.card-body
h3.h6.mb-0 Difficulty History
hr
canvas(id="graph-diff-hist")
div.row
div.col
div.card.shadow-sm.mb-3
div.card-body
h3.h6.mb-0 Difficulty Change (clamped to ±100%)
hr
canvas(id="graph-diff-change")
block endOfBody
script(src="/js/chart.bundle.min.js", integrity="sha384-qgOtiGNaHh9fVWUnRjyHlV39rfbDcvPPkEzL1RHvsHKbuqUqM6uybNuVnghY2z4/")
script(src='/js/decimal.js')
script.
var blockCount = !{blockCount};
var heights = [];
var height = 0;
while (height <= blockCount) {
heights.push([height]);
height += !{coinConfig.difficultyAdjustmentBlockCount};
}
$(document).ready(function() {
loadData(heights, 1, heights.length);
});
function loadData(heightChunks, chunkSize, count) {
var chunkStrs = [];
for (var i = 0; i < heightChunks.length; i++) {
var heightChunk = heightChunks[i];
var chunkStr = "";
for (var j = 0; j < heightChunk.length; j++) {
if (j > 0) {
chunkStr += ",";
}
chunkStr += heightChunk[j];
}
chunkStrs.push(chunkStr);
}
//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);
$("#progress-text").text(`${Math.min(((chunkIndexDone + 1) * chunkSize), count).toLocaleString()} of ${count.toLocaleString()} (${wPercent})`);
};
var finishedCallback = function() {
var summary = summarizeData(results);
createGraph("graph-diff-hist", [summary.graphData], "Difficulty");
createGraph("graph-diff-change", [summary.changeGraphData], "Difficulty Change %");
//createGraph("graph-diff-hist-2", summary.epochChunks, "Difficulty 2");
$("#main-content").show();
$("#progress-wrapper").hide();
};
getData(results, chunkStrs, 0, statusCallback, finishedCallback);
}
function createGraph(graphId, datas, yLabelStr) {
var datasets = [];
for (var i = 0; i < datas.length; i++) {
datasets.push({
borderColor: '#007bff',
borderWidth: 2,
backgroundColor: 'rgba(0,0,0,0)',
data: datas[i],
pointRadius: 1
});
}
var ctx = document.getElementById(graphId).getContext('2d');
var graph = new Chart(ctx, {
type: 'line',
data: {
datasets: datasets
},
options: {
legend: { display: false },
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
scaleLabel: {
display: true,
labelString: 'Difficulty Epoch'
},
//ticks: {
// stepSize: 100,
//}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: yLabelStr
}
}]
}
}
});
}
function getData(results, chunks, chunkIndex, statusCallback, finishedCallback) {
if (chunkIndex > chunks.length - 1) {
finishedCallback();
return;
}
var url = `/api/block-headers-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);
getData(results, chunks, chunkIndex + 1, statusCallback, finishedCallback);
});
}
function summarizeData(raw) {
var summary = {};
summary.graphData = [];
summary.changeGraphData = [];
for (var i = 0; i < raw.length; i++) {
summary.graphData.push({x:i, y:raw[i].difficulty});
if (i == 0) {
summary.changeGraphData.push({x:i, y:raw[i].difficulty});
} else {
var d1 = raw[i].difficulty;
var d0 = raw[i - 1].difficulty
var deltaPercent = 100 * (d1 / d0 - 1);
/*if (d1 > d0) {
// increase
deltaPercent =
} else {
// decrease
deltaPercent = -100 * (1 - d1 / d0);
}*/
if (deltaPercent > 100) {
deltaPercent = 100;
}
if (deltaPercent < -100) {
deltaPercent = -100;
}
summary.changeGraphData.push({x:i, y:deltaPercent});
}
}
/*
var epochChunkCount = 3;
var epochChunkSize = Math.floor(summary.graphData.length / epochChunkCount);
summary.epochChunks = [];
for (var i = 0; i < epochChunkCount; i++) {
summary.epochChunks.push([]);
var scale = summary.graphData[i * epochChunkSize].y;
for (var j = 0; j < 100; j++) {
var data = summary.graphData[i * epochChunkSize + j];
summary.epochChunks[i].push({x:j, y:(data.y / scale)});
}
}*/
return summary;
}