nimbus-eth1/hive_integration/extract_consensus_data.nim

213 lines
5.1 KiB
Nim

import
std/[json, os, strutils, parseopt, terminal],
stew/byteutils
type
ChainData = object
genesis: JsonNode
blocksRlp: seq[byte]
Config = object
outPath: string
filter: string
const genFields = [
"nonce",
"timestamp",
"extraData",
"gasLimit",
"difficulty",
"mixHash",
"coinbase"
]
proc processNetWork(network: string): JsonNode =
var
homesteadBlock = 2000
daoForkSupport = false
daoForkBlock = homesteadBlock
eip150Block = 2000
eip158Block = 2000
byzantiumBlock = 2000
constantinopleBlock = 2000
petersburgBlock = 2000
istanbulBlock = 2000
berlinBlock = 2000
case network
of "Frontier":
discard
of "Homestead":
homesteadBlock = 0
of "EIP150":
homesteadBlock = 0
eip150Block = 0
of "EIP158":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
of "Byzantium":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
of "Constantinople":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
of "ConstantinopleFix":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
petersburgBlock = 0
of "Istanbul":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
petersburgBlock = 0
istanbulBlock = 0
of "Berlin":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
petersburgBlock = 0
istanbulBlock = 0
berlinBlock = 0
of "FrontierToHomesteadAt5":
homesteadBlock = 5
of "HomesteadToEIP150At5":
homesteadBlock = 0
eip150Block = 5
of "HomesteadToDaoAt5":
homesteadBlock = 0
daoForkSupport = true
daoForkBlock = 5
of "EIP158ToByzantiumAt5":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 5
of "ByzantiumToConstantinopleAt5":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 5
of "ByzantiumToConstantinopleFixAt5":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 5
petersburgBlock = 5
of "ConstantinopleFixToIstanbulAt5":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
petersburgBlock = 0
istanbulBlock = 5
of "IstanbulToBerlinAt5":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
petersburgBlock = 0
istanbulBlock = 0
berlinBlock = 5
else:
doAssert(false, "unsupported network: " & network)
var n = newJObject()
n["homesteadBlock"] = newJInt(homesteadBlock)
if daoForkSupport:
n["daoForkSupport"] = newJBool(daoForkSupport)
n["daoForkBlock"] = newJInt(daoForkBlock)
n["eip150Block"] = newJInt(eip150Block)
n["eip158Block"] = newJInt(eip158Block)
n["byzantiumBlock"] = newJInt(byzantiumBlock)
n["constantinopleBlock"] = newJInt(constantinopleBlock)
n["petersburgBlock"] = newJInt(petersburgBlock)
n["istanbulBlock"] = newJInt(istanbulBlock)
n["berlinBlock"] = newJInt(berlinBlock)
n["chainId"] = newJInt(1)
result = n
proc extractChainData(n: JsonNode): ChainData =
let gen = n["genesisBlockHeader"]
var ngen = newJObject()
for x in genFields:
ngen[x] = gen[x]
ngen["alloc"] = n["pre"]
ngen["config"] = processNetwork(n["network"].getStr)
result.genesis = ngen
let blks = n["blocks"]
for x in blks:
let hex = x["rlp"].getStr
let bytes = hexToSeqByte(hex)
result.blocksRlp.add bytes
proc processFile(fileName, outPath: string): int =
let n = json.parseFile(fileName)
for name, unit in n:
let cd = extractChainData(unit)
writeFile(outPath / name & "_config.json", cd.genesis.pretty)
writeFile(outPath / name & "_chain.rlp", cd.blocksRlp)
inc result
proc initConfig(): Config =
result.outPath = "consensus_data"
proc processArguments(conf: var Config) =
var opt = initOptParser()
for kind, key, value in opt.getopt():
case kind
of cmdArgument:
conf.filter = key
of cmdLongOption, cmdShortOption:
case key.toLowerAscii()
of "o": conf.outPath = value
else:
var msg = "Unknown option " & key
if value.len > 0: msg = msg & " : " & value
quit(QuitFailure)
of cmdEnd:
doAssert(false)
proc main() =
const basePath = "tests" / "fixtures" / "eth_tests" / "BlockchainTests"
var conf = initConfig()
processArguments(conf)
createDir(conf.outPath)
var count = 0
for fileName in walkDirRec(basePath):
if not fileName.endsWith(".json"):
continue
let (_, name) = fileName.splitPath()
if conf.filter notin fileName:
continue
terminal.eraseLine(stdout)
stdout.write "\r"
stdout.write name
count += processFile(fileName, conf.outPath)
echo "\ntest data generated: ", count
main()