Commit d2161740 authored by aniket-engg's avatar aniket-engg Committed by Aniket

trace analyser, cache and helper updated

parent 1187d4ad
This diff is collapsed.
...@@ -2,116 +2,129 @@ ...@@ -2,116 +2,129 @@
const remixLib = require('@remix-project/remix-lib') const remixLib = require('@remix-project/remix-lib')
const helper = remixLib.util const helper = remixLib.util
function TraceCache () { export class TraceCache {
this.init()
}
TraceCache.prototype.init = function () { returnValues
// ...Changes contains index in the vmtrace of the corresponding changes currentCall
callsTree
this.returnValues = {} callsData
this.currentCall = null contractCreation
this.callsTree = null steps
this.callsData = {} addresses
this.contractCreation = {} callDataChanges
this.steps = {} memoryChanges
this.addresses = [] storageChanges
sstore
this.callDataChanges = []
this.memoryChanges = []
this.storageChanges = []
this.sstore = {} // all sstore occurence in the trace
}
TraceCache.prototype.pushSteps = function (index, currentCallIndex) { constructor() {
this.steps[index] = currentCallIndex this.init()
} }
TraceCache.prototype.pushCallDataChanges = function (value, calldata) {
this.callDataChanges.push(value)
this.callsData[value] = calldata
}
TraceCache.prototype.pushMemoryChanges = function (value) { init () {
this.memoryChanges.push(value) // ...Changes contains index in the vmtrace of the corresponding changes
}
// outOfGas has been removed because gas left logging is apparently made differently this.returnValues = {}
// in the vm/geth/eth. TODO add the error property (with about the error in all clients) this.currentCall = null
TraceCache.prototype.pushCall = function (step, index, address, callStack, reverted) { this.callsTree = null
let validReturnStep = step.op === 'RETURN' || step.op === 'STOP' this.callsData = {}
if ((validReturnStep || reverted) && (this.currentCall)) { this.contractCreation = {}
this.currentCall.call.return = index - 1 this.steps = {}
if (!validReturnStep) { this.addresses = []
this.currentCall.call.reverted = reverted this.callDataChanges = []
} this.memoryChanges = []
var parent = this.currentCall.parent this.storageChanges = []
this.currentCall = parent ? { call: parent.call, parent: parent.parent } : null this.sstore = {} // all sstore occurence in the trace
return
} }
let call = {
op: step.op, pushSteps (index, currentCallIndex) {
address: address, this.steps[index] = currentCallIndex
callStack: callStack,
calls: {},
start: index
} }
this.addresses.push(address)
if (this.currentCall) { pushCallDataChanges (value, calldata) {
this.currentCall.call.calls[index] = call this.callDataChanges.push(value)
} else { this.callsData[value] = calldata
this.callsTree = { call: call }
} }
this.currentCall = { call: call, parent: this.currentCall }
}
TraceCache.prototype.pushReturnValue = function (step, value) { pushMemoryChanges (value) {
this.returnValues[step] = value this.memoryChanges.push(value)
} }
TraceCache.prototype.pushContractCreationFromMemory = function (index, token, trace, lastMemoryChange) { // outOfGas has been removed because gas left logging is apparently made differently
const memory = trace[lastMemoryChange].memory // in the vm/geth/eth. TODO add the error property (with about the error in all clients)
const stack = trace[index].stack pushCall (step, index, address, callStack, reverted) {
const offset = 2 * parseInt(stack[stack.length - 2], 16) let validReturnStep = step.op === 'RETURN' || step.op === 'STOP'
const size = 2 * parseInt(stack[stack.length - 3], 16) if ((validReturnStep || reverted) && (this.currentCall)) {
this.contractCreation[token] = '0x' + memory.join('').substr(offset, size) this.currentCall.call.return = index - 1
} if (!validReturnStep) {
this.currentCall.call.reverted = reverted
}
var parent = this.currentCall.parent
this.currentCall = parent ? { call: parent.call, parent: parent.parent } : null
return
}
let call = {
op: step.op,
address: address,
callStack: callStack,
calls: {},
start: index
}
this.addresses.push(address)
if (this.currentCall) {
this.currentCall.call.calls[index] = call
} else {
this.callsTree = { call: call }
}
this.currentCall = { call: call, parent: this.currentCall }
}
TraceCache.prototype.pushContractCreation = function (token, code) { pushReturnValue (step, value) {
this.contractCreation[token] = code this.returnValues[step] = value
} }
TraceCache.prototype.resetStoreChanges = function (index, address, key, value) { pushContractCreationFromMemory (index, token, trace, lastMemoryChange) {
this.sstore = {} const memory = trace[lastMemoryChange].memory
this.storageChanges = [] const stack = trace[index].stack
} const offset = 2 * parseInt(stack[stack.length - 2], 16)
const size = 2 * parseInt(stack[stack.length - 3], 16)
this.contractCreation[token] = '0x' + memory.join('').substr(offset, size)
}
TraceCache.prototype.pushStoreChanges = function (index, address, key, value) { pushContractCreation (token, code) {
this.sstore[index] = { this.contractCreation[token] = code
'address': address, }
'key': key,
'value': value, resetStoreChanges (index, address, key, value) {
'hashedKey': helper.sha3_256(key) this.sstore = {}
this.storageChanges = []
} }
this.storageChanges.push(index)
}
TraceCache.prototype.accumulateStorageChanges = function (index, address, storage) { pushStoreChanges (index, address, key, value) {
const ret = Object.assign({}, storage) this.sstore[index] = {
for (var k in this.storageChanges) { 'address': address,
const changesIndex = this.storageChanges[k] 'key': key,
if (changesIndex > index) { 'value': value,
return ret 'hashedKey': helper.sha3_256(key)
} }
var sstore = this.sstore[changesIndex] this.storageChanges.push(index)
if (sstore.address === address && sstore.key) { }
ret[sstore.hashedKey] = {
key: sstore.key, accumulateStorageChanges (index, address, storage) {
value: sstore.value const ret = Object.assign({}, storage)
for (var k in this.storageChanges) {
const changesIndex = this.storageChanges[k]
if (changesIndex > index) {
return ret
}
var sstore = this.sstore[changesIndex]
if (sstore.address === address && sstore.key) {
ret[sstore.hashedKey] = {
key: sstore.key,
value: sstore.value
}
} }
} }
return ret
} }
return ret
} }
module.exports = TraceCache
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
const remixLib = require('@remix-project/remix-lib') const remixLib = require('@remix-project/remix-lib')
const ui = remixLib.helpers.ui const ui = remixLib.helpers.ui
module.exports = { export = {
// vmTraceIndex has to point to a CALL, CODECALL, ... // vmTraceIndex has to point to a CALL, CODECALL, ...
resolveCalledAddress: function (vmTraceIndex, trace) { resolveCalledAddress: function (vmTraceIndex, trace) {
const step = trace[vmTraceIndex] const step = trace[vmTraceIndex]
......
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