Merge pull request #62 from ethereum/refactor_remix_debug2c_2

remove callbacks from more methods
pull/5370/head
yann300 5 years ago committed by GitHub
commit 311bb01c90
  1. 19
      libs/remix-debug/src/Ethdebugger.js
  2. 82
      libs/remix-debug/src/debugger/VmDebugger.js
  3. 23
      libs/remix-debug/src/debugger/solidityLocals.js
  4. 9
      libs/remix-debug/src/debugger/stepManager.js
  5. 33
      libs/remix-debug/src/solidity-decoder/astHelper.js
  6. 80
      libs/remix-debug/src/solidity-decoder/internalCallTree.js
  7. 38
      libs/remix-debug/src/solidity-decoder/solidityProxy.js
  8. 5
      libs/remix-debug/src/solidity-decoder/types/Bool.js
  9. 12
      libs/remix-debug/src/solidity-decoder/types/Enum.js
  10. 6
      libs/remix-debug/src/solidity-decoder/types/util.js
  11. 4
      libs/remix-debug/src/storage/mappingPreimages.js
  12. 116
      libs/remix-debug/src/storage/storageResolver.js
  13. 51
      libs/remix-debug/src/storage/storageViewer.js
  14. 24
      libs/remix-debug/test/debugger.js
  15. 18
      libs/remix-debug/test/decoder/localsTests/helper.js
  16. 32
      libs/remix-lib/src/code/codeManager.js
  17. 48
      libs/remix-lib/src/sourceLocationTracker.js
  18. 86
      libs/remix-lib/src/trace/traceManager.js
  19. 155
      libs/remix-lib/test/traceManager.js

