Commit b09522c2 authored by yann300's avatar yann300

reset vm state instead of creating a new instance

parent 9b65a27b
...@@ -200,6 +200,10 @@ ...@@ -200,6 +200,10 @@
width: 25%; width: 25%;
} }
.udapp .contractProperty button.debug {
width: 3%;
}
.udapp .contractProperty .call { .udapp .contractProperty .call {
background-color: #FF8B8B; background-color: #FF8B8B;
border-color: #FF8B8B; border-color: #FF8B8B;
......
...@@ -15,6 +15,7 @@ var Compiler = require('./app/compiler'); ...@@ -15,6 +15,7 @@ var Compiler = require('./app/compiler');
var ExecutionContext = require('./app/execution-context'); var ExecutionContext = require('./app/execution-context');
var Debugger = require('./app/debugger'); var Debugger = require('./app/debugger');
var FormalVerification = require('./app/formalVerification'); var FormalVerification = require('./app/formalVerification');
var EthJSVM = require('ethereumjs-vm');
// The event listener needs to be registered as early as possible, because the // The event listener needs to be registered as early as possible, because the
// parent will send the message upon the "load" event. // parent will send the message upon the "load" event.
...@@ -431,13 +432,17 @@ var run = function () { ...@@ -431,13 +432,17 @@ var run = function () {
$('#output').append($('<div/>').append($('<pre/>').text('Loading github.com/' + root + '/' + path + ' ...'))); $('#output').append($('<div/>').append($('<pre/>').text('Loading github.com/' + root + '/' + path + ' ...')));
return $.getJSON('https://api.github.com/repos/' + root + '/contents/' + path, cb); return $.getJSON('https://api.github.com/repos/' + root + '/contents/' + path, cb);
} }
var transactionDebugger = new Debugger('#debugger');
var executionContext = new ExecutionContext(); var vm = new EthJSVM(null, null, { activatePrecompiles: true, enableHomestead: true });
var transactionDebugger = new Debugger(executionContext, '#debugger'); vm.stateManager.checkpoint();
transactionDebugger.addProvider('VM', vm);
transactionDebugger.switchProvider('VM');
var executionContext = new ExecutionContext(transactionDebugger);
transactionDebugger.addProvider('EXTERNAL', executionContext.web3());
transactionDebugger.onDebugRequested = function () { transactionDebugger.onDebugRequested = function () {
selectTab($('ul#options li.debugView')); selectTab($('ul#options li.debugView'));
}; };
var renderer = new Renderer(editor, executionContext, updateFiles, transactionDebugger); var renderer = new Renderer(editor, executionContext, updateFiles, transactionDebugger, vm);
var formalVerification = new FormalVerification($('#verificationView'), renderer); var formalVerification = new FormalVerification($('#verificationView'), renderer);
var compiler = new Compiler(editor, renderer, queryParams, handleGithubCall, $('#output'), getHidingRHP, formalVerification, updateFiles); var compiler = new Compiler(editor, renderer, queryParams, handleGithubCall, $('#output'), getHidingRHP, formalVerification, updateFiles);
executionContext.setCompiler(compiler); executionContext.setCompiler(compiler);
......
var remix = require('ethereum-remix'); var remix = require('ethereum-remix');
function Debugger (executionContext, id) { function Debugger (id) {
this.el = document.querySelector(id); this.el = document.querySelector(id);
this.debugger = new remix.ui.Debugger(); this.debugger = new remix.ui.Debugger();
this.el.appendChild(this.debugger.render()); this.el.appendChild(this.debugger.render());
......
...@@ -13,7 +13,8 @@ if (typeof window.web3 !== 'undefined') { ...@@ -13,7 +13,8 @@ if (typeof window.web3 !== 'undefined') {
web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
} }
function ExecutionContext () { function ExecutionContext (_txDebugger) {
var txDebugger = _txDebugger;
var compiler; var compiler;
var executionContext = injectedProvider ? 'injected' : 'vm'; var executionContext = injectedProvider ? 'injected' : 'vm';
...@@ -59,8 +60,12 @@ function ExecutionContext () { ...@@ -59,8 +60,12 @@ function ExecutionContext () {
executionContext = ev.target.value; executionContext = ev.target.value;
if (executionContext === 'web3') { if (executionContext === 'web3') {
setProviderFromEndpoint(); setProviderFromEndpoint();
txDebugger.switchProvider('EXTERNAL');
} else if (executionContext === 'injected') { } else if (executionContext === 'injected') {
web3.setProvider(injectedProvider); web3.setProvider(injectedProvider);
txDebugger.switchProvider('EXTERNAL');
} else if (executionContext === 'vm') {
txDebugger.switchProvider('VM');
} }
} }
compiler.compile(); compiler.compile();
......
...@@ -4,7 +4,7 @@ var UniversalDApp = require('../universal-dapp.js'); ...@@ -4,7 +4,7 @@ var UniversalDApp = require('../universal-dapp.js');
var utils = require('./utils'); var utils = require('./utils');
function Renderer (editor, executionContext, updateFiles, transactionDebugger) { function Renderer (editor, executionContext, updateFiles, transactionDebugger, vm) {
var detailsOpen = {}; var detailsOpen = {};
function renderError (message, container, noAnnotations) { function renderError (message, container, noAnnotations) {
...@@ -61,6 +61,9 @@ function Renderer (editor, executionContext, updateFiles, transactionDebugger) { ...@@ -61,6 +61,9 @@ function Renderer (editor, executionContext, updateFiles, transactionDebugger) {
}); });
} }
vm.stateManager.revert(function () {
vm.stateManager.checkpoint();
});
var dapp = new UniversalDApp(udappContracts, { var dapp = new UniversalDApp(udappContracts, {
mode: executionContext.isVM() ? 'vm' : 'web3', mode: executionContext.isVM() ? 'vm' : 'web3',
web3: executionContext.web3(), web3: executionContext.web3(),
...@@ -81,7 +84,7 @@ function Renderer (editor, executionContext, updateFiles, transactionDebugger) { ...@@ -81,7 +84,7 @@ function Renderer (editor, executionContext, updateFiles, transactionDebugger) {
.append(textRow('uDApp', combined(contractName, contract['interface'], contract.bytecode), 'deploy')) .append(textRow('uDApp', combined(contractName, contract['interface'], contract.bytecode), 'deploy'))
.append(getDetails(contract, source, contractName)); .append(getDetails(contract, source, contractName));
} }
}, transactionDebugger); }, transactionDebugger, vm);
var $contractOutput = dapp.render(); var $contractOutput = dapp.render();
......
/* global prompt */ /* global prompt */
var $ = require('jquery'); var $ = require('jquery');
var EthJSVM = require('ethereumjs-vm');
var ethJSUtil = require('ethereumjs-util'); var ethJSUtil = require('ethereumjs-util');
var EthJSTX = require('ethereumjs-tx'); var EthJSTX = require('ethereumjs-tx');
var ethJSABI = require('ethereumjs-abi'); var ethJSABI = require('ethereumjs-abi');
var EthJSBlock = require('ethereumjs-block'); var EthJSBlock = require('ethereumjs-block');
var BN = ethJSUtil.BN; var BN = ethJSUtil.BN;
function UniversalDApp (contracts, options, transactionDebugger) { function UniversalDApp (contracts, options, transactionDebugger, vm) {
var self = this; var self = this;
self.options = options || {}; self.options = options || {};
...@@ -18,15 +17,13 @@ function UniversalDApp (contracts, options, transactionDebugger) { ...@@ -18,15 +17,13 @@ function UniversalDApp (contracts, options, transactionDebugger) {
self.web3 = options.web3; self.web3 = options.web3;
self.transactionDebugger = transactionDebugger; self.transactionDebugger = transactionDebugger;
transactionDebugger.addProvider('EXTERNAL', self.web3);
if (options.mode === 'vm') { if (options.mode === 'vm') {
// FIXME: use `options.vm` or `self.vm` consistently // FIXME: use `options.vm` or `self.vm` consistently
options.vm = true; options.vm = true;
self.accounts = {}; self.accounts = {};
self.vm = vm;
self.vm = new EthJSVM(null, null, { activatePrecompiles: true, enableHomestead: true });
transactionDebugger.addProvider('VM', self.vm);
self.addAccount('3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511'); self.addAccount('3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511');
self.addAccount('2ac6c190b09897cd8987869cc7b918cfea07ee82038d492abce033c75c1b1d0c'); self.addAccount('2ac6c190b09897cd8987869cc7b918cfea07ee82038d492abce033c75c1b1d0c');
} else if (options.mode !== 'web3') { } else if (options.mode !== 'web3') {
...@@ -355,7 +352,7 @@ UniversalDApp.prototype.getCallButton = function (args) { ...@@ -355,7 +352,7 @@ UniversalDApp.prototype.getCallButton = function (args) {
var getDebugTransaction = function (result) { var getDebugTransaction = function (result) {
var $debugTx = $('<div class="debugTx">'); var $debugTx = $('<div class="debugTx">');
var $button = $('<button class="debug">Debug Transaction</button>'); var $button = $('<button title="Launch Debugger" class="debug"><i class="fa fa-bug"></i></button>');
$button.click(function () { $button.click(function () {
self.transactionDebugger.debug(result); self.transactionDebugger.debug(result);
}); });
...@@ -365,7 +362,7 @@ UniversalDApp.prototype.getCallButton = function (args) { ...@@ -365,7 +362,7 @@ UniversalDApp.prototype.getCallButton = function (args) {
var getDebugCall = function (result) { var getDebugCall = function (result) {
var $debugTx = $('<div class="debugCall">'); var $debugTx = $('<div class="debugCall">');
var $button = $('<button class="debug">Debug Call</button>'); var $button = $('<button title="Launch Debugger" class="debug"><i class="fa fa-bug"></i></button>');
$button.click(function () { $button.click(function () {
self.transactionDebugger.debug(result); self.transactionDebugger.debug(result);
}); });
...@@ -666,7 +663,6 @@ UniversalDApp.prototype.runTx = function (data, args, cb) { ...@@ -666,7 +663,6 @@ UniversalDApp.prototype.runTx = function (data, args, cb) {
var tx; var tx;
if (!self.vm) { if (!self.vm) {
self.transactionDebugger.switchProvider('EXTERNAL');
tx = { tx = {
from: self.options.getAddress ? self.options.getAddress() : self.web3.eth.accounts[0], from: self.options.getAddress ? self.options.getAddress() : self.web3.eth.accounts[0],
to: to, to: to,
...@@ -699,7 +695,6 @@ UniversalDApp.prototype.runTx = function (data, args, cb) { ...@@ -699,7 +695,6 @@ UniversalDApp.prototype.runTx = function (data, args, cb) {
} }
} else { } else {
try { try {
self.transactionDebugger.switchProvider('VM');
var address = self.options.getAddress ? self.options.getAddress() : self.getAccounts()[0]; var address = self.options.getAddress ? self.options.getAddress() : self.getAccounts()[0];
var account = self.accounts[address]; var account = self.accounts[address];
tx = new EthJSTX({ tx = new EthJSTX({
...@@ -720,9 +715,7 @@ UniversalDApp.prototype.runTx = function (data, args, cb) { ...@@ -720,9 +715,7 @@ UniversalDApp.prototype.runTx = function (data, args, cb) {
uncleHeaders: [] uncleHeaders: []
}); });
self.vm.runTx({block: block, tx: tx, skipBalance: true, skipNonce: true}, function (err, result) { self.vm.runTx({block: block, tx: tx, skipBalance: true, skipNonce: true}, function (err, result) {
if (self.vm) { result.transactionHash = self.transactionDebugger.web3().releaseCurrentHash(); // used to keep track of the transaction
result.transactionHash = self.transactionDebugger.web3().releaseCurrentHash(); // used to keep track of the transaction
}
cb(err, result); cb(err, result);
}); });
} catch (e) { } catch (e) {
......
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