enable/disable buttons

fix ascii char, memory panel
trace checker
pull/7/head
yann300 9 years ago
parent 24f0a13a6a
commit 98c34f1ff0
  1. 32
      src/buttonNavigator.js
  2. 10
      src/memoryPanel.js
  3. 30
      src/stepManager.js
  4. 2
      src/traceAnalyser.js
  5. 2
      src/traceCache.js
  6. 90
      src/traceManager.js
  7. 6
      src/traceManagerUtil.js
  8. 13
      src/traceStepManager.js
  9. 1
      src/txBrowser.js

@ -17,39 +17,43 @@ module.exports = React.createClass({
render: function () { render: function () {
return ( return (
<div> <div>
<button onClick={this.props.stepIntoBack} disabled={this.checkButtonState(-1)}> <button ref='intoback' onClick={this.props.stepIntoBack}>
Step Into Back Step Into Back
</button> </button>
<button onClick={this.props.stepOverBack} disabled={this.checkButtonState(-1)}> <button ref='overback' onClick={this.props.stepOverBack}>
Step Over Back Step Over Back
</button> </button>
<button onClick={this.props.stepOverForward} disabled={this.checkButtonState(1)}> <button ref='overforward' onClick={this.props.stepOverForward}>
Step Over Forward Step Over Forward
</button> </button>
<button onClick={this.props.stepIntoForward} disabled={this.checkButtonState(1)}> <button ref='intoforward' onClick={this.props.stepIntoForward}>
Step Into Forward Step Into Forward
</button> </button>
<button onClick={this.props.jumpNextCall} disabled={this.checkButtonState(1)}> <button ref='nextcall' onClick={this.props.jumpNextCall}>
Jump Next Call Jump Next Call
</button> </button>
</div> </div>
) )
}, },
checkButtonState: function (incr) { stepChanged: function (step) {
this.refs.intoback.disabled = step <= 0
this.refs.overback.disabled = step <= 0
if (!this.context.traceManager) { if (!this.context.traceManager) {
return false this.refs.intoforward.disabled = true
} this.refs.overforward.disabled = true
this.refs.nextcall.disabled = true
} else {
var self = this var self = this
this.context.traceManager.getLength(function (error, length) { this.context.traceManager.getLength(function (error, length) {
if (error) { if (error) {
return false console.log(error)
} } else {
if (incr === -1) { self.refs.intoforward.disabled = step >= length - 1
return self.props.step === 0 ? 'disabled' : '' self.refs.overforward.disabled = step >= length - 1
} else if (incr === 1) { self.refs.nextcall.disabled = step >= length - 1
return self.props.step >= self.props.max - 1 ? 'disabled' : ''
} }
}) })
} }
}
}) })

