commit
d3684a8f25
@ -0,0 +1,235 @@
|
||||
var drawChart
|
||||
(() => {
|
||||
const difficulty_window = 69;
|
||||
const target = 10;
|
||||
|
||||
// possible diff algos: LWMA, Cryptonote, MA, EMA
|
||||
const diffAlgo = "Cryptonote"
|
||||
|
||||
const CryptonoteCut = 0; // 12
|
||||
|
||||
|
||||
document.getElementById("title").innerText = `Diff algo: ${diffAlgo} - window: ${difficulty_window} ${(diffAlgo === "Cryptonote" ? "cut: "+CryptonoteCut : "")}`
|
||||
|
||||
let blocks = []
|
||||
let hashrates = []
|
||||
|
||||
let difficulty = 10;
|
||||
let time = 0;
|
||||
|
||||
|
||||
function mineBlock(hashrate) {
|
||||
time = 0;
|
||||
while (true) {
|
||||
time++;
|
||||
if (hashrate / difficulty > Math.random()) {
|
||||
blocks.push({
|
||||
t: time,
|
||||
d: difficulty,
|
||||
})
|
||||
hashrates.push(hashrate)
|
||||
calculateDifficulty()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let x = 0; x < 5; x++) {
|
||||
for (let i = 0; i < 350; i++) {
|
||||
mineBlock(10)
|
||||
}
|
||||
for (let i = 0; i < 350; i++) {
|
||||
mineBlock(6)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function calculateDifficulty() {
|
||||
if (blocks.length < 2) return;
|
||||
const bScan = Math.min(difficulty_window, blocks.length - 1)
|
||||
let blocksToScan = blocks.slice(blocks.length - bScan - 1, blocks.length - 1)
|
||||
//console.log(blocksToScan)
|
||||
|
||||
let avgTime = 0;
|
||||
let avgDiff = 0;
|
||||
|
||||
if (diffAlgo === "LWMA") {
|
||||
let totalWeights = 0;
|
||||
//console.clear()
|
||||
|
||||
for (i in blocksToScan) {
|
||||
let curW = bScan - (bScan - i) + 1 // i+1
|
||||
//console.log("curW", curW)
|
||||
|
||||
totalWeights += curW
|
||||
|
||||
avgTime += blocksToScan[i].t * curW
|
||||
avgDiff += blocksToScan[i].d * curW
|
||||
|
||||
//console.log("diff",blocksToScan[i].d)
|
||||
}
|
||||
avgTime /= totalWeights
|
||||
avgDiff /= totalWeights // bScan
|
||||
} else if (diffAlgo === "EMA") {
|
||||
let totalWeights = 0;
|
||||
//console.clear()
|
||||
|
||||
for (i in blocksToScan) {
|
||||
let curW = (bScan - (bScan - i) + 1) ** 2 // i+1
|
||||
//console.log("curW", curW)
|
||||
|
||||
totalWeights += curW
|
||||
|
||||
avgTime += blocksToScan[i].t * curW
|
||||
avgDiff += blocksToScan[i].d * curW
|
||||
|
||||
//console.log("diff",blocksToScan[i].d)
|
||||
}
|
||||
avgTime /= totalWeights
|
||||
avgDiff /= totalWeights // bScan
|
||||
} else if (diffAlgo === "MA") {
|
||||
for (i in blocksToScan) {
|
||||
|
||||
avgTime += blocksToScan[i].t
|
||||
avgDiff += blocksToScan[i].d
|
||||
}
|
||||
avgTime /= bScan
|
||||
avgDiff /= bScan // bScan
|
||||
} else if (diffAlgo === "Cryptonote") {
|
||||
let cut = Math.max(Math.min(CryptonoteCut, Math.floor(bScan / 2) - 2), 0)
|
||||
if (bScan < difficulty_window) {
|
||||
cut = 0;
|
||||
}
|
||||
if (cut >= bScan) {
|
||||
throw new Error("invalid cut " + CryptonoteCut + " with window of " + bScan)
|
||||
}
|
||||
|
||||
let blTimes = []
|
||||
for (i of blocksToScan) {
|
||||
blTimes.push(i.t)
|
||||
avgDiff += i.d
|
||||
|
||||
}
|
||||
blTimes = blTimes.slice(cut, blTimes.length - cut)
|
||||
|
||||
for (i of blTimes) {
|
||||
avgTime += i
|
||||
|
||||
|
||||
}
|
||||
avgTime /= (bScan - cut)
|
||||
avgDiff /= bScan // bScan
|
||||
}
|
||||
diffMultiplier = Math.min(Math.max(target / avgTime, 0.1), 10)
|
||||
//console.log("avgTime: " + avgTime + " avgDiff: " + avgDiff + " multiplier: " + diffMultiplier)
|
||||
difficulty = Math.ceil(avgDiff * diffMultiplier) // Math.round(avgDiff * diffMultiplier)
|
||||
//console.log(difficulty)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let blockDiffs = []
|
||||
let blockTimes = []
|
||||
let blockHeights = []
|
||||
lastBlockTime = target;
|
||||
|
||||
let deviation = 0;
|
||||
let diffDeviation = 0;
|
||||
|
||||
for (i in blocks) {
|
||||
blockDiffs.push(blocks[i].d)
|
||||
const blockTime = (blocks[i].t + lastBlockTime * 30) / 31
|
||||
|
||||
const perfectDiff = hashrates[i] * target
|
||||
console.log("perfectDiff:", perfectDiff)
|
||||
diffDeviation += Math.sqrt(Math.abs(perfectDiff - blocks[i].d))
|
||||
|
||||
deviation += Math.sqrt(Math.abs(blocks[i].t - blockTime))
|
||||
|
||||
blockTimes.push(blockTime)
|
||||
lastBlockTime = blockTime
|
||||
|
||||
|
||||
blockHeights.push(i)
|
||||
|
||||
}
|
||||
deviation /= blocks.length
|
||||
diffDeviation /= blocks.length
|
||||
|
||||
const ctx = document.getElementById("myChart");
|
||||
const stats = document.getElementById("stats");
|
||||
|
||||
stats.innerText = `block time st.devt: ${(deviation / target * 100).toFixed(2)}% - difficulty st.devt. from perfect value: ${diffDeviation.toFixed(2)}`
|
||||
|
||||
|
||||
drawChart = () => {
|
||||
new Chart(ctx, {
|
||||
type: "line",
|
||||
data: {
|
||||
labels: blockHeights,
|
||||
datasets: [{
|
||||
label: "Mean Block Time",
|
||||
data: blockTimes,
|
||||
borderWidth: 1,
|
||||
},
|
||||
{
|
||||
label: "Difficulty",
|
||||
data: blockDiffs,
|
||||
yAxisID: "y1",
|
||||
borderWidth: 1
|
||||
}, {
|
||||
label: "Hashrate",
|
||||
data: hashrates,
|
||||
yAxisID: "y2",
|
||||
borderWidth: 1
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
options: {
|
||||
// tension: 0.5,
|
||||
elements: {
|
||||
point: {
|
||||
radius: 0,
|
||||
hoverRadius: 3
|
||||
},
|
||||
line: {
|
||||
width: 1
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
type: "linear", // logarithmic
|
||||
display: true,
|
||||
position: "left",
|
||||
max: 20,
|
||||
min: 0
|
||||
},
|
||||
y1: {
|
||||
type: "linear",
|
||||
display: true,
|
||||
position: "right",
|
||||
min: 0,
|
||||
max: 200,
|
||||
|
||||
// grid line settings
|
||||
grid: {
|
||||
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
||||
},
|
||||
},
|
||||
y2: {
|
||||
type: "linear",
|
||||
display: false,
|
||||
min: 0
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
})()
|
||||
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<div id="title"></div>
|
||||
<div>
|
||||
<canvas id="myChart"></canvas>
|
||||
</div>
|
||||
<button onclick=drawChart()>Draw chart</button>
|
||||
<div id=stats></div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src=main.js></script>
|
||||
|
||||
</body>
|
Loading…
Reference in new issue