This commit is contained in:
Yuriy Glukhov 2019-11-06 16:56:54 +02:00 committed by Eugene Kabanov
parent f79f9deeb3
commit 9b39c792d0
9 changed files with 55 additions and 87 deletions

View File

@ -113,7 +113,7 @@ proc addBootstrapNode(node: BeaconNode, bootstrapNode: BootstrapAddr) =
proc useBootstrapFile(node: BeaconNode, bootstrapFile: string) =
for ln in lines(bootstrapFile):
node.addBootstrapNode BootstrapAddr.initAddress(string ln)
node.addBootstrapNode BootstrapAddr.init(string ln)
proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async.} =
new result
@ -756,8 +756,6 @@ proc run*(node: BeaconNode) =
addTimer(second) do (p: pointer):
asyncCheck node.onSecond(second)
asyncCheck node.network.backendLoop()
runForever()
var gPidFile: string
@ -975,7 +973,10 @@ when isMainModule:
let bootstrapFile = config.outputBootstrapFile.string
if bootstrapFile.len > 0:
let bootstrapAddrLine = $bootstrapAddress
let bootstrapAddrLine = when networkBackend != rlpxBackend:
$bootstrapAddress.addresses[0] & "/p2p/" & bootstrapAddress.peer.pretty
else:
$bootstrapAddress
writeFile(bootstrapFile, bootstrapAddrLine)
echo "Wrote ", bootstrapFile

View File

@ -144,7 +144,7 @@ else:
else:
import
libp2p/daemon/daemonapi, libp2p/multiaddress, libp2p_daemon_backend
libp2p/daemon/daemonapi, libp2p_daemon_backend
export
libp2p_daemon_backend
@ -154,16 +154,19 @@ else:
networkKeyFilename = "privkey.protobuf"
type
BootstrapAddr* = MultiAddress
Eth2NodeIdentity* = KeyPair
BootstrapAddr* = PeerInfo
Eth2NodeIdentity* = PeerInfo
proc initAddress*(T: type BootstrapAddr, str: string): T =
let address = MultiAddress.init(str)
if IPFS.match(address) and matchPartial(multiaddress.TCP, address):
result = address
proc init*(T: type BootstrapAddr, str: string): T =
# TODO: The code below is quite awkward.
# How do we parse a PeerInfo object out of a bootstrap MultiAddress string such as:
# /ip4/10.20.30.40/tcp/9100/p2p/16Uiu2HAmEAmp4FdpPzypKwTMmsbCdnUafDvXZCpFrUDbYJZNk7hX
var parts = str.split("/p2p/")
if parts.len == 2:
result.peer = PeerID.init(parts[1])
result.addresses.add MultiAddress.init(parts[0])
else:
raise newException(MultiAddressError,
"Invalid bootstrap node multi-address")
raise newException(ValueError, "Invalid bootstrap multi-address")
proc ensureNetworkIdFile(conf: BeaconNodeConf): string =
result = conf.dataDir / networkKeyFilename
@ -173,17 +176,13 @@ else:
writeFile(result, pk.getBytes)
proc getPersistentNetIdentity*(conf: BeaconNodeConf): Eth2NodeIdentity =
let privateKeyFile = conf.dataDir / networkKeyFilename
var privKey: PrivateKey
if not fileExists(privateKeyFile):
createDir conf.dataDir.string
privKey = PrivateKey.random(Secp256k1)
writeFile(privateKeyFile, privKey.getBytes())
else:
let strdata = readFile(privateKeyFile)
privKey = PrivateKey.init(cast[seq[byte]](strdata))
result = KeyPair(seckey: privKey, pubkey: privKey.getKey())
# 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(id = conf.ensureNetworkIdFile)
result = waitFor daemon.identity()
waitFor daemon.close()
template tcpEndPoint(address, port): auto =
MultiAddress.init(address, Protocol.IPPROTO_TCP, port)
@ -192,7 +191,8 @@ else:
proc allMultiAddresses(nodes: seq[BootstrapAddr]): seq[string] =
for node in nodes:
result.add $node
for a in node.addresses:
result.add $a & "/ipfs/" & node.peer.pretty()
proc createEth2Node*(conf: BeaconNodeConf,
bootstrapNodes: seq[BootstrapAddr]): Future[Eth2Node] {.async.} =
@ -219,11 +219,10 @@ else:
bootstrapNodes = allMultiAddresses(bootstrapNodes),
peersRequired = 1)
info "Daemon started"
mainDaemon = await daemonFut
info "LibP2P daemon started"
proc closeDaemon() {.noconv.} =
info "Shutting down the LibP2P daemon"
waitFor mainDaemon.close()
@ -233,24 +232,33 @@ else:
proc getPersistenBootstrapAddr*(conf: BeaconNodeConf,
ip: IpAddress, port: Port): BootstrapAddr =
let pair = getPersistentNetIdentity(conf)
let pidma = MultiAddress.init(multiCodec("p2p"), PeerID.init(pair.pubkey))
result = tcpEndPoint(ip, port) & pidma
result = getPersistentNetIdentity(conf)
result.addresses = @[tcpEndPoint(ip, port)]
proc isSameNode*(bootstrapNode: BootstrapAddr, id: Eth2NodeIdentity): bool =
if IPFS.match(bootstrapNode):
let pid1 = PeerID.init(bootstrapNode[2].protoAddress())
let pid2 = PeerID.init(id.pubkey)
result = (pid1 == pid2)
bootstrapNode.peer == id.peer
proc shortForm*(id: Eth2NodeIdentity): string =
$PeerID.init(id.pubkey)
# TODO: Make this shorter
$id
proc connectToNetwork*(node: Eth2Node,
bootstrapNodes: seq[MultiAddress]) {.async.} =
## go-libp2p-daemon will perform connection to the network automatically,
## we just need to follow it.
discard
proc connectToNetwork*(node: Eth2Node, bootstrapNodes: seq[PeerInfo]) {.async.} =
# TODO: perhaps we should do these in parallel
var connected = false
for bootstrapNode in bootstrapNodes:
try:
await node.daemon.connect(bootstrapNode.peer, bootstrapNode.addresses)
var peer = node.getPeer(bootstrapNode.peer)
peer.wasDialed = true
await initializeConnection(peer)
connected = true
except CatchableError as err:
error "Failed to connect to bootstrap node",
node = bootstrapNode, err = err.msg
if bootstrapNodes.len > 0 and connected == false:
fatal "Failed to connect to any bootstrap node. Quitting."
quit 1
proc saveConnectionAddressFile*(node: Eth2Node, filename: string) =
let id = waitFor node.daemon.identity()

