config: remove global rng from NimbusConfiguration
move the rng to EthContext
This commit is contained in:
parent
34972c6cea
commit
9108301eef
|
@ -97,7 +97,7 @@ type
|
|||
maxPendingPeers*: int ## Maximum allowed pending peers
|
||||
networkId*: NetworkId ## Network ID as integer
|
||||
ident*: string ## Server ident name string
|
||||
nodeKey*: PrivateKey ## Server private key
|
||||
nodeKey*: string ## Server private key
|
||||
nat*: NatStrategy ## NAT strategy
|
||||
externalIP*: string ## user-provided external IP
|
||||
protocols*: set[ProtocolFlags]## Enabled subprotocols
|
||||
|
@ -125,9 +125,6 @@ type
|
|||
net*: NetConfiguration ## Network configuration
|
||||
debug*: DebugConfiguration ## Debug configuration
|
||||
customGenesis*: CustomGenesis ## Custom Genesis Configuration
|
||||
# You should only create one instance of the RNG per application / library
|
||||
# Ref is used so that it can be shared between components
|
||||
rng*: ref BrHmacDrbgContext
|
||||
importKey*: string
|
||||
importFile*: string
|
||||
verifyFromOk*: bool ## activate `verifyFrom` setting
|
||||
|
@ -350,15 +347,6 @@ proc processENodesList(v: string, o: var seq[ENode]): ConfigStatus =
|
|||
else:
|
||||
break
|
||||
|
||||
proc processPrivateKey(v: string, o: var PrivateKey): ConfigStatus =
|
||||
## Convert hexadecimal string to private key object.
|
||||
let seckey = PrivateKey.fromHex(v)
|
||||
if seckey.isOk():
|
||||
o = seckey[]
|
||||
return Success
|
||||
|
||||
result = ErrorParseOption
|
||||
|
||||
proc processPruneList(v: string, flags: var PruneMode): ConfigStatus =
|
||||
var list = newSeq[string]()
|
||||
processList(v, list)
|
||||
|
@ -556,10 +544,7 @@ proc processNetArguments(key, value: string): ConfigStatus =
|
|||
if result == Success:
|
||||
config.net.maxPendingPeers = res
|
||||
elif skey == "nodekey":
|
||||
var res: PrivateKey
|
||||
result = processPrivateKey(value, res)
|
||||
if result == Success:
|
||||
config.net.nodeKey = res
|
||||
config.net.nodeKey = value
|
||||
elif skey == "ident":
|
||||
config.net.ident = value
|
||||
elif skey == "nat":
|
||||
|
@ -660,7 +645,6 @@ proc getDefaultKeystoreDir*(): string =
|
|||
proc initConfiguration(): NimbusConfiguration =
|
||||
## Allocates and initializes `NimbusConfiguration` with default values
|
||||
result = new NimbusConfiguration
|
||||
result.rng = newRng()
|
||||
|
||||
## Graphql defaults
|
||||
result.graphql.enabled = false
|
||||
|
@ -685,7 +669,6 @@ proc initConfiguration(): NimbusConfiguration =
|
|||
result.net.ident = NimbusIdent
|
||||
result.net.nat = NatAny
|
||||
result.net.protocols = defaultProtocols
|
||||
result.net.nodekey = random(PrivateKey, result.rng[])
|
||||
|
||||
const
|
||||
dataDir = getDefaultDataDir()
|
||||
|
|
|
@ -8,15 +8,36 @@
|
|||
# those terms.
|
||||
|
||||
import
|
||||
accounts/manager
|
||||
accounts/manager,
|
||||
stew/results,
|
||||
eth/keys
|
||||
|
||||
export manager
|
||||
|
||||
type
|
||||
EthContext* = ref object
|
||||
am*: AccountsManager
|
||||
|
||||
# You should only create one instance of the RNG per application / library
|
||||
# Ref is used so that it can be shared between components
|
||||
rng*: ref BrHmacDrbgContext
|
||||
|
||||
proc newEthContext*(): EthContext =
|
||||
result = new(EthContext)
|
||||
result.am = AccountsManager.init()
|
||||
result.rng = newRng()
|
||||
|
||||
proc randomPrivateKey*(ctx: EthContext): PrivateKey =
|
||||
random(PrivateKey, ctx.rng[])
|
||||
|
||||
proc randomKeyPair*(ctx: EthContext): KeyPair =
|
||||
random(KeyPair, ctx.rng[])
|
||||
|
||||
proc hexToKeyPair*(ctx: EthContext, hexPrivateKey: string): Result[KeyPair, string] =
|
||||
if hexPrivateKey.len == 0:
|
||||
let privateKey = ctx.randomPrivateKey()
|
||||
ok(privateKey.toKeyPair())
|
||||
else:
|
||||
let res = PrivateKey.fromHex(hexPrivateKey)
|
||||
if res.isErr:
|
||||
return err($res.error)
|
||||
ok(res.get().toKeyPair())
|
||||
|
|
|
@ -20,7 +20,7 @@ import
|
|||
./sync/protocol_eth65,
|
||||
config, genesis, rpc/[common, p2p, debug], p2p/chain,
|
||||
eth/trie/db, metrics, metrics/[chronos_httpserver, chronicles_support],
|
||||
graphql/ethapi,
|
||||
graphql/ethapi, context,
|
||||
"."/[utils, conf_utils, sealer, constants]
|
||||
|
||||
## TODO:
|
||||
|
@ -36,12 +36,13 @@ type
|
|||
Starting, Running, Stopping
|
||||
|
||||
NimbusNode = ref object
|
||||
rpcServer*: RpcHttpServer
|
||||
ethNode*: EthereumNode
|
||||
state*: NimbusState
|
||||
graphqlServer*: GraphqlHttpServerRef
|
||||
wsRpcServer*: RpcWebSocketServer
|
||||
sealingEngine*: SealingEngineRef
|
||||
rpcServer: RpcHttpServer
|
||||
ethNode: EthereumNode
|
||||
state: NimbusState
|
||||
graphqlServer: GraphqlHttpServerRef
|
||||
wsRpcServer: RpcWebSocketServer
|
||||
sealingEngine: SealingEngineRef
|
||||
ctx: EthContext
|
||||
|
||||
proc start(nimbus: NimbusNode) =
|
||||
var conf = getConfiguration()
|
||||
|
@ -71,7 +72,14 @@ proc start(nimbus: NimbusNode) =
|
|||
else:
|
||||
quit(QuitSuccess)
|
||||
|
||||
let res = conf.loadKeystoreFiles()
|
||||
if conf.keyStore.len > 0:
|
||||
let res = nimbus.ctx.am.loadKeystores(conf.keyStore)
|
||||
if res.isErr:
|
||||
echo res.error()
|
||||
quit(QuitFailure)
|
||||
|
||||
if conf.importKey.len > 0:
|
||||
let res = nimbus.ctx.am.importPrivateKey(conf.importKey)
|
||||
if res.isErr:
|
||||
echo res.error()
|
||||
quit(QuitFailure)
|
||||
|
@ -88,7 +96,12 @@ proc start(nimbus: NimbusNode) =
|
|||
discard setTimer(Moment.fromNow(conf.debug.logMetricsInterval.seconds), logMetrics)
|
||||
|
||||
## Creating P2P Server
|
||||
let keypair = conf.net.nodekey.toKeyPair()
|
||||
let kpres = nimbus.ctx.hexToKeyPair(conf.net.nodekey)
|
||||
if kpres.isErr:
|
||||
echo kpres.error()
|
||||
quit(QuitFailure)
|
||||
|
||||
let keypair = kpres.get()
|
||||
|
||||
var address: Address
|
||||
address.ip = parseIpAddress("0.0.0.0")
|
||||
|
@ -136,7 +149,7 @@ proc start(nimbus: NimbusNode) =
|
|||
|
||||
# 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)
|
||||
setupEthRpc(nimbus.ethNode, nimbus.ctx, chainDB, nimbus.rpcServer)
|
||||
if RpcFlags.Debug in conf.rpc.flags:
|
||||
setupDebugRpc(chainDB, nimbus.rpcServer)
|
||||
|
||||
|
@ -148,7 +161,7 @@ proc start(nimbus: NimbusNode) =
|
|||
|
||||
# Enable Websocket RPC APIs based on RPC flags and protocol flags
|
||||
if RpcFlags.Eth in conf.ws.flags and ProtocolFlags.Eth in conf.net.protocols:
|
||||
setupEthRpc(nimbus.ethNode, chainDB, nimbus.wsRpcServer)
|
||||
setupEthRpc(nimbus.ethNode, nimbus.ctx, chainDB, nimbus.wsRpcServer)
|
||||
if RpcFlags.Debug in conf.ws.flags:
|
||||
setupDebugRpc(chainDB, nimbus.wsRpcServer)
|
||||
|
||||
|
@ -165,11 +178,13 @@ proc start(nimbus: NimbusNode) =
|
|||
nimbus.graphqlServer.start()
|
||||
|
||||
if conf.engineSigner != ZERO_ADDRESS:
|
||||
let rs = validateSealer(chainRef)
|
||||
let rs = validateSealer(conf, nimbus.ctx, chainRef)
|
||||
if rs.isErr:
|
||||
echo rs.error
|
||||
quit(QuitFailure)
|
||||
nimbus.sealingEngine = SealingEngineRef.new(chainRef)
|
||||
nimbus.sealingEngine = SealingEngineRef.new(
|
||||
chainRef, nimbus.ctx, conf.engineSigner
|
||||
)
|
||||
nimbus.sealingEngine.start()
|
||||
|
||||
# metrics server
|
||||
|
@ -224,7 +239,7 @@ proc process*(nimbus: NimbusNode) =
|
|||
waitFor nimbus.stop()
|
||||
|
||||
when isMainModule:
|
||||
var nimbus = NimbusNode(state: Starting)
|
||||
var nimbus = NimbusNode(state: Starting, ctx: newEthContext())
|
||||
|
||||
## Ctrl+C handling
|
||||
proc controlCHandler() {.noconv.} =
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import eth/keys, config
|
||||
|
||||
proc getRng*(): ref BrHmacDrbgContext =
|
||||
getConfiguration().rng
|
||||
|
||||
proc randomPrivateKey*(): PrivateKey =
|
||||
random(PrivateKey, getRng()[])
|
||||
|
||||
proc randomKeyPair*(): KeyPair =
|
||||
random(KeyPair, getRng()[])
|
|
@ -18,8 +18,7 @@ import
|
|||
clique_sealer,
|
||||
clique_snapshot],
|
||||
./p2p/gaslimit,
|
||||
./chain_config,
|
||||
./utils
|
||||
"."/[chain_config, utils, context]
|
||||
|
||||
type
|
||||
EngineState = enum
|
||||
|
@ -30,16 +29,18 @@ type
|
|||
state: EngineState
|
||||
engineLoop: Future[void]
|
||||
chain: Chain
|
||||
ctx: EthContext
|
||||
signer: EthAddress
|
||||
|
||||
proc validateSealer*(chain: Chain): Result[void, string] =
|
||||
let conf = getConfiguration()
|
||||
proc validateSealer*(conf: NimbusConfiguration, ctx: EthContext, chain: Chain): Result[void, string] =
|
||||
if conf.engineSigner == ZERO_ADDRESS:
|
||||
return err("signer address should not zero, use --engine-signer to set signer address")
|
||||
|
||||
if conf.engineSigner notin conf.accounts:
|
||||
let res = ctx.am.getAccount(conf.engineSigner)
|
||||
if res.isErr:
|
||||
return err("signer address not in registered accounts, use --import-key/account to register the account")
|
||||
|
||||
let acc = conf.accounts[conf.engineSigner]
|
||||
let acc = res.get()
|
||||
if not acc.unlocked:
|
||||
return err("signer account not unlocked, please unlock it first via rpc/password file")
|
||||
|
||||
|
@ -119,21 +120,20 @@ proc generateBlock(engine: SealingEngineRef, ethBlock: var EthBlock): Result[voi
|
|||
|
||||
ok()
|
||||
|
||||
proc sealingLoop(engine: SealingEngineRef): Future[void] {.async.} =
|
||||
let clique = engine.chain.clique
|
||||
|
||||
proc signerFunc(signer: EthAddress, message: openArray[byte]):
|
||||
Result[RawSignature, cstring] {.gcsafe.} =
|
||||
let
|
||||
hashData = keccakHash(message)
|
||||
conf = getConfiguration()
|
||||
acc = conf.accounts[signer]
|
||||
ctx = engine.ctx
|
||||
acc = ctx.am.getAccount(signer).tryGet()
|
||||
rawSign = sign(acc.privateKey, SkMessage(hashData.data)).toRaw
|
||||
|
||||
ok(rawSign)
|
||||
|
||||
proc sealingLoop(engine: SealingEngineRef): Future[void] {.async.} =
|
||||
let clique = engine.chain.clique
|
||||
|
||||
let conf = getConfiguration()
|
||||
clique.authorize(conf.engineSigner, signerFunc)
|
||||
clique.authorize(engine.signer, signerFunc)
|
||||
|
||||
# convert times.Duration to chronos.Duration
|
||||
let period = chronos.seconds(clique.cfg.period.inSeconds)
|
||||
|
@ -164,9 +164,14 @@ proc sealingLoop(engine: SealingEngineRef): Future[void] {.async.} =
|
|||
|
||||
info "block generated", number=blk.header.blockNumber
|
||||
|
||||
proc new*(_: type SealingEngineRef, chain: Chain): SealingEngineRef =
|
||||
proc new*(_: type SealingEngineRef,
|
||||
chain: Chain,
|
||||
ctx: EthContext,
|
||||
signer: EthAddress): SealingEngineRef =
|
||||
SealingEngineRef(
|
||||
chain: chain
|
||||
chain: chain,
|
||||
ctx: ctx,
|
||||
signer: signer
|
||||
)
|
||||
|
||||
proc start*(engine: SealingEngineRef) =
|
||||
|
|
|
@ -13,7 +13,8 @@ import
|
|||
eth/[p2p, common, trie/db, rlp, trie],
|
||||
graphql, ../nimbus/graphql/ethapi, graphql/test_common,
|
||||
../nimbus/sync/protocol_eth65,
|
||||
../nimbus/[genesis, config, chain_config], ../nimbus/db/[db_chain, state_db],
|
||||
../nimbus/[genesis, config, chain_config, context],
|
||||
../nimbus/db/[db_chain, state_db],
|
||||
../nimbus/p2p/chain, ../premix/parser, ./test_helpers
|
||||
|
||||
type
|
||||
|
@ -83,7 +84,8 @@ proc graphqlMain*() =
|
|||
)
|
||||
|
||||
let
|
||||
ethNode = setupEthNode(eth)
|
||||
ethCtx = newEthContext()
|
||||
ethNode = setupEthNode(conf, ethCtx, eth)
|
||||
chainDB = newBaseChainDB(newMemoryDb(),
|
||||
pruneTrie = false,
|
||||
conf.net.networkId
|
||||
|
|
|
@ -11,7 +11,7 @@ import
|
|||
testutils/markdown_reports,
|
||||
../nimbus/[constants, config, transaction, utils, errors, forks],
|
||||
../nimbus/db/accounts_cache,
|
||||
../nimbus/random_keys
|
||||
../nimbus/context
|
||||
|
||||
func revmap(x: Table[Fork, string]): Table[string, Fork] =
|
||||
result = initTable[string, Fork]()
|
||||
|
@ -272,11 +272,8 @@ proc getFixtureTransaction*(j: JsonNode, dataIndex, gasIndex, valueIndex: int):
|
|||
proc hashLogEntries*(logs: seq[Log]): string =
|
||||
toLowerAscii("0x" & $keccakHash(rlp.encode(logs)))
|
||||
|
||||
proc setupEthNode*(capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode =
|
||||
var conf = getConfiguration()
|
||||
conf.net.nodekey = randomPrivateKey()
|
||||
let keypair = conf.net.nodekey.toKeyPair()
|
||||
|
||||
proc setupEthNode*(conf: NimbusConfiguration, ctx: EthContext, capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode =
|
||||
let keypair = ctx.hexToKeyPair(conf.net.nodekey).tryGet()
|
||||
var srvAddress: Address
|
||||
srvAddress.ip = parseIpAddress("0.0.0.0")
|
||||
srvAddress.tcpPort = Port(conf.net.bindPort)
|
||||
|
|
|
@ -123,16 +123,14 @@ proc setupEnv(chain: BaseChainDB, signer, ks2: EthAddress, ctx: EthContext): Tes
|
|||
proc rpcMain*() =
|
||||
suite "Remote Procedure Calls":
|
||||
# TODO: Include other transports such as Http
|
||||
var
|
||||
ethNode = setupEthNode(eth)
|
||||
chain = newBaseChainDB(newMemoryDb())
|
||||
|
||||
let
|
||||
conf = getConfiguration()
|
||||
ctx = newEthContext()
|
||||
ethNode = setupEthNode(conf, ctx, eth)
|
||||
chain = newBaseChainDB(newMemoryDb())
|
||||
signer: EthAddress = hexToByteArray[20]("0x0e69cde81b1aa07a45c32c6cd85d67229d36bb1b")
|
||||
ks2: EthAddress = hexToByteArray[20]("0xa3b2222afa5c987da6ef773fde8d01b9f23d481f")
|
||||
ks3: EthAddress = hexToByteArray[20]("0x597176e9a64aad0845d83afdaf698fbeff77703b")
|
||||
conf = getConfiguration()
|
||||
ctx = newEthContext()
|
||||
|
||||
ethNode.chain = newChain(chain)
|
||||
conf.keyStore = "tests" / "keystore"
|
||||
|
|
Loading…
Reference in New Issue