add storageViewer

pull/7/head
yann300 8 years ago
parent 70668fa17d
commit e1aef3c87d
  1. 101
      src/storage/storageResolver.js
  2. 39
      src/storage/storageViewer.js
  3. 7
      src/ui/SolidityLocals.js
  4. 7
      src/ui/SolidityState.js
  5. 8
      src/ui/StoragePanel.js
  6. 8
      src/ui/TxBrowser.js

@ -5,7 +5,6 @@ var util = require('../helpers/global')
class StorageResolver { class StorageResolver {
constructor (_debugger, _traceManager) { constructor (_debugger, _traceManager) {
this.debugger = _debugger
this.traceManager = _traceManager this.traceManager = _traceManager
this.clear() this.clear()
_debugger.event.register('newTraceLoaded', () => { _debugger.event.register('newTraceLoaded', () => {
@ -16,20 +15,23 @@ class StorageResolver {
/** /**
* return the storage for the current context (address and vm trace index) * return the storage for the current context (address and vm trace index)
* by default now returns the range 0 => 1000 * 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} * @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value}
*/ */
storageRange (callback) { storageRange (tx, stepIndex, callback) {
storageRangeInternal(this, '0x0', 1000, callback) storageRangeInternal(this, '0x0', 1000, tx, stepIndex, callback)
} }
/** /**
* return a slot value for the current context (address and vm trace index) * 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} - * @param {Function} - callback - {key, hashedKey, value} -
*/ */
storageSlot (slot, callback) { storageSlot (slot, tx, stepIndex, callback) {
storageRangeInternal(this, slot, 100, function (error, storage) { storageRangeInternal(this, slot, 100, tx, stepIndex, function (error, storage) {
if (error) { if (error) {
callback(error) callback(error)
} else { } else {
@ -49,37 +51,6 @@ class StorageResolver {
return this.storageByAddress[address] && this.storageByAddress[address].complete 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 * clear the cache
* *
@ -94,15 +65,16 @@ class StorageResolver {
* @param {Int} index - execution step index * @param {Int} index - execution step index
* @param {String} address - contract address * @param {String} address - contract address
* @param {Map} storage - Map of the known storage * @param {Map} storage - Map of the known storage
* @param {Int} stepIndex - vm trave index
* @return {Map} - The storage resolved to the given exection point * @return {Map} - The storage resolved to the given exection point
*/ */
resolveStorage (address, storage, callback) { resolveStorage (stepIndex, address, storage, callback) {
this.traceManager.resolveStorage(this.debugger.currentStepIndex, address, storage, callback) this.traceManager.resolveStorage(stepIndex, address, storage, callback)
} }
} }
function resolveAddress (self, callback) { function resolveAddress (self, stepIndex, callback) {
self.traceManager.getCurrentCalledAddressAt(self.debugger.currentStepIndex, (error, result) => { self.traceManager.getCurrentCalledAddressAt(stepIndex, (error, result) => {
if (error) { if (error) {
callback(error) callback(error)
} else { } else {
@ -128,8 +100,8 @@ function storageRangeAtInternal (tx, address, start, maxSize, callback) {
}) })
} }
function storageRangeInternal (self, start, maxSize, callback) { function storageRangeInternal (self, start, maxSize, tx, stepIndex, callback) {
resolveAddress(self, (error, address) => { resolveAddress(self, stepIndex, (error, address) => {
if (error) { if (error) {
callback(error) callback(error)
} else { } else {
@ -140,15 +112,15 @@ function storageRangeInternal (self, start, maxSize, callback) {
callback('no storageRangeAt endpoint found') callback('no storageRangeAt endpoint found')
} else { } else {
if (self.isComplete(address)) { if (self.isComplete(address)) {
var cached = self.fromCache(address) var cached = fromCache(self, address)
self.resolveStorage(address, cached, callback) self.resolveStorage(stepIndex, address, cached, callback)
} else { } else {
storageRangeAtInternal(self.debugger.tx, address, start, maxSize, (error, storage, complete) => { storageRangeAtInternal(tx, address, start, maxSize, (error, storage, complete) => {
if (error) { if (error) {
callback(error) callback(error)
} else { } else {
self.toCache(address, storage, complete) toCache(self, address, storage, complete)
self.resolveStorage(address, storage, callback) 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 module.exports = StorageResolver

@ -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

@ -2,6 +2,7 @@
var DropdownPanel = require('./DropdownPanel') var DropdownPanel = require('./DropdownPanel')
var localDecoder = require('../solidity/localDecoder') var localDecoder = require('../solidity/localDecoder')
var solidityTypeFormatter = require('./SolidityTypeFormatter') var solidityTypeFormatter = require('./SolidityTypeFormatter')
var StorageViewer = require('../storage/storageViewer')
var yo = require('yo-yo') var yo = require('yo-yo')
class SolidityLocals { class SolidityLocals {
@ -41,7 +42,11 @@ class SolidityLocals {
var stack = result[0].value var stack = result[0].value
var memory = result[1].value var memory = result[1].value
try { 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) { if (!result.error) {
this.basicPanel.update(locals) this.basicPanel.update(locals)
} }

@ -2,6 +2,7 @@
var DropdownPanel = require('./DropdownPanel') var DropdownPanel = require('./DropdownPanel')
var stateDecoder = require('../solidity/stateDecoder') var stateDecoder = require('../solidity/stateDecoder')
var solidityTypeFormatter = require('./SolidityTypeFormatter') var solidityTypeFormatter = require('./SolidityTypeFormatter')
var StorageViewer = require('../storage/storageViewer')
var yo = require('yo-yo') var yo = require('yo-yo')
function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy, _storageResolver) { function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy, _storageResolver) {
@ -53,7 +54,11 @@ SolidityState.prototype.init = function () {
self.basicPanel.update({}) self.basicPanel.update({})
console.log(error) console.log(error)
} else { } 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) { if (!result.error) {
self.basicPanel.update(result) self.basicPanel.update(result)
} }

@ -1,5 +1,6 @@
'use strict' 'use strict'
var DropdownPanel = require('./DropdownPanel') var DropdownPanel = require('./DropdownPanel')
var StorageViewer = require('../storage/storageViewer')
var yo = require('yo-yo') var yo = require('yo-yo')
function StoragePanel (_parent, _traceManager, _storageResolver) { function StoragePanel (_parent, _traceManager, _storageResolver) {
@ -22,7 +23,12 @@ StoragePanel.prototype.init = function () {
if (index < 0) return if (index < 0) return
if (self.parent.currentStepIndex !== index) 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) { if (error) {
console.log(error) console.log(error)
self.basicPanel.update({}) self.basicPanel.update({})

@ -46,7 +46,7 @@ TxBrowser.prototype.submit = function () {
return return
} }
this.event.trigger('newTxLoading', [this.blockNumber, this.txNumber]) this.event.trigger('newTxLoading', [this.blockNumber, this.txNumber])
try { // try {
var self = this var self = this
if (this.txNumber.indexOf('0x') !== -1) { if (this.txNumber.indexOf('0x') !== -1) {
util.web3.eth.getTransaction(this.txNumber, function (error, result) { util.web3.eth.getTransaction(this.txNumber, function (error, result) {
@ -57,9 +57,9 @@ TxBrowser.prototype.submit = function () {
self.update(error, result) self.update(error, result)
}) })
} }
} catch (e) { // } catch (e) {
self.update(e.message) // self.update(e.message)
} // }
} }
TxBrowser.prototype.update = function (error, tx) { TxBrowser.prototype.update = function (error, tx) {

Loading…
Cancel
Save