Merge branch 'master' into solcUpdate

pull/7/head
Aniket 5 years ago committed by GitHub
commit fdc08a5a9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2361
      remix-debug/package-lock.json
  2. 5
      remix-debug/package.json
  3. 5
      remix-debug/test/decoder/vmCall.js
  4. 5
      remix-debug/test/vmCall.js
  5. 2081
      remix-lib/package-lock.json
  6. 9
      remix-lib/package.json
  7. 9
      remix-lib/src/code/opcodes.js
  8. 39
      remix-lib/src/execution/execution-context.js
  9. 12
      remix-lib/src/execution/txExecution.js
  10. 9
      remix-lib/src/execution/txListener.js
  11. 19
      remix-lib/src/execution/txRunner.js
  12. 8
      remix-lib/src/helpers/txResultHelper.js
  13. 11
      remix-lib/src/web3Provider/web3VmProvider.js
  14. 8
      remix-lib/test/txResultHelper.js
  15. 3116
      remix-simulator/package-lock.json
  16. 3
      remix-simulator/package.json
  17. 2
      remix-simulator/src/genesis.js
  18. 7
      remix-simulator/src/methods/txProcess.js

File diff suppressed because it is too large Load Diff

@ -19,9 +19,8 @@
"main": "./index.js", "main": "./index.js",
"dependencies": { "dependencies": {
"commander": "^2.19.0", "commander": "^2.19.0",
"ethereumjs-util": "^6.1.0", "ethereumjs-util": "^6.2.0",
"ethereumjs-vm": "3.0.0", "ethereumjs-vm": "4.1.1",
"fast-async": "^6.1.2",
"remix-lib": "0.4.15", "remix-lib": "0.4.15",
"web3": "0.20.6" "web3": "0.20.6"
}, },

