From 9132b40326493c44aca33c7fcfb0ad86efa450d5 Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Thu, 29 Jun 2023 17:34:53 +0200 Subject: [PATCH] VM Browser Example and Various Browser Compatibility Fixes (#2840) * EVM: update EC precompile dependency to new package name rustbn.wasm -> rustbn-wasm * Rebuild package-lock.json * Activate EVM CI browser test run * EVM: add dedicated vite.config.ts to avoid have to run npx vite pointing to browser config * VM/EVM: another vite.config.ts, exlude from linting * VM: guard DEBUG property setting to fix Vite breaking * EVM: update mcl-wasm import from require -> import * VM: add browser example * Make mcl namespace import --------- Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com> --- .github/workflows/browser.yml | 3 +- package-lock.json | 16 +++--- packages/evm/.eslintignore | 1 + packages/evm/package.json | 2 +- packages/evm/src/evm.ts | 3 +- packages/evm/src/precompiles/06-ecadd.ts | 2 +- packages/evm/src/precompiles/07-ecmul.ts | 2 +- packages/evm/src/precompiles/08-ecpairing.ts | 2 +- packages/evm/vite.config.ts | 7 +++ packages/vm/.eslintignore | 1 + packages/vm/examples/browser.html | 52 ++++++++++++++++++++ packages/vm/src/vm.ts | 4 +- packages/vm/vite.config.ts | 7 +++ 13 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 packages/evm/.eslintignore create mode 100644 packages/evm/vite.config.ts create mode 100644 packages/vm/.eslintignore create mode 100644 packages/vm/examples/browser.html create mode 100644 packages/vm/vite.config.ts diff --git a/.github/workflows/browser.yml b/.github/workflows/browser.yml index 64c412760d..232c70971e 100644 --- a/.github/workflows/browser.yml +++ b/.github/workflows/browser.yml @@ -45,8 +45,7 @@ jobs: # No browser tests for ethash - run: npm run test:browser -w=@ethereumjs/wallet - run: cd ../statemanager && npm run test:browser -# EVM: several tests not passing yet -# - run: cd ../evm && npm run test:browser + - run: cd ../evm && npm run test:browser # VM: several tests not passing yet # - run: npm run test:browser -w=@ethereumjs/vm diff --git a/package-lock.json b/package-lock.json index dcbfe2cd53..b3fa5daff9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16931,10 +16931,10 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rustbn.wasm": { + "node_modules/rustbn-wasm": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/rustbn.wasm/-/rustbn.wasm-0.1.0.tgz", - "integrity": "sha512-SyNZMKOjv9DjEXZ65oLXmKeqRqw7Ub5zd9HWqNe+JdQTTvbn9gd3+kvPdO4xyjc6WyDgDFQi14Fq0W2L8UMnRQ==", + "resolved": "https://registry.npmjs.org/rustbn-wasm/-/rustbn-wasm-0.1.0.tgz", + "integrity": "sha512-aioejicxMxkJJr5LtNlRunhAypkLZfLX73vJYxY17TVMZsfNbsy1xuy3WPR9lANYFd2jDACQ8yKtsfJCX0TY2w==", "dependencies": { "@scure/base": "^1.1.1" } @@ -21347,7 +21347,7 @@ "debug": "^4.3.3", "ethereum-cryptography": "^2.0.0", "mcl-wasm": "^0.7.1", - "rustbn.wasm": "^0.1.0" + "rustbn-wasm": "^0.1.0" }, "devDependencies": { "@ethereumjs/statemanager": "^1.0.5", @@ -23466,7 +23466,7 @@ "memory-level": "^1.0.0", "minimist": "^1.2.5", "node-dir": "^0.1.17", - "rustbn.wasm": "^0.1.0", + "rustbn-wasm": "^0.1.0", "solc": "^0.8.1" } }, @@ -34721,10 +34721,10 @@ "queue-microtask": "^1.2.2" } }, - "rustbn.wasm": { + "rustbn-wasm": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/rustbn.wasm/-/rustbn.wasm-0.1.0.tgz", - "integrity": "sha512-SyNZMKOjv9DjEXZ65oLXmKeqRqw7Ub5zd9HWqNe+JdQTTvbn9gd3+kvPdO4xyjc6WyDgDFQi14Fq0W2L8UMnRQ==", + "resolved": "https://registry.npmjs.org/rustbn-wasm/-/rustbn-wasm-0.1.0.tgz", + "integrity": "sha512-aioejicxMxkJJr5LtNlRunhAypkLZfLX73vJYxY17TVMZsfNbsy1xuy3WPR9lANYFd2jDACQ8yKtsfJCX0TY2w==", "requires": { "@scure/base": "^1.1.1" } diff --git a/packages/evm/.eslintignore b/packages/evm/.eslintignore new file mode 100644 index 0000000000..3c018eed27 --- /dev/null +++ b/packages/evm/.eslintignore @@ -0,0 +1 @@ +vite.config.ts \ No newline at end of file diff --git a/packages/evm/package.json b/packages/evm/package.json index f95adcc264..914160f9c9 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -57,7 +57,7 @@ "debug": "^4.3.3", "ethereum-cryptography": "^2.0.0", "mcl-wasm": "^0.7.1", - "rustbn.wasm": "^0.1.0" + "rustbn-wasm": "^0.1.0" }, "devDependencies": { "@ethereumjs/statemanager": "^1.0.5", diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index 1158eaef9a..b1e8bd174e 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -15,6 +15,7 @@ import { zeros, } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' +import * as mcl from 'mcl-wasm' import { EOF, getEOFCode } from './eof.js' import { ERROR, EvmError } from './exceptions.js' @@ -49,11 +50,9 @@ const debugPrecompiles = createDebugLogger('evm:precompiles') // very ugly way to detect if we are running in a browser const isBrowser = new Function('try {return this===window;}catch(e){ return false;}') -let mcl: any let mclInitPromise: any if (isBrowser() === false) { - mcl = require('mcl-wasm') mclInitPromise = mcl.init(mcl.BLS12_381) } diff --git a/packages/evm/src/precompiles/06-ecadd.ts b/packages/evm/src/precompiles/06-ecadd.ts index 8433330cf1..22b1521165 100644 --- a/packages/evm/src/precompiles/06-ecadd.ts +++ b/packages/evm/src/precompiles/06-ecadd.ts @@ -1,6 +1,6 @@ import { short } from '@ethereumjs/util' import { bytesToHex, hexToBytes } from 'ethereum-cryptography/utils.js' -import { ec_add } from 'rustbn.wasm' +import { ec_add } from 'rustbn-wasm' import { OOGResult } from '../evm.js' diff --git a/packages/evm/src/precompiles/07-ecmul.ts b/packages/evm/src/precompiles/07-ecmul.ts index 1a86701b26..f906722209 100644 --- a/packages/evm/src/precompiles/07-ecmul.ts +++ b/packages/evm/src/precompiles/07-ecmul.ts @@ -1,6 +1,6 @@ import { short } from '@ethereumjs/util' import { bytesToHex, hexToBytes } from 'ethereum-cryptography/utils.js' -import { ec_mul } from 'rustbn.wasm' +import { ec_mul } from 'rustbn-wasm' import { OOGResult } from '../evm.js' diff --git a/packages/evm/src/precompiles/08-ecpairing.ts b/packages/evm/src/precompiles/08-ecpairing.ts index 4be7a192d0..42828089d6 100644 --- a/packages/evm/src/precompiles/08-ecpairing.ts +++ b/packages/evm/src/precompiles/08-ecpairing.ts @@ -1,6 +1,6 @@ import { short } from '@ethereumjs/util' import { bytesToHex, hexToBytes } from 'ethereum-cryptography/utils.js' -import { ec_pairing } from 'rustbn.wasm' +import { ec_pairing } from 'rustbn-wasm' import { OOGResult } from '../evm.js' diff --git a/packages/evm/vite.config.ts b/packages/evm/vite.config.ts new file mode 100644 index 0000000000..e620c08fb8 --- /dev/null +++ b/packages/evm/vite.config.ts @@ -0,0 +1,7 @@ +import wasm from 'vite-plugin-wasm' +import topLevelAwait from 'vite-plugin-top-level-await' +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + plugins: [wasm(), topLevelAwait()], +}) diff --git a/packages/vm/.eslintignore b/packages/vm/.eslintignore new file mode 100644 index 0000000000..3c018eed27 --- /dev/null +++ b/packages/vm/.eslintignore @@ -0,0 +1 @@ +vite.config.ts \ No newline at end of file diff --git a/packages/vm/examples/browser.html b/packages/vm/examples/browser.html new file mode 100644 index 0000000000..0173d56d77 --- /dev/null +++ b/packages/vm/examples/browser.html @@ -0,0 +1,52 @@ + + + + + EthereumJS Browser Examples + + + + + +

VM | @ethereumjs/vm

+ Basic usage of this library in the browser (using Vite) + +

Run the Example

+
    +
  1. Go to the library root directory (packages/[LIBRARY_NAME]/)
  2. +
  3. Build "dist" folder with: npm run build
  4. +
  5. Start Vite development server with: npx vite
  6. +
  7. Open the example URL in the browser (http://localhost:5173/examples/browser.html)
  8. +
  9. Open the development console (e.g. Chrome Developer Tools)
  10. +
  11. See example results and play with the code
  12. +
+ +

Interactive CLI

+
    +
  1. Open the "Sources -> Page" tab in the Chrome Developer Tools
  2. +
  3. Set a breakpoint within the original "browser.html" file (so not the one generated by Vite)
  4. +
  5. Now you can use and play with the imports dynamically
  6. +
+ + + + \ No newline at end of file diff --git a/packages/vm/src/vm.ts b/packages/vm/src/vm.ts index b6d2271ea7..f465778232 100644 --- a/packages/vm/src/vm.ts +++ b/packages/vm/src/vm.ts @@ -127,7 +127,9 @@ export class VM { } // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables - this.DEBUG = process?.env?.DEBUG?.includes('ethjs') ?? false + // Additional window check is to prevent vite browser bundling (and potentially other) to break + this.DEBUG = + typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false } async init(): Promise { diff --git a/packages/vm/vite.config.ts b/packages/vm/vite.config.ts new file mode 100644 index 0000000000..e620c08fb8 --- /dev/null +++ b/packages/vm/vite.config.ts @@ -0,0 +1,7 @@ +import wasm from 'vite-plugin-wasm' +import topLevelAwait from 'vite-plugin-top-level-await' +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + plugins: [wasm(), topLevelAwait()], +})