Merge pull request #55 from yann300/fea1

Full Storage Changes + Fix Return Value
pull/7/head
yann300 9 years ago committed by GitHub
commit a050304f9e
  1. 20
      npm-debug.log.2094563598
  2. 18
      src/BasicPanel.js
  3. 73
      src/FullStoragesChanges.js
  4. 7
      src/StoragePanel.js
  5. 2
      src/TxBrowser.js
  6. 36
      src/VmDebugger.js
  7. 4
      src/helpers/ui.js
  8. 25
      src/trace/traceAnalyser.js
  9. 16
      src/trace/traceCache.js
  10. 29
      src/trace/traceManager.js
  11. 23
      test/traceManager.js

@ -0,0 +1,20 @@
0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/nodejs', '/usr/bin/npm', 'config', 'get', 'prefix' ]
2 info using npm@3.8.6
3 info using node@v5.12.0
4 verbose exit [ 0, true ]
5 verbose stack Error: write EPIPE
5 verbose stack at exports._errnoException (util.js:893:11)
5 verbose stack at WriteWrap.afterWrite (net.js:783:14)
6 verbose cwd /home/yann/Ethereum/remix/fea1/remix
7 error Linux 3.16.0-30-generic
8 error argv "/usr/bin/nodejs" "/usr/bin/npm" "config" "get" "prefix"
9 error node v5.12.0
10 error npm v3.8.6
11 error code EPIPE
12 error errno EPIPE
13 error syscall write
14 error write EPIPE
15 error If you need help, you may report this error at:
15 error <https://github.com/npm/npm/issues>
16 verbose exit [ 1, true ]

