//! SPDX-License-Identifier: GPL-3.0-or-later
import { NanoPowValidate } from '#lib/validate'
-import { Bytes, BytesToHex, Logger, bigintRandom, bigintToHex } from '#utils'
+import { BytesToHex, Logger, bigintRandom, isBytes } from '#utils'
import { WorkGenerateResponse } from 'nano-pow'
import { NanoPowWasmWorker } from './worker.js'
// Initialize CPU
let isReady: boolean = false
-let data: { [key: string]: string } = {}
+let data: Record<string, bigint | Bytes> = {}
let v: BigUint64Array = new BigUint64Array(16)
let m: BigUint64Array = new BigUint64Array(16)
let workers: Worker[] = []
}
async function init (hash: Bytes, difficulty: bigint, effort: number): Promise<void> {
- data.hash = BytesToHex(hash.buffer, 64)
- data.difficulty = bigintToHex(difficulty, 16)
+ data.hash = hash
+ data.difficulty = difficulty
for (let i = workers.length; i < effort; i++) {
workers.push(new Worker(url, { type: 'module' }))
})
}
-async function dispatch (): Promise<bigint> {
+async function dispatch (): Promise<Bytes> {
return new Promise(next => {
const attempts = []
for (const w of workers) {
- data.seed = bigintToHex((bigintRandom() & ~((1n << 24n) - 1n)), 16)
+ data.seed = bigintRandom() & ~((1n << 24n) - 1n)
const attempt = new Promise((resolve, reject) => {
w.onerror = reject
w.onmessage = (msg) => resolve(msg.data)
- w.postMessage(JSON.stringify(data))
+ w.postMessage(data)
})
attempts.push(attempt)
}
Promise.all(attempts).then(results => {
- const result = results.find(r => typeof r === 'bigint')
+ const result: Bytes | undefined = results.find(r => isBytes(r))
next(result ?? dispatch())
})
})
if (isReady === false) setup()
await init(hash, difficulty, effort)
- let work = 0n
+ let work: Bytes = new Uint8Array(8)
let result = ''
try {
- work = await dispatch()
- result = (await NanoPowValidate(Bytes(work, 8), hash, difficulty, debug)).difficulty
+ work.set(await dispatch())
+ result = (await NanoPowValidate(work, hash, difficulty, debug)).difficulty
} catch (err) {
LOG: logger.log(err)
} finally {
return {
hash: BytesToHex(hash.buffer, 64),
- work: bigintToHex(work, 16),
+ work: BytesToHex(work.buffer, 16),
difficulty: result
}
}
//@ts-expect-error
import compute from './asm/build/compute.wasm'
-type Main = (w: bigint, h0: bigint, h1: bigint, h2: bigint, h3: bigint, d: bigint) => any
+type Main = (w: bigint, h0: bigint, h1: bigint, h2: bigint, h3: bigint, d: bigint) => bigint
const worker = async (compute: number[]): Promise<void> => {
let isReady = false
}
async function handleMessage (msg: any): Promise<void> {
- let result: any = null
+ let result: any = null, buffer: Transferable[] = []
try {
if (!isReady) await setup()
const hashArray = new BigUint64Array(4)
removeEventListener('message', handleMessage)
result = 'stopped'
} else {
- const data = JSON.parse(msg.data)
- const seed = BigInt(`0x${data.seed}`)
- const difficulty = BigInt(`0x${data.difficulty}`)
- for (let i = 0; i < data.hash.length; i += 16) {
- const u64 = data.hash.slice(i, i + 16)
- hashView.setBigUint64(i / 2, BigInt(`0x${u64}`))
+ const { data } = msg as { data: { hash: Uint8Array, difficulty: bigint, seed: bigint } }
+ const { difficulty, seed } = data
+ const hash = new BigUint64Array(data.hash.buffer)
+ for (let i = 0; i < hash.length; i++) {
+ hashView.setBigUint64(i << 3, hash[i], true)
}
const work = main(seed, hashArray[0], hashArray[1], hashArray[2], hashArray[3], difficulty)
if (typeof work !== 'bigint') {
throw new TypeError('Invalid work from WASM')
}
- const workArray = new BigUint64Array(1)
+ const workArray = new Uint8Array(8)
const workView = new DataView(workArray.buffer)
workView.setBigUint64(0, work, true)
- result = workArray[0]
+ result = workArray
}
} catch (err: unknown) {
if (typeof err === 'object' && err != null) {