Merge branch 'master' of github.com:status-im/nimbus

This commit is contained in:
Ștefan Talpalaru 2019-04-23 17:05:57 +02:00
commit f21190eb8d
No known key found for this signature in database
GPG Key ID: CBF7934204F1B6F9
2 changed files with 101 additions and 12 deletions

View File

@ -10,6 +10,7 @@
import
parseopt, strutils, macros, os, times,
chronos, eth/[keys, common, p2p, net/nat], chronicles, nimcrypto/hash,
eth/p2p/rlpx_protocols/whisper_protocol,
./db/select_backend,
./vm/interpreter/vm_forks
@ -96,6 +97,12 @@ type
Shh ## enable shh_ set of RPC API
Debug ## enable debug_ set of RPC API
ProtocolFlags* {.pure.} = enum
## Protocol flags
Eth ## enable eth subprotocol
Shh ## enable whisper subprotocol
Les ## enable les subprotocol
RpcConfiguration* = object
## JSON-RPC configuration object
flags*: set[RpcFlags] ## RPC flags
@ -125,6 +132,7 @@ type
## Network configuration object
flags*: set[NetworkFlags] ## Network flags
bootNodes*: seq[ENode] ## List of bootnodes
staticNodes*: seq[ENode] ## List of static nodes to connect to
bindPort*: uint16 ## Main TCP bind port
discPort*: uint16 ## Discovery UDP bind port
maxPeers*: int ## Maximum allowed number of peers
@ -134,6 +142,7 @@ type
nodeKey*: PrivateKey ## Server private key
nat*: NatStrategy ## NAT strategy
externalIP*: string ## user-provided external IP
protocols*: set[ProtocolFlags]## Enabled subprotocols
DebugConfiguration* = object
## Debug configuration object
@ -169,9 +178,11 @@ type
rpc*: RpcConfiguration ## JSON-RPC configuration
net*: NetConfiguration ## Network configuration
debug*: DebugConfiguration ## Debug configuration
shh*: WhisperConfig ## Whisper configuration
const
defaultRpcApi = {RpcFlags.Eth, RpcFlags.Shh}
defaultProtocols = {ProtocolFlags.Eth, ProtocolFlags.Shh}
defaultLogLevel = LogLevel.WARN
var nimbusConfig {.threadvar.}: NimbusConfiguration
@ -236,6 +247,14 @@ proc processInteger*(v: string, o: var int): ConfigStatus =
except:
result = ErrorParseOption
proc processFloat*(v: string, o: var float): ConfigStatus =
## Convert string to float.
try:
o = parseFloat(v)
result = Success
except:
result = ErrorParseOption
proc processAddressPortsList(v: string,
o: var seq[TransportAddress]): ConfigStatus =
## Convert <hostname:port>;...;<hostname:port> to list of `TransportAddress`.
@ -273,6 +292,19 @@ proc processRpcApiList(v: string, flags: var set[RpcFlags]): ConfigStatus =
warn "unknown rpc api", name = item
result = ErrorIncorrectOption
proc processProtocolList(v: string, flags: var set[ProtocolFlags]): ConfigStatus =
var list = newSeq[string]()
processList(v, list)
result = Success
for item in list:
case item.toLowerAscii()
of "eth": flags.incl ProtocolFlags.Eth
of "shh": flags.incl ProtocolFlags.Shh
of "les": flags.incl ProtocolFlags.Les
else:
warn "unknown protocol", name = item
result = ErrorIncorrectOption
proc processENode(v: string, o: var ENode): ConfigStatus =
## Convert string to ENode.
let res = initENode(v, o)
@ -427,6 +459,8 @@ proc processNetArguments(key, value: string): ConfigStatus =
result = processENodesList(value, config.net.bootNodes)
elif skey == "bootnodesv5":
result = processENodesList(value, config.net.bootNodes)
elif skey == "staticnodes":
result = processENodesList(value, config.net.staticNodes)
elif skey == "testnet":
config.net.setNetwork(RopstenNet)
elif skey == "mainnet":
@ -493,6 +527,29 @@ proc processNetArguments(key, value: string): ConfigStatus =
else:
error "not a valid NAT mechanism, nor a valid IP address", value
result = ErrorParseOption
elif skey == "protocols":
config.net.protocols = {}
result = processProtocolList(value, config.net.protocols)
else:
result = EmptyOption
proc processShhArguments(key, value: string): ConfigStatus =
## Processes only `Shh` related command line options
result = Success
let config = getConfiguration()
let skey = key.toLowerAscii()
if skey == "shh-maxsize":
var res = 0
result = processInteger(value, res)
if result == Success:
config.shh.maxMsgSize = res.uint32
elif skey == "shh-pow":
var res = 0.0
result = processFloat(value, res)
if result == Success:
config.shh.powRequirement = res
elif skey == "shh-light":
config.shh.isLightNode = true
else:
result = EmptyOption
@ -571,12 +628,19 @@ proc initConfiguration(): NimbusConfiguration =
result.net.discPort = 30303'u16
result.net.ident = NimbusIdent
result.net.nat = NatAny
result.net.protocols = defaultProtocols
const dataDir = getDefaultDataDir()
result.dataDir = getHomeDir() / dataDir
result.prune = PruneMode.Full
## Whisper defaults
result.shh.maxMsgSize = defaultMaxMsgSize
result.shh.powRequirement = defaultMinPow
result.shh.isLightNode = false
result.shh.bloom = fullBloom()
## Debug defaults
result.debug.flags = {}
result.debug.logLevel = defaultLogLevel
@ -608,6 +672,7 @@ NETWORKING OPTIONS:
--bootnodes:<value> Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers)
--bootnodesv4:<value> Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes)
--bootnodesv5:<value> Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes)
--staticnodes:<value> Comma separated enode URLs to connect with
--port:<value> Network listening TCP port (default: 30303)
--discport:<value> Network listening UDP port (defaults to --port argument)
--maxpeers:<value> Maximum number of network peers (default: 25)
@ -623,6 +688,12 @@ NETWORKING OPTIONS:
--morden Use Ethereum Morden Test Network
--networkid:<value> Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby) (default: 3)
--ident:<value> Client identifier (default is '$1')
--protocols:<value> Enable specific set of protocols (default: $4)
WHISPER OPTIONS:
--shh-maxsize:<value> Max message size accepted (default: $5)
--shh-pow:<value> Minimum POW accepted (default: $6)
--shh-light Run as Whisper light client (no outgoing messages)
API AND CONSOLE OPTIONS:
--rpc Enable the HTTP-RPC server
@ -637,7 +708,10 @@ LOGGING AND DEBUGGING OPTIONS:
""" % [
NimbusIdent,
join(logLevels, ", "),
$defaultLogLevel
$defaultLogLevel,
strip($defaultProtocols, chars = {'{','}'}),
$defaultMaxMsgSize,
$defaultMinPow
]
proc processArguments*(msg: var string): ConfigStatus =
@ -679,6 +753,7 @@ proc processArguments*(msg: var string): ConfigStatus =
processArgument processEthArguments, key, value, msg
processArgument processRpcArguments, key, value, msg
processArgument processNetArguments, key, value, msg
processArgument processShhArguments, key, value, msg
processArgument processDebugArguments, key, value, msg
if result != Success:
msg = "Unknown option: '" & key & "'."

View File

@ -12,8 +12,8 @@ import
eth/keys, db/[storage_types, db_chain, select_backend],
eth/common as eth_common, eth/p2p as eth_p2p,
chronos, json_rpc/rpcserver, chronicles,
eth/p2p/rlpx_protocols/[eth_protocol, les_protocol],
eth/p2p/blockchain_sync, eth/net/nat,
eth/p2p/rlpx_protocols/[eth_protocol, les_protocol, whisper_protocol],
eth/p2p/blockchain_sync, eth/net/nat, eth/p2p/peer_pool,
config, genesis, rpc/[common, p2p, debug, whisper], p2p/chain,
eth/trie/db
@ -91,16 +91,24 @@ proc start(): NimbusObject =
doAssert(canonicalHeadHashKey().toOpenArray in trieDB)
nimbus.ethNode = newEthereumNode(keypair, address, conf.net.networkId,
nil, nimbusClientId)
nil, nimbusClientId,
addAllCapabilities = false)
# Add protocol capabilities based on protocol flags
if ProtocolFlags.Eth in conf.net.protocols:
nimbus.ethNode.addCapability eth
if ProtocolFlags.Shh in conf.net.protocols:
nimbus.ethNode.addCapability Whisper
nimbus.ethNode.configureWhisper(conf.shh)
if ProtocolFlags.Les in conf.net.protocols:
nimbus.ethNode.addCapability les
nimbus.ethNode.chain = newChain(chainDB)
if RpcFlags.Eth in conf.rpc.flags:
# Enable RPC APIs based on RPC flags and protocol flags
if RpcFlags.Eth in conf.rpc.flags and ProtocolFlags.Eth in conf.net.protocols:
setupEthRpc(nimbus.ethNode, chainDB, nimbus.rpcServer)
if RpcFlags.Shh in conf.rpc.flags:
if RpcFlags.Shh in conf.rpc.flags and ProtocolFlags.Shh in conf.net.protocols:
setupWhisperRPC(nimbus.rpcServer)
if RpcFlags.Debug in conf.rpc.flags:
setupDebugRpc(chainDB, nimbus.rpcServer)
@ -112,13 +120,19 @@ proc start(): NimbusObject =
result = "EXITING"
nimbus.rpcServer.start()
# Connect directly to the static nodes
for enode in conf.net.staticNodes:
asyncCheck nimbus.ethNode.peerPool.connectToNode(newNode(enode))
# Connect via discovery
waitFor nimbus.ethNode.connectToNetwork(conf.net.bootNodes,
enableDiscovery = NoDiscover notin conf.net.flags)
# 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 ProtocolFlags.Eth in conf.net.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
nimbus.state = Running
result = nimbus