Commit a050304f authored by yann300's avatar yann300 Committed by GitHub

Merge pull request #55 from yann300/fea1

Full Storage Changes + Fix Return Value
parents a91d8c3e 41ed3e48
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') ...@@ -3,9 +3,11 @@ var style = require('./styles/basicStyles')
var yo = require('yo-yo') var yo = require('yo-yo')
var ui = require('./helpers/ui') var ui = require('./helpers/ui')
function BasicPanel (_name) { function BasicPanel (_name, _width, _height) {
this.data this.data
this.name = _name this.name = _name
this.width = _width
this.height = _height
this.view this.view
} }
...@@ -13,13 +15,21 @@ BasicPanel.prototype.update = function () { ...@@ -13,13 +15,21 @@ BasicPanel.prototype.update = function () {
yo.update(this.view, this.render()) 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 () { 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)}> <div style=${ui.formatCss(style.panel.title)}>
${this.name} ${this.name}
</div> </div>
<div style=${ui.formatCss(style.panel.tableContainer)}> <div style=${ui.formatCss({'height': this.height}, style.panel.tableContainer)}>
<pre style=${ui.formatCss(style.panel.table, style.font)} id='basicpanel' >${this.data}</pre> <pre style=${ui.formatCss({'width': this.width}, style.panel.table, style.font)} id='basicpanel' >${this.data}</pre>
</div> </div>
</div>` </div>`
if (!this.view) { if (!this.view) {
......
'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 @@ ...@@ -2,11 +2,13 @@
var BasicPanel = require('./BasicPanel') var BasicPanel = require('./BasicPanel')
var yo = require('yo-yo') var yo = require('yo-yo')
function StoragePanel (_parent, _traceManager) { function StoragePanel (_parent, _traceManager, _address) {
this.parent = _parent this.parent = _parent
this.traceManager = _traceManager this.traceManager = _traceManager
this.basicPanel = new BasicPanel('Storage Changes') this.basicPanel = new BasicPanel('Storage Changes')
this.address = _address
this.init() this.init()
this.disabled = false
} }
StoragePanel.prototype.render = function () { StoragePanel.prototype.render = function () {
...@@ -16,6 +18,7 @@ StoragePanel.prototype.render = function () { ...@@ -16,6 +18,7 @@ StoragePanel.prototype.render = function () {
StoragePanel.prototype.init = function () { StoragePanel.prototype.init = function () {
var self = this var self = this
this.parent.register('indexChanged', this, function (index) { this.parent.register('indexChanged', this, function (index) {
if (self.disabled) return
if (index < 0) return if (index < 0) return
if (self.parent.currentStepIndex !== index) return if (self.parent.currentStepIndex !== index) return
...@@ -27,7 +30,7 @@ StoragePanel.prototype.init = function () { ...@@ -27,7 +30,7 @@ StoragePanel.prototype.init = function () {
self.basicPanel.data = self.formatStorage(storage) self.basicPanel.data = self.formatStorage(storage)
} }
self.basicPanel.update() self.basicPanel.update()
}) }, self.address)
}) })
} }
......
...@@ -31,7 +31,7 @@ TxBrowser.prototype.setDefaultValues = function () { ...@@ -31,7 +31,7 @@ TxBrowser.prototype.setDefaultValues = function () {
this.to = ' - ' this.to = ' - '
this.hash = ' - ' this.hash = ' - '
this.blockNumber = null this.blockNumber = null
this.txNumber = '0xcda2b2835add61af54cf83bd076664d98d7908c6cd98d86423b3b48d8b8e51ff' this.txNumber = '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51'
this.connectInfo = '' this.connectInfo = ''
this.updateWeb3Url(this.web3.currentProvider.host) this.updateWeb3Url(this.web3.currentProvider.host)
} }
......
...@@ -6,6 +6,8 @@ var MemoryPanel = require('./MemoryPanel') ...@@ -6,6 +6,8 @@ var MemoryPanel = require('./MemoryPanel')
var CallstackPanel = require('./CallstackPanel') var CallstackPanel = require('./CallstackPanel')
var StackPanel = require('./StackPanel') var StackPanel = require('./StackPanel')
var StoragePanel = require('./StoragePanel') var StoragePanel = require('./StoragePanel')
var BasicPanel = require('./BasicPanel')
var FullStoragesChangesPanel = require('./FullStoragesChanges')
var yo = require('yo-yo') var yo = require('yo-yo')
var ui = require('./helpers/ui') var ui = require('./helpers/ui')
...@@ -16,6 +18,28 @@ function VmDebugger (_parent, _traceManager, _web3) { ...@@ -16,6 +18,28 @@ function VmDebugger (_parent, _traceManager, _web3) {
this.memoryPanel = new MemoryPanel(_parent, _traceManager) this.memoryPanel = new MemoryPanel(_parent, _traceManager)
this.calldataPanel = new CalldataPanel(_parent, _traceManager) this.calldataPanel = new CalldataPanel(_parent, _traceManager)
this.callstackPanel = new CallstackPanel(_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 this.view
var self = this var self = this
_parent.register('newTraceLoaded', this, function () { _parent.register('newTraceLoaded', this, function () {
...@@ -30,7 +54,17 @@ VmDebugger.prototype.render = function () { ...@@ -30,7 +54,17 @@ VmDebugger.prototype.render = function () {
var view = yo`<div id='vmdebugger' style='display:none'> var view = yo`<div id='vmdebugger' style='display:none'>
<div style=${ui.formatCss(style.container)}> <div style=${ui.formatCss(style.container)}>
<table> <table>
<tbody> <tbody>
<tr>
<td colspan='2'>
${this.returnValuesPanel.render()}
</td>
</tr>
<tr>
<td colspan='2'>
${this.fullStoragesChangesPanel.render()}
</td>
</tr>
<tr> <tr>
<td> <td>
${this.asmCode.render()} ${this.asmCode.render()}
......
...@@ -37,7 +37,9 @@ module.exports = { ...@@ -37,7 +37,9 @@ module.exports = {
var ret = '' var ret = ''
for (var arg in arguments) { for (var arg in arguments) {
for (var k in arguments[arg]) { 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 return ret
......
...@@ -16,6 +16,7 @@ TraceAnalyser.prototype.analyse = function (trace, tx, callback) { ...@@ -16,6 +16,7 @@ TraceAnalyser.prototype.analyse = function (trace, tx, callback) {
lastCallIndex: 0 lastCallIndex: 0
} }
var callStack = [tx.to] var callStack = [tx.to]
this.traceCache.pushCallChanges(0, 0, callStack[0])
this.traceCache.pushCallStack(0, { this.traceCache.pushCallStack(0, {
callStack: callStack.slice(0) callStack: callStack.slice(0)
}) })
...@@ -29,10 +30,21 @@ TraceAnalyser.prototype.analyse = function (trace, tx, callback) { ...@@ -29,10 +30,21 @@ TraceAnalyser.prototype.analyse = function (trace, tx, callback) {
this.buildMemory(k, step) this.buildMemory(k, step)
context = this.buildDepth(k, step, tx, callStack, context) context = this.buildDepth(k, step, tx, callStack, context)
context = this.buildStorage(k, step, context) context = this.buildStorage(k, step, context)
this.buildReturnValues(k, step)
} }
callback(null, true) 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) { TraceAnalyser.prototype.buildCalldata = function (index, step, tx, newContext) {
var calldata = '' var calldata = ''
if (index === 0) { if (index === 0) {
...@@ -66,7 +78,7 @@ TraceAnalyser.prototype.buildMemory = function (index, step) { ...@@ -66,7 +78,7 @@ TraceAnalyser.prototype.buildMemory = function (index, step) {
} }
TraceAnalyser.prototype.buildStorage = function (index, step, context) { 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) var calledAddress = traceHelper.resolveCalledAddress(index, this.trace)
if (calledAddress) { if (calledAddress) {
context.currentStorageAddress = calledAddress context.currentStorageAddress = calledAddress
...@@ -85,20 +97,21 @@ TraceAnalyser.prototype.buildStorage = function (index, step, context) { ...@@ -85,20 +97,21 @@ TraceAnalyser.prototype.buildStorage = function (index, step, context) {
TraceAnalyser.prototype.buildDepth = function (index, step, tx, callStack, context) { TraceAnalyser.prototype.buildDepth = function (index, step, tx, callStack, context) {
if (traceHelper.isCallInstruction(step) && !traceHelper.isCallToPrecompiledContract(index, this.trace)) { if (traceHelper.isCallInstruction(step) && !traceHelper.isCallToPrecompiledContract(index, this.trace)) {
var newAddress
if (traceHelper.isCreateInstruction(step)) { if (traceHelper.isCreateInstruction(step)) {
var contractToken = traceHelper.contractCreationToken(index) newAddress = traceHelper.contractCreationToken(index)
callStack.push(contractToken) callStack.push(newAddress)
var lastMemoryChange = this.traceCache.memoryChanges[this.traceCache.memoryChanges.length - 1] 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 { } else {
var newAddress = traceHelper.resolveCalledAddress(index, this.trace) newAddress = traceHelper.resolveCalledAddress(index, this.trace)
if (newAddress) { if (newAddress) {
callStack.push(newAddress) callStack.push(newAddress)
} else { } else {
console.log('unable to build depth changes. ' + index + ' does not match with a CALL. depth changes will be corrupted') 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, { this.traceCache.pushCallStack(index + 1, {
callStack: callStack.slice(0) callStack: callStack.slice(0)
}) })
......
...@@ -6,12 +6,13 @@ function TraceCache () { ...@@ -6,12 +6,13 @@ function TraceCache () {
TraceCache.prototype.init = function () { TraceCache.prototype.init = function () {
// ...Changes contains index in the vmtrace of the corresponding changes // ...Changes contains index in the vmtrace of the corresponding changes
this.returnValues = {}
this.callChanges = [] this.callChanges = []
this.returnChanges = []
this.calls = {} this.calls = {}
this.callsData = {} this.callsData = {}
this.contractCreation = {} this.contractCreation = {}
this.steps = {} this.steps = {}
this.addresses = []
this.callDataChanges = [] this.callDataChanges = []
this.memoryChanges = [] this.memoryChanges = []
...@@ -33,13 +34,18 @@ TraceCache.prototype.pushMemoryChanges = function (value) { ...@@ -33,13 +34,18 @@ TraceCache.prototype.pushMemoryChanges = function (value) {
this.memoryChanges.push(value) this.memoryChanges.push(value)
} }
TraceCache.prototype.pushCallChanges = function (step, value) { TraceCache.prototype.pushCallChanges = function (step, value, address) {
this.callChanges.push(value) this.callChanges.push(value)
this.calls[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) { TraceCache.prototype.pushContractCreationFromMemory = function (index, token, trace, lastMemoryChange) {
var memory = trace[lastMemoryChange].memory var memory = trace[lastMemoryChange].memory
var stack = trace[index].stack var stack = trace[index].stack
...@@ -52,10 +58,6 @@ TraceCache.prototype.pushContractCreation = function (token, code) { ...@@ -52,10 +58,6 @@ TraceCache.prototype.pushContractCreation = function (token, code) {
this.contractCreation[token] = code this.contractCreation[token] = code
} }
TraceCache.prototype.pushReturnChanges = function (value) {
this.returnChanges.push(value)
}
TraceCache.prototype.pushCallStack = function (index, callStack) { TraceCache.prototype.pushCallStack = function (index, callStack) {
this.callStack[index] = callStack this.callStack[index] = callStack
} }
......
...@@ -73,14 +73,16 @@ TraceManager.prototype.getLength = function (callback) { ...@@ -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) var check = this.checkRequestedStep(stepIndex)
if (check) { if (check) {
return callback(check, null) return callback(check, null)
} }
var stoChange = traceHelper.findLowerBound(stepIndex, this.traceCache.storageChanges) if (!address) {
if (stoChange === undefined) return callback('no storage found', null) var stoChange = traceHelper.findLowerBound(stepIndex, this.traceCache.storageChanges)
var address = this.traceCache.sstore[stoChange].address if (stoChange === undefined) return callback('no storage found', null)
address = this.traceCache.sstore[stoChange].address
}
var storage = {} var storage = {}
storage = this.traceCache.rebuildStorage(address, storage, stepIndex) storage = this.traceCache.rebuildStorage(address, storage, stepIndex)
callback(null, storage) callback(null, storage)
...@@ -104,6 +106,17 @@ TraceManager.prototype.getStorageAt = function (stepIndex, tx, callback) { ...@@ -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) { TraceManager.prototype.getCallDataAt = function (stepIndex, callback) {
var check = this.checkRequestedStep(stepIndex) var check = this.checkRequestedStep(stepIndex)
if (check) { if (check) {
...@@ -203,6 +216,14 @@ TraceManager.prototype.getCurrentPC = function (stepIndex, callback) { ...@@ -203,6 +216,14 @@ TraceManager.prototype.getCurrentPC = function (stepIndex, callback) {
callback(null, this.trace[stepIndex].pc) 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) { TraceManager.prototype.getCurrentStep = function (stepIndex, callback) {
var check = this.checkRequestedStep(stepIndex) var check = this.checkRequestedStep(stepIndex)
if (check) { if (check) {
......
...@@ -297,4 +297,27 @@ tape('TraceManager', function (t) { ...@@ -297,4 +297,27 @@ tape('TraceManager', function (t) {
st.ok(result === 63) st.ok(result === 63)
st.end() 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()
}
})
})
}) })
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment