mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-08 09:38:45 +00:00
* chore: add prettier configuration Signed-off-by: Xe Iaso <me@xeiaso.net> * format: run prettier tree-wide Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(prettier): ignore intentionally ungrammatical files Signed-off-by: Xe Iaso <me@xeiaso.net> * ci: add PR title lint rule Signed-off-by: Xe Iaso <me@xeiaso.net> * ci: add DCO check Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: add commitlint and husky Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: add CONTRIBUTING guidelines Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: set SKIP_INTEGRATION in precommit tests Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: update spelling Signed-off-by: Xe Iaso <me@xeiaso.net> * ci(dco): remove reopened trigger Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: remove dead file Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(prettier): don't format nginx includes Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net>
171 lines
4.7 KiB
TypeScript
171 lines
4.7 KiB
TypeScript
import algorithms from "./algorithms";
|
|
|
|
const defaultDifficulty = 4;
|
|
|
|
const status: HTMLParagraphElement = document.getElementById(
|
|
"status",
|
|
) as HTMLParagraphElement;
|
|
const difficultyInput: HTMLInputElement = document.getElementById(
|
|
"difficulty-input",
|
|
) as HTMLInputElement;
|
|
const algorithmSelect: HTMLSelectElement = document.getElementById(
|
|
"algorithm-select",
|
|
) as HTMLSelectElement;
|
|
const compareSelect: HTMLSelectElement = document.getElementById(
|
|
"compare-select",
|
|
) as HTMLSelectElement;
|
|
const header: HTMLTableRowElement = document.getElementById(
|
|
"table-header",
|
|
) as HTMLTableRowElement;
|
|
const headerCompare: HTMLTableSectionElement = document.getElementById(
|
|
"table-header-compare",
|
|
) as HTMLTableSectionElement;
|
|
const results: HTMLTableRowElement = document.getElementById(
|
|
"results",
|
|
) as HTMLTableRowElement;
|
|
|
|
const setupControls = () => {
|
|
if (defaultDifficulty == null) {
|
|
return;
|
|
}
|
|
|
|
difficultyInput.value = defaultDifficulty.toString();
|
|
for (const alg of Object.keys(algorithms)) {
|
|
const option1 = document.createElement("option");
|
|
algorithmSelect?.append(option1);
|
|
const option2 = document.createElement("option");
|
|
compareSelect.append(option2);
|
|
option1.value = option1.innerText = option2.value = option2.innerText = alg;
|
|
}
|
|
};
|
|
|
|
const benchmarkTrial = async (stats, difficulty, algorithm, signal) => {
|
|
if (!(difficulty >= 1)) {
|
|
throw new Error(`Invalid difficulty: ${difficulty}`);
|
|
}
|
|
const process = algorithms[algorithm];
|
|
if (process == null) {
|
|
throw new Error(`Unknown algorithm: ${algorithm}`);
|
|
}
|
|
|
|
const rawChallenge = new Uint8Array(32);
|
|
crypto.getRandomValues(rawChallenge);
|
|
const challenge = Array.from(rawChallenge)
|
|
.map((c) => c.toString(16).padStart(2, "0"))
|
|
.join("");
|
|
|
|
const t0 = performance.now();
|
|
const { hash, nonce } = await process(
|
|
{ basePrefix: "/", version: "devel" },
|
|
challenge,
|
|
Number(difficulty),
|
|
signal,
|
|
);
|
|
const t1 = performance.now();
|
|
console.log({ hash, nonce });
|
|
|
|
stats.time += t1 - t0;
|
|
stats.iters += nonce;
|
|
|
|
return { time: t1 - t0, nonce };
|
|
};
|
|
|
|
const stats = { time: 0, iters: 0 };
|
|
const comparison = { time: 0, iters: 0 };
|
|
const updateStatus = () => {
|
|
const mainRate = stats.iters / stats.time;
|
|
const compareRate = comparison.iters / comparison.time;
|
|
if (Number.isFinite(mainRate)) {
|
|
status.innerText = `Average hashrate: ${mainRate.toFixed(3)}kH/s`;
|
|
if (Number.isFinite(compareRate)) {
|
|
const change = ((mainRate - compareRate) / mainRate) * 100;
|
|
status.innerText += ` vs ${compareRate.toFixed(3)}kH/s (${change.toFixed(2)}% change)`;
|
|
}
|
|
} else {
|
|
status.innerText = "Benchmarking...";
|
|
}
|
|
};
|
|
|
|
const tableCell = (text) => {
|
|
const td = document.createElement("td");
|
|
td.innerText = text;
|
|
td.style.padding = "0 0.25rem";
|
|
return td;
|
|
};
|
|
|
|
const benchmarkLoop = async (controller) => {
|
|
const difficulty = difficultyInput.value;
|
|
const algorithm = algorithmSelect.value;
|
|
const compareAlgorithm = compareSelect.value;
|
|
updateStatus();
|
|
|
|
try {
|
|
const { time, nonce } = await benchmarkTrial(
|
|
stats,
|
|
difficulty,
|
|
algorithm,
|
|
controller.signal,
|
|
);
|
|
|
|
const tr = document.createElement("tr");
|
|
tr.style.display = "contents";
|
|
tr.append(tableCell(`${time}ms`), tableCell(nonce));
|
|
|
|
// auto-scroll to new rows
|
|
const atBottom =
|
|
results.scrollHeight - results.clientHeight <= results.scrollTop;
|
|
results.append(tr);
|
|
if (atBottom) {
|
|
results.scrollTop = results.scrollHeight - results.clientHeight;
|
|
}
|
|
updateStatus();
|
|
|
|
if (compareAlgorithm !== "NONE") {
|
|
const { time, nonce } = await benchmarkTrial(
|
|
comparison,
|
|
difficulty,
|
|
compareAlgorithm,
|
|
controller.signal,
|
|
);
|
|
tr.append(tableCell(`${time}ms`), tableCell(nonce));
|
|
}
|
|
} catch (e) {
|
|
if (e !== false) {
|
|
status.innerText = e;
|
|
}
|
|
return;
|
|
}
|
|
|
|
await benchmarkLoop(controller);
|
|
};
|
|
|
|
let controller: AbortController | null = null;
|
|
const reset = () => {
|
|
stats.time = stats.iters = 0;
|
|
comparison.time = comparison.iters = 0;
|
|
results.innerHTML = status.innerText = "";
|
|
|
|
const table = results.parentElement as HTMLElement;
|
|
if (compareSelect.value !== "NONE") {
|
|
table.style.gridTemplateColumns = "repeat(4,auto)";
|
|
header.style.display = "none";
|
|
headerCompare.style.display = "contents";
|
|
} else {
|
|
table.style.gridTemplateColumns = "repeat(2,auto)";
|
|
header.style.display = "contents";
|
|
headerCompare.style.display = "none";
|
|
}
|
|
|
|
if (controller != null) {
|
|
controller.abort();
|
|
}
|
|
controller = new AbortController();
|
|
void benchmarkLoop(controller);
|
|
};
|
|
|
|
setupControls();
|
|
difficultyInput.addEventListener("change", reset);
|
|
algorithmSelect.addEventListener("change", reset);
|
|
compareSelect.addEventListener("change", reset);
|
|
reset();
|