use storageResolver

pull/7/head
yann300 8 years ago
parent 9004162563
commit 66a2bf8af4
  1. 4
      src/solidity/localDecoder.js
  2. 6
      src/solidity/stateDecoder.js
  3. 6
      src/solidity/types/ArrayType.js
  4. 8
      src/solidity/types/DynamicByteArray.js
  5. 2
      src/solidity/types/Mapping.js
  6. 9
      src/solidity/types/RefType.js
  7. 4
      src/solidity/types/StringType.js
  8. 4
      src/solidity/types/Struct.js
  9. 6
      src/solidity/types/ValueType.js
  10. 32
      src/solidity/types/util.js
  11. 11
      src/ui/SolidityLocals.js
  12. 7
      src/ui/SolidityState.js
  13. 10
      src/ui/VmDebugger.js

@ -1,6 +1,6 @@
'use strict'
function solidityLocals (vmtraceIndex, internalTreeCall, stack, memory, storage, currentSourceLocation) {
function solidityLocals (vmtraceIndex, internalTreeCall, stack, memory, storageResolver, currentSourceLocation) {
var scope = internalTreeCall.findScope(vmtraceIndex)
if (!scope) {
var error = { 'message': 'Can\'t display locals. reason: compilation result might not have been provided' }
@ -17,7 +17,7 @@ function solidityLocals (vmtraceIndex, internalTreeCall, stack, memory, storage,
name = '<' + anonymousIncr + '>'
anonymousIncr++
}
locals[name] = variable.type.decodeFromStack(variable.stackDepth, stack, memory, storage)
locals[name] = variable.type.decodeFromStack(variable.stackDepth, stack, memory, storageResolver)
}
}
return locals

@ -5,14 +5,14 @@ var decodeInfo = require('./decodeInfo')
* decode the contract state storage
*
* @param {Array} storage location - location of all state variables
* @param {Map} storageContent - storage
* @param {Object} storageResolver - resolve storage queries
* @return {Map} - decoded state variable
*/
async function decodeState (stateVars, storageContent) {
async function decodeState (stateVars, storageResolver) {
var ret = {}
for (var k in stateVars) {
var stateVar = stateVars[k]
ret[stateVar.name] = await stateVar.type.decodeFromStorage(stateVar.storagelocation, storageContent)
ret[stateVar.name] = await stateVar.type.decodeFromStorage(stateVar.storagelocation, storageResolver)
}
return ret
}

@ -24,10 +24,10 @@ class ArrayType extends RefType {
this.arraySize = arraySize
}
async decodeFromStorage (location, storageContent) {
async decodeFromStorage (location, storageResolver) {
var ret = []
var size = null
var slotValue = await util.extractHexValue(location, storageContent, this.storageBytes)
var slotValue = await util.extractHexValue(location, storageResolver, this.storageBytes)
var currentLocation = {
offset: 0,
slot: location.slot
@ -40,7 +40,7 @@ class ArrayType extends RefType {
}
var k = util.toBN(0)
for (; k.lt(size) && k.ltn(300); k.iaddn(1)) {
var item = await this.underlyingType.decodeFromStorage(currentLocation, storageContent)
var item = await this.underlyingType.decodeFromStorage(currentLocation, storageResolver)
ret.push(item)
if (this.underlyingType.storageSlots === 1 && location.offset + this.underlyingType.storageBytes <= 32) {
currentLocation.offset += this.underlyingType.storageBytes

@ -9,19 +9,19 @@ class DynamicByteArray extends RefType {
super(1, 32, 'bytes', location)
}
async decodeFromStorage (location, storageContent) {
var value = await util.extractHexValue(location, storageContent, this.storageBytes)
async decodeFromStorage (location, storageResolver) {
var value = await util.extractHexValue(location, storageResolver, this.storageBytes)
var bn = new BN(value, 16)
if (bn.testn(0)) {
var length = bn.div(new BN(2))
var dataPos = new BN(helper.sha3(location.slot).replace('0x', ''), 16)
var ret = ''
var currentSlot = await util.readFromStorage(dataPos, storageContent)
var currentSlot = await util.readFromStorage(dataPos, storageResolver)
while (length.gt(ret.length) && ret.length < 32000) {
currentSlot = currentSlot.replace('0x', '')
ret += currentSlot
dataPos = dataPos.add(new BN(1))
currentSlot = await util.readFromStorage(dataPos, storageContent)
currentSlot = await util.readFromStorage(dataPos, storageResolver)
}
return {
value: '0x' + ret.replace(/(00)+$/, ''),

@ -6,7 +6,7 @@ class Mapping extends RefType {
super(1, 32, 'mapping', 'storage')
}
async decodeFromStorage (location, storageContent) {
async decodeFromStorage (location, storageResolver) {
return {
value: '<not implemented>',
length: '0x',

@ -16,23 +16,20 @@ class RefType {
* @param {Int} stackDepth - position of the type in the stack
* @param {Array} stack - stack
* @param {String} - memory
* @param {Object} - storage
* @param {Object} - storageResolver
* @return {Object} decoded value
*/
async decodeFromStack (stackDepth, stack, memory, storage) {
async decodeFromStack (stackDepth, stack, memory, storageResolver) {
if (stack.length - 1 < stackDepth) {
return {
error: '<decoding failed - stack underflow ' + stackDepth + '>',
type: this.typeName
}
}
if (!storage) {
storage = {} // TODO this is a fallback, should manage properly locals store in storage
}
var offset = stack[stack.length - 1 - stackDepth]
if (this.isInStorage()) {
offset = util.toBN(offset)
return await this.decodeFromStorage({ offset: 0, slot: offset }, storage)
return await this.decodeFromStorage({ offset: 0, slot: offset }, storageResolver)
} else if (this.isInMemory()) {
offset = parseInt(offset, 16)
return this.decodeFromMemoryInternal(offset, memory)

@ -7,8 +7,8 @@ class StringType extends DynamicBytes {
this.typeName = 'string'
}
async decodeFromStorage (location, storageContent) {
var decoded = await super.decodeFromStorage(location, storageContent)
async decodeFromStorage (location, storageResolver) {
var decoded = await super.decodeFromStorage(location, storageResolver)
return format(decoded)
}

@ -8,14 +8,14 @@ class Struct extends RefType {
this.members = memberDetails.members
}
async decodeFromStorage (location, storageContent) {
async decodeFromStorage (location, storageResolver) {
var ret = {}
this.members.map(async (item, i) => {
var globalLocation = {
offset: location.offset + item.storagelocation.offset,
slot: util.add(location.slot, item.storagelocation.slot)
}
ret[item.name] = await item.type.decodeFromStorage(globalLocation, storageContent)
ret[item.name] = await item.type.decodeFromStorage(globalLocation, storageResolver)
})
return {
value: ret,

@ -13,11 +13,11 @@ class ValueType {
* decode the type with the @arg location from the storage
*
* @param {Object} location - containing offset and slot
* @param {Object} storageContent - storageContent (storage)
* @param {Object} storageResolver - resolve storage queries
* @return {Object} - decoded value
*/
async decodeFromStorage (location, storageContent) {
var value = await util.extractHexValue(location, storageContent, this.storageBytes)
async decodeFromStorage (location, storageResolver) {
var value = await util.extractHexValue(location, storageResolver, this.storageBytes)
return {
value: this.decodeValue(value),
type: this.typeName

@ -21,24 +21,26 @@ function decodeIntFromHex (value, byteLength, signed) {
return bigNumber.toString(10)
}
async function readFromStorage (slot, storageContent) {
var ret
function readFromStorage (slot, storageResolver) {
var hexSlot = ethutil.bufferToHex(slot)
return new Promise((resolve, reject) => {
if (storageContent[hexSlot] !== undefined) {
ret = storageContent[hexSlot].replace(/^0x/, '')
storageResolver.storageSlot(hexSlot, (error, slot) => {
if (error) {
return reject(error)
} else {
hexSlot = ethutil.bufferToHex(ethutil.setLengthLeft(slot, 32))
if (storageContent[hexSlot] !== undefined) {
ret = storageContent[hexSlot].replace(/^0x/, '')
} else {
ret = '000000000000000000000000000000000000000000000000000000000000000'
if (!slot) {
slot = {
key: slot,
value: ''
}
}
slot.value = slot.value.replace('0x', '')
if (slot.value.length < 64) {
slot.value = (new Array(64 - slot.value.length + 1).join('0')) + slot.value
}
if (ret.length < 64) {
ret = (new Array(64 - ret.length + 1).join('0')) + ret
return resolve(slot.value)
}
return resolve(ret)
})
})
}
@ -58,11 +60,11 @@ function extractHexByteSlice (slotValue, byteLength, offsetFromLSB) {
* @returns a hex encoded storage content at the given @arg location. it does not have Ox prefix but always has the full length.
*
* @param {Object} location - object containing the slot and offset of the data to extract.
* @param {Object} storageContent - full storage mapping.
* @param {Object} storageResolver - storage resolver
* @param {Int} byteLength - Length of the byte slice to extract
*/
async function extractHexValue (location, storageContent, byteLength) {
var slotvalue = await readFromStorage(location.slot, storageContent)
async function extractHexValue (location, storageResolver, byteLength) {
var slotvalue = await readFromStorage(location.slot, storageResolver)
return extractHexByteSlice(slotvalue, byteLength, location.offset)
}

@ -6,9 +6,10 @@ var yo = require('yo-yo')
class SolidityLocals {
constructor (_parent, _traceManager, internalTreeCall) {
constructor (_parent, _traceManager, _internalTreeCall, _storageResolver) {
this.parent = _parent
this.internalTreeCall = internalTreeCall
this.internalTreeCall = _internalTreeCall
this.storageResolver = _storageResolver
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Solidity Locals', {
json: true,
@ -40,12 +41,8 @@ class SolidityLocals {
var stack = result[0].value
var memory = result[1].value
try {
this.traceManager.getStorageAt(this.parent.currentStepIndex, this.parent.tx, (error, storage) => {
if (!error) {
var locals = localDecoder.solidityLocals(this.parent.currentStepIndex, this.internalTreeCall, stack, memory, storage, sourceLocation)
var locals = localDecoder.solidityLocals(this.parent.currentStepIndex, this.internalTreeCall, stack, memory, this.storageResolver, sourceLocation)
this.basicPanel.update(locals)
}
})
} catch (e) {
warningDiv.innerHTML = e.message
}

@ -4,7 +4,8 @@ var stateDecoder = require('../solidity/stateDecoder')
var solidityTypeFormatter = require('./SolidityTypeFormatter')
var yo = require('yo-yo')
function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy) {
function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy, _storageResolver) {
this.storageResolver = _storageResolver
this.parent = _parent
this.traceManager = _traceManager
this.codeManager = _codeManager
@ -42,7 +43,7 @@ SolidityState.prototype.init = function () {
return
}
self.traceManager.getStorageAt(index, this.parent.tx, function (error, storage) {
self.traceManager.getCurrentCalledAddressAt(self.parent.currentStepIndex, (error, result) => {
if (error) {
self.basicPanel.update({})
console.log(error)
@ -52,7 +53,7 @@ SolidityState.prototype.init = function () {
self.basicPanel.update({})
console.log(error)
} else {
stateDecoder.decodeState(stateVars, storage).then((result) => {
stateDecoder.decodeState(stateVars, self.storageResolver).then((result) => {
if (!result.error) {
self.basicPanel.update(result)
}

@ -10,18 +10,20 @@ var StepDetail = require('./StepDetail')
var DropdownPanel = require('./DropdownPanel')
var SolidityState = require('./SolidityState')
var SolidityLocals = require('./SolidityLocals')
var StorageResolver = require('../storage/storageResolver.js')
var yo = require('yo-yo')
function VmDebugger (_parent, _traceManager, _codeManager, _solidityProxy, _callTree) {
var storageResolver = new StorageResolver(_parent, _traceManager)
this.asmCode = new CodeListView(_parent, _codeManager)
this.stackPanel = new StackPanel(_parent, _traceManager)
this.storagePanel = new StoragePanel(_parent, _traceManager)
this.storagePanel = new StoragePanel(_parent, _traceManager, storageResolver)
this.memoryPanel = new MemoryPanel(_parent, _traceManager)
this.calldataPanel = new CalldataPanel(_parent, _traceManager)
this.callstackPanel = new CallstackPanel(_parent, _traceManager)
this.stepDetail = new StepDetail(_parent, _traceManager)
this.solidityState = new SolidityState(_parent, _traceManager, _codeManager, _solidityProxy)
this.solidityLocals = new SolidityLocals(_parent, _traceManager, _callTree)
this.solidityState = new SolidityState(_parent, _traceManager, _codeManager, _solidityProxy, storageResolver)
this.solidityLocals = new SolidityLocals(_parent, _traceManager, _callTree, storageResolver)
/* Return values - */
this.returnValuesPanel = new DropdownPanel('Return Value', {json: true})
@ -38,7 +40,7 @@ function VmDebugger (_parent, _traceManager, _codeManager, _solidityProxy, _call
})
/* Return values - */
this.fullStoragesChangesPanel = new FullStoragesChangesPanel(_parent, _traceManager)
this.fullStoragesChangesPanel = new FullStoragesChangesPanel(_parent, _traceManager, storageResolver)
this.view
var self = this

Loading…
Cancel
Save