Make the persistent network keys compatible with the Go daemon
The daemon requires its key file to be encoded as ProtoBuf value with a proper `key scheme` discriminator.
This commit is contained in:
parent
1b1cd915db
commit
3b9e9fefa8
|
@ -21,6 +21,9 @@ const
|
||||||
hasPrompt = not defined(withoutPrompt)
|
hasPrompt = not defined(withoutPrompt)
|
||||||
maxEmptySlotCount = uint64(24*60*60) div SECONDS_PER_SLOT
|
maxEmptySlotCount = uint64(24*60*60) div SECONDS_PER_SLOT
|
||||||
|
|
||||||
|
type
|
||||||
|
KeyPair = eth2_network.KeyPair
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#interop-metrics
|
# https://github.com/ethereum/eth2.0-metrics/blob/master/metrics.md#interop-metrics
|
||||||
declareGauge beacon_slot,
|
declareGauge beacon_slot,
|
||||||
"Latest slot of the beacon chain state"
|
"Latest slot of the beacon chain state"
|
||||||
|
@ -46,7 +49,7 @@ type
|
||||||
nickname: string
|
nickname: string
|
||||||
network: Eth2Node
|
network: Eth2Node
|
||||||
forkVersion: array[4, byte]
|
forkVersion: array[4, byte]
|
||||||
netKeys: DiscKeyPair
|
netKeys: KeyPair
|
||||||
requestManager: RequestManager
|
requestManager: RequestManager
|
||||||
bootstrapNodes: seq[ENode]
|
bootstrapNodes: seq[ENode]
|
||||||
bootstrapEnrs: seq[enr.Record]
|
bootstrapEnrs: seq[enr.Record]
|
||||||
|
@ -187,7 +190,7 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
|
||||||
if fileExists(persistentBootstrapFile):
|
if fileExists(persistentBootstrapFile):
|
||||||
loadBootstrapFile(persistentBootstrapFile, bootNodes, bootEnrs)
|
loadBootstrapFile(persistentBootstrapFile, bootNodes, bootEnrs)
|
||||||
|
|
||||||
bootNodes = filterIt(bootNodes, it.pubkey != netKeys.pubkey)
|
bootNodes = filterIt(bootNodes, it.pubkey != netKeys.pubkey.skkey)
|
||||||
|
|
||||||
let
|
let
|
||||||
network = await createEth2Node(conf, bootNodes)
|
network = await createEth2Node(conf, bootNodes)
|
||||||
|
@ -1117,7 +1120,11 @@ when isMainModule:
|
||||||
tcpPort: Port config.bootstrapPort,
|
tcpPort: Port config.bootstrapPort,
|
||||||
udpPort: Port config.bootstrapPort)
|
udpPort: Port config.bootstrapPort)
|
||||||
|
|
||||||
bootstrapEnr = enr.Record.init(1, networkKeys.seckey, bootstrapAddress)
|
bootstrapEnr = enr.Record.init(
|
||||||
|
1, # sequence number
|
||||||
|
networkKeys.seckey.asEthKey,
|
||||||
|
bootstrapAddress)
|
||||||
|
|
||||||
writeFile(bootstrapFile, bootstrapEnr.toURI)
|
writeFile(bootstrapFile, bootstrapEnr.toURI)
|
||||||
echo "Wrote ", bootstrapFile
|
echo "Wrote ", bootstrapFile
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import
|
import
|
||||||
options, tables, strutils, sequtils,
|
options, tables, strutils, sequtils,
|
||||||
json_serialization, json_serialization/std/net,
|
json_serialization, json_serialization/std/net,
|
||||||
metrics, chronos, chronicles, metrics, libp2p/crypto/secp,
|
metrics, chronos, chronicles, metrics, libp2p/crypto/crypto,
|
||||||
eth/keys, eth/p2p/enode, eth/net/nat, eth/p2p/discoveryv5/enr,
|
eth/keys, eth/p2p/enode, eth/net/nat, eth/p2p/discoveryv5/enr,
|
||||||
eth2_discovery, version, conf
|
eth2_discovery, version, conf
|
||||||
|
|
||||||
type
|
type
|
||||||
DiscKeyPair* = keys.KeyPair
|
KeyPair* = crypto.KeyPair
|
||||||
DiscPrivKey* = keys.PrivateKey
|
PublicKey* = crypto.PublicKey
|
||||||
|
PrivateKey* = crypto.PrivateKey
|
||||||
|
|
||||||
const
|
const
|
||||||
clientId* = "Nimbus beacon node v" & fullVersionStr
|
clientId* = "Nimbus beacon node v" & fullVersionStr
|
||||||
|
@ -66,7 +67,7 @@ when networkBackend in [libp2p, libp2pDaemon]:
|
||||||
import
|
import
|
||||||
os, random,
|
os, random,
|
||||||
stew/io, eth/async_utils,
|
stew/io, eth/async_utils,
|
||||||
libp2p/crypto/crypto as libp2pCrypto, libp2p/[multiaddress, multicodec],
|
libp2p/[multiaddress, multicodec],
|
||||||
ssz
|
ssz
|
||||||
|
|
||||||
export
|
export
|
||||||
|
@ -99,12 +100,11 @@ when networkBackend in [libp2p, libp2pDaemon]:
|
||||||
netBackendName* = "libp2p"
|
netBackendName* = "libp2p"
|
||||||
networkKeyFilename = "privkey.protobuf"
|
networkKeyFilename = "privkey.protobuf"
|
||||||
|
|
||||||
func asLibp2pKey*(key: DiscPrivKey): libp2pCrypto.PrivateKey =
|
func asLibp2pKey*(key: keys.PublicKey): PublicKey =
|
||||||
libp2pCrypto.PrivateKey(scheme: Secp256k1,
|
PublicKey(scheme: Secp256k1, skkey: key)
|
||||||
skkey: SkPrivateKey(data: key.data))
|
|
||||||
|
|
||||||
func asLibp2pKey*(key: keys.PublicKey): libp2pCrypto.PublicKey =
|
func asEthKey*(key: PrivateKey): keys.PrivateKey =
|
||||||
libp2pCrypto.PublicKey(scheme: Secp256k1, skkey: key)
|
keys.PrivateKey(data: key.skkey.data)
|
||||||
|
|
||||||
proc initAddress*(T: type MultiAddress, str: string): T =
|
proc initAddress*(T: type MultiAddress, str: string): T =
|
||||||
let address = MultiAddress.init(str)
|
let address = MultiAddress.init(str)
|
||||||
|
@ -117,29 +117,25 @@ when networkBackend in [libp2p, libp2pDaemon]:
|
||||||
template tcpEndPoint(address, port): auto =
|
template tcpEndPoint(address, port): auto =
|
||||||
MultiAddress.init(address, Protocol.IPPROTO_TCP, port)
|
MultiAddress.init(address, Protocol.IPPROTO_TCP, port)
|
||||||
|
|
||||||
proc genRandomNetKey: DiscPrivKey =
|
|
||||||
let skkey = SkPrivateKey.random
|
|
||||||
DiscPrivKey(data: skkey.data)
|
|
||||||
|
|
||||||
proc ensureNetworkIdFile(conf: BeaconNodeConf): string =
|
proc ensureNetworkIdFile(conf: BeaconNodeConf): string =
|
||||||
result = conf.dataDir / networkKeyFilename
|
result = conf.dataDir / networkKeyFilename
|
||||||
if not fileExists(result):
|
if not fileExists(result):
|
||||||
createDir conf.dataDir.string
|
createDir conf.dataDir.string
|
||||||
let pk = genRandomNetKey()
|
let pk = PrivateKey.random(Secp256k1)
|
||||||
writeFile(result, pk.data)
|
writeFile(result, pk.getBytes)
|
||||||
|
|
||||||
proc getPersistentNetKeys*(conf: BeaconNodeConf): DiscKeyPair =
|
proc getPersistentNetKeys*(conf: BeaconNodeConf): KeyPair =
|
||||||
let privKeyPath = conf.dataDir / networkKeyFilename
|
let privKeyPath = conf.dataDir / networkKeyFilename
|
||||||
var privKey: DiscPrivKey
|
var privKey: PrivateKey
|
||||||
if not fileExists(privKeyPath):
|
if not fileExists(privKeyPath):
|
||||||
createDir conf.dataDir.string
|
createDir conf.dataDir.string
|
||||||
privKey = genRandomNetKey()
|
privKey = PrivateKey.random(Secp256k1)
|
||||||
writeFile(privKeyPath, privKey.data)
|
writeFile(privKeyPath, privKey.getBytes())
|
||||||
else:
|
else:
|
||||||
let strdata = readFile(privKeyPath)
|
let keyBytes = readFile(privKeyPath)
|
||||||
privKey = initPrivateKey(cast[seq[byte]](strdata))
|
privKey = PrivateKey.init(keyBytes.toOpenArrayByte(0, keyBytes.high))
|
||||||
|
|
||||||
DiscKeyPair(seckey: privKey, pubkey: privKey.getPublicKey())
|
KeyPair(seckey: privKey, pubkey: privKey.getKey())
|
||||||
|
|
||||||
proc createEth2Node*(conf: BeaconNodeConf,
|
proc createEth2Node*(conf: BeaconNodeConf,
|
||||||
bootstrapNodes: seq[ENode]): Future[Eth2Node] {.async.} =
|
bootstrapNodes: seq[ENode]): Future[Eth2Node] {.async.} =
|
||||||
|
@ -158,9 +154,9 @@ when networkBackend in [libp2p, libp2pDaemon]:
|
||||||
# TODO nim-libp2p still doesn't have support for announcing addresses
|
# TODO nim-libp2p still doesn't have support for announcing addresses
|
||||||
# that are different from the host address (this is relevant when we
|
# that are different from the host address (this is relevant when we
|
||||||
# are running behind a NAT).
|
# are running behind a NAT).
|
||||||
var switch = newStandardSwitch(some keys.seckey.asLibp2pKey, hostAddress,
|
var switch = newStandardSwitch(some keys.seckey, hostAddress,
|
||||||
triggerSelf = true, gossip = false)
|
triggerSelf = true, gossip = false)
|
||||||
result = Eth2Node.init(conf, switch, keys.seckey)
|
result = Eth2Node.init(conf, switch, keys.seckey.skkey)
|
||||||
else:
|
else:
|
||||||
let keyFile = conf.ensureNetworkIdFile
|
let keyFile = conf.ensureNetworkIdFile
|
||||||
|
|
||||||
|
@ -188,10 +184,10 @@ when networkBackend in [libp2p, libp2pDaemon]:
|
||||||
proc getPersistenBootstrapAddr*(conf: BeaconNodeConf,
|
proc getPersistenBootstrapAddr*(conf: BeaconNodeConf,
|
||||||
ip: IpAddress, port: Port): ENode =
|
ip: IpAddress, port: Port): ENode =
|
||||||
let pair = getPersistentNetKeys(conf)
|
let pair = getPersistentNetKeys(conf)
|
||||||
initENode(pair.pubkey, Address(ip: ip, udpPort: port))
|
initENode(pair.pubkey.skkey, Address(ip: ip, udpPort: port))
|
||||||
|
|
||||||
proc shortForm*(id: DiscKeyPair): string =
|
proc shortForm*(id: KeyPair): string =
|
||||||
$PeerID.init(id.pubkey.asLibp2pKey)
|
$PeerID.init(id.pubkey)
|
||||||
|
|
||||||
proc toPeerInfo(enode: ENode): PeerInfo =
|
proc toPeerInfo(enode: ENode): PeerInfo =
|
||||||
let
|
let
|
||||||
|
|
Loading…
Reference in New Issue