@ -64,12 +64,12 @@ module.exports = React.createClass({
var ret = { ascii: '', raw: '' } var ret = { ascii: '', raw: '' }
for (var k = 0; k < memorySlot.length; k += 2) { for (var k = 0; k < memorySlot.length; k += 2) {
var raw = memorySlot.substr(k, 2) var raw = memorySlot.substr(k, 2)
var ascii = this.context.web3.toAscii(raw) var ascii = String.fromCharCode(parseInt(raw, 16))
if (ascii === String.fromCharCode(0)) { ascii = ascii.replace(/\W/g, '?')
ret.ascii += '?' if (ascii === '') {
} else { ascii = '?'
ret.ascii += ascii
} }
ret.ascii += ascii
ret.raw += ' ' + raw ret.raw += ' ' + raw
} }
return ret return ret

@ -29,6 +29,7 @@ module.exports = React.createClass({
min='0' min='0'
max={this.state.traceLength} /> max={this.state.traceLength} />
<ButtonNavigator <ButtonNavigator
ref='buttons'
stepIntoBack={this.stepIntoBack} stepIntoBack={this.stepIntoBack}
stepIntoForward={this.stepIntoForward} stepIntoForward={this.stepIntoForward}
stepOverBack={this.stepOverBack} stepOverBack={this.stepOverBack}
@ -40,7 +41,7 @@ module.exports = React.createClass({
}, },
componentDidMount: function () { componentDidMount: function () {
this.updateGlobalSelectedItem(0) this.changeState(-1)
}, },
updateGlobalSelectedItem: function (value) { updateGlobalSelectedItem: function (value) {
@ -49,6 +50,7 @@ module.exports = React.createClass({
init: function () { init: function () {
this.refs.slider.setValue(0) this.refs.slider.setValue(0)
this.changeState(-1)
}, },
newTraceAvailable: function () { newTraceAvailable: function () {
@ -59,12 +61,13 @@ module.exports = React.createClass({
console.log(error) console.log(error)
} else { } else {
self.setState({ traceLength: length }) self.setState({ traceLength: length })
self.changeState(0)
} }
}) })
}, },
sliderMoved: function (step) { sliderMoved: function (step) {
if (step >= this.state.traceLength || step < 0) { if (!this.context.traceManager.inRange(step)) {
return return
} }
this.props.onStepChanged(step) this.props.onStepChanged(step)
@ -72,8 +75,11 @@ module.exports = React.createClass({
}, },
stepIntoForward: function () { stepIntoForward: function () {
if (!this.context.traceManager.isLoaded()) {
return
}
var step = this.state.currentStepIndex + 1 var step = this.state.currentStepIndex + 1
if (step >= this.state.traceLength || step < 0) { if (!this.context.traceManager.inRange(step)) {
return return
} }
this.props.onStepChanged(step) this.props.onStepChanged(step)
@ -82,8 +88,11 @@ module.exports = React.createClass({
}, },
stepIntoBack: function () { stepIntoBack: function () {
if (!this.context.traceManager.isLoaded()) {
return
}
var step = this.state.currentStepIndex - 1 var step = this.state.currentStepIndex - 1
if (step >= this.state.traceLength || step < 0) { if (!this.context.traceManager.inRange(step)) {
return return
} }
this.props.onStepChanged(step) this.props.onStepChanged(step)
@ -92,30 +101,30 @@ module.exports = React.createClass({
}, },
stepOverForward: function () { stepOverForward: function () {
var step = this.context.traceManager.findStepOverForward(this.state.currentStepIndex) if (!this.context.traceManager.isLoaded()) {
if (step >= this.state.traceLength || step < 0) {
return return
} }
var step = this.context.traceManager.findStepOverForward(this.state.currentStepIndex)
this.props.onStepChanged(step) this.props.onStepChanged(step)
this.refs.slider.setValue(step) this.refs.slider.setValue(step)
this.changeState(step) this.changeState(step)
}, },
stepOverBack: function () { stepOverBack: function () {
var step = this.context.traceManager.findStepOverBack(this.state.currentStepIndex) if (!this.context.traceManager.isLoaded()) {
if (step >= this.state.traceLength || step < 0) {
return return
} }
var step = this.context.traceManager.findStepOverBack(this.state.currentStepIndex)
this.props.onStepChanged(step) this.props.onStepChanged(step)
this.refs.slider.setValue(step) this.refs.slider.setValue(step)
this.changeState(step) this.changeState(step)
}, },
jumpToNextCall: function () { jumpToNextCall: function () {
var step = this.context.traceManager.findNextCall(this.state.currentStepIndex) if (!this.context.traceManager.isLoaded()) {
if (step >= this.state.traceLength || step < 0) {
return return
} }
var step = this.context.traceManager.findNextCall(this.state.currentStepIndex)
this.props.onStepChanged(step) this.props.onStepChanged(step)
this.refs.slider.setValue(step) this.refs.slider.setValue(step)
this.changeState(step) this.changeState(step)
@ -126,5 +135,6 @@ module.exports = React.createClass({
this.setState({ this.setState({
currentStepIndex: step currentStepIndex: step
}) })
this.refs.buttons.stepChanged(step)
} }
}) })

@ -53,7 +53,7 @@ TraceAnalyser.prototype.buildStorage = function (index, step, context) {
console.log('unable to build storage changes. ' + index + ' does not match with a CALL. storage changes will be corrupted') console.log('unable to build storage changes. ' + index + ' does not match with a CALL. storage changes will be corrupted')
} }
this.traceCache.pushStoreChanges(index + 1, context.currentStorageAddress) this.traceCache.pushStoreChanges(index + 1, context.currentStorageAddress)
} else if (step.op === 'SSTORE') { } else if (traceManagerUtil.isSSTOREInstruction(step)) {
this.traceCache.pushStoreChanges(index + 1, context.currentStorageAddress, step.stack[step.stack.length - 1], step.stack[step.stack.length - 2]) this.traceCache.pushStoreChanges(index + 1, context.currentStorageAddress, step.stack[step.stack.length - 1], step.stack[step.stack.length - 2])
} else if (traceManagerUtil.isReturnInstruction(step)) { } else if (traceManagerUtil.isReturnInstruction(step)) {
context.currentStorageAddress = context.previousStorageAddress context.currentStorageAddress = context.previousStorageAddress

@ -38,7 +38,7 @@ TraceCache.prototype.pushContractCreationFromMemory = function (index, token, tr
var stack = trace[index].stack var stack = trace[index].stack
var offset = 2 * parseInt(stack[stack.length - 2], 16) var offset = 2 * parseInt(stack[stack.length - 2], 16)
var size = 2 * parseInt(stack[stack.length - 3], 16) var size = 2 * parseInt(stack[stack.length - 3], 16)
this.contractCreation[token] = '0x' + memory.substr(offset, size) this.contractCreation[token] = '0x' + memory.join('').substr(offset, size)
} }
TraceCache.prototype.pushContractCreation = function (token, code) { TraceCache.prototype.pushContractCreation = function (token, code) {

@ -53,6 +53,14 @@ TraceManager.prototype.init = function () {
} }
// API section // API section
TraceManager.prototype.inRange = function (step) {
return this.isLoaded() && step >= 0 && step < this.trace.length
}
TraceManager.prototype.isLoaded = function () {
return !this.isLoading && this.trace !== null
}
TraceManager.prototype.getLength = function (callback) { TraceManager.prototype.getLength = function (callback) {
if (!this.trace) { if (!this.trace) {
callback('no trace available', null) callback('no trace available', null)
@ -62,9 +70,9 @@ TraceManager.prototype.getLength = function (callback) {
} }
TraceManager.prototype.getStorageAt = function (stepIndex, tx, callback) { TraceManager.prototype.getStorageAt = function (stepIndex, tx, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
var stoChange = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.storageChanges) var stoChange = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.storageChanges)
if (stoChange === undefined) return callback('no storage found', null) if (stoChange === undefined) return callback('no storage found', null)
@ -86,9 +94,9 @@ TraceManager.prototype.getStorageAt = function (stepIndex, tx, callback) {
} }
TraceManager.prototype.getCallDataAt = function (stepIndex, callback) { TraceManager.prototype.getCallDataAt = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
var callDataChange = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.callDataChanges) var callDataChange = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.callDataChanges)
if (callDataChange === undefined) return callback('no calldata found', null) if (callDataChange === undefined) return callback('no calldata found', null)
@ -96,9 +104,9 @@ TraceManager.prototype.getCallDataAt = function (stepIndex, callback) {
} }
TraceManager.prototype.getCallStackAt = function (stepIndex, callback) { TraceManager.prototype.getCallStackAt = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
var callStackChange = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.callChanges) var callStackChange = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.callChanges)
if (callStackChange === undefined) return callback('no callstack found', null) if (callStackChange === undefined) return callback('no callstack found', null)
@ -106,9 +114,9 @@ TraceManager.prototype.getCallStackAt = function (stepIndex, callback) {
} }
TraceManager.prototype.getStackAt = function (stepIndex, callback) { TraceManager.prototype.getStackAt = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
var stack var stack
if (this.trace[stepIndex].stack) { // there's always a stack if (this.trace[stepIndex].stack) { // there's always a stack
@ -121,9 +129,9 @@ TraceManager.prototype.getStackAt = function (stepIndex, callback) {
} }
TraceManager.prototype.getLastCallChangeSince = function (stepIndex, callback) { TraceManager.prototype.getLastCallChangeSince = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
var callChange = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.callChanges) var callChange = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.callChanges)
if (callChange === undefined) { if (callChange === undefined) {
@ -134,9 +142,9 @@ TraceManager.prototype.getLastCallChangeSince = function (stepIndex, callback) {
} }
TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex, callback) { TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex, callback) {
if (stepIndex > this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
var self = this var self = this
this.getLastCallChangeSince(stepIndex, function (error, addressIndex) { this.getLastCallChangeSince(stepIndex, function (error, addressIndex) {
@ -167,9 +175,9 @@ TraceManager.prototype.getContractCreationCode = function (token, callback) {
} }
TraceManager.prototype.getMemoryAt = function (stepIndex, callback) { TraceManager.prototype.getMemoryAt = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
var lastChanges = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.memoryChanges) var lastChanges = traceManagerUtil.findLowerBound(stepIndex, this.traceCache.memoryChanges)
if (lastChanges === undefined) return callback('no memory found', null) if (lastChanges === undefined) return callback('no memory found', null)
@ -177,41 +185,41 @@ TraceManager.prototype.getMemoryAt = function (stepIndex, callback) {
} }
TraceManager.prototype.getCurrentPC = function (stepIndex, callback) { TraceManager.prototype.getCurrentPC = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
callback(null, this.trace[stepIndex].pc) callback(null, this.trace[stepIndex].pc)
} }
TraceManager.prototype.getCurrentStep = function (stepIndex, callback) { TraceManager.prototype.getCurrentStep = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
callback(null, this.trace[stepIndex].steps) callback(null, this.trace[stepIndex].steps)
} }
TraceManager.prototype.getMemExpand = function (stepIndex, callback) { TraceManager.prototype.getMemExpand = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
callback(null, this.trace[stepIndex].memexpand ? this.trace[stepIndex].memexpand : '') callback(null, this.trace[stepIndex].memexpand ? this.trace[stepIndex].memexpand : '')
} }
TraceManager.prototype.getStepCost = function (stepIndex, callback) { TraceManager.prototype.getStepCost = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
callback(null, this.trace[stepIndex].gasCost) callback(null, this.trace[stepIndex].gasCost)
} }
TraceManager.prototype.getRemainingGas = function (stepIndex, callback) { TraceManager.prototype.getRemainingGas = function (stepIndex, callback) {
if (stepIndex >= this.trace.length) { var check = this.checkRequestedStep(stepIndex)
callback('trace smaller than requested', null) if (check) {
return return callback(check, null)
} }
callback(null, this.trace[stepIndex].gas) callback(null, this.trace[stepIndex].gas)
} }
@ -241,4 +249,14 @@ TraceManager.prototype.findNextCall = function (currentStep) {
return this.traceStepManager.findNextCall(currentStep) return this.traceStepManager.findNextCall(currentStep)
} }
// util
TraceManager.prototype.checkRequestedStep = function (stepIndex) {
if (!this.trace) {
return 'trace not loaded'
} else if (stepIndex >= this.trace.length) {
return 'trace smaller than requested'
}
return undefined
}
module.exports = TraceManager module.exports = TraceManager

@ -49,6 +49,10 @@ module.exports = {
return step.op === 'RETURN' return step.op === 'RETURN'
}, },
isSSTOREInstruction: function (step) {
return step.op === 'SSTORE'
},
newContextStorage: function (step) { newContextStorage: function (step) {
return step.op === 'CREATE' || step.op === 'CALL' return step.op === 'CREATE' || step.op === 'CALL'
}, },
@ -64,7 +68,7 @@ module.exports = {
}, },
contractCreationToken: function (index) { contractCreationToken: function (index) {
return '(Contract Creation - Step' + index + ')' return '(Contract Creation - Step ' + index + ')'
}, },
isContractCreation: function (address) { isContractCreation: function (address) {

@ -26,6 +26,9 @@ TraceStepManager.prototype.findStepOverForward = function (currentStep) {
} }
TraceStepManager.prototype.findStepOutBack = function (currentStep) { TraceStepManager.prototype.findStepOutBack = function (currentStep) {
if (!this.traceAnalyser.trace) {
return currentStep
}
var i = currentStep - 1 var i = currentStep - 1
var depth = 0 var depth = 0
while (--i >= 0) { while (--i >= 0) {
@ -39,10 +42,13 @@ TraceStepManager.prototype.findStepOutBack = function (currentStep) {
depth++ depth++
} }
} }
return i return i + 1
} }
TraceStepManager.prototype.findStepOutForward = function (currentStep) { TraceStepManager.prototype.findStepOutForward = function (currentStep) {
if (!this.traceAnalyser.trace) {
return currentStep
}
var i = currentStep var i = currentStep
var depth = 0 var depth = 0
while (++i < this.traceAnalyser.trace.length) { while (++i < this.traceAnalyser.trace.length) {
@ -56,10 +62,13 @@ TraceStepManager.prototype.findStepOutForward = function (currentStep) {
depth++ depth++
} }
} }
return i return i - 1
} }
TraceStepManager.prototype.findNextCall = function (currentStep) { TraceStepManager.prototype.findNextCall = function (currentStep) {
if (!this.traceAnalyser.trace) {
return currentStep
}
var i = currentStep var i = currentStep
while (++i < this.traceAnalyser.trace.length) { while (++i < this.traceAnalyser.trace.length) {
if (this.isCallInstruction(i)) { if (this.isCallInstruction(i)) {

@ -18,7 +18,6 @@ module.exports = React.createClass({
// creation 0xa9619e1d0a35b2c1d686f5b661b3abd87f998d2844e8e9cc905edb57fc9ce349 // creation 0xa9619e1d0a35b2c1d686f5b661b3abd87f998d2844e8e9cc905edb57fc9ce349
// invokation 0x71a6d583d16d142c5c3e8903060e8a4ee5a5016348a9448df6c3e63b68076ec4 // invokation 0x71a6d583d16d142c5c3e8903060e8a4ee5a5016348a9448df6c3e63b68076ec4
// test: // test:
// creation: 0x72908de76f99fca476f9e3a3b5d352f350a98cd77d09cebfc59ffe32a6ecaa0b // creation: 0x72908de76f99fca476f9e3a3b5d352f350a98cd77d09cebfc59ffe32a6ecaa0b
// invokation: 0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51 // invokation: 0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51

Loading…
Cancel
Save