@ -1,6 +1,6 @@
'use strict' 'use strict'
var utileth = require('ethereumjs-util') var utileth = require('ethereumjs-util')
var Tx = require('ethereumjs-tx') var Tx = require('ethereumjs-tx').Transaction
var Block = require('ethereumjs-block') var Block = require('ethereumjs-block')
var BN = require('ethereumjs-util').BN var BN = require('ethereumjs-util').BN
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
@ -34,8 +34,7 @@ function sendTx (vm, from, to, value, data, cb) {
Init VM / Send Transaction Init VM / Send Transaction
*/ */
function initVM (st, privateKey) { function initVM (st, privateKey) {
var utileth = require('ethereumjs-util') var VM = require('ethereumjs-vm').default
var VM = require('ethereumjs-vm')
var Web3Providers = remixLib.vm.Web3Providers var Web3Providers = remixLib.vm.Web3Providers
var address = utileth.privateToAddress(privateKey) var address = utileth.privateToAddress(privateKey)
var vm = new VM({ var vm = new VM({

@ -1,6 +1,6 @@
'use strict' 'use strict'
var utileth = require('ethereumjs-util') var utileth = require('ethereumjs-util')
var Tx = require('ethereumjs-tx') var Tx = require('ethereumjs-tx').Transaction
var Block = require('ethereumjs-block') var Block = require('ethereumjs-block')
var BN = require('ethereumjs-util').BN var BN = require('ethereumjs-util').BN
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
@ -34,8 +34,7 @@ function sendTx (vm, from, to, value, data, cb) {
Init VM / Send Transaction Init VM / Send Transaction
*/ */
function initVM (st, privateKey) { function initVM (st, privateKey) {
var utileth = require('ethereumjs-util') var VM = require('ethereumjs-vm').default
var VM = require('ethereumjs-vm')
var Web3Providers = remixLib.vm.Web3Providers var Web3Providers = remixLib.vm.Web3Providers
var address = utileth.privateToAddress(privateKey) var address = utileth.privateToAddress(privateKey)
var vm = new VM({ var vm = new VM({

File diff suppressed because it is too large Load Diff

@ -15,13 +15,12 @@
"main": "./index.js", "main": "./index.js",
"dependencies": { "dependencies": {
"async": "^2.1.2", "async": "^2.1.2",
"ethereumjs-block": "^1.6.0", "ethereumjs-block": "^2.2.1",
"ethereumjs-tx": "^1.3.3", "ethereumjs-tx": "^2.1.1",
"ethereumjs-util": "^6.1.0", "ethereumjs-util": "^6.2.0",
"ethereumjs-vm": "3.0.0", "ethereumjs-vm": "4.1.1",
"ethers": "^4.0.27", "ethers": "^4.0.27",
"events": "^3.0.0", "events": "^3.0.0",
"fast-async": "^6.1.2",
"solc": "^0.5.13", "solc": "^0.5.13",
"web3": "0.20.6" "web3": "0.20.6"
}, },

@ -2,6 +2,8 @@
var codes = { var codes = {
// 0x0 range - arithmetic ops // 0x0 range - arithmetic ops
// name, baseCost, off stack, on stack, dynamic, async // name, baseCost, off stack, on stack, dynamic, async
// @todo can be improved on basis of this: https://github.com/ethereumjs/ethereumjs-vm/blob/master/lib/evm/opcodes.ts
0x00: ['STOP', 0, 0, 0, false], 0x00: ['STOP', 0, 0, 0, false],
0x01: ['ADD', 3, 2, 1, false], 0x01: ['ADD', 3, 2, 1, false],
0x02: ['MUL', 5, 2, 1, false], 0x02: ['MUL', 5, 2, 1, false],
@ -36,7 +38,7 @@ var codes = {
// 0x30 range - closure state // 0x30 range - closure state
0x30: ['ADDRESS', 2, 0, 1, true], 0x30: ['ADDRESS', 2, 0, 1, true],
0x31: ['BALANCE', 400, 1, 1, true, true], 0x31: ['BALANCE', 700, 1, 1, true, true],
0x32: ['ORIGIN', 2, 0, 1, true], 0x32: ['ORIGIN', 2, 0, 1, true],
0x33: ['CALLER', 2, 0, 1, true], 0x33: ['CALLER', 2, 0, 1, true],
0x34: ['CALLVALUE', 2, 0, 1, true], 0x34: ['CALLVALUE', 2, 0, 1, true],
@ -50,6 +52,7 @@ var codes = {
0x3c: ['EXTCODECOPY', 700, 4, 0, true, true], 0x3c: ['EXTCODECOPY', 700, 4, 0, true, true],
0x3d: ['RETURNDATASIZE', 2, 0, 1, true], 0x3d: ['RETURNDATASIZE', 2, 0, 1, true],
0x3e: ['RETURNDATACOPY', 3, 3, 0, true], 0x3e: ['RETURNDATACOPY', 3, 3, 0, true],
0x3f: ['EXTCODEHASH', 400, 3, 0, true],
// '0x40' range - block operations // '0x40' range - block operations
0x40: ['BLOCKHASH', 20, 1, 1, true, true], 0x40: ['BLOCKHASH', 20, 1, 1, true, true],
@ -58,13 +61,15 @@ var codes = {
0x43: ['NUMBER', 2, 0, 1, true], 0x43: ['NUMBER', 2, 0, 1, true],
0x44: ['DIFFICULTY', 2, 0, 1, true], 0x44: ['DIFFICULTY', 2, 0, 1, true],
0x45: ['GASLIMIT', 2, 0, 1, true], 0x45: ['GASLIMIT', 2, 0, 1, true],
0x46: ['CHAINID', 2, 0, 1, false],
0x47: ['SELFBALANCE', 5, 0, 1, false],
// 0x50 range - 'storage' and execution // 0x50 range - 'storage' and execution
0x50: ['POP', 2, 1, 0, false], 0x50: ['POP', 2, 1, 0, false],
0x51: ['MLOAD', 3, 1, 1, false], 0x51: ['MLOAD', 3, 1, 1, false],
0x52: ['MSTORE', 3, 2, 0, false], 0x52: ['MSTORE', 3, 2, 0, false],
0x53: ['MSTORE8', 3, 2, 0, false], 0x53: ['MSTORE8', 3, 2, 0, false],
0x54: ['SLOAD', 200, 1, 1, true, true], 0x54: ['SLOAD', 800, 1, 1, true, true],
0x55: ['SSTORE', 0, 2, 0, true, true], 0x55: ['SSTORE', 0, 2, 0, true, true],
0x56: ['JUMP', 8, 1, 0, false], 0x56: ['JUMP', 8, 1, 0, false],
0x57: ['JUMPI', 10, 2, 0, false], 0x57: ['JUMPI', 10, 2, 0, false],

@ -1,28 +1,25 @@
/* global ethereum */ /* global ethereum */
'use strict' 'use strict'
var Web3 = require('web3') const Web3 = require('web3')
var EventManager = require('../eventManager') const EventManager = require('../eventManager')
var EthJSVM = require('ethereumjs-vm') const EthJSVM = require('ethereumjs-vm').default
var ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
var StateManager = require('ethereumjs-vm/dist/stateManager') const StateManager = require('ethereumjs-vm/dist/state/stateManager').default
var Web3VMProvider = require('../web3Provider/web3VmProvider') const Web3VMProvider = require('../web3Provider/web3VmProvider')
var LogsManager = require('./logsManager.js') const LogsManager = require('./logsManager.js')
var rlp = ethUtil.rlp const rlp = ethUtil.rlp
var injectedProvider
var web3
if (typeof window !== 'undefined' && typeof window.web3 !== 'undefined') { if (typeof window !== 'undefined' && typeof window.web3 !== 'undefined') {
injectedProvider = window.web3.currentProvider var injectedProvider = window.web3.currentProvider
web3 = new Web3(injectedProvider) var web3 = new Web3(injectedProvider)
} else { } else {
web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')) web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
} }
var blankWeb3 = new Web3() const blankWeb3 = new Web3()
const currentFork = 'istanbul'
/* /*
extend vm state manager and instanciate VM extend vm state manager and instanciate VM
*/ */
@ -95,7 +92,9 @@ function createVm (hardfork) {
var vms = { var vms = {
byzantium: createVm('byzantium'), byzantium: createVm('byzantium'),
constantinople: createVm('constantinople') constantinople: createVm('constantinople'),
petersburg: createVm('petersburg'),
istanbul: createVm('istanbul')
} }
var mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' var mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'
@ -141,7 +140,7 @@ function ExecutionContext () {
} }
this.web3 = function () { this.web3 = function () {
return this.isVM() ? vms.constantinople.web3vm : web3 return this.isVM() ? vms[currentFork].web3vm : web3
} }
this.detectNetwork = function (callback) { this.detectNetwork = function (callback) {
@ -196,7 +195,7 @@ function ExecutionContext () {
} }
this.vm = function () { this.vm = function () {
return vms.constantinople.vm return vms[currentFork].vm
} }
this.setContext = function (context, endPointUrl, confirmCb, infoCb) { this.setContext = function (context, endPointUrl, confirmCb, infoCb) {
@ -209,8 +208,8 @@ function ExecutionContext () {
if (context === 'vm') { if (context === 'vm') {
executionContext = context executionContext = context
vms.constantinople.stateManager.revert(() => { vms[currentFork].stateManager.revert(() => {
vms.constantinople.stateManager.checkpoint(() => {}) vms[currentFork].stateManager.checkpoint(() => {})
}) })
self.event.trigger('contextChanged', ['vm']) self.event.trigger('contextChanged', ['vm'])
return cb() return cb()

@ -64,16 +64,20 @@ module.exports = {
INVALID_JUMP: 'invalid JUMP', INVALID_JUMP: 'invalid JUMP',
INVALID_OPCODE: 'invalid opcode', INVALID_OPCODE: 'invalid opcode',
REVERT: 'revert', REVERT: 'revert',
STATIC_STATE_CHANGE: 'static state change' STATIC_STATE_CHANGE: 'static state change',
INTERNAL_ERROR: 'internal error',
CREATE_COLLISION: 'create collision',
STOP: 'stop',
REFUND_EXHAUSTED: 'refund exhausted'
} }
var ret = { var ret = {
error: false, error: false,
message: '' message: ''
} }
if (!txResult.result.vm.exceptionError) { if (!txResult.result.execResult.exceptionError) {
return ret return ret
} }
var exceptionError = txResult.result.vm.exceptionError.error || '' var exceptionError = txResult.result.execResult.exceptionError.error || ''
var error = `VM error: ${exceptionError}.\n` var error = `VM error: ${exceptionError}.\n`
var msg var msg
if (exceptionError === errorCode.INVALID_OPCODE) { if (exceptionError === errorCode.INVALID_OPCODE) {
@ -83,7 +87,7 @@ module.exports = {
msg = `\tThe transaction ran out of gas. Please increase the Gas Limit.\n` msg = `\tThe transaction ran out of gas. Please increase the Gas Limit.\n`
ret.error = true ret.error = true
} else if (exceptionError === errorCode.REVERT) { } else if (exceptionError === errorCode.REVERT) {
var returnData = txResult.result.vm.return var returnData = txResult.result.execResult.returnValue
// It is the hash of Error(string) // It is the hash of Error(string)
if (returnData && (returnData.slice(0, 4).toString('hex') === '08c379a0')) { if (returnData && (returnData.slice(0, 4).toString('hex') === '08c379a0')) {
var abiCoder = new ethers.utils.AbiCoder() var abiCoder = new ethers.utils.AbiCoder()

@ -40,14 +40,13 @@ class TxListener {
// in web3 mode && listen remix txs only // in web3 mode && listen remix txs only
if (!this._isListening) return // we don't listen if (!this._isListening) return // we don't listen
if (this._loopId && executionContext.getProvider() !== 'vm') return // we seems to already listen on a "web3" network if (this._loopId && executionContext.getProvider() !== 'vm') return // we seems to already listen on a "web3" network
var call = { var call = {
from: from, from: from,
to: to, to: to,
input: data, input: data,
hash: txResult.transactionHash ? txResult.transactionHash : 'call' + (from || '') + to + data, hash: txResult.transactionHash ? txResult.transactionHash : 'call' + (from || '') + to + data,
isCall: true, isCall: true,
returnValue: executionContext.isVM() ? txResult.result.vm.return : ethJSUtil.toBuffer(txResult.result), returnValue: executionContext.isVM() ? txResult.result.execResult.returnValue : ethJSUtil.toBuffer(txResult.result),
envMode: executionContext.getProvider() envMode: executionContext.getProvider()
} }
@ -80,9 +79,9 @@ class TxListener {
function addExecutionCosts (txResult, tx) { function addExecutionCosts (txResult, tx) {
if (txResult && txResult.result) { if (txResult && txResult.result) {
if (txResult.result.vm) { if (txResult.result.execResult) {
tx.returnValue = txResult.result.vm.return tx.returnValue = txResult.result.execResult.returnValue
if (txResult.result.vm.gasUsed) tx.executionCost = txResult.result.vm.gasUsed.toString(10) if (txResult.result.execResult.gasUsed) tx.executionCost = txResult.result.execResult.gasUsed.toString(10)
} }
if (txResult.result.gasUsed) tx.transactionCost = txResult.result.gasUsed.toString(10) if (txResult.result.gasUsed) tx.transactionCost = txResult.result.gasUsed.toString(10)
} }

@ -1,5 +1,5 @@
'use strict' 'use strict'
var EthJSTX = require('ethereumjs-tx') var EthJSTX = require('ethereumjs-tx').Transaction
var EthJSBlock = require('ethereumjs-block') var EthJSBlock = require('ethereumjs-block')
var ethJSUtil = require('ethereumjs-util') var ethJSUtil = require('ethereumjs-util')
var BN = ethJSUtil.BN var BN = ethJSUtil.BN
@ -115,7 +115,6 @@ class TxRunner {
data: Buffer.from(data.slice(2), 'hex') data: Buffer.from(data.slice(2), 'hex')
}) })
tx.sign(account.privateKey) tx.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)]
var block = new EthJSBlock({ var block = new EthJSBlock({
@ -146,24 +145,20 @@ class TxRunner {
} }
runBlockInVm (tx, block, callback) { runBlockInVm (tx, block, callback) {
executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }, function (err, results) { executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then(function (results) {
err = err ? err.message : err
if (err) {
return callback(err)
}
let result = results.results[0] let result = results.results[0]
if (result) { if (result) {
result.status = '0x' + result.vm.exception.toString(16) const status = result.execResult.exceptionError ? 0 : 1
result.status = `0x${status}`
} }
executionContext.addBlock(block) executionContext.addBlock(block)
executionContext.trackTx('0x' + tx.hash().toString('hex'), block) executionContext.trackTx('0x' + tx.hash().toString('hex'), block)
callback(null, {
callback(err, {
result: result, result: result,
transactionHash: ethJSUtil.bufferToHex(Buffer.from(tx.hash())) transactionHash: ethJSUtil.bufferToHex(Buffer.from(tx.hash()))
}) })
}).catch(function (err) {
callback(err)
}) })
} }

@ -21,14 +21,14 @@ function convertToPrefixedHex (input) {
*/ */
function resultToRemixTx (txResult) { function resultToRemixTx (txResult) {
const { result, transactionHash } = txResult const { result, transactionHash } = txResult
const { status, vm, gasUsed, createdAddress, contractAddress } = result const { status, execResult, gasUsed, createdAddress, contractAddress } = result
let returnValue, errorMessage let returnValue, errorMessage
if (isHexString(result)) { if (isHexString(result)) {
returnValue = result returnValue = result
} else if (vm !== undefined) { } else if (execResult !== undefined) {
returnValue = vm.return returnValue = execResult.returnValue
errorMessage = vm.exceptionError errorMessage = execResult.exceptionError
} }
return { return {

@ -107,8 +107,8 @@ web3VmProvider.prototype.txProcessed = function (self, data) {
self.vmTraces[self.processingHash].gas = '0x' + data.gasUsed.toString(16) self.vmTraces[self.processingHash].gas = '0x' + data.gasUsed.toString(16)
var logs = [] var logs = []
for (var l in data.vm.logs) { for (var l in data.execResult.logs) {
var log = data.vm.logs[l] var log = data.execResult.logs[l]
var topics = [] var topics = []
if (log[1].length > 0) { if (log[1].length > 0) {
for (var k in log[1]) { for (var k in log[1]) {
@ -126,14 +126,15 @@ web3VmProvider.prototype.txProcessed = function (self, data) {
} }
self.txsReceipt[self.processingHash].logs = logs self.txsReceipt[self.processingHash].logs = logs
self.txsReceipt[self.processingHash].transactionHash = self.processingHash self.txsReceipt[self.processingHash].transactionHash = self.processingHash
self.txsReceipt[self.processingHash].status = '0x' + data.vm.exception.toString(16) const status = data.execResult.exceptionError ? 0 : 1
self.txsReceipt[self.processingHash].status = `0x${status}`
if (data.createdAddress) { if (data.createdAddress) {
var address = util.hexConvert(data.createdAddress) var address = util.hexConvert(data.createdAddress)
self.vmTraces[self.processingHash].return = address self.vmTraces[self.processingHash].return = address
self.txsReceipt[self.processingHash].contractAddress = address self.txsReceipt[self.processingHash].contractAddress = address
} else if (data.vm.return) { } else if (data.execResult.returnValue) {
self.vmTraces[self.processingHash].return = util.hexConvert(data.vm.return) self.vmTraces[self.processingHash].return = util.hexConvert(data.execResult.returnValue)
} else { } else {
self.vmTraces[self.processingHash].return = '0x' self.vmTraces[self.processingHash].return = '0x'
} }

@ -46,12 +46,11 @@ const VM_RESULT = {
gasRefund: new BN(0), gasRefund: new BN(0),
gasUsed: new BN(GAS_USED_INT), gasUsed: new BN(GAS_USED_INT),
status: STATUS_OK, status: STATUS_OK,
vm: { execResult: {
exception: 1,
exceptionError: null, exceptionError: null,
gasRefund: new BN(0), gasRefund: new BN(0),
gasUsed: new BN(GAS_USED_INT), gasUsed: new BN(GAS_USED_INT),
return: RETURN_VALUE_BUFFER returnValue: RETURN_VALUE_BUFFER
} }
}, },
transactionHash: TRANSACTION_HASH transactionHash: TRANSACTION_HASH
@ -103,8 +102,7 @@ tape('converts VM result to RemixTx', function (t) {
t.equal(remixTx.return, RETURN_VALUE_HEX) t.equal(remixTx.return, RETURN_VALUE_HEX)
t.equal(remixTx.error, null) t.equal(remixTx.error, null)
txResult.result.vm.exception = 0 txResult.result.execResult.exceptionError = 'this is an error'
txResult.result.vm.exceptionError = 'this is an error'
remixTx = resultToRemixTx(txResult) remixTx = resultToRemixTx(txResult)
t.equal(remixTx.error, 'this is an error') t.equal(remixTx.error, 'this is an error')

File diff suppressed because it is too large Load Diff

@ -21,10 +21,9 @@
"commander": "^2.19.0", "commander": "^2.19.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"ethereumjs-util": "^6.1.0", "ethereumjs-util": "^6.1.0",
"ethereumjs-vm": "3.0.0", "ethereumjs-block": "^2.2.1",
"express": "^4.16.3", "express": "^4.16.3",
"express-ws": "^4.0.0", "express-ws": "^4.0.0",
"fast-async": "^6.3.7",
"merge": "^1.2.0", "merge": "^1.2.0",
"remix-lib": "0.4.15", "remix-lib": "0.4.15",
"standard": "^10.0.3", "standard": "^10.0.3",

@ -17,7 +17,7 @@ function generateBlock () {
uncleHeaders: [] uncleHeaders: []
}) })
executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }, function () { executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then(function () {
executionContext.addBlock(block) executionContext.addBlock(block)
}) })
} }

@ -8,11 +8,8 @@ function runCall (payload, from, to, data, value, gasLimit, txRunner, callbacks,
if (err) { if (err) {
return callback(err) return callback(err)
} }
const returnValue = result.result.execResult.returnValue.toString('hex')
let toReturn = '0x' + result.result.vm.return.toString('hex') const toReturn = `0x${returnValue || '0'}`
if (toReturn === '0x') {
toReturn = '0x0'
}
return callback(null, toReturn) return callback(null, toReturn)
} }

Loading…
Cancel
Save