diff --git a/src/storage/storageResolver.js b/src/storage/storageResolver.js index a0d5b5a817..8a81c84afc 100644 --- a/src/storage/storageResolver.js +++ b/src/storage/storageResolver.js @@ -5,7 +5,6 @@ var util = require('../helpers/global') class StorageResolver { constructor (_debugger, _traceManager) { - this.debugger = _debugger this.traceManager = _traceManager this.clear() _debugger.event.register('newTraceLoaded', () => { @@ -16,20 +15,23 @@ class StorageResolver { /** * return the storage for the current context (address and vm trace index) * by default now returns the range 0 => 1000 - * + * @param {Object} - tx - transaction + * @param {Int} - stepIndex - Index of the stop in the vm trace * @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value} */ - storageRange (callback) { - storageRangeInternal(this, '0x0', 1000, callback) + storageRange (tx, stepIndex, callback) { + storageRangeInternal(this, '0x0', 1000, tx, stepIndex, callback) } /** * return a slot value for the current context (address and vm trace index) - * + * @param {String} - slot - slot key + * @param {Object} - tx - transaction + * @param {Int} - stepIndex - Index of the stop in the vm trace * @param {Function} - callback - {key, hashedKey, value} - */ - storageSlot (slot, callback) { - storageRangeInternal(this, slot, 100, function (error, storage) { + storageSlot (slot, tx, stepIndex, callback) { + storageRangeInternal(this, slot, 100, tx, stepIndex, function (error, storage) { if (error) { callback(error) } else { @@ -49,37 +51,6 @@ class StorageResolver { return this.storageByAddress[address] && this.storageByAddress[address].complete } - /** - * retrieve the storage from the cache. if @arg slot is defined, return only the desired slot, if not return the entire known storage - * - * @param {String} address - contract address - * @param {String} slotKey - key of the value to return - * @return {String} - either the entire known storage or a single value - */ - fromCache (address, slotKey) { - if (!this.storageByAddress[address]) { - return null - } - return slotKey ? this.storageByAddress[address].storage[slotKey] : this.storageByAddress[address].storage - } - - /** - * store the result of `storageRangeAtInternal` - * - * @param {String} address - contract address - * @param {Object} storage - result of `storageRangeAtInternal`, contains {key, hashedKey, value} - * @param {Bool} complete - True if the storage is complete - */ - toCache (address, storage, complete) { - if (!this.storageByAddress[address]) { - this.storageByAddress[address] = {} - } - this.storageByAddress[address].storage = Object.assign(this.storageByAddress[address].storage || {}, storage) - if (complete !== undefined) { - this.storageByAddress[address].complete = complete - } - } - /** * clear the cache * @@ -94,15 +65,16 @@ class StorageResolver { * @param {Int} index - execution step index * @param {String} address - contract address * @param {Map} storage - Map of the known storage + * @param {Int} stepIndex - vm trave index * @return {Map} - The storage resolved to the given exection point */ - resolveStorage (address, storage, callback) { - this.traceManager.resolveStorage(this.debugger.currentStepIndex, address, storage, callback) + resolveStorage (stepIndex, address, storage, callback) { + this.traceManager.resolveStorage(stepIndex, address, storage, callback) } } -function resolveAddress (self, callback) { - self.traceManager.getCurrentCalledAddressAt(self.debugger.currentStepIndex, (error, result) => { +function resolveAddress (self, stepIndex, callback) { + self.traceManager.getCurrentCalledAddressAt(stepIndex, (error, result) => { if (error) { callback(error) } else { @@ -128,8 +100,8 @@ function storageRangeAtInternal (tx, address, start, maxSize, callback) { }) } -function storageRangeInternal (self, start, maxSize, callback) { - resolveAddress(self, (error, address) => { +function storageRangeInternal (self, start, maxSize, tx, stepIndex, callback) { + resolveAddress(self, stepIndex, (error, address) => { if (error) { callback(error) } else { @@ -140,15 +112,15 @@ function storageRangeInternal (self, start, maxSize, callback) { callback('no storageRangeAt endpoint found') } else { if (self.isComplete(address)) { - var cached = self.fromCache(address) - self.resolveStorage(address, cached, callback) + var cached = fromCache(self, address) + self.resolveStorage(stepIndex, address, cached, callback) } else { - storageRangeAtInternal(self.debugger.tx, address, start, maxSize, (error, storage, complete) => { + storageRangeAtInternal(tx, address, start, maxSize, (error, storage, complete) => { if (error) { callback(error) } else { - self.toCache(address, storage, complete) - self.resolveStorage(address, storage, callback) + toCache(self, address, storage, complete) + self.resolveStorage(stepIndex, address, storage, callback) } }) } @@ -158,4 +130,35 @@ function storageRangeInternal (self, start, maxSize, callback) { }) } +/** + * retrieve the storage from the cache. if @arg slot is defined, return only the desired slot, if not return the entire known storage + * + * @param {String} address - contract address + * @param {String} slotKey - key of the value to return + * @return {String} - either the entire known storage or a single value + */ +function fromCache (self, address, slotKey) { + if (!self.storageByAddress[address]) { + return null + } + return slotKey ? self.storageByAddress[address].storage[slotKey] : self.storageByAddress[address].storage +} + +/** + * store the result of `storageRangeAtInternal` + * + * @param {String} address - contract address + * @param {Object} storage - result of `storageRangeAtInternal`, contains {key, hashedKey, value} + * @param {Bool} complete - True if the storage is complete + */ +function toCache (self, address, storage, complete) { + if (!self.storageByAddress[address]) { + self.storageByAddress[address] = {} + } + self.storageByAddress[address].storage = Object.assign(self.storageByAddress[address].storage || {}, storage) + if (complete !== undefined) { + self.storageByAddress[address].complete = complete + } +} + module.exports = StorageResolver diff --git a/src/storage/storageViewer.js b/src/storage/storageViewer.js new file mode 100644 index 0000000000..f041c5300d --- /dev/null +++ b/src/storage/storageViewer.js @@ -0,0 +1,39 @@ +'use strict' + +class StorageViewer { + constructor (_context, _storageResolver) { + this.context = _context + this.storageResolver = _storageResolver + } + + /** + * return the storage for the current context (address and vm trace index) + * by default now returns the range 0 => 1000 + * + * @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value} + */ + storageRange (callback) { + this.storageResolver.storageRange(this.context.tx, this.context.stepIndex, callback) + } + + /** + * return a slot value for the current context (address and vm trace index) + * + * @param {Function} - callback - {key, hashedKey, value} - + */ + storageSlot (slot, callback) { + this.storageResolver.storageSlot(slot, this.context.tx, this.context.stepIndex, callback) + } + + /** + * return True if the storage at @arg address is complete + * + * @param {String} address - contract address + * @return {Bool} - return True if the storage at @arg address is complete + */ + isComplete (address) { + return this.storageResolver.storageRange(address) + } +} + +module.exports = StorageViewer diff --git a/src/ui/SolidityLocals.js b/src/ui/SolidityLocals.js index 70082566bf..a0606444ec 100644 --- a/src/ui/SolidityLocals.js +++ b/src/ui/SolidityLocals.js @@ -2,6 +2,7 @@ var DropdownPanel = require('./DropdownPanel') var localDecoder = require('../solidity/localDecoder') var solidityTypeFormatter = require('./SolidityTypeFormatter') +var StorageViewer = require('../storage/storageViewer') var yo = require('yo-yo') class SolidityLocals { @@ -41,7 +42,11 @@ class SolidityLocals { var stack = result[0].value var memory = result[1].value try { - localDecoder.solidityLocals(this.parent.currentStepIndex, this.internalTreeCall, stack, memory, this.storageResolver, sourceLocation).then((locals) => { + var storageViewer = new StorageViewer({ + stepIndex: this.parent.currentStepIndex, + tx: this.parent.tx + }, this.storageResolver) + localDecoder.solidityLocals(this.parent.currentStepIndex, this.internalTreeCall, stack, memory, storageViewer, sourceLocation).then((locals) => { if (!result.error) { this.basicPanel.update(locals) } diff --git a/src/ui/SolidityState.js b/src/ui/SolidityState.js index 8b95a97547..866d14ddec 100644 --- a/src/ui/SolidityState.js +++ b/src/ui/SolidityState.js @@ -2,6 +2,7 @@ var DropdownPanel = require('./DropdownPanel') var stateDecoder = require('../solidity/stateDecoder') var solidityTypeFormatter = require('./SolidityTypeFormatter') +var StorageViewer = require('../storage/storageViewer') var yo = require('yo-yo') function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy, _storageResolver) { @@ -53,7 +54,11 @@ SolidityState.prototype.init = function () { self.basicPanel.update({}) console.log(error) } else { - stateDecoder.decodeState(stateVars, self.storageResolver).then((result) => { + var storageViewer = new StorageViewer({ + stepIndex: self.parent.currentStepIndex, + tx: self.parent.tx + }, self.storageResolver) + stateDecoder.decodeState(stateVars, storageViewer).then((result) => { if (!result.error) { self.basicPanel.update(result) } diff --git a/src/ui/StoragePanel.js b/src/ui/StoragePanel.js index 67cd24e623..672b92f43e 100644 --- a/src/ui/StoragePanel.js +++ b/src/ui/StoragePanel.js @@ -1,5 +1,6 @@ 'use strict' var DropdownPanel = require('./DropdownPanel') +var StorageViewer = require('../storage/storageViewer') var yo = require('yo-yo') function StoragePanel (_parent, _traceManager, _storageResolver) { @@ -22,7 +23,12 @@ StoragePanel.prototype.init = function () { if (index < 0) return if (self.parent.currentStepIndex !== index) return - self.storageResolver.storageRange((error, storage) => { + var storageViewer = new StorageViewer({ + stepIndex: this.parent.currentStepIndex, + tx: this.parent.tx + }, this.storageResolver) + + storageViewer.storageRange((error, storage) => { if (error) { console.log(error) self.basicPanel.update({}) diff --git a/src/ui/TxBrowser.js b/src/ui/TxBrowser.js index a9a2798a29..b7610ad3a5 100644 --- a/src/ui/TxBrowser.js +++ b/src/ui/TxBrowser.js @@ -46,7 +46,7 @@ TxBrowser.prototype.submit = function () { return } this.event.trigger('newTxLoading', [this.blockNumber, this.txNumber]) - try { + // try { var self = this if (this.txNumber.indexOf('0x') !== -1) { util.web3.eth.getTransaction(this.txNumber, function (error, result) { @@ -57,9 +57,9 @@ TxBrowser.prototype.submit = function () { self.update(error, result) }) } - } catch (e) { - self.update(e.message) - } + // } catch (e) { + // self.update(e.message) + // } } TxBrowser.prototype.update = function (error, tx) {