]> zoso.dev Git - libnemo.git/commitdiff
Fix promise thenable handling in pow.
authorChris Duncan <chris@zoso.dev>
Tue, 3 Dec 2024 05:18:03 +0000 (21:18 -0800)
committerChris Duncan <chris@zoso.dev>
Tue, 3 Dec 2024 05:18:03 +0000 (21:18 -0800)
src/lib/pow.ts

index 01f3c8a5962ed8bab775b71735fe42ff6d13dff9..28f7eb39a5d6573e109727c264bd17367cb2c872 100644 (file)
@@ -18,44 +18,44 @@ import { Blake2b } from './blake2b.js'
 
 (function () {
 
-       function array_hex (arr, index, length) {
-               let out = ''
-               for (let i = length - 1; i > -1; i--) {
-                       out += (arr[i] > 15 ? '' : '0') + arr[i].toString(16)
-               }
-               return out
-       }
+  function array_hex (arr, index, length) {
+    let out = ''
+    for (let i = length - 1; i > -1; i--) {
+      out += (arr[i] > 15 ? '' : '0') + arr[i].toString(16)
+    }
+    return out
+  }
 
-       function hex_reverse (hex) {
-               let out = ''
-               for (let i = hex.length; i > 0; i -= 2) {
-                       out += hex.slice(i - 2, i)
-               }
-               return out
-       }
+  function hex_reverse (hex) {
+    let out = ''
+    for (let i = hex.length; i > 0; i -= 2) {
+      out += hex.slice(i - 2, i)
+    }
+    return out
+  }
 
-       function calculate (hashHex, callback, progressCallback, threshold = '0xFFFFFFF8') {
-               if (typeof threshold === 'number') threshold = '0x' + threshold.toString(16)
+  function calculate (hashHex, callback, progressCallback, threshold = '0xFFFFFFF8') {
+    if (typeof threshold === 'number') threshold = '0x' + threshold.toString(16)
 
-               const canvas = document.createElement('canvas')
+    const canvas = document.createElement('canvas')
 
-               canvas.width = window.NanoWebglPow.width
-               canvas.height = window.NanoWebglPow.height
+    canvas.width = window.NanoWebglPow.width
+    canvas.height = window.NanoWebglPow.height
 
-               const gl = canvas.getContext('webgl2')
+    const gl = canvas.getContext('webgl2')
 
-               if (!gl)
-                       throw new Error('webgl2_required')
+    if (!gl)
+      throw new Error('webgl2_required')
 
-               if (!/^[A-F-a-f0-9]{64}$/.test(hashHex))
-                       throw new Error('invalid_hash')
+    if (!/^[A-F-a-f0-9]{64}$/.test(hashHex))
+      throw new Error('invalid_hash')
 
-               gl.clearColor(0, 0, 0, 1)
+    gl.clearColor(0, 0, 0, 1)
 
-               const reverseHex = hex_reverse(hashHex)
+    const reverseHex = hex_reverse(hashHex)
 
-               // Vertext Shader
-               const vsSource = `#version 300 es
+    // Vertext Shader
+    const vsSource = `#version 300 es
     precision highp float;
     layout (location=0) in vec4 position;
     layout (location=1) in vec2 uv;
@@ -67,8 +67,8 @@ import { Blake2b } from './blake2b.js'
       gl_Position = position;
     }`
 
-               // Fragment shader
-               const fsSource = `#version 300 es
+    // Fragment shader
+    const fsSource = `#version 300 es
     precision highp float;
     precision highp int;
 
@@ -230,164 +230,166 @@ import { Blake2b } from './blake2b.js'
       }
     }`
 
-               const vertexShader = gl.createShader(gl.VERTEX_SHADER)
-               gl.shaderSource(vertexShader, vsSource)
-               gl.compileShader(vertexShader)
-
-               if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS))
-                       throw gl.getShaderInfoLog(vertexShader)
-
-               const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
-               gl.shaderSource(fragmentShader, fsSource)
-               gl.compileShader(fragmentShader)
-
-               if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS))
-                       throw gl.getShaderInfoLog(fragmentShader)
-
-               const program = gl.createProgram()
-               gl.attachShader(program, vertexShader)
-               gl.attachShader(program, fragmentShader)
-               gl.linkProgram(program)
-
-               if (!gl.getProgramParameter(program, gl.LINK_STATUS))
-                       throw gl.getProgramInfoLog(program)
-
-               gl.useProgram(program)
-
-               // Construct simple 2D geometry
-               const triangleArray = gl.createVertexArray()
-               gl.bindVertexArray(triangleArray)
-
-               // Vertex Positions, 2 triangles
-               const positions = new Float32Array([
-                       -1, -1, 0, -1, 1, 0, 1, 1, 0,
-                       1, -1, 0, 1, 1, 0, -1, -1, 0
-               ])
-               const positionBuffer = gl.createBuffer()
-               gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
-               gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW)
-               gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0)
-               gl.enableVertexAttribArray(0)
-
-               // Texture Positions
-               const uvPosArray = new Float32Array([
-                       1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1
-               ])
-               const uvBuffer = gl.createBuffer()
-               gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer)
-               gl.bufferData(gl.ARRAY_BUFFER, uvPosArray, gl.STATIC_DRAW)
-               gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0)
-               gl.enableVertexAttribArray(1)
-
-               const work0Location = gl.getUniformLocation(program, 'u_work0')
-               const work1Location = gl.getUniformLocation(program, 'u_work1')
-
-               // Draw output until success or progressCallback says to stop
-               const work0 = new Uint8Array(4)
-               const work1 = new Uint8Array(4)
-               let n = 0
-
-               function draw () {
-                       n++
-                       window.crypto.getRandomValues(work0)
-                       window.crypto.getRandomValues(work1)
-
-                       gl.uniform4uiv(work0Location, Array.from(work0))
-                       gl.uniform4uiv(work1Location, Array.from(work1))
-
-                       // Check with progressCallback every 100 frames
-                       if (n % 100 === 0 && typeof progressCallback === 'function' && progressCallback(n))
-                               return
-
-                       gl.clear(gl.COLOR_BUFFER_BIT)
-                       gl.drawArrays(gl.TRIANGLES, 0, 6)
-                       const pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4)
-                       gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
-
-                       // Check the pixels for any success
-                       for (let i = 0; i < pixels.length; i += 4) {
-                               if (pixels[i] !== 0) {
-                                       // Return the work value with the custom bits
-                                       typeof callback === 'function' &&
-                                               callback(
-                                                       array_hex(work1, 0, 4) +
-                                                       array_hex([
-                                                               pixels[i + 2],
-                                                               pixels[i + 3],
-                                                               work0[2] ^ (pixels[i] - 1),
-                                                               work0[3] ^ (pixels[i + 1] - 1)
-                                                       ], 0, 4), n)
-                                       return
-                               }
-                       }
-                       // Nothing found yet, try again
-                       window.requestAnimationFrame(draw)
-               }
-
-               // Begin generation
-               window.requestAnimationFrame(draw)
-       }
-
-       window.NanoWebglPow = calculate
-       // Both width and height must be multiple of 256, (one byte)
-       // but do not need to be the same,
-       // matching GPU capabilities is the aim
-       window.NanoWebglPow.width = 256 * 2
-       window.NanoWebglPow.height = 256 * 2
+    const vertexShader = gl.createShader(gl.VERTEX_SHADER)
+    gl.shaderSource(vertexShader, vsSource)
+    gl.compileShader(vertexShader)
+
+    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS))
+      throw gl.getShaderInfoLog(vertexShader)
+
+    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
+    gl.shaderSource(fragmentShader, fsSource)
+    gl.compileShader(fragmentShader)
+
+    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS))
+      throw gl.getShaderInfoLog(fragmentShader)
+
+    const program = gl.createProgram()
+    gl.attachShader(program, vertexShader)
+    gl.attachShader(program, fragmentShader)
+    gl.linkProgram(program)
+
+    if (!gl.getProgramParameter(program, gl.LINK_STATUS))
+      throw gl.getProgramInfoLog(program)
+
+    gl.useProgram(program)
+
+    // Construct simple 2D geometry
+    const triangleArray = gl.createVertexArray()
+    gl.bindVertexArray(triangleArray)
+
+    // Vertex Positions, 2 triangles
+    const positions = new Float32Array([
+      -1, -1, 0, -1, 1, 0, 1, 1, 0,
+      1, -1, 0, 1, 1, 0, -1, -1, 0
+    ])
+    const positionBuffer = gl.createBuffer()
+    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
+    gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW)
+    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0)
+    gl.enableVertexAttribArray(0)
+
+    // Texture Positions
+    const uvPosArray = new Float32Array([
+      1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1
+    ])
+    const uvBuffer = gl.createBuffer()
+    gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer)
+    gl.bufferData(gl.ARRAY_BUFFER, uvPosArray, gl.STATIC_DRAW)
+    gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0)
+    gl.enableVertexAttribArray(1)
+
+    const work0Location = gl.getUniformLocation(program, 'u_work0')
+    const work1Location = gl.getUniformLocation(program, 'u_work1')
+
+    // Draw output until success or progressCallback says to stop
+    const work0 = new Uint8Array(4)
+    const work1 = new Uint8Array(4)
+    let n = 0
+
+    function draw () {
+      n++
+      window.crypto.getRandomValues(work0)
+      window.crypto.getRandomValues(work1)
+
+      gl.uniform4uiv(work0Location, Array.from(work0))
+      gl.uniform4uiv(work1Location, Array.from(work1))
+
+      // Check with progressCallback every 100 frames
+      if (n % 100 === 0 && typeof progressCallback === 'function' && progressCallback(n))
+        return
+
+      gl.clear(gl.COLOR_BUFFER_BIT)
+      gl.drawArrays(gl.TRIANGLES, 0, 6)
+      const pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4)
+      gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
+
+      // Check the pixels for any success
+      for (let i = 0; i < pixels.length; i += 4) {
+        if (pixels[i] !== 0) {
+          // Return the work value with the custom bits
+          typeof callback === 'function' &&
+            callback(
+              array_hex(work1, 0, 4) +
+              array_hex([
+                pixels[i + 2],
+                pixels[i + 3],
+                work0[2] ^ (pixels[i] - 1),
+                work0[3] ^ (pixels[i + 1] - 1)
+              ], 0, 4), n)
+          return
+        }
+      }
+      // Nothing found yet, try again
+      window.requestAnimationFrame(draw)
+    }
+
+    // Begin generation
+    window.requestAnimationFrame(draw)
+  }
+
+  window.NanoWebglPow = calculate
+  // Both width and height must be multiple of 256, (one byte)
+  // but do not need to be the same,
+  // matching GPU capabilities is the aim
+  window.NanoWebglPow.width = 256 * 2
+  window.NanoWebglPow.height = 256 * 2
 
 })()
 
 
 const p = () => {
-       const NONCE_BYTES = 8
-       const RECEIVE_THRESHOLD = 'fffffe0000000000'
-       const SEND_THRESHOLD = 'fffffff800000000'
-
-       /**
-       * Listens for messages from a calling function.
-       */
-       addEventListener('message', (message) => {
-               const data = JSON.parse(new TextDecoder().decode(message.data ?? message))
-               if (data === 'stop') close()
-               for (const d of data) {
-                       d.nonce = find(d.hash, d.threshold)
-                       console.log('pow found')
-               }
-               const buf = new TextEncoder().encode(JSON.stringify(data)).buffer
-               //@ts-expect-error
-               postMessage(buf, [buf])
-       })
-
-       async function find (hash: string, threshold: string = SEND_THRESHOLD) {
-               return new Promise((resolve, reject) => {
-                       window.NanoWebglPow(hash, resolve, console.log)
-
-               })
-               // let result = null
-               // let count = 0
-               // do {
-               //   count++
-               //   const nonce: Uint8Array = new Uint8Array(NONCE_BYTES)
-               //   crypto.getRandomValues(nonce)
-               //   const test: string = new Blake2b(NONCE_BYTES)
-               //     .update(nonce)
-               //     .update(parseHex(hash))
-               //     .digest('hex') as string
-               //   if (count % 1000 === 0) console.log(`${count} hashes...`)
-               //   if (BigInt(`0x${test}`) >= BigInt(`0x${threshold}`)) {
-               //     result = nonce
-               //   }
-               // } while (result == null)
-               // return result
-       }
-
-       function parseHex (hex: string) {
-               if (hex.length % 2 === 1) hex = `0${hex}`
-               const arr = hex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16))
-               return Uint8Array.from(arr ?? [])
-       }
-
-       return { find }
+  const NONCE_BYTES = 8
+  const RECEIVE_THRESHOLD = 'fffffe0000000000'
+  const SEND_THRESHOLD = 'fffffff800000000'
+
+  /**
+  * Listens for messages from a calling function.
+  */
+  addEventListener('message', (message) => {
+    const data = JSON.parse(new TextDecoder().decode(message.data ?? message))
+    if (data === 'stop') close()
+    for (const d of data) {
+      find(d.hash, d.threshold).then(nonce => {
+        console.log('pow found')
+        d.work = nonce
+        const buf = new TextEncoder().encode(JSON.stringify(data)).buffer
+        //@ts-expect-error
+        postMessage(buf, [buf])
+      })
+    }
+  })
+
+  async function find (hash: string, threshold: string = SEND_THRESHOLD) {
+    return new Promise((resolve, reject) => {
+      window.NanoWebglPow(hash, resolve, console.log)
+
+    })
+    // let result = null
+    // let count = 0
+    // do {
+    //   count++
+    //   const nonce: Uint8Array = new Uint8Array(NONCE_BYTES)
+    //   crypto.getRandomValues(nonce)
+    //   const test: string = new Blake2b(NONCE_BYTES)
+    //     .update(nonce)
+    //     .update(parseHex(hash))
+    //     .digest('hex') as string
+    //   if (count % 1000 === 0) console.log(`${count} hashes...`)
+    //   if (BigInt(`0x${test}`) >= BigInt(`0x${threshold}`)) {
+    //     result = nonce
+    //   }
+    // } while (result == null)
+    // return result
+  }
+
+  function parseHex (hex: string) {
+    if (hex.length % 2 === 1) hex = `0${hex}`
+    const arr = hex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16))
+    return Uint8Array.from(arr ?? [])
+  }
+
+  return { find }
 }
 
 export const Pow = p()