[LibP2P] Persistent network key for the bootstrap node

This commit is contained in:
Zahary Karadjov 2019-06-12 15:23:05 +03:00
parent 12e9367f78
commit 15fdf78d6a
No known key found for this signature in database
GPG Key ID: C8936F8A3073D609
4 changed files with 46 additions and 23 deletions

View File

@ -118,8 +118,8 @@ when networkBackend == rlpxBackend:
else:
import
random,
libp2p/daemon/daemonapi, eth/async_utils,
os, random, std_shims/io,
libp2p/crypto/crypto, libp2p/daemon/daemonapi, eth/async_utils,
ssz
when networkBackend == libp2pSpecBackend:
@ -136,6 +136,9 @@ else:
BootstrapAddr* = PeerInfo
Eth2NodeIdentity* = PeerInfo
const
networkKeyFilename = "privkey.protobuf"
proc writeValue*(writer: var JsonWriter, value: PeerID) {.inline.} =
writer.writeValue value.pretty
@ -151,20 +154,26 @@ else:
proc init*(T: type BootstrapAddr, str: string): T =
Json.decode(str, PeerInfo)
proc createEth2Node*(conf: BeaconNodeConf): Future[Eth2Node] {.async.} =
var node = new Eth2Node
await node.init()
return node
proc ensureNetworkIdFile(conf: BeaconNodeConf): string =
result = conf.dataDir / networkKeyFilename
if not fileExists(result):
createDir conf.dataDir.string
let pk = PrivateKey.random(Ed25519)
writeFile(result, pk.getBytes)
proc getPersistentNetIdentity*(conf: BeaconNodeConf): Eth2NodeIdentity =
# Using waitFor here is reasonable, because this proc is needed only
# prior to connecting to the network. The RLPx alternative reads from
# file and it's much easier to use if it's not async.
# TODO: revisit in the future when we have our own Lib2P2 implementation.
let daemon = waitFor newDaemonApi()
let daemon = waitFor newDaemonApi(id = conf.ensureNetworkIdFile)
result = waitFor daemon.identity()
waitFor daemon.close()
proc createEth2Node*(conf: BeaconNodeConf): Future[Eth2Node] {.async.} =
var daemon = await newDaemonApi({PSGossipSub}, id = conf.ensureNetworkIdFile)
return await Eth2Node.init(daemon)
proc getPersistenBootstrapAddr*(conf: BeaconNodeConf,
ip: IpAddress, port: Port): BootstrapAddr =
# TODO what about the ports?

View File

@ -91,19 +91,20 @@ include libp2p_backends_common
include eth/p2p/p2p_backends_helpers
include eth/p2p/p2p_tracing
proc init*(node: Eth2Node) {.async.} =
node.daemon = await newDaemonApi({PSGossipSub})
node.daemon.userData = node
init node.peers
proc init*(T: type Eth2Node, daemon: DaemonAPI): Future[T] {.async.} =
new result
result.daemon = daemon
result.daemon.userData = result
init result.peers
newSeq node.protocolStates, allProtocols.len
newSeq result.protocolStates, allProtocols.len
for proto in allProtocols:
if proto.networkStateInitializer != nil:
node.protocolStates[proto.index] = proto.networkStateInitializer(node)
result.protocolStates[proto.index] = proto.networkStateInitializer(result)
for msg in proto.messages:
if msg.libp2pProtocol.len > 0:
await node.daemon.addHandler(@[msg.libp2pProtocol], msg.thunk)
await daemon.addHandler(@[msg.libp2pProtocol], msg.thunk)
proc readMsg(stream: P2PStream, MsgType: type,
deadline: Future[void]): Future[Option[MsgType]] {.async.} =

View File

@ -160,17 +160,18 @@ include eth/p2p/p2p_tracing
proc handleConnectingBeaconChainPeer(daemon: DaemonAPI, stream: P2PStream) {.async, gcsafe.}
proc init*(node: Eth2Node) {.async.} =
node.daemon = await newDaemonApi({PSGossipSub})
node.daemon.userData = node
init node.peers
proc init*(T: type Eth2Node, daemon: DaemonAPI): Future[Eth2Node] {.async.} =
new result
result.daemon = daemon
result.daemon.userData = result
result.peers = initTable[PeerID, Peer]()
newSeq node.protocolStates, allProtocols.len
newSeq result.protocolStates, allProtocols.len
for proto in allProtocols:
if proto.networkStateInitializer != nil:
node.protocolStates[proto.index] = proto.networkStateInitializer(node)
result.protocolStates[proto.index] = proto.networkStateInitializer(result)
await node.daemon.addHandler(@[beaconChainProtocol], handleConnectingBeaconChainPeer)
await daemon.addHandler(@[beaconChainProtocol], handleConnectingBeaconChainPeer)
proc init*(T: type Peer, network: Eth2Node, id: PeerID): Peer =
new result

View File

@ -13,12 +13,24 @@ asyncTest "connect two nodes":
var c1 = BeaconNodeConf.defaults
c1.dataDir = OutDir(tempDir / "node-1")
var n1PersistentAddress = c1.getPersistenBootstrapAddr(
parseIpAddress("127.0.0.1"), Port 50000)
var n1 = await createEth2Node(c1)
var n1Address = getPersistenBootstrapAddr(c1, parseIpAddress("127.0.0.1"), Port 50000)
var n1ActualAddress = await n1.daemon.identity()
echo "persistent: ", n1PersistentAddress
echo "actual:", n1ActualAddress
doAssert n1PersistentAddress == n1ActualAddress
echo "Node 1 address: ", n1PersistentAddress
echo "Press any key to continue"
discard stdin.readLine()
var c2 = BeaconNodeConf.defaults
c2.dataDir = OutDir(tempDir / "node-2")
var n2 = await createEth2Node(c2)
await n2.connectToNetwork(bootstrapNodes = @[n1Address])
await n2.connectToNetwork(bootstrapNodes = @[n1ActualAddress])