fixes crappy custom genesis and chain config parser
instead of using stdlib/json, now we switch to json_serialization the result is much tidier code and more robust when parsing optional fields. fixes #635
This commit is contained in:
parent
6966324f3b
commit
f2491e6307
|
@ -0,0 +1,195 @@
|
||||||
|
# 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/[tables, strutils, options, times],
|
||||||
|
eth/[common, rlp], stint, stew/[byteutils],
|
||||||
|
nimcrypto/hash,
|
||||||
|
json_serialization, chronicles,
|
||||||
|
json_serialization/std/options as jsoptions,
|
||||||
|
json_serialization/std/tables as jstable,
|
||||||
|
json_serialization/lexer
|
||||||
|
|
||||||
|
type
|
||||||
|
# beware that although in some cases
|
||||||
|
# chainId have identical value to networkId
|
||||||
|
# they are separate entity
|
||||||
|
ChainId* = distinct uint
|
||||||
|
|
||||||
|
ChainOptions = object
|
||||||
|
chainId : ChainId
|
||||||
|
homesteadBlock : Option[BlockNumber]
|
||||||
|
daoForkBlock : Option[BlockNumber]
|
||||||
|
daoForkSupport : bool
|
||||||
|
eip150Block : Option[BlockNumber]
|
||||||
|
eip150Hash : Hash256
|
||||||
|
eip155Block : Option[BlockNumber]
|
||||||
|
eip158Block : Option[BlockNumber]
|
||||||
|
byzantiumBlock : Option[BlockNumber]
|
||||||
|
constantinopleBlock: Option[BlockNumber]
|
||||||
|
petersburgBlock : Option[BlockNumber]
|
||||||
|
istanbulBlock : Option[BlockNumber]
|
||||||
|
muirGlacierBlock : Option[BlockNumber]
|
||||||
|
berlinBlock : Option[BlockNumber]
|
||||||
|
|
||||||
|
ChainConfig* = object
|
||||||
|
chainId* : ChainId
|
||||||
|
homesteadBlock* : BlockNumber
|
||||||
|
daoForkBlock* : BlockNumber
|
||||||
|
daoForkSupport* : bool
|
||||||
|
|
||||||
|
# EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
|
||||||
|
eip150Block* : BlockNumber
|
||||||
|
eip150Hash* : Hash256
|
||||||
|
|
||||||
|
eip155Block* : BlockNumber
|
||||||
|
eip158Block* : BlockNumber
|
||||||
|
|
||||||
|
byzantiumBlock* : BlockNumber
|
||||||
|
constantinopleBlock*: BlockNumber
|
||||||
|
petersburgBlock* : BlockNumber
|
||||||
|
istanbulBlock* : BlockNumber
|
||||||
|
muirGlacierBlock* : BlockNumber
|
||||||
|
berlinBlock* : BlockNumber
|
||||||
|
|
||||||
|
Genesis* = object
|
||||||
|
nonce* : BlockNonce
|
||||||
|
timestamp* : EthTime
|
||||||
|
extraData* : seq[byte]
|
||||||
|
gasLimit* : GasInt
|
||||||
|
difficulty* : DifficultyInt
|
||||||
|
mixHash* : Hash256
|
||||||
|
coinbase* : EthAddress
|
||||||
|
alloc* : GenesisAlloc
|
||||||
|
|
||||||
|
GenesisAlloc* = Table[EthAddress, GenesisAccount]
|
||||||
|
GenesisAccount* = object
|
||||||
|
code* : seq[byte]
|
||||||
|
storage*: Table[UInt256, UInt256]
|
||||||
|
balance*: UInt256
|
||||||
|
nonce* : AccountNonce
|
||||||
|
|
||||||
|
CustomGenesis* = object
|
||||||
|
config* : ChainConfig
|
||||||
|
genesis*: Genesis
|
||||||
|
|
||||||
|
AddressBalance = object
|
||||||
|
address {.rlpCustomSerialization.}: EthAddress
|
||||||
|
account {.rlpCustomSerialization.}: GenesisAccount
|
||||||
|
|
||||||
|
CustomChain = object
|
||||||
|
config : ChainOptions
|
||||||
|
genesis: Genesis
|
||||||
|
|
||||||
|
proc read(rlp: var Rlp, x: var AddressBalance, _: type EthAddress): EthAddress {.inline.} =
|
||||||
|
let val = rlp.read(UInt256).toByteArrayBE()
|
||||||
|
result[0 .. ^1] = val.toOpenArray(12, val.high)
|
||||||
|
|
||||||
|
proc read(rlp: var Rlp, x: var AddressBalance, _: type GenesisAccount): GenesisAccount {.inline.} =
|
||||||
|
GenesisAccount(balance: rlp.read(UInt256))
|
||||||
|
|
||||||
|
func decodePrealloc*(data: seq[byte]): GenesisAlloc =
|
||||||
|
for tup in rlp.decode(data, seq[AddressBalance]):
|
||||||
|
result[tup.address] = tup.account
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var BlockNumber) =
|
||||||
|
let tok = reader.lexer.tok
|
||||||
|
if tok == tkInt:
|
||||||
|
value = toBlockNumber(reader.lexer.absintVal)
|
||||||
|
reader.lexer.next()
|
||||||
|
elif tok == tkString:
|
||||||
|
value = UInt256.fromHex(reader.lexer.strVal)
|
||||||
|
reader.lexer.next()
|
||||||
|
else:
|
||||||
|
reader.raiseUnexpectedValue("expect int or hex string")
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var ChainId) =
|
||||||
|
value = reader.readValue(int).ChainId
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var Hash256) =
|
||||||
|
value = Hash256.fromHex(reader.readValue(string))
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var BlockNonce) =
|
||||||
|
value = fromHex[uint64](reader.readValue(string)).toBlockNonce
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var EthTime) =
|
||||||
|
value = fromHex[int64](reader.readValue(string)).fromUnix
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var seq[byte]) =
|
||||||
|
value = hexToSeqByte(reader.readValue(string))
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var GasInt) =
|
||||||
|
value = fromHex[GasInt](reader.readValue(string))
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var EthAddress) =
|
||||||
|
value = parseAddress(reader.readValue(string))
|
||||||
|
|
||||||
|
proc readValue(reader: var JsonReader, value: var AccountNonce) =
|
||||||
|
value = fromHex[uint64](reader.readValue(string))
|
||||||
|
|
||||||
|
template to(a: string, b: type EthAddress): EthAddress =
|
||||||
|
# json_serialization decode table stuff
|
||||||
|
parseAddress(a)
|
||||||
|
|
||||||
|
template to(a: string, b: type UInt256): UInt256 =
|
||||||
|
# json_serialization decode table stuff
|
||||||
|
UInt256.fromHex(a)
|
||||||
|
|
||||||
|
proc loadCustomGenesis*(fileName: string, cg: var CustomGenesis): bool =
|
||||||
|
var cc: CustomChain
|
||||||
|
try:
|
||||||
|
cc = Json.loadFile(fileName, CustomChain, allowUnknownFields = true)
|
||||||
|
except IOError as e:
|
||||||
|
error "Genesis config file error", fileName, msg=e.msg
|
||||||
|
return false
|
||||||
|
except JsonReaderError as e:
|
||||||
|
error "Invalid genesis config file format", fileName, msg=e.formatMsg("")
|
||||||
|
return false
|
||||||
|
except:
|
||||||
|
var msg = getCurrentExceptionMsg()
|
||||||
|
error "Error loading genesis block config file", fileName, msg
|
||||||
|
return false
|
||||||
|
|
||||||
|
cg.genesis = cc.genesis
|
||||||
|
cg.config.chainId = cc.config.chainId
|
||||||
|
cg.config.daoForkSupport = cc.config.daoForkSupport
|
||||||
|
cg.config.eip150Hash = cc.config.eip150Hash
|
||||||
|
|
||||||
|
template validateFork(forkName: untyped, nextBlock: BlockNumber) =
|
||||||
|
let fork = astToStr(forkName)
|
||||||
|
if cc.config.forkName.isSome:
|
||||||
|
cg.config.forkName = cc.config.forkName.get()
|
||||||
|
else:
|
||||||
|
cg.config.forkName = nextBlock
|
||||||
|
if cg.config.forkName > nextBlock:
|
||||||
|
error "Forks can't be assigned out of order", fork=fork
|
||||||
|
return false
|
||||||
|
|
||||||
|
validateFork(berlinBlock, high(BlockNumber).toBlockNumber)
|
||||||
|
validateFork(muirGlacierBlock, cg.config.berlinBlock)
|
||||||
|
validateFork(istanbulBlock, cg.config.muirGlacierBlock)
|
||||||
|
validateFork(petersburgBlock, cg.config.istanbulBlock)
|
||||||
|
validateFork(constantinopleBlock, cg.config.petersburgBlock)
|
||||||
|
validateFork(byzantiumBlock, cg.config.constantinopleBlock)
|
||||||
|
validateFork(eip158Block, cg.config.byzantiumBlock)
|
||||||
|
validateFork(eip155Block, cg.config.eip158Block)
|
||||||
|
validateFork(eip150Block, cg.config.eip155Block)
|
||||||
|
validateFork(daoForkBlock, cg.config.eip150Block)
|
||||||
|
validateFork(homesteadBlock, cg.config.daoForkBlock)
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
proc parseGenesisAlloc*(data: string, ga: var GenesisAlloc): bool =
|
||||||
|
try:
|
||||||
|
ga = Json.decode(data, GenesisAlloc, allowUnknownFields = true)
|
||||||
|
except JsonReaderError as e:
|
||||||
|
error "Invalid genesis config file format", msg=e.formatMsg("")
|
||||||
|
return false
|
||||||
|
|
||||||
|
return true
|
|
@ -11,8 +11,9 @@ import
|
||||||
parseopt, strutils, macros, os, times, json, tables, stew/[byteutils],
|
parseopt, strutils, macros, os, times, json, tables, stew/[byteutils],
|
||||||
chronos, eth/[keys, common, p2p, net/nat], chronicles, nimcrypto/hash,
|
chronos, eth/[keys, common, p2p, net/nat], chronicles, nimcrypto/hash,
|
||||||
eth/p2p/bootnodes, eth/p2p/rlpx_protocols/whisper_protocol,
|
eth/p2p/bootnodes, eth/p2p/rlpx_protocols/whisper_protocol,
|
||||||
./db/select_backend, eth/keys,
|
./db/select_backend, eth/keys, ./chain_config
|
||||||
./vm_types2
|
|
||||||
|
from ./vm_types2 import Fork
|
||||||
|
|
||||||
const
|
const
|
||||||
NimbusName* = "Nimbus"
|
NimbusName* = "Nimbus"
|
||||||
|
@ -130,31 +131,6 @@ type
|
||||||
keystore*: JsonNode
|
keystore*: JsonNode
|
||||||
unlocked*: bool
|
unlocked*: bool
|
||||||
|
|
||||||
# beware that although in some cases
|
|
||||||
# chainId have identical value to networkId
|
|
||||||
# they are separate entity
|
|
||||||
ChainId* = distinct uint
|
|
||||||
|
|
||||||
ChainConfig* = object
|
|
||||||
chainId*: ChainId
|
|
||||||
homesteadBlock*: BlockNumber
|
|
||||||
daoForkBlock*: BlockNumber
|
|
||||||
daoForkSupport*: bool
|
|
||||||
|
|
||||||
# EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
|
|
||||||
eip150Block*: BlockNumber
|
|
||||||
eip150Hash*: Hash256
|
|
||||||
|
|
||||||
eip155Block*: BlockNumber
|
|
||||||
eip158Block*: BlockNumber
|
|
||||||
|
|
||||||
byzantiumBlock*: BlockNumber
|
|
||||||
constantinopleBlock*: BlockNumber
|
|
||||||
petersburgBlock*: BlockNumber
|
|
||||||
istanbulBlock*: BlockNumber
|
|
||||||
muirGlacierBlock*: BlockNumber
|
|
||||||
berlinBlock*: BlockNumber
|
|
||||||
|
|
||||||
NimbusConfiguration* = ref object
|
NimbusConfiguration* = ref object
|
||||||
## Main Nimbus configuration object
|
## Main Nimbus configuration object
|
||||||
dataDir*: string
|
dataDir*: string
|
||||||
|
@ -165,37 +141,13 @@ type
|
||||||
net*: NetConfiguration ## Network configuration
|
net*: NetConfiguration ## Network configuration
|
||||||
debug*: DebugConfiguration ## Debug configuration
|
debug*: DebugConfiguration ## Debug configuration
|
||||||
shh*: WhisperConfig ## Whisper configuration
|
shh*: WhisperConfig ## Whisper configuration
|
||||||
customGenesis*: CustomGenesisConfig ## Custom Genesis Configuration
|
customGenesis*: CustomGenesis ## Custom Genesis Configuration
|
||||||
# You should only create one instance of the RNG per application / library
|
# You should only create one instance of the RNG per application / library
|
||||||
# Ref is used so that it can be shared between components
|
# Ref is used so that it can be shared between components
|
||||||
rng*: ref BrHmacDrbgContext
|
rng*: ref BrHmacDrbgContext
|
||||||
accounts*: Table[EthAddress, NimbusAccount]
|
accounts*: Table[EthAddress, NimbusAccount]
|
||||||
importFile*: string
|
importFile*: string
|
||||||
|
|
||||||
CustomGenesisConfig* = object
|
|
||||||
chainId*: ChainId
|
|
||||||
homesteadBlock*: BlockNumber
|
|
||||||
daoForkBlock*: BlockNumber
|
|
||||||
daoForkSupport*: bool
|
|
||||||
eip150Block*: BlockNumber
|
|
||||||
eip150Hash*: Hash256
|
|
||||||
eip155Block*: BlockNumber
|
|
||||||
eip158Block*: BlockNumber
|
|
||||||
byzantiumBlock*: BlockNumber
|
|
||||||
constantinopleBlock*: BlockNumber
|
|
||||||
petersburgBlock*: BlockNumber
|
|
||||||
istanbulBlock*: BlockNumber
|
|
||||||
muirGlacierBlock*: BlockNumber
|
|
||||||
berlinBlock*: BlockNumber
|
|
||||||
nonce*: BlockNonce
|
|
||||||
extraData*: seq[byte]
|
|
||||||
gasLimit*: int64
|
|
||||||
difficulty*: UInt256
|
|
||||||
prealloc*: JsonNode
|
|
||||||
mixHash*: Hash256
|
|
||||||
coinBase*: EthAddress
|
|
||||||
timestamp*: EthTime
|
|
||||||
|
|
||||||
const
|
const
|
||||||
defaultRpcApi = {RpcFlags.Eth, RpcFlags.Shh}
|
defaultRpcApi = {RpcFlags.Eth, RpcFlags.Shh}
|
||||||
defaultProtocols = {ProtocolFlags.Eth, ProtocolFlags.Shh}
|
defaultProtocols = {ProtocolFlags.Eth, ProtocolFlags.Shh}
|
||||||
|
@ -220,26 +172,6 @@ proc toFork*(c: ChainConfig, number: BlockNumber): Fork =
|
||||||
elif number >= c.homesteadBlock: FkHomestead
|
elif number >= c.homesteadBlock: FkHomestead
|
||||||
else: FkFrontier
|
else: FkFrontier
|
||||||
|
|
||||||
proc privateChainConfig*(): ChainConfig =
|
|
||||||
let config = getConfiguration()
|
|
||||||
result = ChainConfig(
|
|
||||||
chainId: config.customGenesis.chainId,
|
|
||||||
homesteadBlock: config.customGenesis.homesteadBlock,
|
|
||||||
daoForkSupport: config.customGenesis.daoForkSupport,
|
|
||||||
daoForkBlock: config.customGenesis.daoForkBlock,
|
|
||||||
eip150Block: config.customGenesis.eip150Block,
|
|
||||||
eip150Hash: config.customGenesis.eip150Hash,
|
|
||||||
eip155Block: config.customGenesis.eip155Block,
|
|
||||||
eip158Block: config.customGenesis.eip158Block,
|
|
||||||
byzantiumBlock: config.customGenesis.byzantiumBlock,
|
|
||||||
constantinopleBlock: config.customGenesis.constantinopleBlock,
|
|
||||||
petersburgBlock: config.customGenesis.petersburgBlock,
|
|
||||||
istanbulBlock: config.customGenesis.istanbulBlock,
|
|
||||||
muirGlacierBlock: config.customGenesis.muirGlacierBlock,
|
|
||||||
berlinBlock: config.customGenesis.berlinBlock
|
|
||||||
)
|
|
||||||
trace "Custom genesis block configuration loaded", configuration=result
|
|
||||||
|
|
||||||
proc publicChainConfig*(id: PublicNetwork): ChainConfig =
|
proc publicChainConfig*(id: PublicNetwork): ChainConfig =
|
||||||
# For some public networks, NetworkId and ChainId value are identical
|
# For some public networks, NetworkId and ChainId value are identical
|
||||||
# but that is not always the case
|
# but that is not always the case
|
||||||
|
@ -311,155 +243,14 @@ proc publicChainConfig*(id: PublicNetwork): ChainConfig =
|
||||||
berlinBlock: 4_460_644.toBlockNumber
|
berlinBlock: 4_460_644.toBlockNumber
|
||||||
)
|
)
|
||||||
of CustomNet:
|
of CustomNet:
|
||||||
privateChainConfig()
|
let conf = getConfiguration()
|
||||||
|
trace "Custom genesis block configuration loaded", conf=conf.customGenesis.config
|
||||||
|
conf.customGenesis.config
|
||||||
else:
|
else:
|
||||||
error "No chain config for public network", networkId = id
|
error "No chain config for public network", networkId = id
|
||||||
doAssert(false, "No chain config for " & $id)
|
doAssert(false, "No chain config for " & $id)
|
||||||
ChainConfig()
|
ChainConfig()
|
||||||
|
|
||||||
proc processCustomGenesisConfig(customGenesis: JsonNode): ConfigStatus =
|
|
||||||
## Parses Custom Genesis Block config options when customnetwork option provided
|
|
||||||
|
|
||||||
template checkForFork(chain, currentFork, previousFork: untyped, optional = false) =
|
|
||||||
# Template to load fork blocks and validate order
|
|
||||||
let currentForkName = currentFork.astToStr()
|
|
||||||
if chain.hasKey(currentForkName) and not optional:
|
|
||||||
if chain[currentForkName].kind == JInt:
|
|
||||||
currentFork = chain[currentForkName].getInt().toBlockNumber
|
|
||||||
if currentFork < previousFork:
|
|
||||||
error "Forks can't be assigned out of order"
|
|
||||||
quit(1)
|
|
||||||
else:
|
|
||||||
error "Invalid block value provided for", currentForkName, invalidValue=currentFork
|
|
||||||
quit(1)
|
|
||||||
|
|
||||||
proc parseConfig(T: type, c: JsonNode, field: string): T =
|
|
||||||
when T is string:
|
|
||||||
c[field].getStr()
|
|
||||||
elif T is Uint256:
|
|
||||||
hexToUint[256](c[field].getStr())
|
|
||||||
elif T is bool:
|
|
||||||
c[field].getBool()
|
|
||||||
elif T is Hash256:
|
|
||||||
MDigest[256].fromHex(c[field].getStr())
|
|
||||||
elif T is uint:
|
|
||||||
c[field].getInt().uint
|
|
||||||
elif T is Blocknonce:
|
|
||||||
(parseHexInt(c[field].getStr()).uint64).toBlockNonce
|
|
||||||
elif T is EthTime:
|
|
||||||
fromHex[int64](c[field].getStr()).fromUnix
|
|
||||||
elif T is EthAddress:
|
|
||||||
parseAddress(c[field].getStr())
|
|
||||||
elif T is seq[byte]:
|
|
||||||
hexToSeqByte(c[field].getStr())
|
|
||||||
elif T is int64:
|
|
||||||
fromHex[int64](c[field].getStr())
|
|
||||||
elif T is ChainId:
|
|
||||||
c[field].getInt().T
|
|
||||||
|
|
||||||
template validateConfigValue(chainDetails, field, jtype, T: untyped, checkError: static[bool] = true) =
|
|
||||||
let fieldName = field.astToStr()
|
|
||||||
if chainDetails.hasKey(fieldName):
|
|
||||||
if chainDetails[fieldName].kind == jtype:
|
|
||||||
field = parseConfig(T, chainDetails, fieldName)
|
|
||||||
else:
|
|
||||||
error "Invalid value provided for ", fieldName
|
|
||||||
quit(1)
|
|
||||||
else:
|
|
||||||
when checkError:
|
|
||||||
error "No value found in genesis block for", fieldName
|
|
||||||
quit(1)
|
|
||||||
|
|
||||||
let config = getConfiguration()
|
|
||||||
result = Success
|
|
||||||
var
|
|
||||||
chainId = 1.ChainId
|
|
||||||
homesteadBlock, daoForkblock, eip150Block, eip155Block, eip158Block, byzantiumBlock, constantinopleBlock = high(BlockNumber).toBlockNumber
|
|
||||||
petersburgBlock, istanbulBlock, muirGlacierBlock, berlinBlock = high(BlockNumber).toBlockNumber
|
|
||||||
eip150Hash, mixHash : MDigest[256]
|
|
||||||
daoForkSupport = false
|
|
||||||
nonce = 66.toBlockNonce
|
|
||||||
extraData = hexToSeqByte("0x")
|
|
||||||
gasLimit = 16777216.int64
|
|
||||||
difficulty = 1048576.u256
|
|
||||||
alloc = parseJson("{}")
|
|
||||||
timestamp : EthTime
|
|
||||||
coinbase : EthAddress
|
|
||||||
|
|
||||||
|
|
||||||
if customGenesis.hasKey("config"):
|
|
||||||
# Validate all fork blocks for custom genesis
|
|
||||||
let forkDetails = customGenesis["config"]
|
|
||||||
validateConfigValue(forkDetails, chainId, JInt, ChainId, checkError=false)
|
|
||||||
checkForFork(forkDetails, homesteadBlock, 0.toBlockNumber)
|
|
||||||
validateConfigValue(forkDetails, daoForkSupport, JBool, bool, checkError=false)
|
|
||||||
if daoForkSupport == true:
|
|
||||||
checkForFork(forkDetails, daoForkBlock, 0.toBlockNumber)
|
|
||||||
|
|
||||||
checkForFork(forkDetails, eip150Block, homesteadBlock)
|
|
||||||
validateConfigValue(forkDetails, eip150Hash, JString, Hash256, checkError = false)
|
|
||||||
checkForFork(forkDetails, eip155Block, eip150Block)
|
|
||||||
checkForFork(forkDetails, eip158Block, eip155Block)
|
|
||||||
checkForFork(forkDetails, byzantiumBlock, eip158Block)
|
|
||||||
checkForFork(forkDetails, constantinopleBlock, byzantiumBlock)
|
|
||||||
checkForFork(forkDetails, petersburgBlock, constantinopleBlock)
|
|
||||||
checkForFork(forkDetails, istanbulBlock, petersburgBlock)
|
|
||||||
checkForFork(forkDetails, muirGlacierBlock, istanbulBlock, optional = true)
|
|
||||||
checkForFork(forkDetails, istanbulBlock, berlinBlock)
|
|
||||||
|
|
||||||
validateConfigValue(customGenesis, nonce, JString, BlockNonce, checkError = false)
|
|
||||||
validateConfigValue(customGenesis, extraData, JSTring, seq[byte], checkError = false)
|
|
||||||
validateConfigValue(customGenesis, gasLimit, JString, int64, checkError = false)
|
|
||||||
validateConfigValue(customGenesis, difficulty, JString, UInt256)
|
|
||||||
if customGenesis.hasKey("alloc"):
|
|
||||||
alloc = customGenesis["alloc"]
|
|
||||||
|
|
||||||
validateConfigValue(customGenesis, mixHash, JString, Hash256, checkError = false)
|
|
||||||
validateConfigValue(customGenesis, coinbase, JString, EthAddress, checkError = false)
|
|
||||||
validateConfigValue(customGenesis, timestamp, JString, EthTime, checkError = false)
|
|
||||||
|
|
||||||
config.customGenesis = CustomGenesisConfig(
|
|
||||||
chainId: chainId,
|
|
||||||
homesteadBlock: homesteadBlock,
|
|
||||||
eip150Block: eip150Block,
|
|
||||||
eip150Hash: eip150Hash,
|
|
||||||
eip155Block: eip155Block,
|
|
||||||
eip158Block: eip158Block,
|
|
||||||
daoForkSupport: daoForkSupport,
|
|
||||||
byzantiumBlock: byzantiumBlock,
|
|
||||||
constantinopleBlock: constantinopleBlock,
|
|
||||||
petersburgBlock: petersburgBlock,
|
|
||||||
istanbulBlock: istanbulBlock,
|
|
||||||
muirGlacierBlock: muirGlacierBlock,
|
|
||||||
berlinBlock: berlinBlock,
|
|
||||||
nonce: nonce,
|
|
||||||
extraData: extraData,
|
|
||||||
gasLimit: gasLimit,
|
|
||||||
difficulty: difficulty,
|
|
||||||
prealloc: alloc,
|
|
||||||
mixHash: mixHash,
|
|
||||||
coinbase: coinbase,
|
|
||||||
timestamp: timestamp
|
|
||||||
)
|
|
||||||
|
|
||||||
proc customGenesis(key, value: string): ConfigStatus =
|
|
||||||
if value == "":
|
|
||||||
error "No genesis block config provided for custom network", network=key
|
|
||||||
result = ErrorParseOption
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
result = processCustomGenesisConfig(parseFile(value))
|
|
||||||
except IOError:
|
|
||||||
error "Genesis block config file not found", invalidFileName=value
|
|
||||||
result = ErrorParseOption
|
|
||||||
except JsonParsingError:
|
|
||||||
error "Invalid genesis block config file format", invalidFileName=value
|
|
||||||
result = ErrorIncorrectOption
|
|
||||||
except:
|
|
||||||
var msg = getCurrentExceptionMsg()
|
|
||||||
error "Error loading genesis block config file", invalidFileName=msg
|
|
||||||
result = Error
|
|
||||||
|
|
||||||
proc processList(v: string, o: var seq[string]) =
|
proc processList(v: string, o: var seq[string]) =
|
||||||
## Process comma-separated list of strings.
|
## Process comma-separated list of strings.
|
||||||
if len(v) > 0:
|
if len(v) > 0:
|
||||||
|
@ -687,7 +478,8 @@ proc processNetArguments(key, value: string): ConfigStatus =
|
||||||
elif skey == "kovan":
|
elif skey == "kovan":
|
||||||
config.net.setNetwork(KovanNet)
|
config.net.setNetwork(KovanNet)
|
||||||
elif skey == "customnetwork":
|
elif skey == "customnetwork":
|
||||||
result = customGenesis(key, value)
|
if not loadCustomGenesis(value, config.customGenesis):
|
||||||
|
result = Error
|
||||||
config.net.networkId = NetworkId(CustomNet)
|
config.net.networkId = NetworkId(CustomNet)
|
||||||
elif skey == "networkid":
|
elif skey == "networkid":
|
||||||
var res = 0
|
var res = 0
|
||||||
|
|
|
@ -10,7 +10,7 @@ import
|
||||||
stew/[byteutils], eth/trie/[hexary, db],
|
stew/[byteutils], eth/trie/[hexary, db],
|
||||||
eth/[common, rlp], chronicles,
|
eth/[common, rlp], chronicles,
|
||||||
../errors, ../constants, ./storage_types,
|
../errors, ../constants, ./storage_types,
|
||||||
../utils, ../config
|
../utils, ../config, ../chain_config
|
||||||
|
|
||||||
type
|
type
|
||||||
BaseChainDB* = ref object
|
BaseChainDB* = ref object
|
||||||
|
|
|
@ -1,62 +1,10 @@
|
||||||
import
|
import
|
||||||
tables, json, times, strutils,
|
std/[json, strutils, times, tables],
|
||||||
eth/[common, rlp, trie], stint, stew/[byteutils],
|
eth/[common, rlp, trie], stew/[byteutils],
|
||||||
chronicles, eth/trie/db,
|
chronicles, eth/trie/db,
|
||||||
db/[db_chain, state_db], genesis_alloc, config, constants
|
./db/[db_chain, state_db],
|
||||||
|
./genesis_alloc, ./config, ./constants,
|
||||||
type
|
./chain_config
|
||||||
Genesis* = object
|
|
||||||
config*: ChainConfig
|
|
||||||
nonce*: BlockNonce
|
|
||||||
timestamp*: EthTime
|
|
||||||
extraData*: seq[byte]
|
|
||||||
gasLimit*: GasInt
|
|
||||||
difficulty*: DifficultyInt
|
|
||||||
mixhash*: Hash256
|
|
||||||
coinbase*: EthAddress
|
|
||||||
alloc*: GenesisAlloc
|
|
||||||
|
|
||||||
GenesisAlloc = TableRef[EthAddress, GenesisAccount]
|
|
||||||
GenesisAccount = object
|
|
||||||
code*: seq[byte]
|
|
||||||
storage*: Table[UInt256, UInt256]
|
|
||||||
balance*: UInt256
|
|
||||||
nonce*: AccountNonce
|
|
||||||
|
|
||||||
func toAddress(n: UInt256): EthAddress =
|
|
||||||
let a = n.toByteArrayBE()
|
|
||||||
result[0 .. ^1] = a.toOpenArray(12, a.high)
|
|
||||||
|
|
||||||
func decodePrealloc(data: seq[byte]): GenesisAlloc =
|
|
||||||
result = newTable[EthAddress, GenesisAccount]()
|
|
||||||
for tup in rlp.decode(data, seq[(UInt256, UInt256)]):
|
|
||||||
result[toAddress(tup[0])] = GenesisAccount(balance: tup[1])
|
|
||||||
|
|
||||||
proc customNetPrealloc(genesisBlock: JsonNode): GenesisAlloc =
|
|
||||||
result = newTable[EthAddress, GenesisAccount]()
|
|
||||||
for address, account in genesisBlock.pairs():
|
|
||||||
let nonce = if "nonce" in account:
|
|
||||||
parseHexInt(account["nonce"].getStr).AccountNonce
|
|
||||||
else:
|
|
||||||
AccountNonce(0)
|
|
||||||
|
|
||||||
let code = if "code" in account:
|
|
||||||
hexToSeqByte(account["code"].getStr)
|
|
||||||
else:
|
|
||||||
@[]
|
|
||||||
|
|
||||||
var acc = GenesisAccount(
|
|
||||||
balance: fromHex(UInt256, account["balance"].getStr),
|
|
||||||
code: code,
|
|
||||||
nonce: nonce
|
|
||||||
)
|
|
||||||
|
|
||||||
if "storage" in account:
|
|
||||||
let storage = account["storage"]
|
|
||||||
for k, v in storage:
|
|
||||||
acc.storage[fromHex(UInt256, k)] = fromHex(UInt256, v.getStr)
|
|
||||||
|
|
||||||
result[parseAddress(address)] = acc
|
|
||||||
|
|
||||||
proc defaultGenesisBlockForNetwork*(id: PublicNetwork): Genesis =
|
proc defaultGenesisBlockForNetwork*(id: PublicNetwork): Genesis =
|
||||||
result = case id
|
result = case id
|
||||||
|
@ -95,28 +43,13 @@ proc defaultGenesisBlockForNetwork*(id: PublicNetwork): Genesis =
|
||||||
alloc: decodePrealloc(goerliAllocData)
|
alloc: decodePrealloc(goerliAllocData)
|
||||||
)
|
)
|
||||||
of CustomNet:
|
of CustomNet:
|
||||||
let genesis = getConfiguration().customGenesis
|
let customGenesis = getConfiguration().customGenesis
|
||||||
var alloc = new GenesisAlloc
|
customGenesis.genesis
|
||||||
assert(genesis.prealloc.isNil.not, "genesis prealloc should not nil")
|
|
||||||
if genesis.prealloc != parseJson("{}"):
|
|
||||||
alloc = customNetPrealloc(genesis.prealloc)
|
|
||||||
Genesis(
|
|
||||||
nonce: genesis.nonce,
|
|
||||||
extraData: genesis.extraData,
|
|
||||||
gasLimit: genesis.gasLimit,
|
|
||||||
difficulty: genesis.difficulty,
|
|
||||||
alloc: alloc,
|
|
||||||
timestamp: genesis.timestamp,
|
|
||||||
mixhash: genesis.mixHash,
|
|
||||||
coinbase: genesis.coinbase
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# TODO: Fill out the rest
|
# TODO: Fill out the rest
|
||||||
error "No default genesis for network", id
|
error "No default genesis for network", id
|
||||||
doAssert(false, "No default genesis for " & $id)
|
doAssert(false, "No default genesis for " & $id)
|
||||||
Genesis()
|
Genesis()
|
||||||
result.config = publicChainConfig(id)
|
|
||||||
|
|
||||||
proc toBlock*(g: Genesis, db: BaseChainDB = nil): BlockHeader =
|
proc toBlock*(g: Genesis, db: BaseChainDB = nil): BlockHeader =
|
||||||
let (tdb, pruneTrie) = if db.isNil: (newMemoryDB(), true)
|
let (tdb, pruneTrie) = if db.isNil: (newMemoryDB(), true)
|
||||||
|
@ -130,8 +63,6 @@ proc toBlock*(g: Genesis, db: BaseChainDB = nil): BlockHeader =
|
||||||
for k, v in account.storage:
|
for k, v in account.storage:
|
||||||
sdb.setStorage(address, k, v)
|
sdb.setStorage(address, k, v)
|
||||||
|
|
||||||
var root = sdb.rootHash
|
|
||||||
|
|
||||||
result = BlockHeader(
|
result = BlockHeader(
|
||||||
nonce: g.nonce,
|
nonce: g.nonce,
|
||||||
timestamp: g.timestamp,
|
timestamp: g.timestamp,
|
||||||
|
@ -140,7 +71,7 @@ proc toBlock*(g: Genesis, db: BaseChainDB = nil): BlockHeader =
|
||||||
difficulty: g.difficulty,
|
difficulty: g.difficulty,
|
||||||
mixDigest: g.mixhash,
|
mixDigest: g.mixhash,
|
||||||
coinbase: g.coinbase,
|
coinbase: g.coinbase,
|
||||||
stateRoot: root,
|
stateRoot: sdb.rootHash,
|
||||||
parentHash: GENESIS_PARENT_HASH,
|
parentHash: GENESIS_PARENT_HASH,
|
||||||
txRoot: BLANK_ROOT_HASH,
|
txRoot: BLANK_ROOT_HASH,
|
||||||
receiptRoot: BLANK_ROOT_HASH,
|
receiptRoot: BLANK_ROOT_HASH,
|
||||||
|
@ -161,7 +92,4 @@ proc commit*(g: Genesis, db: BaseChainDB) =
|
||||||
proc initializeEmptyDb*(db: BaseChainDB) =
|
proc initializeEmptyDb*(db: BaseChainDB) =
|
||||||
trace "Writing genesis to DB"
|
trace "Writing genesis to DB"
|
||||||
let networkId = getConfiguration().net.networkId.toPublicNetwork()
|
let networkId = getConfiguration().net.networkId.toPublicNetwork()
|
||||||
# if networkId == CustomNet:
|
|
||||||
# raise newException(Exception, "Custom genesis not implemented")
|
|
||||||
# else:
|
|
||||||
defaultGenesisBlockForNetwork(networkId).commit(db)
|
defaultGenesisBlockForNetwork(networkId).commit(db)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import ../db/db_chain, eth/common, chronicles, ../vm_state, ../vm_types,
|
import ../db/db_chain, eth/common, chronicles, ../vm_state, ../vm_types,
|
||||||
../vm_computation, ../vm_message, ../vm_types2, stint, nimcrypto,
|
../vm_computation, ../vm_message, ../vm_types2, stint, nimcrypto,
|
||||||
../utils, eth/trie/db, ./executor, ../config, ../genesis, ../utils,
|
../utils, eth/trie/db, ./executor, ../chain_config, ../genesis, ../utils,
|
||||||
stew/endians2
|
stew/endians2
|
||||||
|
|
||||||
when not defined(release):
|
when not defined(release):
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import hexstrings, eth/[common, rlp, keys, trie/db], stew/byteutils, nimcrypto,
|
import hexstrings, eth/[common, rlp, keys, trie/db], stew/byteutils, nimcrypto,
|
||||||
../db/[db_chain, accounts_cache], strutils, algorithm, options, times, json,
|
../db/[db_chain, accounts_cache], strutils, algorithm, options, times, json,
|
||||||
../constants, stint, hexstrings, rpc_types, ../config,
|
../constants, stint, hexstrings, rpc_types, ../chain_config,
|
||||||
../vm_state_transactions, ../vm_state, ../vm_types, ../vm_types2,
|
../vm_state_transactions, ../vm_state, ../vm_types, ../vm_types2,
|
||||||
../vm_computation, ../p2p/executor, ../utils, ../transaction,
|
../vm_computation, ../p2p/executor, ../utils, ../transaction,
|
||||||
../transaction/call_evm
|
../transaction/call_evm
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
times, eth/common, stint,
|
times, eth/common, stint,
|
||||||
../constants, ../config
|
../constants, ../chain_config
|
||||||
|
|
||||||
const
|
const
|
||||||
ExpDiffPeriod = 100000.u256
|
ExpDiffPeriod = 100000.u256
|
||||||
|
|
|
@ -10,7 +10,7 @@ import
|
||||||
strformat, times, options,
|
strformat, times, options,
|
||||||
eth/[common, rlp],
|
eth/[common, rlp],
|
||||||
./difficulty, ../constants,
|
./difficulty, ../constants,
|
||||||
../config
|
../chain_config
|
||||||
|
|
||||||
export BlockHeader
|
export BlockHeader
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"chainId": 1,
|
||||||
|
"homesteadBlock": 0,
|
||||||
|
"daoForkSupport": true,
|
||||||
|
"eip150Block": 0,
|
||||||
|
"eip155Block": 0,
|
||||||
|
"eip158Block": 0,
|
||||||
|
"byzantiumBlock": 0,
|
||||||
|
"constantinopleBlock": 0,
|
||||||
|
"petersburgBlock": 0,
|
||||||
|
"istanbulBlock": 0,
|
||||||
|
"berlinBlock": 2000
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"nonce": "0x0",
|
||||||
|
"timestamp": "0x0",
|
||||||
|
"extraData": "0x00",
|
||||||
|
"gasLimit": "0x5f5e100",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
|
||||||
|
"alloc": {
|
||||||
|
"0000000000000000000000000000000000000100": {
|
||||||
|
"code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160005500",
|
||||||
|
"balance": "0xba1a9ce0ba1a9ce"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000101": {
|
||||||
|
"code": "0x60047fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160005500",
|
||||||
|
"balance": "0xba1a9ce0ba1a9ce"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000102": {
|
||||||
|
"code": "0x60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160005500",
|
||||||
|
"balance": "0xba1a9ce0ba1a9ce"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000103": {
|
||||||
|
"code": "0x600060000160005500",
|
||||||
|
"balance": "0xba1a9ce0ba1a9ce"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000104": {
|
||||||
|
"code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60010160005500",
|
||||||
|
"balance": "0xba1a9ce0ba1a9ce"
|
||||||
|
},
|
||||||
|
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||||
|
"balance": "0xba1a9ce0ba1a9ce"
|
||||||
|
},
|
||||||
|
"cccccccccccccccccccccccccccccccccccccccc": {
|
||||||
|
"code": "0x600060006000600060006004356101000162fffffff100",
|
||||||
|
"balance": "0xba1a9ce0ba1a9ce"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": "0x0",
|
||||||
|
"gasUsed": "0x0",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"chainId": 7,
|
||||||
|
"homesteadBlock": 0,
|
||||||
|
"eip150Block": 0,
|
||||||
|
"eip158Block": 0
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"coinbase": "0x0000000000000000000000000000000000000000",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"gasLimit": "0x2fefd8",
|
||||||
|
"nonce": "0x0000000000000000",
|
||||||
|
"timestamp": "0x1234",
|
||||||
|
"alloc": {
|
||||||
|
"cf49fda3be353c69b41ed96333cd24302da4556f": {
|
||||||
|
"balance": "0x123450000000000000000"
|
||||||
|
},
|
||||||
|
"0161e041aad467a890839d5b08b138c1e6373072": {
|
||||||
|
"balance": "0x123450000000000000000"
|
||||||
|
},
|
||||||
|
"87da6a8c6e9eff15d703fc2773e32f6af8dbe301": {
|
||||||
|
"balance": "0x123450000000000000000"
|
||||||
|
},
|
||||||
|
"b97de4b8c857e4f6bc354f226dc3249aaee49209": {
|
||||||
|
"balance": "0x123450000000000000000"
|
||||||
|
},
|
||||||
|
"c5065c9eeebe6df2c2284d046bfc906501846c51": {
|
||||||
|
"balance": "0x123450000000000000000"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000314": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a223e05d1461006a578063abd1a0cf1461008d578063abfced1d146100d4578063e05c914a14610110578063e6768b451461014c575b610000565b346100005761007761019d565b6040518082815260200191505060405180910390f35b34610000576100be600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101a3565b6040518082815260200191505060405180910390f35b346100005761010e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101ed565b005b346100005761014a600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610236565b005b346100005761017960048080359060200190919080359060200190919080359060200190919050506103c4565b60405180848152602001838152602001828152602001935050505060405180910390f35b60005481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b7f6031a8d62d7c95988fa262657cd92107d90ed96e08d8f867d32f26edfe85502260405180905060405180910390a17f47e2689743f14e97f7dcfa5eec10ba1dff02f83b3d1d4b9c07b206cbbda66450826040518082815260200191505060405180910390a1817fa48a6b249a5084126c3da369fbc9b16827ead8cb5cdc094b717d3f1dcd995e2960405180905060405180910390a27f7890603b316f3509577afd111710f9ebeefa15e12f72347d9dffd0d65ae3bade81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff167f7efef9ea3f60ddc038e50cccec621f86a0195894dc0520482abf8b5c6b659e4160405180905060405180910390a28181604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a05b5050565b6000600060008585859250925092505b935093509390505600a165627a7a72305820aaf842d0d0c35c45622c5263cbb54813d2974d3999c8c38551d7c613ea2bc1170029",
|
||||||
|
"storage": {
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x1234",
|
||||||
|
"0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9": "0x01"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000315": {
|
||||||
|
"balance": "0x9999999999999999999999999999999",
|
||||||
|
"code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef2769ca1461003e575b610000565b3461000057610078600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061007a565b005b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f1935050505015610106578173ffffffffffffffffffffffffffffffffffffffff167f30a3c50752f2552dcc2b93f5b96866280816a986c0c0408cb6778b9fa198288f826040518082815260200191505060405180910390a25b5b50505600a165627a7a72305820637991fabcc8abad4294bf2bb615db78fbec4edff1635a2647d3894e2daf6a610029"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"genesis": {
|
||||||
|
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
|
||||||
|
"difficulty" : "0x020000",
|
||||||
|
"extraData" : "0x42",
|
||||||
|
"gasLimit" : "0x2fefd8",
|
||||||
|
"mixHash" : "0x2c85bcbce56429100b2108254bb56906257582aeafcbd682bc9af67a9f5aee46",
|
||||||
|
"nonce" : "0x78cc16f7b4f65485",
|
||||||
|
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"timestamp" : "0x54c98c81",
|
||||||
|
"alloc" : {
|
||||||
|
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||||
|
"balance" : "0x09184e72a000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ import
|
||||||
../nimbus/db/[db_chain, accounts_cache],
|
../nimbus/db/[db_chain, accounts_cache],
|
||||||
../nimbus/utils/header,
|
../nimbus/utils/header,
|
||||||
../nimbus/p2p/[executor, dao],
|
../nimbus/p2p/[executor, dao],
|
||||||
../nimbus/config,
|
../nimbus/[config, chain_config],
|
||||||
../stateless/[tree_from_witness, witness_types]
|
../stateless/[tree_from_witness, witness_types]
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import unittest2, ../nimbus/[genesis, config], eth/common, nimcrypto/hash
|
import
|
||||||
|
std/[os],
|
||||||
|
unittest2, eth/common, nimcrypto/hash,
|
||||||
|
../nimbus/[genesis, config, chain_config]
|
||||||
|
|
||||||
proc genesisMain*() =
|
const dataFolder = "tests" / "customgenesis"
|
||||||
|
|
||||||
|
proc genesisTest() =
|
||||||
suite "Genesis":
|
suite "Genesis":
|
||||||
test "Correct mainnet hash":
|
test "Correct mainnet hash":
|
||||||
let g = defaultGenesisBlockForNetwork(MainNet)
|
let g = defaultGenesisBlockForNetwork(MainNet)
|
||||||
|
@ -22,5 +27,17 @@ proc genesisMain*() =
|
||||||
let b = g.toBlock
|
let b = g.toBlock
|
||||||
check(b.blockHash == "bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a".toDigest)
|
check(b.blockHash == "bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a".toDigest)
|
||||||
|
|
||||||
|
proc customGenesisTest() =
|
||||||
|
suite "Custom Genesis":
|
||||||
|
test "loadCustomGenesis":
|
||||||
|
var cga, cgb, cgc: CustomGenesis
|
||||||
|
check loadCustomGenesis(dataFolder / "berlin2000.json", cga)
|
||||||
|
check loadCustomGenesis(dataFolder / "chainid7.json", cgb)
|
||||||
|
check loadCustomGenesis(dataFolder / "noconfig.json", cgc)
|
||||||
|
|
||||||
|
proc genesisMain*() =
|
||||||
|
genesisTest()
|
||||||
|
customGenesisTest()
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
genesisMain()
|
genesisMain()
|
||||||
|
|
|
@ -13,7 +13,7 @@ import
|
||||||
eth/[p2p, common, trie/db, rlp, trie],
|
eth/[p2p, common, trie/db, rlp, trie],
|
||||||
eth/p2p/rlpx_protocols/eth_protocol,
|
eth/p2p/rlpx_protocols/eth_protocol,
|
||||||
graphql, ../nimbus/graphql/ethapi, graphql/test_common,
|
graphql, ../nimbus/graphql/ethapi, graphql/test_common,
|
||||||
../nimbus/[genesis, config], ../nimbus/db/[db_chain, state_db],
|
../nimbus/[genesis, config, chain_config], ../nimbus/db/[db_chain, state_db],
|
||||||
../nimbus/p2p/chain, ../premix/parser, ./test_helpers
|
../nimbus/p2p/chain, ../premix/parser, ./test_helpers
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -37,17 +37,19 @@ proc setupChain(chainDB: BaseChainDB) =
|
||||||
jn = v
|
jn = v
|
||||||
break
|
break
|
||||||
|
|
||||||
let genesisBlock = jn.toBlock("genesisRLP")
|
let genesis = jn.toBlock("genesisRLP")
|
||||||
|
|
||||||
let conf = getConfiguration()
|
let conf = getConfiguration()
|
||||||
conf.customGenesis.nonce = genesisBlock.header.nonce
|
conf.customGenesis.genesis.nonce = genesis.header.nonce
|
||||||
conf.customGenesis.extraData = genesisBlock.header.extraData
|
conf.customGenesis.genesis.extraData = genesis.header.extraData
|
||||||
conf.customGenesis.gasLimit = genesisBlock.header.gasLimit
|
conf.customGenesis.genesis.gasLimit = genesis.header.gasLimit
|
||||||
conf.customGenesis.difficulty = genesisBlock.header.difficulty
|
conf.customGenesis.genesis.difficulty = genesis.header.difficulty
|
||||||
conf.customGenesis.mixHash = genesisBlock.header.mixDigest
|
conf.customGenesis.genesis.mixHash = genesis.header.mixDigest
|
||||||
conf.customGenesis.coinBase = genesisBlock.header.coinbase
|
conf.customGenesis.genesis.coinBase = genesis.header.coinbase
|
||||||
conf.customGenesis.timestamp = genesisBlock.header.timestamp
|
conf.customGenesis.genesis.timestamp = genesis.header.timestamp
|
||||||
conf.customGenesis.prealloc = jn["pre"]
|
if not parseGenesisAlloc($(jn["pre"]), conf.customGenesis.genesis.alloc):
|
||||||
|
quit(QuitFailure)
|
||||||
|
|
||||||
chainDB.initializeEmptyDb()
|
chainDB.initializeEmptyDb()
|
||||||
|
|
||||||
let blocks = jn["blocks"]
|
let blocks = jn["blocks"]
|
||||||
|
@ -68,7 +70,7 @@ proc setupChain(chainDB: BaseChainDB) =
|
||||||
proc graphqlMain*() =
|
proc graphqlMain*() =
|
||||||
let conf = getConfiguration()
|
let conf = getConfiguration()
|
||||||
conf.net.networkId = NetworkId(CustomNet)
|
conf.net.networkId = NetworkId(CustomNet)
|
||||||
conf.customGenesis = CustomGenesisConfig(
|
conf.customGenesis.config = ChainConfig(
|
||||||
chainId : MainNet.ChainId,
|
chainId : MainNet.ChainId,
|
||||||
byzantiumBlock : 0.toBlockNumber,
|
byzantiumBlock : 0.toBlockNumber,
|
||||||
constantinopleBlock : 0.toBlockNumber,
|
constantinopleBlock : 0.toBlockNumber,
|
||||||
|
|
Loading…
Reference in New Issue