-
Notifications
You must be signed in to change notification settings - Fork 115
/
test_witness_json.nim
190 lines (161 loc) · 4.95 KB
/
test_witness_json.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# Nimbus
# Copyright (c) 2020-2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# https://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# https://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
import
eth/common, json, os, unittest2,
../nimbus/db/core_db,
./tree_from_witness, parseopt,
./witness_types, stew/byteutils
type
Tester = object
rootHash: KeccakHash
error: bool
output: seq[byte]
proc write(t: var Tester, x: openArray[byte]) =
t.output.add x
proc write(t: var Tester, x: string) =
let len = (x.len - 2) div 2
var buf: array[4096, byte]
hexToByteArray(x, buf, 0, len - 1)
t.write(buf.toOpenArray(0, len - 1))
proc write(t: var Tester, x: JsonNode) =
t.write(x.getStr())
proc processBranchNode(t: var Tester, x: JsonNode) =
t.write(x["mask"])
proc processExtensionNode(t: var Tester, x: JsonNode) =
t.write(x["nibblesLen"])
t.write(x["nibbles"])
proc processNode(t: var Tester, x: JsonNode, storageMode: bool = false)
proc writeSub(t: var Tester, x: JsonNode, name: string): string =
let subName = name & "Sub"
let nodeType = x[name].getStr()
if subName in x:
let subType = x[subName].getStr()
t.write(subType)
else:
t.write(nodeType)
result = nodeType
proc processHashNode(t: var Tester, x: JsonNode) =
discard t.writeSub(x, "nodeType")
t.write(x["data"])
proc processStorage(t: var Tester, tree: JsonNode) =
for x in tree:
t.processNode(x, true)
proc processByteCode(t: var Tester, x: JsonNode) =
let codeType = t.writeSub(x, "codeType")
case codeType
of "0x00":
let codeLen = x["codeLen"].getStr()
t.write(codeLen)
if codeLen != "0x00":
t.write(x["code"])
of "0x01":
t.write(x["codeLen"])
t.processHashNode(x["codeHash"])
else:
raise newException(ParsingError, "wrong bytecode type")
proc processAccountNode(t: var Tester, x: JsonNode) =
let accountType = t.writeSub(x, "accountType")
t.write(x["address"])
t.write(x["balance"])
t.write(x["nonce"])
case accountType:
of "0x00":
discard
of "0x01":
t.processByteCode(x)
t.processStorage(x["storage"])
else:
raise newException(ParsingError, "wrong account type")
proc processStorageLeafNode(t: var Tester, x: JsonNode) =
t.write(x["key"])
t.write(x["value"])
proc processNode(t: var Tester, x: JsonNode, storageMode: bool = false) =
let nodeType = t.writeSub(x, "nodeType")
case nodeType
of "0x00": t.processBranchNode(x)
of "0x01": t.processExtensionNode(x)
of "0x02":
if storageMode:
t.processStorageLeafNode(x)
else:
t.processAccountNode(x)
of "0x03":
t.write(x["data"])
else:
raise newException(ParsingError, "wrong node type")
proc parseRootHash(x: string): KeccakHash =
result.data = hexToByteArray[32](x)
proc parseTester(t: var Tester, n: JsonNode, testStatusIMPL: var TestStatus) =
t.error = n["error"].getBool()
t.rootHash = parseRootHash(n["rootHash"].getStr())
t.write(n["version"])
t.write(n["metadata"])
let tree = n["tree"]
try:
for x in tree:
t.processNode(x)
except ParsingError:
check t.error == true
proc parseTester(filename: string, testStatusIMPL: var TestStatus): Tester =
let n = parseFile(filename)
parseTester(result, n, testStatusIMPL)
proc runTest(filePath, fileName: string) =
test fileName:
let t = parseTester(filePath, testStatusIMPL)
var db = newCoreDbRef(DefaultDbMemory)
try:
var tb = initTreeBuilder(t.output, db, {wfNoFlag})
let root = tb.buildTree()
if t.error:
check root != t.rootHash
else:
check root == t.rootHash
check t.error == false
except ParsingError, ContractCodeError:
# echo "Exception detected ", getCurrentExceptionMsg()
check t.error == true
proc writeFuzzData(filePath, fileName: string) =
var testStatusIMPL: TestStatus
let t = parseTester(filePath, testStatusIMPL)
# this block below check the parsed json
var db = newCoreDbRef(DefaultDbMemory)
var tb = initTreeBuilder(t.output, db, {wfNoFlag})
discard tb.buildTree()
writeFile(fileName, t.output)
proc fuzzTool(): bool {.used.} =
var filename: string
var numArg = 0
for kind, key, val in getopt():
case kind
of cmdArgument:
inc numArg
case numArg
of 1:
if key != "fuzz":
quit(1)
of 2:
filename = key
else:
discard
of cmdLongOption, cmdShortOption:
discard
of cmdEnd: assert(false) # cannot happen
if filename != "":
echo "generate fuzz data"
writeFuzzData(filename, "fuzz.data")
return true
proc witnessJsonMain*() =
suite "test tree builder against json fixtures":
for x in walkDirRec("stateless" / "fixtures"):
let y = splitPath(x)
runTest(x, y.tail)
when isMainModule:
if not fuzzTool():
witnessJsonMain()