]> zoso.dev Git - nano-pow.git/commitdiff
Create initial validate function for GL. Refactor classes export to create a better...
authorChris Duncan <chris@zoso.dev>
Sun, 12 Jan 2025 20:00:21 +0000 (12:00 -0800)
committerChris Duncan <chris@zoso.dev>
Sun, 12 Jan 2025 20:00:21 +0000 (12:00 -0800)
src/classes/gl.ts
src/classes/index.ts

index d7423d20005313f06b761944b3a72f33b7b91a09..253c4a0727ecacd93d63677b1f6f9a8c0954330a 100644 (file)
@@ -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<boolean> {
+               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
+       }
 }
index b5330eee5c0857728566f2598049cf6241c26dac..c3e2a3c42bc8182341e8a57e6cca66a63a2bb277 100644 (file)
@@ -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