parent
8528f1b704
commit
5e7f2c990d
|
@ -13,6 +13,8 @@ requires "nim >= 0.18.1",
|
||||||
"stint",
|
"stint",
|
||||||
"https://github.com/status-im/nim-eth-common",
|
"https://github.com/status-im/nim-eth-common",
|
||||||
"https://github.com/status-im/nim-eth-p2p",
|
"https://github.com/status-im/nim-eth-p2p",
|
||||||
|
"https://github.com/status-im/nim-asyncdispatch2",
|
||||||
|
"https://github.com/status-im/nim-eth-rpc",
|
||||||
"https://github.com/status-im/nim-eth-keyfile"
|
"https://github.com/status-im/nim-eth-keyfile"
|
||||||
|
|
||||||
proc test(name: string, lang = "c") =
|
proc test(name: string, lang = "c") =
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
# This file may not be copied, modified, or distributed except according to
|
# This file may not be copied, modified, or distributed except according to
|
||||||
# those terms.
|
# those terms.
|
||||||
|
|
||||||
import parseopt, strutils, net, ethp2p, eth_keyfile, eth_keys, json,
|
import parseopt, strutils
|
||||||
nimcrypto
|
import asyncdispatch2, eth_keys, ethp2p
|
||||||
|
|
||||||
const
|
const
|
||||||
NimbusName* = "Nimbus"
|
NimbusName* = "Nimbus"
|
||||||
|
@ -29,42 +29,50 @@ const
|
||||||
NimbusVersion* = $NimbusMajor & "." & $NimbusMinor & "." & $NimbusPatch
|
NimbusVersion* = $NimbusMajor & "." & $NimbusMinor & "." & $NimbusPatch
|
||||||
## is the version of Nimbus as a string.
|
## is the version of Nimbus as a string.
|
||||||
|
|
||||||
|
NimbusIdent* = NimbusName & "/" & NimbusVersion
|
||||||
|
## project ident name for networking services
|
||||||
|
|
||||||
|
NimbusHeader* = NimbusName & " Version " & NimbusVersion &
|
||||||
|
" [" & hostOS & ": " & hostCPU & "]\r\n" &
|
||||||
|
NimbusCopyright
|
||||||
|
## command line nimbus header
|
||||||
|
|
||||||
type
|
type
|
||||||
ConfigStatus* = enum
|
ConfigStatus* = enum
|
||||||
## Configuration status flags
|
## Configuration status flags
|
||||||
Success, ## Success
|
Success, ## Success
|
||||||
EmptyOption, ## No options in category
|
EmptyOption, ## No options in category
|
||||||
ErrorUnknownOption, ## Unknown option in command line found
|
ErrorUnknownOption, ## Unknown option in command line found
|
||||||
ErrorParseOption, ## Error in parsing command line option
|
ErrorParseOption, ## Error in parsing command line option
|
||||||
Error ## Unspecified error
|
ErrorIncorrectOption, ## Option has incorrect value
|
||||||
|
Error ## Unspecified error
|
||||||
|
|
||||||
RpcFlags* {.pure.} = enum
|
RpcFlags* {.pure.} = enum
|
||||||
## RPC flags
|
## RPC flags
|
||||||
Enabled ## RPC enabled
|
Enabled ## RPC enabled
|
||||||
|
|
||||||
RpcConfiguration* = object
|
RpcConfiguration* = object
|
||||||
## JSON-RPC configuration object
|
## JSON-RPC configuration object
|
||||||
flags*: set[RpcFlags] ## RPC flags
|
flags*: set[RpcFlags] ## RPC flags
|
||||||
bindAddress*: IpAddress ## RPC bind address
|
binds*: seq[TransportAddress] ## RPC bind address
|
||||||
bindPort*: uint16 ## RPC bind port
|
|
||||||
allowedIPs*: seq[IpAddress] ## Sequence of allowed IP addresses
|
|
||||||
username*: string ## RPC authorization username
|
|
||||||
password*: string ## RPC authorization password
|
|
||||||
|
|
||||||
NetworkFlags* = enum
|
NetworkFlags* = enum
|
||||||
## Ethereum network flags
|
## Ethereum network flags
|
||||||
LocalNet, ## Use local network only
|
RopstenNet, ## Use test Ropsten network
|
||||||
TestNet, ## Use test network only
|
RinkebyNet, ## Use test Rinkeby network
|
||||||
MainNet, ## Use main network only
|
MordenNet, ## Use test Morden network
|
||||||
NoDiscover, ## Peer discovery disabled
|
KovanNet, ## Use test Kovan network
|
||||||
V5Discover, ## Dicovery V5 enabled
|
CustomNet, ## Use custom network
|
||||||
|
MainNet, ## Use main network only
|
||||||
|
NoDiscover, ## Peer discovery disabled
|
||||||
|
V5Discover, ## Dicovery V5 enabled
|
||||||
|
|
||||||
DebugFlags* {.pure.} = enum
|
DebugFlags* {.pure.} = enum
|
||||||
## Debug selection flags
|
## Debug selection flags
|
||||||
Enabled, ## Debugging enabled
|
Enabled, ## Debugging enabled
|
||||||
Test1, ## Test1 enabled
|
Test1, ## Test1 enabled
|
||||||
Test2, ## Test2 enabled
|
Test2, ## Test2 enabled
|
||||||
Test3 ## Test3 enabled
|
Test3 ## Test3 enabled
|
||||||
|
|
||||||
NetConfiguration* = object
|
NetConfiguration* = object
|
||||||
## Network configuration object
|
## Network configuration object
|
||||||
|
@ -76,6 +84,7 @@ type
|
||||||
discPort*: uint16
|
discPort*: uint16
|
||||||
maxPeers*: int
|
maxPeers*: int
|
||||||
maxPendingPeers*: int
|
maxPendingPeers*: int
|
||||||
|
networkId*: int
|
||||||
nodeKey*: PrivateKey
|
nodeKey*: PrivateKey
|
||||||
|
|
||||||
DebugConfiguration* = object
|
DebugConfiguration* = object
|
||||||
|
@ -84,9 +93,9 @@ type
|
||||||
|
|
||||||
NimbusConfiguration* = ref object
|
NimbusConfiguration* = ref object
|
||||||
## Main Nimbus configuration object
|
## Main Nimbus configuration object
|
||||||
rpc*: RpcConfiguration ## JSON-RPC configuration
|
rpc*: RpcConfiguration ## JSON-RPC configuration
|
||||||
net*: NetConfiguration ## Network configuration
|
net*: NetConfiguration ## Network configuration
|
||||||
debug*: DebugConfiguration ## Debug configuration
|
debug*: DebugConfiguration ## Debug configuration
|
||||||
|
|
||||||
var nimbusConfig {.threadvar.}: NimbusConfiguration
|
var nimbusConfig {.threadvar.}: NimbusConfiguration
|
||||||
|
|
||||||
|
@ -96,14 +105,10 @@ proc initConfiguration(): NimbusConfiguration =
|
||||||
|
|
||||||
## RPC defaults
|
## RPC defaults
|
||||||
result.rpc.flags = {}
|
result.rpc.flags = {}
|
||||||
result.rpc.bindAddress = parseIpAddress("127.0.0.1")
|
result.rpc.binds = @[initTAddress("127.0.0.1:8545")]
|
||||||
result.rpc.bindPort = uint16(7654)
|
|
||||||
result.rpc.username = ""
|
|
||||||
result.rpc.password = ""
|
|
||||||
result.rpc.allowedIPs = newSeq[IpAddress]()
|
|
||||||
|
|
||||||
## Network defaults
|
## Network defaults
|
||||||
result.net.flags = {TestNet}
|
result.net.flags = {RopstenNet}
|
||||||
result.net.bootNodes = newSeq[ENode]()
|
result.net.bootNodes = newSeq[ENode]()
|
||||||
result.net.bootNodes4 = newSeq[ENode]()
|
result.net.bootNodes4 = newSeq[ENode]()
|
||||||
result.net.bootNodes5 = newSeq[ENode]()
|
result.net.bootNodes5 = newSeq[ENode]()
|
||||||
|
@ -136,26 +141,28 @@ proc processInteger(v: string, o: var int): ConfigStatus =
|
||||||
except:
|
except:
|
||||||
result = ErrorParseOption
|
result = ErrorParseOption
|
||||||
|
|
||||||
proc processIpAddress(v: string, o: var IpAddress): ConfigStatus =
|
proc processAddressPortsList(v: string,
|
||||||
## Convert string to IpAddress.
|
o: var seq[TransportAddress]): ConfigStatus =
|
||||||
try:
|
var list = newSeq[string]()
|
||||||
o = parseIpAddress(v)
|
|
||||||
result = Success
|
|
||||||
except:
|
|
||||||
result = ErrorParseOption
|
|
||||||
|
|
||||||
proc processAddressesList(v: string, o: var seq[IpAddress]): ConfigStatus =
|
|
||||||
## Convert comma-separated list of strings to list of IpAddress.
|
|
||||||
var
|
|
||||||
address: IpAddress
|
|
||||||
list = newSeq[string]()
|
|
||||||
processList(v, list)
|
processList(v, list)
|
||||||
for item in list:
|
for item in list:
|
||||||
result = processIpAddress(item, address)
|
var tas4: seq[TransportAddress]
|
||||||
if result == Success:
|
var tas6: seq[TransportAddress]
|
||||||
o.add(address)
|
try:
|
||||||
else:
|
tas4 = resolveTAddress(item, IpAddressFamily.IPv4)
|
||||||
|
except:
|
||||||
|
discard
|
||||||
|
try:
|
||||||
|
tas6 = resolveTAddress(item, IpAddressFamily.IPv6)
|
||||||
|
except:
|
||||||
|
discard
|
||||||
|
if len(tas4) == 0 and len(tas6) == 0:
|
||||||
|
result = ErrorParseOption
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
for a in tas4: o.add(a)
|
||||||
|
for a in tas6: o.add(a)
|
||||||
|
result = Success
|
||||||
|
|
||||||
proc processENode(v: string, o: var ENode): ConfigStatus =
|
proc processENode(v: string, o: var ENode): ConfigStatus =
|
||||||
## Convert string to ENode.
|
## Convert string to ENode.
|
||||||
|
@ -218,21 +225,32 @@ proc processRpcArguments(key, value: string): ConfigStatus =
|
||||||
if skey == "rpc":
|
if skey == "rpc":
|
||||||
config.rpc.flags.incl(Enabled)
|
config.rpc.flags.incl(Enabled)
|
||||||
elif skey == "rpcbind":
|
elif skey == "rpcbind":
|
||||||
result = processIpAddress(value, config.rpc.bindAddress)
|
config.rpc.binds.setLen(0)
|
||||||
elif skey == "rpcport":
|
result = processAddressPortsList(value, config.rpc.binds)
|
||||||
var res = 0
|
|
||||||
result = processInteger(value, res)
|
|
||||||
if result == Success:
|
|
||||||
config.rpc.bindPort = uint16(res and 0xFFFF)
|
|
||||||
elif skey == "rpcuser":
|
|
||||||
config.rpc.username = value
|
|
||||||
elif skey == "rpcpassword":
|
|
||||||
config.rpc.password = value
|
|
||||||
elif skey == "rpcallowip":
|
|
||||||
result = processAddressesList(value, config.rpc.allowedIPs)
|
|
||||||
else:
|
else:
|
||||||
result = EmptyOption
|
result = EmptyOption
|
||||||
|
|
||||||
|
proc setNetwork(conf: var NetConfiguration, network: NetworkFlags,
|
||||||
|
id: int = 0) =
|
||||||
|
conf.flags.excl({MainNet, MordenNet, RopstenNet, RinkebyNet, KovanNet,
|
||||||
|
CustomNet})
|
||||||
|
conf.flags.incl(network)
|
||||||
|
case network
|
||||||
|
of MainNet:
|
||||||
|
conf.networkId = 1
|
||||||
|
of MordenNet:
|
||||||
|
conf.networkId = 2
|
||||||
|
of RopstenNet:
|
||||||
|
conf.networkId = 3
|
||||||
|
of RinkebyNet:
|
||||||
|
conf.networkId = 4
|
||||||
|
of KovanNet:
|
||||||
|
conf.networkId = 42
|
||||||
|
of CustomNet:
|
||||||
|
conf.networkId = id
|
||||||
|
else:
|
||||||
|
discard
|
||||||
|
|
||||||
proc processNetArguments(key, value: string): ConfigStatus =
|
proc processNetArguments(key, value: string): ConfigStatus =
|
||||||
## Processes only `Networking` related command line options
|
## Processes only `Networking` related command line options
|
||||||
result = Success
|
result = Success
|
||||||
|
@ -245,17 +263,34 @@ proc processNetArguments(key, value: string): ConfigStatus =
|
||||||
elif skey == "bootnodesv5":
|
elif skey == "bootnodesv5":
|
||||||
result = processENodesList(value, config.net.bootNodes5)
|
result = processENodesList(value, config.net.bootNodes5)
|
||||||
elif skey == "testnet":
|
elif skey == "testnet":
|
||||||
config.net.flags.incl(TestNet)
|
config.net.setNetwork(RopstenNet)
|
||||||
config.net.flags.excl(LocalNet)
|
|
||||||
config.net.flags.excl(MainNet)
|
|
||||||
elif skey == "localnet":
|
|
||||||
config.net.flags.incl(LocalNet)
|
|
||||||
config.net.flags.excl(TestNet)
|
|
||||||
config.net.flags.excl(MainNet)
|
|
||||||
elif skey == "mainnet":
|
elif skey == "mainnet":
|
||||||
config.net.flags.incl(MainNet)
|
config.net.setNetwork(MainNet)
|
||||||
config.net.flags.excl(LocalNet)
|
elif skey == "ropsten":
|
||||||
config.net.flags.excl(TestNet)
|
config.net.setNetwork(RopstenNet)
|
||||||
|
elif skey == "rinkeby":
|
||||||
|
config.net.setNetwork(RinkebyNet)
|
||||||
|
elif skey == "morden":
|
||||||
|
config.net.setNetwork(MordenNet)
|
||||||
|
elif skey == "kovan":
|
||||||
|
config.net.setNetwork(KovanNet)
|
||||||
|
elif skey == "networkid":
|
||||||
|
var res = 0
|
||||||
|
result = processInteger(value, res)
|
||||||
|
if result == Success:
|
||||||
|
case res
|
||||||
|
of 1:
|
||||||
|
config.net.setNetwork(MainNet)
|
||||||
|
of 2:
|
||||||
|
config.net.setNetwork(MordenNet)
|
||||||
|
of 3:
|
||||||
|
config.net.setNetwork(RopstenNet)
|
||||||
|
of 4:
|
||||||
|
config.net.setNetwork(RinkebyNet)
|
||||||
|
of 42:
|
||||||
|
config.net.setNetwork(KovanNet)
|
||||||
|
else:
|
||||||
|
config.net.setNetwork(CustomNet, res)
|
||||||
elif skey == "nodiscover":
|
elif skey == "nodiscover":
|
||||||
config.net.flags.incl(NoDiscover)
|
config.net.flags.incl(NoDiscover)
|
||||||
elif skey == "v5discover":
|
elif skey == "v5discover":
|
||||||
|
@ -321,13 +356,13 @@ template checkArgument(a, b, c, e: untyped) =
|
||||||
(e) = "Error processing option [" & key & "] with value [" & value & "]"
|
(e) = "Error processing option [" & key & "] with value [" & value & "]"
|
||||||
result = res
|
result = res
|
||||||
break
|
break
|
||||||
|
elif res == ErrorIncorrectOption:
|
||||||
proc getVersionString*(): string =
|
(e) = "Incorrect value for option [" & key & "] value [" & value & "]"
|
||||||
result = NimbusName & ", " & NimbusVersion & "\n" & NimbusCopyright & "\n"
|
result = res
|
||||||
|
break
|
||||||
|
|
||||||
proc getHelpString*(): string =
|
proc getHelpString*(): string =
|
||||||
result = getVersionString()
|
result = """
|
||||||
result &= """
|
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
nimbus [options]
|
nimbus [options]
|
||||||
|
@ -346,17 +381,16 @@ NETWORKING OPTIONS:
|
||||||
--nodiscover Disables the peer discovery mechanism (manual peer addition)
|
--nodiscover Disables the peer discovery mechanism (manual peer addition)
|
||||||
--v5discover Enables the experimental RLPx V5 (Topic Discovery) mechanism
|
--v5discover Enables the experimental RLPx V5 (Topic Discovery) mechanism
|
||||||
--nodekey:<value> P2P node private key (as hexadecimal string)
|
--nodekey:<value> P2P node private key (as hexadecimal string)
|
||||||
--testnet Use Ethereum Test Network
|
--testnet Use Ethereum Ropsten Test Network (default)
|
||||||
|
--rinkeby Use Ethereum Rinkeby Test Network
|
||||||
|
--ropsten Use Ethereum Test Network (Ropsten Network)
|
||||||
--mainnet Use Ethereum Main Network
|
--mainnet Use Ethereum Main Network
|
||||||
--localnet Use local network only
|
--morden Use Ethereum Morden Test Network
|
||||||
|
--networkid:<value> Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby) (default: 3)
|
||||||
|
|
||||||
API AND CONSOLE OPTIONS:
|
API AND CONSOLE OPTIONS:
|
||||||
--rpc Enable the HTTP-RPC server
|
--rpc Enable the HTTP-RPC server
|
||||||
--rpcbind:<value> HTTP-RPC server will bind to given address (default: 127.0.0.1)
|
--rpcbind:<value> HTTP-RPC server will bind to given comma separated address:port pairs (default: 127.0.0.1:8545)
|
||||||
--rpcport:<value> HTTP-RPC server listening port (default: 7654)
|
|
||||||
--rpcuser:<value> HTTP-RPC authorization username
|
|
||||||
--rpcpassword:<value> HTTP-RPC authorization password
|
|
||||||
--rpcallowip:<value> Allow HTTP-RPC connections from specified IP addresses
|
|
||||||
|
|
||||||
LOGGING AND DEBUGGING OPTIONS:
|
LOGGING AND DEBUGGING OPTIONS:
|
||||||
--debug Enable debug mode
|
--debug Enable debug mode
|
||||||
|
@ -379,7 +413,7 @@ proc processArguments*(msg: var string): ConfigStatus =
|
||||||
result = Success
|
result = Success
|
||||||
break
|
break
|
||||||
of "version", "ver", "v":
|
of "version", "ver", "v":
|
||||||
msg = getVersionString()
|
msg = NimbusVersion
|
||||||
result = Success
|
result = Success
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
# This file may not be copied, modified, or distributed except according to
|
# This file may not be copied, modified, or distributed except according to
|
||||||
# those terms.
|
# those terms.
|
||||||
|
|
||||||
import config, asyncdispatch
|
import strutils
|
||||||
import p2p/service, p2p/disc4service
|
import asyncdispatch2, eth-rpc/server
|
||||||
|
import config, rpc/common
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var message: string
|
var message: string
|
||||||
|
echo NimbusHeader
|
||||||
if processArguments(message) != ConfigStatus.Success:
|
if processArguments(message) != ConfigStatus.Success:
|
||||||
echo message
|
echo message
|
||||||
quit(QuitFailure)
|
quit(QuitFailure)
|
||||||
|
@ -19,12 +21,11 @@ when isMainModule:
|
||||||
if len(message) > 0:
|
if len(message) > 0:
|
||||||
echo message
|
echo message
|
||||||
|
|
||||||
var disc4: Discovery4Service
|
var conf = getConfiguration()
|
||||||
if disc4.init() != ServiceStatus.Success:
|
if RpcFlags.Enabled in conf.rpc.flags:
|
||||||
quit(QuitFailure)
|
var rpcserver = newRpcServer(conf.rpc.binds)
|
||||||
if disc4.configure() != ServiceStatus.Success:
|
setupCommonRPC(rpcserver)
|
||||||
echo disc4.errorMessage()
|
rpcserver.start()
|
||||||
quit(QuitFailure)
|
|
||||||
if disc4.start() != ServiceStatus.Success:
|
while true:
|
||||||
echo disc4.errorMessage()
|
poll()
|
||||||
quit(QuitFailure)
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Nimbus
|
||||||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
# Licensed under either of
|
||||||
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
# at your option.
|
||||||
|
# This file may not be copied, modified, or distributed except according to
|
||||||
|
# those terms.
|
||||||
|
import eth-rpc/server, nimcrypto
|
||||||
|
import ../config
|
||||||
|
|
||||||
|
proc setupCommonRPC*(server: RpcServer) =
|
||||||
|
server.rpc("web3_clientVersion") do() -> string:
|
||||||
|
result = NimbusIdent
|
||||||
|
|
||||||
|
server.rpc("web3_sha3") do(data: string) -> string:
|
||||||
|
var rawdata = fromHex(data)
|
||||||
|
result = "0x" & $keccak_256.digest(rawdata)
|
||||||
|
|
||||||
|
server.rpc("net_version") do() -> int:
|
||||||
|
let conf = getConfiguration()
|
||||||
|
result = conf.net.networkId
|
Loading…
Reference in New Issue