Libp2p goals and integration plan

p2p

#1

There is a consensus that libp2p integration is useful. But i wanted to summarize what benefits we can expect, and maybe figure out more of them. Second part is mostly technicalities and, i hope, they will help people to review relevant changes.

One of the main reasons why libp2p became so popular is a support of variety of transports. Application can connect from browser using websockets. Or using recent implementation of the QUIC protocol. Also it can use existing or implement transport that fits a particular use case. It was mentioned by @mandrigin that our transport stack can be better optimized for mobile. For example, android app is receiving messages when application is in background. This way it can’t get into sleep mode, constantly consumes cpu and gets reported by android OS. We will be able to improve it by implementing HTTP transport or by managing open TCP connections carefully.

We have a problem that status network depends on servers running on digital ocean and gce. It can solved by running sufficient number of desktop clients consistently. But it is practically impossible to connect to, not from, a desktop client. Desktop client doesn’t advertise itself. Most of them are running at home network and do not have publicly routable ip address. Meaning that they have to bypass some kind of NAT to establish network connection with outer world. Libp2p has the same problem, as any other p2p solution, and they already made several tools to address it. We will be able to re-use those tools and infrastructure to bypass NAT, in some cases, and create a network that won’t depend on our cluster.

We still need people to run clients. But it will be a good start if at least 30 people are running discoverable and consistently available desktop clients.

Another nice thing, it will be possible to connect with the whisper network from a browser. It will require re-implementing whisper and status protocol in javascript. So i won’t expect it to happen soon. But at least it will be possible.

initial integration

The first step is to make whisper run with arbitrary stream. Current solution assumes that rlpx stream will be passed by devp2p server. It already accepts abstracts type for reading and writing messages. We need to add an abstract type for peer identity, instead of using p2p.Peer. Libp2p stream will be wrapped by rlp stream. No other changes are necessary in whisper itself.

In current implementation we are using heartbeats between nodes in the network. Heartbeats are implemented in the devp2p server. They are used to ensure that connection won’t get closed if whisper will go idle and to detect flaky peers. We detect flaky peers to let client know that message from mobile device at least reached any peer in the network. It is not a proper solution. But we decided to go with it to provide some feedback to a client. The plan is to add similar heartbeats either as a separate libp2p stream or add keapalive message type to whisper itself.

In status-go we use peer pool that manages discovery to find target number of peers. Peer pool triggers search in multiple discoveries and adds found peers to a server, controlling target number of those peers. Server provides API for adding and removing peers. Dials peers in the background. And allows to get notification when peer was connected/disconnected. We can do exactly same thing but using APIs provided by libp2p. It will require creating common interface for libp2p and devp2p servers.

Servers that will participate in libp2p network will have to advertise all protocols and addresses they are listening on. We will do it using ENR with a special field for multiaddress. If multiaddress is set, record will be added to libp2p server, if not - to devp2p. We could use same topic for discovery, e.g. whisper for all our relay nodes. But it can be tweaked during development.

Libp2p and devp2p would be physically separate networks. It means that clients running libp2p won’t be able to receive messages from clients running devp2p. The workaround for this problem is to have whisper nodes in the network that run both libp2p and devp2p servers.

what’s next

I plan to wrap up initial integration in a week or two. After that it will be possible to experiment with different transports and start work on exposing desktop clients.

Thanks for reading, if you have questions or concerns please let me know.


#2

When you say libp2p integration, do you mean as for go-ethereum to be merged upstream? For Nimbus Nim implementation of libp2p? Or is this something only for status-go… which would seem weird to me?


#3

this integration is specific to status-go. it will be compatible with geth upstream integration once it will be merged. technically overlap is small and most of the work are around different tools that we are using.

i started to work on this initially cause libp2p already has a number of tools that can help to bypass a nat. then there was an idea that we can have more mobile-friendly transport protocol (instead of devp2p). can you please elaborate why status-go integration seems weird to you?


#4

