Merge branch 'master' of https://github.com/ethereum/remix-project into contextmenu

pull/5370/head
filip mertens 4 years ago
commit eb62a5c572
  1. 4
      apps/remix-ide-e2e/src/tests/debugger.spec.ts
  2. 3
      libs/remix-debug/src/Ethdebugger.ts
  3. 11
      libs/remix-debug/src/debugger/solidityLocals.ts
  4. 10
      libs/remix-debug/src/solidity-decoder/internalCallTree.ts
  5. 4
      libs/remix-debug/src/solidity-decoder/localDecoder.ts
  6. 33
      libs/remix-debug/src/solidity-decoder/types/RefType.ts
  7. 4
      libs/remix-debug/src/solidity-decoder/types/StringType.ts
  8. 2
      libs/remix-debug/src/solidity-decoder/types/ValueType.ts
  9. 10
      libs/remix-debug/test/decoder/localsTests/helper.ts

@ -323,7 +323,7 @@ const localVariable_step266_ABIEncoder = { // eslint-disable-line
value: '0x0000000000000000000000000000000000000000000000000000000000000002' value: '0x0000000000000000000000000000000000000000000000000000000000000002'
}, },
userData: { userData: {
error: '<decoding failed - no decoder for calldata>', value: '0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000015b38da6a701c568545dcfcb03fcb875f56beddc4',
type: 'bytes' type: 'bytes'
} }
} }
@ -360,7 +360,7 @@ const localVariable_step717_ABIEncoder = { // eslint-disable-line
value: '0x5b38da6a701c568545dcfcb03fcb875f56beddc45b38da6a701c568545dcfcb03fcb875f56beddc400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001' value: '0x5b38da6a701c568545dcfcb03fcb875f56beddc45b38da6a701c568545dcfcb03fcb875f56beddc400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001'
}, },
userData: { userData: {
error: '<decoding failed - no decoder for calldata>', value: '0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000015b38da6a701c568545dcfcb03fcb875f56beddc4',
type: 'bytes' type: 'bytes'
} }
} }