@ -90,8 +90,23 @@ Ethdebugger.prototype.extractLocalsAt = function (step, callback) {
Ethdebugger.prototype.decodeLocalsAt = function (step, sourceLocation, callback) { Ethdebugger.prototype.decodeLocalsAt = function (step, sourceLocation, callback) {
const self = this const self = this
this.traceManager.waterfall([ this.traceManager.waterfall([
this.traceManager.getStackAt, function getStackAt (stepIndex, callback) {
this.traceManager.getMemoryAt, try {
const result = self.traceManager.getStackAt(stepIndex)
callback(null, result)
} catch (error) {
callback(error)
}
},
function getMemoryAt (stepIndex, callback) {
try {
const result = self.traceManager.getMemoryAt(stepIndex)
callback(null, result)
} catch (error) {
callback(error)
}
},
function getCurrentCalledAddressAt (stepIndex, next) { function getCurrentCalledAddressAt (stepIndex, next) {
try { try {
const address = self.traceManager.getCurrentCalledAddressAt(stepIndex) const address = self.traceManager.getCurrentCalledAddressAt(stepIndex)

@ -60,23 +60,23 @@ class VmDebuggerLogic {
this.event.trigger('functionsStackUpdate', [this._callTree.retrieveFunctionsStack(index)]) this.event.trigger('functionsStackUpdate', [this._callTree.retrieveFunctionsStack(index)])
this._traceManager.getCallDataAt(index, (error, calldata) => { try {
if (error) { const calldata = this._traceManager.getCallDataAt(index)
// console.log(error) if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerCallDataUpdate', [{}])
} else if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerCallDataUpdate', [calldata]) this.event.trigger('traceManagerCallDataUpdate', [calldata])
} }
}) } catch (error) {
this.event.trigger('traceManagerCallDataUpdate', [{}])
}
this._traceManager.getMemoryAt(index, (error, memory) => { try {
if (error) { const memory = this._traceManager.getMemoryAt(index)
// console.log(error) if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerMemoryUpdate', [{}])
} else if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerMemoryUpdate', [ui.formatMemory(memory, 16)]) this.event.trigger('traceManagerMemoryUpdate', [ui.formatMemory(memory, 16)])
} }
}) } catch (error) {
this.event.trigger('traceManagerMemoryUpdate', [{}])
}
try { try {
const callstack = this._traceManager.getCallStackAt(index) const callstack = this._traceManager.getCallStackAt(index)
@ -87,14 +87,14 @@ class VmDebuggerLogic {
this.event.trigger('traceManagerCallStackUpdate', [{}]) this.event.trigger('traceManagerCallStackUpdate', [{}])
} }
this._traceManager.getStackAt(index, (error, callstack) => { try {
if (error) { const callstack = this._traceManager.getStackAt(index)
// console.log(error) if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerStackUpdate', [{}])
} else if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerStackUpdate', [callstack]) this.event.trigger('traceManagerStackUpdate', [callstack])
} }
}) } catch (error) {
this.event.trigger('traceManagerStackUpdate', [{}])
}
try { try {
const address = this._traceManager.getCurrentCalledAddressAt(index) const address = this._traceManager.getCurrentCalledAddressAt(index)
@ -102,21 +102,24 @@ class VmDebuggerLogic {
var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: address }, this.storageResolver, this._traceManager) var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: address }, this.storageResolver, this._traceManager)
storageViewer.storageRange((error, storage) => { storageViewer.storageRange().then((storage) => {
if (error) { if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceManagerStorageUpdate', [{}])
} else if (this.stepManager.currentStepIndex === index) {
var header = storageViewer.isComplete(address) ? '[Completely Loaded]' : '[Partially Loaded]' var header = storageViewer.isComplete(address) ? '[Completely Loaded]' : '[Partially Loaded]'
this.event.trigger('traceManagerStorageUpdate', [storage, header]) this.event.trigger('traceManagerStorageUpdate', [storage, header])
} }
}).catch((_error) => {
this.event.trigger('traceManagerStorageUpdate', [{}])
}) })
} catch (error) { } catch (error) {
console.log(error) this.event.trigger('traceManagerStorageUpdate', [{}])
} }
this._traceManager.getCurrentStep(index, (error, step) => { try {
this.event.trigger('traceCurrentStepUpdate', [error, step]) const step = this._traceManager.getCurrentStep(index)
}) this.event.trigger('traceCurrentStepUpdate', [null, step])
} catch (error) {
this.event.trigger('traceCurrentStepUpdate', [error])
}
try { try {
const addmem = this._traceManager.getMemExpand(index) const addmem = this._traceManager.getMemExpand(index)
@ -146,13 +149,14 @@ class VmDebuggerLogic {
this.event.trigger('traceRemainingGasUpdate', [error]) this.event.trigger('traceRemainingGasUpdate', [error])
} }
this._traceManager.getReturnValue(index, (error, returnValue) => { try {
if (error) { const returnValue = this._traceManager.getReturnValue(index)
this.event.trigger('traceReturnValueUpdate', [[error]]) if (this.stepManager.currentStepIndex === index) {
} else if (this.stepManager.currentStepIndex === index) {
this.event.trigger('traceReturnValueUpdate', [[returnValue]]) this.event.trigger('traceReturnValueUpdate', [[returnValue]])
} }
}) } catch (error) {
this.event.trigger('traceReturnValueUpdate', [[error]])
}
}) })
} }
@ -161,11 +165,9 @@ class VmDebuggerLogic {
this.traceLength = 0 this.traceLength = 0
this.debugger.event.register('newTraceLoaded', (length) => { this.debugger.event.register('newTraceLoaded', (length) => {
this._traceManager.getAddresses((error, addresses) => { const addresses = this._traceManager.getAddresses()
if (error) return this.event.trigger('traceAddressesUpdate', [addresses])
this.event.trigger('traceAddressesUpdate', [addresses]) this.addresses = addresses
this.addresses = addresses
})
this._traceManager.getLength((error, length) => { this._traceManager.getLength((error, length) => {
if (error) return if (error) return
@ -186,11 +188,9 @@ class VmDebuggerLogic {
for (var k in this.addresses) { for (var k in this.addresses) {
var address = this.addresses[k] var address = this.addresses[k]
var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: address }, this.storageResolver, this._traceManager) var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: address }, this.storageResolver, this._traceManager)
storageViewer.storageRange((error, result) => { storageViewer.storageRange().then((result) => {
if (!error) { storageJSON[address] = result
storageJSON[address] = result this.event.trigger('traceStorageUpdate', [storageJSON])
this.event.trigger('traceStorageUpdate', [storageJSON])
}
}) })
} }
}) })

@ -30,13 +30,28 @@ class DebuggerSolidityLocals {
} }
decode (sourceLocation) { decode (sourceLocation) {
const self = this
this.event.trigger('solidityLocalsMessage', ['']) this.event.trigger('solidityLocalsMessage', [''])
this.traceManager.waterfall([ this.traceManager.waterfall([
this.traceManager.getStackAt, function getStackAt (stepIndex, callback) {
this.traceManager.getMemoryAt,
(stepIndex, next) => {
try { try {
const address = this.traceManager.getCurrentCalledAddressAt(stepIndex) const result = self.traceManager.getStackAt(stepIndex)
callback(null, result)
} catch (error) {
callback(error)
}
},
function getMemoryAt (stepIndex, callback) {
try {
const result = self.traceManager.getMemoryAt(stepIndex)
callback(null, result)
} catch (error) {
callback(error)
}
},
function getCurrentCalledAddressAt (stepIndex, next) {
try {
const address = self.traceManager.getCurrentCalledAddressAt(stepIndex)
next(null, address) next(null, address)
} catch (error) { } catch (error) {
next(error) next(error)

@ -41,11 +41,7 @@ class DebuggerStepManager {
if (index < 0) return if (index < 0) return
if (this.currentStepIndex !== index) return if (this.currentStepIndex !== index) return
this.traceManager.buildCallPath(index, (error, callsPath) => { this.traceManager.buildCallPath(index).then((callsPath) => {
if (error) {
console.log(error)
return this.event.trigger('revertWarning', [''])
}
this.currentCall = callsPath[callsPath.length - 1] this.currentCall = callsPath[callsPath.length - 1]
if (this.currentCall.reverted) { if (this.currentCall.reverted) {
let revertedReason = this.currentCall.outofgas ? 'outofgas' : '' let revertedReason = this.currentCall.outofgas ? 'outofgas' : ''
@ -59,6 +55,9 @@ class DebuggerStepManager {
this.event.trigger('revertWarning', ['parenthasthrown']) this.event.trigger('revertWarning', ['parenthasthrown'])
} }
this.event.trigger('revertWarning', ['']) this.event.trigger('revertWarning', [''])
}).catch((error) => {
console.log(error)
this.event.trigger('revertWarning', [''])
}) })
}) })
} }

@ -51,27 +51,24 @@ function extractStateDefinitions (contractName, sourcesList, contracts) {
contracts = extractContractDefinitions(sourcesList) contracts = extractContractDefinitions(sourcesList)
} }
const node = contracts.contractsByName[contractName] const node = contracts.contractsByName[contractName]
if (node) { if (!node) {
const stateItems = [] return null
const stateVar = [] }
const baseContracts = getLinearizedBaseContracts(node.id, contracts.contractsById) const stateItems = []
baseContracts.reverse() const stateVar = []
for (let k in baseContracts) { const baseContracts = getLinearizedBaseContracts(node.id, contracts.contractsById)
const ctr = baseContracts[k] baseContracts.reverse()
for (let i in ctr.children) { for (let k in baseContracts) {
const item = ctr.children[i] const ctr = baseContracts[k]
stateItems.push(item) for (let i in ctr.children) {
if (item.name === 'VariableDeclaration') { const item = ctr.children[i]
stateVar.push(item) stateItems.push(item)
} if (item.name === 'VariableDeclaration') {
stateVar.push(item)
} }
} }
return {
stateDefinitions: stateItems,
stateVariables: stateVar
}
} }
return null return {stateDefinitions: stateItems, stateVariables: stateVar}
} }
/** /**

@ -224,26 +224,27 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
// we check if the current vm trace step target a new ast node of type VariableDeclaration // we check if the current vm trace step target a new ast node of type VariableDeclaration
// that way we know that there is a new local variable from here. // that way we know that there is a new local variable from here.
if (variableDeclaration && !tree.scopes[scopeId].locals[variableDeclaration.attributes.name]) { if (variableDeclaration && !tree.scopes[scopeId].locals[variableDeclaration.attributes.name]) {
tree.traceManager.getStackAt(step, (error, stack) => { try {
const stack = tree.traceManager.getStackAt(step)
// the stack length at this point is where the value of the new local variable will be stored. // the stack length at this point is where the value of the new local variable will be stored.
// so, either this is the direct value, or the offset in memory. That depends on the type. // so, either this is the direct value, or the offset in memory. That depends on the type.
if (!error) { tree.solidityProxy.contractNameAt(step).then((contractName) => {
tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached if (variableDeclaration.attributes.name !== '') {
if (!error && variableDeclaration.attributes.name !== '') { var states = tree.solidityProxy.extractStatesDefinitions()
var states = tree.solidityProxy.extractStatesDefinitions() var location = typesUtil.extractLocationFromAstVariable(variableDeclaration)
var location = typesUtil.extractLocationFromAstVariable(variableDeclaration) location = location === 'default' ? 'storage' : location
location = location === 'default' ? 'storage' : location
// we push the new local variable in our tree // we push the new local variable in our tree
tree.scopes[scopeId].locals[variableDeclaration.attributes.name] = { tree.scopes[scopeId].locals[variableDeclaration.attributes.name] = {
name: variableDeclaration.attributes.name, name: variableDeclaration.attributes.name,
type: decodeInfo.parseType(variableDeclaration.attributes.type, states, contractName, location), type: decodeInfo.parseType(variableDeclaration.attributes.type, states, contractName, location),
stackDepth: stack.length, stackDepth: stack.length,
sourceLocation: sourceLocation sourceLocation: sourceLocation
}
} }
}) }
} })
}) } catch (error) {
console.log(error)
}
} }
// we check here if we are at the beginning inside a new function. // we check here if we are at the beginning inside a new function.
// if that is the case, we have to add to locals tree the inputs and output params // if that is the case, we have to add to locals tree the inputs and output params
@ -253,34 +254,35 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
const functionDefinitionAndInputs = {functionDefinition, inputs: []} const functionDefinitionAndInputs = {functionDefinition, inputs: []}
// means: the previous location was a function definition && JUMPDEST // means: the previous location was a function definition && JUMPDEST
// => we are at the beginning of the function and input/output are setup // => we are at the beginning of the function and input/output are setup
tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached
if (!error) { tree.solidityProxy.contractNameAt(step).then((contractName) => { // cached
tree.traceManager.getStackAt(step, (error, stack) => { try {
if (!error) { const stack = tree.traceManager.getStackAt(step)
var states = tree.solidityProxy.extractStatesDefinitions() var states = tree.solidityProxy.extractStatesDefinitions()
if (functionDefinition.children && functionDefinition.children.length) { if (functionDefinition.children && functionDefinition.children.length) {
let inputs let inputs
let outputs let outputs
for (const element of functionDefinition.children) { for (const element of functionDefinition.children) {
if (element.name === 'ParameterList') { if (element.name === 'ParameterList') {
if (!inputs) inputs = element if (!inputs) inputs = element
else { else {
outputs = element outputs = element
break break
}
}
}
// input params
if (inputs) {
functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, inputs.children.length, -1)
} }
// output params
if (outputs) addParams(outputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, 0, 1)
} }
} }
}) // input params
if (inputs) {
functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, inputs.children.length, -1)
}
// output params
if (outputs) addParams(outputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, 0, 1)
}
} catch (error) {
console.log(error)
} }
}) })
tree.functionDefinitionsByScope[scopeId] = functionDefinitionAndInputs tree.functionDefinitionsByScope[scopeId] = functionDefinitionAndInputs
} }
} }

@ -39,26 +39,25 @@ class SolidityProxy {
* @param {Int} vmTraceIndex - index in the vm trave where to resolve the executed contract name * @param {Int} vmTraceIndex - index in the vm trave where to resolve the executed contract name
* @param {Function} cb - callback returns (error, contractName) * @param {Function} cb - callback returns (error, contractName)
*/ */
contractNameAt (vmTraceIndex, cb) { contractNameAt (vmTraceIndex) {
try { return new Promise((resolve, reject) => {
const address = this.traceManager.getCurrentCalledAddressAt(vmTraceIndex) try {
const address = this.traceManager.getCurrentCalledAddressAt(vmTraceIndex)
if (this.cache.contractNameByAddress[address]) { if (this.cache.contractNameByAddress[address]) {
cb(null, this.cache.contractNameByAddress[address]) return resolve(this.cache.contractNameByAddress[address])
} else { }
this.codeManager.getCode(address, (error, code) => { this.codeManager.getCode(address, (error, code) => {
if (error) { if (error) {
cb(error) return reject(error)
} else {
const contractName = contractNameFromCode(this.contracts, code.bytecode, address)
this.cache.contractNameByAddress[address] = contractName
cb(null, contractName)
} }
const contractName = contractNameFromCode(this.contracts, code.bytecode, address)
this.cache.contractNameByAddress[address] = contractName
resolve(contractName)
}) })
} catch (error) {
reject(error)
} }
} catch (error) { })
cb(error)
}
} }
/** /**
@ -98,12 +97,9 @@ class SolidityProxy {
*/ */
extractStateVariablesAt (vmtraceIndex) { extractStateVariablesAt (vmtraceIndex) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.contractNameAt(vmtraceIndex, (error, contractName) => { this.contractNameAt(vmtraceIndex).then((contractName) => {
if (error) { resolve(this.extractStateVariables(contractName))
return reject(error) }).catch(reject)
}
return resolve(this.extractStateVariables(contractName))
})
}) })
} }

