mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-24 17:58:30 +00:00
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 =
|
proc genesisToTrie(filePath: string): HexaryTrie =
|
||||||
# TODO: Doing our best here with API that exists, to be improved.
|
# TODO: Doing our best here with API that exists, to be improved.
|
||||||
var cn: CustomNetwork
|
var cn: NetworkParams
|
||||||
if not loadCustomNetwork(filePath, cn):
|
if not loadNetworkParams(filePath, cn):
|
||||||
quit(1)
|
quit(1)
|
||||||
|
|
||||||
var chainDB = newBaseChainDB(
|
var chainDB = newBaseChainDB(
|
||||||
|
@ -21,8 +21,8 @@ proc processNode(genesisFile, chainFile,
|
|||||||
conf = makeConfig(@["--customnetwork:" & genesisFile])
|
conf = makeConfig(@["--customnetwork:" & genesisFile])
|
||||||
chainDB = newBaseChainDB(newMemoryDb(),
|
chainDB = newBaseChainDB(newMemoryDb(),
|
||||||
pruneTrie = false,
|
pruneTrie = false,
|
||||||
conf.networkId.get,
|
conf.networkId,
|
||||||
conf.customNetwork.get()
|
conf.networkParams
|
||||||
)
|
)
|
||||||
|
|
||||||
initializeEmptyDb(chainDB)
|
initializeEmptyDb(chainDB)
|
||||||
|
@ -67,13 +67,13 @@ proc processNode(ctx: GraphqlRef, node: JsonNode, fileName: string, testStatusIM
|
|||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
let
|
let
|
||||||
conf = makeConfig(@["--customnetwork:" & genesisFile])
|
conf = makeConfig(@["--custom-network:" & genesisFile])
|
||||||
ethCtx = newEthContext()
|
ethCtx = newEthContext()
|
||||||
ethNode = setupEthNode(conf, ethCtx, eth)
|
ethNode = setupEthNode(conf, ethCtx, eth)
|
||||||
chainDB = newBaseChainDB(newMemoryDb(),
|
chainDB = newBaseChainDB(newMemoryDb(),
|
||||||
pruneTrie = false,
|
pruneTrie = false,
|
||||||
conf.networkId.get,
|
conf.networkId,
|
||||||
conf.customNetwork.get
|
conf.networkParams
|
||||||
)
|
)
|
||||||
|
|
||||||
initializeEmptyDb(chainDB)
|
initializeEmptyDb(chainDB)
|
||||||
|
@ -15,7 +15,7 @@ import
|
|||||||
json_serialization/std/options as jsoptions,
|
json_serialization/std/options as jsoptions,
|
||||||
json_serialization/std/tables as jstable,
|
json_serialization/std/tables as jstable,
|
||||||
json_serialization/lexer,
|
json_serialization/lexer,
|
||||||
./forks
|
"."/[forks, genesis_alloc]
|
||||||
|
|
||||||
type
|
type
|
||||||
CliqueOptions = object
|
CliqueOptions = object
|
||||||
@ -83,7 +83,7 @@ type
|
|||||||
balance*: UInt256
|
balance*: UInt256
|
||||||
nonce* : AccountNonce
|
nonce* : AccountNonce
|
||||||
|
|
||||||
CustomNetwork* = object
|
NetworkParams* = object
|
||||||
config* : ChainConfig
|
config* : ChainConfig
|
||||||
genesis*: Genesis
|
genesis*: Genesis
|
||||||
|
|
||||||
@ -159,19 +159,19 @@ template to(a: string, b: type UInt256): UInt256 =
|
|||||||
# json_serialization decode table stuff
|
# json_serialization decode table stuff
|
||||||
UInt256.fromHex(a)
|
UInt256.fromHex(a)
|
||||||
|
|
||||||
proc loadCustomNetwork*(fileName: string, cg: var CustomNetwork): bool =
|
proc loadNetworkParams*(fileName: string, cg: var NetworkParams): bool =
|
||||||
var cc: CustomChain
|
var cc: CustomChain
|
||||||
try:
|
try:
|
||||||
cc = Json.loadFile(fileName, CustomChain, allowUnknownFields = true)
|
cc = Json.loadFile(fileName, CustomChain, allowUnknownFields = true)
|
||||||
except IOError as e:
|
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
|
return false
|
||||||
except JsonReaderError as e:
|
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
|
return false
|
||||||
except:
|
except:
|
||||||
var msg = getCurrentExceptionMsg()
|
var msg = getCurrentExceptionMsg()
|
||||||
error "Error loading genesis block config file", fileName, msg
|
error "Error loading network params file", fileName, msg
|
||||||
return false
|
return false
|
||||||
|
|
||||||
cg.genesis = cc.genesis
|
cg.genesis = cc.genesis
|
||||||
@ -237,14 +237,14 @@ proc toFork*(c: ChainConfig, number: BlockNumber): Fork =
|
|||||||
elif number >= c.homesteadBlock: FkHomestead
|
elif number >= c.homesteadBlock: FkHomestead
|
||||||
else: FkFrontier
|
else: FkFrontier
|
||||||
|
|
||||||
proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
proc chainConfigForNetwork(id: NetworkId): 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
|
||||||
|
|
||||||
result = case id
|
result = case id
|
||||||
of MainNet:
|
of MainNet:
|
||||||
ChainConfig(
|
ChainConfig(
|
||||||
poaEngine: false, # TODO: use real engine conf: PoW
|
poaEngine: false,
|
||||||
chainId: MainNet.ChainId,
|
chainId: MainNet.ChainId,
|
||||||
homesteadBlock: 1_150_000.toBlockNumber, # 14/03/2016 20:49:53
|
homesteadBlock: 1_150_000.toBlockNumber, # 14/03/2016 20:49:53
|
||||||
daoForkBlock: 1_920_000.toBlockNumber,
|
daoForkBlock: 1_920_000.toBlockNumber,
|
||||||
@ -263,7 +263,7 @@ proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
|||||||
)
|
)
|
||||||
of RopstenNet:
|
of RopstenNet:
|
||||||
ChainConfig(
|
ChainConfig(
|
||||||
poaEngine: false, # TODO: use real engine conf: PoW
|
poaEngine: false,
|
||||||
chainId: RopstenNet.ChainId,
|
chainId: RopstenNet.ChainId,
|
||||||
homesteadBlock: 0.toBlockNumber,
|
homesteadBlock: 0.toBlockNumber,
|
||||||
daoForkSupport: false,
|
daoForkSupport: false,
|
||||||
@ -281,7 +281,7 @@ proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
|||||||
)
|
)
|
||||||
of RinkebyNet:
|
of RinkebyNet:
|
||||||
ChainConfig(
|
ChainConfig(
|
||||||
poaEngine: true, # TODO: use real engine conf: PoA
|
poaEngine: true,
|
||||||
chainId: RinkebyNet.ChainId,
|
chainId: RinkebyNet.ChainId,
|
||||||
homesteadBlock: 1.toBlockNumber,
|
homesteadBlock: 1.toBlockNumber,
|
||||||
daoForkSupport: false,
|
daoForkSupport: false,
|
||||||
@ -299,7 +299,7 @@ proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
|||||||
)
|
)
|
||||||
of GoerliNet:
|
of GoerliNet:
|
||||||
ChainConfig(
|
ChainConfig(
|
||||||
poaEngine: true, # TODO: use real engine conf: PoA
|
poaEngine: true,
|
||||||
chainId: GoerliNet.ChainId,
|
chainId: GoerliNet.ChainId,
|
||||||
homesteadBlock: 0.toBlockNumber,
|
homesteadBlock: 0.toBlockNumber,
|
||||||
daoForkSupport: false,
|
daoForkSupport: false,
|
||||||
@ -316,6 +316,47 @@ proc chainConfig*(id: NetworkId, cn: CustomNetwork): ChainConfig =
|
|||||||
londonBlock: 5_062_605.toBlockNumber # June 30, 2021
|
londonBlock: 5_062_605.toBlockNumber # June 30, 2021
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# everything else will use CustomNet config
|
ChainConfig()
|
||||||
trace "Custom genesis block configuration loaded", conf=cn.config
|
|
||||||
cn.config
|
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
|
# Nimbus
|
||||||
# Copyright (c) 2021 Status Research & Development GmbH
|
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
@ -10,6 +10,7 @@
|
|||||||
import
|
import
|
||||||
std/[options, strutils, times, os],
|
std/[options, strutils, times, os],
|
||||||
pkg/[
|
pkg/[
|
||||||
|
chronicles,
|
||||||
confutils,
|
confutils,
|
||||||
confutils/defs,
|
confutils/defs,
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
@ -21,6 +22,8 @@ import
|
|||||||
constants, vm_compile_info
|
constants, vm_compile_info
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export stewNet
|
||||||
|
|
||||||
const
|
const
|
||||||
NimbusName* = "nimbus-eth1"
|
NimbusName* = "nimbus-eth1"
|
||||||
## project name string
|
## project name string
|
||||||
@ -41,6 +44,8 @@ const
|
|||||||
|
|
||||||
NimVersion = staticExec("nim --version").strip()
|
NimVersion = staticExec("nim --version").strip()
|
||||||
|
|
||||||
|
# TODO: fix this agent-string format to match other
|
||||||
|
# eth clients format
|
||||||
NimbusIdent* = "$# v$# [$#: $#, $#, $#, $#]" % [
|
NimbusIdent* = "$# v$# [$#: $#, $#, $#, $#]" % [
|
||||||
NimbusName,
|
NimbusName,
|
||||||
NimbusVersion,
|
NimbusVersion,
|
||||||
@ -99,8 +104,8 @@ const
|
|||||||
defaultEthGraphqlPort = 8547
|
defaultEthGraphqlPort = 8547
|
||||||
defaultListenAddress = (static ValidIpAddress.init("0.0.0.0"))
|
defaultListenAddress = (static ValidIpAddress.init("0.0.0.0"))
|
||||||
defaultAdminListenAddress = (static ValidIpAddress.init("127.0.0.1"))
|
defaultAdminListenAddress = (static ValidIpAddress.init("127.0.0.1"))
|
||||||
defaultListenAddressDesc = $defaultListenAddress
|
defaultListenAddressDesc = $defaultListenAddress & ", meaning all network interfaces"
|
||||||
defaultAdminListenAddressDesc = $defaultAdminListenAddress
|
defaultAdminListenAddressDesc = $defaultAdminListenAddress & ", meaning local host only"
|
||||||
logLevelDesc = getLogLevels()
|
logLevelDesc = getLogLevels()
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -108,8 +113,9 @@ type
|
|||||||
Full
|
Full
|
||||||
Archive
|
Archive
|
||||||
|
|
||||||
NimbusCmd* = enum
|
NimbusCmd* {.pure.} = enum
|
||||||
noCommand
|
noCommand
|
||||||
|
`import`
|
||||||
|
|
||||||
ProtocolFlag* {.pure.} = enum
|
ProtocolFlag* {.pure.} = enum
|
||||||
## Protocol flags
|
## Protocol flags
|
||||||
@ -121,14 +127,10 @@ type
|
|||||||
Eth ## enable eth_ set of RPC API
|
Eth ## enable eth_ set of RPC API
|
||||||
Debug ## enable debug_ set of RPC API
|
Debug ## enable debug_ set of RPC API
|
||||||
|
|
||||||
EnodeList* = object
|
DiscoveryType* {.pure.} = enum
|
||||||
value*: seq[Enode]
|
None
|
||||||
|
V4
|
||||||
Protocols* = object
|
V5
|
||||||
value*: set[ProtocolFlag]
|
|
||||||
|
|
||||||
RpcApi* = object
|
|
||||||
value*: set[RpcFlag]
|
|
||||||
|
|
||||||
NimbusConf* = object of RootObj
|
NimbusConf* = object of RootObj
|
||||||
## Main Nimbus configuration object
|
## Main Nimbus configuration object
|
||||||
@ -142,7 +144,7 @@ type
|
|||||||
name: "data-dir" }: OutDir
|
name: "data-dir" }: OutDir
|
||||||
|
|
||||||
keyStore* {.
|
keyStore* {.
|
||||||
desc: "Directory for the keystore files"
|
desc: "Load one or more keystore files from this directory"
|
||||||
defaultValue: defaultKeystoreDir()
|
defaultValue: defaultKeystoreDir()
|
||||||
defaultValueDesc: "inside datadir"
|
defaultValueDesc: "inside datadir"
|
||||||
abbr: "k"
|
abbr: "k"
|
||||||
@ -155,20 +157,15 @@ type
|
|||||||
abbr : "p"
|
abbr : "p"
|
||||||
name: "prune-mode" }: PruneMode
|
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* {.
|
importKey* {.
|
||||||
desc: "Import unencrypted 32 bytes hex private key file"
|
desc: "Import unencrypted 32 bytes hex private key from a file"
|
||||||
defaultValue: ""
|
defaultValue: ""
|
||||||
abbr: "e"
|
abbr: "e"
|
||||||
name: "import-key" }: InputFile
|
name: "import-key" }: InputFile
|
||||||
|
|
||||||
engineSigner* {.
|
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
|
defaultValue: ZERO_ADDRESS
|
||||||
defaultValueDesc: ""
|
defaultValueDesc: ""
|
||||||
abbr: "s"
|
abbr: "s"
|
||||||
@ -179,182 +176,164 @@ type
|
|||||||
defaultValueDesc: ""
|
defaultValueDesc: ""
|
||||||
name: "verify-from" }: Option[uint64]
|
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* {.
|
case cmd* {.
|
||||||
command
|
command
|
||||||
defaultValue: noCommand }: NimbusCmd
|
defaultValue: NimbusCmd.noCommand }: NimbusCmd
|
||||||
|
|
||||||
of noCommand:
|
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* {.
|
rpcEnabled* {.
|
||||||
|
separator: "\pLOCAL SERVICE OPTIONS:"
|
||||||
desc: "Enable the JSON-RPC server"
|
desc: "Enable the JSON-RPC server"
|
||||||
defaultValue: false
|
defaultValue: false
|
||||||
name: "rpc" }: bool
|
name: "rpc" }: bool
|
||||||
|
|
||||||
rpcPort* {.
|
rpcPort* {.
|
||||||
desc: "Listening HTTP port for the JSON-RPC server"
|
desc: "Listening port of the JSON-RPC server"
|
||||||
defaultValue: defaultEthRpcPort
|
defaultValue: defaultEthRpcPort
|
||||||
defaultValueDesc: $defaultEthRpcPort
|
defaultValueDesc: $defaultEthRpcPort
|
||||||
name: "rpc-port" }: Port
|
name: "rpc-port" }: Port
|
||||||
|
|
||||||
rpcAddress* {.
|
rpcAddress* {.
|
||||||
desc: "Listening address of the RPC server"
|
desc: "Listening IP address of the JSON-RPC server"
|
||||||
defaultValue: defaultAdminListenAddress
|
defaultValue: defaultAdminListenAddress
|
||||||
defaultValueDesc: $defaultAdminListenAddressDesc
|
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||||
name: "rpc-address" }: ValidIpAddress
|
name: "rpc-address" }: ValidIpAddress
|
||||||
|
|
||||||
rpcApi* {.
|
rpcApi {.
|
||||||
desc: "Enable specific set of RPC API from list (comma-separated) (available: eth, debug)"
|
desc: "Enable specific set of RPC API (available: eth, debug)"
|
||||||
defaultValue: RpcApi(value: {RpcFlag.Eth})
|
defaultValue: @[]
|
||||||
defaultValueDesc: $RpcFlag.Eth
|
defaultValueDesc: $RpcFlag.Eth
|
||||||
name: "rpc-api" }: RpcApi
|
name: "rpc-api" }: seq[string]
|
||||||
|
|
||||||
wsEnabled* {.
|
wsEnabled* {.
|
||||||
desc: "Enable the Websocket JSON-RPC server"
|
desc: "Enable the Websocket JSON-RPC server"
|
||||||
@ -362,60 +341,65 @@ type
|
|||||||
name: "ws" }: bool
|
name: "ws" }: bool
|
||||||
|
|
||||||
wsPort* {.
|
wsPort* {.
|
||||||
desc: "Listening Websocket port for the JSON-RPC server"
|
desc: "Listening port of the Websocket JSON-RPC server"
|
||||||
defaultValue: defaultEthWsPort
|
defaultValue: defaultEthWsPort
|
||||||
defaultValueDesc: $defaultEthWsPort
|
defaultValueDesc: $defaultEthWsPort
|
||||||
name: "ws-port" }: Port
|
name: "ws-port" }: Port
|
||||||
|
|
||||||
wsAddress* {.
|
wsAddress* {.
|
||||||
desc: "Listening address of the Websocket JSON-RPC server"
|
desc: "Listening IP address of the Websocket JSON-RPC server"
|
||||||
defaultValue: defaultAdminListenAddress
|
defaultValue: defaultAdminListenAddress
|
||||||
defaultValueDesc: $defaultAdminListenAddressDesc
|
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||||
name: "ws-address" }: ValidIpAddress
|
name: "ws-address" }: ValidIpAddress
|
||||||
|
|
||||||
wsApi* {.
|
wsApi {.
|
||||||
desc: "Enable specific set of Websocket RPC API from list (comma-separated) (available: eth, debug)"
|
desc: "Enable specific set of Websocket RPC API (available: eth, debug)"
|
||||||
defaultValue: RpcApi(value: {RpcFlag.Eth})
|
defaultValue: @[]
|
||||||
defaultValueDesc: $RpcFlag.Eth
|
defaultValueDesc: $RpcFlag.Eth
|
||||||
name: "ws-api" }: RpcApi
|
name: "ws-api" }: seq[string]
|
||||||
|
|
||||||
graphqlEnabled* {.
|
graphqlEnabled* {.
|
||||||
desc: "Enable the HTTP-GraphQL server"
|
desc: "Enable the GraphQL HTTP server"
|
||||||
defaultValue: false
|
defaultValue: false
|
||||||
name: "graphql" }: bool
|
name: "graphql" }: bool
|
||||||
|
|
||||||
graphqlPort* {.
|
graphqlPort* {.
|
||||||
desc: "Listening HTTP port for the GraphQL server"
|
desc: "Listening port of the GraphQL HTTP server"
|
||||||
defaultValue: defaultEthGraphqlPort
|
defaultValue: defaultEthGraphqlPort
|
||||||
defaultValueDesc: $defaultEthGraphqlPort
|
defaultValueDesc: $defaultEthGraphqlPort
|
||||||
name: "graphql-port" }: Port
|
name: "graphql-port" }: Port
|
||||||
|
|
||||||
graphqlAddress* {.
|
graphqlAddress* {.
|
||||||
desc: "Listening address of the GraphQL server"
|
desc: "Listening IP address of the GraphQL HTTP server"
|
||||||
defaultValue: defaultAdminListenAddress
|
defaultValue: defaultAdminListenAddress
|
||||||
defaultValueDesc: $defaultAdminListenAddressDesc
|
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||||
name: "graphql-address" }: ValidIpAddress
|
name: "graphql-address" }: ValidIpAddress
|
||||||
|
|
||||||
logLevel* {.
|
metricsEnabled* {.
|
||||||
separator: "\pLOGGING AND DEBUGGING OPTIONS:"
|
desc: "Enable the built-in metrics HTTP server"
|
||||||
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
|
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 =
|
proc parseCmdArg(T: type NetworkId, p: TaintedString): T =
|
||||||
parseInt(p.string).T
|
parseInt(p.string).T
|
||||||
@ -439,54 +423,16 @@ proc processList(v: string, o: var seq[string]) =
|
|||||||
if len(n) > 0:
|
if len(n) > 0:
|
||||||
o.add(n)
|
o.add(n)
|
||||||
|
|
||||||
proc parseCmdArg(T: type EnodeList, p: TaintedString): T =
|
proc parseCmdArg(T: type NetworkParams, 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 =
|
|
||||||
try:
|
try:
|
||||||
if not loadCustomNetwork(p.string, result):
|
if not loadNetworkParams(p.string, result):
|
||||||
raise newException(ValueError, "failed to load customNetwork")
|
raise newException(ValueError, "failed to load customNetwork")
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
# on linux/mac, nim compiler refuse to compile
|
# on linux/mac, nim compiler refuse to compile
|
||||||
# with unlisted exception error
|
# with unlisted exception error
|
||||||
raise newException(ValueError, "failed to load customNetwork")
|
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 @[]
|
return @[]
|
||||||
|
|
||||||
proc setBootnodes(output: var seq[ENode], nodeUris: openarray[string]) =
|
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:
|
for item in nodeUris:
|
||||||
output.add(ENode.fromString(item).tryGet())
|
output.add(ENode.fromString(item).tryGet())
|
||||||
|
|
||||||
proc getBootNodes*(conf: NimbusConf): seq[Enode] =
|
iterator repeatingList(listOfList: openArray[string]): string =
|
||||||
if conf.mainnet:
|
for strList in listOfList:
|
||||||
result.setBootnodes(MainnetBootnodes)
|
var list = newSeq[string]()
|
||||||
elif conf.ropsten:
|
processList(strList, list)
|
||||||
result.setBootnodes(RopstenBootnodes)
|
for item in list:
|
||||||
elif conf.rinkeby:
|
yield item
|
||||||
result.setBootnodes(RinkebyBootnodes)
|
|
||||||
elif conf.goerli:
|
proc append(output: var seq[ENode], nodeUris: openArray[string]) =
|
||||||
result.setBootnodes(GoerliBootnodes)
|
for item in repeatingList(nodeUris):
|
||||||
elif conf.kovan:
|
let res = ENode.fromString(item)
|
||||||
result.setBootnodes(KovanBootnodes)
|
if res.isErr:
|
||||||
elif conf.bootnodes.value.len > 0:
|
warn "Ignoring invalid bootstrap address", address=item
|
||||||
result = conf.bootnodes.value
|
continue
|
||||||
elif conf.bootnodesv4.value.len > 0:
|
output.add res.get()
|
||||||
result = conf.bootnodesv4.value
|
|
||||||
elif conf.bootnodesv5.value.len > 0:
|
iterator strippedLines(filename: string): (int, string) =
|
||||||
result = conf.bootnodesv5.value
|
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] =
|
proc getNetworkId(conf: NimbusConf): Option[NetworkId] =
|
||||||
if conf.mainnet:
|
if conf.network.len == 0:
|
||||||
some MainNet
|
return none NetworkId
|
||||||
elif conf.ropsten:
|
|
||||||
some RopstenNet
|
let network = toLowerAscii(conf.network)
|
||||||
elif conf.rinkeby:
|
case network
|
||||||
some RinkebyNet
|
of "mainnet": return some MainNet
|
||||||
elif conf.goerli:
|
of "ropsten": return some RopstenNet
|
||||||
some GoerliNet
|
of "rinkeby": return some RinkebyNet
|
||||||
elif conf.kovan:
|
of "goerli" : return some GoerliNet
|
||||||
some KovanNet
|
of "kovan" : return some KovanNet
|
||||||
else:
|
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 =
|
proc makeConfig*(cmdLine = commandLineParams()): NimbusConf =
|
||||||
{.push warning[ProveInit]: off.}
|
{.push warning[ProveInit]: off.}
|
||||||
@ -535,28 +575,32 @@ proc makeConfig*(cmdLine = commandLineParams()): NimbusConf =
|
|||||||
)
|
)
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
result.networkId = result.getNetworkId()
|
var networkId = result.getNetworkId()
|
||||||
|
|
||||||
if result.networkId.isNone and result.customNetwork.isSome:
|
if result.customNetwork.isSome:
|
||||||
# WARNING: networkId and chainId are two distinct things
|
result.networkParams = result.customNetwork.get()
|
||||||
# they usage should not be mixed in other places.
|
if networkId.isNone:
|
||||||
# We only set networkId to chainId if networkId not set in cli and
|
# WARNING: networkId and chainId are two distinct things
|
||||||
# --custom-network is set.
|
# they usage should not be mixed in other places.
|
||||||
# If chainId is not defined in config file, it's ok because
|
# We only set networkId to chainId if networkId not set in cli and
|
||||||
# the default networkId `CustomNetwork` has 0 value too.
|
# --custom-network is set.
|
||||||
result.networkId = some(NetworkId(result.customNetwork.get().config.chainId))
|
# 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
|
# bootnodes is set via getBootNodes
|
||||||
result.networkId = some MainNet
|
networkId = some MainNet
|
||||||
result.mainnet = true
|
|
||||||
|
|
||||||
if result.udpPort == Port(0):
|
result.networkId = networkId.get()
|
||||||
# if udpPort not set in cli, then
|
|
||||||
result.udpPort = result.tcpPort
|
|
||||||
|
|
||||||
if result.customNetwork.isNone:
|
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:
|
when isMainModule:
|
||||||
# for testing purpose
|
# for testing purpose
|
||||||
|
@ -16,9 +16,9 @@ type
|
|||||||
BaseChainDB* = ref object
|
BaseChainDB* = ref object
|
||||||
db* : TrieDatabaseRef
|
db* : TrieDatabaseRef
|
||||||
pruneTrie*: bool
|
pruneTrie*: bool
|
||||||
config* : ChainConfig
|
|
||||||
networkId*: NetworkId
|
networkId*: NetworkId
|
||||||
customNetwork*: CustomNetwork
|
config* : ChainConfig
|
||||||
|
genesis* : Genesis
|
||||||
|
|
||||||
# startingBlock, currentBlock, and highestBlock
|
# startingBlock, currentBlock, and highestBlock
|
||||||
# are progress indicator
|
# are progress indicator
|
||||||
@ -34,14 +34,14 @@ proc newBaseChainDB*(
|
|||||||
db: TrieDatabaseRef,
|
db: TrieDatabaseRef,
|
||||||
pruneTrie: bool = true,
|
pruneTrie: bool = true,
|
||||||
id: NetworkId = MainNet,
|
id: NetworkId = MainNet,
|
||||||
cn = CustomNetwork() ): BaseChainDB =
|
params = networkParams(MainNet)): BaseChainDB =
|
||||||
|
|
||||||
new(result)
|
new(result)
|
||||||
result.db = db
|
result.db = db
|
||||||
result.pruneTrie = pruneTrie
|
result.pruneTrie = pruneTrie
|
||||||
result.config = chainConfig(id, cn)
|
|
||||||
result.networkId = id
|
result.networkId = id
|
||||||
result.customNetwork = cn
|
result.config = params.config
|
||||||
|
result.genesis = params.genesis
|
||||||
|
|
||||||
proc `$`*(db: BaseChainDB): string =
|
proc `$`*(db: BaseChainDB): string =
|
||||||
result = "BaseChainDB"
|
result = "BaseChainDB"
|
||||||
|
@ -1,51 +1,11 @@
|
|||||||
import
|
import
|
||||||
std/[times, tables],
|
std/tables,
|
||||||
eth/[common, rlp, trie, p2p], stew/[byteutils],
|
eth/[common, rlp, trie, p2p],
|
||||||
chronicles, eth/trie/db,
|
chronicles, eth/trie/db,
|
||||||
./db/[db_chain, state_db],
|
./db/[db_chain, state_db],
|
||||||
./genesis_alloc, ./constants,
|
./constants,
|
||||||
./chain_config, ./forks, ./p2p/gaslimit
|
./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 =
|
proc toBlock*(g: Genesis, db: BaseChainDB = nil): BlockHeader =
|
||||||
let (tdb, pruneTrie) = if db.isNil: (newMemoryDB(), true)
|
let (tdb, pruneTrie) = if db.isNil: (newMemoryDB(), true)
|
||||||
else: (db.db, db.pruneTrie)
|
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:
|
elif db.isNil.not and db.config.toFork(0.toBlockNumber) >= FkLondon:
|
||||||
result.baseFee = EIP1559_INITIAL_BASE_FEE.u256
|
result.baseFee = EIP1559_INITIAL_BASE_FEE.u256
|
||||||
|
|
||||||
if g.gasLimit == 0:
|
if g.gasLimit.isZero:
|
||||||
result.gasLimit = GENESIS_GAS_LIMIT
|
result.gasLimit = GENESIS_GAS_LIMIT
|
||||||
|
|
||||||
if g.difficulty == 0:
|
if g.difficulty.isZero:
|
||||||
result.difficulty = GENESIS_DIFFICULTY
|
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) =
|
proc initializeEmptyDb*(db: BaseChainDB) =
|
||||||
trace "Writing genesis to DB"
|
trace "Writing genesis to DB"
|
||||||
let genesis = genesisBlockForNetwork(db.networkId, db.customNetwork)
|
let b = db.genesis.toBlock(db)
|
||||||
genesis.commit(db)
|
doAssert(b.blockNumber.isZero, "can't commit genesis block with number > 0")
|
||||||
|
discard db.persistHeaderToDb(b)
|
||||||
|
@ -41,43 +41,17 @@ type
|
|||||||
wsRpcServer: RpcWebSocketServer
|
wsRpcServer: RpcWebSocketServer
|
||||||
sealingEngine: SealingEngineRef
|
sealingEngine: SealingEngineRef
|
||||||
ctx: EthContext
|
ctx: EthContext
|
||||||
|
chainRef: Chain
|
||||||
|
|
||||||
template init(T: type RpcHttpServer, ip: ValidIpAddress, port: Port): T =
|
proc importBlocks(conf: NimbusConf, chainDB: BaseChainDB) =
|
||||||
newRpcHttpServer([initTAddress(ip, port)])
|
if string(conf.blocksFile).len > 0:
|
||||||
|
|
||||||
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:
|
|
||||||
# success or not, we quit after importing blocks
|
# success or not, we quit after importing blocks
|
||||||
if not importRlpBlock(string conf.importBlocks, chainDB):
|
if not importRlpBlock(string conf.blocksFile, chainDB):
|
||||||
quit(QuitFailure)
|
quit(QuitFailure)
|
||||||
else:
|
else:
|
||||||
quit(QuitSuccess)
|
quit(QuitSuccess)
|
||||||
|
|
||||||
|
proc manageAccounts(nimbus: NimbusNode, conf: NimbusConf) =
|
||||||
if string(conf.keyStore).len > 0:
|
if string(conf.keyStore).len > 0:
|
||||||
let res = nimbus.ctx.am.loadKeystores(string conf.keyStore)
|
let res = nimbus.ctx.am.loadKeystores(string conf.keyStore)
|
||||||
if res.isErr:
|
if res.isErr:
|
||||||
@ -90,17 +64,8 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||||||
echo res.error()
|
echo res.error()
|
||||||
quit(QuitFailure)
|
quit(QuitFailure)
|
||||||
|
|
||||||
# metrics logging
|
proc setupP2P(nimbus: NimbusNode, conf: NimbusConf,
|
||||||
if conf.logMetricsEnabled:
|
chainDB: BaseChainDB, protocols: set[ProtocolFlag]) =
|
||||||
# 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 P2P Server
|
## Creating P2P Server
|
||||||
let kpres = nimbus.ctx.hexToKeyPair(conf.nodeKeyHex)
|
let kpres = nimbus.ctx.hexToKeyPair(conf.nodeKeyHex)
|
||||||
if kpres.isErr:
|
if kpres.isErr:
|
||||||
@ -131,33 +96,58 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||||||
if extPorts.isSome:
|
if extPorts.isSome:
|
||||||
(address.tcpPort, address.udpPort) = extPorts.get()
|
(address.tcpPort, address.udpPort) = extPorts.get()
|
||||||
|
|
||||||
nimbus.ethNode = newEthereumNode(keypair, address, networkId,
|
nimbus.ethNode = newEthereumNode(keypair, address, conf.networkId,
|
||||||
nil, conf.agentString,
|
nil, conf.agentString,
|
||||||
addAllCapabilities = false,
|
addAllCapabilities = false,
|
||||||
minPeers = conf.maxPeers)
|
minPeers = conf.maxPeers)
|
||||||
# Add protocol capabilities based on protocol flags
|
# Add protocol capabilities based on protocol flags
|
||||||
if ProtocolFlag.Eth in conf.protocols.value:
|
if ProtocolFlag.Eth in protocols:
|
||||||
nimbus.ethNode.addCapability eth
|
nimbus.ethNode.addCapability eth
|
||||||
if ProtocolFlag.Les in conf.protocols.value:
|
if ProtocolFlag.Les in protocols:
|
||||||
nimbus.ethNode.addCapability les
|
nimbus.ethNode.addCapability les
|
||||||
|
|
||||||
# chainRef: some name to avoid module-name/filed/function misunderstandings
|
# chainRef: some name to avoid module-name/filed/function misunderstandings
|
||||||
let chainRef = newChain(chainDB)
|
nimbus.chainRef = newChain(chainDB)
|
||||||
nimbus.ethNode.chain = chainRef
|
nimbus.ethNode.chain = nimbus.chainRef
|
||||||
if conf.verifyFrom.isSome:
|
if conf.verifyFrom.isSome:
|
||||||
let verifyFrom = conf.verifyFrom.get()
|
let verifyFrom = conf.verifyFrom.get()
|
||||||
chainRef.extraValidation = 0 < verifyFrom
|
nimbus.chainRef.extraValidation = 0 < verifyFrom
|
||||||
chainRef.verifyFrom = 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
|
# Creating RPC Server
|
||||||
if conf.rpcEnabled:
|
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)
|
setupCommonRpc(nimbus.ethNode, conf, nimbus.rpcServer)
|
||||||
|
|
||||||
# Enable RPC APIs based on RPC flags and protocol flags
|
# 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)
|
setupEthRpc(nimbus.ethNode, nimbus.ctx, chainDB, nimbus.rpcServer)
|
||||||
if RpcFlag.Debug in conf.rpcApi.value:
|
if RpcFlag.Debug in rpcFlags:
|
||||||
setupDebugRpc(chainDB, nimbus.rpcServer)
|
setupDebugRpc(chainDB, nimbus.rpcServer)
|
||||||
|
|
||||||
nimbus.rpcServer.rpc("admin_quit") do() -> string:
|
nimbus.rpcServer.rpc("admin_quit") do() -> string:
|
||||||
@ -169,13 +159,14 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||||||
|
|
||||||
# Creating Websocket RPC Server
|
# Creating Websocket RPC Server
|
||||||
if conf.wsEnabled:
|
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)
|
setupCommonRpc(nimbus.ethNode, conf, nimbus.wsRpcServer)
|
||||||
|
|
||||||
# Enable Websocket RPC APIs based on RPC flags and protocol flags
|
# 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)
|
setupEthRpc(nimbus.ethNode, nimbus.ctx, chainDB, nimbus.wsRpcServer)
|
||||||
if RpcFlag.Debug in conf.wsApi.value:
|
if RpcFlag.Debug in wsFlags:
|
||||||
setupDebugRpc(chainDB, nimbus.wsRpcServer)
|
setupDebugRpc(chainDB, nimbus.wsRpcServer)
|
||||||
|
|
||||||
nimbus.wsRpcServer.start()
|
nimbus.wsRpcServer.start()
|
||||||
@ -185,12 +176,12 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||||||
nimbus.graphqlServer.start()
|
nimbus.graphqlServer.start()
|
||||||
|
|
||||||
if conf.engineSigner != ZERO_ADDRESS:
|
if conf.engineSigner != ZERO_ADDRESS:
|
||||||
let rs = validateSealer(conf, nimbus.ctx, chainRef)
|
let rs = validateSealer(conf, nimbus.ctx, nimbus.chainRef)
|
||||||
if rs.isErr:
|
if rs.isErr:
|
||||||
echo rs.error
|
echo rs.error
|
||||||
quit(QuitFailure)
|
quit(QuitFailure)
|
||||||
nimbus.sealingEngine = SealingEngineRef.new(
|
nimbus.sealingEngine = SealingEngineRef.new(
|
||||||
chainRef, nimbus.ctx, conf.engineSigner
|
nimbus.chainRef, nimbus.ctx, conf.engineSigner
|
||||||
)
|
)
|
||||||
nimbus.sealingEngine.start()
|
nimbus.sealingEngine.start()
|
||||||
|
|
||||||
@ -199,31 +190,53 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
|||||||
info "Starting metrics HTTP server", address = conf.metricsAddress, port = conf.metricsPort
|
info "Starting metrics HTTP server", address = conf.metricsAddress, port = conf.metricsPort
|
||||||
startMetricsHttpServer($conf.metricsAddress, conf.metricsPort)
|
startMetricsHttpServer($conf.metricsAddress, conf.metricsPort)
|
||||||
|
|
||||||
# Connect directly to the static nodes
|
proc start(nimbus: NimbusNode, conf: NimbusConf) =
|
||||||
for enode in conf.staticNodes.value:
|
## logging
|
||||||
asyncCheck nimbus.ethNode.peerPool.connectToNode(newNode(enode))
|
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
|
createDir(string conf.dataDir)
|
||||||
let bootNodes = conf.getBootNodes()
|
let trieDB = trieDB newChainDb(string conf.dataDir)
|
||||||
waitFor nimbus.ethNode.connectToNetwork(bootNodes,
|
var chainDB = newBaseChainDB(trieDB,
|
||||||
enableDiscovery = not conf.noDiscover)
|
conf.pruneMode == PruneMode.Full,
|
||||||
|
conf.networkId,
|
||||||
|
conf.networkParams
|
||||||
|
)
|
||||||
|
chainDB.populateProgress()
|
||||||
|
|
||||||
if ProtocolFlag.Eth in conf.protocols.value:
|
if canonicalHeadHashKey().toOpenArray notin trieDB:
|
||||||
# TODO: temp code until the CLI/RPC interface is fleshed out
|
initializeEmptyDb(chainDb)
|
||||||
let status = waitFor nimbus.ethNode.fastBlockchainSync()
|
doAssert(canonicalHeadHashKey().toOpenArray in trieDB)
|
||||||
if status != syncSuccess:
|
|
||||||
debug "Block sync failed: ", status
|
|
||||||
|
|
||||||
if nimbus.state == Starting:
|
let protocols = conf.getProtocolFlags()
|
||||||
# it might have been set to "Stopping" with Ctrl+C
|
|
||||||
nimbus.state = Running
|
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.} =
|
proc stop*(nimbus: NimbusNode, conf: NimbusConf) {.async, gcsafe.} =
|
||||||
trace "Graceful shutdown"
|
trace "Graceful shutdown"
|
||||||
if conf.rpcEnabled:
|
if conf.rpcEnabled:
|
||||||
nimbus.rpcServer.stop()
|
nimbus.rpcServer.stop()
|
||||||
if conf.wsEnabled:
|
if conf.wsEnabled:
|
||||||
nimbus.wsRpcServer.start()
|
nimbus.wsRpcServer.stop()
|
||||||
if conf.graphqlEnabled:
|
if conf.graphqlEnabled:
|
||||||
await nimbus.graphqlServer.stop()
|
await nimbus.graphqlServer.stop()
|
||||||
if conf.engineSigner != ZERO_ADDRESS:
|
if conf.engineSigner != ZERO_ADDRESS:
|
||||||
|
@ -115,10 +115,9 @@ func calculateForkIds(c: ChainConfig,
|
|||||||
prevFork = result[fork].nextFork
|
prevFork = result[fork].nextFork
|
||||||
prevCRC = result[fork].crc
|
prevCRC = result[fork].crc
|
||||||
|
|
||||||
proc setForkId(c: Chain, cn: CustomNetwork)
|
proc setForkId(c: Chain)
|
||||||
{. raises: [Defect,CatchableError].} =
|
{. raises: [Defect,CatchableError].} =
|
||||||
let g = genesisBlockForNetwork(c.db.networkId, cn)
|
c.blockZeroHash = toBlock(c.db.genesis).blockHash
|
||||||
c.blockZeroHash = g.toBlock.blockHash
|
|
||||||
let genesisCRC = crc32(0, c.blockZeroHash.data)
|
let genesisCRC = crc32(0, c.blockZeroHash.data)
|
||||||
c.forkIds = calculateForkIds(c.db.config, genesisCRC)
|
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:
|
if not db.config.daoForkSupport:
|
||||||
db.config.daoForkBlock = db.config.homesteadBlock
|
db.config.daoForkBlock = db.config.homesteadBlock
|
||||||
c.extraValidation = extraValidation
|
c.extraValidation = extraValidation
|
||||||
c.setForkId(db.customNetwork)
|
c.setForkId()
|
||||||
|
|
||||||
# Initalise the PoA state regardless of whether it is needed on the current
|
# Initalise the PoA state regardless of whether it is needed on the current
|
||||||
# network. For non-PoA networks (when `db.config.poaEngine` is `false`),
|
# 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)
|
result = "0x" & $keccak_256.digest(rawdata)
|
||||||
|
|
||||||
server.rpc("net_version") do() -> string:
|
server.rpc("net_version") do() -> string:
|
||||||
result = $conf.networkId.get()
|
result = $conf.networkId
|
||||||
|
|
||||||
server.rpc("net_listening") do() -> bool:
|
server.rpc("net_listening") do() -> bool:
|
||||||
let numPeers = node.peerPool.connectedNodes.len
|
let numPeers = node.peerPool.connectedNodes.len
|
||||||
@ -46,8 +46,9 @@ proc setupCommonRPC*(node: EthereumNode, conf: NimbusConf, server: RpcServer) =
|
|||||||
|
|
||||||
server.rpc("net_nodeInfo") do() -> NodeInfo:
|
server.rpc("net_nodeInfo") do() -> NodeInfo:
|
||||||
let enode = toEnode(node)
|
let enode = toEnode(node)
|
||||||
|
let nodeId = toNodeId(node.keys.pubkey)
|
||||||
result = NodeInfo(
|
result = NodeInfo(
|
||||||
id: node.discovery.thisNode.id.toHex,
|
id: nodeId.toHex,
|
||||||
name: conf.agentString,
|
name: conf.agentString,
|
||||||
enode: $enode,
|
enode: $enode,
|
||||||
ip: $enode.address.ip,
|
ip: $enode.address.ip,
|
||||||
|
3
tests/bootstrap/append_bootnodes.txt
Normal file
3
tests/bootstrap/append_bootnodes.txt
Normal file
@ -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
|
4
tests/bootstrap/override_bootnodes.txt
Normal file
4
tests/bootstrap/override_bootnodes.txt
Normal file
@ -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
|
46
tests/customgenesis/chainid1.json
Normal file
46
tests/customgenesis/chainid1.json
Normal file
@ -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.
|
## transactions.
|
||||||
prng: Rand
|
prng: Rand
|
||||||
accounts: Table[string,PrivateKey] ## accounts table
|
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
|
batch: seq[seq[BlockHeader]] ## collect header chains
|
||||||
chain: Chain
|
chain: Chain
|
||||||
|
|
||||||
@ -192,15 +193,17 @@ proc initPrettyPrinters(pp: var PrettyPrinters; ap: TesterPool) =
|
|||||||
|
|
||||||
proc resetChainDb(ap: TesterPool; extraData: Blob; debug = false) =
|
proc resetChainDb(ap: TesterPool; extraData: Blob; debug = false) =
|
||||||
## Setup new block chain with bespoke genesis
|
## Setup new block chain with bespoke genesis
|
||||||
ap.chain = BaseChainDB(
|
let chainDB = newBaseChainDB(
|
||||||
db: newMemoryDb(),
|
newMemoryDb(),
|
||||||
config: ap.boot.config).newChain
|
id = ap.networkId,
|
||||||
|
params = ap.boot)
|
||||||
|
ap.chain = newChain(chainDB)
|
||||||
ap.chain.clique.db.populateProgress
|
ap.chain.clique.db.populateProgress
|
||||||
|
|
||||||
# new genesis block
|
# new genesis block
|
||||||
var g = ap.boot.genesis
|
|
||||||
if 0 < extraData.len:
|
if 0 < extraData.len:
|
||||||
g.extraData = extraData
|
chainDB.genesis.extraData = extraData
|
||||||
g.commit(ap.chain.clique.db)
|
initializeEmptyDB(chainDB)
|
||||||
# fine tune Clique descriptor
|
# fine tune Clique descriptor
|
||||||
ap.chain.clique.cfg.debug = debug
|
ap.chain.clique.cfg.debug = debug
|
||||||
ap.chain.clique.cfg.prettyPrint.initPrettyPrinters(ap)
|
ap.chain.clique.cfg.prettyPrint.initPrettyPrinters(ap)
|
||||||
@ -242,9 +245,9 @@ proc sayHeaderChain*(ap: TesterPool; indent = 0): TesterPool {.discardable.} =
|
|||||||
|
|
||||||
proc newVoterPool*(networkId = GoerliNet): TesterPool =
|
proc newVoterPool*(networkId = GoerliNet): TesterPool =
|
||||||
TesterPool(
|
TesterPool(
|
||||||
boot: CustomNetwork(
|
networkId: networkId,
|
||||||
genesis: genesisBlockForNetwork(networkId, CustomNetwork()),
|
boot: networkParams(networkId)
|
||||||
config: chainConfig(networkId, CustomNetwork()))).initTesterPool
|
).initTesterPool
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public: getter
|
# Public: getter
|
||||||
|
@ -2,17 +2,20 @@ import
|
|||||||
std/[os],
|
std/[os],
|
||||||
pkg/[unittest2, confutils],
|
pkg/[unittest2, confutils],
|
||||||
eth/[p2p, common],
|
eth/[p2p, common],
|
||||||
../nimbus/[config, chain_config]
|
../nimbus/[config, chain_config],
|
||||||
|
./test_helpers
|
||||||
|
|
||||||
proc `==`(a, b: ChainId): bool =
|
proc `==`(a, b: ChainId): bool =
|
||||||
a.int == b.int
|
a.int == b.int
|
||||||
|
|
||||||
proc configurationMain*() =
|
proc configurationMain*() =
|
||||||
suite "configuration test suite":
|
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":
|
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.dataDir.string == defaultDataDir()
|
||||||
check conf.keyStore.string == defaultKeystoreDir()
|
check conf.keyStore.string == defaultKeystoreDir()
|
||||||
|
|
||||||
@ -25,7 +28,7 @@ proc configurationMain*() =
|
|||||||
check dd.keyStore.string == "banana/bin"
|
check dd.keyStore.string == "banana/bin"
|
||||||
|
|
||||||
test "prune-mode":
|
test "prune-mode":
|
||||||
let aa = makeConfig(@[])
|
let aa = makeTestConfig()
|
||||||
check aa.pruneMode == PruneMode.Full
|
check aa.pruneMode == PruneMode.Full
|
||||||
|
|
||||||
let bb = makeConfig(@["--prune-mode:full"])
|
let bb = makeConfig(@["--prune-mode:full"])
|
||||||
@ -38,39 +41,143 @@ proc configurationMain*() =
|
|||||||
check dd.pruneMode == PruneMode.Archive
|
check dd.pruneMode == PruneMode.Archive
|
||||||
|
|
||||||
test "import":
|
test "import":
|
||||||
let aa = makeConfig(@[])
|
let aa = makeTestConfig()
|
||||||
check aa.importBlocks.string == ""
|
check aa.cmd == NimbusCmd.noCommand
|
||||||
|
|
||||||
let bb = makeConfig(@["--import-blocks:" & genesisFile])
|
let bb = makeConfig(@["import", genesisFile])
|
||||||
check bb.importBlocks.string == genesisFile
|
check bb.cmd == NimbusCmd.`import`
|
||||||
|
check bb.blocksFile.string == genesisFile
|
||||||
let cc = makeConfig(@["-b:" & genesisFile])
|
|
||||||
check cc.importBlocks.string == genesisFile
|
|
||||||
|
|
||||||
test "network-id":
|
test "network-id":
|
||||||
let aa = makeConfig(@[])
|
let aa = makeTestConfig()
|
||||||
check aa.networkId.get() == MainNet
|
check aa.networkId == MainNet
|
||||||
check aa.mainnet == true
|
check aa.networkParams != NetworkParams()
|
||||||
check aa.customNetwork.get() == CustomNetwork()
|
|
||||||
|
|
||||||
let conf = makeConfig(@["--custom-network:" & genesisFile, "--network-id:345"])
|
let conf = makeConfig(@["--custom-network:" & genesisFile, "--network:345"])
|
||||||
check conf.networkId.get() == 345.NetworkId
|
check conf.networkId == 345.NetworkId
|
||||||
|
|
||||||
test "network-id first, custom-network next":
|
test "network-id first, custom-network next":
|
||||||
let conf = makeConfig(@["--network-id:678", "--custom-network:" & genesisFile])
|
let conf = makeConfig(@["--network:678", "--custom-network:" & genesisFile])
|
||||||
check conf.networkId.get() == 678.NetworkId
|
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":
|
test "network-id not set, copy from chainId of customnetwork":
|
||||||
let conf = makeConfig(@["--custom-network:" & genesisFile])
|
let conf = makeConfig(@["--custom-network:" & genesisFile])
|
||||||
check conf.networkId.get() == 123.NetworkId
|
check conf.networkId == 123.NetworkId
|
||||||
|
|
||||||
test "network-id not set, goerli set":
|
test "network-id not set, goerli set":
|
||||||
let conf = makeConfig(@["--goerli"])
|
let conf = makeConfig(@["--network:goerli"])
|
||||||
check conf.networkId.get() == GoerliNet
|
check conf.networkId == GoerliNet
|
||||||
|
|
||||||
test "network-id set, goerli set":
|
test "network-id set, goerli set":
|
||||||
let conf = makeConfig(@["--goerli", "--network-id:123"])
|
let conf = makeConfig(@["--network:goerli", "--network:123"])
|
||||||
check conf.networkId.get() == GoerliNet
|
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:
|
when isMainModule:
|
||||||
configurationMain()
|
configurationMain()
|
||||||
|
@ -60,11 +60,11 @@ template runTests(name: string, hex: bool, calculator: typed) =
|
|||||||
check diff == t.currentDifficulty
|
check diff == t.currentDifficulty
|
||||||
|
|
||||||
proc difficultyMain*() =
|
proc difficultyMain*() =
|
||||||
let mainnetConfig = chainConfig(MainNet, CustomNetwork())
|
let mainnetConfig = networkParams(MainNet).config
|
||||||
func calcDifficultyMainNetWork(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
|
func calcDifficultyMainNetWork(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
|
||||||
mainnetConfig.calcDifficulty(timeStamp, parent)
|
mainnetConfig.calcDifficulty(timeStamp, parent)
|
||||||
|
|
||||||
let ropstenConfig = chainConfig(RopstenNet, CustomNetwork())
|
let ropstenConfig = networkParams(RopstenNet).config
|
||||||
func calcDifficultyRopsten(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
|
func calcDifficultyRopsten(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
|
||||||
ropstenConfig.calcDifficulty(timeStamp, parent)
|
ropstenConfig.calcDifficulty(timeStamp, parent)
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ template runTest(network: untyped) =
|
|||||||
test `network`.astToStr:
|
test `network`.astToStr:
|
||||||
var
|
var
|
||||||
memDB = newMemoryDB()
|
memDB = newMemoryDB()
|
||||||
chainDB = newBaseChainDB(memDB, true, network)
|
chainDB = newBaseChainDB(memDB, true, network, networkParams(network))
|
||||||
chain = newChain(chainDB)
|
chain = newChain(chainDB)
|
||||||
|
|
||||||
for x in `network IDs`:
|
for x in `network IDs`:
|
||||||
|
@ -8,39 +8,39 @@ const dataFolder = "tests" / "customgenesis"
|
|||||||
proc genesisTest() =
|
proc genesisTest() =
|
||||||
suite "Genesis":
|
suite "Genesis":
|
||||||
test "Correct mainnet hash":
|
test "Correct mainnet hash":
|
||||||
let g = genesisBlockForNetwork(MainNet, CustomNetwork())
|
let g = networkParams(MainNet).genesis
|
||||||
let b = g.toBlock
|
let b = g.toBlock
|
||||||
check(b.blockHash == "D4E56740F876AEF8C010B86A40D5F56745A118D0906A34E69AEC8C0DB1CB8FA3".toDigest)
|
check(b.blockHash == "D4E56740F876AEF8C010B86A40D5F56745A118D0906A34E69AEC8C0DB1CB8FA3".toDigest)
|
||||||
|
|
||||||
test "Correct ropstennet hash":
|
test "Correct ropstennet hash":
|
||||||
let g = genesisBlockForNetwork(RopstenNet, CustomNetwork())
|
let g = networkParams(RopstenNet).genesis
|
||||||
let b = g.toBlock
|
let b = g.toBlock
|
||||||
check(b.blockHash == "41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d".toDigest)
|
check(b.blockHash == "41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d".toDigest)
|
||||||
|
|
||||||
test "Correct rinkebynet hash":
|
test "Correct rinkebynet hash":
|
||||||
let g = genesisBlockForNetwork(RinkebyNet, CustomNetwork())
|
let g = networkParams(RinkebyNet).genesis
|
||||||
let b = g.toBlock
|
let b = g.toBlock
|
||||||
check(b.blockHash == "6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177".toDigest)
|
check(b.blockHash == "6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177".toDigest)
|
||||||
|
|
||||||
test "Correct goerlinet hash":
|
test "Correct goerlinet hash":
|
||||||
let g = genesisBlockForNetwork(GoerliNet, CustomNetwork())
|
let g = networkParams(GoerliNet).genesis
|
||||||
let b = g.toBlock
|
let b = g.toBlock
|
||||||
check(b.blockHash == "bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a".toDigest)
|
check(b.blockHash == "bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a".toDigest)
|
||||||
|
|
||||||
proc customGenesisTest() =
|
proc customGenesisTest() =
|
||||||
suite "Custom Genesis":
|
suite "Custom Genesis":
|
||||||
test "loadCustomGenesis":
|
test "loadCustomGenesis":
|
||||||
var cga, cgb, cgc: CustomNetwork
|
var cga, cgb, cgc: NetworkParams
|
||||||
check loadCustomNetwork(dataFolder / "berlin2000.json", cga)
|
check loadNetworkParams(dataFolder / "berlin2000.json", cga)
|
||||||
check loadCustomNetwork(dataFolder / "chainid7.json", cgb)
|
check loadNetworkParams(dataFolder / "chainid7.json", cgb)
|
||||||
check loadCustomNetwork(dataFolder / "noconfig.json", cgc)
|
check loadNetworkParams(dataFolder / "noconfig.json", cgc)
|
||||||
check cga.config.poaEngine == false
|
check cga.config.poaEngine == false
|
||||||
check cgb.config.poaEngine == false
|
check cgb.config.poaEngine == false
|
||||||
check cgc.config.poaEngine == false
|
check cgc.config.poaEngine == false
|
||||||
|
|
||||||
test "calaveras.json":
|
test "calaveras.json":
|
||||||
var cg: CustomNetwork
|
var cg: NetworkParams
|
||||||
check loadCustomNetwork(dataFolder / "calaveras.json", cg)
|
check loadNetworkParams(dataFolder / "calaveras.json", cg)
|
||||||
let h = toBlock(cg.genesis, nil)
|
let h = toBlock(cg.genesis, nil)
|
||||||
let stateRoot = "664c93de37eb4a72953ea42b8c046cdb64c9f0b0bca5505ade8d970d49ebdb8c".toDigest
|
let stateRoot = "664c93de37eb4a72953ea42b8c046cdb64c9f0b0bca5505ade8d970d49ebdb8c".toDigest
|
||||||
let genesisHash = "eb9233d066c275efcdfed8037f4fc082770176aefdbcb7691c71da412a5670f2".toDigest
|
let genesisHash = "eb9233d066c275efcdfed8037f4fc082770176aefdbcb7691c71da412a5670f2".toDigest
|
||||||
|
@ -63,7 +63,7 @@ proc setupChain(): BaseChainDB =
|
|||||||
if not parseGenesisAlloc($(jn["pre"]), genesis.alloc):
|
if not parseGenesisAlloc($(jn["pre"]), genesis.alloc):
|
||||||
quit(QuitFailure)
|
quit(QuitFailure)
|
||||||
|
|
||||||
let customNetwork = CustomNetwork(
|
let customNetwork = NetworkParams(
|
||||||
config: config,
|
config: config,
|
||||||
genesis: genesis
|
genesis: genesis
|
||||||
)
|
)
|
||||||
@ -95,7 +95,7 @@ proc setupChain(): BaseChainDB =
|
|||||||
|
|
||||||
proc graphqlMain*() =
|
proc graphqlMain*() =
|
||||||
let
|
let
|
||||||
conf = makeConfig(@[]) # don't use makeConfig default cmdLine from inside all_tests
|
conf = makeTestConfig()
|
||||||
ethCtx = newEthContext()
|
ethCtx = newEthContext()
|
||||||
ethNode = setupEthNode(conf, ethCtx, eth)
|
ethNode = setupEthNode(conf, ethCtx, eth)
|
||||||
chainDB = setupChain()
|
chainDB = setupChain()
|
||||||
|
@ -275,13 +275,17 @@ proc hashLogEntries*(logs: seq[Log]): string =
|
|||||||
proc setupEthNode*(conf: NimbusConf, ctx: EthContext, capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode =
|
proc setupEthNode*(conf: NimbusConf, ctx: EthContext, capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode =
|
||||||
let keypair = ctx.hexToKeyPair(conf.nodeKeyHex).tryGet()
|
let keypair = ctx.hexToKeyPair(conf.nodeKeyHex).tryGet()
|
||||||
var srvAddress: Address
|
var srvAddress: Address
|
||||||
srvAddress.ip = parseIpAddress("0.0.0.0")
|
srvAddress.ip = conf.listenAddress
|
||||||
srvAddress.tcpPort = conf.tcpPort
|
srvAddress.tcpPort = conf.tcpPort
|
||||||
srvAddress.udpPort = conf.udpPort
|
srvAddress.udpPort = conf.udpPort
|
||||||
result = newEthereumNode(
|
result = newEthereumNode(
|
||||||
keypair, srvAddress,
|
keypair, srvAddress,
|
||||||
conf.networkId.get(),
|
conf.networkId,
|
||||||
nil, conf.agentString,
|
nil, conf.agentString,
|
||||||
addAllCapabilities = false)
|
addAllCapabilities = false)
|
||||||
for capability in capabilities:
|
for capability in capabilities:
|
||||||
result.addCapability capability
|
result.addCapability capability
|
||||||
|
|
||||||
|
proc makeTestConfig*(): NimbusConf =
|
||||||
|
# commandLineParams() will not works inside all_tests
|
||||||
|
makeConfig(@[])
|
||||||
|
@ -124,14 +124,14 @@ proc rpcMain*() =
|
|||||||
suite "Remote Procedure Calls":
|
suite "Remote Procedure Calls":
|
||||||
# TODO: Include other transports such as Http
|
# TODO: Include other transports such as Http
|
||||||
let
|
let
|
||||||
conf = makeConfig(@[]) # don't use makeConfig default cmdLine from inside all_tests
|
conf = makeTestConfig()
|
||||||
ctx = newEthContext()
|
ctx = newEthContext()
|
||||||
ethNode = setupEthNode(conf, ctx, eth)
|
ethNode = setupEthNode(conf, ctx, eth)
|
||||||
chain = newBaseChainDB(
|
chain = newBaseChainDB(
|
||||||
newMemoryDb(),
|
newMemoryDb(),
|
||||||
conf.pruneMode == PruneMode.Full,
|
conf.pruneMode == PruneMode.Full,
|
||||||
conf.networkId.get(),
|
conf.networkId,
|
||||||
conf.customNetwork.get()
|
conf.networkParams
|
||||||
)
|
)
|
||||||
signer: EthAddress = hexToByteArray[20]("0x0e69cde81b1aa07a45c32c6cd85d67229d36bb1b")
|
signer: EthAddress = hexToByteArray[20]("0x0e69cde81b1aa07a45c32c6cd85d67229d36bb1b")
|
||||||
ks2: EthAddress = hexToByteArray[20]("0xa3b2222afa5c987da6ef773fde8d01b9f23d481f")
|
ks2: EthAddress = hexToByteArray[20]("0xa3b2222afa5c987da6ef773fde8d01b9f23d481f")
|
||||||
@ -182,7 +182,7 @@ proc rpcMain*() =
|
|||||||
|
|
||||||
test "net_version":
|
test "net_version":
|
||||||
let res = await client.net_version()
|
let res = await client.net_version()
|
||||||
check res == $conf.networkId.get()
|
check res == $conf.networkId
|
||||||
|
|
||||||
test "net_listening":
|
test "net_listening":
|
||||||
let res = await client.net_listening()
|
let res = await client.net_listening()
|
||||||
|
@ -45,7 +45,7 @@ proc main() {.used.} =
|
|||||||
# 52029 first block with receipts logs
|
# 52029 first block with receipts logs
|
||||||
# 66407 failed transaction
|
# 66407 failed transaction
|
||||||
|
|
||||||
# nimbus --rpcapi: eth, debug --prune: archive
|
# nimbus --rpc-api: eth, debug --prune: archive
|
||||||
|
|
||||||
var conf = makeConfig()
|
var conf = makeConfig()
|
||||||
let db = newChainDb(string conf.dataDir)
|
let db = newChainDb(string conf.dataDir)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user