View File

@ -470,9 +470,6 @@ proc init*[MsgType](T: type Responder[MsgType],
peer: Peer, stream: P2PStream): T =
T(UntypedResponder(peer: peer, stream: stream))
proc backendLoop*(node: Eth2Node) {.async.} =
discard
import
typetraits

View File

@ -8,8 +8,6 @@ import
export
daemonapi, p2pProtocol, libp2p_json_serialization, ssz
logScope: topics = "lp2pdab"
type
Eth2Node* = ref object of RootObj
daemon*: DaemonAPI
@ -472,43 +470,6 @@ proc init*[MsgType](T: type Responder[MsgType],
peer: Peer, stream: P2PStream): T =
T(UntypedResponder(peer: peer, stream: stream))
proc backendLoop*(node: Eth2Node) {.async.} =
var peerFuts = newSeq[Future[void]]()
var peerStore = newSeq[tuple[peer: Peer, future: Future[void]]]()
while true:
var list = await node.daemon.listPeers()
peerFuts.setLen(0)
peerStore.setLen(0)
for item in list:
var peerCheck = node.peers.getOrDefault(item.peer)
if isNil(peerCheck):
var peer = node.getPeer(item.peer)
peer.wasDialed = true
info "Handshaking with new peer", peer = item.peer.pretty(),
addresses = item.addresses
let fut = initializeConnection(peer)
peerStore.add((peer, fut))
peerFuts.add(fut)
await allFutures(peerFuts)
for item in peerFuts:
var peer: Peer
for storeItem in peerStore:
if item == storeItem.future:
peer = storeItem.peer
break
if item.finished():
info "Handshake with peer succeeded", peer = peer.id.pretty(),
peers = len(node.peers)
elif item.failed():
info "Handshake with peer failed", peer = peer.id.pretty(),
peers = len(node.peers),
error = item.error.msg
await sleepAsync(1.seconds)
import
typetraits

View File

@ -106,7 +106,7 @@ p2pProtocol BeaconSync(version = 1,
if theirStatus.isSome:
await peer.handleInitialStatus(node, ourStatus, theirStatus.get)
else:
warn "Status response not received in time", peer = peer.id.pretty()
warn "Status response not received in time"
onPeerDisconnected do (peer: Peer):
libp2p_peers.set peer.network.peers.len.int64
@ -234,3 +234,4 @@ proc handleInitialStatus(peer: Peer,
except CatchableError:
warn "Failed to sync with peer", peer, err = getCurrentExceptionMsg()

@ -1 +1 @@
Subproject commit 173c7b4a86e6d75a69577166526b0f5840c45003
Subproject commit 88b79e230005d8301c3ae950abdbf8ad55e37f19

2
vendor/nim-libp2p vendored

@ -1 +1 @@
Subproject commit 1c16eb5d69a9fb8e9577d68d3fb97843a40d31a4
Subproject commit f3fc763895986e96d53349e0696c897303104765

@ -1 +1 @@
Subproject commit 448a03ed4bd5837e18a3c50e10c6e31d25a6c9e5
Subproject commit ae60eef4e8413e49fb0dbcae9a343fb479509fa0

2
vendor/nim-web3 vendored

@ -1 +1 @@
Subproject commit 37fc46111489bc521731b59f52f42b6327fa7829
Subproject commit 7bc29e747004b8aa7988eab537029ecab73dcb45