@ -10,10 +10,9 @@ class Bool extends ValueType {
decodeValue (value) { decodeValue (value) {
if (!value) { if (!value) {
return false return false
} else {
value = util.extractHexByteSlice(value, this.storageBytes, 0)
return value !== '00'
} }
value = util.extractHexByteSlice(value, this.storageBytes, 0)
return value !== '00'
} }
} }

@ -16,14 +16,12 @@ class Enum extends ValueType {
decodeValue (value) { decodeValue (value) {
if (!value) { if (!value) {
return this.enumDef.children[0].attributes.name return this.enumDef.children[0].attributes.name
} else {
value = parseInt(value, 16)
if (this.enumDef.children.length > value) {
return this.enumDef.children[value].attributes.name
} else {
return 'INVALID_ENUM<' + value + '>'
}
} }
value = parseInt(value, 16)
if (this.enumDef.children.length > value) {
return this.enumDef.children[value].attributes.name
}
return 'INVALID_ENUM<' + value + '>'
} }
} }

@ -100,9 +100,8 @@ function extractLocation (type) {
let match = type.match(/( storage ref| storage pointer| memory| calldata)?$/) let match = type.match(/( storage ref| storage pointer| memory| calldata)?$/)
if (match[1] !== '') { if (match[1] !== '') {
return match[1].trim() return match[1].trim()
} else {
return null
} }
return null
} }
function extractLocationFromAstVariable (node) { function extractLocationFromAstVariable (node) {
@ -110,9 +109,8 @@ function extractLocationFromAstVariable (node) {
return node.attributes.storageLocation return node.attributes.storageLocation
} else if (node.attributes.stateVariable) { } else if (node.attributes.stateVariable) {
return 'storage' return 'storage'
} else {
return 'default' // local variables => storage, function parameters & return values => memory, state => storage
} }
return 'default' // local variables => storage, function parameters & return values => memory, state => storage
} }
function normalizeHex (hex) { function normalizeHex (hex) {

@ -13,7 +13,7 @@ module.exports = {
* @param {Function} callback - calback * @param {Function} callback - calback
* @return {Map} - solidity mapping location (e.g { "<mapping_slot>" : { "<mapping-key1>": preimageOf1 }, { "<mapping-key2>": preimageOf2 }, ... }) * @return {Map} - solidity mapping location (e.g { "<mapping_slot>" : { "<mapping-key1>": preimageOf1 }, { "<mapping-key2>": preimageOf2 }, ... })
*/ */
async function decodeMappingsKeys (web3, storage, corrections, callback) { async function decodeMappingsKeys (web3, storage, corrections) {
const ret = {} const ret = {}
if (!corrections.length) corrections.push({offset: 0, slot: 0}) if (!corrections.length) corrections.push({offset: 0, slot: 0})
for (let hashedLoc in storage) { for (let hashedLoc in storage) {
@ -38,7 +38,7 @@ async function decodeMappingsKeys (web3, storage, corrections, callback) {
ret[mappingSlot][mappingKey] = preimage ret[mappingSlot][mappingKey] = preimage
} }
} }
callback(null, ret) return ret
} }
/** /**

@ -25,8 +25,8 @@ class StorageResolver {
* @param {String} - address - lookup address * @param {String} - address - lookup address
* @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value} * @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value}
*/ */
storageRange (tx, stepIndex, address, callback) { storageRange (tx, stepIndex, address) {
this.storageRangeInternal(this, this.zeroSlot, tx, stepIndex, address, callback) return this.storageRangeInternal(this, this.zeroSlot, tx, stepIndex, address)
} }
/** /**
@ -39,22 +39,16 @@ class StorageResolver {
* @param {Array} corrections - used in case the calculated sha3 has been modifyed before SSTORE (notably used for struct in mapping). * @param {Array} corrections - used in case the calculated sha3 has been modifyed before SSTORE (notably used for struct in mapping).
* @return {Function} - callback * @return {Function} - callback
*/ */
initialPreimagesMappings (tx, stepIndex, address, corrections, callback) { initialPreimagesMappings (tx, stepIndex, address, corrections) {
if (this.preimagesMappingByAddress[address]) { return new Promise((resolve, reject) => {
return callback(null, this.preimagesMappingByAddress[address]) if (this.preimagesMappingByAddress[address]) {
} return resolve(this.preimagesMappingByAddress[address])
this.storageRange(tx, stepIndex, address, (error, storage) => {
if (error) {
return callback(error)
} }
mappingPreimages.decodeMappingsKeys(this.web3, storage, corrections, (error, mappings) => { this.storageRange(tx, stepIndex, address).then((storage) => {
if (error) { const mappings = mappingPreimages.decodeMappingsKeys(this.web3, storage, corrections)
callback(error) this.preimagesMappingByAddress[address] = mappings
} else { resolve(mappings)
this.preimagesMappingByAddress[address] = mappings }).catch(reject)
callback(null, mappings)
}
})
}) })
} }
@ -67,13 +61,11 @@ class StorageResolver {
* @param {String} - address - lookup address * @param {String} - address - lookup address
* @param {Function} - callback - {key, hashedKey, value} - * @param {Function} - callback - {key, hashedKey, value} -
*/ */
storageSlot (slot, tx, stepIndex, address, callback) { storageSlot (slot, tx, stepIndex, address) {
this.storageRangeInternal(this, slot, tx, stepIndex, address, (error, storage) => { return new Promise((resolve, reject) => {
if (error) { this.storageRangeInternal(this, slot, tx, stepIndex, address).then((storage) => {
callback(error) resolve(storage[slot] !== undefined ? storage[slot] : null)
} else { }).catch(reject)
callback(null, storage[slot] !== undefined ? storage[slot] : null)
}
}) })
} }
@ -93,26 +85,26 @@ class StorageResolver {
* even if the next 1000 items are not in the cache. * even if the next 1000 items are not in the cache.
* - If @arg slot is not cached, the corresponding value will be resolved and the next 1000 slots. * - If @arg slot is not cached, the corresponding value will be resolved and the next 1000 slots.
*/ */
storageRangeInternal (self, slotKey, tx, stepIndex, address, callback) { storageRangeInternal (self, slotKey, tx, stepIndex, address) {
var cached = this.fromCache(self, address) return new Promise((resolve, reject) => {
if (cached && cached.storage[slotKey]) { // we have the current slot in the cache and maybe the next 1000... var cached = this.fromCache(self, address)
return callback(null, cached.storage) if (cached && cached.storage[slotKey]) { // we have the current slot in the cache and maybe the next 1000...
} return resolve(cached.storage)
this.storageRangeWeb3Call(tx, address, slotKey, self.maxSize, (error, storage, nextKey) => {
if (error) {
return callback(error)
} }
if (!storage[slotKey] && slotKey !== self.zeroSlot) { // we don't cache the zero slot (could lead to inconsistency) this.storageRangeWeb3Call(tx, address, slotKey, self.maxSize).then((result) => {
storage[slotKey] = { const [storage, nextKey] = result
key: slotKey, if (!storage[slotKey] && slotKey !== self.zeroSlot) { // we don't cache the zero slot (could lead to inconsistency)
value: self.zeroSlot storage[slotKey] = {
key: slotKey,
value: self.zeroSlot
}
} }
} self.toCache(self, address, storage)
self.toCache(self, address, storage) if (slotKey === self.zeroSlot && !nextKey) { // only working if keys are sorted !!
if (slotKey === self.zeroSlot && !nextKey) { // only working if keys are sorted !! self.storageByAddress[address].complete = true
self.storageByAddress[address].complete = true }
} return resolve(storage)
callback(null, storage) }).catch(reject)
}) })
} }
@ -142,25 +134,27 @@ class StorageResolver {
self.storageByAddress[address].storage = Object.assign(self.storageByAddress[address].storage || {}, storage) self.storageByAddress[address].storage = Object.assign(self.storageByAddress[address].storage || {}, storage)
} }
storageRangeWeb3Call (tx, address, start, maxSize, callback) { storageRangeWeb3Call (tx, address, start, maxSize) {
if (traceHelper.isContractCreation(address)) { return new Promise((resolve, reject) => {
callback(null, {}, null) if (traceHelper.isContractCreation(address)) {
} else { resolve([{}, null])
this.web3.debug.storageRangeAt( } else {
tx.blockHash, tx.transactionIndex === undefined ? tx.hash : tx.transactionIndex, this.web3.debug.storageRangeAt(
address, tx.blockHash, tx.transactionIndex === undefined ? tx.hash : tx.transactionIndex,
start, address,
maxSize, start,
(error, result) => { maxSize,
if (error) { (error, result) => {
callback(error) if (error) {
} else if (result.storage) { reject(error)
callback(null, result.storage, result.nextKey) } else if (result.storage) {
} else { resolve([result.storage, result.nextKey])
callback('the storage has not been provided') } else {
} reject('the storage has not been provided')
}) }
} })
}
})
} }
} }

