From 8c6b6d10390f8fb6f84a14a6dc9facd8aa49c7d2 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 29 Nov 2016 15:48:40 +0100 Subject: [PATCH] fix step over, step into action --- src/trace/traceAnalyser.js | 16 ++------- src/trace/traceCache.js | 22 +++++++----- src/trace/traceManager.js | 12 ++----- src/trace/traceStepManager.js | 67 +++++++++-------------------------- test/traceManager.js | 14 -------- 5 files changed, 34 insertions(+), 97 deletions(-) diff --git a/src/trace/traceAnalyser.js b/src/trace/traceAnalyser.js index cdc3839545..bba3dc13d4 100644 --- a/src/trace/traceAnalyser.js +++ b/src/trace/traceAnalyser.js @@ -16,11 +16,7 @@ TraceAnalyser.prototype.analyse = function (trace, tx, callback) { lastCallIndex: 0 } var callStack = [tx.to] - this.traceCache.pushCallChanges(0, 0, callStack[0]) - this.traceCache.pushCallStack(0, { - callStack: callStack.slice(0) - }) - + this.traceCache.pushCall(trace[0], 0, callStack[0], callStack.slice(0)) if (traceHelper.isContractCreation(tx.to)) { this.traceCache.pushContractCreation(tx.to, tx.input) } @@ -110,10 +106,7 @@ TraceAnalyser.prototype.buildDepth = function (index, step, tx, callStack, conte 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, newAddress) - this.traceCache.pushCallStack(index + 1, { - callStack: callStack.slice(0) - }) + this.traceCache.pushCall(step, index + 1, newAddress, callStack.slice(0)) this.buildCalldata(index, step, tx, true) this.traceCache.pushSteps(index, context.currentCallIndex) context.lastCallIndex = context.currentCallIndex @@ -121,10 +114,7 @@ TraceAnalyser.prototype.buildDepth = function (index, step, tx, callStack, conte } else if (traceHelper.isReturnInstruction(step) || traceHelper.isStopInstruction(step)) { if (index + 1 < this.trace.length) { callStack.pop() - this.traceCache.pushCallChanges(step, index + 1) - this.traceCache.pushCallStack(index + 1, { - callStack: callStack.slice(0) - }) + this.traceCache.pushCall(step, index + 1, null, callStack.slice(0)) this.buildCalldata(index, step, tx, false) this.traceCache.pushSteps(index, context.currentCallIndex) context.currentCallIndex = context.lastCallIndex + 1 diff --git a/src/trace/traceCache.js b/src/trace/traceCache.js index 040c0919bb..e6f7459c09 100644 --- a/src/trace/traceCache.js +++ b/src/trace/traceCache.js @@ -9,6 +9,7 @@ TraceCache.prototype.init = function () { this.returnValues = {} this.callChanges = [] this.calls = {} + this.callsRef = [0] // track of calls during the vm trace analysis this.callsData = {} this.contractCreation = {} this.steps = {} @@ -18,7 +19,6 @@ TraceCache.prototype.init = function () { this.memoryChanges = [] this.storageChanges = [] this.sstore = {} // all sstore occurence in the trace - this.callStack = {} // contains all callStack by vmtrace index (we need to rebuild it, callstack is not included in the vmtrace) } TraceCache.prototype.pushSteps = function (index, currentCallIndex) { @@ -34,11 +34,19 @@ TraceCache.prototype.pushMemoryChanges = function (value) { this.memoryChanges.push(value) } -TraceCache.prototype.pushCallChanges = function (step, value, address) { - this.callChanges.push(value) - this.calls[value] = { +TraceCache.prototype.pushCall = function (step, index, address, callStack) { + this.callChanges.push(index) + this.calls[index] = { op: step.op, - address: address + address: address, + callStack: callStack + } + if (step.op === 'RETURN' || step.op === 'STOP') { + var call = this.callsRef.pop() + this.calls[index].call = call + this.calls[call].return = index + } else { + this.callsRef.push(index) } } @@ -58,10 +66,6 @@ TraceCache.prototype.pushContractCreation = function (token, code) { this.contractCreation[token] = code } -TraceCache.prototype.pushCallStack = function (index, callStack) { - this.callStack[index] = callStack -} - TraceCache.prototype.pushStoreChanges = function (index, address, key, value) { this.sstore[index] = { 'address': address, diff --git a/src/trace/traceManager.js b/src/trace/traceManager.js index 56e535efc0..fcecd09ed1 100644 --- a/src/trace/traceManager.js +++ b/src/trace/traceManager.js @@ -135,7 +135,7 @@ TraceManager.prototype.getCallStackAt = function (stepIndex, callback) { } var callStackChange = util.findLowerBoundValue(stepIndex, this.traceCache.callChanges) if (callStackChange === null) return callback('no callstack found', null) - callback(null, this.traceCache.callStack[callStackChange].callStack) + callback(null, this.traceCache.calls[callStackChange].callStack) } TraceManager.prototype.getStackAt = function (stepIndex, callback) { @@ -179,7 +179,7 @@ TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex, callback if (addressIndex === 0) { callback(null, self.tx.to) } else { - var callStack = self.traceCache.callStack[addressIndex].callStack + var callStack = self.traceCache.calls[addressIndex].callStack var calledAddress = callStack[callStack.length - 1] if (calledAddress) { callback(null, calledAddress) @@ -274,14 +274,6 @@ TraceManager.prototype.findStepOverForward = function (currentStep) { return this.traceStepManager.findStepOverForward(currentStep) } -TraceManager.prototype.findStepOutBack = function (currentStep) { - return this.traceStepManager.findStepOutBack(currentStep) -} - -TraceManager.prototype.findStepOutForward = function (currentStep) { - return this.traceStepManager.findStepOutForward(currentStep) -} - TraceManager.prototype.findNextCall = function (currentStep) { return this.traceStepManager.findNextCall(currentStep) } diff --git a/src/trace/traceStepManager.js b/src/trace/traceStepManager.js index 5f20aa25d2..1a1b641126 100644 --- a/src/trace/traceStepManager.js +++ b/src/trace/traceStepManager.js @@ -1,5 +1,6 @@ 'use strict' var traceHelper = require('../helpers/traceHelper') +var util = require('../helpers/util') function TraceStepManager (_traceAnalyser) { this.traceAnalyser = _traceAnalyser @@ -16,66 +17,30 @@ TraceStepManager.prototype.isReturnInstruction = function (index) { } TraceStepManager.prototype.findStepOverBack = function (currentStep) { - if (currentStep === 0) return 0 - return this.findStepOutBack(currentStep) -} - -TraceStepManager.prototype.findStepOverForward = function (currentStep) { - if (currentStep === this.traceAnalyser.trace.length - 1) return currentStep - return this.findStepOutForward(currentStep) -} - -TraceStepManager.prototype.findStepOutBack = function (currentStep) { - if (!this.traceAnalyser.trace) { - return currentStep + if (this.isReturnInstruction(currentStep - 1)) { + return this.traceAnalyser.traceCache.calls[currentStep].call - 1 + } else { + return currentStep > 0 ? currentStep - 1 : 0 } - var i = currentStep - 1 - var depth = 0 - while (--i >= 0) { - if (this.isCallInstruction(i)) { - if (depth === 0) { - break - } else { - depth-- - } - } else if (this.isReturnInstruction(i)) { - depth++ - } - } - return i } -TraceStepManager.prototype.findStepOutForward = function (currentStep) { - if (!this.traceAnalyser.trace) { - return currentStep - } - var i = currentStep - var depth = 0 - while (++i < this.traceAnalyser.trace.length) { - if (this.isReturnInstruction(i)) { - if (depth === 0) { - break - } else { - depth-- - } - } else if (this.isCallInstruction(i)) { - depth++ - } +TraceStepManager.prototype.findStepOverForward = function (currentStep) { + if (this.isCallInstruction(currentStep)) { + return this.traceAnalyser.traceCache.calls[currentStep + 1].return + } else { + return this.traceAnalyser.trace.length >= currentStep + 1 ? currentStep + 1 : currentStep } - return i } TraceStepManager.prototype.findNextCall = function (currentStep) { - if (!this.traceAnalyser.trace) { + var callChanges = this.traceAnalyser.traceCache.callChanges + var stepIndex = util.findLowerBound(currentStep, callChanges) + var callchange = callChanges[stepIndex + 1] + if (callchange && this.isCallInstruction(callchange - 1)) { + return callchange - 1 + } else { return currentStep } - var i = currentStep - while (++i < this.traceAnalyser.trace.length) { - if (this.isCallInstruction(i)) { - return i - } - } - return currentStep } module.exports = TraceStepManager diff --git a/test/traceManager.js b/test/traceManager.js index facb586eca..0fe47dae96 100644 --- a/test/traceManager.js +++ b/test/traceManager.js @@ -286,20 +286,6 @@ tape('TraceManager', function (t) { st.end() }) - t.test('TraceManager.findStepOutBack', function (st) { - var result = traceManager.findStepOutBack(70) - console.log(result) - st.ok(result === 63) - st.end() - }) - - t.test('TraceManager.findStepOutForward', function (st) { - var result = traceManager.findStepOutForward(15) - console.log(result) - st.ok(result === 142) - st.end() - }) - t.test('TraceManager.findNextCall', function (st) { var result = traceManager.findNextCall(10) console.log(result)