mirror of
https://github.com/Qortal/qortal-mobile.git
synced 2025-04-24 20:07:52 +00:00
105 lines
3.1 KiB
JavaScript
105 lines
3.1 KiB
JavaScript
import { Sha256 } from 'asmcrypto.js';
|
|
import wasmInit from './memory-pow.wasm?init';
|
|
import NativePOW from './utils/nativepow'
|
|
let compute; // Exported compute function from Wasm
|
|
let memory; // WebAssembly.Memory instance
|
|
let heap; // Uint8Array view of the memory buffer
|
|
let brk = 512 * 1024; // Initial brk set to 512 KiB
|
|
const allocations = new Map(); // Track allocations by pointer
|
|
let workBufferPtr = null; // Reuse work buffer
|
|
const workBufferLength = 8 * 1024 * 1024; // 8 MiB
|
|
|
|
// Load the WebAssembly module
|
|
async function loadWasm() {
|
|
try {
|
|
memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }); // 16 MiB
|
|
heap = new Uint8Array(memory.buffer);
|
|
|
|
const importObject = {
|
|
env: {
|
|
memory, // Pass memory to Wasm
|
|
abort: () => { throw new Error('Wasm abort called'); }, // Handle abort calls from Wasm
|
|
},
|
|
};
|
|
|
|
const wasmModule = await wasmInit(importObject);
|
|
compute = wasmModule.exports.compute2;
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Memory allocation function
|
|
function sbrk(size) {
|
|
const old = brk;
|
|
|
|
// If a previous allocation exists for this size, reuse it
|
|
if (allocations.has(size)) {
|
|
return allocations.get(size);
|
|
}
|
|
|
|
brk += size;
|
|
|
|
// Grow memory if needed
|
|
if (brk > memory.buffer.byteLength) {
|
|
const pagesNeeded = Math.ceil((brk - memory.buffer.byteLength) / (64 * 1024)); // 64 KiB per page
|
|
try {
|
|
memory.grow(pagesNeeded);
|
|
heap = new Uint8Array(memory.buffer); // Update heap view
|
|
} catch (e) {
|
|
console.error('Failed to grow memory:', e);
|
|
throw new RangeError('WebAssembly.Memory.grow(): Maximum memory size exceeded');
|
|
}
|
|
}
|
|
|
|
allocations.set(size, old); // Track the allocation
|
|
return old;
|
|
}
|
|
|
|
// Proof-of-Work computation function
|
|
async function computePow(chatBytes, difficulty) {
|
|
// if (!compute) {
|
|
// throw new Error('WebAssembly module not initialized. Call loadWasm first.');
|
|
// }
|
|
|
|
// const chatBytesArray = Uint8Array.from(Object.values(chatBytes));
|
|
// const chatBytesHash = new Sha256().process(chatBytesArray).finish().result;
|
|
|
|
// // Allocate memory for the hash
|
|
// const hashPtr = sbrk(32);
|
|
// const hashAry = new Uint8Array(memory.buffer, hashPtr, 32);
|
|
// hashAry.set(chatBytesHash);
|
|
|
|
// // Reuse the work buffer if already allocated
|
|
// if (!workBufferPtr) {
|
|
// workBufferPtr = sbrk(workBufferLength);
|
|
// }
|
|
console.log('native')
|
|
const nonce = await NativePOW.computeProofOfWork({ chatBytes, difficulty });
|
|
console.log('nonce', nonce)
|
|
(hashPtr, workBufferPtr, workBufferLength, difficulty);
|
|
|
|
return { nonce, chatBytesArray };
|
|
}
|
|
|
|
// Worker event listener
|
|
self.addEventListener('message', async (e) => {
|
|
const { chatBytes, difficulty } = e.data;
|
|
|
|
try {
|
|
// Initialize Wasm if not already done
|
|
// if (!compute) {
|
|
// await loadWasm();
|
|
// }
|
|
|
|
// Perform the POW computation
|
|
const result = await computePow(chatBytes, difficulty);
|
|
|
|
// Send the result back to the main thread
|
|
self.postMessage(result);
|
|
} catch (error) {
|
|
console.error('Error in worker:', error);
|
|
self.postMessage({ error: error.message });
|
|
}
|
|
});
|