Skip to content

Commit

Permalink
Update rustbn-wasm usage (ethereumjs#3304)
Browse files Browse the repository at this point in the history
* Update rustbn-wasm usage everywhere

* Update package lock

* use EVM.create

* Update examples

* Address feedback

* Update rustbn-wasm commit hash

* Remove console log

* fix test

* update rustbn again

* update rustbn

* Add bn128 to vm test runner init

* Update to latest rustbn-wasm

* Update rustbn-wasm to published v0.4.0 version

* Rebuild package-lock.json

---------

Co-authored-by: Holger Drewes <[email protected]>
  • Loading branch information
acolytec3 and holgerd77 authored Mar 8, 2024
1 parent a35bf07 commit 5e3cfdd
Show file tree
Hide file tree
Showing 44 changed files with 197 additions and 185 deletions.
16 changes: 9 additions & 7 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion packages/evm/examples/browser.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
const stateManager = new DefaultStateManager()
const blockchain = await Blockchain.create()

const evm = new EVM({
const evm = await EVM.create({
common,
stateManager,
blockchain,
Expand Down
10 changes: 7 additions & 3 deletions packages/evm/examples/eips.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Chain, Common } from '@ethereumjs/common'
import { EVM } from '@ethereumjs/evm'

const common = new Common({ chain: Chain.Mainnet, eips: [3074] })
const evm = new EVM({ common })
console.log(`EIP 3074 is active - ${evm.common.isActivatedEIP(3074)}`)
const main = async () => {
const common = new Common({ chain: Chain.Mainnet, eips: [3074] })
const evm = await EVM.create({ common })
console.log(`EIP 3074 is active - ${evm.common.isActivatedEIP(3074)}`)
}

main()
2 changes: 1 addition & 1 deletion packages/evm/examples/runCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const main = async () => {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London })
const blockchain = await Blockchain.create()

const evm = new EVM({
const evm = await EVM.create({
common,
blockchain,
})
Expand Down
2 changes: 1 addition & 1 deletion packages/evm/examples/simple.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { hexToBytes } from '@ethereumjs/util'
import { EVM } from '@ethereumjs/evm'

const evm = new EVM()
const main = async () => {
const evm = await EVM.create({})
const res = await evm.runCode({ code: hexToBytes('0x6001') }) // PUSH1 01 -- simple bytecode to push 1 onto the stack
console.log(res.executionGasUsed) // 3n
}
Expand Down
2 changes: 1 addition & 1 deletion packages/evm/examples/withBlockchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const main = async () => {
const stateManager = new DefaultStateManager()
const blockchain = await Blockchain.create()

const evm = new EVM({
const evm = await EVM.create({
common,
stateManager,
blockchain,
Expand Down
2 changes: 1 addition & 1 deletion packages/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"@types/debug": "^4.1.9",
"debug": "^4.3.3",
"ethereum-cryptography": "^2.1.3",
"rustbn-wasm": "^0.2.0"
"rustbn-wasm": "^0.4.0"
},
"devDependencies": {
"@ethersproject/abi": "^5.0.12",
Expand Down
21 changes: 20 additions & 1 deletion packages/evm/src/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
zeros,
} from '@ethereumjs/util'
import debugDefault from 'debug'
import { initRustBN } from 'rustbn-wasm'

import { EOF, getEOFCode } from './eof.js'
import { ERROR, EvmError } from './exceptions.js'
Expand Down Expand Up @@ -137,7 +138,24 @@ export class EVM implements EVMInterface {

protected readonly _emit: (topic: string, data: any) => Promise<void>

constructor(opts: EVMOpts = {}) {
private bn128: {
ec_pairing: (input_str: string) => string
ec_add: (input_str: string) => string
ec_mul: (input_hex: string) => string
}

static async create(createOpts?: EVMOpts) {
const opts = createOpts ?? ({} as EVMOpts)
if (opts?.bn128 === undefined) {
opts.bn128 = await initRustBN()
}
return new EVM(opts)
}
constructor(opts: EVMOpts) {
if (opts.bn128 === undefined) {
throw new Error('rustbn not provided')
}
this.bn128 = opts.bn128 // Required to instantiate the EVM
this.events = new AsyncEventEmitter()

this._optsCached = opts
Expand Down Expand Up @@ -1079,6 +1097,7 @@ export class EVM implements EVMInterface {
...this._optsCached,
common,
stateManager: this.stateManager.shallowCopy(),
bn128: this.bn128,
}
;(opts.stateManager as any).common = common
return new EVM(opts)
Expand Down
2 changes: 2 additions & 0 deletions packages/evm/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import {
EVMRunCodeOpts,
ExecResult,
Log,
bn128,
} from './types.js'
export {
bn128,
EOF,
EVM,
EvmError,
Expand Down
4 changes: 2 additions & 2 deletions packages/evm/src/precompiles/06-ecadd.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { bytesToHex, bytesToUnprefixedHex, hexToBytes, short } from '@ethereumjs/util'
import { ec_add } from 'rustbn-wasm'

import { OOGResult } from '../evm.js'

import type { EVM } from '../evm.js'
import type { ExecResult } from '../types.js'
import type { PrecompileInput } from './types.js'

Expand All @@ -24,7 +24,7 @@ export function precompile06(opts: PrecompileInput): ExecResult {
return OOGResult(opts.gasLimit)
}

const returnData = hexToBytes(ec_add(inputData))
const returnData = hexToBytes((opts._EVM as EVM)['bn128'].ec_add(inputData))

// check ecadd success or failure by comparing the output length
if (returnData.length !== 64) {
Expand Down
4 changes: 2 additions & 2 deletions packages/evm/src/precompiles/07-ecmul.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { bytesToHex, bytesToUnprefixedHex, hexToBytes, short } from '@ethereumjs/util'
import { ec_mul } from 'rustbn-wasm'

import { OOGResult } from '../evm.js'

import type { EVM } from '../evm.js'
import type { ExecResult } from '../types.js'
import type { PrecompileInput } from './types.js'

Expand All @@ -24,7 +24,7 @@ export function precompile07(opts: PrecompileInput): ExecResult {
return OOGResult(opts.gasLimit)
}

const returnData = hexToBytes(ec_mul(inputData))
const returnData = hexToBytes((opts._EVM as EVM)['bn128'].ec_mul(inputData))

// check ecmul success or failure by comparing the output length
if (returnData.length !== 64) {
Expand Down
6 changes: 4 additions & 2 deletions packages/evm/src/precompiles/08-ecpairing.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { bytesToHex, bytesToUnprefixedHex, hexToBytes, short } from '@ethereumjs/util'
import { ec_pairing } from 'rustbn-wasm'

import { OOGResult } from '../evm.js'

import type { EVM } from '../evm.js'
import type { ExecResult } from '../types.js'
import type { PrecompileInput } from './types.js'

Expand All @@ -28,7 +28,9 @@ export function precompile08(opts: PrecompileInput): ExecResult {
return OOGResult(opts.gasLimit)
}

const returnData = hexToBytes(ec_pairing(bytesToUnprefixedHex(inputData)))
const returnData = hexToBytes(
(opts._EVM as EVM)['bn128'].ec_pairing(bytesToUnprefixedHex(inputData))
)

// check ecpairing success or failure by comparing the output length
if (returnData.length !== 32) {
Expand Down
17 changes: 17 additions & 0 deletions packages/evm/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ export type EVMProfilerOpts = {
* Options for instantiating a {@link EVM}.
*/
export interface EVMOpts {
/**
* The BN128 curve package (`rustbn-wasm`)
*/
bn128?: {
ec_pairing: (input_str: string) => string
ec_add: (input_str: string) => string
ec_mul: (input_hex: string) => string
}
/**
* Use a {@link Common} instance for EVM instantiation.
*
Expand Down Expand Up @@ -380,3 +388,12 @@ export class DefaultBlockchain implements Blockchain {
return this
}
}

/**
* The BN128 curve package (`rustbn-wasm`)
*/
export interface bn128 {
ec_pairing: (input_str: string) => string
ec_add: (input_str: string) => string
ec_mul: (input_hex: string) => string
}
2 changes: 1 addition & 1 deletion packages/evm/test/asyncEvents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('async events', () => {
it('should work', async () => {
const caller = new Address(hexToBytes('0x00000000000000000000000000000000000000ee'))
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Constantinople })
const evm = new EVM({
const evm = await EVM.create({
common,
})
evm.events.on('step', async (event, next) => {
Expand Down
6 changes: 3 additions & 3 deletions packages/evm/test/blobVersionedHashes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('BLOBHASH / access blobVersionedHashes in calldata', () => {
chain: 'custom',
hardfork: Hardfork.Cancun,
})
const evm = new EVM({
const evm = await EVM.create({
common,
})

Expand Down Expand Up @@ -44,7 +44,7 @@ describe(`BLOBHASH: access blobVersionedHashes within contract calls`, () => {
chain: 'custom',
hardfork: Hardfork.Cancun,
})
const evm = new EVM({
const evm = await EVM.create({
common,
})

Expand Down Expand Up @@ -95,7 +95,7 @@ describe(`BLOBHASH: access blobVersionedHashes in a CREATE/CREATE2 frame`, () =>
chain: 'custom',
hardfork: Hardfork.Cancun,
})
const evm = new EVM({
const evm = await EVM.create({
common,
})

Expand Down
4 changes: 2 additions & 2 deletions packages/evm/test/customCrypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('custom crypto', () => {
}
const msg = Uint8Array.from([0, 1, 2, 3])
const common = new Common({ chain: Chain.Mainnet, customCrypto })
const evm = new EVM({ common })
const evm = await EVM.create({ common })
const addressStr = '0000000000000000000000000000000000000002'
const SHA256 = getActivePrecompiles(common).get(addressStr)!
const result = await SHA256({
Expand All @@ -46,7 +46,7 @@ describe('custom crypto', () => {
}
const msg = concatBytes(randomBytes(32), setLengthLeft(intToBytes(27), 32), randomBytes(32))
const common = new Common({ chain: Chain.Mainnet, customCrypto })
const evm = new EVM({ common })
const evm = await EVM.create({ common })
const addressStr = '0000000000000000000000000000000000000001'
const ECRECOVER = getActivePrecompiles(common).get(addressStr)!
const result = await ECRECOVER({
Expand Down
18 changes: 6 additions & 12 deletions packages/evm/test/customOpcodes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ describe('VM: custom opcodes', () => {
}

it('should add custom opcodes to the EVM', async () => {
const evm = new EVM({
customOpcodes: [testOpcode],
})
const evm = await EVM.create({ customOpcodes: [testOpcode] })
const gas = 123456
let correctOpcodeName = false
evm.events.on('step', (e: InterpreterStep) => {
Expand All @@ -45,7 +43,7 @@ describe('VM: custom opcodes', () => {
})

it('should delete opcodes from the EVM', async () => {
const evm = new EVM({
const evm = await EVM.create({
customOpcodes: [{ opcode: 0x20 }], // deletes KECCAK opcode
})
const gas = BigInt(123456)
Expand All @@ -59,7 +57,7 @@ describe('VM: custom opcodes', () => {
it('should not override default opcodes', async () => {
// This test ensures that always the original opcode map is used
// Thus, each time you recreate a EVM, it is in a clean state
const evm = new EVM({
const evm = await EVM.create({
customOpcodes: [{ opcode: 0x01 }], // deletes ADD opcode
})
const gas = BigInt(123456)
Expand All @@ -69,7 +67,7 @@ describe('VM: custom opcodes', () => {
})
assert.ok(res.executionGasUsed === gas, 'successfully deleted opcode')

const evmDefault = new EVM({})
const evmDefault = await EVM.create({})

// PUSH 04
// PUSH 01
Expand All @@ -88,9 +86,7 @@ describe('VM: custom opcodes', () => {

it('should override opcodes in the EVM', async () => {
testOpcode.opcode = 0x20 // Overrides KECCAK
const evm = new EVM({
customOpcodes: [testOpcode],
})
const evm = await EVM.create({ customOpcodes: [testOpcode] })
const gas = 123456
const res = await evm.runCode({
code: hexToBytes('0x20'),
Expand All @@ -113,9 +109,7 @@ describe('VM: custom opcodes', () => {
},
}

const evm = new EVM({
customOpcodes: [testOpcode],
})
const evm = await EVM.create({ customOpcodes: [testOpcode] })
evm.events.on('beforeMessage', () => {})
evm.events.on('beforeMessage', () => {})
const evmCopy = evm.shallowCopy()
Expand Down
Loading

0 comments on commit 5e3cfdd

Please sign in to comment.