From: Chris Duncan Date: Sun, 12 Jan 2025 20:00:21 +0000 (-0800) Subject: Create initial validate function for GL. Refactor classes export to create a better... X-Git-Tag: v1.2.0~11 X-Git-Url: https://zoso.dev/?a=commitdiff_plain;h=a658aacb4d8700db3451462ae126655dbc11bfc8;p=nano-pow.git Create initial validate function for GL. Refactor classes export to create a better fallback mechanism. --- diff --git a/src/classes/gl.ts b/src/classes/gl.ts index d7423d2..253c4a0 100644 --- a/src/classes/gl.ts +++ b/src/classes/gl.ts @@ -106,7 +106,6 @@ export class NanoPowGl { this.#gl.clear(this.#gl.COLOR_BUFFER_BIT) /** Upload work buffer */ - crypto.getRandomValues(work) this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, this.#workBuffer) this.#gl.bufferSubData(this.#gl.UNIFORM_BUFFER, 0, Uint32Array.from(work)) this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null) @@ -186,14 +185,55 @@ export class NanoPowGl { /** Start drawing to calculate one nonce per pixel */ let nonce = null - const work = new Uint8Array(8) + const seed = new Uint8Array(8) while (nonce == null) { - this.#draw(work) + crypto.getRandomValues(seed) + this.#draw(seed) const found = await this.#checkQueryResult() if (found) { - nonce = this.#readResult(work) + nonce = this.#readResult(seed) } } return nonce } + + /** + * Validates that a nonce satisfies Nano proof-of-work requirements. + * + * @param {string} work - Hexadecimal proof-of-work value to validate + * @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts + * @param {number} [threshold=0xfffffff8] - Difficulty of proof-of-work calculation + */ + static async validate (work: string, hash: string, threshold: number = 0xfffffff8): Promise { + if (NanoPowGl.#gl == null) throw new Error('WebGL 2 is required') + if (!/^[A-F-a-f0-9]{16}$/.test(hash)) throw new Error(`invalid_hash ${work}`) + if (!/^[A-F-a-f0-9]{64}$/.test(hash)) throw new Error(`invalid_hash ${hash}`) + if (typeof threshold !== 'number') throw new TypeError(`Invalid threshold ${threshold}`) + if (this.#gl == null) throw new Error('WebGL 2 is required') + + /** Set up uniform buffer object */ + const uboView = new DataView(new ArrayBuffer(144)) + for (let i = 0; i < 64; i += 8) { + const uint32 = hash.slice(i, i + 8) + uboView.setUint32(i * 2, parseInt(uint32, 16)) + } + uboView.setUint32(128, threshold, true) + uboView.setFloat32(132, NanoPowGl.#WORKLOAD - 1, true) + NanoPowGl.#gl.bindBuffer(NanoPowGl.#gl.UNIFORM_BUFFER, NanoPowGl.#uboBuffer) + NanoPowGl.#gl.bufferSubData(NanoPowGl.#gl.UNIFORM_BUFFER, 0, uboView) + NanoPowGl.#gl.bindBuffer(NanoPowGl.#gl.UNIFORM_BUFFER, null) + + /** Start drawing to calculate one nonce per pixel */ + let nonce = null + const data = new DataView(new ArrayBuffer(8)) + data.setBigUint64(0, BigInt(`0x${work}`), true) + const seed = new Uint8Array(data.buffer) + this.#draw(seed) + const found = await this.#checkQueryResult() + if (found) { + nonce = this.#readResult(seed) + } + if (found && nonce !== work) throw new Error(`Nonce found but does not match work`) + return found + } } diff --git a/src/classes/index.ts b/src/classes/index.ts index b5330ee..c3e2a3c 100644 --- a/src/classes/index.ts +++ b/src/classes/index.ts @@ -2,13 +2,27 @@ // SPDX-License-Identifier: GPL-3.0-or-later import { NanoPowGl } from "./gl.js" -import { NanoPowGpu as gpu } from "./gpu.js" -console.log(`export barrel`) -let NanoPowGpu = null +import { NanoPowGpu } from "./gpu.js" + +let isGlSupported, isGpuSupported = false +try { + await NanoPowGl.init() + isGlSupported = true +} catch (err) { + console.warn(`WebGL is not supported in this environment.`) + isGlSupported = false +} try { - NanoPowGpu = await gpu.init() + await NanoPowGpu.init() + isGpuSupported = true } catch (err) { console.warn(`WebGPU is not supported in this environment.`) + isGpuSupported = false +} + +const NanoPow = { + search: isGpuSupported ? NanoPowGpu.search : isGlSupported ? NanoPowGl.search : null, + validate: isGpuSupported ? NanoPowGpu.validate : isGlSupported ? NanoPowGl.validate : null, } -console.log(`barrel`) -export { NanoPowGl, NanoPowGpu } +export { NanoPowGl, NanoPowGpu, NanoPow } +export default NanoPow