@ -15,13 +15,7 @@ class StorageViewer {
this.web3 = this.storageResolver.web3 this.web3 = this.storageResolver.web3
this.initialMappingsLocationPromise = null this.initialMappingsLocationPromise = null
this.currentMappingsLocationPromise = null this.currentMappingsLocationPromise = null
_traceManager.accumulateStorageChanges(this.context.stepIndex, this.context.address, {}, (error, storageChanges) => { this.storageChanges = _traceManager.accumulateStorageChanges(this.context.stepIndex, this.context.address, {})
if (!error) {
this.storageChanges = storageChanges
} else {
console.log(error)
}
})
} }
/** /**
@ -30,13 +24,11 @@ class StorageViewer {
* *
* @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value} * @param {Function} - callback - contains a map: [hashedKey] = {key, hashedKey, value}
*/ */
storageRange (callback) { storageRange () {
this.storageResolver.storageRange(this.context.tx, this.context.stepIndex, this.context.address, (error, storage) => { return new Promise((resolve, reject) => {
if (error) { this.storageResolver.storageRange(this.context.tx, this.context.stepIndex, this.context.address).then((storage) => {
callback(error) resolve(Object.assign({}, storage, this.storageChanges))
} else { }).catch(reject)
callback(null, Object.assign({}, storage, this.storageChanges))
}
}) })
} }
@ -50,13 +42,9 @@ class StorageViewer {
if (this.storageChanges[hashed]) { if (this.storageChanges[hashed]) {
return callback(null, this.storageChanges[hashed]) return callback(null, this.storageChanges[hashed])
} }
this.storageResolver.storageSlot(hashed, this.context.tx, this.context.stepIndex, this.context.address, (error, storage) => { this.storageResolver.storageSlot(hashed, this.context.tx, this.context.stepIndex, this.context.address).then((storage) => {
if (error) { callback(null, storage)
callback(error) }).catch(callback)
} else {
callback(null, storage)
}
})
} }
/** /**
@ -76,15 +64,7 @@ class StorageViewer {
*/ */
async initialMappingsLocation (corrections) { async initialMappingsLocation (corrections) {
if (!this.initialMappingsLocationPromise) { if (!this.initialMappingsLocationPromise) {
this.initialMappingsLocationPromise = new Promise((resolve, reject) => { this.initialMappingsLocationPromise = this.storageResolver.initialPreimagesMappings(this.context.tx, this.context.stepIndex, this.context.address, corrections)
this.storageResolver.initialPreimagesMappings(this.context.tx, this.context.stepIndex, this.context.address, corrections, (error, initialMappingsLocation) => {
if (error) {
reject(error)
} else {
resolve(initialMappingsLocation)
}
})
})
} }
return this.initialMappingsLocationPromise return this.initialMappingsLocationPromise
} }
@ -118,14 +98,9 @@ class StorageViewer {
if (this.mappingsLocationChanges) { if (this.mappingsLocationChanges) {
return callback(null, this.mappingsLocationChanges) return callback(null, this.mappingsLocationChanges)
} }
mappingPreimages.decodeMappingsKeys(this.web3, storageChanges, corrections, (error, mappings) => { const mappings = mappingPreimages.decodeMappingsKeys(this.web3, storageChanges, corrections)
if (!error) { this.mappingsLocationChanges = mappings
this.mappingsLocationChanges = mappings return callback(null, this.mappingsLocationChanges)
return callback(null, this.mappingsLocationChanges)
} else {
callback(error)
}
})
} }
} }

