nimbus-eth1/hive_integration/nodocker/consensus/extract_consensus_data.nim

259 lines
6.5 KiB
Nim

# Nimbus
# Copyright (c) 2021 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.
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
muirGlacierBlock = 2000
berlinBlock = 2000
londonBlock = 2000
arrowGlacierBlock = 2000
case network
# All the network forks, which includes all the EVM, DAO and Glacier forks.
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
muirGlacierBlock = 0
berlinBlock = 0
of "London":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
petersburgBlock = 0
istanbulBlock = 0
muirGlacierBlock = 0
berlinBlock = 0
londonBlock = 0
of "ArrowGlacier":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
petersburgBlock = 0
istanbulBlock = 0
muirGlacierBlock = 0
berlinBlock = 0
londonBlock = 0
arrowGlacierBlock = 0
# Just the subset of "At5" networks mentioned in the test suite.
of "FrontierToHomesteadAt5":
homesteadBlock = 5
of "HomesteadToDaoAt5":
homesteadBlock = 0
daoForkSupport = true
daoForkBlock = 5
of "HomesteadToEIP150At5":
homesteadBlock = 0
eip150Block = 5
of "EIP158ToByzantiumAt5":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 5
of "ByzantiumToConstantinopleFixAt5":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 5
petersburgBlock = 5
of "BerlinToLondonAt5":
homesteadBlock = 0
eip150Block = 0
eip158Block = 0
byzantiumBlock = 0
constantinopleBlock = 0
petersburgBlock = 0
istanbulBlock = 0
muirGlacierBlock = 0
berlinBlock = 0
londonBlock = 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["muirGlacierBlock"] = newJInt(muirGlacierBlock)
n["berlinBlock"] = newJInt(berlinBlock)
n["londonBlock"] = newJInt(londonBlock)
n["arrowGlacierBlock"] = newJInt(arrowGlacierBlock)
n["chainId"] = newJInt(1)
result = n
proc optionalField(n: string, genesis, gen: JsonNode) =
if n in gen:
genesis[n] = gen[n]
proc extractChainData(n: JsonNode, chainFile: string): ChainData =
let gen = n["genesisBlockHeader"]
var genesis = newJObject()
for x in genFields:
genesis[x] = gen[x]
optionalField("baseFeePerGas", genesis, gen)
genesis["alloc"] = n["pre"]
var ngen = newJObject()
ngen["genesis"] = genesis
ngen["config"] = processNetwork(n["network"].getStr)
ngen["lastblockhash"] = n["lastblockhash"]
ngen["chainfile"] = %chainFile
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)
let (folder, name) = fileName.splitPath()
let last = folder.splitPath().tail
for name, unit in n:
let name = last & "_" & name
let cd = extractChainData(unit, outPath / name & "_chain.rlp")
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()