config: fix new config based on input from jamie and zahary

This commit is contained in:
jangko 2021-09-16 22:59:46 +07:00
parent 69f2a0f95a
commit a3badea928
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
22 changed files with 723 additions and 502 deletions

View File

@ -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(

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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:

View File

@ -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`),

View File

@ -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,

View 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

View 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

View 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"
}
}
}
}

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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`:

View File

@ -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

View File

@ -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()

View File

@ -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(@[])

View File

@ -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()

View File

@ -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)