diff --git a/package-lock.json b/package-lock.json index 6e1d8b6e10a..189f3ccbe53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14657,6 +14657,12 @@ "node": ">=0.10.0" } }, + "node_modules/workerpool": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.1.3.tgz", + "integrity": "sha512-LhUrk4tbxJRDQmRrrFWA9EnboXI79fe0ZNTy3u8m+dqPN1EkVSIsQYAB8OF/fkyhG8Rtup+c/bzj/+bzbG8fqg==", + "dev": true + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -15340,7 +15346,8 @@ "rollup-plugin-visualizer": "^5.12.0", "rustbn-wasm": "^0.4.0", "solc": "^0.8.1", - "split": "^1.0.1" + "split": "^1.0.1", + "workerpool": "^9.1.3" }, "engines": { "node": ">=18" diff --git a/packages/evm/examples/keccakWorker.js b/packages/evm/examples/keccakWorker.js new file mode 100644 index 00000000000..94bfba15e5b --- /dev/null +++ b/packages/evm/examples/keccakWorker.js @@ -0,0 +1,11 @@ +import { keccak256 } from 'ethereum-cryptography/keccak.js' +import workerpool from 'workerpool' + +function keccak256AB(i) { + const res = keccak256(new Uint8Array(i)) + return res.buffer +} + +workerpool.worker({ + keccak256AB, +}) diff --git a/packages/evm/examples/workerPool.ts b/packages/evm/examples/workerPool.ts new file mode 100644 index 00000000000..7b860fa3082 --- /dev/null +++ b/packages/evm/examples/workerPool.ts @@ -0,0 +1,57 @@ +import { keccak256 } from 'ethereum-cryptography/keccak.js' +import path from 'path' +import { fileURLToPath } from 'url' +import workerpool from 'workerpool' + +// Additional fix: +// https://iamwebwiz.medium.com/how-to-fix-dirname-is-not-defined-in-es-module-scope-34d94a86694d +const __filename = fileURLToPath(import.meta.url) // get the resolved path to the file +const __dirname = path.dirname(__filename) // get the name of the directory + +const pool = workerpool.pool() +const pool2 = workerpool.pool(__dirname + '/keccakWorker.js') + +function add(a: number, b: number) { + return a + b +} + +function transferAB(i: ArrayBuffer) { + console.log(i) + console.log(new Uint8Array(i)) +} + +const main = async () => { + console.time('t') + for (let i = 0; i < 1000; i++) { + if (i % 2 === 0) { + const res = keccak256(new Uint8Array([1, 2, 3, 4, 5])) + console.log(res) + } else { + // First simple test to see if things work at all + /*await pool.exec(add, [1, 2]).then(function (result) { + console.log(result) // outputs 7 + })*/ + // Does not work ("ReferenceError: assert is not defined"), likely because datatype not allowed + /*await pool.exec(keccak256, [new Uint8Array([1, 2, 3, 4, 5])]).then(function (result) { + console.log(result) // outputs 7 + })*/ + // Uint8Array does not work, so we need to transfer the underlying ArrayBuffer, see e.g. + // https://advancedweb.hu/how-to-transfer-binary-data-efficiently-across-worker-threads-in-nodejs/ + // https://stackoverflow.com/questions/37228285/uint8array-to-arraybuffer + /*await pool.exec(transferAB, [new Uint8Array([1, 2, 3, 4, 5]).buffer]).then(function (result) { + console.log(result) // outputs 7 + })*/ + // For keccak we cannot import the keccak256 function into a dynamic worker function, + // so now we need to switch to dedicated workers + await pool2 + .exec('keccak256AB', [new Uint8Array([1, 2, 3, 4, 5]).buffer]) + .then(function (result) { + console.log(new Uint8Array(result)) + }) + } + } + console.timeEnd('t') + await pool.terminate() +} + +void main() diff --git a/packages/evm/package.json b/packages/evm/package.json index c3394ced8b5..0b73b6ac917 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -74,6 +74,7 @@ "benchmark": "^2.1.4", "level": "^8.0.0", "mcl-wasm": "^1.5.0", + "workerpool": "^9.1.3", "memory-level": "^1.0.0", "minimist": "^1.2.5", "node-dir": "^0.1.17",