Commit 80b87ef2 authored by aniket-engg's avatar aniket-engg Committed by Aniket

traceManager and traceStepManager updated

parent d2161740
...@@ -7,18 +7,27 @@ const traceHelper = require('./traceHelper') ...@@ -7,18 +7,27 @@ const traceHelper = require('./traceHelper')
const remixLib = require('@remix-project/remix-lib') const remixLib = require('@remix-project/remix-lib')
const util = remixLib.util const util = remixLib.util
function TraceManager (options) { export class TraceManager {
web3
isLoading: boolean
trace
traceCache
traceAnalyser
traceStepManager
tx
constructor (options) {
this.web3 = options.web3 this.web3 = options.web3
this.isLoading = false this.isLoading = false
this.trace = null this.trace = null
this.traceCache = new TraceCache() this.traceCache = new TraceCache()
this.traceAnalyser = new TraceAnalyser(this.traceCache) this.traceAnalyser = new TraceAnalyser(this.traceCache)
this.traceStepManager = new TraceStepManager(this.traceAnalyser) this.traceStepManager = new TraceStepManager(this.traceAnalyser)
this.tx }
}
// init section // init section
TraceManager.prototype.resolveTrace = async function (tx) { async resolveTrace (tx) {
this.tx = tx this.tx = tx
this.init() this.init()
if (!this.web3) throw new Error('web3 not loaded') if (!this.web3) throw new Error('web3 not loaded')
...@@ -26,10 +35,10 @@ TraceManager.prototype.resolveTrace = async function (tx) { ...@@ -26,10 +35,10 @@ TraceManager.prototype.resolveTrace = async function (tx) {
try { try {
const result = await this.getTrace(tx.hash) const result = await this.getTrace(tx.hash)
if (result.structLogs.length > 0) { if (result['structLogs'].length > 0) {
this.trace = result.structLogs this.trace = result['structLogs']
this.traceAnalyser.analyse(result.structLogs, tx) this.traceAnalyser.analyse(result['structLogs'], tx)
this.isLoading = false this.isLoading = false
return true return true
} }
...@@ -42,9 +51,9 @@ TraceManager.prototype.resolveTrace = async function (tx) { ...@@ -42,9 +51,9 @@ TraceManager.prototype.resolveTrace = async function (tx) {
this.isLoading = false this.isLoading = false
throw new Error(error) throw new Error(error)
} }
} }
TraceManager.prototype.getTrace = function (txHash) { getTrace (txHash) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const options = { const options = {
disableStorage: true, disableStorage: true,
...@@ -57,39 +66,39 @@ TraceManager.prototype.getTrace = function (txHash) { ...@@ -57,39 +66,39 @@ TraceManager.prototype.getTrace = function (txHash) {
resolve(result) resolve(result)
}) })
}) })
} }
TraceManager.prototype.init = function () { init () {
this.trace = null this.trace = null
this.traceCache.init() this.traceCache.init()
} }
// API section // API section
TraceManager.prototype.inRange = function (step) { inRange (step) {
return this.isLoaded() && step >= 0 && step < this.trace.length return this.isLoaded() && step >= 0 && step < this.trace.length
} }
TraceManager.prototype.isLoaded = function () { isLoaded () {
return !this.isLoading && this.trace !== null return !this.isLoading && this.trace !== null
} }
TraceManager.prototype.getLength = function (callback) { getLength (callback) {
if (!this.trace) { if (!this.trace) {
callback('no trace available', null) callback('no trace available', null)
} else { } else {
callback(null, this.trace.length) callback(null, this.trace.length)
} }
} }
TraceManager.prototype.accumulateStorageChanges = function (index, address, storageOrigin) { accumulateStorageChanges (index, address, storageOrigin) {
return this.traceCache.accumulateStorageChanges(index, address, storageOrigin) return this.traceCache.accumulateStorageChanges(index, address, storageOrigin)
} }
TraceManager.prototype.getAddresses = function () { getAddresses () {
return this.traceCache.addresses return this.traceCache.addresses
} }
TraceManager.prototype.getCallDataAt = function (stepIndex) { getCallDataAt (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
...@@ -100,9 +109,9 @@ TraceManager.prototype.getCallDataAt = function (stepIndex) { ...@@ -100,9 +109,9 @@ TraceManager.prototype.getCallDataAt = function (stepIndex) {
throw new Error('no calldata found') throw new Error('no calldata found')
} }
return [this.traceCache.callsData[callDataChange]] return [this.traceCache.callsData[callDataChange]]
} }
TraceManager.prototype.buildCallPath = async function (stepIndex) { async buildCallPath (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
...@@ -111,9 +120,9 @@ TraceManager.prototype.buildCallPath = async function (stepIndex) { ...@@ -111,9 +120,9 @@ TraceManager.prototype.buildCallPath = async function (stepIndex) {
const callsPath = util.buildCallPath(stepIndex, this.traceCache.callsTree.call) const callsPath = util.buildCallPath(stepIndex, this.traceCache.callsTree.call)
if (callsPath === null) throw new Error('no call path built') if (callsPath === null) throw new Error('no call path built')
return callsPath return callsPath
} }
TraceManager.prototype.getCallStackAt = function (stepIndex) { getCallStackAt (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
...@@ -124,9 +133,9 @@ TraceManager.prototype.getCallStackAt = function (stepIndex) { ...@@ -124,9 +133,9 @@ TraceManager.prototype.getCallStackAt = function (stepIndex) {
throw new Error('no callstack found') throw new Error('no callstack found')
} }
return call.callStack return call.callStack
} }
TraceManager.prototype.getStackAt = function (stepIndex) { getStackAt (stepIndex) {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
if (this.trace[stepIndex] && this.trace[stepIndex].stack) { // there's always a stack if (this.trace[stepIndex] && this.trace[stepIndex].stack) { // there's always a stack
let stack = this.trace[stepIndex].stack.slice(0) let stack = this.trace[stepIndex].stack.slice(0)
...@@ -135,9 +144,9 @@ TraceManager.prototype.getStackAt = function (stepIndex) { ...@@ -135,9 +144,9 @@ TraceManager.prototype.getStackAt = function (stepIndex) {
} else { } else {
throw new Error('no stack found') throw new Error('no stack found')
} }
} }
TraceManager.prototype.getLastCallChangeSince = function (stepIndex) { getLastCallChangeSince (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
...@@ -149,9 +158,9 @@ TraceManager.prototype.getLastCallChangeSince = function (stepIndex) { ...@@ -149,9 +158,9 @@ TraceManager.prototype.getLastCallChangeSince = function (stepIndex) {
return 0 return 0
} }
return callChange return callChange
} }
TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex) { getCurrentCalledAddressAt (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
const resp = this.getLastCallChangeSince(stepIndex) const resp = this.getLastCallChangeSince(stepIndex)
...@@ -162,34 +171,34 @@ TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex) { ...@@ -162,34 +171,34 @@ TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex) {
} catch (error) { } catch (error) {
throw new Error(error) throw new Error(error)
} }
} }
TraceManager.prototype.getContractCreationCode = function (token) { getContractCreationCode (token) {
if (!this.traceCache.contractCreation[token]) { if (!this.traceCache.contractCreation[token]) {
throw new Error('no contract creation named ' + token) throw new Error('no contract creation named ' + token)
} }
return this.traceCache.contractCreation[token] return this.traceCache.contractCreation[token]
} }
TraceManager.prototype.getMemoryAt = function (stepIndex) { getMemoryAt (stepIndex) {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
const lastChanges = util.findLowerBoundValue(stepIndex, this.traceCache.memoryChanges) const lastChanges = util.findLowerBoundValue(stepIndex, this.traceCache.memoryChanges)
if (lastChanges === null) { if (lastChanges === null) {
throw new Error('no memory found') throw new Error('no memory found')
} }
return this.trace[lastChanges].memory return this.trace[lastChanges].memory
} }
TraceManager.prototype.getCurrentPC = function (stepIndex) { getCurrentPC (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
throw new Error(check) throw new Error(check)
} }
return this.trace[stepIndex].pc return this.trace[stepIndex].pc
} }
TraceManager.prototype.getReturnValue = function (stepIndex) { getReturnValue (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
...@@ -199,68 +208,68 @@ TraceManager.prototype.getReturnValue = function (stepIndex) { ...@@ -199,68 +208,68 @@ TraceManager.prototype.getReturnValue = function (stepIndex) {
throw new Error('current step is not a return step') throw new Error('current step is not a return step')
} }
return this.traceCache.returnValues[stepIndex] return this.traceCache.returnValues[stepIndex]
} }
TraceManager.prototype.getCurrentStep = function (stepIndex) { getCurrentStep (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
throw new Error(check) throw new Error(check)
} }
return this.traceCache.steps[stepIndex] return this.traceCache.steps[stepIndex]
} }
TraceManager.prototype.getMemExpand = function (stepIndex) { getMemExpand (stepIndex) {
return (this.getStepProperty(stepIndex, 'memexpand') || '') return (this.getStepProperty(stepIndex, 'memexpand') || '')
} }
TraceManager.prototype.getStepCost = function (stepIndex) { getStepCost (stepIndex) {
return this.getStepProperty(stepIndex, 'gasCost') return this.getStepProperty(stepIndex, 'gasCost')
} }
TraceManager.prototype.getRemainingGas = function (stepIndex) { getRemainingGas (stepIndex) {
return this.getStepProperty(stepIndex, 'gas') return this.getStepProperty(stepIndex, 'gas')
} }
TraceManager.prototype.getStepProperty = function (stepIndex, property) { getStepProperty (stepIndex, property) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
throw new Error(check) throw new Error(check)
} }
return this.trace[stepIndex][property] return this.trace[stepIndex][property]
} }
TraceManager.prototype.isCreationStep = function (stepIndex) { isCreationStep (stepIndex) {
return traceHelper.isCreateInstruction(this.trace[stepIndex]) return traceHelper.isCreateInstruction(this.trace[stepIndex])
} }
// step section // step section
TraceManager.prototype.findStepOverBack = function (currentStep) { findStepOverBack (currentStep) {
return this.traceStepManager.findStepOverBack(currentStep) return this.traceStepManager.findStepOverBack(currentStep)
} }
TraceManager.prototype.findStepOverForward = function (currentStep) { findStepOverForward (currentStep) {
return this.traceStepManager.findStepOverForward(currentStep) return this.traceStepManager.findStepOverForward(currentStep)
} }
TraceManager.prototype.findNextCall = function (currentStep) { findNextCall (currentStep) {
return this.traceStepManager.findNextCall(currentStep) return this.traceStepManager.findNextCall(currentStep)
} }
TraceManager.prototype.findStepOut = function (currentStep) { findStepOut (currentStep) {
return this.traceStepManager.findStepOut(currentStep) return this.traceStepManager.findStepOut(currentStep)
} }
TraceManager.prototype.checkRequestedStep = function (stepIndex) { checkRequestedStep (stepIndex) {
if (!this.trace) { if (!this.trace) {
throw new Error('trace not loaded') throw new Error('trace not loaded')
} else if (stepIndex >= this.trace.length) { } else if (stepIndex >= this.trace.length) {
throw new Error('trace smaller than requested') throw new Error('trace smaller than requested')
} }
} }
TraceManager.prototype.waterfall = function (calls, stepindex, cb) { waterfall (calls, stepindex, cb) {
let ret = [] let ret = []
let retError = null let retError = null
for (var call in calls) { for (var call in calls) {
...@@ -270,6 +279,5 @@ TraceManager.prototype.waterfall = function (calls, stepindex, cb) { ...@@ -270,6 +279,5 @@ TraceManager.prototype.waterfall = function (calls, stepindex, cb) {
}]) }])
} }
cb(retError, ret) cb(retError, ret)
}
} }
module.exports = TraceManager
...@@ -4,52 +4,55 @@ const traceHelper = require('./traceHelper') ...@@ -4,52 +4,55 @@ const traceHelper = require('./traceHelper')
const remixLib = require('@remix-project/remix-lib') const remixLib = require('@remix-project/remix-lib')
const util = remixLib.util const util = remixLib.util
function TraceStepManager (_traceAnalyser) { export class TraceStepManager {
traceAnalyser
constructor (_traceAnalyser) {
this.traceAnalyser = _traceAnalyser this.traceAnalyser = _traceAnalyser
} }
TraceStepManager.prototype.isCallInstruction = function (index) { isCallInstruction (index) {
const state = this.traceAnalyser.trace[index] const state = this.traceAnalyser.trace[index]
return traceHelper.isCallInstruction(state) && !traceHelper.isCallToPrecompiledContract(index, this.traceAnalyser.trace) return traceHelper.isCallInstruction(state) && !traceHelper.isCallToPrecompiledContract(index, this.traceAnalyser.trace)
} }
TraceStepManager.prototype.isReturnInstruction = function (index) { isReturnInstruction (index) {
const state = this.traceAnalyser.trace[index] const state = this.traceAnalyser.trace[index]
return traceHelper.isReturnInstruction(state) return traceHelper.isReturnInstruction(state)
} }
TraceStepManager.prototype.findStepOverBack = function (currentStep) { findStepOverBack (currentStep) {
if (this.isReturnInstruction(currentStep)) { if (this.isReturnInstruction(currentStep)) {
const call = util.findCall(currentStep, this.traceAnalyser.traceCache.callsTree.call) const call = util.findCall(currentStep, this.traceAnalyser.traceCache.callsTree.call)
return call.start > 0 ? call.start - 1 : 0 return call.start > 0 ? call.start - 1 : 0
} }
return currentStep > 0 ? currentStep - 1 : 0 return currentStep > 0 ? currentStep - 1 : 0
} }
TraceStepManager.prototype.findStepOverForward = function (currentStep) { findStepOverForward (currentStep) {
if (this.isCallInstruction(currentStep)) { if (this.isCallInstruction(currentStep)) {
const call = util.findCall(currentStep + 1, this.traceAnalyser.traceCache.callsTree.call) const call = util.findCall(currentStep + 1, this.traceAnalyser.traceCache.callsTree.call)
return call.return + 1 < this.traceAnalyser.trace.length ? call.return + 1 : this.traceAnalyser.trace.length - 1 return call.return + 1 < this.traceAnalyser.trace.length ? call.return + 1 : this.traceAnalyser.trace.length - 1
} }
return this.traceAnalyser.trace.length >= currentStep + 1 ? currentStep + 1 : currentStep return this.traceAnalyser.trace.length >= currentStep + 1 ? currentStep + 1 : currentStep
} }
TraceStepManager.prototype.findNextCall = function (currentStep) { findNextCall (currentStep) {
const call = util.findCall(currentStep, this.traceAnalyser.traceCache.callsTree.call) const call = util.findCall(currentStep, this.traceAnalyser.traceCache.callsTree.call)
const subCalls = Object.keys(call.calls) const subCalls = Object.keys(call.calls)
if (subCalls.length) { if (subCalls.length) {
var callStart = util.findLowerBound(currentStep, subCalls) + 1 var callStart = util.findLowerBound(currentStep, subCalls) + 1
if (subCalls.length > callStart) { if (subCalls.length > callStart) {
return subCalls[callStart] - 1 return parseInt(subCalls[callStart]) - 1
} }
return currentStep return currentStep
} }
return currentStep return currentStep
} }
TraceStepManager.prototype.findStepOut = function (currentStep) { findStepOut (currentStep) {
const call = util.findCall(currentStep, this.traceAnalyser.traceCache.callsTree.call) const call = util.findCall(currentStep, this.traceAnalyser.traceCache.callsTree.call)
return call.return return call.return
}
} }
module.exports = TraceStepManager
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