enhance net-key command line option to accept random, hex, and path
- previously it only accept hex - fix #587
This commit is contained in:
parent
a087d65542
commit
a5d4759bfd
|
@ -317,11 +317,14 @@ type
|
|||
defaultValueDesc: $DiscoveryType.V4
|
||||
name: "discovery" .}: DiscoveryType
|
||||
|
||||
nodeKeyHex* {.
|
||||
desc: "P2P node private key (as 32 bytes hex string)"
|
||||
defaultValue: ""
|
||||
defaultValueDesc: "random"
|
||||
name: "node-key" .}: string
|
||||
netKey* {.
|
||||
desc: "P2P ethereum node (secp256k1) private key (random, path, hex)"
|
||||
longDesc:
|
||||
"- random: generate random network key for this node instance\n" &
|
||||
"- path : path to where the private key will be loaded or auto generated\n" &
|
||||
"- hex : 32 bytes hex of network private key"
|
||||
defaultValue: "random"
|
||||
name: "net-key" .}: string
|
||||
|
||||
agentString* {.
|
||||
desc: "Node agent string which is used as identifier in network"
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
# those terms.
|
||||
|
||||
import
|
||||
std/[strutils, os],
|
||||
accounts/manager,
|
||||
stew/results,
|
||||
stew/[results, io2, byteutils],
|
||||
eth/keys
|
||||
|
||||
export manager
|
||||
|
@ -32,12 +33,45 @@ proc randomPrivateKey*(ctx: EthContext): PrivateKey =
|
|||
proc randomKeyPair*(ctx: EthContext): KeyPair =
|
||||
random(KeyPair, ctx.rng[])
|
||||
|
||||
proc hexToKeyPair*(ctx: EthContext, hexPrivateKey: string): Result[KeyPair, string] =
|
||||
if hexPrivateKey.len == 0:
|
||||
proc containsOnlyHexDigits(hex: string): bool =
|
||||
const HexDigitsX = HexDigits + {'x'}
|
||||
for c in hex:
|
||||
if c notin HexDigitsX:
|
||||
return false
|
||||
true
|
||||
|
||||
proc getNetKeys*(ctx: EthContext, netKey, dataDir: string): Result[KeyPair, string] =
|
||||
if netKey.len == 0 or netKey == "random":
|
||||
let privateKey = ctx.randomPrivateKey()
|
||||
ok(privateKey.toKeyPair())
|
||||
else:
|
||||
let res = PrivateKey.fromHex(hexPrivateKey)
|
||||
return ok(privateKey.toKeyPair())
|
||||
elif netKey.len in {64, 66} and netKey.containsOnlyHexDigits:
|
||||
let res = PrivateKey.fromHex(netKey)
|
||||
if res.isErr:
|
||||
return err($res.error)
|
||||
ok(res.get().toKeyPair())
|
||||
return ok(res.get().toKeyPair())
|
||||
else:
|
||||
# TODO: should we secure the private key with
|
||||
# keystore encryption?
|
||||
if fileAccessible(netKey, {AccessFlags.Find}):
|
||||
try:
|
||||
let lines = netKey.readLines(1)
|
||||
if lines.len == 0:
|
||||
return err("empty network key file")
|
||||
let rc = PrivateKey.fromHex(lines[0])
|
||||
if rc.isErr:
|
||||
return err($rc.error)
|
||||
return ok(rc.get().toKeyPair())
|
||||
except IOError as e:
|
||||
return err("cannot open network key file: " & e.msg)
|
||||
except ValueError as ex:
|
||||
return err("invalid hex string in network key file: " & ex.msg)
|
||||
else:
|
||||
let privateKey = ctx.randomPrivateKey()
|
||||
|
||||
try:
|
||||
createDir(netKey.splitFile.dir)
|
||||
netKey.writeFile(privateKey.toRaw.to0xHex)
|
||||
except IOError as e:
|
||||
return err("could not write network key file: " & e.msg)
|
||||
|
||||
return ok(privateKey.toKeyPair())
|
||||
|
|
|
@ -22,7 +22,7 @@ import
|
|||
metrics,
|
||||
metrics/[chronos_httpserver, chronicles_support],
|
||||
stew/shims/net as stewNet,
|
||||
websock/types as ws,
|
||||
websock/websock as ws,
|
||||
"."/[conf_utils, config, constants, context, genesis, sealer, utils, version],
|
||||
./db/[storage_types, db_chain, select_backend],
|
||||
./graphql/ethapi,
|
||||
|
@ -69,21 +69,21 @@ proc manageAccounts(nimbus: NimbusNode, conf: NimbusConf) =
|
|||
if string(conf.keyStore).len > 0:
|
||||
let res = nimbus.ctx.am.loadKeystores(string conf.keyStore)
|
||||
if res.isErr:
|
||||
echo res.error()
|
||||
fatal "Load keystore error", msg = res.error()
|
||||
quit(QuitFailure)
|
||||
|
||||
if string(conf.importKey).len > 0:
|
||||
let res = nimbus.ctx.am.importPrivateKey(string conf.importKey)
|
||||
if res.isErr:
|
||||
echo res.error()
|
||||
fatal "Import private key error", msg = res.error()
|
||||
quit(QuitFailure)
|
||||
|
||||
proc setupP2P(nimbus: NimbusNode, conf: NimbusConf,
|
||||
chainDB: BaseChainDB, protocols: set[ProtocolFlag]) =
|
||||
## Creating P2P Server
|
||||
let kpres = nimbus.ctx.hexToKeyPair(conf.nodeKeyHex)
|
||||
let kpres = nimbus.ctx.getNetKeys(conf.netKey, conf.dataDir.string)
|
||||
if kpres.isErr:
|
||||
echo kpres.error()
|
||||
fatal "Get network keys error", msg = kpres.error
|
||||
quit(QuitFailure)
|
||||
|
||||
let keypair = kpres.get()
|
||||
|
@ -117,7 +117,8 @@ proc setupP2P(nimbus: NimbusNode, conf: NimbusConf,
|
|||
addAllCapabilities = false, minPeers = conf.maxPeers,
|
||||
bootstrapNodes = bootstrapNodes,
|
||||
bindUdpPort = conf.udpPort, bindTcpPort = conf.tcpPort,
|
||||
bindIp = conf.listenAddress)
|
||||
bindIp = conf.listenAddress,
|
||||
rng = nimbus.ctx.rng)
|
||||
|
||||
# Add protocol capabilities based on protocol flags
|
||||
if ProtocolFlag.Eth in protocols:
|
||||
|
@ -187,12 +188,12 @@ proc localServices(nimbus: NimbusNode, conf: NimbusConf,
|
|||
discard setTimer(Moment.fromNow(conf.logMetricsInterval.seconds), logMetrics)
|
||||
discard setTimer(Moment.fromNow(conf.logMetricsInterval.seconds), logMetrics)
|
||||
|
||||
# Provide JWT authentication handler for websockets
|
||||
# Provide JWT authentication handler for rpcHttpServer
|
||||
let jwtKey = block:
|
||||
# Create or load shared secret
|
||||
let rc = nimbus.ctx.rng.jwtSharedSecret(conf)
|
||||
if rc.isErr:
|
||||
error "Failed create or load shared secret",
|
||||
fatal "Failed create or load shared secret",
|
||||
msg = $(rc.unsafeError) # avoid side effects
|
||||
quit(QuitFailure)
|
||||
rc.value
|
||||
|
@ -250,7 +251,10 @@ proc localServices(nimbus: NimbusNode, conf: NimbusConf,
|
|||
# Construct server object
|
||||
nimbus.wsRpcServer = newRpcWebSocketServer(
|
||||
initTAddress(conf.wsAddress, conf.wsPort),
|
||||
authHooks = hooks
|
||||
authHooks = hooks,
|
||||
# yuck, we should remove this ugly cast when
|
||||
# we fix nim-websock
|
||||
rng = cast[ws.Rng](nimbus.ctx.rng)
|
||||
)
|
||||
setupCommonRpc(nimbus.ethNode, conf, nimbus.wsRpcServer)
|
||||
|
||||
|
@ -284,7 +288,7 @@ proc localServices(nimbus: NimbusNode, conf: NimbusConf,
|
|||
|
||||
let rs = validateSealer(conf, nimbus.ctx, nimbus.chainRef)
|
||||
if rs.isErr:
|
||||
echo rs.error
|
||||
fatal "Engine signer validation error", msg = rs.error
|
||||
quit(QuitFailure)
|
||||
|
||||
proc signFunc(signer: EthAddress, message: openArray[byte]): Result[RawSignature, cstring] {.gcsafe.} =
|
||||
|
@ -297,7 +301,7 @@ proc localServices(nimbus: NimbusNode, conf: NimbusConf,
|
|||
|
||||
nimbus.chainRef.clique.authorize(conf.engineSigner, signFunc)
|
||||
|
||||
# always create sealing engine instanca but not always run it
|
||||
# always create sealing engine instance but not always run it
|
||||
# e.g. engine api need sealing engine without it running
|
||||
var initialState = EngineStopped
|
||||
if chainDB.headTotalDifficulty() > chainDB.ttd:
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import
|
||||
std/[os],
|
||||
pkg/[unittest2, confutils],
|
||||
eth/[p2p, common],
|
||||
../nimbus/[config, chain_config],
|
||||
eth/[p2p, common, keys],
|
||||
stew/byteutils,
|
||||
../nimbus/[config, chain_config, context],
|
||||
./test_helpers
|
||||
|
||||
proc `==`(a, b: ChainId): bool =
|
||||
|
@ -208,5 +209,39 @@ proc configurationMain*() =
|
|||
check conf.engineApiEnabled == false
|
||||
check conf.rpcEnabled == false
|
||||
|
||||
let ctx = newEthContext()
|
||||
test "net-key random":
|
||||
let conf = makeConfig(@["--net-key:random"])
|
||||
check conf.netKey == "random"
|
||||
let rc = ctx.getNetKeys(conf.netKey, conf.dataDir.string)
|
||||
check rc.isOk
|
||||
|
||||
test "net-key hex without 0x prefix":
|
||||
let conf = makeConfig(@["--net-key:9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"])
|
||||
check conf.netKey == "9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"
|
||||
let rc = ctx.getNetKeys(conf.netKey, conf.dataDir.string)
|
||||
check rc.isOk
|
||||
let pkhex = rc.get.seckey.toRaw.to0xHex
|
||||
check pkhex == "0x9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"
|
||||
|
||||
test "net-key hex with 0x prefix":
|
||||
let conf = makeConfig(@["--net-key:0x9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"])
|
||||
check conf.netKey == "0x9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"
|
||||
let rc = ctx.getNetKeys(conf.netKey, conf.dataDir.string)
|
||||
check rc.isOk
|
||||
let pkhex = rc.get.seckey.toRaw.to0xHex
|
||||
check pkhex == "0x9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"
|
||||
|
||||
test "net-key path":
|
||||
let conf = makeConfig(@["--net-key:nimcache/key.txt"])
|
||||
check conf.netKey == "nimcache/key.txt"
|
||||
let rc1 = ctx.getNetKeys(conf.netKey, conf.dataDir.string)
|
||||
check rc1.isOk
|
||||
let pkhex1 = rc1.get.seckey.toRaw.to0xHex
|
||||
let rc2 = ctx.getNetKeys(conf.netKey, conf.dataDir.string)
|
||||
check rc2.isOk
|
||||
let pkhex2 = rc2.get.seckey.toRaw.to0xHex
|
||||
check pkhex1 == pkhex2
|
||||
|
||||
when isMainModule:
|
||||
configurationMain()
|
||||
|
|
|
@ -278,7 +278,7 @@ proc hashLogEntries*(logs: seq[Log]): string =
|
|||
proc setupEthNode*(
|
||||
conf: NimbusConf, ctx: EthContext,
|
||||
capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode =
|
||||
let keypair = ctx.hexToKeyPair(conf.nodeKeyHex).tryGet()
|
||||
let keypair = ctx.getNetKeys(conf.netKey, conf.dataDir.string).tryGet()
|
||||
let srvAddress = Address(
|
||||
ip: conf.listenAddress, tcpPort: conf.tcpPort, udpPort: conf.udpPort)
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0fee4be2ccbbfa3f158b741c3a34b04130c8b424
|
||||
Subproject commit 5ccdaed0adfb1534ee1d193fc6f97e7961008bbe
|
Loading…
Reference in New Issue