@ -3,9 +3,11 @@ var style = require('./styles/basicStyles')
var yo = require('yo-yo')
var ui = require('./helpers/ui')
function BasicPanel (_name) {
function BasicPanel (_name, _width, _height) {
this.data
this.name = _name
this.width = _width
this.height = _height
this.view
}
@ -13,13 +15,21 @@ BasicPanel.prototype.update = function () {
yo.update(this.view, this.render())
}
BasicPanel.prototype.hide = function () {
this.view.style.display = 'none'
}
BasicPanel.prototype.show = function () {
this.view.style.display = 'block'
}
BasicPanel.prototype.render = function () {
var view = yo`<div style=${ui.formatCss(style.panel.container)}>
var view = yo`<div id='container' style=${ui.formatCss({'width': this.width}, style.panel.container)}>
<div style=${ui.formatCss(style.panel.title)}>
${this.name}
</div>
<div style=${ui.formatCss(style.panel.tableContainer)}>
<pre style=${ui.formatCss(style.panel.table, style.font)} id='basicpanel' >${this.data}</pre>
<div style=${ui.formatCss({'height': this.height}, style.panel.tableContainer)}>
<pre style=${ui.formatCss({'width': this.width}, style.panel.table, style.font)} id='basicpanel' >${this.data}</pre>
</div>
</div>`
if (!this.view) {

@ -0,0 +1,73 @@
'use strict'
var BasicPanel = require('./BasicPanel')
var yo = require('yo-yo')
function FullStoragesChanges (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.addresses = []
this.view
this.traceLength
this.basicPanel = new BasicPanel('Full Storages Changes', '1205px', '100px')
this.init()
}
FullStoragesChanges.prototype.render = function () {
var view = yo`<div id='fullstorageschangespanel' >${this.basicPanel.render()}</div>`
if (!this.view) {
this.view = view
}
return view
}
FullStoragesChanges.prototype.hide = function () {
this.view.style.display = 'none'
}
FullStoragesChanges.prototype.show = function () {
this.view.style.display = 'block'
}
FullStoragesChanges.prototype.init = function () {
var self = this
this.parent.register('newTraceLoaded', this, function (length) {
self.panels = []
self.traceManager.getAddresses(function (error, addresses) {
if (!error) {
self.addresses = addresses
self.basicPanel.data = ''
yo.update(self.view, self.render())
self.hide()
}
})
self.traceManager.getLength(function (error, length) {
if (!error) {
self.traceLength = length
}
})
})
this.parent.register('indexChanged', this, function (index) {
if (index < 0) return
if (self.parent.currentStepIndex !== index) return
if (index === self.traceLength - 1) {
var storageJSON = {}
for (var k in self.addresses) {
self.traceManager.getStorageAt(index, null, function (error, result) {
if (!error) {
storageJSON[self.addresses[k]] = result
self.basicPanel.data = JSON.stringify(storageJSON, null, '\t')
yo.update(self.view, self.render())
self.show()
}
}, self.addresses[k])
}
} else {
self.hide()
}
})
}
module.exports = FullStoragesChanges

@ -2,11 +2,13 @@
var BasicPanel = require('./BasicPanel')
var yo = require('yo-yo')
function StoragePanel (_parent, _traceManager) {
function StoragePanel (_parent, _traceManager, _address) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new BasicPanel('Storage Changes')
this.address = _address
this.init()
this.disabled = false
}
StoragePanel.prototype.render = function () {
@ -16,6 +18,7 @@ StoragePanel.prototype.render = function () {
StoragePanel.prototype.init = function () {
var self = this
this.parent.register('indexChanged', this, function (index) {
if (self.disabled) return
if (index < 0) return
if (self.parent.currentStepIndex !== index) return
@ -27,7 +30,7 @@ StoragePanel.prototype.init = function () {
self.basicPanel.data = self.formatStorage(storage)
}
self.basicPanel.update()
})
}, self.address)
})
}

@ -31,7 +31,7 @@ TxBrowser.prototype.setDefaultValues = function () {
this.to = ' - '
this.hash = ' - '
this.blockNumber = null
this.txNumber = '0xcda2b2835add61af54cf83bd076664d98d7908c6cd98d86423b3b48d8b8e51ff'
this.txNumber = '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51'
this.connectInfo = ''
this.updateWeb3Url(this.web3.currentProvider.host)
}

@ -6,6 +6,8 @@ var MemoryPanel = require('./MemoryPanel')
var CallstackPanel = require('./CallstackPanel')
var StackPanel = require('./StackPanel')
var StoragePanel = require('./StoragePanel')
var BasicPanel = require('./BasicPanel')
var FullStoragesChangesPanel = require('./FullStoragesChanges')
var yo = require('yo-yo')
var ui = require('./helpers/ui')
@ -16,6 +18,28 @@ function VmDebugger (_parent, _traceManager, _web3) {
this.memoryPanel = new MemoryPanel(_parent, _traceManager)
this.calldataPanel = new CalldataPanel(_parent, _traceManager)
this.callstackPanel = new CallstackPanel(_parent, _traceManager)
/* Return values - */
this.returnValuesPanel = new BasicPanel('Return Value', '1205px', '100px')
_parent.register('indexChanged', this.returnValuesPanel, function (index) {
var self = this
_traceManager.getReturnValue(index, function (error, returnValue) {
if (error) {
console.log(error)
self.data = ''
} else if (_parent.currentStepIndex === index) {
self.data = returnValue
}
self.update()
if (!returnValue) {
self.hide()
}
})
})
/* Return values - */
this.fullStoragesChangesPanel = new FullStoragesChangesPanel(_parent, _traceManager)
this.view
var self = this
_parent.register('newTraceLoaded', this, function () {
@ -30,7 +54,17 @@ VmDebugger.prototype.render = function () {
var view = yo`<div id='vmdebugger' style='display:none'>
<div style=${ui.formatCss(style.container)}>
<table>
<tbody>
<tbody>
<tr>
<td colspan='2'>
${this.returnValuesPanel.render()}
</td>
</tr>
<tr>
<td colspan='2'>
${this.fullStoragesChangesPanel.render()}
</td>
</tr>
<tr>
<td>
${this.asmCode.render()}

@ -37,7 +37,9 @@ module.exports = {
var ret = ''
for (var arg in arguments) {
for (var k in arguments[arg]) {
ret += k + ':' + arguments[arg][k] + ';'
if (arguments[arg][k] && ret.indexOf(k) === -1) {
ret += k + ':' + arguments[arg][k] + ';'
}
}
}
return ret

@ -16,6 +16,7 @@ TraceAnalyser.prototype.analyse = function (trace, tx, callback) {
lastCallIndex: 0
}
var callStack = [tx.to]
this.traceCache.pushCallChanges(0, 0, callStack[0])
this.traceCache.pushCallStack(0, {
callStack: callStack.slice(0)
})
@ -29,10 +30,21 @@ TraceAnalyser.prototype.analyse = function (trace, tx, callback) {
this.buildMemory(k, step)
context = this.buildDepth(k, step, tx, callStack, context)
context = this.buildStorage(k, step, context)
this.buildReturnValues(k, step)
}
callback(null, true)
}
TraceAnalyser.prototype.buildReturnValues = function (index, step) {
if (traceHelper.isReturnInstruction(step)) {
var offset = 2 * parseInt(step.stack[step.stack.length - 1], 16)
var size = 2 * parseInt(step.stack[step.stack.length - 2], 16)
var memory = this.trace[this.traceCache.memoryChanges[this.traceCache.memoryChanges.length - 1]].memory
console.log('push returnValue ' + index)
this.traceCache.pushReturnValue(index, '0x' + memory.join('').substr(offset, size))
}
}
TraceAnalyser.prototype.buildCalldata = function (index, step, tx, newContext) {
var calldata = ''
if (index === 0) {
@ -66,7 +78,7 @@ TraceAnalyser.prototype.buildMemory = function (index, step) {
}
TraceAnalyser.prototype.buildStorage = function (index, step, context) {
if (traceHelper.newContextStorage(step)) {
if (traceHelper.newContextStorage(step) && !traceHelper.isCallToPrecompiledContract(index, this.trace)) {
var calledAddress = traceHelper.resolveCalledAddress(index, this.trace)
if (calledAddress) {
context.currentStorageAddress = calledAddress
@ -85,20 +97,21 @@ TraceAnalyser.prototype.buildStorage = function (index, step, context) {
TraceAnalyser.prototype.buildDepth = function (index, step, tx, callStack, context) {
if (traceHelper.isCallInstruction(step) && !traceHelper.isCallToPrecompiledContract(index, this.trace)) {
var newAddress
if (traceHelper.isCreateInstruction(step)) {
var contractToken = traceHelper.contractCreationToken(index)
callStack.push(contractToken)
newAddress = traceHelper.contractCreationToken(index)
callStack.push(newAddress)
var lastMemoryChange = this.traceCache.memoryChanges[this.traceCache.memoryChanges.length - 1]
this.traceCache.pushContractCreationFromMemory(index, contractToken, this.trace, lastMemoryChange)
this.traceCache.pushContractCreationFromMemory(index, newAddress, this.trace, lastMemoryChange)
} else {
var newAddress = traceHelper.resolveCalledAddress(index, this.trace)
newAddress = traceHelper.resolveCalledAddress(index, this.trace)
if (newAddress) {
callStack.push(newAddress)
} else {
console.log('unable to build depth changes. ' + index + ' does not match with a CALL. depth changes will be corrupted')
}
}
this.traceCache.pushCallChanges(step, index + 1)
this.traceCache.pushCallChanges(step, index + 1, newAddress)
this.traceCache.pushCallStack(index + 1, {
callStack: callStack.slice(0)
})

@ -6,12 +6,13 @@ function TraceCache () {
TraceCache.prototype.init = function () {
// ...Changes contains index in the vmtrace of the corresponding changes
this.returnValues = {}
this.callChanges = []
this.returnChanges = []
this.calls = {}
this.callsData = {}
this.contractCreation = {}
this.steps = {}
this.addresses = []
this.callDataChanges = []
this.memoryChanges = []
@ -33,13 +34,18 @@ TraceCache.prototype.pushMemoryChanges = function (value) {
this.memoryChanges.push(value)
}
TraceCache.prototype.pushCallChanges = function (step, value) {
TraceCache.prototype.pushCallChanges = function (step, value, address) {
this.callChanges.push(value)
this.calls[value] = {
op: step.op
op: step.op,
address: address
}
}
TraceCache.prototype.pushReturnValue = function (step, value) {
this.returnValues[step] = value
}
TraceCache.prototype.pushContractCreationFromMemory = function (index, token, trace, lastMemoryChange) {
var memory = trace[lastMemoryChange].memory
var stack = trace[index].stack
@ -52,10 +58,6 @@ TraceCache.prototype.pushContractCreation = function (token, code) {
this.contractCreation[token] = code
}
TraceCache.prototype.pushReturnChanges = function (value) {
this.returnChanges.push(value)
}
TraceCache.prototype.pushCallStack = function (index, callStack) {
this.callStack[index] = callStack
}

@ -73,14 +73,16 @@ TraceManager.prototype.getLength = function (callback) {
}
}
TraceManager.prototype.getStorageAt = function (stepIndex, tx, callback) {
TraceManager.prototype.getStorageAt = function (stepIndex, tx, callback, address) {
var check = this.checkRequestedStep(stepIndex)
if (check) {
return callback(check, null)
}
var stoChange = traceHelper.findLowerBound(stepIndex, this.traceCache.storageChanges)
if (stoChange === undefined) return callback('no storage found', null)
var address = this.traceCache.sstore[stoChange].address
if (!address) {
var stoChange = traceHelper.findLowerBound(stepIndex, this.traceCache.storageChanges)
if (stoChange === undefined) return callback('no storage found', null)
address = this.traceCache.sstore[stoChange].address
}
var storage = {}
storage = this.traceCache.rebuildStorage(address, storage, stepIndex)
callback(null, storage)
@ -104,6 +106,17 @@ TraceManager.prototype.getStorageAt = function (stepIndex, tx, callback) {
*/
}
TraceManager.prototype.getAddresses = function (callback) {
var addresses = [ this.tx.to ]
for (var k in this.traceCache.calls) {
var address = this.traceCache.calls[k].address
if (address && addresses.join('').indexOf(address) === -1) {
addresses.push(address)
}
}
callback(null, addresses)
}
TraceManager.prototype.getCallDataAt = function (stepIndex, callback) {
var check = this.checkRequestedStep(stepIndex)
if (check) {
@ -203,6 +216,14 @@ TraceManager.prototype.getCurrentPC = function (stepIndex, callback) {
callback(null, this.trace[stepIndex].pc)
}
TraceManager.prototype.getReturnValue = function (stepIndex, callback) {
var check = this.checkRequestedStep(stepIndex)
if (check) {
return callback(check, null)
}
callback(null, this.traceCache.returnValues[stepIndex])
}
TraceManager.prototype.getCurrentStep = function (stepIndex, callback) {
var check = this.checkRequestedStep(stepIndex)
if (check) {

@ -297,4 +297,27 @@ tape('TraceManager', function (t) {
st.ok(result === 63)
st.end()
})
t.test('TraceManager.getAddresses', function (st) {
traceManager.getAddresses(function (error, result) {
if (error) {
st.fail(error)
} else {
st.ok(result[0] === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
st.ok(result[1] === '(Contract Creation - Step 63)')
st.end()
}
})
})
t.test('TraceManager.getReturnValue', function (st) {
traceManager.getReturnValue(108, function (error, result) {
if (error) {
st.fail(error)
} else {
st.ok(result === '0x60606040526008565b00')
st.end()
}
})
})
})

Loading…
Cancel
Save