@ -104,9 +104,10 @@ export class Ethdebugger {
const stack = this.traceManager.getStackAt(step) const stack = this.traceManager.getStackAt(step)
const memory = this.traceManager.getMemoryAt(step) const memory = this.traceManager.getMemoryAt(step)
const address = this.traceManager.getCurrentCalledAddressAt(step) const address = this.traceManager.getCurrentCalledAddressAt(step)
const calldata = this.traceManager.getCallDataAt(step)
try { try {
const storageViewer = new StorageViewer({ stepIndex: step, tx: this.tx, address: address }, this.storageResolver, this.traceManager) const storageViewer = new StorageViewer({ stepIndex: step, tx: this.tx, address: address }, this.storageResolver, this.traceManager)
const locals = await localDecoder.solidityLocals(step, this.callTree, stack, memory, storageViewer, sourceLocation, null) const locals = await localDecoder.solidityLocals(step, this.callTree, stack, memory, storageViewer, calldata, sourceLocation, null)
if (locals['error']) { if (locals['error']) {
return callback(locals['error']) return callback(locals['error'])
} }

@ -62,6 +62,14 @@ export class DebuggerSolidityLocals {
} catch (error) { } catch (error) {
next(error) next(error)
} }
},
function getCallDataAt (stepIndex, next) {
try {
const calldata = self.traceManager.getCallDataAt(stepIndex)
next(null, calldata)
} catch (error) {
next(error)
}
}], }],
this.stepManager.currentStepIndex, this.stepManager.currentStepIndex,
(error, result) => { (error, result) => {
@ -70,9 +78,10 @@ export class DebuggerSolidityLocals {
} }
var stack = result[0].value var stack = result[0].value
var memory = result[1].value var memory = result[1].value
var calldata = result[3].value
try { try {
var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: result[2].value }, this.storageResolver, this.traceManager) var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: result[2].value }, this.storageResolver, this.traceManager)
solidityLocals(this.stepManager.currentStepIndex, this.internalTreeCall, stack, memory, storageViewer, sourceLocation, cursor).then((locals) => { solidityLocals(this.stepManager.currentStepIndex, this.internalTreeCall, stack, memory, storageViewer, calldata, sourceLocation, cursor).then((locals) => {
if (!cursor) { if (!cursor) {
if (!locals['error']) { if (!locals['error']) {
this.event.trigger('solidityLocals', [locals]) this.event.trigger('solidityLocals', [locals])

@ -310,10 +310,10 @@ async function includeVariableDeclaration (tree, step, sourceLocation, scopeId,
// } // }
// input params // input params
if (inputs && inputs.parameters) { if (inputs && inputs.parameters) {
functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractObj.name, previousSourceLocation, stack.length, inputs.parameters.length, -1) functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractObj, previousSourceLocation, stack.length, inputs.parameters.length, -1)
} }
// output params // output params
if (outputs) addParams(outputs, tree, scopeId, states, contractObj.name, previousSourceLocation, stack.length, 0, 1) if (outputs) addParams(outputs, tree, scopeId, states, contractObj, previousSourceLocation, stack.length, 0, 1)
} }
} catch (error) { } catch (error) {
console.log(error) console.log(error)
@ -373,7 +373,8 @@ function extractFunctionDefinitions (ast, astWalker) {
return ret return ret
} }
function addParams (parameterList, tree, scopeId, states, contractName, sourceLocation, stackLength, stackPosition, dir) { function addParams (parameterList, tree, scopeId, states, contractObj, sourceLocation, stackLength, stackPosition, dir) {
const contractName = contractObj.name
const params = [] const params = []
for (const inputParam in parameterList.parameters) { for (const inputParam in parameterList.parameters) {
const param = parameterList.parameters[inputParam] const param = parameterList.parameters[inputParam]
@ -386,7 +387,8 @@ function addParams (parameterList, tree, scopeId, states, contractName, sourceLo
name: attributesName, name: attributesName,
type: parseType(param.typeDescriptions.typeString, states, contractName, location), type: parseType(param.typeDescriptions.typeString, states, contractName, location),
stackDepth: stackDepth, stackDepth: stackDepth,
sourceLocation: sourceLocation sourceLocation: sourceLocation,
abi: contractObj.contract.abi
} }
params.push(attributesName) params.push(attributesName)
} }

@ -1,6 +1,6 @@
'use strict' 'use strict'
export async function solidityLocals (vmtraceIndex, internalTreeCall, stack, memory, storageResolver, currentSourceLocation, cursor) { export async function solidityLocals (vmtraceIndex, internalTreeCall, stack, memory, storageResolver, calldata, currentSourceLocation, cursor) {
const scope = internalTreeCall.findScope(vmtraceIndex) const scope = internalTreeCall.findScope(vmtraceIndex)
if (!scope) { if (!scope) {
const error = { message: 'Can\'t display locals. reason: compilation result might not have been provided' } const error = { message: 'Can\'t display locals. reason: compilation result might not have been provided' }
@ -18,7 +18,7 @@ export async function solidityLocals (vmtraceIndex, internalTreeCall, stack, mem
anonymousIncr++ anonymousIncr++
} }
try { try {
locals[name] = await variable.type.decodeFromStack(variable.stackDepth, stack, memory, storageResolver, cursor) locals[name] = await variable.type.decodeFromStack(variable.stackDepth, stack, memory, storageResolver, calldata, cursor, variable)
} catch (e) { } catch (e) {
console.log(e) console.log(e)
locals[name] = '<decoding failed - ' + e.message + '>' locals[name] = '<decoding failed - ' + e.message + '>'

@ -1,4 +1,5 @@
'use strict' 'use strict'
import { ethers } from 'ethers'
import { toBN } from './util' import { toBN } from './util'
export class RefType { export class RefType {
@ -7,6 +8,7 @@ export class RefType {
storageBytes storageBytes
typeName typeName
basicType basicType
underlyingType
constructor (storageSlots, storageBytes, typeName, location) { constructor (storageSlots, storageBytes, typeName, location) {
this.location = location this.location = location
@ -33,7 +35,7 @@ export class RefType {
* @param {Object} - storageResolver * @param {Object} - storageResolver
* @return {Object} decoded value * @return {Object} decoded value
*/ */
async decodeFromStack (stackDepth, stack, memory, storageResolver, cursor): Promise<any> { async decodeFromStack (stackDepth, stack, memory, storageResolver, calldata, cursor, variableDetails?): Promise<any> {
if (stack.length - 1 < stackDepth) { if (stack.length - 1 < stackDepth) {
return { error: '<decoding failed - stack underflow ' + stackDepth + '>', type: this.typeName } return { error: '<decoding failed - stack underflow ' + stackDepth + '>', type: this.typeName }
} }
@ -49,6 +51,26 @@ export class RefType {
} else if (this.isInMemory()) { } else if (this.isInMemory()) {
offset = parseInt(offset, 16) offset = parseInt(offset, 16)
return this.decodeFromMemoryInternal(offset, memory, cursor) return this.decodeFromMemoryInternal(offset, memory, cursor)
} else if (this.isInCallData()) {
calldata = calldata.length > 0 ? calldata[0] : '0x'
const ethersAbi = new ethers.utils.Interface(variableDetails.abi)
const fnSign = calldata.substr(0, 10)
const decodedData = ethersAbi.decodeFunctionData(ethersAbi.getFunction(fnSign), calldata)
let decodedValue = decodedData[variableDetails.name]
const isArray = Array.isArray(decodedValue)
if (isArray) {
decodedValue = decodedValue.map((el) => {
return {
value: el.toString(),
type: this.underlyingType.typeName
}
})
}
return {
length: Array.isArray(decodedValue) ? '0x' + decodedValue.length.toString(16) : undefined,
value: decodedValue,
type: this.typeName
}
} else { } else {
return { error: '<decoding failed - no decoder for ' + this.location + '>', type: this.typeName } return { error: '<decoding failed - no decoder for ' + this.location + '>', type: this.typeName }
} }
@ -84,4 +106,13 @@ export class RefType {
isInMemory () { isInMemory () {
return this.location.indexOf('memory') === 0 return this.location.indexOf('memory') === 0
} }
/**
* current type defined in storage
*
* @return {Bool} - return true if the type is defined in the storage
*/
isInCallData () {
return this.location.indexOf('calldata') === 0
}
} }

@ -20,9 +20,9 @@ export class StringType extends DynamicByteArray {
return format(decoded) return format(decoded)
} }
async decodeFromStack (stackDepth, stack, memory) { async decodeFromStack (stackDepth, stack, memory, calldata, variableDetails?) {
try { try {
return await super.decodeFromStack(stackDepth, stack, memory, null, null) return await super.decodeFromStack(stackDepth, stack, memory, null, calldata, variableDetails)
} catch (e) { } catch (e) {
console.log(e) console.log(e)
return '<decoding failed - ' + e.message + '>' return '<decoding failed - ' + e.message + '>'

@ -43,7 +43,7 @@ export class ValueType {
* @param {String} - memory * @param {String} - memory
* @return {Object} - decoded value * @return {Object} - decoded value
*/ */
async decodeFromStack (stackDepth, stack, memory) { async decodeFromStack (stackDepth, stack, memory, calldata, variableDetails?) {
let value let value
if (stackDepth >= stack.length) { if (stackDepth >= stack.length) {
value = this.decodeValue('') value = this.decodeValue('')

@ -22,13 +22,21 @@ export function decodeLocals (st, index, traceManager, callTree, verifier) {
} catch (error) { } catch (error) {
callback(error) callback(error)
} }
},
function getCallDataAt (stepIndex, callback) {
try {
const result = traceManager.getCallDataAt(stepIndex)
callback(null, result)
} catch (error) {
callback(error)
}
}], }],
index, index,
function (error, result) { function (error, result) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
solidityLocals(index, callTree, result[0].value, result[1].value, {}, { start: 5000 }, null).then((locals) => { solidityLocals(index, callTree, result[0].value, result[1].value, {}, result[2].value, { start: 5000 }, null).then((locals) => {
verifier(locals) verifier(locals)
}) })
}) })

Loading…
Cancel
Save