Unverified Commit 45cf8dd3 authored by yann300's avatar yann300 Committed by GitHub

Merge pull request #1208 from ethereum/selectFork

Fork selection for javascript VM
parents 497fb0bf 980f19d0
...@@ -111,7 +111,8 @@ export const DebuggerApiMixin = (Base) => class extends Base { ...@@ -111,7 +111,8 @@ export const DebuggerApiMixin = (Base) => class extends Base {
} }
return null return null
}, },
debugWithGeneratedSources: false debugWithGeneratedSources: false,
fork: 'berlin'
}) })
return await debug.debugger.traceManager.getTrace(hash) return await debug.debugger.traceManager.getTrace(hash)
} }
......
...@@ -129,7 +129,7 @@ contract t2est { ...@@ -129,7 +129,7 @@ contract t2est {
const records = `{ const records = `{
"accounts": { "accounts": {
"account{10}": "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c" "account{2}": "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c"
}, },
"linkReferences": { "linkReferences": {
"testLib": "created{1512830014773}" "testLib": "created{1512830014773}"
...@@ -146,7 +146,7 @@ const records = `{ ...@@ -146,7 +146,7 @@ const records = `{
"linkReferences": {}, "linkReferences": {},
"inputs": "()", "inputs": "()",
"type": "constructor", "type": "constructor",
"from": "account{10}" "from": "account{2}"
} }
}, },
{ {
...@@ -172,7 +172,7 @@ const records = `{ ...@@ -172,7 +172,7 @@ const records = `{
"name": "", "name": "",
"type": "constructor", "type": "constructor",
"inputs": "(uint256)", "inputs": "(uint256)",
"from": "account{10}" "from": "account{2}"
} }
}, },
{ {
...@@ -188,7 +188,7 @@ const records = `{ ...@@ -188,7 +188,7 @@ const records = `{
"name": "set", "name": "set",
"inputs": "(uint256,address)", "inputs": "(uint256,address)",
"type": "function", "type": "function",
"from": "account{10}" "from": "account{2}"
} }
} }
], ],
...@@ -287,7 +287,7 @@ const records = `{ ...@@ -287,7 +287,7 @@ const records = `{
const scenario = { const scenario = {
accounts: { accounts: {
'account{10}': '0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c' 'account{2}': '0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c'
}, },
linkReferences: {}, linkReferences: {},
transactions: [ transactions: [
...@@ -305,7 +305,7 @@ const scenario = { ...@@ -305,7 +305,7 @@ const scenario = {
name: '', name: '',
type: 'constructor', type: 'constructor',
inputs: '(uint256)', inputs: '(uint256)',
from: 'account{10}' from: 'account{2}'
} }
}, },
{ {
...@@ -320,7 +320,7 @@ const scenario = { ...@@ -320,7 +320,7 @@ const scenario = {
name: 'set', name: 'set',
inputs: '(uint256)', inputs: '(uint256)',
type: 'function', type: 'function',
from: 'account{10}' from: 'account{2}'
} }
} }
], ],
......
...@@ -62,7 +62,7 @@ module.exports = { ...@@ -62,7 +62,7 @@ module.exports = {
'Call web3.eth.getAccounts() using JavaScript VM': function (browser: NightwatchBrowser) { 'Call web3.eth.getAccounts() using JavaScript VM': function (browser: NightwatchBrowser) {
browser browser
.executeScript('web3.eth.getAccounts()') .executeScript('web3.eth.getAccounts()')
.waitForElementContainsText('*[data-id="terminalJournal"]', '"0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C", "0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB", "0x583031D1113aD414F02576BD6afaBfb302140225", "0xdD870fA1b7C4700F2BD7f44238821C26f7392148"', 80000) .waitForElementContainsText('*[data-id="terminalJournal"]', '"0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db", "0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB", "0x617F2E2fD72FD9D5503197092aC168c91465E7f2", "0x17F6AD8Ef982297579C203069C1DbfFE4348c372", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C"', 80000)
}, },
'Call web3.eth.getAccounts() using Web3 Provider': function (browser: NightwatchBrowser) { 'Call web3.eth.getAccounts() using Web3 Provider': function (browser: NightwatchBrowser) {
......
...@@ -152,6 +152,21 @@ module.exports = { ...@@ -152,6 +152,21 @@ module.exports = {
.journalLastChildIncludes('Parameters:') .journalLastChildIncludes('Parameters:')
.journalLastChildIncludes('2,3,error_string_2') .journalLastChildIncludes('2,3,error_string_2')
.journalLastChildIncludes('Debug the transaction to get more information.') .journalLastChildIncludes('Debug the transaction to get more information.')
},
'Should Compile and Deploy a contract which define a custom error, the error should be logged in the terminal , using London VM Fork': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="settingsVMLondonMode"]') // switch to London fork
.selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite
.click('#runTabView button[class^="instanceButton"]')
.waitForElementPresent('.instance:nth-of-type(2)')
.click('.instance:nth-of-type(2) > div > button')
.clickFunction('g - transact (not payable)')
.journalLastChildIncludes('Error provided by the contract:')
.journalLastChildIncludes('CustomError')
.journalLastChildIncludes('Parameters:')
.journalLastChildIncludes('2,3,error_string_2')
.journalLastChildIncludes('Debug the transaction to get more information.')
.end() .end()
} }
} }
......
...@@ -98,11 +98,15 @@ class SettingsUI { ...@@ -98,11 +98,15 @@ class SettingsUI {
</label> </label>
<div class="${css.environment}"> <div class="${css.environment}">
<select id="selectExEnvOptions" data-id="settingsSelectEnvOptions" class="form-control ${css.select} custom-select"> <select id="selectExEnvOptions" data-id="settingsSelectEnvOptions" class="form-control ${css.select} custom-select">
<option id="vm-mode" <option id="vm-mode-berlin" data-id="settingsVMBerlinMode"
title="Execution environment does not connect to any node, everything is local and in memory only." title="Execution environment does not connect to any node, everything is local and in memory only."
value="vm" name="executionContext"> JavaScript VM value="vm-berlin" name="executionContext" fork="berlin" > JavaScript VM (Berlin)
</option> </option>
<option id="injected-mode" <option id="vm-mode-london" data-id="settingsVMLondonMode"
title="Execution environment does not connect to any node, everything is local and in memory only."
value="vm-london" name="executionContext" fork="london"> JavaScript VM (London)
</option>
<option id="injected-mode" data-id="settingsInjectedMode"
title="Execution environment has been provided by Metamask or similar provider." title="Execution environment has been provided by Metamask or similar provider."
value="injected" name="executionContext"> Injected Web3 value="injected" name="executionContext"> Injected Web3
</option> </option>
...@@ -236,11 +240,14 @@ class SettingsUI { ...@@ -236,11 +240,14 @@ class SettingsUI {
this.blockchain.event.register('removeProvider', name => removeProvider(name)) this.blockchain.event.register('removeProvider', name => removeProvider(name))
selectExEnv.addEventListener('change', (event) => { selectExEnv.addEventListener('change', (event) => {
const context = selectExEnv.options[selectExEnv.selectedIndex].value const provider = selectExEnv.options[selectExEnv.selectedIndex]
this.setExecutionContext(context) const fork = provider.getAttribute('fork') // can be undefined if connected to an external source (web3 provider / injected)
let context = provider.value
context = context.startsWith('vm') ? 'vm' : context // context has to be 'vm', 'web3' or 'injected'
this.setExecutionContext({ context, fork })
}) })
selectExEnv.value = this.blockchain.getProvider() selectExEnv.value = this._getProviderDropdownValue()
} }
setExecutionContext (context) { setExecutionContext (context) {
...@@ -278,9 +285,19 @@ class SettingsUI { ...@@ -278,9 +285,19 @@ class SettingsUI {
` `
} }
/**
* generate a value used by the env dropdown list.
* @return {String} - can return 'vm-berlin, 'vm-london', 'injected' or 'web3'
*/
_getProviderDropdownValue () {
const provider = this.blockchain.getProvider()
const fork = this.blockchain.getCurrentFork()
return provider === 'vm' ? provider + '-' + fork : provider
}
setFinalContext () { setFinalContext () {
// set the final context. Cause it is possible that this is not the one we've originaly selected // set the final context. Cause it is possible that this is not the one we've originaly selected
this.selectExEnv.value = this.blockchain.getProvider() this.selectExEnv.value = this._getProviderDropdownValue()
this.event.trigger('clearInstance', []) this.event.trigger('clearInstance', [])
this.updatePlusButton() this.updatePlusButton()
} }
......
...@@ -208,6 +208,14 @@ class Blockchain { ...@@ -208,6 +208,14 @@ class Blockchain {
return this.executionContext.getProvider() return this.executionContext.getProvider()
} }
/**
* return the fork name applied to the current envionment
* @return {String} - fork name
*/
getCurrentFork () {
return this.executionContext.getCurrentFork()
}
isWeb3Provider () { isWeb3Provider () {
const isVM = this.getProvider() === 'vm' const isVM = this.getProvider() === 'vm'
const isInjected = this.getProvider() === 'injected' const isInjected = this.getProvider() === 'injected'
......
...@@ -21,7 +21,8 @@ export class ExecutionContext { ...@@ -21,7 +21,8 @@ export class ExecutionContext {
this.executionContext = null this.executionContext = null
this.blockGasLimitDefault = 4300000 this.blockGasLimitDefault = 4300000
this.blockGasLimit = this.blockGasLimitDefault this.blockGasLimit = this.blockGasLimitDefault
this.currentFork = 'berlin' this.defaultFork = 'berlin'
this.currentFork = this.defaultFork
this.mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' this.mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'
this.customNetWorks = {} this.customNetWorks = {}
this.blocks = {} this.blocks = {}
...@@ -48,6 +49,10 @@ export class ExecutionContext { ...@@ -48,6 +49,10 @@ export class ExecutionContext {
return this.executionContext return this.executionContext
} }
getCurrentFork () {
return this.currentFork
}
isVM () { isVM () {
return this.executionContext === 'vm' return this.executionContext === 'vm'
} }
...@@ -58,7 +63,7 @@ export class ExecutionContext { ...@@ -58,7 +63,7 @@ export class ExecutionContext {
web3 () { web3 () {
if (this.customWeb3[this.executionContext]) return this.customWeb3[this.executionContext] if (this.customWeb3[this.executionContext]) return this.customWeb3[this.executionContext]
return this.isVM() ? this.vms[this.currentFork].web3vm : web3 return web3
} }
detectNetwork (callback) { detectNetwork (callback) {
...@@ -118,16 +123,21 @@ export class ExecutionContext { ...@@ -118,16 +123,21 @@ export class ExecutionContext {
this.executionContextChange(context, endPointUrl, confirmCb, infoCb, null) this.executionContextChange(context, endPointUrl, confirmCb, infoCb, null)
} }
executionContextChange (context, endPointUrl, confirmCb, infoCb, cb) { executionContextChange (value, endPointUrl, confirmCb, infoCb, cb) {
const context = value.context
const fork = value.fork || this.defaultFork
if (!cb) cb = () => {} if (!cb) cb = () => {}
if (!confirmCb) confirmCb = () => {} if (!confirmCb) confirmCb = () => {}
if (!infoCb) infoCb = () => {} if (!infoCb) infoCb = () => {}
if (context === 'vm') { if (context === 'vm') {
this.executionContext = context this.executionContext = context
this.currentFork = fork
this.event.trigger('contextChanged', ['vm']) this.event.trigger('contextChanged', ['vm'])
return cb() return cb()
} }
this.currentFork = this.defaultFork // in the case of injected and web3, we default to the last fork.
if (context === 'injected') { if (context === 'injected') {
if (injectedProvider === undefined) { if (injectedProvider === undefined) {
infoCb('No injected Web3 provider found. Make sure your provider (e.g. MetaMask) is active and running (when recently activated you may have to reload the page).') infoCb('No injected Web3 provider found. Make sure your provider (e.g. MetaMask) is active and running (when recently activated you may have to reload the page).')
...@@ -147,7 +157,7 @@ export class ExecutionContext { ...@@ -147,7 +157,7 @@ export class ExecutionContext {
} }
if (this.customNetWorks[context]) { if (this.customNetWorks[context]) {
var network = this.customNetWorks[context] var network = this.customNetWorks[context]
this.setProviderFromEndpoint(network.provider, network.name, (error) => { this.setProviderFromEndpoint(network.provider, { context: network.name }, (error) => {
if (error) infoCb(error) if (error) infoCb(error)
cb() cb()
}) })
...@@ -184,8 +194,9 @@ export class ExecutionContext { ...@@ -184,8 +194,9 @@ export class ExecutionContext {
// TODO: remove this when this function is moved // TODO: remove this when this function is moved
setProviderFromEndpoint (endpoint, context, cb) { setProviderFromEndpoint (endpoint, value, cb) {
const oldProvider = web3.currentProvider const oldProvider = web3.currentProvider
const context = value.context
web3.setProvider(endpoint) web3.setProvider(endpoint)
web3.eth.net.isListening((err, isConnected) => { web3.eth.net.isListening((err, isConnected) => {
......
...@@ -5,12 +5,6 @@ const { Provider, extend } = require('@remix-project/remix-simulator') ...@@ -5,12 +5,6 @@ const { Provider, extend } = require('@remix-project/remix-simulator')
class VMProvider { class VMProvider {
constructor (executionContext) { constructor (executionContext) {
this.executionContext = executionContext this.executionContext = executionContext
this.RemixSimulatorProvider = new Provider({})
this.RemixSimulatorProvider.init()
this.web3 = new Web3(this.RemixSimulatorProvider)
extend(this.web3)
this.accounts = {}
this.executionContext.setWeb3('vm', this.web3)
} }
getAccounts (cb) { getAccounts (cb) {
...@@ -23,8 +17,14 @@ class VMProvider { ...@@ -23,8 +17,14 @@ class VMProvider {
} }
resetEnvironment () { resetEnvironment () {
this.accounts = {}
this.RemixSimulatorProvider = new Provider({ fork: this.executionContext.getCurrentFork() })
this.RemixSimulatorProvider.init()
this.RemixSimulatorProvider.Accounts.resetAccounts() this.RemixSimulatorProvider.Accounts.resetAccounts()
this.web3 = new Web3(this.RemixSimulatorProvider)
extend(this.web3)
this.accounts = {} this.accounts = {}
this.executionContext.setWeb3('vm', this.web3)
} }
// TODO: is still here because of the plugin API // TODO: is still here because of the plugin API
......
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
} }
], ],
"dependencies": { "dependencies": {
"@ethereumjs/block": "^3.2.1", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/tx": "^3.1.3", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.3.2", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-astwalker": "^0.0.26", "@remix-project/remix-astwalker": "^0.0.26",
"@remix-project/remix-lib": "^0.5.0", "@remix-project/remix-lib": "^0.5.0",
"async": "^2.6.2", "async": "^2.6.2",
......
...@@ -34,9 +34,9 @@ ...@@ -34,9 +34,9 @@
] ]
}, },
"dependencies": { "dependencies": {
"@ethereumjs/block": "^3.2.1", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/tx": "^3.1.3", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.3.2", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-lib": "^0.5.0", "@remix-project/remix-lib": "^0.5.0",
"@types/tape": "^4.2.33", "@types/tape": "^4.2.33",
"async": "^2.6.2", "async": "^2.6.2",
......
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
], ],
"main": "src/index.js", "main": "src/index.js",
"dependencies": { "dependencies": {
"@ethereumjs/block": "^3.2.1", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/common": "^2.2.0", "@ethereumjs/common": "^2.2.0",
"@ethereumjs/tx": "^3.1.3", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.3.2", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-astwalker": "^0.0.26", "@remix-project/remix-astwalker": "^0.0.26",
"@remix-project/remix-lib": "^0.5.0", "@remix-project/remix-lib": "^0.5.0",
"async": "^2.6.2", "async": "^2.6.2",
......
...@@ -41,7 +41,7 @@ export class Ethdebugger { ...@@ -41,7 +41,7 @@ export class Ethdebugger {
this.opts = opts this.opts = opts
this.event = new EventManager() this.event = new EventManager()
this.traceManager = new TraceManager({ web3: this.web3 }) this.traceManager = new TraceManager({ web3: this.web3, fork: this.opts.fork })
this.codeManager = new CodeManager(this.traceManager) this.codeManager = new CodeManager(this.traceManager)
this.solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: this.traceManager.getCurrentCalledAddressAt.bind(this.traceManager), getCode: this.codeManager.getCode.bind(this.codeManager) }) this.solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: this.traceManager.getCurrentCalledAddressAt.bind(this.traceManager), getCode: this.codeManager.getCode.bind(this.codeManager) })
this.storageResolver = null this.storageResolver = null
...@@ -55,7 +55,7 @@ export class Ethdebugger { ...@@ -55,7 +55,7 @@ export class Ethdebugger {
} }
setManagers () { setManagers () {
this.traceManager = new TraceManager({ web3: this.web3 }) this.traceManager = new TraceManager({ web3: this.web3, fork: this.opts.fork })
this.codeManager = new CodeManager(this.traceManager) this.codeManager = new CodeManager(this.traceManager)
this.solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: this.traceManager.getCurrentCalledAddressAt.bind(this.traceManager), getCode: this.codeManager.getCode.bind(this.codeManager) }) this.solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: this.traceManager.getCurrentCalledAddressAt.bind(this.traceManager), getCode: this.codeManager.getCode.bind(this.codeManager) })
this.storageResolver = null this.storageResolver = null
......
...@@ -4,6 +4,7 @@ import { EventManager } from '../eventManager' ...@@ -4,6 +4,7 @@ import { EventManager } from '../eventManager'
import { isContractCreation } from '../trace/traceHelper' import { isContractCreation } from '../trace/traceHelper'
import { findNodeAtInstructionIndex } from '../source/sourceMappingDecoder' import { findNodeAtInstructionIndex } from '../source/sourceMappingDecoder'
import { CodeResolver } from './codeResolver' import { CodeResolver } from './codeResolver'
import { TraceManager } from '../trace/traceManager' // eslint-disable-line
/* /*
resolve contract code referenced by vmtrace in order to be used by asm listview. resolve contract code referenced by vmtrace in order to be used by asm listview.
...@@ -15,7 +16,7 @@ import { CodeResolver } from './codeResolver' ...@@ -15,7 +16,7 @@ import { CodeResolver } from './codeResolver'
export class CodeManager { export class CodeManager {
event event
isLoading: boolean isLoading: boolean
traceManager traceManager: TraceManager
codeResolver codeResolver
constructor (_traceManager) { constructor (_traceManager) {
...@@ -32,7 +33,8 @@ export class CodeManager { ...@@ -32,7 +33,8 @@ export class CodeManager {
return resolve(code) return resolve(code)
}) })
}) })
} },
fork: this.traceManager.getCurrentFork()
}) })
} }
......
...@@ -6,12 +6,14 @@ export class CodeResolver { ...@@ -6,12 +6,14 @@ export class CodeResolver {
bytecodeByAddress bytecodeByAddress
instructionsByAddress instructionsByAddress
instructionsIndexByBytesOffset instructionsIndexByBytesOffset
fork
constructor ({ getCode }) { constructor ({ getCode, fork }) {
this.getCode = getCode this.getCode = getCode
this.bytecodeByAddress = {} // bytes code by contract addesses this.bytecodeByAddress = {} // bytes code by contract addesses
this.instructionsByAddress = {} // assembly items instructions list by contract addesses this.instructionsByAddress = {} // assembly items instructions list by contract addesses
this.instructionsIndexByBytesOffset = {} // mapping between bytes offset and instructions index. this.instructionsIndexByBytesOffset = {} // mapping between bytes offset and instructions index.
this.fork = fork
} }
clear () { clear () {
...@@ -39,7 +41,7 @@ export class CodeResolver { ...@@ -39,7 +41,7 @@ export class CodeResolver {
} }
formatCode (hexCode) { formatCode (hexCode) {
const [code, instructionsIndexByBytesOffset] = nameOpCodes(Buffer.from(hexCode.substring(2), 'hex')) const [code, instructionsIndexByBytesOffset] = nameOpCodes(Buffer.from(hexCode.substring(2), 'hex'), this.fork)
return { code, instructionsIndexByBytesOffset } return { code, instructionsIndexByBytesOffset }
} }
......
'use strict' 'use strict'
import opcodes from './opcodes' import Common from '@ethereumjs/common'
import { getOpcodesForHF } from '@ethereumjs/vm/dist/evm/opcodes'
import getOpcodes from './opcodes'
export function nameOpCodes (raw, hardfork) {
const common = new Common({ chain: 'mainnet', hardfork })
const opcodes = getOpcodesForHF(common)
export function nameOpCodes (raw) {
let pushData = '' let pushData = ''
const codeMap = {} const codeMap = {}
const code = [] const code = []
for (let i = 0; i < raw.length; i++) { for (let i = 0; i < raw.length; i++) {
const pc = i const pc = i
const curOpCode = opcodes(raw[pc], false).name let curOpCode
try {
curOpCode = opcodes.get(raw[pc]).fullName
} catch (e) {
curOpCode = 'INVALID'
}
codeMap[i] = code.length codeMap[i] = code.length
// no destinations into the middle of PUSH // no destinations into the middle of PUSH
if (curOpCode.slice(0, 4) === 'PUSH') { if (curOpCode.slice(0, 4) === 'PUSH') {
...@@ -25,17 +35,35 @@ export function nameOpCodes (raw) { ...@@ -25,17 +35,35 @@ export function nameOpCodes (raw) {
return [code, codeMap] return [code, codeMap]
} }
type Opcode = {
name: String,
pushData?: Array<number>
in?: number
out?: number
}
/** /**
* Parses code as a list of integers into a list of objects containing * Parses code as a list of integers into a list of objects containing
* information about the opcode. * information about the opcode.
*/ */
export function parseCode (raw) { export function parseCode (raw) {
const common = new Common({ chain: 'mainnet', hardfork: 'berlin' })
const opcodes = getOpcodesForHF(common)
const code = [] const code = []
for (let i = 0; i < raw.length; i++) { for (let i = 0; i < raw.length; i++) {
const opcode = opcodes(raw[i], true) const opcode: Opcode = { name: 'INVALID' }
try {
const code = opcodes.get(raw[i])
const opcodeDetails = getOpcodes(raw[i], false)
opcode.in = opcodeDetails.in
opcode.out = opcodeDetails.out
opcode.name = code.fullName
} catch (e) {
opcode.name = 'INVALID'
}
if (opcode.name.slice(0, 4) === 'PUSH') { if (opcode.name.slice(0, 4) === 'PUSH') {
const length = raw[i] - 0x5f const length = raw[i] - 0x5f
opcode['pushData'] = raw.slice(i + 1, i + length + 1) opcode.pushData = raw.slice(i + 1, i + length + 1)
// in case pushdata extends beyond code // in case pushdata extends beyond code
if (i + 1 + length > raw.length) { if (i + 1 + length > raw.length) {
for (let j = opcode['pushData'].length; j < length; j++) { for (let j = opcode['pushData'].length; j < length; j++) {
...@@ -60,5 +88,5 @@ export function log (num, base) { ...@@ -60,5 +88,5 @@ export function log (num, base) {
} }
export function roundLog (num, base) { export function roundLog (num, base) {
return Math.ceil(this.log(num, base)) return Math.ceil(log(num, base))
} }
...@@ -26,7 +26,8 @@ export class Debugger { ...@@ -26,7 +26,8 @@ export class Debugger {
this.debugger = new Ethdebugger({ this.debugger = new Ethdebugger({
web3: options.web3, web3: options.web3,
debugWithGeneratedSources: options.debugWithGeneratedSources, debugWithGeneratedSources: options.debugWithGeneratedSources,
compilationResult: this.compilationResult compilationResult: this.compilationResult,
fork: options.fork
}) })
const { traceManager, callTree, solidityProxy } = this.debugger const { traceManager, callTree, solidityProxy } = this.debugger
......
...@@ -7,6 +7,7 @@ import { util } from '@remix-project/remix-lib' ...@@ -7,6 +7,7 @@ import { util } from '@remix-project/remix-lib'
export class TraceManager { export class TraceManager {
web3 web3
fork: string
isLoading: boolean isLoading: boolean
trace trace
traceCache traceCache
...@@ -16,6 +17,7 @@ export class TraceManager { ...@@ -16,6 +17,7 @@ export class TraceManager {
constructor (options) { constructor (options) {
this.web3 = options.web3 this.web3 = options.web3
this.fork = options.fork
this.isLoading = false this.isLoading = false
this.trace = null this.trace = null
this.traceCache = new TraceCache() this.traceCache = new TraceCache()
...@@ -70,6 +72,10 @@ export class TraceManager { ...@@ -70,6 +72,10 @@ export class TraceManager {
this.traceCache.init() this.traceCache.init()
} }
getCurrentFork () {
return this.fork
}
// API section // API section
inRange (step) { inRange (step) {
return this.isLoaded() && step >= 0 && step < this.trace.length return this.isLoaded() && step >= 0 && step < this.trace.length
......
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
], ],
"main": "src/index.js", "main": "src/index.js",
"dependencies": { "dependencies": {
"@ethereumjs/block": "^3.2.1", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/tx": "^3.1.3", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.3.2", "@ethereumjs/vm": "^5.4.1",
"async": "^2.1.2", "async": "^2.1.2",
"ethereumjs-util": "^7.0.10", "ethereumjs-util": "^7.0.10",
"ethers": "^4.0.40", "ethers": "^4.0.40",
......
'use strict' 'use strict'
import { Transaction } from '@ethereumjs/tx' import { Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx'
import { Block } from '@ethereumjs/block' import { Block } from '@ethereumjs/block'
import { BN, bufferToHex, Address } from 'ethereumjs-util' import { BN, bufferToHex, Address } from 'ethereumjs-util'
import { EventManager } from '../eventManager' import { EventManager } from '../eventManager'
...@@ -71,7 +71,11 @@ export class TxRunnerVM { ...@@ -71,7 +71,11 @@ export class TxRunnerVM {
} }
} }
} }
const tx = Transaction.fromTxData({
const EIP1559 = this.commonContext.hardfork() !== 'berlin'
let tx
if (!EIP1559) {
tx = Transaction.fromTxData({
nonce: new BN(res.nonce), nonce: new BN(res.nonce),
gasPrice: '0x1', gasPrice: '0x1',
gasLimit: gasLimit, gasLimit: gasLimit,
...@@ -79,6 +83,17 @@ export class TxRunnerVM { ...@@ -79,6 +83,17 @@ export class TxRunnerVM {
value: value, value: value,
data: Buffer.from(data.slice(2), 'hex') data: Buffer.from(data.slice(2), 'hex')
}, { common: this.commonContext }).sign(account.privateKey) }, { common: this.commonContext }).sign(account.privateKey)
} else {
tx = FeeMarketEIP1559Transaction.fromTxData({
nonce: new BN(res.nonce),
maxPriorityFeePerGas: '0x01',
maxFeePerGas: '0x1',
gasLimit: gasLimit,
to: to,
value: value,
data: Buffer.from(data.slice(2), 'hex')
}).sign(account.privateKey)
}
const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e'] const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e']
const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)] const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)]
...@@ -89,7 +104,8 @@ export class TxRunnerVM { ...@@ -89,7 +104,8 @@ export class TxRunnerVM {
number: self.blockNumber, number: self.blockNumber,
coinbase: coinbases[self.blockNumber % coinbases.length], coinbase: coinbases[self.blockNumber % coinbases.length],
difficulty: difficulties[self.blockNumber % difficulties.length], difficulty: difficulties[self.blockNumber % difficulties.length],
gasLimit: new BN(gasLimit.replace('0x', ''), 16).imuln(2) gasLimit: new BN(gasLimit.replace('0x', ''), 16).imuln(2),
baseFeePerGas: EIP1559 ? '0x1' : undefined
}, },
transactions: [tx] transactions: [tx]
}, { common: this.commonContext }) }, { common: this.commonContext })
......
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
], ],
"main": "src/index.js", "main": "src/index.js",
"dependencies": { "dependencies": {
"@ethereumjs/block": "^3.2.1", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/common": "^2.2.0", "@ethereumjs/common": "^2.2.0",
"@ethereumjs/tx": "^3.1.3", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.3.2", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-lib": "^0.5.0", "@remix-project/remix-lib": "^0.5.0",
"ansi-gray": "^0.1.1", "ansi-gray": "^0.1.1",
"async": "^3.1.0", "async": "^3.1.0",
......
...@@ -18,14 +18,12 @@ export class Provider { ...@@ -18,14 +18,12 @@ export class Provider {
Accounts Accounts
Transactions Transactions
methods methods
host: string
connected: boolean; connected: boolean;
constructor (host: string = 'vm', options: Record<string, unknown> = {}) { constructor (options: Record<string, unknown> = {}) {
this.options = options this.options = options
this.host = host
this.connected = true this.connected = true
this.vmContext = new VMContext() this.vmContext = new VMContext(options['fork'])
this.Accounts = new Accounts(this.vmContext) this.Accounts = new Accounts(this.vmContext)
this.Transactions = new Transactions(this.vmContext) this.Transactions = new Transactions(this.vmContext)
......
...@@ -91,24 +91,18 @@ export class VMContext { ...@@ -91,24 +91,18 @@ export class VMContext {
blocks blocks
latestBlockNumber latestBlockNumber
txs txs
vms defaultFork
currentVm
web3vm web3vm
logsManager logsManager
exeResults exeResults
constructor () { constructor (fork?) {
this.blockGasLimitDefault = 4300000 this.blockGasLimitDefault = 4300000
this.blockGasLimit = this.blockGasLimitDefault this.blockGasLimit = this.blockGasLimitDefault
this.currentFork = 'berlin' this.defaultFork = fork || 'berlin'
this.vms = { this.currentFork = this.defaultFork
/* this.currentVm = this.createVm(this.currentFork)
byzantium: createVm('byzantium'),
constantinople: createVm('constantinople'),
petersburg: createVm('petersburg'),
istanbul: createVm('istanbul'),
*/
berlin: this.createVm('berlin')
}
this.blocks = {} this.blocks = {}
this.latestBlockNumber = 0 this.latestBlockNumber = 0
this.txs = {} this.txs = {}
...@@ -122,7 +116,7 @@ export class VMContext { ...@@ -122,7 +116,7 @@ export class VMContext {
const vm = new VM({ const vm = new VM({
common, common,
activatePrecompiles: true, activatePrecompiles: true,
stateManager: stateManager, stateManager,
allowUnlimitedContractSize: true allowUnlimitedContractSize: true
}) })
...@@ -131,8 +125,12 @@ export class VMContext { ...@@ -131,8 +125,12 @@ export class VMContext {
return { vm, web3vm, stateManager, common } return { vm, web3vm, stateManager, common }
} }
getCurrentFork () {
return this.currentFork
}
web3 () { web3 () {
return this.vms[this.currentFork].web3vm return this.currentVm.web3vm
} }
blankWeb3 () { blankWeb3 () {
...@@ -140,11 +138,11 @@ export class VMContext { ...@@ -140,11 +138,11 @@ export class VMContext {
} }
vm () { vm () {
return this.vms[this.currentFork].vm return this.currentVm.vm
} }
vmObject () { vmObject () {
return this.vms[this.currentFork] return this.currentVm
} }
addBlock (block) { addBlock (block) {
......
...@@ -8,7 +8,7 @@ describe('Accounts', () => { ...@@ -8,7 +8,7 @@ describe('Accounts', () => {
before(async function () { before(async function () {
const provider = new Provider() const provider = new Provider()
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider as any)
}) })
describe('eth_getAccounts', () => { describe('eth_getAccounts', () => {
......
...@@ -6,11 +6,11 @@ import * as assert from 'assert' ...@@ -6,11 +6,11 @@ import * as assert from 'assert'
describe('blocks', () => { describe('blocks', () => {
before(async () => { before(async () => {
const provider = new Provider('vm', { const provider = new Provider({
coinbase: '0x0000000000000000000000000000000000000001' coinbase: '0x0000000000000000000000000000000000000001'
}) })
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider as any)
}) })
describe('eth_getBlockByNumber', () => { describe('eth_getBlockByNumber', () => {
......
...@@ -8,7 +8,7 @@ describe('Misc', () => { ...@@ -8,7 +8,7 @@ describe('Misc', () => {
before(async () => { before(async () => {
const provider = new Provider() const provider = new Provider()
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider as any)
}) })
describe('web3_clientVersion', () => { describe('web3_clientVersion', () => {
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
} }
], ],
"dependencies": { "dependencies": {
"@ethereumjs/block": "^3.2.1", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/tx": "^3.1.3", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.3.2", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-lib": "^0.5.0", "@remix-project/remix-lib": "^0.5.0",
"async": "^2.6.2", "async": "^2.6.2",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.0.0",
......
...@@ -35,14 +35,13 @@ ...@@ -35,14 +35,13 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-tests#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-tests#readme",
"dependencies": { "dependencies": {
"@ethereumjs/block": "^3.2.1", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/common": "^2.2.0", "@ethereumjs/common": "^2.2.0",
"@ethereumjs/tx": "^3.1.3", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.3.2", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-lib": "^0.5.0", "@remix-project/remix-lib": "^0.5.0",
"@remix-project/remix-simulator": "^0.2.0", "@remix-project/remix-simulator": "^0.2.0",
"@remix-project/remix-solidity": "^0.4.0", "@remix-project/remix-solidity": "^0.4.0",
"ansi-gray": "^0.1.1",
"async": "^2.6.0", "async": "^2.6.0",
"axios": ">=0.21.1", "axios": ">=0.21.1",
"change-case": "^3.0.1", "change-case": "^3.0.1",
......
...@@ -208,7 +208,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => { ...@@ -208,7 +208,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
} }
return null return null
}, },
debugWithGeneratedSources: state.opt.debugWithGeneratedSources debugWithGeneratedSources: state.opt.debugWithGeneratedSources,
fork: 'berlin'
}) })
debuggerInstance.debug(blockNumber, txNumber, tx, () => { debuggerInstance.debug(blockNumber, txNumber, tx, () => {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -130,10 +130,10 @@ ...@@ -130,10 +130,10 @@
}, },
"dependencies": { "dependencies": {
"@erebos/bzz-node": "^0.13.0", "@erebos/bzz-node": "^0.13.0",
"@ethereumjs/block": "^3.2.1", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/common": "^2.2.0", "@ethereumjs/common": "^2.3.1",
"@ethereumjs/tx": "^3.1.3", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.3.2", "@ethereumjs/vm": "^5.4.1",
"@remixproject/engine": "^0.3.17", "@remixproject/engine": "^0.3.17",
"@remixproject/engine-web": "^0.3.17", "@remixproject/engine-web": "^0.3.17",
"@remixproject/plugin": "^0.3.17", "@remixproject/plugin": "^0.3.17",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment