feat: progress bar and incremental PoW generation
This commit is contained in:
parent
ad4582cc16
commit
9dfb0713ad
8 changed files with 221 additions and 137 deletions
|
@ -37,8 +37,8 @@
|
|||
"webpack-dev-server": "^4.15.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mcaptcha/pow-wasm": "^0.1.0-rc1",
|
||||
"@mcaptcha/pow_sha256-polyfill": "^0.1.0-rc1",
|
||||
"@mcaptcha/vanilla-glue": "^0.1.0-rc1"
|
||||
"@mcaptcha/pow_sha256-polyfill": "^0.1.0-rc2",
|
||||
"@mcaptcha/vanilla-glue": "^0.1.0-rc1",
|
||||
"@mcaptcha/pow-wasm": "^0.1.0-rc2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ SPDX-License-Identifier: MIT OR Apache-2.0
|
|||
|
||||
<. include!("../components/headers/widget-headers.html"); .>
|
||||
<body>
|
||||
<form class="widget__contaienr">
|
||||
<main class="widget__container">
|
||||
<form class="widget__inner-container">
|
||||
<noscript>
|
||||
<div class="widget__noscript-container">
|
||||
<span class="widget__noscript-warning">
|
||||
|
@ -53,4 +54,6 @@ SPDX-License-Identifier: MIT OR Apache-2.0
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="progress__bar"><div class="progress__fill"></div></div>
|
||||
</main>
|
||||
<.include!("./footer.html"); .>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
import { Work, ServiceWorkerWork } from "./types";
|
||||
import { Work, ServiceWorkerMessage } from "./types";
|
||||
import fetchPoWConfig from "./fetchPoWConfig";
|
||||
import sendWork from "./sendWork";
|
||||
import sendToParent from "./sendToParent";
|
||||
|
@ -24,6 +24,9 @@ export const registerVerificationEventHandler = (): void => {
|
|||
};
|
||||
|
||||
export const solveCaptchaRunner = async (e: Event): Promise<void> => {
|
||||
const PROGRESS_FILL = <HTMLElement>document.querySelector(".progress__fill");
|
||||
let width = 0;
|
||||
|
||||
if (LOCK) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
|
@ -32,6 +35,8 @@ export const solveCaptchaRunner = async (e: Event): Promise<void> => {
|
|||
try {
|
||||
LOCK = true;
|
||||
if (CONST.btn().checked == false) {
|
||||
width = 0;
|
||||
PROGRESS_FILL.style.width = `${width}%`;
|
||||
CONST.messageText().before();
|
||||
LOCK = false;
|
||||
return;
|
||||
|
@ -43,32 +48,49 @@ export const solveCaptchaRunner = async (e: Event): Promise<void> => {
|
|||
CONST.messageText().during();
|
||||
// 1. get config
|
||||
const config = await fetchPoWConfig();
|
||||
const max_recorded_nonce = config.max_recorded_nonce;
|
||||
// 2. prove work
|
||||
worker.postMessage(config);
|
||||
|
||||
worker.onmessage = async (event: MessageEvent) => {
|
||||
const resp: ServiceWorkerWork = event.data;
|
||||
const resp: ServiceWorkerMessage = event.data;
|
||||
|
||||
if (resp.type === "work") {
|
||||
width = 80;
|
||||
PROGRESS_FILL.style.width = `${width}%`;
|
||||
console.log(
|
||||
`Proof generated. Difficuly: ${config.difficulty_factor} Duration: ${resp.work.time}`
|
||||
`Proof generated. Difficuly: ${config.difficulty_factor} Duration: ${resp.value.work.time}`
|
||||
);
|
||||
|
||||
const proof: Work = {
|
||||
key: CONST.sitekey(),
|
||||
string: config.string,
|
||||
nonce: resp.work.nonce,
|
||||
result: resp.work.result,
|
||||
time: Math.trunc(resp.work.time),
|
||||
worker_type: resp.work.worker_type,
|
||||
nonce: resp.value.work.nonce,
|
||||
result: resp.value.work.result,
|
||||
time: Math.trunc(resp.value.work.time),
|
||||
worker_type: resp.value.work.worker_type,
|
||||
};
|
||||
|
||||
width = 90;
|
||||
PROGRESS_FILL.style.width = `${width}%`;
|
||||
// 3. submit work
|
||||
const token = await sendWork(proof);
|
||||
// 4. send token
|
||||
sendToParent(token);
|
||||
// 5. mark checkbox checked
|
||||
CONST.btn().checked = true;
|
||||
width = 100;
|
||||
PROGRESS_FILL.style.width = `${width}%`;
|
||||
CONST.messageText().after();
|
||||
LOCK = false;
|
||||
}
|
||||
if (resp.type === "progress") {
|
||||
if (width < 80) {
|
||||
width = (resp.nonce / max_recorded_nonce) * 100;
|
||||
PROGRESS_FILL.style.width = `${width}%`;
|
||||
}
|
||||
console.log(`received nonce ${resp.nonce}`);
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
CONST.messageText().error();
|
||||
|
|
|
@ -7,11 +7,27 @@
|
|||
|
||||
@import "../reset";
|
||||
|
||||
.widget__contaienr {
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.widget__container {
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
.widget__inner-container {
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.widget__noscript-container {
|
||||
|
@ -110,3 +126,19 @@
|
|||
font-size: 0.5rem;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
/* progress bar courtesy of https://codepen.io/Bizzy-Coding/pen/poOymVJ?editors=1111 */
|
||||
.progress__bar {
|
||||
position: relative;
|
||||
height: 5px;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.progress__fill {
|
||||
background: #65a2e0;
|
||||
border-radius: 15px;
|
||||
height: 100%;
|
||||
width: 0%;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
import { gen_pow } from "@mcaptcha/pow-wasm";
|
||||
import { stepped_gen_pow } from "@mcaptcha/pow-wasm";
|
||||
import * as p from "@mcaptcha/pow_sha256-polyfill";
|
||||
import { WasmWork, PoWConfig, SubmitWork } from "./types";
|
||||
|
||||
|
@ -12,19 +12,25 @@ import { WasmWork, PoWConfig, SubmitWork } from "./types";
|
|||
* @param {PoWConfig} config - the proof-of-work configuration using which
|
||||
* work needs to be computed
|
||||
* */
|
||||
const prove = async (config: PoWConfig): Promise<SubmitWork> => {
|
||||
const prove = async (
|
||||
config: PoWConfig,
|
||||
progress: (nonce: number) => void
|
||||
): Promise<SubmitWork> => {
|
||||
const WASM = "wasm";
|
||||
const JS = "js";
|
||||
const STEPS = 5000;
|
||||
if (WasmSupported) {
|
||||
let proof: WasmWork = null;
|
||||
let res: SubmitWork = null;
|
||||
let time: number = null;
|
||||
|
||||
const t0 = performance.now();
|
||||
const proofString = gen_pow(
|
||||
const proofString = stepped_gen_pow(
|
||||
config.salt,
|
||||
config.string,
|
||||
config.difficulty_factor
|
||||
config.difficulty_factor,
|
||||
STEPS,
|
||||
progress
|
||||
);
|
||||
const t1 = performance.now();
|
||||
time = t1 - t0;
|
||||
|
@ -47,10 +53,12 @@ const prove = async (config: PoWConfig): Promise<SubmitWork> => {
|
|||
|
||||
const t0 = performance.now();
|
||||
|
||||
proof = await p.generate_work(
|
||||
proof = await p.stepped_generate_work(
|
||||
config.salt,
|
||||
config.string,
|
||||
config.difficulty_factor
|
||||
config.difficulty_factor,
|
||||
STEPS,
|
||||
progress
|
||||
);
|
||||
const t1 = performance.now();
|
||||
time = t1 - t0;
|
||||
|
|
|
@ -6,16 +6,30 @@
|
|||
import log from "../logger";
|
||||
|
||||
import prove from "./prove";
|
||||
import { PoWConfig, ServiceWorkerWork } from "./types";
|
||||
import { PoWConfig, ServiceWorkerMessage, ServiceWorkerWork } from "./types";
|
||||
|
||||
log.log("worker registered");
|
||||
onmessage = async (e) => {
|
||||
console.debug("message received at worker");
|
||||
const config: PoWConfig = e.data;
|
||||
|
||||
const work = await prove(config);
|
||||
const res: ServiceWorkerWork = {
|
||||
work,
|
||||
const progressCallback = (nonce: number) => {
|
||||
const res: ServiceWorkerMessage = {
|
||||
type: "progress",
|
||||
nonce: nonce,
|
||||
};
|
||||
|
||||
postMessage(res);
|
||||
};
|
||||
|
||||
const work = await prove(config, progressCallback);
|
||||
const w: ServiceWorkerWork = {
|
||||
work,
|
||||
};
|
||||
|
||||
const res: ServiceWorkerMessage = {
|
||||
type: "work",
|
||||
value: w,
|
||||
};
|
||||
|
||||
postMessage(res);
|
||||
|
|
|
@ -32,8 +32,13 @@ export type PoWConfig = {
|
|||
string: string;
|
||||
difficulty_factor: number;
|
||||
salt: string;
|
||||
max_recorded_nonce: number;
|
||||
};
|
||||
|
||||
export type Token = {
|
||||
token: string;
|
||||
};
|
||||
|
||||
export type ServiceWorkerMessage =
|
||||
| { type: "work"; value: ServiceWorkerWork }
|
||||
| { type: "progress"; nonce: number };
|
||||
|
|
16
yarn.lock
16
yarn.lock
|
@ -631,15 +631,15 @@
|
|||
resolved "https://registry.yarnpkg.com/@mcaptcha/core-glue/-/core-glue-0.1.0-rc1.tgz#76d665a3fc537062061e12e274f969ac3e053685"
|
||||
integrity sha512-P4SgUioJDR38QpnP9sPY72NyaYex8MXD6RbzrfKra+ngamT26XjqVZEHBiZU2RT7u0SsWhuko4N1ntNOghsgpg==
|
||||
|
||||
"@mcaptcha/pow-wasm@^0.1.0-rc1":
|
||||
version "0.1.0-rc1"
|
||||
resolved "https://registry.yarnpkg.com/@mcaptcha/pow-wasm/-/pow-wasm-0.1.0-rc1.tgz#eef8409e0c74e9c7261587bdebd80a8c4af92f9e"
|
||||
integrity sha512-7+PGKoe1StFRsa9TEqztzK4/obbdY4OfavFX+geTk8b3K26D+eHPyimJ9BPlpI1VZl8ujR3CnbfbnQSRaqS7ZQ==
|
||||
"@mcaptcha/pow-wasm@^0.1.0-rc2":
|
||||
version "0.1.0-rc2"
|
||||
resolved "https://registry.yarnpkg.com/@mcaptcha/pow-wasm/-/pow-wasm-0.1.0-rc2.tgz#c7aaa678325600a178b11a702e2aeb9f8143e605"
|
||||
integrity sha512-2G0nQ2GQWECRcE5kzfULDsQ032s6/PDzE1rncMdQAR1Mu2YQfFZHgnX4zLJmQnjKIhy9meIjXvatVSyIllrbtg==
|
||||
|
||||
"@mcaptcha/pow_sha256-polyfill@^0.1.0-rc1":
|
||||
version "0.1.0-rc1"
|
||||
resolved "https://registry.yarnpkg.com/@mcaptcha/pow_sha256-polyfill/-/pow_sha256-polyfill-0.1.0-rc1.tgz#dfeee88f5f6fd99aeae65dbcff6fbb09fe8a1696"
|
||||
integrity sha512-OFA4W3/vh8ORUnifbm8c/8eP22CbiXr4Un6/l4fMyqLj1aoQLMGAiuqab0trGqBnY0DU2bwTMyxflx26/cWgIw==
|
||||
"@mcaptcha/pow_sha256-polyfill@^0.1.0-rc2":
|
||||
version "0.1.0-rc2"
|
||||
resolved "https://registry.yarnpkg.com/@mcaptcha/pow_sha256-polyfill/-/pow_sha256-polyfill-0.1.0-rc2.tgz#253320e7a6666e395ef9dfb123d1102066d72b87"
|
||||
integrity sha512-ERIbxIo+ZnQKtti/T4FLmcY0neuc5R05L97qYc62Hm++i+3dx/W6A8oC4V9U0XKCPYnHZFoZozAZlbsGXjrsVQ==
|
||||
|
||||
"@mcaptcha/vanilla-glue@^0.1.0-rc1":
|
||||
version "0.1.0-rc1"
|
||||
|
|
Loading…
Reference in a new issue