Well I’d imagine libp2p replaces devp2p for all subprotocols that sit on it, afaik Whisper was the testcase for libp2p, so if it’s iin status-go only, are we expecting the application to maintain 2 seperate p2p networks? libp2p(for Whisper??) and devp2p for (Eth/LES/ULC)?


#5

Practically they are separate even now. We are connected with at most 5 whisper nodes, those nodes are running only whisper. And with 3 full ethereum nodes, as LES requires connection with full node. You are technically right of course that instead of having 8 connections we could have 5. But I don’t think that it will save any noticeable cpu or optimize something significant. We can expect that people will start running upstream whisper nodes, but it didn’t happen in more than 1.5 years, so why should we?

So, yes i imagined that app will be running both libp2p and devp2p connections. devp2p connections will be limited only to the connection with full ethereum node. we will run them in the cluster or get from vipnode integration. and whisper nodes will be connected over libp2p, with dappnodes or desktop clients.

Also nodes will be discovered using same discovery network, discovery v5 and rendezvous. As both LES and WHISPER are simple topics in those networks.


#6

This is our fault - because we didn’t make this happen yet. A better question IMO would be: how do we make this happen?


#7

on the other hand there are a lot of people who are running desktop clients daily. with fast and reliable discovery we can use those nodes instead of cluster, even if they don’t have 100% uptime. and this is something that can be made available now.


#8

desktop option to be a node.


#9

lmao, synchronicity.


#10

Short list of other libp2p efforts, off the top of my head:

On the libp2p side, https://github.com/raulk is generously offering help and is coordinating the eth-libp2p cooperation - had some really good discussions with him in Prague - happy to make introductions with him and others.

The eth2.0 stuff is ways off, so perhaps not too relevant to the app - it’s also slightly different in that it doesn’t consider backwards compatibility with eth1.0 at this stage. Nonetheless a good thing to keep an eye on because eventually the efforts will be merged, with eth2 currently being the free-form experimentation grounds.

As noted, libp2p is pretty cool in that it opens the avenue for several features. However, there are also aspects of it that make it a little more difficult to work with - https://blog.nucypher.com/why-were-rolling-our-own-intra-planetary-node-discovery-at-nucypher-beeb53018b0 outlines some of them.

While it might be tempting to go full whammy from the start, it’s also good to keep in mind that the core philosophy of libp2p is to define small and orthogonal interfaces for functionality - layering, isolation, all that - libp2p the go repo is a reference implementation but it’s probably valuable to approach libp2p from the interface side and see which of those interfaces make sense or need refinement, rather than jumping to the go code directly, so that the discussion happens at a more abstract and impactful level.


#11

sure, what kind of things/layers you think makes sense to discuss?
current plan is mostly straightforward. as a start we will use secio+tcp/websocket/? instead of rlpx stream for whisper communication. we won’t use any libp2p discovery tools. they have kad-based discovery and their own version of rendezvous. but we will stick with discovery v5 and ENR-rendezvous. also i was planning to add dns discovery, once it gets finalized in ethereum EIPs.

this is kinda the same idea that will be implemented in geth https://github.com/ethereum/devp2p/issues/45#issuecomment-423645814 . the difference is only about how it will be integrated codewise. and timeline i guess


#12

What do people here think of MetaMask’s work? https://github.com/MetaMask/mustekala


#13

this is more of a side-network that stores state in ipfs and uses libp2p to disseminate updates between clients. it cannot using libp2p directly connect to geth node. current architecture describers that some nodes (layer 1 in mustekala docs) will be getting state from geth/parity and storing it in ipfs.

i like the project and idea that light clients can collectively store the state that is easy to consume for every new client. i don’t completely understand safety assumptions, for example, it seems to me that every client still need to validate blocks advertised in that network and maintain a view of the canonical chain based on that.

this is definitely something that status app can participate in and benefit from. i think it might scale better then maintaining direct connection with full ethereum node from every client. but probably in short/medium term we will use what geth provides.