config: fix new config based on input from jamie and zahary
This commit is contained in:
parent
69f2a0f95a
commit
a3badea928
|
@ -16,8 +16,8 @@ import
|
|||
|
||||
proc genesisToTrie(filePath: string): HexaryTrie =
|
||||
# TODO: Doing our best here with API that exists, to be improved.
|
||||
var cn: CustomNetwork
|
||||
if not loadCustomNetwork(filePath, cn):
|
||||
var cn: NetworkParams
|
||||
if not loadNetworkParams(filePath, cn):
|
||||
quit(1)
|
||||
|
||||
var chainDB = newBaseChainDB(
|
||||
|
|
|
@ -21,8 +21,8 @@ proc processNode(genesisFile, chainFile,
|
|||
conf = makeConfig(@["--customnetwork:" & genesisFile])
|
||||
chainDB = newBaseChainDB(newMemoryDb(),
|
||||
pruneTrie = false,
|
||||
conf.networkId.get,
|
||||
conf.customNetwork.get()
|
||||
conf.networkId,
|
||||
conf.networkParams
|
||||
)
|
||||
|
||||
initializeEmptyDb(chainDB)
|
||||
|
|
|
@ -67,13 +67,13 @@ proc processNode(ctx: GraphqlRef, node: JsonNode, fileName: string, testStatusIM
|
|||
|
||||
proc main() =
|
||||
let
|
||||
conf = makeConfig(@["--customnetwork:" & genesisFile])
|
||||
conf = makeConfig(@["--custom-network:" & genesisFile])
|
||||
ethCtx = newEthContext()
|
||||
ethNode = setupEthNode(conf, ethCtx, eth)
|
||||
chainDB = newBaseChainDB(newMemoryDb(),
|
||||
pruneTrie = false,
|
||||
conf.networkId.get,
|
||||
conf.customNetwork.get
|
||||
conf.networkId,
|
||||
conf.networkParams
|
||||
)
|
||||
|
||||
initializeEmptyDb(chainDB)
|
||||
|
|
|
@ -15,7 +15,7 @@ import
|
|||
json_serialization/std/options as jsoptions,
|
||||
json_serialization/std/tables as jstable,
|
||||
json_serialization/lexer,
|
||||
./forks
|
||||
"."/[forks, genesis_alloc]
|
||||
|
||||
type
|
||||
CliqueOptions = object
|
||||
|
@ -83,7 +83,7 @@ type
|
|||
balance*: UInt256
|
||||
nonce* : AccountNonce
|
||||
|
||||
CustomNetwork* = object
|
||||
NetworkParams* = object
|
||||
config* : ChainConfig
|
||||
genesis*: Genesis
|
||||
|
||||
|
@ -159,19 +159,19 @@ template to(a: string, b: type UInt256): UInt256 =
|
|||
# json_serialization decode table stuff
|
||||
UInt256.fromHex(a)
|
||||
|
||||
proc loadCustomNetwork*(fileName: string, cg: var CustomNetwork): bool =
|
||||
proc loadNetworkParams*(fileName: string, cg: var NetworkParams): 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
|
||||
error "Network params I/O error", fileName, msg=e.msg
|
||||
return false
|
||||
except JsonReaderError as e:
|
||||
error "Invalid genesis config file format", fileName, msg=e.formatMsg("")
|
||||
error "Invalid network params file format", fileName, msg=e.formatMsg("")
|
||||
return false
|
||||
except:
|
||||
var msg = getCurrentExceptionMsg()
|
||||
error "Error loading genesis block config file", fileName, msg
|
||||
error "Error loading network params file", fileName, msg
|
||||
return false
|
||||
|
||||
cg.genesis = cc.genesis
|
||||
|
@ -237,14 +237,14 @@ proc toFork*(c: ChainConfig, number: BlockNumber): Fork =
|
|||
elif number >= c.homesteadBlock: FkHomestead
|
||||
else: FkFrontier
|
||||
|
||||
proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
||||
proc chainConfigForNetwork(id: NetworkId): ChainConfig =
|
||||
# For some public networks, NetworkId and ChainId value are identical
|
||||
# but that is not always the case
|
||||
|
||||
result = case id
|
||||
of MainNet:
|
||||
ChainConfig(
|
||||
poaEngine: false, # TODO: use real engine conf: PoW
|
||||
poaEngine: false,
|
||||
chainId: MainNet.ChainId,
|
||||
homesteadBlock: 1_150_000.toBlockNumber, # 14/03/2016 20:49:53
|
||||
daoForkBlock: 1_920_000.toBlockNumber,
|
||||
|
@ -263,7 +263,7 @@ proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
|||
)
|
||||
of RopstenNet:
|
||||
ChainConfig(
|
||||
poaEngine: false, # TODO: use real engine conf: PoW
|
||||
poaEngine: false,
|
||||
chainId: RopstenNet.ChainId,
|
||||
homesteadBlock: 0.toBlockNumber,
|
||||
daoForkSupport: false,
|
||||
|
@ -281,7 +281,7 @@ proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
|||
)
|
||||
of RinkebyNet:
|
||||
ChainConfig(
|
||||
poaEngine: true, # TODO: use real engine conf: PoA
|
||||
poaEngine: true,
|
||||
chainId: RinkebyNet.ChainId,
|
||||
homesteadBlock: 1.toBlockNumber,
|
||||
daoForkSupport: false,
|
||||
|
@ -299,7 +299,7 @@ proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
|||
)
|
||||
of GoerliNet:
|
||||
ChainConfig(
|
||||
poaEngine: true, # TODO: use real engine conf: PoA
|
||||
poaEngine: true,
|
||||
chainId: GoerliNet.ChainId,
|
||||
homesteadBlock: 0.toBlockNumber,
|
||||
daoForkSupport: false,
|
||||
|
@ -316,6 +316,47 @@ proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
|||
londonBlock: 5_062_605.toBlockNumber # June 30, 2021
|
||||
)
|
||||
else:
|
||||
# everything else will use CustomNet config
|
||||
trace "Custom genesis block configuration loaded", conf=cn.config
|
||||
cn.config
|
||||
ChainConfig()
|
||||
|
||||
proc genesisBlockForNetwork(id: NetworkId): Genesis =
|
||||
result = case id
|
||||
of MainNet:
|
||||
Genesis(
|
||||
nonce: 66.toBlockNonce,
|
||||
extraData: hexToSeqByte("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
|
||||
gasLimit: 5000,
|
||||
difficulty: 17179869184.u256,
|
||||
alloc: decodePrealloc(mainnetAllocData)
|
||||
)
|
||||
of RopstenNet:
|
||||
Genesis(
|
||||
nonce: 66.toBlockNonce,
|
||||
extraData: hexToSeqByte("0x3535353535353535353535353535353535353535353535353535353535353535"),
|
||||
gasLimit: 16777216,
|
||||
difficulty: 1048576.u256,
|
||||
alloc: decodePrealloc(testnetAllocData)
|
||||
)
|
||||
of RinkebyNet:
|
||||
Genesis(
|
||||
nonce: 0.toBlockNonce,
|
||||
timestamp: initTime(0x58ee40ba, 0),
|
||||
extraData: hexToSeqByte("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
|
||||
gasLimit: 4700000,
|
||||
difficulty: 1.u256,
|
||||
alloc: decodePrealloc(rinkebyAllocData)
|
||||
)
|
||||
of GoerliNet:
|
||||
Genesis(
|
||||
nonce: 0.toBlockNonce,
|
||||
timestamp: initTime(0x5c51a607, 0),
|
||||
extraData: hexToSeqByte("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
|
||||
gasLimit: 0xa00000,
|
||||
difficulty: 1.u256,
|
||||
alloc: decodePrealloc(goerliAllocData)
|
||||
)
|
||||
else:
|
||||
Genesis()
|
||||
|
||||
proc networkParams*(id: NetworkId): NetworkParams =
|
||||
result.genesis = genesisBlockForNetwork(id)
|
||||
result.config = chainConfigForNetwork(id)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Nimbus
|
||||
# Copyright (c) 2021 Status Research & Development GmbH
|
||||
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
|
@ -10,6 +10,7 @@
|
|||
import
|
||||
std/[options, strutils, times, os],
|
||||
pkg/[
|
||||
chronicles,
|
||||
confutils,
|
||||
confutils/defs,
|
||||
stew/byteutils,
|
||||
|
@ -21,6 +22,8 @@ import
|
|||
constants, vm_compile_info
|
||||
]
|
||||
|
||||
export stewNet
|
||||
|
||||
const
|
||||
NimbusName* = "nimbus-eth1"
|
||||
## project name string
|
||||
|
@ -41,6 +44,8 @@ const
|
|||
|
||||
NimVersion = staticExec("nim --version").strip()
|
||||
|
||||
# TODO: fix this agent-string format to match other
|
||||
# eth clients format
|
||||
NimbusIdent* = "$# v$# [$#: $#, $#, $#, $#]" % [
|
||||
NimbusName,
|
||||
NimbusVersion,
|
||||
|
@ -99,8 +104,8 @@ const
|
|||
defaultEthGraphqlPort = 8547
|
||||
defaultListenAddress = (static ValidIpAddress.init("0.0.0.0"))
|
||||
defaultAdminListenAddress = (static ValidIpAddress.init("127.0.0.1"))
|
||||
defaultListenAddressDesc = $defaultListenAddress
|
||||
defaultAdminListenAddressDesc = $defaultAdminListenAddress
|
||||
defaultListenAddressDesc = $defaultListenAddress & ", meaning all network interfaces"
|
||||
defaultAdminListenAddressDesc = $defaultAdminListenAddress & ", meaning local host only"
|
||||
logLevelDesc = getLogLevels()
|
||||
|
||||
type
|
||||
|
@ -108,8 +113,9 @@ type
|
|||
Full
|
||||
Archive
|
||||
|
||||
NimbusCmd* = enum
|
||||
NimbusCmd* {.pure.} = enum
|
||||
noCommand
|
||||
`import`
|
||||
|
||||
ProtocolFlag* {.pure.} = enum
|
||||
## Protocol flags
|
||||
|
@ -121,14 +127,10 @@ type
|
|||
Eth ## enable eth_ set of RPC API
|
||||
Debug ## enable debug_ set of RPC API
|
||||
|
||||
EnodeList* = object
|
||||
value*: seq[Enode]
|
||||
|
||||
Protocols* = object
|
||||
value*: set[ProtocolFlag]
|
||||
|
||||
RpcApi* = object
|
||||
value*: set[RpcFlag]
|
||||
DiscoveryType* {.pure.} = enum
|
||||
None
|
||||
V4
|
||||
V5
|
||||
|
||||
NimbusConf* = object of RootObj
|
||||
## Main Nimbus configuration object
|
||||
|
@ -142,7 +144,7 @@ type
|
|||
name: "data-dir" }: OutDir
|
||||
|
||||
keyStore* {.
|
||||
desc: "Directory for the keystore files"
|
||||
desc: "Load one or more keystore files from this directory"
|
||||
defaultValue: defaultKeystoreDir()
|
||||
defaultValueDesc: "inside datadir"
|
||||
abbr: "k"
|
||||
|
@ -155,20 +157,15 @@ type
|
|||
abbr : "p"
|
||||
name: "prune-mode" }: PruneMode
|
||||
|
||||
importBlocks* {.
|
||||
desc: "Import RLP encoded block(s) in a file, validate, write to database and quit"
|
||||
defaultValue: ""
|
||||
abbr: "b"
|
||||
name: "import-blocks" }: InputFile
|
||||
|
||||
importKey* {.
|
||||
desc: "Import unencrypted 32 bytes hex private key file"
|
||||
desc: "Import unencrypted 32 bytes hex private key from a file"
|
||||
defaultValue: ""
|
||||
abbr: "e"
|
||||
name: "import-key" }: InputFile
|
||||
|
||||
engineSigner* {.
|
||||
desc: "Enable sealing engine to run and producing blocks at specified interval (only PoA/Clique supported)"
|
||||
desc: "Set the signer address(as 20 bytes hex) and enable sealing engine to run and " &
|
||||
"producing blocks at specified interval (only PoA/Clique supported)"
|
||||
defaultValue: ZERO_ADDRESS
|
||||
defaultValueDesc: ""
|
||||
abbr: "s"
|
||||
|
@ -179,182 +176,164 @@ type
|
|||
defaultValueDesc: ""
|
||||
name: "verify-from" }: Option[uint64]
|
||||
|
||||
network {.
|
||||
separator: "\pETHEREUM NETWORK OPTIONS:"
|
||||
desc: "Name or id number of Ethereum network(mainnet(1), ropsten(3), rinkeby(4), goerli(5), kovan(42), other=custom)"
|
||||
#[longDesc:
|
||||
"- mainnet: Ethereum main network\n" &
|
||||
"- ropsten: Test network (proof-of-work, the one most like Ethereum mainnet)\n" &
|
||||
"- rinkeby: Test network (proof-of-authority, for those running Geth clients)\n" &
|
||||
"- görli : Test network (proof-of-authority, works across all clients)\n" &
|
||||
"- kovan : Test network (proof-of-authority, for those running OpenEthereum clients)"]#
|
||||
defaultValue: "" # the default value is set in makeConfig
|
||||
defaultValueDesc: "mainnet(1)"
|
||||
abbr: "i"
|
||||
name: "network" }: string
|
||||
|
||||
customNetwork {.
|
||||
desc: "Use custom genesis block for private Ethereum Network (as /path/to/genesis.json)"
|
||||
defaultValueDesc: ""
|
||||
abbr: "c"
|
||||
name: "custom-network" }: Option[NetworkParams]
|
||||
|
||||
networkId* {.
|
||||
hidden # TODO: use ignore from confutils if its become available
|
||||
defaultValue: MainNet
|
||||
name: "network-id"}: NetworkId
|
||||
|
||||
networkParams* {.
|
||||
hidden # TODO: use ignore from confutils if its become available
|
||||
defaultValue: NetworkParams()
|
||||
name: "network-params"}: NetworkParams
|
||||
|
||||
logLevel* {.
|
||||
separator: "\pLOGGING AND DEBUGGING OPTIONS:"
|
||||
desc: "Sets the log level for process and topics (" & logLevelDesc & ")"
|
||||
defaultValue: LogLevel.INFO
|
||||
defaultValueDesc: $LogLevel.INFO
|
||||
name: "log-level" }: LogLevel
|
||||
|
||||
logFile* {.
|
||||
desc: "Specifies a path for the written Json log file"
|
||||
name: "log-file" }: Option[OutFile]
|
||||
|
||||
logMetricsEnabled* {.
|
||||
desc: "Enable metrics logging"
|
||||
defaultValue: false
|
||||
name: "log-metrics" .}: bool
|
||||
|
||||
logMetricsInterval* {.
|
||||
desc: "Interval at which to log metrics, in seconds"
|
||||
defaultValue: 10
|
||||
name: "log-metrics-interval" .}: int
|
||||
|
||||
bootstrapNodes {.
|
||||
separator: "\pNETWORKING OPTIONS:"
|
||||
desc: "Specifies one or more bootstrap nodes(as enode URL) to use when connecting to the network"
|
||||
defaultValue: @[]
|
||||
defaultValueDesc: ""
|
||||
abbr: "b"
|
||||
name: "bootstrap-node" }: seq[string]
|
||||
|
||||
bootstrapFile {.
|
||||
desc: "Specifies a line-delimited file of bootstrap Ethereum network addresses(enode URL). " &
|
||||
"By default, addresses will be added to bootstrap node list. " &
|
||||
"But if the first line equals to `override` word, it will override built-in list"
|
||||
defaultValue: ""
|
||||
name: "bootstrap-file" }: InputFile
|
||||
|
||||
staticPeers {.
|
||||
desc: "Connect to one or more trusted peers(as enode URL)"
|
||||
defaultValue: @[]
|
||||
defaultValueDesc: ""
|
||||
name: "static-peers" }: seq[string]
|
||||
|
||||
listenAddress* {.
|
||||
desc: "Listening IP address for Ethereum P2P and Discovery traffic"
|
||||
defaultValue: defaultListenAddress
|
||||
defaultValueDesc: $defaultListenAddressDesc
|
||||
name: "listen-address" }: ValidIpAddress
|
||||
|
||||
tcpPort* {.
|
||||
desc: "Ethereum P2P network listening TCP port"
|
||||
defaultValue: defaultPort
|
||||
defaultValueDesc: $defaultPort
|
||||
name: "tcp-port" }: Port
|
||||
|
||||
udpPort* {.
|
||||
desc: "Ethereum P2P network listening UDP port"
|
||||
defaultValue: 0 # set udpPort defaultValue in `makeConfig`
|
||||
defaultValueDesc: "default to --tcp-port"
|
||||
name: "udp-port" }: Port
|
||||
|
||||
maxPeers* {.
|
||||
desc: "Maximum number of peers to connect to"
|
||||
defaultValue: 25
|
||||
name: "max-peers" }: int
|
||||
|
||||
nat* {.
|
||||
desc: "Specify method to use for determining public address. " &
|
||||
"Must be one of: any, none, upnp, pmp, extip:<IP>"
|
||||
defaultValue: NatConfig(hasExtIp: false, nat: NatAny)
|
||||
defaultValueDesc: "any"
|
||||
name: "nat" .}: NatConfig
|
||||
|
||||
discovery* {.
|
||||
desc: "Specify method to find suitable peer in an Ethereum network (None, V4, V5)"
|
||||
#[longDesc:
|
||||
"- None: Disables the peer discovery mechanism (manual peer addition)\n" &
|
||||
"- V4 : Node Discovery Protocol v4(default)\n" &
|
||||
"- V5 : Node Discovery Protocol v5"]#
|
||||
defaultValue: DiscoveryType.V4
|
||||
defaultValueDesc: $DiscoveryType.V4
|
||||
name: "discovery" .}: DiscoveryType
|
||||
|
||||
nodeKeyHex* {.
|
||||
desc: "P2P node private key (as 32 bytes hex string)"
|
||||
defaultValue: ""
|
||||
defaultValueDesc: "random"
|
||||
name: "node-key" .}: string
|
||||
|
||||
agentString* {.
|
||||
desc: "Node agent string which is used as identifier in network"
|
||||
defaultValue: NimbusIdent
|
||||
defaultValueDesc: $NimbusIdent
|
||||
name: "agent-string" .}: string
|
||||
|
||||
protocols {.
|
||||
desc: "Enable specific set of protocols (available: Eth, Les)"
|
||||
defaultValue: @[]
|
||||
defaultValueDesc: $ProtocolFlag.Eth
|
||||
name: "protocols" .}: seq[string]
|
||||
|
||||
case cmd* {.
|
||||
command
|
||||
defaultValue: noCommand }: NimbusCmd
|
||||
defaultValue: NimbusCmd.noCommand }: NimbusCmd
|
||||
|
||||
of noCommand:
|
||||
mainnet* {.
|
||||
separator: "\pETHEREUM NETWORK OPTIONS:"
|
||||
defaultValue: false
|
||||
defaultValueDesc: ""
|
||||
desc: "Use Ethereum main network (default)"
|
||||
}: bool
|
||||
|
||||
ropsten* {.
|
||||
desc: "Use Ropsten test network (proof-of-work, the one most like Ethereum mainnet)"
|
||||
defaultValue: false
|
||||
defaultValueDesc: ""
|
||||
}: bool
|
||||
|
||||
rinkeby* {.
|
||||
desc: "Use Rinkeby test network (proof-of-authority, for those running Geth clients)"
|
||||
defaultValue: false
|
||||
defaultValueDesc: ""
|
||||
}: bool
|
||||
|
||||
goerli* {.
|
||||
desc: "Use Görli test network (proof-of-authority, works across all clients)"
|
||||
defaultValue: false
|
||||
defaultValueDesc: ""
|
||||
}: bool
|
||||
|
||||
kovan* {.
|
||||
desc: "Use Kovan test network (proof-of-authority, for those running OpenEthereum clients)"
|
||||
defaultValue: false
|
||||
defaultValueDesc: ""
|
||||
}: bool
|
||||
|
||||
networkId* {.
|
||||
desc: "Network id (1=mainnet, 3=ropsten, 4=rinkeby, 5=goerli, 42=kovan, other=custom)"
|
||||
defaultValueDesc: "mainnet"
|
||||
abbr: "i"
|
||||
name: "network-id" }: Option[NetworkId]
|
||||
|
||||
customNetwork* {.
|
||||
desc: "Use custom genesis block for private Ethereum Network (as /path/to/genesis.json)"
|
||||
defaultValueDesc: ""
|
||||
abbr: "c"
|
||||
name: "custom-network" }: Option[CustomNetwork]
|
||||
|
||||
bootNodes* {.
|
||||
separator: "\pNETWORKING OPTIONS:"
|
||||
desc: "Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers)"
|
||||
defaultValue: EnodeList()
|
||||
defaultValueDesc: ""
|
||||
name: "boot-nodes" }: EnodeList
|
||||
|
||||
bootNodesv4* {.
|
||||
desc: "Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes)"
|
||||
defaultValue: EnodeList()
|
||||
defaultValueDesc: ""
|
||||
name: "boot-nodes-v4" }: EnodeList
|
||||
|
||||
bootNodesv5* {.
|
||||
desc: "Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes)"
|
||||
defaultValue: EnodeList()
|
||||
defaultValueDesc: ""
|
||||
name: "boot-nodes-v5" }: EnodeList
|
||||
|
||||
staticNodes* {.
|
||||
desc: "Comma separated enode URLs to connect with"
|
||||
defaultValue: EnodeList()
|
||||
defaultValueDesc: ""
|
||||
name: "static-nodes" }: EnodeList
|
||||
|
||||
listenAddress* {.
|
||||
desc: "Listening address for the Ethereum P2P and Discovery traffic"
|
||||
defaultValue: defaultListenAddress
|
||||
defaultValueDesc: $defaultListenAddressDesc
|
||||
name: "listen-address" }: ValidIpAddress
|
||||
|
||||
tcpPort* {.
|
||||
desc: "Network listening TCP port"
|
||||
defaultValue: defaultPort
|
||||
defaultValueDesc: $defaultPort
|
||||
name: "tcp-port" }: Port
|
||||
|
||||
udpPort* {.
|
||||
desc: "Network listening UDP port"
|
||||
defaultValue: 0 # set udpPort defaultValue in `makeConfig`
|
||||
defaultValueDesc: "default to --tcp-port"
|
||||
name: "udp-port" }: Port
|
||||
|
||||
maxPeers* {.
|
||||
desc: "The maximum number of peers to connect to"
|
||||
defaultValue: 25
|
||||
name: "max-peers" }: int
|
||||
|
||||
maxEndPeers* {.
|
||||
desc: "Maximum number of pending connection attempts"
|
||||
defaultValue: 0
|
||||
name: "max-end-peers" }: int
|
||||
|
||||
nat* {.
|
||||
desc: "Specify method to use for determining public address. " &
|
||||
"Must be one of: any, none, upnp, pmp, extip:<IP>"
|
||||
defaultValue: NatConfig(hasExtIp: false, nat: NatAny)
|
||||
defaultValueDesc: "any"
|
||||
name: "nat" .}: NatConfig
|
||||
|
||||
noDiscover* {.
|
||||
desc: "Disables the peer discovery mechanism (manual peer addition)"
|
||||
defaultValue: false
|
||||
name: "no-discover" .}: bool
|
||||
|
||||
discv5Enabled* {.
|
||||
desc: "Enable Discovery v5"
|
||||
defaultValue: false
|
||||
name: "discv5" .}: bool
|
||||
|
||||
nodeKeyHex* {.
|
||||
desc: "P2P node private key (as hexadecimal string)"
|
||||
defaultValue: ""
|
||||
defaultValueDesc: "random"
|
||||
name: "node-key" .}: string
|
||||
|
||||
agentString* {.
|
||||
desc: "Node agent string which is used as identifier in network"
|
||||
defaultValue: NimbusIdent
|
||||
defaultValueDesc: $NimbusIdent
|
||||
name: "agent-string" .}: string
|
||||
|
||||
protocols* {.
|
||||
desc: "Enable specific set of protocols (Eth, Les)"
|
||||
defaultValue: Protocols(value: {ProtocolFlag.Eth})
|
||||
defaultValueDesc: $ProtocolFlag.Eth
|
||||
name: "protocols" .}: Protocols
|
||||
|
||||
metricsEnabled* {.
|
||||
separator: "\pLOCAL SERVICE OPTIONS:"
|
||||
desc: "Enable the metrics server"
|
||||
defaultValue: false
|
||||
name: "metrics" }: bool
|
||||
|
||||
metricsPort* {.
|
||||
desc: "Listening HTTP port of the metrics server"
|
||||
defaultValue: defaultMetricsServerPort
|
||||
defaultValueDesc: $defaultMetricsServerPort
|
||||
name: "metrics-port" }: Port
|
||||
|
||||
metricsAddress* {.
|
||||
desc: "Listening address of the metrics server"
|
||||
defaultValue: defaultAdminListenAddress
|
||||
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||
name: "metrics-address" }: ValidIpAddress
|
||||
|
||||
rpcEnabled* {.
|
||||
separator: "\pLOCAL SERVICE OPTIONS:"
|
||||
desc: "Enable the JSON-RPC server"
|
||||
defaultValue: false
|
||||
name: "rpc" }: bool
|
||||
|
||||
rpcPort* {.
|
||||
desc: "Listening HTTP port for the JSON-RPC server"
|
||||
desc: "Listening port of the JSON-RPC server"
|
||||
defaultValue: defaultEthRpcPort
|
||||
defaultValueDesc: $defaultEthRpcPort
|
||||
name: "rpc-port" }: Port
|
||||
|
||||
rpcAddress* {.
|
||||
desc: "Listening address of the RPC server"
|
||||
desc: "Listening IP address of the JSON-RPC server"
|
||||
defaultValue: defaultAdminListenAddress
|
||||
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||
name: "rpc-address" }: ValidIpAddress
|
||||
|
||||
rpcApi* {.
|
||||
desc: "Enable specific set of RPC API from list (comma-separated) (available: eth, debug)"
|
||||
defaultValue: RpcApi(value: {RpcFlag.Eth})
|
||||
rpcApi {.
|
||||
desc: "Enable specific set of RPC API (available: eth, debug)"
|
||||
defaultValue: @[]
|
||||
defaultValueDesc: $RpcFlag.Eth
|
||||
name: "rpc-api" }: RpcApi
|
||||
name: "rpc-api" }: seq[string]
|
||||
|
||||
wsEnabled* {.
|
||||
desc: "Enable the Websocket JSON-RPC server"
|
||||
|
@ -362,60 +341,65 @@ type
|
|||
name: "ws" }: bool
|
||||
|
||||
wsPort* {.
|
||||
desc: "Listening Websocket port for the JSON-RPC server"
|
||||
desc: "Listening port of the Websocket JSON-RPC server"
|
||||
defaultValue: defaultEthWsPort
|
||||
defaultValueDesc: $defaultEthWsPort
|
||||
name: "ws-port" }: Port
|
||||
|
||||
wsAddress* {.
|
||||
desc: "Listening address of the Websocket JSON-RPC server"
|
||||
desc: "Listening IP address of the Websocket JSON-RPC server"
|
||||
defaultValue: defaultAdminListenAddress
|
||||
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||
name: "ws-address" }: ValidIpAddress
|
||||
|
||||
wsApi* {.
|
||||
desc: "Enable specific set of Websocket RPC API from list (comma-separated) (available: eth, debug)"
|
||||
defaultValue: RpcApi(value: {RpcFlag.Eth})
|
||||
wsApi {.
|
||||
desc: "Enable specific set of Websocket RPC API (available: eth, debug)"
|
||||
defaultValue: @[]
|
||||
defaultValueDesc: $RpcFlag.Eth
|
||||
name: "ws-api" }: RpcApi
|
||||
name: "ws-api" }: seq[string]
|
||||
|
||||
graphqlEnabled* {.
|
||||
desc: "Enable the HTTP-GraphQL server"
|
||||
desc: "Enable the GraphQL HTTP server"
|
||||
defaultValue: false
|
||||
name: "graphql" }: bool
|
||||
|
||||
graphqlPort* {.
|
||||
desc: "Listening HTTP port for the GraphQL server"
|
||||
desc: "Listening port of the GraphQL HTTP server"
|
||||
defaultValue: defaultEthGraphqlPort
|
||||
defaultValueDesc: $defaultEthGraphqlPort
|
||||
name: "graphql-port" }: Port
|
||||
|
||||
graphqlAddress* {.
|
||||
desc: "Listening address of the GraphQL server"
|
||||
desc: "Listening IP address of the GraphQL HTTP server"
|
||||
defaultValue: defaultAdminListenAddress
|
||||
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||
name: "graphql-address" }: ValidIpAddress
|
||||
|
||||
logLevel* {.
|
||||
separator: "\pLOGGING AND DEBUGGING OPTIONS:"
|
||||
desc: "Sets the log level for process and topics (" & logLevelDesc & ")"
|
||||
defaultValue: LogLevel.INFO
|
||||
defaultValueDesc: $LogLevel.INFO
|
||||
name: "log-level" }: LogLevel
|
||||
|
||||
logFile* {.
|
||||
desc: "Specifies a path for the written Json log file"
|
||||
name: "log-file" }: Option[OutFile]
|
||||
|
||||
logMetricsEnabled* {.
|
||||
desc: "Enable metrics logging"
|
||||
metricsEnabled* {.
|
||||
desc: "Enable the built-in metrics HTTP server"
|
||||
defaultValue: false
|
||||
name: "log-metrics" .}: bool
|
||||
name: "metrics" }: bool
|
||||
|
||||
metricsPort* {.
|
||||
desc: "Listening port of the built-in metrics HTTP server"
|
||||
defaultValue: defaultMetricsServerPort
|
||||
defaultValueDesc: $defaultMetricsServerPort
|
||||
name: "metrics-port" }: Port
|
||||
|
||||
metricsAddress* {.
|
||||
desc: "Listening IP address of the built-in metrics HTTP server"
|
||||
defaultValue: defaultAdminListenAddress
|
||||
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||
name: "metrics-address" }: ValidIpAddress
|
||||
|
||||
of `import`:
|
||||
|
||||
blocksFile* {.
|
||||
argument
|
||||
desc: "Import RLP encoded block(s) from a file, validate, write to database and quit"
|
||||
defaultValue: ""
|
||||
name: "blocks-file" }: InputFile
|
||||
|
||||
logMetricsInterval* {.
|
||||
desc: "Interval at which to log metrics, in seconds"
|
||||
defaultValue: 10
|
||||
name: "log-metrics-interval" .}: int
|
||||
|
||||
proc parseCmdArg(T: type NetworkId, p: TaintedString): T =
|
||||
parseInt(p.string).T
|
||||
|
@ -439,54 +423,16 @@ proc processList(v: string, o: var seq[string]) =
|
|||
if len(n) > 0:
|
||||
o.add(n)
|
||||
|
||||
proc parseCmdArg(T: type EnodeList, p: TaintedString): T =
|
||||
var list = newSeq[string]()
|
||||
processList(p.string, list)
|
||||
for item in list:
|
||||
let res = ENode.fromString(item)
|
||||
if res.isErr:
|
||||
raise newException(ValueError, "failed to parse EnodeList")
|
||||
result.value.add res.get()
|
||||
|
||||
proc completeCmdArg(T: type EnodeList, val: TaintedString): seq[string] =
|
||||
return @[]
|
||||
|
||||
proc parseCmdArg(T: type Protocols, p: TaintedString): T =
|
||||
var list = newSeq[string]()
|
||||
processList(p.string, list)
|
||||
for item in list:
|
||||
case item.toLowerAscii()
|
||||
of "eth": result.value.incl ProtocolFlag.Eth
|
||||
of "les": result.value.incl ProtocolFlag.Les
|
||||
else:
|
||||
raise newException(ValueError, "unknown protocol: " & item)
|
||||
|
||||
proc completeCmdArg(T: type Protocols, val: TaintedString): seq[string] =
|
||||
return @[]
|
||||
|
||||
proc parseCmdArg(T: type RpcApi, p: TaintedString): T =
|
||||
var list = newSeq[string]()
|
||||
processList(p.string, list)
|
||||
for item in list:
|
||||
case item.toLowerAscii()
|
||||
of "eth": result.value.incl RpcFlag.Eth
|
||||
of "debug": result.value.incl RpcFlag.Debug
|
||||
else:
|
||||
raise newException(ValueError, "unknown rpc api: " & item)
|
||||
|
||||
proc completeCmdArg(T: type RpcApi, val: TaintedString): seq[string] =
|
||||
return @[]
|
||||
|
||||
proc parseCmdArg(T: type CustomNetwork, p: TaintedString): T =
|
||||
proc parseCmdArg(T: type NetworkParams, p: TaintedString): T =
|
||||
try:
|
||||
if not loadCustomNetwork(p.string, result):
|
||||
if not loadNetworkParams(p.string, result):
|
||||
raise newException(ValueError, "failed to load customNetwork")
|
||||
except Exception as exc:
|
||||
# on linux/mac, nim compiler refuse to compile
|
||||
# with unlisted exception error
|
||||
raise newException(ValueError, "failed to load customNetwork")
|
||||
|
||||
proc completeCmdArg(T: type CustomNetwork, val: TaintedString): seq[string] =
|
||||
proc completeCmdArg(T: type NetworkParams, val: TaintedString): seq[string] =
|
||||
return @[]
|
||||
|
||||
proc setBootnodes(output: var seq[ENode], nodeUris: openarray[string]) =
|
||||
|
@ -494,37 +440,131 @@ proc setBootnodes(output: var seq[ENode], nodeUris: openarray[string]) =
|
|||
for item in nodeUris:
|
||||
output.add(ENode.fromString(item).tryGet())
|
||||
|
||||
proc getBootNodes*(conf: NimbusConf): seq[Enode] =
|
||||
if conf.mainnet:
|
||||
result.setBootnodes(MainnetBootnodes)
|
||||
elif conf.ropsten:
|
||||
result.setBootnodes(RopstenBootnodes)
|
||||
elif conf.rinkeby:
|
||||
result.setBootnodes(RinkebyBootnodes)
|
||||
elif conf.goerli:
|
||||
result.setBootnodes(GoerliBootnodes)
|
||||
elif conf.kovan:
|
||||
result.setBootnodes(KovanBootnodes)
|
||||
elif conf.bootnodes.value.len > 0:
|
||||
result = conf.bootnodes.value
|
||||
elif conf.bootnodesv4.value.len > 0:
|
||||
result = conf.bootnodesv4.value
|
||||
elif conf.bootnodesv5.value.len > 0:
|
||||
result = conf.bootnodesv5.value
|
||||
iterator repeatingList(listOfList: openArray[string]): string =
|
||||
for strList in listOfList:
|
||||
var list = newSeq[string]()
|
||||
processList(strList, list)
|
||||
for item in list:
|
||||
yield item
|
||||
|
||||
proc append(output: var seq[ENode], nodeUris: openArray[string]) =
|
||||
for item in repeatingList(nodeUris):
|
||||
let res = ENode.fromString(item)
|
||||
if res.isErr:
|
||||
warn "Ignoring invalid bootstrap address", address=item
|
||||
continue
|
||||
output.add res.get()
|
||||
|
||||
iterator strippedLines(filename: string): (int, string) =
|
||||
var i = 0
|
||||
for line in lines(filename):
|
||||
let stripped = strip(line)
|
||||
if stripped.startsWith('#'): # Comments
|
||||
continue
|
||||
|
||||
if stripped.len > 0:
|
||||
yield (i, stripped)
|
||||
inc i
|
||||
|
||||
proc loadBootstrapFile(fileName: string, output: var seq[Enode]) =
|
||||
if fileName.len == 0:
|
||||
return
|
||||
|
||||
try:
|
||||
for i, ln in strippedLines(fileName):
|
||||
if cmpIgnoreCase(ln, "override") == 0 and i == 0:
|
||||
# override built-in list if the first line is 'override'
|
||||
output = newSeq[ENode]()
|
||||
continue
|
||||
|
||||
let res = ENode.fromString(ln)
|
||||
if res.isErr:
|
||||
warn "Ignoring invalid bootstrap address", address=ln, line=i, file=fileName
|
||||
continue
|
||||
|
||||
output.add res.get()
|
||||
|
||||
except IOError as e:
|
||||
error "Could not read bootstrap file", msg = e.msg
|
||||
quit 1
|
||||
|
||||
proc getNetworkId(conf: NimbusConf): Option[NetworkId] =
|
||||
if conf.mainnet:
|
||||
some MainNet
|
||||
elif conf.ropsten:
|
||||
some RopstenNet
|
||||
elif conf.rinkeby:
|
||||
some RinkebyNet
|
||||
elif conf.goerli:
|
||||
some GoerliNet
|
||||
elif conf.kovan:
|
||||
some KovanNet
|
||||
if conf.network.len == 0:
|
||||
return none NetworkId
|
||||
|
||||
let network = toLowerAscii(conf.network)
|
||||
case network
|
||||
of "mainnet": return some MainNet
|
||||
of "ropsten": return some RopstenNet
|
||||
of "rinkeby": return some RinkebyNet
|
||||
of "goerli" : return some GoerliNet
|
||||
of "kovan" : return some KovanNet
|
||||
else:
|
||||
conf.networkId
|
||||
try:
|
||||
some parseInt(network).NetworkId
|
||||
except CatchableError:
|
||||
error "Failed to parse network name or id", network
|
||||
quit QuitFailure
|
||||
|
||||
proc getProtocolFlags*(conf: NimbusConf): set[ProtocolFlag] =
|
||||
if conf.protocols.len == 0:
|
||||
return {ProtocolFlag.Eth}
|
||||
|
||||
for item in repeatingList(conf.protocols):
|
||||
case item.toLowerAscii()
|
||||
of "eth": result.incl ProtocolFlag.Eth
|
||||
of "les": result.incl ProtocolFlag.Les
|
||||
else:
|
||||
error "Unknown protocol", name=item
|
||||
quit QuitFailure
|
||||
|
||||
proc getRpcFlags(api: openArray[string]): set[RpcFlag] =
|
||||
if api.len == 0:
|
||||
return {RpcFlag.Eth}
|
||||
|
||||
for item in repeatingList(api):
|
||||
case item.toLowerAscii()
|
||||
of "eth": result.incl RpcFlag.Eth
|
||||
of "debug": result.incl RpcFlag.Debug
|
||||
else:
|
||||
error "Unknown RPC API: ", name=item
|
||||
quit QuitFailure
|
||||
|
||||
proc getRpcFlags*(conf: NimbusConf): set[RpcFlag] =
|
||||
getRpcFlags(conf.rpcApi)
|
||||
|
||||
proc getWsFlags*(conf: NimbusConf): set[RpcFlag] =
|
||||
getRpcFlags(conf.wsApi)
|
||||
|
||||
proc getBootNodes*(conf: NimbusConf): seq[Enode] =
|
||||
# Ignore standard bootnodes if customNetwork is loaded
|
||||
if conf.customNetwork.isNone:
|
||||
case conf.networkId
|
||||
of MainNet:
|
||||
result.setBootnodes(MainnetBootnodes)
|
||||
of RopstenNet:
|
||||
result.setBootnodes(RopstenBootnodes)
|
||||
of RinkebyNet:
|
||||
result.setBootnodes(RinkebyBootnodes)
|
||||
of GoerliNet:
|
||||
result.setBootnodes(GoerliBootnodes)
|
||||
of KovanNet:
|
||||
result.setBootnodes(KovanBootnodes)
|
||||
else:
|
||||
# custom network id
|
||||
discard
|
||||
|
||||
# always allow custom boostrap nodes
|
||||
# if it is set by user
|
||||
if conf.bootstrapNodes.len > 0:
|
||||
result.append(conf.bootstrapNodes)
|
||||
|
||||
# bootstrap nodes loaded from file might append or
|
||||
# override built-in bootnodes
|
||||
loadBootstrapFile(string conf.bootstrapFile, result)
|
||||
|
||||
proc getStaticPeers*(conf: NimbusConf): seq[Enode] =
|
||||
result.append(conf.staticPeers)
|
||||
|
||||
proc makeConfig*(cmdLine = commandLineParams()): NimbusConf =
|
||||
{.push warning[ProveInit]: off.}
|
||||
|
@ -535,28 +575,32 @@ proc makeConfig*(cmdLine = commandLineParams()): NimbusConf =
|
|||
)
|
||||
{.pop.}
|
||||
|
||||
result.networkId = result.getNetworkId()
|
||||
var networkId = result.getNetworkId()
|
||||
|
||||
if result.networkId.isNone and result.customNetwork.isSome:
|
||||
# WARNING: networkId and chainId are two distinct things
|
||||
# they usage should not be mixed in other places.
|
||||
# We only set networkId to chainId if networkId not set in cli and
|
||||
# --custom-network is set.
|
||||
# If chainId is not defined in config file, it's ok because
|
||||
# the default networkId `CustomNetwork` has 0 value too.
|
||||
result.networkId = some(NetworkId(result.customNetwork.get().config.chainId))
|
||||
if result.customNetwork.isSome:
|
||||
result.networkParams = result.customNetwork.get()
|
||||
if networkId.isNone:
|
||||
# WARNING: networkId and chainId are two distinct things
|
||||
# they usage should not be mixed in other places.
|
||||
# We only set networkId to chainId if networkId not set in cli and
|
||||
# --custom-network is set.
|
||||
# If chainId is not defined in config file, it's ok because
|
||||
# zero means CustomNet
|
||||
networkId = some(NetworkId(result.networkParams.config.chainId))
|
||||
|
||||
if result.networkId.isNone:
|
||||
if networkId.isNone:
|
||||
# bootnodes is set via getBootNodes
|
||||
result.networkId = some MainNet
|
||||
result.mainnet = true
|
||||
networkId = some MainNet
|
||||
|
||||
if result.udpPort == Port(0):
|
||||
# if udpPort not set in cli, then
|
||||
result.udpPort = result.tcpPort
|
||||
result.networkId = networkId.get()
|
||||
|
||||
if result.customNetwork.isNone:
|
||||
result.customNetwork = some CustomNetwork()
|
||||
result.networkParams = networkParams(result.networkId)
|
||||
|
||||
if result.cmd == noCommand:
|
||||
if result.udpPort == Port(0):
|
||||
# if udpPort not set in cli, then
|
||||
result.udpPort = result.tcpPort
|
||||
|
||||
when isMainModule:
|
||||
# for testing purpose
|
||||
|
|
|
@ -16,9 +16,9 @@ type
|
|||
BaseChainDB* = ref object
|
||||
db* : TrieDatabaseRef
|
||||
pruneTrie*: bool
|
||||
config* : ChainConfig
|
||||
networkId*: NetworkId
|
||||
customNetwork*: CustomNetwork
|
||||
config* : ChainConfig
|
||||
genesis* : Genesis
|
||||
|
||||
# startingBlock, currentBlock, and highestBlock
|
||||
# are progress indicator
|
||||
|
@ -34,14 +34,14 @@ proc newBaseChainDB*(
|
|||
db: TrieDatabaseRef,
|
||||
pruneTrie: bool = true,
|
||||
id: NetworkId = MainNet,
|
||||
cn = CustomNetwork() ): BaseChainDB =
|
||||
params = networkParams(MainNet)): BaseChainDB =
|
||||
|
||||
new(result)
|
||||
result.db = db
|
||||
result.pruneTrie = pruneTrie
|
||||
result.config = chainConfig(id, cn)
|
||||
result.networkId = id
|
||||
result.customNetwork = cn
|
||||
result.config = params.config
|
||||
result.genesis = params.genesis
|
||||
|
||||
proc `$`*(db: BaseChainDB): string =
|
||||
result = "BaseChainDB"
|
||||
|
|
|
@ -1,51 +1,11 @@
|
|||
import
|
||||
std/[times, tables],
|
||||
eth/[common, rlp, trie, p2p], stew/[byteutils],
|
||||
std/tables,
|
||||
eth/[common, rlp, trie, p2p],
|
||||
chronicles, eth/trie/db,
|
||||
./db/[db_chain, state_db],
|
||||
./genesis_alloc, ./constants,
|
||||
./constants,
|
||||
./chain_config, ./forks, ./p2p/gaslimit
|
||||
|
||||
proc genesisBlockForNetwork*(id: NetworkId, cn: CustomNetwork): Genesis =
|
||||
result = case id
|
||||
of MainNet:
|
||||
Genesis(
|
||||
nonce: 66.toBlockNonce,
|
||||
extraData: hexToSeqByte("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
|
||||
gasLimit: 5000,
|
||||
difficulty: 17179869184.u256,
|
||||
alloc: decodePrealloc(mainnetAllocData)
|
||||
)
|
||||
of RopstenNet:
|
||||
Genesis(
|
||||
nonce: 66.toBlockNonce,
|
||||
extraData: hexToSeqByte("0x3535353535353535353535353535353535353535353535353535353535353535"),
|
||||
gasLimit: 16777216,
|
||||
difficulty: 1048576.u256,
|
||||
alloc: decodePrealloc(testnetAllocData)
|
||||
)
|
||||
of RinkebyNet:
|
||||
Genesis(
|
||||
nonce: 0.toBlockNonce,
|
||||
timestamp: initTime(0x58ee40ba, 0),
|
||||
extraData: hexToSeqByte("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
|
||||
gasLimit: 4700000,
|
||||
difficulty: 1.u256,
|
||||
alloc: decodePrealloc(rinkebyAllocData)
|
||||
)
|
||||
of GoerliNet:
|
||||
Genesis(
|
||||
nonce: 0.toBlockNonce,
|
||||
timestamp: initTime(0x5c51a607, 0),
|
||||
extraData: hexToSeqByte("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
|
||||
gasLimit: 0xa00000,
|
||||
difficulty: 1.u256,
|
||||
alloc: decodePrealloc(goerliAllocData)
|
||||
)
|
||||
else:
|
||||
# everything else will use custom genesis
|
||||
cn.genesis
|
||||
|
||||
proc toBlock*(g: Genesis, db: BaseChainDB = nil): BlockHeader =
|
||||
let (tdb, pruneTrie) = if db.isNil: (newMemoryDB(), true)
|
||||
else: (db.db, db.pruneTrie)
|
||||
|
@ -78,18 +38,14 @@ proc toBlock*(g: Genesis, db: BaseChainDB = nil): BlockHeader =
|
|||
elif db.isNil.not and db.config.toFork(0.toBlockNumber) >= FkLondon:
|
||||
result.baseFee = EIP1559_INITIAL_BASE_FEE.u256
|
||||
|
||||
if g.gasLimit == 0:
|
||||
if g.gasLimit.isZero:
|
||||
result.gasLimit = GENESIS_GAS_LIMIT
|
||||
|
||||
if g.difficulty == 0:
|
||||
if g.difficulty.isZero:
|
||||
result.difficulty = GENESIS_DIFFICULTY
|
||||
|
||||
proc commit*(g: Genesis, db: BaseChainDB) =
|
||||
let b = g.toBlock(db)
|
||||
doAssert(b.blockNumber == 0, "can't commit genesis block with number > 0")
|
||||
discard db.persistHeaderToDb(b)
|
||||
|
||||
proc initializeEmptyDb*(db: BaseChainDB) =
|
||||
trace "Writing genesis to DB"
|
||||
let genesis = genesisBlockForNetwork(db.networkId, db.customNetwork)
|
||||
genesis.commit(db)
|
||||
let b = db.genesis.toBlock(db)
|
||||
doAssert(b.blockNumber.isZero, "can't commit genesis block with number > 0")
|
||||
discard db.persistHeaderToDb(b)
|
||||
|
|
|
@ -41,43 +41,17 @@ type
|
|||
wsRpcServer: RpcWebSocketServer
|
||||
sealingEngine: SealingEngineRef
|
||||
ctx: EthContext
|
||||
chainRef: Chain
|
||||
|
||||
template init(T: type RpcHttpServer, ip: ValidIpAddress, port: Port): T =
|
||||
newRpcHttpServer([initTAddress(ip, port)])
|
||||
|
||||
template init(T: type RpcWebSocketServer, ip: ValidIpAddress, port: Port): T =
|
||||
newRpcWebSocketServer(initTAddress(ip, port))
|
||||
|
||||
proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
||||
## logging
|
||||
setLogLevel(conf.logLevel)
|
||||
if conf.logFile.isSome:
|
||||
let logFile = string conf.logFile.get()
|
||||
defaultChroniclesStream.output.outFile = nil # to avoid closing stdout
|
||||
discard defaultChroniclesStream.output.open(logFile, fmAppend)
|
||||
|
||||
createDir(string conf.dataDir)
|
||||
let trieDB = trieDB newChainDb(string conf.dataDir)
|
||||
let networkId = conf.networkId.get()
|
||||
let customNetwork = conf.customNetwork.get()
|
||||
var chainDB = newBaseChainDB(trieDB,
|
||||
conf.pruneMode == PruneMode.Full,
|
||||
networkId,
|
||||
customNetwork
|
||||
)
|
||||
chainDB.populateProgress()
|
||||
|
||||
if canonicalHeadHashKey().toOpenArray notin trieDB:
|
||||
initializeEmptyDb(chainDb)
|
||||
doAssert(canonicalHeadHashKey().toOpenArray in trieDB)
|
||||
|
||||
if string(conf.importBlocks).len > 0:
|
||||
proc importBlocks(conf: NimbusConf, chainDB: BaseChainDB) =
|
||||
if string(conf.blocksFile).len > 0:
|
||||
# success or not, we quit after importing blocks
|
||||
if not importRlpBlock(string conf.importBlocks, chainDB):
|
||||
if not importRlpBlock(string conf.blocksFile, chainDB):
|
||||
quit(QuitFailure)
|
||||
else:
|
||||
quit(QuitSuccess)
|
||||
|
||||
proc manageAccounts(nimbus: NimbusNode, conf: NimbusConf) =
|
||||
if string(conf.keyStore).len > 0:
|
||||
let res = nimbus.ctx.am.loadKeystores(string conf.keyStore)
|
||||
if res.isErr:
|
||||
|
@ -90,17 +64,8 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||
echo res.error()
|
||||
quit(QuitFailure)
|
||||
|
||||
# metrics logging
|
||||
if conf.logMetricsEnabled:
|
||||
# https://github.com/nim-lang/Nim/issues/17369
|
||||
var logMetrics: proc(udata: pointer) {.gcsafe, raises: [Defect].}
|
||||
logMetrics = proc(udata: pointer) =
|
||||
{.gcsafe.}:
|
||||
let registry = defaultRegistry
|
||||
info "metrics", registry
|
||||
discard setTimer(Moment.fromNow(conf.logMetricsInterval.seconds), logMetrics)
|
||||
discard setTimer(Moment.fromNow(conf.logMetricsInterval.seconds), logMetrics)
|
||||
|
||||
proc setupP2P(nimbus: NimbusNode, conf: NimbusConf,
|
||||
chainDB: BaseChainDB, protocols: set[ProtocolFlag]) =
|
||||
## Creating P2P Server
|
||||
let kpres = nimbus.ctx.hexToKeyPair(conf.nodeKeyHex)
|
||||
if kpres.isErr:
|
||||
|
@ -131,33 +96,58 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||
if extPorts.isSome:
|
||||
(address.tcpPort, address.udpPort) = extPorts.get()
|
||||
|
||||
nimbus.ethNode = newEthereumNode(keypair, address, networkId,
|
||||
nimbus.ethNode = newEthereumNode(keypair, address, conf.networkId,
|
||||
nil, conf.agentString,
|
||||
addAllCapabilities = false,
|
||||
minPeers = conf.maxPeers)
|
||||
# Add protocol capabilities based on protocol flags
|
||||
if ProtocolFlag.Eth in conf.protocols.value:
|
||||
if ProtocolFlag.Eth in protocols:
|
||||
nimbus.ethNode.addCapability eth
|
||||
if ProtocolFlag.Les in conf.protocols.value:
|
||||
if ProtocolFlag.Les in protocols:
|
||||
nimbus.ethNode.addCapability les
|
||||
|
||||
# chainRef: some name to avoid module-name/filed/function misunderstandings
|
||||
let chainRef = newChain(chainDB)
|
||||
nimbus.ethNode.chain = chainRef
|
||||
nimbus.chainRef = newChain(chainDB)
|
||||
nimbus.ethNode.chain = nimbus.chainRef
|
||||
if conf.verifyFrom.isSome:
|
||||
let verifyFrom = conf.verifyFrom.get()
|
||||
chainRef.extraValidation = 0 < verifyFrom
|
||||
chainRef.verifyFrom = verifyFrom
|
||||
nimbus.chainRef.extraValidation = 0 < verifyFrom
|
||||
nimbus.chainRef.verifyFrom = verifyFrom
|
||||
|
||||
# Connect directly to the static nodes
|
||||
let staticPeers = conf.getStaticPeers()
|
||||
for enode in staticPeers:
|
||||
asyncCheck nimbus.ethNode.peerPool.connectToNode(newNode(enode))
|
||||
|
||||
# Connect via discovery
|
||||
let bootNodes = conf.getBootNodes()
|
||||
if bootNodes.len > 0:
|
||||
waitFor nimbus.ethNode.connectToNetwork(bootNodes,
|
||||
enableDiscovery = conf.discovery != DiscoveryType.None)
|
||||
|
||||
proc localServices(nimbus: NimbusNode, conf: NimbusConf,
|
||||
chainDB: BaseChainDB, protocols: set[ProtocolFlag]) =
|
||||
# metrics logging
|
||||
if conf.logMetricsEnabled:
|
||||
# https://github.com/nim-lang/Nim/issues/17369
|
||||
var logMetrics: proc(udata: pointer) {.gcsafe, raises: [Defect].}
|
||||
logMetrics = proc(udata: pointer) =
|
||||
{.gcsafe.}:
|
||||
let registry = defaultRegistry
|
||||
info "metrics", registry
|
||||
discard setTimer(Moment.fromNow(conf.logMetricsInterval.seconds), logMetrics)
|
||||
discard setTimer(Moment.fromNow(conf.logMetricsInterval.seconds), logMetrics)
|
||||
|
||||
# Creating RPC Server
|
||||
if conf.rpcEnabled:
|
||||
nimbus.rpcServer = RpcHttpServer.init(conf.rpcAddress, conf.rpcPort)
|
||||
nimbus.rpcServer = newRpcHttpServer([initTAddress(conf.rpcAddress, conf.rpcPort)])
|
||||
setupCommonRpc(nimbus.ethNode, conf, nimbus.rpcServer)
|
||||
|
||||
# Enable RPC APIs based on RPC flags and protocol flags
|
||||
if RpcFlag.Eth in conf.rpcApi.value and ProtocolFlag.Eth in conf.protocols.value:
|
||||
let rpcFlags = conf.getRpcFlags()
|
||||
if RpcFlag.Eth in rpcFlags and ProtocolFlag.Eth in protocols:
|
||||
setupEthRpc(nimbus.ethNode, nimbus.ctx, chainDB, nimbus.rpcServer)
|
||||
if RpcFlag.Debug in conf.rpcApi.value:
|
||||
if RpcFlag.Debug in rpcFlags:
|
||||
setupDebugRpc(chainDB, nimbus.rpcServer)
|
||||
|
||||
nimbus.rpcServer.rpc("admin_quit") do() -> string:
|
||||
|
@ -169,13 +159,14 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||
|
||||
# Creating Websocket RPC Server
|
||||
if conf.wsEnabled:
|
||||
nimbus.wsRpcServer = RpcWebSocketServer.init(conf.wsAddress, conf.wsPort)
|
||||
nimbus.wsRpcServer = newRpcWebSocketServer(initTAddress(conf.wsAddress, conf.wsPort))
|
||||
setupCommonRpc(nimbus.ethNode, conf, nimbus.wsRpcServer)
|
||||
|
||||
# Enable Websocket RPC APIs based on RPC flags and protocol flags
|
||||
if RpcFlag.Eth in conf.wsApi.value and ProtocolFlag.Eth in conf.protocols.value:
|
||||
let wsFlags = conf.getWsFlags()
|
||||
if RpcFlag.Eth in wsFlags and ProtocolFlag.Eth in protocols:
|
||||
setupEthRpc(nimbus.ethNode, nimbus.ctx, chainDB, nimbus.wsRpcServer)
|
||||
if RpcFlag.Debug in conf.wsApi.value:
|
||||
if RpcFlag.Debug in wsFlags:
|
||||
setupDebugRpc(chainDB, nimbus.wsRpcServer)
|
||||
|
||||
nimbus.wsRpcServer.start()
|
||||
|
@ -185,12 +176,12 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||
nimbus.graphqlServer.start()
|
||||
|
||||
if conf.engineSigner != ZERO_ADDRESS:
|
||||
let rs = validateSealer(conf, nimbus.ctx, chainRef)
|
||||
let rs = validateSealer(conf, nimbus.ctx, nimbus.chainRef)
|
||||
if rs.isErr:
|
||||
echo rs.error
|
||||
quit(QuitFailure)
|
||||
nimbus.sealingEngine = SealingEngineRef.new(
|
||||
chainRef, nimbus.ctx, conf.engineSigner
|
||||
nimbus.chainRef, nimbus.ctx, conf.engineSigner
|
||||
)
|
||||
nimbus.sealingEngine.start()
|
||||
|
||||
|
@ -199,31 +190,53 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||
info "Starting metrics HTTP server", address = conf.metricsAddress, port = conf.metricsPort
|
||||
startMetricsHttpServer($conf.metricsAddress, conf.metricsPort)
|
||||
|
||||
# Connect directly to the static nodes
|
||||
for enode in conf.staticNodes.value:
|
||||
asyncCheck nimbus.ethNode.peerPool.connectToNode(newNode(enode))
|
||||
proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
||||
## logging
|
||||
setLogLevel(conf.logLevel)
|
||||
if conf.logFile.isSome:
|
||||
let logFile = string conf.logFile.get()
|
||||
defaultChroniclesStream.output.outFile = nil # to avoid closing stdout
|
||||
discard defaultChroniclesStream.output.open(logFile, fmAppend)
|
||||
|
||||
# Connect via discovery
|
||||
let bootNodes = conf.getBootNodes()
|
||||
waitFor nimbus.ethNode.connectToNetwork(bootNodes,
|
||||
enableDiscovery = not conf.noDiscover)
|
||||
createDir(string conf.dataDir)
|
||||
let trieDB = trieDB newChainDb(string conf.dataDir)
|
||||
var chainDB = newBaseChainDB(trieDB,
|
||||
conf.pruneMode == PruneMode.Full,
|
||||
conf.networkId,
|
||||
conf.networkParams
|
||||
)
|
||||
chainDB.populateProgress()
|
||||
|
||||
if ProtocolFlag.Eth in conf.protocols.value:
|
||||
# TODO: temp code until the CLI/RPC interface is fleshed out
|
||||
let status = waitFor nimbus.ethNode.fastBlockchainSync()
|
||||
if status != syncSuccess:
|
||||
debug "Block sync failed: ", status
|
||||
if canonicalHeadHashKey().toOpenArray notin trieDB:
|
||||
initializeEmptyDb(chainDb)
|
||||
doAssert(canonicalHeadHashKey().toOpenArray in trieDB)
|
||||
|
||||
if nimbus.state == Starting:
|
||||
# it might have been set to "Stopping" with Ctrl+C
|
||||
nimbus.state = Running
|
||||
let protocols = conf.getProtocolFlags()
|
||||
|
||||
case conf.cmd
|
||||
of NimbusCmd.`import`:
|
||||
importBlocks(conf, chainDB)
|
||||
else:
|
||||
manageAccounts(nimbus, conf)
|
||||
setupP2P(nimbus, conf, chainDB, protocols)
|
||||
localServices(nimbus, conf, chainDB, protocols)
|
||||
|
||||
if ProtocolFlag.Eth in protocols:
|
||||
# TODO: temp code until the CLI/RPC interface is fleshed out
|
||||
let status = waitFor nimbus.ethNode.fastBlockchainSync()
|
||||
if status != syncSuccess:
|
||||
debug "Block sync failed: ", status
|
||||
|
||||
if nimbus.state == Starting:
|
||||
# it might have been set to "Stopping" with Ctrl+C
|
||||
nimbus.state = Running
|
||||
|
||||
proc stop*(nimbus: NimbusNode, conf: NimbusConf) {.async, gcsafe.} =
|
||||
trace "Graceful shutdown"
|
||||
if conf.rpcEnabled:
|
||||
nimbus.rpcServer.stop()
|
||||
if conf.wsEnabled:
|
||||
nimbus.wsRpcServer.start()
|
||||
nimbus.wsRpcServer.stop()
|
||||
if conf.graphqlEnabled:
|
||||
await nimbus.graphqlServer.stop()
|
||||
if conf.engineSigner != ZERO_ADDRESS:
|
||||
|
|
|
@ -115,10 +115,9 @@ func calculateForkIds(c: ChainConfig,
|
|||
prevFork = result[fork].nextFork
|
||||
prevCRC = result[fork].crc
|
||||
|
||||
proc setForkId(c: Chain, cn: CustomNetwork)
|
||||
proc setForkId(c: Chain)
|
||||
{. raises: [Defect,CatchableError].} =
|
||||
let g = genesisBlockForNetwork(c.db.networkId, cn)
|
||||
c.blockZeroHash = g.toBlock.blockHash
|
||||
c.blockZeroHash = toBlock(c.db.genesis).blockHash
|
||||
let genesisCRC = crc32(0, c.blockZeroHash.data)
|
||||
c.forkIds = calculateForkIds(c.db.config, genesisCRC)
|
||||
|
||||
|
@ -136,7 +135,7 @@ proc initChain(c: Chain; db: BaseChainDB; poa: Clique; extraValidation: bool)
|
|||
if not db.config.daoForkSupport:
|
||||
db.config.daoForkBlock = db.config.homesteadBlock
|
||||
c.extraValidation = extraValidation
|
||||
c.setForkId(db.customNetwork)
|
||||
c.setForkId()
|
||||
|
||||
# Initalise the PoA state regardless of whether it is needed on the current
|
||||
# network. For non-PoA networks (when `db.config.poaEngine` is `false`),
|
||||
|
|
|
@ -34,7 +34,7 @@ proc setupCommonRPC*(node: EthereumNode, conf: NimbusConf, server: RpcServer) =
|
|||
result = "0x" & $keccak_256.digest(rawdata)
|
||||
|
||||
server.rpc("net_version") do() -> string:
|
||||
result = $conf.networkId.get()
|
||||
result = $conf.networkId
|
||||
|
||||
server.rpc("net_listening") do() -> bool:
|
||||
let numPeers = node.peerPool.connectedNodes.len
|
||||
|
@ -46,8 +46,9 @@ proc setupCommonRPC*(node: EthereumNode, conf: NimbusConf, server: RpcServer) =
|
|||
|
||||
server.rpc("net_nodeInfo") do() -> NodeInfo:
|
||||
let enode = toEnode(node)
|
||||
let nodeId = toNodeId(node.keys.pubkey)
|
||||
result = NodeInfo(
|
||||
id: node.discovery.thisNode.id.toHex,
|
||||
id: nodeId.toHex,
|
||||
name: conf.agentString,
|
||||
enode: $enode,
|
||||
ip: $enode.address.ip,
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303
|
||||
enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303
|
||||
enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303
|
|
@ -0,0 +1,4 @@
|
|||
override
|
||||
enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303
|
||||
enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303
|
||||
enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"config": {
|
||||
"chainId": 1,
|
||||
"homesteadBlock": 0,
|
||||
"eip150Block": 0,
|
||||
"eip158Block": 0,
|
||||
"londonBlock": 1337
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,7 +43,8 @@ type
|
|||
## transactions.
|
||||
prng: Rand
|
||||
accounts: Table[string,PrivateKey] ## accounts table
|
||||
boot: CustomNetwork ## imported Genesis configuration
|
||||
networkId: NetworkId
|
||||
boot: NetworkParams ## imported Genesis configuration
|
||||
batch: seq[seq[BlockHeader]] ## collect header chains
|
||||
chain: Chain
|
||||
|
||||
|
@ -192,15 +193,17 @@ proc initPrettyPrinters(pp: var PrettyPrinters; ap: TesterPool) =
|
|||
|
||||
proc resetChainDb(ap: TesterPool; extraData: Blob; debug = false) =
|
||||
## Setup new block chain with bespoke genesis
|
||||
ap.chain = BaseChainDB(
|
||||
db: newMemoryDb(),
|
||||
config: ap.boot.config).newChain
|
||||
let chainDB = newBaseChainDB(
|
||||
newMemoryDb(),
|
||||
id = ap.networkId,
|
||||
params = ap.boot)
|
||||
ap.chain = newChain(chainDB)
|
||||
ap.chain.clique.db.populateProgress
|
||||
|
||||
# new genesis block
|
||||
var g = ap.boot.genesis
|
||||
if 0 < extraData.len:
|
||||
g.extraData = extraData
|
||||
g.commit(ap.chain.clique.db)
|
||||
chainDB.genesis.extraData = extraData
|
||||
initializeEmptyDB(chainDB)
|
||||
# fine tune Clique descriptor
|
||||
ap.chain.clique.cfg.debug = debug
|
||||
ap.chain.clique.cfg.prettyPrint.initPrettyPrinters(ap)
|
||||
|
@ -242,9 +245,9 @@ proc sayHeaderChain*(ap: TesterPool; indent = 0): TesterPool {.discardable.} =
|
|||
|
||||
proc newVoterPool*(networkId = GoerliNet): TesterPool =
|
||||
TesterPool(
|
||||
boot: CustomNetwork(
|
||||
genesis: genesisBlockForNetwork(networkId, CustomNetwork()),
|
||||
config: chainConfig(networkId, CustomNetwork()))).initTesterPool
|
||||
networkId: networkId,
|
||||
boot: networkParams(networkId)
|
||||
).initTesterPool
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public: getter
|
||||
|
|
|
@ -2,17 +2,20 @@ import
|
|||
std/[os],
|
||||
pkg/[unittest2, confutils],
|
||||
eth/[p2p, common],
|
||||
../nimbus/[config, chain_config]
|
||||
../nimbus/[config, chain_config],
|
||||
./test_helpers
|
||||
|
||||
proc `==`(a, b: ChainId): bool =
|
||||
a.int == b.int
|
||||
|
||||
proc configurationMain*() =
|
||||
suite "configuration test suite":
|
||||
const genesisFile = "tests" / "customgenesis" / "calaveras.json"
|
||||
const
|
||||
genesisFile = "tests" / "customgenesis" / "calaveras.json"
|
||||
bootNode = "enode://a24ac7c5484ef4ed0c5eb2d36620ba4e4aa13b8c84684e1b4aab0cebea2ae45cb4d375b77eab56516d34bfbd3c1a833fc51296ff084b770b94fb9028c4d25ccf@52.169.42.101:30303"
|
||||
|
||||
test "data-dir and key-store":
|
||||
let conf = makeConfig(@[]) # don't use makeConfig default cmdLine from inside all_tests
|
||||
let conf = makeTestConfig()
|
||||
check conf.dataDir.string == defaultDataDir()
|
||||
check conf.keyStore.string == defaultKeystoreDir()
|
||||
|
||||
|
@ -25,7 +28,7 @@ proc configurationMain*() =
|
|||
check dd.keyStore.string == "banana/bin"
|
||||
|
||||
test "prune-mode":
|
||||
let aa = makeConfig(@[])
|
||||
let aa = makeTestConfig()
|
||||
check aa.pruneMode == PruneMode.Full
|
||||
|
||||
let bb = makeConfig(@["--prune-mode:full"])
|
||||
|
@ -38,39 +41,143 @@ proc configurationMain*() =
|
|||
check dd.pruneMode == PruneMode.Archive
|
||||
|
||||
test "import":
|
||||
let aa = makeConfig(@[])
|
||||
check aa.importBlocks.string == ""
|
||||
let aa = makeTestConfig()
|
||||
check aa.cmd == NimbusCmd.noCommand
|
||||
|
||||
let bb = makeConfig(@["--import-blocks:" & genesisFile])
|
||||
check bb.importBlocks.string == genesisFile
|
||||
|
||||
let cc = makeConfig(@["-b:" & genesisFile])
|
||||
check cc.importBlocks.string == genesisFile
|
||||
let bb = makeConfig(@["import", genesisFile])
|
||||
check bb.cmd == NimbusCmd.`import`
|
||||
check bb.blocksFile.string == genesisFile
|
||||
|
||||
test "network-id":
|
||||
let aa = makeConfig(@[])
|
||||
check aa.networkId.get() == MainNet
|
||||
check aa.mainnet == true
|
||||
check aa.customNetwork.get() == CustomNetwork()
|
||||
let aa = makeTestConfig()
|
||||
check aa.networkId == MainNet
|
||||
check aa.networkParams != NetworkParams()
|
||||
|
||||
let conf = makeConfig(@["--custom-network:" & genesisFile, "--network-id:345"])
|
||||
check conf.networkId.get() == 345.NetworkId
|
||||
let conf = makeConfig(@["--custom-network:" & genesisFile, "--network:345"])
|
||||
check conf.networkId == 345.NetworkId
|
||||
|
||||
test "network-id first, custom-network next":
|
||||
let conf = makeConfig(@["--network-id:678", "--custom-network:" & genesisFile])
|
||||
check conf.networkId.get() == 678.NetworkId
|
||||
let conf = makeConfig(@["--network:678", "--custom-network:" & genesisFile])
|
||||
check conf.networkId == 678.NetworkId
|
||||
|
||||
test "network-id set, no custom-network":
|
||||
let conf = makeConfig(@["--network:678"])
|
||||
check conf.networkId == 678.NetworkId
|
||||
check conf.networkParams == NetworkParams()
|
||||
|
||||
test "network-id not set, copy from chainId of customnetwork":
|
||||
let conf = makeConfig(@["--custom-network:" & genesisFile])
|
||||
check conf.networkId.get() == 123.NetworkId
|
||||
check conf.networkId == 123.NetworkId
|
||||
|
||||
test "network-id not set, goerli set":
|
||||
let conf = makeConfig(@["--goerli"])
|
||||
check conf.networkId.get() == GoerliNet
|
||||
let conf = makeConfig(@["--network:goerli"])
|
||||
check conf.networkId == GoerliNet
|
||||
|
||||
test "network-id set, goerli set":
|
||||
let conf = makeConfig(@["--goerli", "--network-id:123"])
|
||||
check conf.networkId.get() == GoerliNet
|
||||
let conf = makeConfig(@["--network:goerli", "--network:123"])
|
||||
check conf.networkId == 123.NetworkId
|
||||
|
||||
test "rpc-api":
|
||||
let conf = makeTestConfig()
|
||||
let flags = conf.getRpcFlags()
|
||||
check RpcFlag.Eth in flags
|
||||
|
||||
let aa = makeConfig(@["--rpc-api:eth"])
|
||||
let ax = aa.getRpcFlags()
|
||||
check RpcFlag.Eth in ax
|
||||
|
||||
let bb = makeConfig(@["--rpc-api:eth", "--rpc-api:debug"])
|
||||
let bx = bb.getRpcFlags()
|
||||
check RpcFlag.Eth in bx
|
||||
check RpcFlag.Debug in bx
|
||||
|
||||
let cc = makeConfig(@["--rpc-api:eth,debug"])
|
||||
let cx = cc.getRpcFlags()
|
||||
check RpcFlag.Eth in cx
|
||||
check RpcFlag.Debug in cx
|
||||
|
||||
test "ws-api":
|
||||
let conf = makeTestConfig()
|
||||
let flags = conf.getWsFlags()
|
||||
check RpcFlag.Eth in flags
|
||||
|
||||
let aa = makeConfig(@["--ws-api:eth"])
|
||||
let ax = aa.getWsFlags()
|
||||
check RpcFlag.Eth in ax
|
||||
|
||||
let bb = makeConfig(@["--ws-api:eth", "--ws-api:debug"])
|
||||
let bx = bb.getWsFlags()
|
||||
check RpcFlag.Eth in bx
|
||||
check RpcFlag.Debug in bx
|
||||
|
||||
let cc = makeConfig(@["--ws-api:eth,debug"])
|
||||
let cx = cc.getWsFlags()
|
||||
check RpcFlag.Eth in cx
|
||||
check RpcFlag.Debug in cx
|
||||
|
||||
test "protocols":
|
||||
let conf = makeTestConfig()
|
||||
let flags = conf.getProtocolFlags()
|
||||
check ProtocolFlag.Eth in flags
|
||||
|
||||
let aa = makeConfig(@["--protocols:les"])
|
||||
let ax = aa.getProtocolFlags()
|
||||
check ProtocolFlag.Les in ax
|
||||
|
||||
let bb = makeConfig(@["--protocols:eth", "--protocols:les"])
|
||||
let bx = bb.getProtocolFlags()
|
||||
check ProtocolFlag.Eth in bx
|
||||
check ProtocolFlag.Les in bx
|
||||
|
||||
let cc = makeConfig(@["--protocols:eth,les"])
|
||||
let cx = cc.getProtocolFlags()
|
||||
check ProtocolFlag.Eth in cx
|
||||
check ProtocolFlag.Les in cx
|
||||
|
||||
test "bootstrap-node and bootstrap-file":
|
||||
let conf = makeTestConfig()
|
||||
let bootnodes = conf.getBootnodes()
|
||||
let bootNodeLen = bootnodes.len
|
||||
check bootNodeLen > 0 # mainnet bootnodes
|
||||
|
||||
let aa = makeConfig(@["--bootstrap-node:" & bootNode])
|
||||
let ax = aa.getBootNodes()
|
||||
check ax.len == bootNodeLen + 1
|
||||
|
||||
const
|
||||
bootFilePath = "tests" / "bootstrap"
|
||||
bootFileAppend = bootFilePath / "append_bootnodes.txt"
|
||||
bootFileOverride = bootFilePath / "override_bootnodes.txt"
|
||||
|
||||
let bb = makeConfig(@["--bootstrap-file:" & bootFileAppend])
|
||||
let bx = bb.getBootNodes()
|
||||
check bx.len == bootNodeLen + 3
|
||||
|
||||
let cc = makeConfig(@["--bootstrap-file:" & bootFileOverride])
|
||||
let cx = cc.getBootNodes()
|
||||
check cx.len == 3
|
||||
|
||||
test "static-peers":
|
||||
let conf = makeTestConfig()
|
||||
check conf.getStaticPeers().len == 0
|
||||
|
||||
let aa = makeConfig(@["--static-peers:" & bootNode])
|
||||
check aa.getStaticPeers().len == 1
|
||||
|
||||
let bb = makeConfig(@["--static-peers:" & bootNode & "," & bootNode])
|
||||
check bb.getStaticPeers().len == 2
|
||||
|
||||
let cc = makeConfig(@["--static-peers:" & bootNode, "--static-peers:" & bootNode])
|
||||
check cc.getStaticPeers().len == 2
|
||||
|
||||
test "chainId of custom-network is oneof std network":
|
||||
const
|
||||
chainid1 = "tests" / "customgenesis" / "chainid1.json"
|
||||
|
||||
let conf = makeConfig(@["--custom-network:" & chainid1])
|
||||
check conf.networkId == 1.NetworkId
|
||||
check conf.networkParams.config.londonBlock == 1337
|
||||
check conf.getBootnodes().len == 0
|
||||
|
||||
when isMainModule:
|
||||
configurationMain()
|
||||
|
|
|
@ -60,11 +60,11 @@ template runTests(name: string, hex: bool, calculator: typed) =
|
|||
check diff == t.currentDifficulty
|
||||
|
||||
proc difficultyMain*() =
|
||||
let mainnetConfig = chainConfig(MainNet, CustomNetwork())
|
||||
let mainnetConfig = networkParams(MainNet).config
|
||||
func calcDifficultyMainNetWork(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
|
||||
mainnetConfig.calcDifficulty(timeStamp, parent)
|
||||
|
||||
let ropstenConfig = chainConfig(RopstenNet, CustomNetwork())
|
||||
let ropstenConfig = networkParams(RopstenNet).config
|
||||
func calcDifficultyRopsten(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
|
||||
ropstenConfig.calcDifficulty(timeStamp, parent)
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ template runTest(network: untyped) =
|
|||
test `network`.astToStr:
|
||||
var
|
||||
memDB = newMemoryDB()
|
||||
chainDB = newBaseChainDB(memDB, true, network)
|
||||
chainDB = newBaseChainDB(memDB, true, network, networkParams(network))
|
||||
chain = newChain(chainDB)
|
||||
|
||||
for x in `network IDs`:
|
||||
|
|
|
@ -8,39 +8,39 @@ const dataFolder = "tests" / "customgenesis"
|
|||
proc genesisTest() =
|
||||
suite "Genesis":
|
||||
test "Correct mainnet hash":
|
||||
let g = genesisBlockForNetwork(MainNet, CustomNetwork())
|
||||
let g = networkParams(MainNet).genesis
|
||||
let b = g.toBlock
|
||||
check(b.blockHash == "D4E56740F876AEF8C010B86A40D5F56745A118D0906A34E69AEC8C0DB1CB8FA3".toDigest)
|
||||
|
||||
test "Correct ropstennet hash":
|
||||
let g = genesisBlockForNetwork(RopstenNet, CustomNetwork())
|
||||
let g = networkParams(RopstenNet).genesis
|
||||
let b = g.toBlock
|
||||
check(b.blockHash == "41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d".toDigest)
|
||||
|
||||
test "Correct rinkebynet hash":
|
||||
let g = genesisBlockForNetwork(RinkebyNet, CustomNetwork())
|
||||
let g = networkParams(RinkebyNet).genesis
|
||||
let b = g.toBlock
|
||||
check(b.blockHash == "6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177".toDigest)
|
||||
|
||||
test "Correct goerlinet hash":
|
||||
let g = genesisBlockForNetwork(GoerliNet, CustomNetwork())
|
||||
let g = networkParams(GoerliNet).genesis
|
||||
let b = g.toBlock
|
||||
check(b.blockHash == "bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a".toDigest)
|
||||
|
||||
proc customGenesisTest() =
|
||||
suite "Custom Genesis":
|
||||
test "loadCustomGenesis":
|
||||
var cga, cgb, cgc: CustomNetwork
|
||||
check loadCustomNetwork(dataFolder / "berlin2000.json", cga)
|
||||
check loadCustomNetwork(dataFolder / "chainid7.json", cgb)
|
||||
check loadCustomNetwork(dataFolder / "noconfig.json", cgc)
|
||||
var cga, cgb, cgc: NetworkParams
|
||||
check loadNetworkParams(dataFolder / "berlin2000.json", cga)
|
||||
check loadNetworkParams(dataFolder / "chainid7.json", cgb)
|
||||
check loadNetworkParams(dataFolder / "noconfig.json", cgc)
|
||||
check cga.config.poaEngine == false
|
||||
check cgb.config.poaEngine == false
|
||||
check cgc.config.poaEngine == false
|
||||
|
||||
test "calaveras.json":
|
||||
var cg: CustomNetwork
|
||||
check loadCustomNetwork(dataFolder / "calaveras.json", cg)
|
||||
var cg: NetworkParams
|
||||
check loadNetworkParams(dataFolder / "calaveras.json", cg)
|
||||
let h = toBlock(cg.genesis, nil)
|
||||
let stateRoot = "664c93de37eb4a72953ea42b8c046cdb64c9f0b0bca5505ade8d970d49ebdb8c".toDigest
|
||||
let genesisHash = "eb9233d066c275efcdfed8037f4fc082770176aefdbcb7691c71da412a5670f2".toDigest
|
||||
|
|
|
@ -63,7 +63,7 @@ proc setupChain(): BaseChainDB =
|
|||
if not parseGenesisAlloc($(jn["pre"]), genesis.alloc):
|
||||
quit(QuitFailure)
|
||||
|
||||
let customNetwork = CustomNetwork(
|
||||
let customNetwork = NetworkParams(
|
||||
config: config,
|
||||
genesis: genesis
|
||||
)
|
||||
|
@ -95,7 +95,7 @@ proc setupChain(): BaseChainDB =
|
|||
|
||||
proc graphqlMain*() =
|
||||
let
|
||||
conf = makeConfig(@[]) # don't use makeConfig default cmdLine from inside all_tests
|
||||
conf = makeTestConfig()
|
||||
ethCtx = newEthContext()
|
||||
ethNode = setupEthNode(conf, ethCtx, eth)
|
||||
chainDB = setupChain()
|
||||
|
|
|
@ -275,13 +275,17 @@ proc hashLogEntries*(logs: seq[Log]): string =
|
|||
proc setupEthNode*(conf: NimbusConf, ctx: EthContext, capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode =
|
||||
let keypair = ctx.hexToKeyPair(conf.nodeKeyHex).tryGet()
|
||||
var srvAddress: Address
|
||||
srvAddress.ip = parseIpAddress("0.0.0.0")
|
||||
srvAddress.ip = conf.listenAddress
|
||||
srvAddress.tcpPort = conf.tcpPort
|
||||
srvAddress.udpPort = conf.udpPort
|
||||
result = newEthereumNode(
|
||||
keypair, srvAddress,
|
||||
conf.networkId.get(),
|
||||
conf.networkId,
|
||||
nil, conf.agentString,
|
||||
addAllCapabilities = false)
|
||||
for capability in capabilities:
|
||||
result.addCapability capability
|
||||
|
||||
proc makeTestConfig*(): NimbusConf =
|
||||
# commandLineParams() will not works inside all_tests
|
||||
makeConfig(@[])
|
||||
|
|
|
@ -124,14 +124,14 @@ proc rpcMain*() =
|
|||
suite "Remote Procedure Calls":
|
||||
# TODO: Include other transports such as Http
|
||||
let
|
||||
conf = makeConfig(@[]) # don't use makeConfig default cmdLine from inside all_tests
|
||||
conf = makeTestConfig()
|
||||
ctx = newEthContext()
|
||||
ethNode = setupEthNode(conf, ctx, eth)
|
||||
chain = newBaseChainDB(
|
||||
newMemoryDb(),
|
||||
conf.pruneMode == PruneMode.Full,
|
||||
conf.networkId.get(),
|
||||
conf.customNetwork.get()
|
||||
conf.networkId,
|
||||
conf.networkParams
|
||||
)
|
||||
signer: EthAddress = hexToByteArray[20]("0x0e69cde81b1aa07a45c32c6cd85d67229d36bb1b")
|
||||
ks2: EthAddress = hexToByteArray[20]("0xa3b2222afa5c987da6ef773fde8d01b9f23d481f")
|
||||
|
@ -182,7 +182,7 @@ proc rpcMain*() =
|
|||
|
||||
test "net_version":
|
||||
let res = await client.net_version()
|
||||
check res == $conf.networkId.get()
|
||||
check res == $conf.networkId
|
||||
|
||||
test "net_listening":
|
||||
let res = await client.net_listening()
|
||||
|
|
|
@ -45,7 +45,7 @@ proc main() {.used.} =
|
|||
# 52029 first block with receipts logs
|
||||
# 66407 failed transaction
|
||||
|
||||
# nimbus --rpcapi: eth, debug --prune: archive
|
||||
# nimbus --rpc-api: eth, debug --prune: archive
|
||||
|
||||
var conf = makeConfig()
|
||||
let db = newChainDb(string conf.dataDir)
|
||||
|
|
Loading…
Reference in New Issue