Skip to content

Commit 376b11c

Browse files
committed
improved CFG and added legend
1 parent c1891a7 commit 376b11c

File tree

8 files changed

+42
-5
lines changed

8 files changed

+42
-5
lines changed

src/api/bytecode/EVMDisassembler.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ export class EVMDisassembler implements Disassembler {
112112
}
113113

114114
static removeMetadata(bytecode: string): string {
115-
const splittedBytecode: string[] = bytecode.split(EVMDisassembler.metadataPrefix)
115+
let splittedBytecode: string[] = bytecode.split(EVMDisassembler.metadataPrefix)
116+
if (splittedBytecode.length < 2) {
117+
splittedBytecode = bytecode.split(EVMDisassembler.metadataPrefix.toUpperCase())
118+
}
116119
if (splittedBytecode.length < 2) {
117120
return bytecode
118121
}

src/api/bytecode/Opcodes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export class Opcodes {
153153
}
154154

155155
static isJump(op: Opcode) {
156-
return op.name.startsWith('JUMP')
156+
return op.name.startsWith('JUMP') && op.name !== 'JUMPDEST'
157157
}
158158

159159
static isJumpOp(op: string) {

src/api/cfg/CFGBlocks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class CFGBlocks {
2222
}
2323

2424
keys(): number[] {
25-
return Object.keys(this.blocks).map(e => parseInt(e))
25+
return Object.keys(this.blocks).map(e => parseFloat(e))
2626
}
2727

2828
values(): OperationBlock[][] {

src/api/cfg/GraphVizService.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,22 @@ export class GraphVizService {
1111
graph [splines=ortho ranksep="2" nodesep="2"]
1212
rankdir=LR
1313
node [shape=plain fillcolor="#2A2A2A" style=filled fontname="Courier"]
14+
${this.createLegend()}
1415
${this.buildBody(blocks, trace)}
1516
}`
1617
}
1718

19+
private createLegend() {
20+
return `
21+
subgraph cluster_legend {
22+
label="Legend";
23+
legend1 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"><TR><TD COLSPAN="3"><font color="#ffffff">Not run in transaction</font></TD></TR><TR><TD><font color="#12cc12">0x3f</font></TD><TD ID="3f" HREF=" "><font color="#12cc12">JUMPDEST</font></TD></TR></TABLE> >]
24+
legend2 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"><TR><TD COLSPAN="3"><font color="#ffffff">Run in transaction</font></TD></TR><TR><TD><font color="#ff1020">0x0</font></TD><TD><font color="#ff1020">PUSH1</font></TD><TD><font color="#ff1020">0x80</font></TD></TR></TABLE> >]
25+
legend3 [label=< <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"><TR><TD COLSPAN="3"><font color="#ffffff">Run in transaction</font></TD></TR><TR><TD COLSPAN="3"><font color="#ffffff">Belongs to a loop</font></TD></TR><TR><TD><font color="#CD950C">0x3f</font></TD><TD ID="3f" HREF=" "><font color="#CD950C">JUMPDEST</font></TD></TR></TABLE> >]
26+
}
27+
`
28+
}
29+
1830
private buildBody(blocks: CFGBlocks, trace: DebugTrace): string {
1931
let body: string = ''
2032
blocks.keys().forEach(key => {

src/api/cfg/OperationBlock.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ export interface OperationBlock {
44
offset: number
55
operations: Operation[]
66
childA?: number
7-
childB?: number
7+
childB?: number,
8+
repeated?: number
89
}

src/api/service/controller/DebuggerController.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export class DebuggerController extends Controller {
5858
blocks = contractBlocks.contractConstructor.blocks
5959
}
6060
this.cfgService.completeCFGWithTrace(blocks, trace)
61+
this.cfgService.checkTraceLoops(blocks, trace)
6162
return this.graphVizService.createDotFromBlocks(blocks, trace)
6263
}
6364

src/api/service/service/CFGService.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,26 @@ export class CFGService {
4848
}
4949
}
5050

51+
checkTraceLoops(blocks: CFGBlocks, trace: DebugTrace) {
52+
const logs = trace.result.structLogs
53+
const count = this.count(logs.map(l => l.pc))
54+
const repeated: any = Object.keys(count).filter(key => count[key] > 1).map( key=> { return {offset: key, repeated: count[key]}})
55+
for (const repeatedOffset of repeated) {
56+
console.log(`trying to find block ${repeatedOffset.offset}`)
57+
const block = blocks.get(repeatedOffset.offset)
58+
if (block) {
59+
console.log('block found')
60+
block.repeated = repeatedOffset.repeated
61+
}
62+
}
63+
}
64+
65+
private count(logs): any[] {
66+
return logs.reduce((a, b) => ({ ...a,
67+
[b]: (a[b] || 0) + 1
68+
}), {})
69+
}
70+
5171
private populateMissingBranch(block: OperationBlock, blocks: CFGBlocks, stack: string[], op: string) {
5272
if (op === 'JUMP') {
5373
const dest = stack[stack.length-1]

src/api/service/service/TransactionServiceImpl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class TransactionServiceImpl implements TransactionService {
9090
if (cleanDeployedBytecode.length % 2 !== 0) {
9191
cleanDeployedBytecode = cleanDeployedBytecode.substr(0, cleanDeployedBytecode.length-1)
9292
}
93-
if (cleanBytecode === cleanDeployedBytecode) {
93+
if (cleanBytecode.toUpperCase() === cleanDeployedBytecode.toUpperCase() || (!cleanDeployedBytecode || cleanDeployedBytecode === '0x')) {
9494
return this.buildTrace(trace, trace.result.structLogs.filter(log => log.depth === 0))
9595
}
9696
const allCalls = trace.result.structLogs.filter(log => this.isCall(log.op))

0 commit comments

Comments
 (0)