Commit 220f7e7a authored by Iuri Matias's avatar Iuri Matias Committed by Aniket

refactor getSourceLocationFromVMTraceIndex to a promise

refactor getCallStackAt refactor getSourceLocationFromInstructionIndex refactor extractStateVariablesAt refactor getLastCallChangeSince refactor checkRequestedStep refactor getCurrentCalledAddressAt
parent e9faef98
...@@ -65,17 +65,16 @@ Ethdebugger.prototype.setCompilationResult = function (compilationResult) { ...@@ -65,17 +65,16 @@ Ethdebugger.prototype.setCompilationResult = function (compilationResult) {
} }
} }
/* resolve source location */
Ethdebugger.prototype.sourceLocationFromVMTraceIndex = function (address, stepIndex, callback) { Ethdebugger.prototype.sourceLocationFromVMTraceIndex = function (address, stepIndex, callback) {
this.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, stepIndex, this.solidityProxy.contracts, (error, rawLocation) => { this.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, stepIndex, this.solidityProxy.contracts).then((rawLocation) => {
callback(error, rawLocation) callback(null, rawLocation)
}) }).catch(callback)
} }
Ethdebugger.prototype.sourceLocationFromInstructionIndex = function (address, instIndex, callback) { Ethdebugger.prototype.sourceLocationFromInstructionIndex = function (address, instIndex, callback) {
this.callTree.sourceLocationTracker.getSourceLocationFromInstructionIndex(address, instIndex, this.solidityProxy.contracts, (error, rawLocation) => { this.callTree.sourceLocationTracker.getSourceLocationFromInstructionIndex(address, instIndex, this.solidityProxy.contracts).then((rawLocation) => {
callback(error, rawLocation) callback(null, rawLocation)
}) }).catch(callback)
} }
/* breakpoint */ /* breakpoint */
...@@ -89,10 +88,18 @@ Ethdebugger.prototype.extractLocalsAt = function (step, callback) { ...@@ -89,10 +88,18 @@ Ethdebugger.prototype.extractLocalsAt = function (step, callback) {
} }
Ethdebugger.prototype.decodeLocalsAt = function (step, sourceLocation, callback) { Ethdebugger.prototype.decodeLocalsAt = function (step, sourceLocation, callback) {
const self = this
this.traceManager.waterfall([ this.traceManager.waterfall([
this.traceManager.getStackAt, this.traceManager.getStackAt,
this.traceManager.getMemoryAt, this.traceManager.getMemoryAt,
this.traceManager.getCurrentCalledAddressAt], function getCurrentCalledAddressAt (stepIndex, next) {
try {
const address = self.traceManager.getCurrentCalledAddressAt(stepIndex)
next(null, address)
} catch (error) {
next(error)
}
}],
step, step,
(error, result) => { (error, result) => {
if (!error) { if (!error) {
...@@ -122,14 +129,14 @@ Ethdebugger.prototype.decodeLocalsAt = function (step, sourceLocation, callback) ...@@ -122,14 +129,14 @@ Ethdebugger.prototype.decodeLocalsAt = function (step, sourceLocation, callback)
/* decode state */ /* decode state */
Ethdebugger.prototype.extractStateAt = function (step, callback) { Ethdebugger.prototype.extractStateAt = function (step, callback) {
this.solidityProxy.extractStateVariablesAt(step, (error, stateVars) => { this.solidityProxy.extractStateVariablesAt(step).then((stateVars) => {
callback(error, stateVars) callback(null, stateVars)
}) }).catch(callback)
} }
Ethdebugger.prototype.decodeStateAt = function (step, stateVars, callback) { Ethdebugger.prototype.decodeStateAt = function (step, stateVars, callback) {
this.traceManager.getCurrentCalledAddressAt(step, (error, address) => { try {
if (error) return callback(error) const address = this.traceManager.getCurrentCalledAddressAt(step)
const storageViewer = new StorageViewer({ const storageViewer = new StorageViewer({
stepIndex: step, stepIndex: step,
tx: this.tx, tx: this.tx,
...@@ -142,7 +149,9 @@ Ethdebugger.prototype.decodeStateAt = function (step, stateVars, callback) { ...@@ -142,7 +149,9 @@ Ethdebugger.prototype.decodeStateAt = function (step, stateVars, callback) {
callback(result.error) callback(result.error)
} }
}) })
}) } catch (error) {
callback(error)
}
} }
Ethdebugger.prototype.storageViewAt = function (step, address) { Ethdebugger.prototype.storageViewAt = function (step, address) {
......
...@@ -78,14 +78,14 @@ class VmDebuggerLogic { ...@@ -78,14 +78,14 @@ class VmDebuggerLogic {
} }
}) })
this._traceManager.getCallStackAt(index, (error, callstack) => { try {
if (error) { const callstack = this._traceManager.getCallStackAt(index)
// console.log(error) if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerCallStackUpdate', [{}])
} else if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerCallStackUpdate', [callstack]) this.event.trigger('traceManagerCallStackUpdate', [callstack])
} }
}) } catch (error) {
this.event.trigger('traceManagerCallStackUpdate', [{}])
}
this._traceManager.getStackAt(index, (error, callstack) => { this._traceManager.getStackAt(index, (error, callstack) => {
if (error) { if (error) {
...@@ -96,22 +96,22 @@ class VmDebuggerLogic { ...@@ -96,22 +96,22 @@ class VmDebuggerLogic {
} }
}) })
this._traceManager.getCurrentCalledAddressAt(index, (error, address) => { try {
if (error) return const address = this._traceManager.getCurrentCalledAddressAt(index)
if (!this.storageResolver) return if (!this.storageResolver) return
var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: address }, this.storageResolver, this._traceManager) var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: address }, this.storageResolver, this._traceManager)
storageViewer.storageRange((error, storage) => { storageViewer.storageRange((error, storage) => {
if (error) { if (error) {
// console.log(error)
this.event.trigger('traceManagerStorageUpdate', [{}]) this.event.trigger('traceManagerStorageUpdate', [{}])
} else if (this.stepManager.currentStepIndex === index) { } else if (this.stepManager.currentStepIndex === index) {
var header = storageViewer.isComplete(address) ? '[Completely Loaded]' : '[Partially Loaded]' var header = storageViewer.isComplete(address) ? '[Completely Loaded]' : '[Partially Loaded]'
this.event.trigger('traceManagerStorageUpdate', [storage, header]) this.event.trigger('traceManagerStorageUpdate', [storage, header])
} }
}) })
}) } catch (error) {
}
this._traceManager.getCurrentStep(index, (error, step) => { this._traceManager.getCurrentStep(index, (error, step) => {
this.event.trigger('traceCurrentStepUpdate', [error, step]) this.event.trigger('traceCurrentStepUpdate', [error, step])
...@@ -131,9 +131,12 @@ class VmDebuggerLogic { ...@@ -131,9 +131,12 @@ class VmDebuggerLogic {
this.event.trigger('traceStepCostUpdate', [error]) this.event.trigger('traceStepCostUpdate', [error])
} }
this._traceManager.getCurrentCalledAddressAt(index, (error, address) => { try {
this.event.trigger('traceCurrentCalledAddressAtUpdate', [error, address]) const address = this._traceManager.getCurrentCalledAddressAt(index)
}) this.event.trigger('traceCurrentCalledAddressAtUpdate', [null, address])
} catch (error) {
this.event.trigger('traceCurrentCalledAddressAtUpdate', [error])
}
try { try {
const remaining = this._traceManager.getRemainingGas(index) const remaining = this._traceManager.getRemainingGas(index)
......
...@@ -45,21 +45,29 @@ function Debugger (options) { ...@@ -45,21 +45,29 @@ function Debugger (options) {
}) })
} }
Debugger.prototype.registerAndHighlightCodeItem = function (index) { Debugger.prototype.registerAndHighlightCodeItem = async function (index) {
// register selected code item, highlight the corresponding source location // register selected code item, highlight the corresponding source location
this.debugger.traceManager.getCurrentCalledAddressAt(index, async (error, address) => { // this.debugger.traceManager.getCurrentCalledAddressAt(index, async (error, address) => {
if (error) return console.log(error)
try {
const address = this.debugger.traceManager.getCurrentCalledAddressAt(index)
const compilationResultForAddress = await this.compilationResult(address) const compilationResultForAddress = await this.compilationResult(address)
if (!compilationResultForAddress) return if (!compilationResultForAddress) return
this.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, index, compilationResultForAddress.data.contracts, (error, rawLocation) => {
if (!error && compilationResultForAddress && compilationResultForAddress.data) { this.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, index, compilationResultForAddress.data.contracts).then((rawLocation) => {
if (compilationResultForAddress && compilationResultForAddress.data) {
var lineColumnPos = this.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file, compilationResultForAddress.source.sources, compilationResultForAddress.data.sources) var lineColumnPos = this.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file, compilationResultForAddress.source.sources, compilationResultForAddress.data.sources)
this.event.trigger('newSourceLocation', [lineColumnPos, rawLocation]) this.event.trigger('newSourceLocation', [lineColumnPos, rawLocation])
} else { } else {
this.event.trigger('newSourceLocation', [null]) this.event.trigger('newSourceLocation', [null])
} }
}).catch((_error) => {
this.event.trigger('newSourceLocation', [null])
}) })
}) // })
} catch (error) {
return console.log(error)
}
} }
Debugger.prototype.updateWeb3 = function (web3) { Debugger.prototype.updateWeb3 = function (web3) {
...@@ -107,10 +115,8 @@ Debugger.prototype.debugTx = function (tx, loadingCb) { ...@@ -107,10 +115,8 @@ Debugger.prototype.debugTx = function (tx, loadingCb) {
this.step_manager = new StepManager(this.debugger, this.debugger.traceManager) this.step_manager = new StepManager(this.debugger, this.debugger.traceManager)
this.debugger.codeManager.event.register('changed', this, (code, address, instIndex) => { this.debugger.codeManager.event.register('changed', this, (code, address, instIndex) => {
this.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, this.step_manager.currentStepIndex, this.debugger.solidityProxy.contracts, (error, sourceLocation) => { this.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, this.step_manager.currentStepIndex, this.debugger.solidityProxy.contracts).then((sourceLocation) => {
if (!error) { this.vmDebuggerLogic.event.trigger('sourceLocationChanged', [sourceLocation])
this.vmDebuggerLogic.event.trigger('sourceLocationChanged', [sourceLocation])
}
}) })
}) })
......
...@@ -34,7 +34,14 @@ class DebuggerSolidityLocals { ...@@ -34,7 +34,14 @@ class DebuggerSolidityLocals {
this.traceManager.waterfall([ this.traceManager.waterfall([
this.traceManager.getStackAt, this.traceManager.getStackAt,
this.traceManager.getMemoryAt, this.traceManager.getMemoryAt,
this.traceManager.getCurrentCalledAddressAt], function getCurrentCalledAddressAt (stepIndex, next) {
try {
const address = this.traceManager.getCurrentCalledAddressAt(stepIndex)
next(null, address)
} catch (error) {
next(error)
}
}],
this.stepManager.currentStepIndex, this.stepManager.currentStepIndex,
(error, result) => { (error, result) => {
if (error) { if (error) {
......
...@@ -50,21 +50,20 @@ class DebuggerSolidityState { ...@@ -50,21 +50,20 @@ class DebuggerSolidityState {
} }
decode (index) { decode (index) {
this.traceManager.getCurrentCalledAddressAt(this.stepManager.currentStepIndex, (error, address) => { try {
if (error) { const address = this.traceManager.getCurrentCalledAddressAt(this.stepManager.currentStepIndex)
return this.event.trigger('solidityState', [{}])
}
if (this.stateVariablesByAddresses[address]) { if (this.stateVariablesByAddresses[address]) {
return this.extractStateVariables(this.stateVariablesByAddresses[address], address) return this.extractStateVariables(this.stateVariablesByAddresses[address], address)
} }
this.solidityProxy.extractStateVariablesAt(index, (error, stateVars) => { this.solidityProxy.extractStateVariablesAt(index).then((stateVars) => {
if (error) {
return this.event.trigger('solidityState', [{}])
}
this.stateVariablesByAddresses[address] = stateVars this.stateVariablesByAddresses[address] = stateVars
this.extractStateVariables(stateVars, address) this.extractStateVariables(stateVars, address)
}).catch((_error) => {
this.event.trigger('solidityState', [{}])
}) })
}) } catch (error) {
return this.event.trigger('solidityState', [{}])
}
} }
extractStateVariables (stateVars, address) { extractStateVariables (stateVars, address) {
......
...@@ -126,21 +126,21 @@ class InternalCallTree { ...@@ -126,21 +126,21 @@ class InternalCallTree {
extractSourceLocation (step) { extractSourceLocation (step) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.traceManager.getCurrentCalledAddressAt(step, (error, address) => { try {
if (!error) { const address = this.traceManager.getCurrentCalledAddressAt(step)
this.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, step, this.solidityProxy.contracts, (error, sourceLocation) => { try {
if (!error) { this.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, step, this.solidityProxy.contracts).then(resolve).catch((error) => {
return resolve(sourceLocation) return reject('InternalCallTree - Cannot retrieve sourcelocation for step ' + step + ' ' + error)
} else {
return reject('InternalCallTree - Cannot retrieve sourcelocation for step ' + step + ' ' + error)
}
}) })
} else { } catch (error) {
return reject('InternalCallTree - Cannot retrieve address for step ' + step + ' ' + error) return reject('InternalCallTree - Cannot retrieve address for step ' + step + ' ' + error)
} }
}) } catch (error) {
return reject('InternalCallTree - Cannot retrieve address for step ' + step + ' ' + error)
}
}) })
} }
} }
async function buildTree (tree, step, scopeId, isExternalCall) { async function buildTree (tree, step, scopeId, isExternalCall) {
......
...@@ -40,25 +40,25 @@ class SolidityProxy { ...@@ -40,25 +40,25 @@ class SolidityProxy {
* @param {Function} cb - callback returns (error, contractName) * @param {Function} cb - callback returns (error, contractName)
*/ */
contractNameAt (vmTraceIndex, cb) { contractNameAt (vmTraceIndex, cb) {
this.traceManager.getCurrentCalledAddressAt(vmTraceIndex, (error, address) => { try {
if (error) { const address = this.traceManager.getCurrentCalledAddressAt(vmTraceIndex)
cb(error)
if (this.cache.contractNameByAddress[address]) {
cb(null, this.cache.contractNameByAddress[address])
} else { } else {
if (this.cache.contractNameByAddress[address]) { this.codeManager.getCode(address, (error, code) => {
cb(null, this.cache.contractNameByAddress[address]) if (error) {
} else { cb(error)
this.codeManager.getCode(address, (error, code) => { } else {
if (error) { const contractName = contractNameFromCode(this.contracts, code.bytecode, address)
cb(error) this.cache.contractNameByAddress[address] = contractName
} else { cb(null, contractName)
const contractName = contractNameFromCode(this.contracts, code.bytecode, address) }
this.cache.contractNameByAddress[address] = contractName })
cb(null, contractName)
}
})
}
} }
}) } catch (error) {
cb(error)
}
} }
/** /**
...@@ -96,13 +96,14 @@ class SolidityProxy { ...@@ -96,13 +96,14 @@ class SolidityProxy {
* @param {Int} vmTraceIndex - index in the vm trave where to resolve the state variables * @param {Int} vmTraceIndex - index in the vm trave where to resolve the state variables
* @return {Object} - returns state variables of @args vmTraceIndex * @return {Object} - returns state variables of @args vmTraceIndex
*/ */
extractStateVariablesAt (vmtraceIndex, cb) { extractStateVariablesAt (vmtraceIndex) {
this.contractNameAt(vmtraceIndex, (error, contractName) => { return new Promise((resolve, reject) => {
if (error) { this.contractNameAt(vmtraceIndex, (error, contractName) => {
cb(error) if (error) {
} else { return reject(error)
cb(null, this.extractStateVariables(contractName)) }
} return resolve(this.extractStateVariables(contractName))
})
}) })
} }
......
...@@ -215,15 +215,18 @@ function testDebugging (debugManager) { ...@@ -215,15 +215,18 @@ function testDebugging (debugManager) {
// storage // storage
tape('traceManager.getCurrentCalledAddressAt', (t) => { tape('traceManager.getCurrentCalledAddressAt', (t) => {
t.plan(1) t.plan(1)
debugManager.traceManager.getCurrentCalledAddressAt(38, (error, address) => {
if (error) return t.end(error) try {
const address = debugManager.traceManager.getCurrentCalledAddressAt(38)
console.log(address) console.log(address)
var storageView = debugManager.storageViewAt(196, address) var storageView = debugManager.storageViewAt(196, address)
storageView.storageRange((error, storage) => { storageView.storageRange((error, storage) => {
if (error) return t.end(error) if (error) return t.end(error)
t.equal(JSON.stringify(storage), JSON.stringify({ '0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563': { key: '0x0000000000000000000000000000000000000000000000000000000000000000', value: '0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db' } })) t.equal(JSON.stringify(storage), JSON.stringify({ '0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563': { key: '0x0000000000000000000000000000000000000000000000000000000000000000', value: '0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db' } }))
}) })
}) } catch (error) {
return t.end(error)
}
}) })
tape('traceManager.decodeStateAt', (t) => { tape('traceManager.decodeStateAt', (t) => {
...@@ -247,8 +250,8 @@ function testDebugging (debugManager) { ...@@ -247,8 +250,8 @@ function testDebugging (debugManager) {
tape('traceManager.decodeLocalsAt', (t) => { tape('traceManager.decodeLocalsAt', (t) => {
t.plan(1) t.plan(1)
const tested = JSON.parse('{"proposalNames":{"value":[{"value":"0x48656C6C6F20576F726C64210000000000000000000000000000000000000000","type":"bytes32"}],"length":"0x1","type":"bytes32[]"},"p":{"value":"45","type":"uint256"},"addressLocal":{"value":"0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB","type":"address"},"i":{"value":"2","type":"uint256"},"proposalsLocals":{"value":[{"value":{"name":{"value":"0x48656C6C6F20576F726C64210000000000000000000000000000000000000000","type":"bytes32"},"voteCount":{"value":"0","type":"uint256"}},"type":"struct Ballot.Proposal"}],"length":"0x1","type":"struct Ballot.Proposal[]"}}') const tested = JSON.parse('{"proposalNames":{"value":[{"value":"0x48656C6C6F20576F726C64210000000000000000000000000000000000000000","type":"bytes32"}],"length":"0x1","type":"bytes32[]"},"p":{"value":"45","type":"uint256"},"addressLocal":{"value":"0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB","type":"address"},"i":{"value":"2","type":"uint256"},"proposalsLocals":{"value":[{"value":{"name":{"value":"0x48656C6C6F20576F726C64210000000000000000000000000000000000000000","type":"bytes32"},"voteCount":{"value":"0","type":"uint256"}},"type":"struct Ballot.Proposal"}],"length":"0x1","type":"struct Ballot.Proposal[]"}}')
debugManager.traceManager.getCurrentCalledAddressAt(330, (error, address) => { try {
if (error) return t.end(error) const address = debugManager.traceManager.getCurrentCalledAddressAt(330)
debugManager.sourceLocationFromVMTraceIndex(address, 330, (error, location) => { debugManager.sourceLocationFromVMTraceIndex(address, 330, (error, location) => {
if (error) return t.end(error) if (error) return t.end(error)
debugManager.decodeLocalsAt(330, location, (error, decodedlocals) => { debugManager.decodeLocalsAt(330, location, (error, decodedlocals) => {
...@@ -256,7 +259,10 @@ function testDebugging (debugManager) { ...@@ -256,7 +259,10 @@ function testDebugging (debugManager) {
t.equal(JSON.stringify(decodedlocals), JSON.stringify(tested)) t.equal(JSON.stringify(decodedlocals), JSON.stringify(tested))
}) })
}) })
}) // })
} catch (error) {
return t.end(error)
}
}) })
tape('breakPointManager', (t) => { tape('breakPointManager', (t) => {
......
...@@ -39,12 +39,12 @@ CodeManager.prototype.resolveStep = function (stepIndex, tx) { ...@@ -39,12 +39,12 @@ CodeManager.prototype.resolveStep = function (stepIndex, tx) {
if (stepIndex === 0) { if (stepIndex === 0) {
return retrieveCodeAndTrigger(this, tx.to, stepIndex, tx) return retrieveCodeAndTrigger(this, tx.to, stepIndex, tx)
} }
this.traceManager.getCurrentCalledAddressAt(stepIndex, (error, address) => { try {
if (error) { const address = this.traceManager.getCurrentCalledAddressAt(stepIndex)
return console.log(error)
}
retrieveCodeAndTrigger(this, address, stepIndex, tx) retrieveCodeAndTrigger(this, address, stepIndex, tx)
}) } catch (error) {
return console.log(error)
}
} }
/** /**
...@@ -80,11 +80,8 @@ CodeManager.prototype.getCode = function (address, cb) { ...@@ -80,11 +80,8 @@ CodeManager.prototype.getCode = function (address, cb) {
* @return {Object} return the ast node of the function * @return {Object} return the ast node of the function
*/ */
CodeManager.prototype.getFunctionFromStep = function (stepIndex, sourceMap, ast) { CodeManager.prototype.getFunctionFromStep = function (stepIndex, sourceMap, ast) {
this.traceManager.getCurrentCalledAddressAt(stepIndex, (error, address) => { try {
if (error) { const address = this.traceManager.getCurrentCalledAddressAt(stepIndex)
console.log(error)
return { error: 'Cannot retrieve current address for ' + stepIndex }
}
this.traceManager.getCurrentPC(stepIndex, (error, pc) => { this.traceManager.getCurrentPC(stepIndex, (error, pc) => {
if (error) { if (error) {
console.log(error) console.log(error)
...@@ -92,7 +89,10 @@ CodeManager.prototype.getFunctionFromStep = function (stepIndex, sourceMap, ast) ...@@ -92,7 +89,10 @@ CodeManager.prototype.getFunctionFromStep = function (stepIndex, sourceMap, ast)
} }
return this.getFunctionFromPC(address, pc, sourceMap, ast) return this.getFunctionFromPC(address, pc, sourceMap, ast)
}) })
}) } catch (error) {
console.log(error)
return { error: 'Cannot retrieve current address for ' + stepIndex }
}
} }
/** /**
......
...@@ -22,13 +22,11 @@ function SourceLocationTracker (_codeManager) { ...@@ -22,13 +22,11 @@ function SourceLocationTracker (_codeManager) {
* @param {Object} contractDetails - AST of compiled contracts * @param {Object} contractDetails - AST of compiled contracts
* @param {Function} cb - callback function * @param {Function} cb - callback function
*/ */
SourceLocationTracker.prototype.getSourceLocationFromInstructionIndex = function (address, index, contracts, cb) { SourceLocationTracker.prototype.getSourceLocationFromInstructionIndex = function (address, index, contracts) {
extractSourceMap(this, this.codeManager, address, contracts, (error, sourceMap) => { return new Promise((resolve, reject) => {
if (error) { extractSourceMap(this, this.codeManager, address, contracts).then((sourceMap) => {
cb(error) resolve(this.sourceMappingDecoder.atIndex(index, sourceMap))
} else { }).catch(reject)
cb(null, this.sourceMappingDecoder.atIndex(index, sourceMap))
}
}) })
} }
...@@ -40,19 +38,21 @@ SourceLocationTracker.prototype.getSourceLocationFromInstructionIndex = function ...@@ -40,19 +38,21 @@ SourceLocationTracker.prototype.getSourceLocationFromInstructionIndex = function
* @param {Object} contractDetails - AST of compiled contracts * @param {Object} contractDetails - AST of compiled contracts
* @param {Function} cb - callback function * @param {Function} cb - callback function
*/ */
SourceLocationTracker.prototype.getSourceLocationFromVMTraceIndex = function (address, vmtraceStepIndex, contracts, cb) { SourceLocationTracker.prototype.getSourceLocationFromVMTraceIndex = function (address, vmtraceStepIndex, contracts) {
extractSourceMap(this, this.codeManager, address, contracts, (error, sourceMap) => { return new Promise((resolve, reject) => {
if (!error) { extractSourceMap(this, this.codeManager, address, contracts, (error, sourceMap) => {
this.codeManager.getInstructionIndex(address, vmtraceStepIndex, (error, index) => { if (!error) {
if (error) { this.codeManager.getInstructionIndex(address, vmtraceStepIndex, (error, index) => {
cb(error) if (error) {
} else { reject(error)
cb(null, this.sourceMappingDecoder.atIndex(index, sourceMap)) } else {
} resolve(this.sourceMappingDecoder.atIndex(index, sourceMap))
}) }
} else { })
cb(error) } else {
} reject(error)
}
})
}) })
} }
......
...@@ -90,8 +90,9 @@ TraceManager.prototype.getAddresses = function (callback) { ...@@ -90,8 +90,9 @@ TraceManager.prototype.getAddresses = function (callback) {
} }
TraceManager.prototype.getCallDataAt = function (stepIndex, callback) { TraceManager.prototype.getCallDataAt = function (stepIndex, callback) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null) return callback(check, null)
} }
const callDataChange = util.findLowerBoundValue(stepIndex, this.traceCache.callDataChanges) const callDataChange = util.findLowerBoundValue(stepIndex, this.traceCache.callDataChanges)
...@@ -100,8 +101,9 @@ TraceManager.prototype.getCallDataAt = function (stepIndex, callback) { ...@@ -100,8 +101,9 @@ TraceManager.prototype.getCallDataAt = function (stepIndex, callback) {
} }
TraceManager.prototype.buildCallPath = function (stepIndex, callback) { TraceManager.prototype.buildCallPath = function (stepIndex, callback) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null) return callback(check, null)
} }
const callsPath = util.buildCallPath(stepIndex, this.traceCache.callsTree.call) const callsPath = util.buildCallPath(stepIndex, this.traceCache.callsTree.call)
...@@ -109,19 +111,23 @@ TraceManager.prototype.buildCallPath = function (stepIndex, callback) { ...@@ -109,19 +111,23 @@ TraceManager.prototype.buildCallPath = function (stepIndex, callback) {
callback(null, callsPath) callback(null, callsPath)
} }
TraceManager.prototype.getCallStackAt = function (stepIndex, callback) { TraceManager.prototype.getCallStackAt = function (stepIndex) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
return callback(check, null) } catch (check) {
throw new Error(check)
} }
const call = util.findCall(stepIndex, this.traceCache.callsTree.call) const call = util.findCall(stepIndex, this.traceCache.callsTree.call)
if (call === null) return callback('no callstack found', null) if (call === null) {
callback(null, call.callStack) throw new Error('no callstack found')
}
return call.callStack
} }
TraceManager.prototype.getStackAt = function (stepIndex, callback) { TraceManager.prototype.getStackAt = function (stepIndex, callback) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null) return callback(check, null)
} }
let stack let stack
...@@ -134,35 +140,31 @@ TraceManager.prototype.getStackAt = function (stepIndex, callback) { ...@@ -134,35 +140,31 @@ TraceManager.prototype.getStackAt = function (stepIndex, callback) {
} }
} }
TraceManager.prototype.getLastCallChangeSince = function (stepIndex, callback) { TraceManager.prototype.getLastCallChangeSince = function (stepIndex) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
return callback(check, null) } catch (check) {
throw new Error(check)
} }
const callChange = util.findCall(stepIndex, this.traceCache.callsTree.call) const callChange = util.findCall(stepIndex, this.traceCache.callsTree.call)
if (callChange === null) { if (callChange === null) {
callback(null, 0) return 0
} else {
callback(null, callChange)
} }
return callChange
} }
TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex, callback) { TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
return callback(check, null) const resp = this.getLastCallChangeSince(stepIndex)
} if (!resp) {
this.getLastCallChangeSince(stepIndex, function (error, resp) { throw new Error('unable to get current called address. ' + stepIndex + ' does not match with a CALL')
if (error) {
callback(error, null)
} else {
if (resp) {
callback(null, resp.address)
} else {
callback('unable to get current called address. ' + stepIndex + ' does not match with a CALL')
}
} }
}) return resp.address
} catch (error) {
throw new Error(error)
}
} }
TraceManager.prototype.getContractCreationCode = function (token, callback) { TraceManager.prototype.getContractCreationCode = function (token, callback) {
...@@ -174,8 +176,9 @@ TraceManager.prototype.getContractCreationCode = function (token, callback) { ...@@ -174,8 +176,9 @@ TraceManager.prototype.getContractCreationCode = function (token, callback) {
} }
TraceManager.prototype.getMemoryAt = function (stepIndex, callback) { TraceManager.prototype.getMemoryAt = function (stepIndex, callback) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null) return callback(check, null)
} }
const lastChanges = util.findLowerBoundValue(stepIndex, this.traceCache.memoryChanges) const lastChanges = util.findLowerBoundValue(stepIndex, this.traceCache.memoryChanges)
...@@ -184,16 +187,18 @@ TraceManager.prototype.getMemoryAt = function (stepIndex, callback) { ...@@ -184,16 +187,18 @@ TraceManager.prototype.getMemoryAt = function (stepIndex, callback) {
} }
TraceManager.prototype.getCurrentPC = function (stepIndex, callback) { TraceManager.prototype.getCurrentPC = function (stepIndex, callback) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null) return callback(check, null)
} }
callback(null, this.trace[stepIndex].pc) callback(null, this.trace[stepIndex].pc)
} }
TraceManager.prototype.getReturnValue = function (stepIndex, callback) { TraceManager.prototype.getReturnValue = function (stepIndex, callback) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null) return callback(check, null)
} }
if (!this.traceCache.returnValues[stepIndex]) { if (!this.traceCache.returnValues[stepIndex]) {
...@@ -204,8 +209,9 @@ TraceManager.prototype.getReturnValue = function (stepIndex, callback) { ...@@ -204,8 +209,9 @@ TraceManager.prototype.getReturnValue = function (stepIndex, callback) {
} }
TraceManager.prototype.getCurrentStep = function (stepIndex, callback) { TraceManager.prototype.getCurrentStep = function (stepIndex, callback) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null) return callback(check, null)
} }
callback(null, this.traceCache.steps[stepIndex]) callback(null, this.traceCache.steps[stepIndex])
...@@ -224,8 +230,9 @@ TraceManager.prototype.getRemainingGas = function (stepIndex) { ...@@ -224,8 +230,9 @@ TraceManager.prototype.getRemainingGas = function (stepIndex) {
} }
TraceManager.prototype.getStepProperty = function (stepIndex, property) { TraceManager.prototype.getStepProperty = function (stepIndex, property) {
const check = this.checkRequestedStep(stepIndex) try {
if (check) { this.checkRequestedStep(stepIndex)
} catch (check) {
throw new Error(check) throw new Error(check)
} }
return this.trace[stepIndex][property] return this.trace[stepIndex][property]
...@@ -252,14 +259,12 @@ TraceManager.prototype.findStepOut = function (currentStep) { ...@@ -252,14 +259,12 @@ TraceManager.prototype.findStepOut = function (currentStep) {
return this.traceStepManager.findStepOut(currentStep) return this.traceStepManager.findStepOut(currentStep)
} }
// util
TraceManager.prototype.checkRequestedStep = function (stepIndex) { TraceManager.prototype.checkRequestedStep = function (stepIndex) {
if (!this.trace) { if (!this.trace) {
return 'trace not loaded' throw new Error('trace not loaded')
} else if (stepIndex >= this.trace.length) { } else if (stepIndex >= this.trace.length) {
return 'trace smaller than requested' throw new Error('trace smaller than requested')
} }
return undefined
} }
TraceManager.prototype.waterfall = function (calls, stepindex, cb) { TraceManager.prototype.waterfall = function (calls, stepindex, cb) {
......
...@@ -78,22 +78,20 @@ tape('TraceManager', function (t) { ...@@ -78,22 +78,20 @@ tape('TraceManager', function (t) {
t.test('TraceManager.getCallStackAt', function (st) { t.test('TraceManager.getCallStackAt', function (st) {
st.plan(3) st.plan(3)
traceManager.getCallStackAt(0, function (error, result) { try {
if (error) { const result = traceManager.getCallStackAt(0)
st.fail(error) st.ok(result[0] === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
} else { } catch (error) {
st.ok(result[0] === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') st.fail(error)
} }
})
traceManager.getCallStackAt(64, function (error, result) { try {
if (error) { const result = traceManager.getCallStackAt(64)
st.fail(error) st.ok(result.length === 2)
} else { st.ok(result[1] === '(Contract Creation - Step 63)')
st.ok(result.length === 2) } catch (error) {
st.ok(result[1] === '(Contract Creation - Step 63)') st.fail(error)
} }
})
}) })
t.test('TraceManager.getStackAt', function (st) { t.test('TraceManager.getStackAt', function (st) {
...@@ -120,64 +118,60 @@ tape('TraceManager', function (t) { ...@@ -120,64 +118,60 @@ tape('TraceManager', function (t) {
t.test('TraceManager.getLastCallChangeSince', function (st) { t.test('TraceManager.getLastCallChangeSince', function (st) {
st.plan(3) st.plan(3)
traceManager.getLastCallChangeSince(10, function (error, result) {
try {
const result = traceManager.getLastCallChangeSince(10)
console.log(result) console.log(result)
if (error) { st.ok(result.start === 0)
st.fail(error) } catch (error) {
} else { st.fail(error)
st.ok(result.start === 0) }
}
})
traceManager.getLastCallChangeSince(70, function (error, result) { try {
const result = traceManager.getLastCallChangeSince(70)
console.log(result) console.log(result)
if (error) { st.ok(result.start === 64)
st.fail(error) } catch (error) {
} else { st.fail(error)
st.ok(result.start === 64) }
}
})
traceManager.getLastCallChangeSince(111, function (error, result) { try {
const result = traceManager.getLastCallChangeSince(111)
console.log(result) console.log(result)
if (error) { st.ok(result.start === 0)
st.fail(error) // this was 109 before: 111 is targeting the root call (starting index 0)
} else { // this test make more sense as it is now (109 is the index of RETURN).
st.ok(result.start === 0) } catch (error) {
// this was 109 before: 111 is targeting the root call (starting index 0) st.fail(error)
// this test make more sense as it is now (109 is the index of RETURN). }
}
})
}) })
t.test('TraceManager.getCurrentCalledAddressAt', function (st) { t.test('TraceManager.getCurrentCalledAddressAt', function (st) {
st.plan(3) st.plan(3)
traceManager.getCurrentCalledAddressAt(10, function (error, result) {
try {
const result = traceManager.getCurrentCalledAddressAt(10)
console.log(result) console.log(result)
if (error) { st.ok(result === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
st.fail(error) } catch (error) {
} else { st.fail(error)
st.ok(result === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') }
}
})
traceManager.getCurrentCalledAddressAt(70, function (error, result) { try {
const result = traceManager.getCurrentCalledAddressAt(70)
console.log(result) console.log(result)
if (error) { st.ok(result === '(Contract Creation - Step 63)')
st.fail(error) } catch (error) {
} else { st.fail(error)
st.ok(result === '(Contract Creation - Step 63)') }
}
})
traceManager.getCurrentCalledAddressAt(111, function (error, result) { try {
const result = traceManager.getCurrentCalledAddressAt(111)
console.log(result) console.log(result)
if (error) { st.ok(result === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
st.fail(error) } catch (error) {
} else { st.fail(error)
st.ok(result === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') }
}
})
}) })
t.test('TraceManager.getContractCreationCode', function (st) { // contract code has been retrieved from the memory t.test('TraceManager.getContractCreationCode', function (st) { // contract code has been retrieved from the memory
......
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