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

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

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

@ -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({})

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

Loading…
Cancel
Save