From 974575b695108dd70f4b165f6789f71c3647c2b1 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 14 May 2018 20:01:18 +0200 Subject: Make sol-cov work with truffle and other artifact adapters --- packages/sol-cov/src/trace.ts | 100 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 packages/sol-cov/src/trace.ts (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts new file mode 100644 index 000000000..6bc28989d --- /dev/null +++ b/packages/sol-cov/src/trace.ts @@ -0,0 +1,100 @@ +import { StructLog, TransactionTrace } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import { addHexPrefix, stripHexPrefix } from 'ethereumjs-util'; +import * as fs from 'fs'; +import * as _ from 'lodash'; + +export interface TraceByContractAddress { + [contractAddress: string]: StructLog[]; +} +function padZeros(address: string) { + return addHexPrefix(_.padStart(stripHexPrefix(address), 40, '0')); +} + +export function getTracesByContractAddress(structLogs: StructLog[], startAddress: string): TraceByContractAddress { + const traceByContractAddress: TraceByContractAddress = {}; + let currentTraceSegment = []; + const callStack = [startAddress]; + // tslint:disable-next-line: prefer-for-of + for (let i = 0; i < structLogs.length; ++i) { + const structLog = structLogs[i]; + if (structLog.depth !== callStack.length - 1) { + throw new Error("Malformed trace. trace depth doesn't match call stack depth"); + } + // After that check we have a guarantee that call stack is never empty + // If it would: callStack.length - 1 === structLog.depth === -1 + // That means that we can always safely pop from it + currentTraceSegment.push(structLog); + + if (structLog.op === 'DELEGATECALL') { + const currentAddress = _.last(callStack) as string; + const jumpAddressOffset = 4; + const newAddress = padZeros(new BigNumber(addHexPrefix(structLog.stack[jumpAddressOffset])).toString(16)); + callStack.push(newAddress); + traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( + currentTraceSegment, + ); + currentTraceSegment = []; + } else if (structLog.op === 'RETURN') { + const currentAddress = callStack.pop() as string; + traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( + currentTraceSegment, + ); + currentTraceSegment = []; + } else if (structLog.op === 'STOP') { + const currentAddress = callStack.pop() as string; + traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( + currentTraceSegment, + ); + currentTraceSegment = []; + if (i !== structLogs.length - 1) { + throw new Error('Malformed trace. STOP is not the last opcode executed'); + } + } else if (structLog.op === 'CREATE') { + console.warn( + "Detected a contract created from within another contract. Sol-cov currently doesn't support that scenario. We'll just skip that trace", + ); + return traceByContractAddress; + } else if (structLog.op === 'CALL') { + const currentAddress = _.last(callStack) as string; + const jumpAddressOffset = 2; + const newAddress = padZeros(new BigNumber(addHexPrefix(structLog.stack[jumpAddressOffset])).toString(16)); + callStack.push(newAddress); + traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( + currentTraceSegment, + ); + currentTraceSegment = []; + } else if (structLog.op === 'CALLCODE') { + throw new Error('CALLCODE opcode unsupported by coverage'); + } else if (structLog.op === 'STATICCALL') { + throw new Error('STATICCALL opcode unsupported by coverage'); + } else if (structLog.op === 'REVERT') { + const currentAddress = callStack.pop() as string; + traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( + currentTraceSegment, + ); + currentTraceSegment = []; + if (i !== structLogs.length - 1) { + throw new Error('Malformed trace. REVERT is not the last opcode executed'); + } + } else if (structLog.op === 'INVALID') { + const currentAddress = callStack.pop() as string; + traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( + currentTraceSegment, + ); + currentTraceSegment = []; + if (i !== structLogs.length - 1) { + throw new Error('Malformed trace. INVALID is not the last opcode executed'); + } + } else if (structLog.op === 'SELFDESTRUCT') { + throw new Error('SELFDESTRUCT opcode unsupported by coverage'); + } + } + if (callStack.length !== 0) { + throw new Error('Malformed trace. Call stack non empty at the end'); + } + if (currentTraceSegment.length !== 0) { + throw new Error('Malformed trace. currentTraceSegment non empty at the end'); + } + return traceByContractAddress; +} -- cgit v1.2.3 From 427a29145d90070e8c67753e7f76c7b88322eefb Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 15 May 2018 11:13:01 +0200 Subject: Support all opcodes in a trace parser --- packages/sol-cov/src/trace.ts | 72 +++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 48 deletions(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index 6bc28989d..febb1034e 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -1,5 +1,5 @@ -import { StructLog, TransactionTrace } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; +import { OpCode, StructLog, TransactionTrace } from '@0xproject/types'; +import { BigNumber, logUtils } from '@0xproject/utils'; import { addHexPrefix, stripHexPrefix } from 'ethereumjs-util'; import * as fs from 'fs'; import * as _ from 'lodash'; @@ -26,68 +26,44 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress // That means that we can always safely pop from it currentTraceSegment.push(structLog); - if (structLog.op === 'DELEGATECALL') { + if ( + structLog.op === OpCode.CallCode || + structLog.op === OpCode.StaticCall || + structLog.op === OpCode.Call || + structLog.op === OpCode.DelegateCall + ) { const currentAddress = _.last(callStack) as string; - const jumpAddressOffset = 4; + const jumpAddressOffset = structLog.op === OpCode.DelegateCall ? 4 : 2; const newAddress = padZeros(new BigNumber(addHexPrefix(structLog.stack[jumpAddressOffset])).toString(16)); callStack.push(newAddress); traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( currentTraceSegment, ); currentTraceSegment = []; - } else if (structLog.op === 'RETURN') { + } else if ( + structLog.op === OpCode.Return || + structLog.op === OpCode.Stop || + structLog.op === OpCode.Revert || + structLog.op === OpCode.Invalid || + structLog.op === OpCode.SelfDestruct + ) { const currentAddress = callStack.pop() as string; traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( currentTraceSegment, ); currentTraceSegment = []; - } else if (structLog.op === 'STOP') { - const currentAddress = callStack.pop() as string; - traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( - currentTraceSegment, - ); - currentTraceSegment = []; - if (i !== structLogs.length - 1) { - throw new Error('Malformed trace. STOP is not the last opcode executed'); + if (structLog.op === OpCode.SelfDestruct) { + // TODO: Record contract bytecode before the selfdestruct and handle that scenario + logUtils.warn( + "Detected a selfdestruct. Sol-cov currently doesn't support that scenario. We'll just skip the trace part for a destructed contract", + ); } - } else if (structLog.op === 'CREATE') { - console.warn( + } else if (structLog.op === OpCode.Create) { + // TODO: Extract the new contract address from the stack and handle that scenario + logUtils.warn( "Detected a contract created from within another contract. Sol-cov currently doesn't support that scenario. We'll just skip that trace", ); return traceByContractAddress; - } else if (structLog.op === 'CALL') { - const currentAddress = _.last(callStack) as string; - const jumpAddressOffset = 2; - const newAddress = padZeros(new BigNumber(addHexPrefix(structLog.stack[jumpAddressOffset])).toString(16)); - callStack.push(newAddress); - traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( - currentTraceSegment, - ); - currentTraceSegment = []; - } else if (structLog.op === 'CALLCODE') { - throw new Error('CALLCODE opcode unsupported by coverage'); - } else if (structLog.op === 'STATICCALL') { - throw new Error('STATICCALL opcode unsupported by coverage'); - } else if (structLog.op === 'REVERT') { - const currentAddress = callStack.pop() as string; - traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( - currentTraceSegment, - ); - currentTraceSegment = []; - if (i !== structLogs.length - 1) { - throw new Error('Malformed trace. REVERT is not the last opcode executed'); - } - } else if (structLog.op === 'INVALID') { - const currentAddress = callStack.pop() as string; - traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( - currentTraceSegment, - ); - currentTraceSegment = []; - if (i !== structLogs.length - 1) { - throw new Error('Malformed trace. INVALID is not the last opcode executed'); - } - } else if (structLog.op === 'SELFDESTRUCT') { - throw new Error('SELFDESTRUCT opcode unsupported by coverage'); } } if (callStack.length !== 0) { -- cgit v1.2.3 From 1ff34bd0f4084d2f9dfd6f07447bb63684ac51ac Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 15 May 2018 15:14:36 +0200 Subject: Remove web3Factory.create and remove dev-tools dependency on sol-cov --- packages/sol-cov/src/trace.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index febb1034e..30508898b 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -7,7 +7,7 @@ import * as _ from 'lodash'; export interface TraceByContractAddress { [contractAddress: string]: StructLog[]; } -function padZeros(address: string) { +function padZeros(address: string): string { return addHexPrefix(_.padStart(stripHexPrefix(address), 40, '0')); } -- cgit v1.2.3 From 83c37c6a7a320326975c8afd9d49a42c9afcefd4 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 22 May 2018 11:05:24 -0700 Subject: Address feedback --- packages/sol-cov/src/trace.ts | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index 30508898b..81c8bb0ff 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -1,5 +1,5 @@ import { OpCode, StructLog, TransactionTrace } from '@0xproject/types'; -import { BigNumber, logUtils } from '@0xproject/utils'; +import { addressUtils, BigNumber, logUtils } from '@0xproject/utils'; import { addHexPrefix, stripHexPrefix } from 'ethereumjs-util'; import * as fs from 'fs'; import * as _ from 'lodash'; @@ -7,17 +7,13 @@ import * as _ from 'lodash'; export interface TraceByContractAddress { [contractAddress: string]: StructLog[]; } -function padZeros(address: string): string { - return addHexPrefix(_.padStart(stripHexPrefix(address), 40, '0')); -} export function getTracesByContractAddress(structLogs: StructLog[], startAddress: string): TraceByContractAddress { const traceByContractAddress: TraceByContractAddress = {}; let currentTraceSegment = []; const callStack = [startAddress]; - // tslint:disable-next-line: prefer-for-of - for (let i = 0; i < structLogs.length; ++i) { - const structLog = structLogs[i]; + // tslint:disable-next-line:prefer-for-of + for (const structLog of structLogs) { if (structLog.depth !== callStack.length - 1) { throw new Error("Malformed trace. trace depth doesn't match call stack depth"); } @@ -26,26 +22,19 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress // That means that we can always safely pop from it currentTraceSegment.push(structLog); - if ( - structLog.op === OpCode.CallCode || - structLog.op === OpCode.StaticCall || - structLog.op === OpCode.Call || - structLog.op === OpCode.DelegateCall - ) { + if (_.includes([OpCode.CallCode, OpCode.StaticCall, OpCode.Call, OpCode.DelegateCall], structLog.op)) { const currentAddress = _.last(callStack) as string; const jumpAddressOffset = structLog.op === OpCode.DelegateCall ? 4 : 2; - const newAddress = padZeros(new BigNumber(addHexPrefix(structLog.stack[jumpAddressOffset])).toString(16)); + const newAddress = addressUtils.padZeros( + new BigNumber(addHexPrefix(structLog.stack[jumpAddressOffset])).toString(16), + ); callStack.push(newAddress); traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( currentTraceSegment, ); currentTraceSegment = []; } else if ( - structLog.op === OpCode.Return || - structLog.op === OpCode.Stop || - structLog.op === OpCode.Revert || - structLog.op === OpCode.Invalid || - structLog.op === OpCode.SelfDestruct + _.includes([OpCode.Return, OpCode.Stop, OpCode.Revert, OpCode.Invalid, OpCode.SelfDestruct], structLog.op) ) { const currentAddress = callStack.pop() as string; traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( -- cgit v1.2.3 From 06be580d2cbe7e3543d8c4deeb4d1c22b325e6a7 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 22 May 2018 13:21:44 -0700 Subject: Fix a bug in CALL-like opcode handling --- packages/sol-cov/src/trace.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index 81c8bb0ff..feebaaab5 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -13,7 +13,8 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress let currentTraceSegment = []; const callStack = [startAddress]; // tslint:disable-next-line:prefer-for-of - for (const structLog of structLogs) { + for (let i = 0; i < structLogs.length; i++) { + const structLog = structLogs[i]; if (structLog.depth !== callStack.length - 1) { throw new Error("Malformed trace. trace depth doesn't match call stack depth"); } @@ -26,13 +27,22 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress const currentAddress = _.last(callStack) as string; const jumpAddressOffset = structLog.op === OpCode.DelegateCall ? 4 : 2; const newAddress = addressUtils.padZeros( - new BigNumber(addHexPrefix(structLog.stack[jumpAddressOffset])).toString(16), + new BigNumber(addHexPrefix(structLog.stack[structLog.stack.length - jumpAddressOffset])).toString(16), ); - callStack.push(newAddress); - traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( - currentTraceSegment, - ); - currentTraceSegment = []; + if (structLog === _.last(structLogs)) { + throw new Error('CALL-like opcode can not be the last one'); + } + // Sometimes calls don't change the execution context (current address). When we do a transfer to an + // externally owned account - it does the call and immidiately returns because there is no fallback + // function. We manually check if the call depth had changed to handle that case. + const nextStructLog = structLogs[i + 1]; + if (nextStructLog.depth !== structLog.depth) { + callStack.push(newAddress); + traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( + currentTraceSegment, + ); + currentTraceSegment = []; + } } else if ( _.includes([OpCode.Return, OpCode.Stop, OpCode.Revert, OpCode.Invalid, OpCode.SelfDestruct], structLog.op) ) { -- cgit v1.2.3 From 9740199870d83dc999079883754ec512c1ff544b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 22 May 2018 13:44:48 -0700 Subject: Fix sol-cov tests --- packages/sol-cov/src/trace.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index feebaaab5..389bd8309 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -27,7 +27,9 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress const currentAddress = _.last(callStack) as string; const jumpAddressOffset = structLog.op === OpCode.DelegateCall ? 4 : 2; const newAddress = addressUtils.padZeros( - new BigNumber(addHexPrefix(structLog.stack[structLog.stack.length - jumpAddressOffset])).toString(16), + new BigNumber(addHexPrefix(structLog.stack[structLog.stack.length - jumpAddressOffset - 1])).toString( + 16, + ), ); if (structLog === _.last(structLogs)) { throw new Error('CALL-like opcode can not be the last one'); -- cgit v1.2.3 From 6e0aef5f2bd8cd3ca9086abf4794028feac5ae9b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 22 May 2018 15:14:07 -0700 Subject: Fix depth tracking in a tracer --- packages/sol-cov/src/trace.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index 389bd8309..28fc7d004 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -25,7 +25,7 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress if (_.includes([OpCode.CallCode, OpCode.StaticCall, OpCode.Call, OpCode.DelegateCall], structLog.op)) { const currentAddress = _.last(callStack) as string; - const jumpAddressOffset = structLog.op === OpCode.DelegateCall ? 4 : 2; + const jumpAddressOffset = 1; const newAddress = addressUtils.padZeros( new BigNumber(addHexPrefix(structLog.stack[structLog.stack.length - jumpAddressOffset - 1])).toString( 16, @@ -65,6 +65,21 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress "Detected a contract created from within another contract. Sol-cov currently doesn't support that scenario. We'll just skip that trace", ); return traceByContractAddress; + } else { + if (structLog !== _.last(structLogs)) { + const nextStructLog = structLogs[i + 1]; + if (nextStructLog.depth === structLog.depth) { + continue; + } else if (nextStructLog.depth === structLog.depth - 1) { + const currentAddress = callStack.pop() as string; + traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( + currentTraceSegment, + ); + currentTraceSegment = []; + } else { + throw new Error('Shit broke'); + } + } } } if (callStack.length !== 0) { -- cgit v1.2.3 From 8c7f0902c044b671ca66c004d9c29e018bcdb20e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 22 May 2018 16:29:10 -0700 Subject: Add a more verbose comment for self-destruct --- packages/sol-cov/src/trace.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index 28fc7d004..4d106e355 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -54,7 +54,11 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress ); currentTraceSegment = []; if (structLog.op === OpCode.SelfDestruct) { - // TODO: Record contract bytecode before the selfdestruct and handle that scenario + // After contract execution, we look at all sub-calls to external contracts, and for each one, fetch + // the bytecode and compute the coverage for the call. If the contract is destroyed with a call + // to `selfdestruct`, we are unable to fetch it's bytecode and compute coverage. + // TODO: Refactor this logic to fetch the sub-called contract bytecode before the selfdestruct is called + // in order to handle this edge-case. logUtils.warn( "Detected a selfdestruct. Sol-cov currently doesn't support that scenario. We'll just skip the trace part for a destructed contract", ); -- cgit v1.2.3 From ebc750d5bf95da76424da81550a88e6b74de8c36 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 22 May 2018 17:41:48 -0700 Subject: Address feedback --- packages/sol-cov/src/trace.ts | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index 4d106e355..cb5410909 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -8,6 +8,10 @@ export interface TraceByContractAddress { [contractAddress: string]: StructLog[]; } +function getAddressFromStackEntry(stackEntry: string): string { + return addressUtils.padZeros(new BigNumber(addHexPrefix(stackEntry)).toString(16)); +} + export function getTracesByContractAddress(structLogs: StructLog[], startAddress: string): TraceByContractAddress { const traceByContractAddress: TraceByContractAddress = {}; let currentTraceSegment = []; @@ -16,26 +20,32 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress for (let i = 0; i < structLogs.length; i++) { const structLog = structLogs[i]; if (structLog.depth !== callStack.length - 1) { - throw new Error("Malformed trace. trace depth doesn't match call stack depth"); + throw new Error("Malformed trace. Trace depth doesn't match call stack depth"); } // After that check we have a guarantee that call stack is never empty // If it would: callStack.length - 1 === structLog.depth === -1 // That means that we can always safely pop from it currentTraceSegment.push(structLog); - if (_.includes([OpCode.CallCode, OpCode.StaticCall, OpCode.Call, OpCode.DelegateCall], structLog.op)) { + const isCallLike = _.includes( + [OpCode.CallCode, OpCode.StaticCall, OpCode.Call, OpCode.DelegateCall], + structLog.op, + ); + const isEndOpcode = _.includes( + [OpCode.Return, OpCode.Stop, OpCode.Revert, OpCode.Invalid, OpCode.SelfDestruct], + structLog.op, + ); + if (isCallLike) { const currentAddress = _.last(callStack) as string; const jumpAddressOffset = 1; - const newAddress = addressUtils.padZeros( - new BigNumber(addHexPrefix(structLog.stack[structLog.stack.length - jumpAddressOffset - 1])).toString( - 16, - ), + const newAddress = getAddressFromStackEntry( + structLog.stack[structLog.stack.length - jumpAddressOffset - 1], ); if (structLog === _.last(structLogs)) { - throw new Error('CALL-like opcode can not be the last one'); + throw new Error('Malformed trace. CALL-like opcode can not be the last one'); } // Sometimes calls don't change the execution context (current address). When we do a transfer to an - // externally owned account - it does the call and immidiately returns because there is no fallback + // externally owned account - it does the call and immediately returns because there is no fallback // function. We manually check if the call depth had changed to handle that case. const nextStructLog = structLogs[i + 1]; if (nextStructLog.depth !== structLog.depth) { @@ -45,9 +55,7 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress ); currentTraceSegment = []; } - } else if ( - _.includes([OpCode.Return, OpCode.Stop, OpCode.Revert, OpCode.Invalid, OpCode.SelfDestruct], structLog.op) - ) { + } else if (isEndOpcode) { const currentAddress = callStack.pop() as string; traceByContractAddress[currentAddress] = (traceByContractAddress[currentAddress] || []).concat( currentTraceSegment, @@ -81,7 +89,7 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress ); currentTraceSegment = []; } else { - throw new Error('Shit broke'); + throw new Error('Malformed trace. Unexpected call depth change'); } } } @@ -90,7 +98,7 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress throw new Error('Malformed trace. Call stack non empty at the end'); } if (currentTraceSegment.length !== 0) { - throw new Error('Malformed trace. currentTraceSegment non empty at the end'); + throw new Error('Malformed trace. Current trace segment non empty at the end'); } return traceByContractAddress; } -- cgit v1.2.3 From c9aef166495c0a1b1c34db01226602375c0b3547 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 23 May 2018 10:39:56 -0700 Subject: Fix linter issues --- packages/sol-cov/src/trace.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/sol-cov/src/trace.ts') diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-cov/src/trace.ts index cb5410909..6caea1610 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-cov/src/trace.ts @@ -9,7 +9,8 @@ export interface TraceByContractAddress { } function getAddressFromStackEntry(stackEntry: string): string { - return addressUtils.padZeros(new BigNumber(addHexPrefix(stackEntry)).toString(16)); + const hexBase = 16; + return addressUtils.padZeros(new BigNumber(addHexPrefix(stackEntry)).toString(hexBase)); } export function getTracesByContractAddress(structLogs: StructLog[], startAddress: string): TraceByContractAddress { -- cgit v1.2.3