Add cli option to start fluffy with a netkey file (#974)

Default the network key will be taken from a network key file
instead of randomly generated on each run. This is done because
the data that gets stored in the content database is dependant on
the network key used, as the node id is derived from this.
This commit is contained in:
Kim De Mey 2022-02-17 14:13:39 +01:00 committed by GitHub
parent bd364ba2a6
commit d1127d77b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 8 deletions

View File

@ -9,7 +9,7 @@
import import
std/[os, strutils], std/[os, strutils],
chronicles, chronicles, stew/io2,
eth/p2p/discoveryv5/enr eth/p2p/discoveryv5/enr
iterator strippedLines(filename: string): string {.raises: [ref IOError].} = iterator strippedLines(filename: string): string {.raises: [ref IOError].} =
@ -43,3 +43,45 @@ proc loadBootstrapFile*(bootstrapFile: string,
else: else:
fatal "Unknown bootstrap file format", ext fatal "Unknown bootstrap file format", ext
quit 1 quit 1
# Note:
# Currently just works with the network private key stored as hex in a file.
# In the future it would be nice to re-use keystore from nimbus-eth2 for this.
# However that would require the pull the keystore.nim and parts of
# keystore_management.nim out of nimbus-eth2.
proc getPersistentNetKey*(
rng: var BrHmacDrbgContext, keyFilePath: string, dataDir: string):
PrivateKey =
if fileAccessible(keyFilePath, {AccessFlags.Find}):
info "Network key file is present, reading key", key_file = keyFilePath
let readResult = readAllChars(keyFilePath)
if readResult.isErr():
fatal "Could not load network key file", key_file = keyFilePath
quit QuitFailure
let netKeyInHex = readResult.get()
if netKeyInHex.len() == 64:
let netKey = PrivateKey.fromHex(netkeyInHex)
if netKey.isOk():
info "Network key was successfully read", key_file = keyFilePath
netKey.get()
else:
fatal "Invalid private key length in file", key_file = keyFilePath
quit QuitFailure
else:
fatal "Invalid private key from file", key_file = keyFilePath
quit QuitFailure
else:
info "Network key file is missing, creating a new one",
key_file = keyFilePath
let key = PrivateKey.random(rng)
if io2.writeFile(keyFilePath, $key).isErr:
fatal "Failed to write the network key file", key_file = keyFilePath
quit 1
info "New network key file was created", key_file = keyFilePath
key

View File

@ -83,18 +83,24 @@ type
"This option allows to enable/disable this functionality" "This option allows to enable/disable this functionality"
name: "enr-auto-update" .}: bool name: "enr-auto-update" .}: bool
networkKey* {.
desc: "Private key (secp256k1) for the p2p network, hex encoded. Safer keyfile support to be added.",
defaultValue: PrivateKey.random(keys.newRng()[])
defaultValueDesc: "random"
name: "network-key-unsafe" .}: PrivateKey
dataDir* {. dataDir* {.
desc: "The directory where fluffy will store the content data" desc: "The directory where fluffy will store the content data"
defaultValue: defaultDataDir() defaultValue: defaultDataDir()
defaultValueDesc: $defaultDataDirDesc defaultValueDesc: $defaultDataDirDesc
name: "data-dir" .}: OutDir name: "data-dir" .}: OutDir
networkKeyFile* {.
desc: "Source of network (secp256k1) private key file"
defaultValue: config.dataDir / "netkey",
name: "netkey-file" }: string
networkKey* {.
hidden
desc: "Private key (secp256k1) for the p2p network, hex encoded.",
defaultValue: none(PrivateKey)
defaultValueDesc: "none"
name: "netkey-unsafe" .}: Option[PrivateKey]
metricsEnabled* {. metricsEnabled* {.
defaultValue: false defaultValue: false
desc: "Enable the metrics server" desc: "Enable the metrics server"

View File

@ -54,6 +54,11 @@ proc run(config: PortalConf) {.raises: [CatchableError, Defect].} =
except CatchableError as exc: raise exc except CatchableError as exc: raise exc
# TODO: Ideally we don't have the Exception here # TODO: Ideally we don't have the Exception here
except Exception as exc: raiseAssert exc.msg except Exception as exc: raiseAssert exc.msg
netkey =
if config.networkKey.isSome():
config.networkKey.get()
else:
getPersistentNetKey(rng[], config.networkKeyFile, config.dataDir.string)
var bootstrapRecords: seq[Record] var bootstrapRecords: seq[Record]
loadBootstrapFile(string config.bootstrapNodesFile, bootstrapRecords) loadBootstrapFile(string config.bootstrapNodesFile, bootstrapRecords)
@ -63,7 +68,7 @@ proc run(config: PortalConf) {.raises: [CatchableError, Defect].} =
discoveryConfig = DiscoveryConfig.init( discoveryConfig = DiscoveryConfig.init(
config.tableIpLimit, config.bucketIpLimit, config.bitsPerHop) config.tableIpLimit, config.bucketIpLimit, config.bitsPerHop)
d = newProtocol( d = newProtocol(
config.networkKey, netkey,
extIp, none(Port), extUdpPort, extIp, none(Port), extUdpPort,
bootstrapRecords = bootstrapRecords, bootstrapRecords = bootstrapRecords,
bindIp = bindIp, bindPort = udpPort, bindIp = bindIp, bindPort = udpPort,