From cd5a4ad55d93f7624bdc324e4474a707fbdaa393 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 17 May 2021 10:58:33 +0200 Subject: [PATCH 1/5] refactor calldata decoding & fix nested array decoding --- .../src/solidity-decoder/types/RefType.ts | 54 ++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/libs/remix-debug/src/solidity-decoder/types/RefType.ts b/libs/remix-debug/src/solidity-decoder/types/RefType.ts index 031d52f295..dd9d0fc98a 100644 --- a/libs/remix-debug/src/solidity-decoder/types/RefType.ts +++ b/libs/remix-debug/src/solidity-decoder/types/RefType.ts @@ -52,27 +52,45 @@ export class RefType { offset = parseInt(offset, 16) 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 this._decodeFromCallData(variableDetails, calldata) + } else { + return { error: '', type: this.typeName } + } + } + + _decodeFromCallData (variableDetails, calldata) { + 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) { + return this._decodeCallDataArray(decodedValue, this) + } + return { + length: isArray ? '0x' + decodedValue.length.toString(16) : undefined, + value: decodedValue, + type: this.typeName + } + } + + _decodeCallDataArray (value, type) { + const isArray = Array.isArray(value) + if (isArray) { + value = value.map((el) => { + return this._decodeCallDataArray(el, this.underlyingType) + }) return { - length: Array.isArray(decodedValue) ? '0x' + decodedValue.length.toString(16) : undefined, - value: decodedValue, - type: this.typeName + length: value.length.toString(16), + value: value, + type: type.typeName } } else { - return { error: '', type: this.typeName } + return { + value: value.toString(), + type: type.underlyingType.typeName + } } } From 956c03ed5bb6693387978e7f2028bc458c42d2bd Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 17 May 2021 14:48:26 +0200 Subject: [PATCH 2/5] linting --- libs/remix-debug/src/solidity-decoder/types/RefType.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-debug/src/solidity-decoder/types/RefType.ts b/libs/remix-debug/src/solidity-decoder/types/RefType.ts index dd9d0fc98a..299c4f8d6a 100644 --- a/libs/remix-debug/src/solidity-decoder/types/RefType.ts +++ b/libs/remix-debug/src/solidity-decoder/types/RefType.ts @@ -63,10 +63,10 @@ export class RefType { 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 decodedValue = decodedData[variableDetails.name] const isArray = Array.isArray(decodedValue) if (isArray) { - return this._decodeCallDataArray(decodedValue, this) + return this._decodeCallDataArray(decodedValue, this) } return { length: isArray ? '0x' + decodedValue.length.toString(16) : undefined, From f68eecfb8b4261ebbc4ef85c80f8ca6177c9e82f Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 12:31:38 +0200 Subject: [PATCH 3/5] refactor unitest --- .../test/decoder/contracts/calldata.ts | 13 ++ libs/remix-debug/test/decoder/localDecoder.ts | 37 ++-- .../test/decoder/localsTests/calldata.ts | 133 +++++++++++ .../test/decoder/localsTests/int.ts | 207 +++++++++--------- .../test/decoder/localsTests/misc.ts | 113 +++++----- .../test/decoder/localsTests/misc2.ts | 85 +++---- .../test/decoder/localsTests/structArray.ts | 201 ++++++++--------- .../test/decoder/stateTests/mapping.ts | 7 +- libs/remix-debug/test/decoder/vmCall.ts | 64 +++--- 9 files changed, 514 insertions(+), 346 deletions(-) create mode 100644 libs/remix-debug/test/decoder/contracts/calldata.ts create mode 100644 libs/remix-debug/test/decoder/localsTests/calldata.ts diff --git a/libs/remix-debug/test/decoder/contracts/calldata.ts b/libs/remix-debug/test/decoder/contracts/calldata.ts new file mode 100644 index 0000000000..75b3694429 --- /dev/null +++ b/libs/remix-debug/test/decoder/contracts/calldata.ts @@ -0,0 +1,13 @@ +'use strict' + +module.exports = { + contract: ` +contract calldataLocal { + constructor () public { + } + + function level11(uint8[1] calldata foo, string[2][1] calldata boo) public { + + } + } +`} diff --git a/libs/remix-debug/test/decoder/localDecoder.ts b/libs/remix-debug/test/decoder/localDecoder.ts index d76ff4c2c0..1c647a6875 100644 --- a/libs/remix-debug/test/decoder/localDecoder.ts +++ b/libs/remix-debug/test/decoder/localDecoder.ts @@ -4,37 +4,40 @@ var compiler = require('solc') var intLocal = require('./contracts/intLocal') var miscLocal = require('./contracts/miscLocal') var structArrayLocal = require('./contracts/structArrayLocal') +var calldataLocal = require('./contracts/calldata') var vmCall = require('./vmCall') var intLocalTest = require('./localsTests/int') var miscLocalTest = require('./localsTests/misc') var misc2LocalTest = require('./localsTests/misc2') var structArrayLocalTest = require('./localsTests/structArray') +var calldataLocalTest = require('./localsTests/calldata') var compilerInput = require('../helpers/compilerHelper').compilerInput tape('solidity', function (t) { t.test('local decoder', async function (st) { var privateKey = Buffer.from('dae9801649ba2d95a21e688b56f77905e5667c44ce868ec83f82e838712a2c7a', 'hex') var vm = await vmCall.initVM(st, privateKey) - test(st, vm, privateKey) + await test(st, vm, privateKey) }) }) -function test (st, vm, privateKey) { +async function test (st, vm, privateKey) { var output = compiler.compile(compilerInput(intLocal.contract)) output = JSON.parse(output) - intLocalTest(st, vm, privateKey, output.contracts['test.sol']['intLocal'].evm.bytecode.object, output, function () { - output = compiler.compile(compilerInput(miscLocal.contract)) - output = JSON.parse(output) - miscLocalTest(st, vm, privateKey, output.contracts['test.sol']['miscLocal'].evm.bytecode.object, output, function () { - output = compiler.compile(compilerInput(miscLocal.contract)) - output = JSON.parse(output) - misc2LocalTest(st, vm, privateKey, output.contracts['test.sol']['miscLocal2'].evm.bytecode.object, output, function () { - output = compiler.compile(compilerInput(structArrayLocal.contract)) - output = JSON.parse(output) - structArrayLocalTest(st, vm, privateKey, output.contracts['test.sol']['structArrayLocal'].evm.bytecode.object, output, function () { - st.end() - }) - }) - }) - }) + await intLocalTest(st, vm, privateKey, output.contracts['test.sol']['intLocal'].evm.bytecode.object, output) + output = compiler.compile(compilerInput(miscLocal.contract)) + output = JSON.parse(output) + await miscLocalTest(st, vm, privateKey, output.contracts['test.sol']['miscLocal'].evm.bytecode.object, output) + output = compiler.compile(compilerInput(miscLocal.contract)) + output = JSON.parse(output) + await misc2LocalTest(st, vm, privateKey, output.contracts['test.sol']['miscLocal2'].evm.bytecode.object, output) + output = compiler.compile(compilerInput(structArrayLocal.contract)) + output = JSON.parse(output) + await structArrayLocalTest(st, vm, privateKey, output.contracts['test.sol']['structArrayLocal'].evm.bytecode.object, output) + + output = compiler.compile(compilerInput(calldataLocal.contract)) + output = JSON.parse(output) + await calldataLocalTest(st, vm, privateKey, output.contracts['test.sol']['structArrayLocal'].evm.bytecode.object, output) + + st.end() } diff --git a/libs/remix-debug/test/decoder/localsTests/calldata.ts b/libs/remix-debug/test/decoder/localsTests/calldata.ts new file mode 100644 index 0000000000..98c55cf74b --- /dev/null +++ b/libs/remix-debug/test/decoder/localsTests/calldata.ts @@ -0,0 +1,133 @@ +'use strict' + +import { sendTx } from '../vmCall' +import { TraceManager } from '../../../src/trace/traceManager' +import { CodeManager } from '../../../src/code/codeManager' +import { contractCreationToken } from '../../../src/trace/traceHelper' +import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy' +import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree' +import { EventManager } from '../../../src/eventManager' +import * as helper from './helper' + +module.exports = async function (st, vm, privateKey, contractBytecode, compilationResult) { + let txHash + try { + let data = await sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode) + const to = (data as any).result.contractAddress + data = await sendTx(vm, { nonce: 0, privateKey: privateKey }, to, 0, '0xa372a595000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000006746573742031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067465737420320000000000000000000000000000000000000000000000000000') // call to level11 + txHash = (data as any).hash + } catch (e) { + return st.fail(e) + } + return new Promise((resolve) => { + vm.web3.eth.getTransaction(txHash, function (error, tx) { + if (error) { + return st.fail(error) + } + tx.to = contractCreationToken('0') + var traceManager = new TraceManager({ web3: vm.web3 }) + var codeManager = new CodeManager(traceManager) + codeManager.clear() + var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) + solidityProxy.reset(compilationResult) + var debuggerEvent = new EventManager() + var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) + callTree.event.register('callTreeBuildFailed', (error) => { + st.fail(error) + }) + callTree.event.register('callTreeNotReady', (reason) => { + st.fail(reason) + }) + callTree.event.register('callTreeReady', (scopes, scopeStarts) => { + try { + let functions1 = callTree.retrieveFunctionsStack(102) + let functions2 = callTree.retrieveFunctionsStack(115) + let functions3 = callTree.retrieveFunctionsStack(13) + + st.equals(functions1.length, 1) + st.equals(functions2.length, 2) + st.equals(functions3.length, 0) + + st.equals(Object.keys(functions1[0])[0], 'functionDefinition') + st.equals(Object.keys(functions1[0])[1], 'inputs') + st.equals(functions1[0].inputs[0], 'foo') + st.equals(Object.keys(functions2[0])[0], 'functionDefinition') + st.equals(Object.keys(functions2[0])[1], 'inputs') + st.equals(Object.keys(functions2[1])[0], 'functionDefinition') + st.equals(Object.keys(functions2[1])[1], 'inputs') + st.equals(functions2[0].inputs[0], 'asd') + st.equals(functions2[1].inputs[0], 'foo') + + st.equals(functions1[0].functionDefinition.name, 'level11') + st.equals(functions2[0].functionDefinition.name, 'level12') + st.equals(functions2[1].functionDefinition.name, 'level11') + + st.equals(scopeStarts[0], '') + st.equals(scopeStarts[13], '1') + st.equals(scopeStarts[102], '2') + st.equals(scopeStarts[115], '2.1') + st.equals(scopeStarts[136], '3') + st.equals(scopeStarts[153], '4') + st.equals(scopeStarts[166], '4.1') + st.equals(scopes[''].locals['ui8'].type.typeName, 'uint8') + st.equals(scopes[''].locals['ui16'].type.typeName, 'uint16') + st.equals(scopes[''].locals['ui32'].type.typeName, 'uint32') + st.equals(scopes[''].locals['ui64'].type.typeName, 'uint64') + st.equals(scopes[''].locals['ui128'].type.typeName, 'uint128') + st.equals(scopes[''].locals['ui256'].type.typeName, 'uint256') + st.equals(scopes[''].locals['ui'].type.typeName, 'uint256') + st.equals(scopes[''].locals['i8'].type.typeName, 'int8') + st.equals(scopes[''].locals['i16'].type.typeName, 'int16') + st.equals(scopes[''].locals['i32'].type.typeName, 'int32') + st.equals(scopes[''].locals['i64'].type.typeName, 'int64') + st.equals(scopes[''].locals['i128'].type.typeName, 'int128') + st.equals(scopes[''].locals['i256'].type.typeName, 'int256') + st.equals(scopes[''].locals['i'].type.typeName, 'int256') + st.equals(scopes[''].locals['ishrink'].type.typeName, 'int32') + st.equals(scopes['2'].locals['ui8'].type.typeName, 'uint8') + st.equals(scopes['2.1'].locals['ui81'].type.typeName, 'uint8') + st.equals(scopes['3'].locals['ui81'].type.typeName, 'uint8') + st.equals(scopes['4'].locals['ui8'].type.typeName, 'uint8') + st.equals(scopes['4.1'].locals['ui81'].type.typeName, 'uint8') + } catch (e) { + st.fail(e.message) + } + + helper.decodeLocals(st, 95, traceManager, callTree, function (locals) { + st.equals(Object.keys(locals).length, 16) + st.equals(locals['ui8'].value, '130') + st.equals(locals['ui16'].value, '456') + st.equals(locals['ui32'].value, '4356') + st.equals(locals['ui64'].value, '3543543543') + st.equals(locals['ui128'].value, '234567') + st.equals(locals['ui256'].value, '115792089237316195423570985008687907853269984665640564039457584007880697216513') + st.equals(locals['ui'].value, '123545666') + st.equals(locals['i8'].value, '-45') + st.equals(locals['i16'].value, '-1234') + st.equals(locals['i32'].value, '3455') + st.equals(locals['i64'].value, '-35566') + st.equals(locals['i128'].value, '-444444') + st.equals(locals['i256'].value, '3434343') + st.equals(locals['i'].value, '-32432423423') + st.equals(locals['ishrink'].value, '2') + }) + + helper.decodeLocals(st, 106, traceManager, callTree, function (locals) { + try { + st.equals(locals['ui8'].value, '123') + st.equals(Object.keys(locals).length, 2) + } catch (e) { + st.fail(e.message) + } + resolve({}) + }) + }) + traceManager.resolveTrace(tx).then(() => { + debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) + }).catch((error) => { + st.fail(error) + }) + }) + }) +} + diff --git a/libs/remix-debug/test/decoder/localsTests/int.ts b/libs/remix-debug/test/decoder/localsTests/int.ts index a727358061..b8e0200ff5 100644 --- a/libs/remix-debug/test/decoder/localsTests/int.ts +++ b/libs/remix-debug/test/decoder/localsTests/int.ts @@ -9,119 +9,122 @@ import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree import { EventManager } from '../../../src/eventManager' import * as helper from './helper' -module.exports = function (st, vm, privateKey, contractBytecode, compilationResult, cb) { - sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, txHash) { - if (error) { - return st.fail(error) - } - vm.web3.eth.getTransaction(txHash, function (error, tx) { +module.exports = function (st, vm, privateKey, contractBytecode, compilationResult) { + return new Promise((resolve) => { + sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, data) { if (error) { return st.fail(error) } - tx.to = contractCreationToken('0') - var traceManager = new TraceManager({ web3: vm.web3 }) - var codeManager = new CodeManager(traceManager) - codeManager.clear() - var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) - solidityProxy.reset(compilationResult) - var debuggerEvent = new EventManager() - var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) - callTree.event.register('callTreeBuildFailed', (error) => { - st.fail(error) - }) - callTree.event.register('callTreeNotReady', (reason) => { - st.fail(reason) - }) - callTree.event.register('callTreeReady', (scopes, scopeStarts) => { - try { - let functions1 = callTree.retrieveFunctionsStack(102) - let functions2 = callTree.retrieveFunctionsStack(115) - let functions3 = callTree.retrieveFunctionsStack(13) - - st.equals(functions1.length, 1) - st.equals(functions2.length, 2) - st.equals(functions3.length, 0) - - st.equals(Object.keys(functions1[0])[0], 'functionDefinition') - st.equals(Object.keys(functions1[0])[1], 'inputs') - st.equals(functions1[0].inputs[0], 'foo') - st.equals(Object.keys(functions2[0])[0], 'functionDefinition') - st.equals(Object.keys(functions2[0])[1], 'inputs') - st.equals(Object.keys(functions2[1])[0], 'functionDefinition') - st.equals(Object.keys(functions2[1])[1], 'inputs') - st.equals(functions2[0].inputs[0], 'asd') - st.equals(functions2[1].inputs[0], 'foo') - - st.equals(functions1[0].functionDefinition.name, 'level11') - st.equals(functions2[0].functionDefinition.name, 'level12') - st.equals(functions2[1].functionDefinition.name, 'level11') - - st.equals(scopeStarts[0], '') - st.equals(scopeStarts[13], '1') - st.equals(scopeStarts[102], '2') - st.equals(scopeStarts[115], '2.1') - st.equals(scopeStarts[136], '3') - st.equals(scopeStarts[153], '4') - st.equals(scopeStarts[166], '4.1') - st.equals(scopes[''].locals['ui8'].type.typeName, 'uint8') - st.equals(scopes[''].locals['ui16'].type.typeName, 'uint16') - st.equals(scopes[''].locals['ui32'].type.typeName, 'uint32') - st.equals(scopes[''].locals['ui64'].type.typeName, 'uint64') - st.equals(scopes[''].locals['ui128'].type.typeName, 'uint128') - st.equals(scopes[''].locals['ui256'].type.typeName, 'uint256') - st.equals(scopes[''].locals['ui'].type.typeName, 'uint256') - st.equals(scopes[''].locals['i8'].type.typeName, 'int8') - st.equals(scopes[''].locals['i16'].type.typeName, 'int16') - st.equals(scopes[''].locals['i32'].type.typeName, 'int32') - st.equals(scopes[''].locals['i64'].type.typeName, 'int64') - st.equals(scopes[''].locals['i128'].type.typeName, 'int128') - st.equals(scopes[''].locals['i256'].type.typeName, 'int256') - st.equals(scopes[''].locals['i'].type.typeName, 'int256') - st.equals(scopes[''].locals['ishrink'].type.typeName, 'int32') - st.equals(scopes['2'].locals['ui8'].type.typeName, 'uint8') - st.equals(scopes['2.1'].locals['ui81'].type.typeName, 'uint8') - st.equals(scopes['3'].locals['ui81'].type.typeName, 'uint8') - st.equals(scopes['4'].locals['ui8'].type.typeName, 'uint8') - st.equals(scopes['4.1'].locals['ui81'].type.typeName, 'uint8') - } catch (e) { - st.fail(e.message) + const txHash = data.hash + vm.web3.eth.getTransaction(txHash, function (error, tx) { + if (error) { + return st.fail(error) } - - helper.decodeLocals(st, 95, traceManager, callTree, function (locals) { - st.equals(Object.keys(locals).length, 16) - st.equals(locals['ui8'].value, '130') - st.equals(locals['ui16'].value, '456') - st.equals(locals['ui32'].value, '4356') - st.equals(locals['ui64'].value, '3543543543') - st.equals(locals['ui128'].value, '234567') - st.equals(locals['ui256'].value, '115792089237316195423570985008687907853269984665640564039457584007880697216513') - st.equals(locals['ui'].value, '123545666') - st.equals(locals['i8'].value, '-45') - st.equals(locals['i16'].value, '-1234') - st.equals(locals['i32'].value, '3455') - st.equals(locals['i64'].value, '-35566') - st.equals(locals['i128'].value, '-444444') - st.equals(locals['i256'].value, '3434343') - st.equals(locals['i'].value, '-32432423423') - st.equals(locals['ishrink'].value, '2') + tx.to = contractCreationToken('0') + var traceManager = new TraceManager({ web3: vm.web3 }) + var codeManager = new CodeManager(traceManager) + codeManager.clear() + var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) + solidityProxy.reset(compilationResult) + var debuggerEvent = new EventManager() + var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) + callTree.event.register('callTreeBuildFailed', (error) => { + st.fail(error) }) - - helper.decodeLocals(st, 106, traceManager, callTree, function (locals) { + callTree.event.register('callTreeNotReady', (reason) => { + st.fail(reason) + }) + callTree.event.register('callTreeReady', (scopes, scopeStarts) => { try { - st.equals(locals['ui8'].value, '123') - st.equals(Object.keys(locals).length, 2) + let functions1 = callTree.retrieveFunctionsStack(102) + let functions2 = callTree.retrieveFunctionsStack(115) + let functions3 = callTree.retrieveFunctionsStack(13) + + st.equals(functions1.length, 1) + st.equals(functions2.length, 2) + st.equals(functions3.length, 0) + + st.equals(Object.keys(functions1[0])[0], 'functionDefinition') + st.equals(Object.keys(functions1[0])[1], 'inputs') + st.equals(functions1[0].inputs[0], 'foo') + st.equals(Object.keys(functions2[0])[0], 'functionDefinition') + st.equals(Object.keys(functions2[0])[1], 'inputs') + st.equals(Object.keys(functions2[1])[0], 'functionDefinition') + st.equals(Object.keys(functions2[1])[1], 'inputs') + st.equals(functions2[0].inputs[0], 'asd') + st.equals(functions2[1].inputs[0], 'foo') + + st.equals(functions1[0].functionDefinition.name, 'level11') + st.equals(functions2[0].functionDefinition.name, 'level12') + st.equals(functions2[1].functionDefinition.name, 'level11') + + st.equals(scopeStarts[0], '') + st.equals(scopeStarts[13], '1') + st.equals(scopeStarts[102], '2') + st.equals(scopeStarts[115], '2.1') + st.equals(scopeStarts[136], '3') + st.equals(scopeStarts[153], '4') + st.equals(scopeStarts[166], '4.1') + st.equals(scopes[''].locals['ui8'].type.typeName, 'uint8') + st.equals(scopes[''].locals['ui16'].type.typeName, 'uint16') + st.equals(scopes[''].locals['ui32'].type.typeName, 'uint32') + st.equals(scopes[''].locals['ui64'].type.typeName, 'uint64') + st.equals(scopes[''].locals['ui128'].type.typeName, 'uint128') + st.equals(scopes[''].locals['ui256'].type.typeName, 'uint256') + st.equals(scopes[''].locals['ui'].type.typeName, 'uint256') + st.equals(scopes[''].locals['i8'].type.typeName, 'int8') + st.equals(scopes[''].locals['i16'].type.typeName, 'int16') + st.equals(scopes[''].locals['i32'].type.typeName, 'int32') + st.equals(scopes[''].locals['i64'].type.typeName, 'int64') + st.equals(scopes[''].locals['i128'].type.typeName, 'int128') + st.equals(scopes[''].locals['i256'].type.typeName, 'int256') + st.equals(scopes[''].locals['i'].type.typeName, 'int256') + st.equals(scopes[''].locals['ishrink'].type.typeName, 'int32') + st.equals(scopes['2'].locals['ui8'].type.typeName, 'uint8') + st.equals(scopes['2.1'].locals['ui81'].type.typeName, 'uint8') + st.equals(scopes['3'].locals['ui81'].type.typeName, 'uint8') + st.equals(scopes['4'].locals['ui8'].type.typeName, 'uint8') + st.equals(scopes['4.1'].locals['ui81'].type.typeName, 'uint8') } catch (e) { st.fail(e.message) } - cb() + + helper.decodeLocals(st, 95, traceManager, callTree, function (locals) { + st.equals(Object.keys(locals).length, 16) + st.equals(locals['ui8'].value, '130') + st.equals(locals['ui16'].value, '456') + st.equals(locals['ui32'].value, '4356') + st.equals(locals['ui64'].value, '3543543543') + st.equals(locals['ui128'].value, '234567') + st.equals(locals['ui256'].value, '115792089237316195423570985008687907853269984665640564039457584007880697216513') + st.equals(locals['ui'].value, '123545666') + st.equals(locals['i8'].value, '-45') + st.equals(locals['i16'].value, '-1234') + st.equals(locals['i32'].value, '3455') + st.equals(locals['i64'].value, '-35566') + st.equals(locals['i128'].value, '-444444') + st.equals(locals['i256'].value, '3434343') + st.equals(locals['i'].value, '-32432423423') + st.equals(locals['ishrink'].value, '2') + }) + + helper.decodeLocals(st, 106, traceManager, callTree, function (locals) { + try { + st.equals(locals['ui8'].value, '123') + st.equals(Object.keys(locals).length, 2) + } catch (e) { + st.fail(e.message) + } + resolve({}) + }) + }) + traceManager.resolveTrace(tx).then(() => { + debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) + }).catch((error) => { + st.fail(error) }) - }) - traceManager.resolveTrace(tx).then(() => { - debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) - }).catch((error) => { - st.fail(error) }) }) - }) + }) } diff --git a/libs/remix-debug/test/decoder/localsTests/misc.ts b/libs/remix-debug/test/decoder/localsTests/misc.ts index 628852ebaf..7d59d2fbe7 100644 --- a/libs/remix-debug/test/decoder/localsTests/misc.ts +++ b/libs/remix-debug/test/decoder/localsTests/misc.ts @@ -8,66 +8,69 @@ import * as helper from './helper' import { TraceManager } from '../../../src/trace/traceManager' import { CodeManager } from '../../../src/code/codeManager' -module.exports = function (st, vm, privateKey, contractBytecode, compilationResult, cb) { - sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, txHash) { - if (error) { - return st.fail(error) - } - vm.web3.eth.getTransaction(txHash, function (error, tx) { +module.exports = function (st, vm, privateKey, contractBytecode, compilationResult) { + return new Promise((resolve) => { + sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, data) { if (error) { return st.fail(error) } - tx.to = contractCreationToken('0') - var traceManager = new TraceManager({ web3: vm.web3 }) - var codeManager = new CodeManager(traceManager) - codeManager.clear() - var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) - solidityProxy.reset(compilationResult) - var debuggerEvent = new EventManager() - var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) - callTree.event.register('callTreeBuildFailed', (error) => { - st.fail(error) - }) - callTree.event.register('callTreeReady', (scopes, scopeStarts) => { - helper.decodeLocals(st, 70, traceManager, callTree, function (locals) { - try { - st.equals(locals['boolFalse'].value, false) - st.equals(locals['boolTrue'].value, true) - st.equals(locals['testEnum'].value, 'three') - st.equals(locals['sender'].value, '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB') - st.equals(locals['_bytes1'].value, '0x99') - st.equals(locals['__bytes1'].value, '0x99') - st.equals(locals['__bytes2'].value, '0x99AB') - st.equals(locals['__bytes4'].value, '0x99FA0000') - st.equals(locals['__bytes6'].value, '0x990000000000') - st.equals(locals['__bytes7'].value, '0x99356700000000') - st.equals(locals['__bytes8'].value, '0x99ABD41700000000') - st.equals(locals['__bytes9'].value, '0x99156744AF00000000') - st.equals(locals['__bytes13'].value, '0x99123423425300000000000000') - st.equals(locals['__bytes16'].value, '0x99AFAD23432400000000000000000000') - st.equals(locals['__bytes24'].value, '0x99AFAD234324000000000000000000000000000000000000') - st.equals(locals['__bytes32'].value, '0x9999ABD41799ABD4170000000000000000000000000000000000000000000000') - st.equals(Object.keys(locals).length, 16) - } catch (e) { - st.fail(e.message) - } + const txHash = data.hash + vm.web3.eth.getTransaction(txHash, function (error, tx) { + if (error) { + return st.fail(error) + } + tx.to = contractCreationToken('0') + var traceManager = new TraceManager({ web3: vm.web3 }) + var codeManager = new CodeManager(traceManager) + codeManager.clear() + var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) + solidityProxy.reset(compilationResult) + var debuggerEvent = new EventManager() + var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) + callTree.event.register('callTreeBuildFailed', (error) => { + st.fail(error) }) - - helper.decodeLocals(st, 7, traceManager, callTree, function (locals) { - try { - // st.equals(Object.keys(locals).length, 0) - st.equals(0, 0) - } catch (e) { - st.fail(e.message) - } - cb() + callTree.event.register('callTreeReady', (scopes, scopeStarts) => { + helper.decodeLocals(st, 70, traceManager, callTree, function (locals) { + try { + st.equals(locals['boolFalse'].value, false) + st.equals(locals['boolTrue'].value, true) + st.equals(locals['testEnum'].value, 'three') + st.equals(locals['sender'].value, '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB') + st.equals(locals['_bytes1'].value, '0x99') + st.equals(locals['__bytes1'].value, '0x99') + st.equals(locals['__bytes2'].value, '0x99AB') + st.equals(locals['__bytes4'].value, '0x99FA0000') + st.equals(locals['__bytes6'].value, '0x990000000000') + st.equals(locals['__bytes7'].value, '0x99356700000000') + st.equals(locals['__bytes8'].value, '0x99ABD41700000000') + st.equals(locals['__bytes9'].value, '0x99156744AF00000000') + st.equals(locals['__bytes13'].value, '0x99123423425300000000000000') + st.equals(locals['__bytes16'].value, '0x99AFAD23432400000000000000000000') + st.equals(locals['__bytes24'].value, '0x99AFAD234324000000000000000000000000000000000000') + st.equals(locals['__bytes32'].value, '0x9999ABD41799ABD4170000000000000000000000000000000000000000000000') + st.equals(Object.keys(locals).length, 16) + } catch (e) { + st.fail(e.message) + } + }) + + helper.decodeLocals(st, 7, traceManager, callTree, function (locals) { + try { + // st.equals(Object.keys(locals).length, 0) + st.equals(0, 0) + } catch (e) { + st.fail(e.message) + } + resolve({}) + }) + }) + traceManager.resolveTrace(tx).then(() => { + debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) + }).catch((error) => { + st.fail(error) }) - }) - traceManager.resolveTrace(tx).then(() => { - debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) - }).catch((error) => { - st.fail(error) }) }) - }) + }) } diff --git a/libs/remix-debug/test/decoder/localsTests/misc2.ts b/libs/remix-debug/test/decoder/localsTests/misc2.ts index 3c48b21fab..f28e0a2cde 100644 --- a/libs/remix-debug/test/decoder/localsTests/misc2.ts +++ b/libs/remix-debug/test/decoder/localsTests/misc2.ts @@ -8,52 +8,55 @@ import * as helper from './helper' import { TraceManager } from '../../../src/trace/traceManager' import { CodeManager } from '../../../src/code/codeManager' -module.exports = function (st, vm, privateKey, contractBytecode, compilationResult, cb) { - sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, txHash) { - if (error) { - return st.fail(error) - } - vm.web3.eth.getTransaction(txHash, function (error, tx) { +module.exports = function (st, vm, privateKey, contractBytecode, compilationResult) { + return new Promise((resolve) => { + sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, data) { if (error) { return st.fail(error) } - tx.to = contractCreationToken('0') - var traceManager = new TraceManager({ web3: vm.web3 }) - var codeManager = new CodeManager(traceManager) - codeManager.clear() - var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) - solidityProxy.reset(compilationResult) - var debuggerEvent = new EventManager() - var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) - callTree.event.register('callTreeBuildFailed', (error) => { - st.fail(error) - }) - callTree.event.register('callTreeReady', (scopes, scopeStarts) => { - helper.decodeLocals(st, 49, traceManager, callTree, function (locals) { - try { - st.equals(locals['dynbytes'].value, '0x64796e616d69636279746573') - st.equals(locals['smallstring'].value, 'test_test_test') - st.equals(Object.keys(locals).length, 2) - } catch (e) { - st.fail(e.message) - } + const txHash = data.hash + vm.web3.eth.getTransaction(txHash, function (error, tx) { + if (error) { + return st.fail(error) + } + tx.to = contractCreationToken('0') + var traceManager = new TraceManager({ web3: vm.web3 }) + var codeManager = new CodeManager(traceManager) + codeManager.clear() + var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) + solidityProxy.reset(compilationResult) + var debuggerEvent = new EventManager() + var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) + callTree.event.register('callTreeBuildFailed', (error) => { + st.fail(error) }) - - helper.decodeLocals(st, 7, traceManager, callTree, function (locals) { - try { - // st.equals(Object.keys(locals).length, 0) - st.equals(0, 0) - } catch (e) { - st.fail(e.message) - } - cb() + callTree.event.register('callTreeReady', (scopes, scopeStarts) => { + helper.decodeLocals(st, 49, traceManager, callTree, function (locals) { + try { + st.equals(locals['dynbytes'].value, '0x64796e616d69636279746573') + st.equals(locals['smallstring'].value, 'test_test_test') + st.equals(Object.keys(locals).length, 2) + } catch (e) { + st.fail(e.message) + } + }) + + helper.decodeLocals(st, 7, traceManager, callTree, function (locals) { + try { + // st.equals(Object.keys(locals).length, 0) + st.equals(0, 0) + } catch (e) { + st.fail(e.message) + } + resolve({}) + }) + }) + traceManager.resolveTrace(tx).then(() => { + debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) + }).catch((error) => { + st.fail(error) }) - }) - traceManager.resolveTrace(tx).then(() => { - debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) - }).catch((error) => { - st.fail(error) }) }) - }) + }) } diff --git a/libs/remix-debug/test/decoder/localsTests/structArray.ts b/libs/remix-debug/test/decoder/localsTests/structArray.ts index ece13a77b8..9041e9ea7b 100644 --- a/libs/remix-debug/test/decoder/localsTests/structArray.ts +++ b/libs/remix-debug/test/decoder/localsTests/structArray.ts @@ -8,110 +8,113 @@ import * as helper from './helper' import { TraceManager } from '../../../src/trace/traceManager' import { CodeManager } from '../../../src/code/codeManager' -module.exports = function (st, vm, privateKey, contractBytecode, compilationResult, cb) { - sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, txHash) { - if (error) { - return st.fail(error) - } - vm.web3.eth.getTransaction(txHash, function (error, tx) { +module.exports = function (st, vm, privateKey, contractBytecode, compilationResult) { + return new Promise((resolve) => { + sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, data) { if (error) { return st.fail(error) } - tx.to = contractCreationToken('0') - var traceManager = new TraceManager({ web3: vm.web3 }) - var codeManager = new CodeManager(traceManager) - codeManager.clear() - var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) - solidityProxy.reset(compilationResult) - var debuggerEvent = new EventManager() - var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) - callTree.event.register('callTreeBuildFailed', (error) => { - st.fail(error) - }) - callTree.event.register('callTreeReady', (scopes, scopeStarts) => { - helper.decodeLocals(st, 1622, traceManager, callTree, function (locals) { - try { - st.equals(locals['bytesSimple'].length, '0x14') - st.equals(locals['bytesSimple'].value, '0x746573745f7375706572') - st.equals(locals['e'].value['a'].value, 'test') - st.equals(locals['e'].value['a'].length, '0x8') - st.equals(locals['e'].value['a'].raw, '0x74657374') - st.equals(locals['e'].value['b'].value, '5') - st.equals(locals['e'].value['c'].length, '0x220') - st.equals(locals['e'].value['c'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374') - st.equals(locals['e'].value['c'].value, 'test_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_test') - st.equals(locals['e'].value['d'].value, '3') - st.equals(locals['f'].length, '0x1b8') - st.equals(locals['f'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f') - st.equals(locals['f'].value, 'test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_') - st.equals(locals['e'].value['e'].value, true) - - st.equals(locals['simpleArray'].value[0].value, '45') - st.equals(locals['simpleArray'].value[1].value, '324324') - st.equals(locals['simpleArray'].value[2].value, '-333') - st.equals(locals['simpleArray'].value[3].value, '5656') - st.equals(locals['simpleArray'].value[4].value, '-1111') - - st.equals(locals['stringArray'].value[0].value, 'long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_') - st.equals(locals['stringArray'].value[1].value, 'two') - st.equals(locals['stringArray'].value[2].value, 'three') - - st.equals(locals['dynArray'].value[0].value[0].value, '3423423532') - st.equals(locals['dynArray'].value[1].value[0].value, '-342343323532') - st.equals(locals['dynArray'].value[1].value[1].value, '23432') - st.equals(locals['dynArray'].value[2].value[0].value, '-432432') - st.equals(locals['dynArray'].value[2].value[1].value, '3423423532') - st.equals(locals['dynArray'].value[2].value[2].value, '-432432') - - st.equals(locals['structArray'].value[0].value['a'].value, 'test') - st.equals(locals['structArray'].value[0].value['a'].length, '0x8') - st.equals(locals['structArray'].value[0].value['a'].raw, '0x74657374') - st.equals(locals['structArray'].value[0].value['b'].value, '5') - st.equals(locals['structArray'].value[0].value['c'].length, '0x220') - st.equals(locals['structArray'].value[0].value['c'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374') - st.equals(locals['structArray'].value[0].value['c'].value, 'test_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_test') - st.equals(locals['structArray'].value[0].value['d'].value, '3') - st.equals(locals['structArray'].value[0].value['e'].value, true) - - st.equals(locals['structArray'].value[1].value['a'].value, 'item1 a') - st.equals(locals['structArray'].value[1].value['b'].value, '20') - st.equals(locals['structArray'].value[1].value['c'].value, 'item1 c') - st.equals(locals['structArray'].value[1].value['d'].value, '-45') - st.equals(locals['structArray'].value[1].value['e'].value, false) - - st.equals(locals['structArray'].value[2].value['a'].value, 'item2 a') - st.equals(locals['structArray'].value[2].value['b'].value, '200') - st.equals(locals['structArray'].value[2].value['c'].value, 'item2 c') - st.equals(locals['structArray'].value[2].value['d'].value, '-450') - st.equals(locals['structArray'].value[2].value['e'].value, true) - - st.equals(locals['arrayStruct'].value.a.value[0].value, 'string') - st.equals(locals['arrayStruct'].value.b.value[0].value, '34') - st.equals(locals['arrayStruct'].value.b.value[1].value, '-23') - st.equals(locals['arrayStruct'].value.b.value[2].value, '-3') - st.equals(locals['arrayStruct'].value.c.value, 'three') - - st.equals(Object.keys(locals).length, 8) - } catch (e) { - st.fail(e.message) - } + const txHash = data.hash + vm.web3.eth.getTransaction(txHash, function (error, tx) { + if (error) { + return st.fail(error) + } + tx.to = contractCreationToken('0') + var traceManager = new TraceManager({ web3: vm.web3 }) + var codeManager = new CodeManager(traceManager) + codeManager.clear() + var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) + solidityProxy.reset(compilationResult) + var debuggerEvent = new EventManager() + var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) + callTree.event.register('callTreeBuildFailed', (error) => { + st.fail(error) }) - - helper.decodeLocals(st, 7, traceManager, callTree, function (locals) { - try { - st.equals(0, 0) - // st.equals(Object.keys(locals).length, 0) - } catch (e) { - st.fail(e.message) - } - cb() + callTree.event.register('callTreeReady', (scopes, scopeStarts) => { + helper.decodeLocals(st, 1622, traceManager, callTree, function (locals) { + try { + st.equals(locals['bytesSimple'].length, '0x14') + st.equals(locals['bytesSimple'].value, '0x746573745f7375706572') + st.equals(locals['e'].value['a'].value, 'test') + st.equals(locals['e'].value['a'].length, '0x8') + st.equals(locals['e'].value['a'].raw, '0x74657374') + st.equals(locals['e'].value['b'].value, '5') + st.equals(locals['e'].value['c'].length, '0x220') + st.equals(locals['e'].value['c'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374') + st.equals(locals['e'].value['c'].value, 'test_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_test') + st.equals(locals['e'].value['d'].value, '3') + st.equals(locals['f'].length, '0x1b8') + st.equals(locals['f'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f') + st.equals(locals['f'].value, 'test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_') + st.equals(locals['e'].value['e'].value, true) + + st.equals(locals['simpleArray'].value[0].value, '45') + st.equals(locals['simpleArray'].value[1].value, '324324') + st.equals(locals['simpleArray'].value[2].value, '-333') + st.equals(locals['simpleArray'].value[3].value, '5656') + st.equals(locals['simpleArray'].value[4].value, '-1111') + + st.equals(locals['stringArray'].value[0].value, 'long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_') + st.equals(locals['stringArray'].value[1].value, 'two') + st.equals(locals['stringArray'].value[2].value, 'three') + + st.equals(locals['dynArray'].value[0].value[0].value, '3423423532') + st.equals(locals['dynArray'].value[1].value[0].value, '-342343323532') + st.equals(locals['dynArray'].value[1].value[1].value, '23432') + st.equals(locals['dynArray'].value[2].value[0].value, '-432432') + st.equals(locals['dynArray'].value[2].value[1].value, '3423423532') + st.equals(locals['dynArray'].value[2].value[2].value, '-432432') + + st.equals(locals['structArray'].value[0].value['a'].value, 'test') + st.equals(locals['structArray'].value[0].value['a'].length, '0x8') + st.equals(locals['structArray'].value[0].value['a'].raw, '0x74657374') + st.equals(locals['structArray'].value[0].value['b'].value, '5') + st.equals(locals['structArray'].value[0].value['c'].length, '0x220') + st.equals(locals['structArray'].value[0].value['c'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374') + st.equals(locals['structArray'].value[0].value['c'].value, 'test_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_test') + st.equals(locals['structArray'].value[0].value['d'].value, '3') + st.equals(locals['structArray'].value[0].value['e'].value, true) + + st.equals(locals['structArray'].value[1].value['a'].value, 'item1 a') + st.equals(locals['structArray'].value[1].value['b'].value, '20') + st.equals(locals['structArray'].value[1].value['c'].value, 'item1 c') + st.equals(locals['structArray'].value[1].value['d'].value, '-45') + st.equals(locals['structArray'].value[1].value['e'].value, false) + + st.equals(locals['structArray'].value[2].value['a'].value, 'item2 a') + st.equals(locals['structArray'].value[2].value['b'].value, '200') + st.equals(locals['structArray'].value[2].value['c'].value, 'item2 c') + st.equals(locals['structArray'].value[2].value['d'].value, '-450') + st.equals(locals['structArray'].value[2].value['e'].value, true) + + st.equals(locals['arrayStruct'].value.a.value[0].value, 'string') + st.equals(locals['arrayStruct'].value.b.value[0].value, '34') + st.equals(locals['arrayStruct'].value.b.value[1].value, '-23') + st.equals(locals['arrayStruct'].value.b.value[2].value, '-3') + st.equals(locals['arrayStruct'].value.c.value, 'three') + + st.equals(Object.keys(locals).length, 8) + } catch (e) { + st.fail(e.message) + } + }) + + helper.decodeLocals(st, 7, traceManager, callTree, function (locals) { + try { + st.equals(0, 0) + // st.equals(Object.keys(locals).length, 0) + } catch (e) { + st.fail(e.message) + } + resolve({}) + }) + }) + traceManager.resolveTrace(tx).then(() => { + debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) + }).catch((error) => { + st.fail(error) }) - }) - traceManager.resolveTrace(tx).then(() => { - debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) - }).catch((error) => { - st.fail(error) }) }) - }) + }) } diff --git a/libs/remix-debug/test/decoder/stateTests/mapping.ts b/libs/remix-debug/test/decoder/stateTests/mapping.ts index eb2a0115b6..671bf4b9b6 100644 --- a/libs/remix-debug/test/decoder/stateTests/mapping.ts +++ b/libs/remix-debug/test/decoder/stateTests/mapping.ts @@ -12,11 +12,12 @@ module.exports = async function testMappingStorage (st, cb) { var vm = await initVM(st, privateKey) var output = compile(compilerInput(mappingStorage.contract)) output = JSON.parse(output) - sendTx(vm, {nonce: 0, privateKey: privateKey}, null, 0, output.contracts['test.sol']['SimpleMappingState'].evm.bytecode.object, function (error, txHash) { + sendTx(vm, {nonce: 0, privateKey: privateKey}, null, 0, output.contracts['test.sol']['SimpleMappingState'].evm.bytecode.object, function (error, data) { if (error) { console.log(error) st.end(error) } else { + const txHash = data.hash vm.web3.eth.getTransaction(txHash, (error, tx) => { if (error) { console.log(error) @@ -31,12 +32,12 @@ module.exports = async function testMappingStorage (st, cb) { function testMapping (st, vm, privateKey, contractAddress, output, cb) { sendTx(vm, {nonce: 1, privateKey: privateKey}, contractAddress, 0, '2fd0a83a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001074686973206973206120737472696e6700000000000000000000000000000000', - function (error, txHash) { + function (error, data) { if (error) { console.log(error) st.end(error) } else { - console.log(txHash) + const txHash = data.hash vm.web3.eth.getTransaction(txHash, (error, tx) => { if (error) { console.log(error) diff --git a/libs/remix-debug/test/decoder/vmCall.ts b/libs/remix-debug/test/decoder/vmCall.ts index 0061f986b1..89417ac698 100644 --- a/libs/remix-debug/test/decoder/vmCall.ts +++ b/libs/remix-debug/test/decoder/vmCall.ts @@ -6,36 +6,42 @@ import { vm as remixlibVM } from '@remix-project/remix-lib' import VM from '@ethereumjs/vm' import Common from '@ethereumjs/common' -export function sendTx (vm, from, to, value, data, cb) { - var tx = new Tx({ - nonce: new BN(from.nonce++), - gasPrice: new BN(1), - gasLimit: new BN(3000000, 10), - to: to, - value: new BN(value, 10), - data: Buffer.from(data, 'hex') - }) - tx = tx.sign(from.privateKey) - - var block = Block.fromBlockData({ - header: { - timestamp: new Date().getTime() / 1000 | 0, - number: 0 - } - }) // still using default common - - try { - vm.runTx({block: block, tx: tx, skipBalance: true, skipNonce: true}).then(function (result) { - setTimeout(() => { - cb(null, bufferToHex(tx.hash())) - }, 500) - }).catch((error) => { - console.error(error) - cb(error) +export function sendTx (vm, from, to, value, data, cb?) { + cb = cb || (() => {}) + return new Promise ((resolve, reject) => { + var tx = new Tx({ + nonce: new BN(from.nonce++), + gasPrice: new BN(1), + gasLimit: new BN(3000000, 10), + to: to, + value: new BN(value, 10), + data: Buffer.from(data, 'hex') }) - } catch (e) { - console.error(e) - } + tx = tx.sign(from.privateKey) + + var block = Block.fromBlockData({ + header: { + timestamp: new Date().getTime() / 1000 | 0, + number: 0 + } + }) // still using default common + + try { + vm.runTx({block: block, tx: tx, skipBalance: true, skipNonce: true}).then(function (result) { + setTimeout(() => { + const hash = bufferToHex(tx.hash()) + cb(null, { hash, result }) + resolve({ hash, result }) + }, 500) + }).catch((error) => { + console.error(error) + cb(error) + reject(error) + }) + } catch (e) { + console.error(e) + } + }) } async function createVm (hardfork) { From c47a8aad388991b15c150e1ddf1a03a0b4b4399a Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 21:58:03 +0200 Subject: [PATCH 4/5] fix decode call data array --- libs/remix-debug/src/solidity-decoder/types/RefType.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-debug/src/solidity-decoder/types/RefType.ts b/libs/remix-debug/src/solidity-decoder/types/RefType.ts index 299c4f8d6a..3e51915077 100644 --- a/libs/remix-debug/src/solidity-decoder/types/RefType.ts +++ b/libs/remix-debug/src/solidity-decoder/types/RefType.ts @@ -89,7 +89,7 @@ export class RefType { } else { return { value: value.toString(), - type: type.underlyingType.typeName + type: (type.underlyingType && type.underlyingType.typeName) || type.typeName } } } From 40a8f83630acbe140709efbbfe88f4ea1574d584 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 21:58:29 +0200 Subject: [PATCH 5/5] ensure calldata locals are propery tested --- .../test/decoder/contracts/calldata.ts | 5 +- libs/remix-debug/test/decoder/localDecoder.ts | 2 +- .../test/decoder/localsTests/calldata.ts | 94 +++---------------- 3 files changed, 15 insertions(+), 86 deletions(-) diff --git a/libs/remix-debug/test/decoder/contracts/calldata.ts b/libs/remix-debug/test/decoder/contracts/calldata.ts index 75b3694429..62d3df3ea4 100644 --- a/libs/remix-debug/test/decoder/contracts/calldata.ts +++ b/libs/remix-debug/test/decoder/contracts/calldata.ts @@ -2,12 +2,13 @@ module.exports = { contract: ` -contract calldataLocal { + pragma experimental ABIEncoderV2; + contract calldataLocal { constructor () public { } function level11(uint8[1] calldata foo, string[2][1] calldata boo) public { - + uint p = 45; } } `} diff --git a/libs/remix-debug/test/decoder/localDecoder.ts b/libs/remix-debug/test/decoder/localDecoder.ts index 1c647a6875..2a8f4f8997 100644 --- a/libs/remix-debug/test/decoder/localDecoder.ts +++ b/libs/remix-debug/test/decoder/localDecoder.ts @@ -37,7 +37,7 @@ async function test (st, vm, privateKey) { output = compiler.compile(compilerInput(calldataLocal.contract)) output = JSON.parse(output) - await calldataLocalTest(st, vm, privateKey, output.contracts['test.sol']['structArrayLocal'].evm.bytecode.object, output) + await calldataLocalTest(st, vm, privateKey, output.contracts['test.sol']['calldataLocal'].evm.bytecode.object, output) st.end() } diff --git a/libs/remix-debug/test/decoder/localsTests/calldata.ts b/libs/remix-debug/test/decoder/localsTests/calldata.ts index 98c55cf74b..8f7d3b5fa8 100644 --- a/libs/remix-debug/test/decoder/localsTests/calldata.ts +++ b/libs/remix-debug/test/decoder/localsTests/calldata.ts @@ -1,9 +1,9 @@ 'use strict' +import deepequal from 'deep-equal' import { sendTx } from '../vmCall' import { TraceManager } from '../../../src/trace/traceManager' import { CodeManager } from '../../../src/code/codeManager' -import { contractCreationToken } from '../../../src/trace/traceHelper' import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy' import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree' import { EventManager } from '../../../src/eventManager' @@ -13,8 +13,9 @@ module.exports = async function (st, vm, privateKey, contractBytecode, compilati let txHash try { let data = await sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode) - const to = (data as any).result.contractAddress - data = await sendTx(vm, { nonce: 0, privateKey: privateKey }, to, 0, '0xa372a595000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000006746573742031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067465737420320000000000000000000000000000000000000000000000000000') // call to level11 + const to = (data as any).result.createdAddress.toString() + // call to level11 + data = await sendTx(vm, { nonce: 1, privateKey: privateKey }, to, 0, 'a372a595000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015400000000000000000000000000000000000000000000000000000000000000') txHash = (data as any).hash } catch (e) { return st.fail(e) @@ -24,7 +25,6 @@ module.exports = async function (st, vm, privateKey, contractBytecode, compilati if (error) { return st.fail(error) } - tx.to = contractCreationToken('0') var traceManager = new TraceManager({ web3: vm.web3 }) var codeManager = new CodeManager(traceManager) codeManager.clear() @@ -39,95 +39,23 @@ module.exports = async function (st, vm, privateKey, contractBytecode, compilati st.fail(reason) }) callTree.event.register('callTreeReady', (scopes, scopeStarts) => { - try { - let functions1 = callTree.retrieveFunctionsStack(102) - let functions2 = callTree.retrieveFunctionsStack(115) - let functions3 = callTree.retrieveFunctionsStack(13) - - st.equals(functions1.length, 1) - st.equals(functions2.length, 2) - st.equals(functions3.length, 0) - - st.equals(Object.keys(functions1[0])[0], 'functionDefinition') - st.equals(Object.keys(functions1[0])[1], 'inputs') - st.equals(functions1[0].inputs[0], 'foo') - st.equals(Object.keys(functions2[0])[0], 'functionDefinition') - st.equals(Object.keys(functions2[0])[1], 'inputs') - st.equals(Object.keys(functions2[1])[0], 'functionDefinition') - st.equals(Object.keys(functions2[1])[1], 'inputs') - st.equals(functions2[0].inputs[0], 'asd') - st.equals(functions2[1].inputs[0], 'foo') - - st.equals(functions1[0].functionDefinition.name, 'level11') - st.equals(functions2[0].functionDefinition.name, 'level12') - st.equals(functions2[1].functionDefinition.name, 'level11') - - st.equals(scopeStarts[0], '') - st.equals(scopeStarts[13], '1') - st.equals(scopeStarts[102], '2') - st.equals(scopeStarts[115], '2.1') - st.equals(scopeStarts[136], '3') - st.equals(scopeStarts[153], '4') - st.equals(scopeStarts[166], '4.1') - st.equals(scopes[''].locals['ui8'].type.typeName, 'uint8') - st.equals(scopes[''].locals['ui16'].type.typeName, 'uint16') - st.equals(scopes[''].locals['ui32'].type.typeName, 'uint32') - st.equals(scopes[''].locals['ui64'].type.typeName, 'uint64') - st.equals(scopes[''].locals['ui128'].type.typeName, 'uint128') - st.equals(scopes[''].locals['ui256'].type.typeName, 'uint256') - st.equals(scopes[''].locals['ui'].type.typeName, 'uint256') - st.equals(scopes[''].locals['i8'].type.typeName, 'int8') - st.equals(scopes[''].locals['i16'].type.typeName, 'int16') - st.equals(scopes[''].locals['i32'].type.typeName, 'int32') - st.equals(scopes[''].locals['i64'].type.typeName, 'int64') - st.equals(scopes[''].locals['i128'].type.typeName, 'int128') - st.equals(scopes[''].locals['i256'].type.typeName, 'int256') - st.equals(scopes[''].locals['i'].type.typeName, 'int256') - st.equals(scopes[''].locals['ishrink'].type.typeName, 'int32') - st.equals(scopes['2'].locals['ui8'].type.typeName, 'uint8') - st.equals(scopes['2.1'].locals['ui81'].type.typeName, 'uint8') - st.equals(scopes['3'].locals['ui81'].type.typeName, 'uint8') - st.equals(scopes['4'].locals['ui8'].type.typeName, 'uint8') - st.equals(scopes['4.1'].locals['ui81'].type.typeName, 'uint8') - } catch (e) { - st.fail(e.message) - } - - helper.decodeLocals(st, 95, traceManager, callTree, function (locals) { - st.equals(Object.keys(locals).length, 16) - st.equals(locals['ui8'].value, '130') - st.equals(locals['ui16'].value, '456') - st.equals(locals['ui32'].value, '4356') - st.equals(locals['ui64'].value, '3543543543') - st.equals(locals['ui128'].value, '234567') - st.equals(locals['ui256'].value, '115792089237316195423570985008687907853269984665640564039457584007880697216513') - st.equals(locals['ui'].value, '123545666') - st.equals(locals['i8'].value, '-45') - st.equals(locals['i16'].value, '-1234') - st.equals(locals['i32'].value, '3455') - st.equals(locals['i64'].value, '-35566') - st.equals(locals['i128'].value, '-444444') - st.equals(locals['i256'].value, '3434343') - st.equals(locals['i'].value, '-32432423423') - st.equals(locals['ishrink'].value, '2') - }) - - helper.decodeLocals(st, 106, traceManager, callTree, function (locals) { + helper.decodeLocals(st, 140, traceManager, callTree, function (locals) { try { - st.equals(locals['ui8'].value, '123') - st.equals(Object.keys(locals).length, 2) + const expected = {"p":{"value":"45","type":"uint256"},"foo":{"length":"1","value":[{"value":"3","type":"uint8"}],"type":"uint8[1]"},"boo":{"length":"1","value":[{"length":"2","value":[{"value":"R","type":"string"},{"value":"T","type":"string"}],"type":"string[2]"}],"type":"string[2][1]"}} + st.deepEqual(locals, expected) } catch (e) { st.fail(e.message) } resolve({}) }) }) + + traceManager.resolveTrace(tx).then(() => { debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) }).catch((error) => { st.fail(error) }) }) - }) -} - + }) +} \ No newline at end of file