@ -193,23 +193,27 @@ function testDebugging (debugManager) {
// stack // stack
tape('traceManager.getStackAt 4', (t) => { tape('traceManager.getStackAt 4', (t) => {
t.plan(1) t.plan(1)
debugManager.traceManager.getStackAt(4, (error, callstack) => { try {
if (error) return t.end(error) const callstack = debugManager.traceManager.getStackAt(4)
t.equal(JSON.stringify(callstack), JSON.stringify([ '0x0000000000000000000000000000000000000000000000000000000000000000' ])) t.equal(JSON.stringify(callstack), JSON.stringify(['0x0000000000000000000000000000000000000000000000000000000000000000']))
}) } catch (error) {
return t.end(error)
}
}) })
tape('traceManager.getStackAt 41', (t) => { tape('traceManager.getStackAt 41', (t) => {
t.plan(1) t.plan(1)
debugManager.traceManager.getStackAt(41, (error, callstack) => { try {
if (error) return t.end(error) const callstack = debugManager.traceManager.getStackAt(41)
t.equal(JSON.stringify(callstack), JSON.stringify([ t.equal(JSON.stringify(callstack), JSON.stringify([
'0x0000000000000000000000000000000000000000000000000000000000000080', '0x0000000000000000000000000000000000000000000000000000000000000080',
'0x0000000000000000000000000000000000000000000000000000000000000020', '0x0000000000000000000000000000000000000000000000000000000000000020',
'0x0000000000000000000000000000000000000000000000000000000000000080', '0x0000000000000000000000000000000000000000000000000000000000000080',
'0x00000000000000000000000000000000000000000000000000000000000000e0', '0x00000000000000000000000000000000000000000000000000000000000000e0',
'0x00000000000000000000000000000000000000000000000000000000000000e0'])) '0x00000000000000000000000000000000000000000000000000000000000000e0']))
}) } catch (error) {
return t.end(error)
}
}) })
// storage // storage
@ -220,9 +224,11 @@ function testDebugging (debugManager) {
const address = debugManager.traceManager.getCurrentCalledAddressAt(38) const address = debugManager.traceManager.getCurrentCalledAddressAt(38)
console.log(address) console.log(address)
var storageView = debugManager.storageViewAt(196, address) var storageView = debugManager.storageViewAt(196, address)
storageView.storageRange((error, storage) => {
if (error) return t.end(error) storageView.storageRange().then((storage) => {
t.equal(JSON.stringify(storage), JSON.stringify({ '0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563': { key: '0x0000000000000000000000000000000000000000000000000000000000000000', value: '0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db' } })) t.equal(JSON.stringify(storage), JSON.stringify({ '0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563': { key: '0x0000000000000000000000000000000000000000000000000000000000000000', value: '0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db' } }))
}).catch((error) => {
if (error) return t.end(error)
}) })
} catch (error) { } catch (error) {
return t.end(error) return t.end(error)

@ -7,8 +7,22 @@ var localDecoder = require('../../../src/solidity-decoder/localDecoder')
function decodeLocal (st, index, traceManager, callTree, verifier) { function decodeLocal (st, index, traceManager, callTree, verifier) {
try { try {
traceManager.waterfall([ traceManager.waterfall([
traceManager.getStackAt, function getStackAt (stepIndex, callback) {
traceManager.getMemoryAt], try {
const result = traceManager.getStackAt(stepIndex)
callback(null, result)
} catch (error) {
callback(error)
}
},
function getMemoryAt (stepIndex, callback) {
try {
const result = traceManager.getMemoryAt(stepIndex)
callback(null, result)
} catch (error) {
callback(error)
}
}],
index, index,
function (error, result) { function (error, result) {
if (!error) { if (!error) {

@ -63,12 +63,9 @@ CodeManager.prototype.getCode = function (address, cb) {
if (codes) { if (codes) {
return cb(null, codes) return cb(null, codes)
} }
this.traceManager.getContractCreationCode(address, (error, hexCode) => { const hexCode = this.traceManager.getContractCreationCode(address)
if (!error) { codes = this.codeResolver.cacheExecutingCode(address, hexCode)
codes = this.codeResolver.cacheExecutingCode(address, hexCode) cb(null, codes)
cb(null, codes)
}
})
} }
/** /**
@ -82,16 +79,11 @@ CodeManager.prototype.getCode = function (address, cb) {
CodeManager.prototype.getFunctionFromStep = function (stepIndex, sourceMap, ast) { CodeManager.prototype.getFunctionFromStep = function (stepIndex, sourceMap, ast) {
try { try {
const address = this.traceManager.getCurrentCalledAddressAt(stepIndex) const address = this.traceManager.getCurrentCalledAddressAt(stepIndex)
this.traceManager.getCurrentPC(stepIndex, (error, pc) => { const pc = this.traceManager.getCurrentPC(stepIndex)
if (error) { return this.getFunctionFromPC(address, pc, sourceMap, ast)
console.log(error)
return { error: 'Cannot retrieve current PC for ' + stepIndex }
}
return this.getFunctionFromPC(address, pc, sourceMap, ast)
})
} catch (error) { } catch (error) {
console.log(error) console.log(error)
return { error: 'Cannot retrieve current address for ' + stepIndex } return { error: 'Cannot retrieve current address or PC for ' + stepIndex }
} }
} }
@ -103,14 +95,14 @@ CodeManager.prototype.getFunctionFromStep = function (stepIndex, sourceMap, ast)
* @param {Function} callback - instruction index * @param {Function} callback - instruction index
*/ */
CodeManager.prototype.getInstructionIndex = function (address, step, callback) { CodeManager.prototype.getInstructionIndex = function (address, step, callback) {
this.traceManager.getCurrentPC(step, (error, pc) => { try {
if (error) { const pc = this.traceManager.getCurrentPC(step)
console.log(error)
return callback('Cannot retrieve current PC for ' + step, null)
}
const itemIndex = this.codeResolver.getInstructionIndex(address, pc) const itemIndex = this.codeResolver.getInstructionIndex(address, pc)
callback(null, itemIndex) callback(null, itemIndex)
}) } catch (error) {
console.log(error)
return callback('Cannot retrieve current PC for ' + step, null)
}
} }
/** /**

@ -40,19 +40,15 @@ SourceLocationTracker.prototype.getSourceLocationFromInstructionIndex = function
*/ */
SourceLocationTracker.prototype.getSourceLocationFromVMTraceIndex = function (address, vmtraceStepIndex, contracts) { SourceLocationTracker.prototype.getSourceLocationFromVMTraceIndex = function (address, vmtraceStepIndex, contracts) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
extractSourceMap(this, this.codeManager, address, contracts, (error, sourceMap) => { extractSourceMap(this, this.codeManager, address, contracts).then((sourceMap) => {
if (!error) { this.codeManager.getInstructionIndex(address, vmtraceStepIndex, (error, index) => {
this.codeManager.getInstructionIndex(address, vmtraceStepIndex, (error, index) => { if (error) {
if (error) { reject(error)
reject(error) } else {
} else { resolve(this.sourceMappingDecoder.atIndex(index, sourceMap))
resolve(this.sourceMappingDecoder.atIndex(index, sourceMap)) }
} })
}) }).catch(reject)
} else {
reject(error)
}
})
}) })
} }
@ -78,21 +74,23 @@ function getSourceMap (address, code, contracts) {
return null return null
} }
function extractSourceMap (self, codeManager, address, contracts, cb) { function extractSourceMap (self, codeManager, address, contracts) {
if (self.sourceMapByAddress[address]) return cb(null, self.sourceMapByAddress[address]) return new Promise((resolve, reject) => {
if (self.sourceMapByAddress[address]) return resolve(self.sourceMapByAddress[address])
codeManager.getCode(address, (error, result) => { codeManager.getCode(address, (error, result) => {
if (!error) { if (!error) {
const sourceMap = getSourceMap(address, result.bytecode, contracts) const sourceMap = getSourceMap(address, result.bytecode, contracts)
if (sourceMap) { if (sourceMap) {
if (!helper.isContractCreation(address)) self.sourceMapByAddress[address] = sourceMap if (!helper.isContractCreation(address)) self.sourceMapByAddress[address] = sourceMap
cb(null, sourceMap) resolve(sourceMap)
} else {
reject('no sourcemap associated with the code ' + address)
}
} else { } else {
cb('no sourcemap associated with the code ' + address) reject(error)
} }
} else { })
cb(error)
}
}) })
} }

@ -80,35 +80,36 @@ TraceManager.prototype.getLength = function (callback) {
} }
} }
TraceManager.prototype.accumulateStorageChanges = function (index, address, storageOrigin, callback) { TraceManager.prototype.accumulateStorageChanges = function (index, address, storageOrigin) {
const storage = this.traceCache.accumulateStorageChanges(index, address, storageOrigin) return this.traceCache.accumulateStorageChanges(index, address, storageOrigin)
callback(null, storage)
} }
TraceManager.prototype.getAddresses = function (callback) { TraceManager.prototype.getAddresses = function () {
callback(null, this.traceCache.addresses) return this.traceCache.addresses
} }
TraceManager.prototype.getCallDataAt = function (stepIndex, callback) { TraceManager.prototype.getCallDataAt = function (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
return callback(check, null) throw new Error(check)
} }
const callDataChange = util.findLowerBoundValue(stepIndex, this.traceCache.callDataChanges) const callDataChange = util.findLowerBoundValue(stepIndex, this.traceCache.callDataChanges)
if (callDataChange === null) return callback('no calldata found', null) if (callDataChange === null) {
callback(null, [this.traceCache.callsData[callDataChange]]) throw new Error('no calldata found')
}
return [this.traceCache.callsData[callDataChange]]
} }
TraceManager.prototype.buildCallPath = function (stepIndex, callback) { TraceManager.prototype.buildCallPath = async function (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
return callback(check, null) throw new Error(check)
} }
const callsPath = util.buildCallPath(stepIndex, this.traceCache.callsTree.call) const callsPath = util.buildCallPath(stepIndex, this.traceCache.callsTree.call)
if (callsPath === null) return callback('no call path built', null) if (callsPath === null) throw new Error('no call path built')
callback(null, callsPath) return callsPath
} }
TraceManager.prototype.getCallStackAt = function (stepIndex) { TraceManager.prototype.getCallStackAt = function (stepIndex) {
@ -124,19 +125,14 @@ TraceManager.prototype.getCallStackAt = function (stepIndex) {
return call.callStack return call.callStack
} }
TraceManager.prototype.getStackAt = function (stepIndex, callback) { TraceManager.prototype.getStackAt = function (stepIndex) {
try { this.checkRequestedStep(stepIndex)
this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null)
}
let stack
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
stack = this.trace[stepIndex].stack.slice(0) let stack = this.trace[stepIndex].stack.slice(0)
stack.reverse() stack.reverse()
callback(null, stack) return stack
} else { } else {
callback('no stack found', null) throw new Error('no stack found')
} }
} }
@ -167,54 +163,50 @@ TraceManager.prototype.getCurrentCalledAddressAt = function (stepIndex) {
} }
} }
TraceManager.prototype.getContractCreationCode = function (token, callback) { TraceManager.prototype.getContractCreationCode = function (token) {
if (this.traceCache.contractCreation[token]) { if (!this.traceCache.contractCreation[token]) {
callback(null, this.traceCache.contractCreation[token]) throw new Error('no contract creation named ' + token)
} else {
callback('no contract creation named ' + token, null)
} }
return this.traceCache.contractCreation[token]
} }
TraceManager.prototype.getMemoryAt = function (stepIndex, callback) { TraceManager.prototype.getMemoryAt = function (stepIndex) {
try { this.checkRequestedStep(stepIndex)
this.checkRequestedStep(stepIndex)
} catch (check) {
return callback(check, null)
}
const lastChanges = util.findLowerBoundValue(stepIndex, this.traceCache.memoryChanges) const lastChanges = util.findLowerBoundValue(stepIndex, this.traceCache.memoryChanges)
if (lastChanges === null) return callback('no memory found', null) if (lastChanges === null) {
callback(null, this.trace[lastChanges].memory) throw new Error('no memory found')
}
return this.trace[lastChanges].memory
} }
TraceManager.prototype.getCurrentPC = function (stepIndex, callback) { TraceManager.prototype.getCurrentPC = function (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
return callback(check, null) throw new Error(check)
} }
callback(null, this.trace[stepIndex].pc) return this.trace[stepIndex].pc
} }
TraceManager.prototype.getReturnValue = function (stepIndex, callback) { TraceManager.prototype.getReturnValue = function (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
return callback(check, null) throw new Error(check)
} }
if (!this.traceCache.returnValues[stepIndex]) { if (!this.traceCache.returnValues[stepIndex]) {
callback('current step is not a return step') throw new Error('current step is not a return step')
} else {
callback(null, this.traceCache.returnValues[stepIndex])
} }
return this.traceCache.returnValues[stepIndex]
} }
TraceManager.prototype.getCurrentStep = function (stepIndex, callback) { TraceManager.prototype.getCurrentStep = function (stepIndex) {
try { try {
this.checkRequestedStep(stepIndex) this.checkRequestedStep(stepIndex)
} catch (check) { } catch (check) {
return callback(check, null) throw new Error(check)
} }
callback(null, this.traceCache.steps[stepIndex]) return this.traceCache.steps[stepIndex]
} }
TraceManager.prototype.getMemExpand = function (stepIndex) { TraceManager.prototype.getMemExpand = function (stepIndex) {

@ -55,25 +55,19 @@ tape('TraceManager', function (t) {
}) })
t.test('TraceManager.accumulateStorageChanges', function (st) { t.test('TraceManager.accumulateStorageChanges', function (st) {
traceManager.accumulateStorageChanges(110, '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5', {}, function (error, result) { const result = traceManager.accumulateStorageChanges(110, '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5', {})
if (error) { st.ok(result['0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563'].value === '0x38')
st.fail(error) st.end()
} else {
st.ok(result['0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563'].value === '0x38')
st.end()
}
})
}) })
t.test('TraceManager.getCallData', function (st) { t.test('TraceManager.getCallData', function (st) {
traceManager.getCallDataAt(0, function (error, result) { try {
if (error) { const result = traceManager.getCallDataAt(0)
st.fail(error) st.ok(result[0] === '0x60fe47b10000000000000000000000000000000000000000000000000000000000000038')
} else { st.end()
st.ok(result[0] === '0x60fe47b10000000000000000000000000000000000000000000000000000000000000038') } catch (error) {
st.end() st.fail(error)
} }
})
}) })
t.test('TraceManager.getCallStackAt', function (st) { t.test('TraceManager.getCallStackAt', function (st) {
@ -96,24 +90,22 @@ tape('TraceManager', function (t) {
t.test('TraceManager.getStackAt', function (st) { t.test('TraceManager.getStackAt', function (st) {
st.plan(3) st.plan(3)
traceManager.getStackAt(0, function (error, result) { try {
const result = traceManager.getStackAt(0)
console.log(result) console.log(result)
if (error) { st.ok(result.length === 0)
st.fail(error) } catch (error) {
} else { st.fail(error)
st.ok(result.length === 0) }
}
})
traceManager.getStackAt(28, function (error, result) { try {
const result = traceManager.getStackAt(28)
console.log(result) console.log(result)
if (error) { st.ok(result.length === 4)
st.fail(error) st.ok(result[3] === '0x60fe47b1')
} else { } catch (error) {
st.ok(result.length === 4) st.fail(error)
st.ok(result[3] === '0x60fe47b1') }
}
})
}) })
t.test('TraceManager.getLastCallChangeSince', function (st) { t.test('TraceManager.getLastCallChangeSince', function (st) {
@ -175,61 +167,56 @@ tape('TraceManager', function (t) {
}) })
t.test('TraceManager.getContractCreationCode', function (st) { // contract code has been retrieved from the memory t.test('TraceManager.getContractCreationCode', function (st) { // contract code has been retrieved from the memory
traceManager.getContractCreationCode('(Contract Creation - Step 63)', function (error, result) { try {
const result = traceManager.getContractCreationCode('(Contract Creation - Step 63)')
console.log(result) console.log(result)
if (error) { st.ok(result === '0x60606040526040516020806045833981016040528080519060200190919050505b806001016000600050819055505b50600a80603b6000396000f360606040526008565b00000000000000000000000000000000000000000000000000000000000000002d')
st.fail(error) st.end()
} else { } catch (error) {
st.ok(result === '0x60606040526040516020806045833981016040528080519060200190919050505b806001016000600050819055505b50600a80603b6000396000f360606040526008565b00000000000000000000000000000000000000000000000000000000000000002d') st.fail(error)
st.end() }
}
})
}) })
t.test('TraceManager.getMemoryAt', function (st) { t.test('TraceManager.getMemoryAt', function (st) {
st.plan(3) st.plan(3)
traceManager.getMemoryAt(0, function (error, result) { try {
const result = traceManager.getMemoryAt(0)
console.log(result) console.log(result)
if (error) { st.ok(result.length === 0)
st.fail(error) } catch (error) {
} else { st.fail(error)
st.ok(result.length === 0) }
}
})
traceManager.getMemoryAt(34, function (error, result) { try {
const result = traceManager.getMemoryAt(34)
console.log(result) console.log(result)
if (error) { st.ok(result.length === 3)
st.fail(error) st.ok(result[2] === '0000000000000000000000000000000000000000000000000000000000000060')
} else { } catch (error) {
st.ok(result.length === 3) st.fail(error)
st.ok(result[2] === '0000000000000000000000000000000000000000000000000000000000000060') }
}
})
}) })
t.test('TraceManager.getCurrentPC', function (st) { t.test('TraceManager.getCurrentPC', function (st) {
traceManager.getCurrentPC(13, function (error, result) { try {
const result = traceManager.getCurrentPC(13)
console.log(result) console.log(result)
if (error) { st.ok(result === '65')
st.fail(error) st.end()
} else { } catch (error) {
st.ok(result === '65') st.fail(error)
st.end() }
}
})
}) })
t.test('TraceManager.getCurrentStep', function (st) { t.test('TraceManager.getCurrentStep', function (st) {
traceManager.getCurrentStep(66, function (error, result) { try {
const result = traceManager.getCurrentStep(66)
console.log(result) console.log(result)
if (error) { st.ok(result === 2)
st.fail(error) st.end()
} else { } catch (error) {
st.ok(result === 2) st.fail(error)
st.end() }
}
})
}) })
t.test('TraceManager.getMemExpand', function (st) { t.test('TraceManager.getMemExpand', function (st) {
@ -287,25 +274,19 @@ tape('TraceManager', function (t) {
}) })
t.test('TraceManager.getAddresses', function (st) { t.test('TraceManager.getAddresses', function (st) {
traceManager.getAddresses(function (error, result) { const result = traceManager.getAddresses()
if (error) { st.ok(result[0] === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
st.fail(error) st.ok(result[1] === '(Contract Creation - Step 63)')
} else { st.end()
st.ok(result[0] === '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
st.ok(result[1] === '(Contract Creation - Step 63)')
st.end()
}
})
}) })
t.test('TraceManager.getReturnValue', function (st) { t.test('TraceManager.getReturnValue', function (st) {
traceManager.getReturnValue(108, function (error, result) { try {
if (error) { const result = traceManager.getReturnValue(108)
st.fail(error) st.ok(result[0] === '0x60606040526008565b0000000000000000000000000000000000000000000000')
} else { st.end()
st.ok(result[0] === '0x60606040526008565b0000000000000000000000000000000000000000000000') } catch (error) {
st.end() st.fail(error)
} }
})
}) })
}) })

Loading…
Cancel
Save