Skip to content

Commit

Permalink
VM Browser Example and Various Browser Compatibility Fixes (#2840)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
holgerd77 and acolytec3 committed Jun 29, 2023
1 parent bec76a9 commit 9132b40
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 17 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/browser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/evm/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vite.config.ts
2 changes: 1 addition & 1 deletion packages/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 1 addition & 2 deletions packages/evm/src/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
}

Expand Down
2 changes: 1 addition & 1 deletion packages/evm/src/precompiles/06-ecadd.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down
2 changes: 1 addition & 1 deletion packages/evm/src/precompiles/07-ecmul.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down
2 changes: 1 addition & 1 deletion packages/evm/src/precompiles/08-ecpairing.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down
7 changes: 7 additions & 0 deletions packages/evm/vite.config.ts
Original file line number Diff line number Diff line change
@@ -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()],
})
1 change: 1 addition & 0 deletions packages/vm/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vite.config.ts
52 changes: 52 additions & 0 deletions packages/vm/examples/browser.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!doctype html>
<html>

<head>
<title>EthereumJS Browser Examples</title>
<script type="module">
import { Address } from '@ethereumjs/util'
import { Chain, Common, Hardfork } from '@ethereumjs/common'
import { LegacyTransaction } from '@ethereumjs/tx'
import { VM } from '@ethereumjs/vm'

const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin })
const vm = await VM.create({ common })

const tx = LegacyTransaction.fromTxData({
gasLimit: BigInt(21000),
value: BigInt(1),
to: Address.zero(),
v: BigInt(37),
r: BigInt('62886504200765677832366398998081608852310526822767264927793100349258111544447'),
s: BigInt('21948396863567062449199529794141973192314514851405455194940751428901681436138'),
})
const res = await vm.runTx({ tx, skipBalance: true })
console.log(res)
</script>

</head>

<body style="padding:50px; font-family: Arial, Helvetica, sans-serif;">
<h1>VM | @ethereumjs/vm</h1>
Basic usage of this library in the browser (using <a href="https://github.com/vitejs/vite" target="_blank">Vite</a>)

<h3>Run the Example</h3>
<ol>
<li>Go to the library root directory (packages/[LIBRARY_NAME]/)</li>
<li>Build "dist" folder with: npm run build</li>
<li>Start Vite development server with: npx vite</li>
<li>Open the example URL in the browser (http://localhost:5173/examples/browser.html)</li>
<li>Open the development console (e.g. Chrome Developer Tools)</li>
<li>See example results and play with the code</li>
</ol>

<h3>Interactive CLI</h3>
<ol>
<li>Open the "Sources -> Page" tab in the Chrome Developer Tools</li>
<li>Set a breakpoint within the original "browser.html" file (so not the one generated by Vite)</li>
<li>Now you can use and play with the imports dynamically</li>
</ol>

</body>

</html>
4 changes: 3 additions & 1 deletion packages/vm/src/vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
Expand Down
7 changes: 7 additions & 0 deletions packages/vm/vite.config.ts
Original file line number Diff line number Diff line change
@@ -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()],
})

0 comments on commit 9132b40

Please sign in to comment.