nimbus-eth1/nimbus/nimbus.nim

153 lines
4.1 KiB
Nim
Raw Normal View History

2018-04-27 08:53:53 +00:00
# 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
os, strutils, net, eth_common, db/[storage_types, db_chain],
asyncdispatch2, json_rpc/rpcserver, eth_keys, chronicles,
eth_p2p, eth_p2p/rlpx_protocols/[eth_protocol, les_protocol],
eth_p2p/blockchain_sync,
config, genesis, rpc/[common, p2p, debug, whisper], p2p/chain,
eth_trie/db
const UseSqlite = false
when UseSqlite:
import db/backends/sqlite_backend
else:
import db/backends/rocksdb_backend
2018-06-20 17:27:32 +00:00
## TODO:
## * No IPv6 support
## * No multiple bind addresses support
## * No database support
const
nimbusClientId = "nimbus 0.1.0"
2018-06-20 17:27:32 +00:00
when not defined(windows):
from posix import SIGINT, SIGTERM
type
NimbusState = enum
Starting, Running, Stopping, Stopped
NimbusObject = ref object
rpcServer*: RpcHttpServer
ethNode*: EthereumNode
2018-06-20 17:27:32 +00:00
state*: NimbusState
proc initializeEmptyDb(db: BaseChainDB) =
trace "Writing genesis to DB"
2018-08-01 12:50:44 +00:00
let networkId = getConfiguration().net.networkId.toPublicNetwork()
if networkId == CustomNet:
raise newException(Exception, "Custom genesis not implemented")
else:
defaultGenesisBlockForNetwork(networkId).commit(db)
2018-06-20 17:27:32 +00:00
proc start(): NimbusObject =
var nimbus = NimbusObject()
var conf = getConfiguration()
## Creating RPC Server
if RpcFlags.Enabled in conf.rpc.flags:
nimbus.rpcServer = newRpcHttpServer(conf.rpc.binds)
2018-06-20 17:27:32 +00:00
setupCommonRpc(nimbus.rpcServer)
## Creating P2P Server
if conf.net.nodekey.isZeroKey():
conf.net.nodekey = newPrivateKey()
var keypair: KeyPair
keypair.seckey = conf.net.nodekey
keypair.pubkey = conf.net.nodekey.getPublicKey()
var address: Address
address.ip = parseIpAddress("0.0.0.0")
address.tcpPort = Port(conf.net.bindPort)
address.udpPort = Port(conf.net.discPort)
createDir(conf.dataDir)
let trieDB = trieDB newChainDb(conf.dataDir)
2018-11-30 10:07:20 +00:00
let chainDB = newBaseChainDB(trieDB, conf.prune == PruneMode.Full)
if canonicalHeadHashKey().toOpenArray notin trieDB:
initializeEmptyDb(chainDb)
2018-08-02 14:07:44 +00:00
assert(canonicalHeadHashKey().toOpenArray in trieDB)
nimbus.ethNode = newEthereumNode(keypair, address, conf.net.networkId,
nil, nimbusClientId)
2018-06-20 17:27:32 +00:00
2018-08-29 08:49:01 +00:00
nimbus.ethNode.chain = newChain(chainDB)
if RpcFlags.Eth in conf.rpc.flags:
2018-08-29 08:49:01 +00:00
setupEthRpc(nimbus.ethNode, chainDB, nimbus.rpcServer)
2018-06-20 17:27:32 +00:00
if RpcFlags.Shh in conf.rpc.flags:
setupWhisperRPC(nimbus.rpcServer)
if RpcFlags.Debug in conf.rpc.flags:
setupDebugRpc(chainDB, nimbus.rpcServer)
2018-06-20 17:27:32 +00:00
## Starting servers
nimbus.state = Starting
if RpcFlags.Enabled in conf.rpc.flags:
nimbus.rpcServer.rpc("admin_quit") do() -> string:
nimbus.state = Stopping
result = "EXITING"
nimbus.rpcServer.start()
2018-09-25 13:30:44 +00:00
waitFor nimbus.ethNode.connectToNetwork(conf.net.bootNodes,
enableDiscovery = NoDiscover notin conf.net.flags)
# TODO: temp code until the CLI/RPC interface is fleshed out
2018-08-29 08:49:01 +00:00
let status = waitFor nimbus.ethNode.fastBlockchainSync()
if status != syncSuccess:
debug "Block sync failed: ", status
2018-06-20 17:27:32 +00:00
nimbus.state = Running
result = nimbus
proc stop*(nimbus: NimbusObject) {.async.} =
trace "Graceful shutdown"
2018-06-20 17:27:32 +00:00
nimbus.rpcServer.stop()
proc process*(nimbus: NimbusObject) =
if nimbus.state == Running:
when not defined(windows):
proc signalBreak(udata: pointer) =
nimbus.state = Stopping
# Adding SIGINT, SIGTERM handlers
2018-08-29 08:49:01 +00:00
# discard addSignal(SIGINT, signalBreak)
# discard addSignal(SIGTERM, signalBreak)
2018-06-20 17:27:32 +00:00
# Main loop
while nimbus.state == Running:
poll()
# Stop loop
waitFor nimbus.stop()
2018-04-27 08:53:53 +00:00
when isMainModule:
var message: string
2018-06-20 17:27:32 +00:00
## Pring Nimbus header
echo NimbusHeader
## Processing command line arguments
if processArguments(message) != ConfigStatus.Success:
2018-04-27 08:53:53 +00:00
echo message
quit(QuitFailure)
else:
if len(message) > 0:
echo message
2018-06-20 17:27:32 +00:00
quit(QuitSuccess)
2018-04-27 08:53:53 +00:00
2018-06-20 17:27:32 +00:00
var nimbus = start()
nimbus.process()