今天看啥  ›  专栏  ›  狗厂

[英]使用Go实现的去中心化P2P网络协议

狗厂  · 掘金  ·  · 2018-07-11 08:16

Noise: An opinionated, P2P networking stack for decentralized protocols in Go.

github.com/perlin-netw…

Peer-to-peer (P2P) networking is something that is just damn hard to get right.

The thing is, there has been no standardized solution to developing P2P applications that has been widely adopted by any community; with prior open-sourced attempts seeming like some mangled code pulled out of a poor magicians hat.

As a result, we see a lot of projects going for improper P2P networking solutions such as:

  • gRPC, which was intended to be used for micro-services. NOT as a networking stack for trustless P2P applications.
  • Consul, Etcd, and even ZooKeeper, which was intended to be used for service discovery in a trusted, centralized network.

And on the other hand, we see hodgepodges of code such as:

  • libp2p, which feels oddly modular and far too verbose in all the wrong ways as though it was ripped out of IPFS.

In response, we now have a wide array of projects in the decentralized space, rolling out with their own immature networking stacks that are festered with bugs and low-level detail that is making the development of decentralized apps/cryptographic protocols just a huge conglomerated mess.

That is why we‘re releasing our own opinionated solution to this problem by open-sourcing our first project under Perlin called Noise.


What is Noise?

Noise is an opinionated, easy-to-use P2P networking stack for developing decentralized applications and cryptographic protocols written in Go.

In developing Noise, our goals are three-fold:

Developer Ergonomics. Developers should never feel forced to read from and write with, an ugly code mess tied to thousands of unnecessary dependencies with abhorrent documentation while writing secure, high-performance, and low-latency networking systems.

Thousands of decentralized projects produce insightful, yet highly non-reusable code selfishly stuck to the abstractions of their own projects code-base for the sake of showing off their own coding prowess.

Don’t-Repeat-Yourself (DRY). When dealing with security and performance, Noise is opinionated in having developers work with friendly and concise abstractions over battle-tested, high performance, and secure technologies such as Ed25519 signatures, KCP, glog, and protobufs.

Tons of decentralized projects roll out their own custom bug-prone wire serialization formats, networking protocols, cryptosystems and signature schemes which only makes the learning curve for developers more tedious in taking apart/contributing to such projects.

Keep-It-Simple-Stupid (KISS). Developers should feel comfortable in diving through Noise’s code-base, writing decentralized applications with a minimal amount of boilerplate while being backed by sufficient amounts of examples.

Developers should not have to write 200 lines of code while digging through crappy documentation for the sake of writing a hello world application.


How do I use Noise?

Well, lets make a simple decentralized P2P chat application in Go.

Lets make a protobuf file messages/chat.proto representing the structure of a single chat message that we want to be sent/received over the wire.

Lets now generate a cryptographic keypair which represents a peers identity over a network.

We’ll print out the public and private key of the peer using Google’s glog library just for the heck of it.

1 line of code to create a cryptographic peer ID.

Sweet, now lets go on to initiating the networking stack for the app which will listen for incoming peers on port 3000; enabling for peers to connect to you using TCP through address tcp://localhost:3000.

4 lines of code to setup the network.

Should it be the case that you want peers connecting outside of your LAN, just change the address to your remote IPv4 address and port forward on your router port 3000.

We’ll also pop in automatic peer discovery provided by Noise which will automatically bootstrap you to an entire network of peers should you know just a single peers address (rather than all the peers addresses) in the network.

1 line of code for automatic peer discovery based off of a secure Kademlia-inspired routing table structure.

Great, now lets have Noise intercept and handle for incoming chat messages from other peers, and print them out in the format:

<peer address> message here

9 lines of code to receive and process an incoming chat message from other peers.

Lets start up the network, and optionally bootstrap to some peers by their addresses.

5 lines of code to build a network and check for errors, and 1 line of code to specify bootstrapping peers.

There you have it, a full-blown P2P networked application with:

  1. Plug-n-Play Peer Discovery.
  2. Cryptographic Peer IDs.
  3. Cryptographically-signed messages.
  4. Messaging over a reliable, low-latency protocol KCP/TCP.

Oh wait, I forgot: what about sending and broadcasting a chat message over our network of peers?

1 line of code to broadcast a message to an entire network of peers.

There, now you have a full-blown decentralized P2P chat application.

Apart from all this, with Noise you additionally can:

  • Emit messages to specific peers.
if client, err := net.Client("localhost:3001"); err == nil{
err := client.Tell(message here)
}
  • Perform request/response-style RPCs.
if client, err := net.Client("localhost:3001"); err == nil {
response, err := client.Request(request message here)
}
  • Securely transfer files and larger data bodies across peers.
  • Apply exponential reconnection backoff upon peer disconnection.
builder.AddPlugin(new(backoff.Plugin))
  • Automatically port-forward your node’s listening port via. UPnP.
nat.RegisterPlugin(builder)
  • Utilize different cryptosystems and hash functions for node IDs and message verification.
  • Interact with peers in a device and platform-agnostic manner.
  • … and even make custom peer networking topologies using Noise should you not wish to utilize peer discovery.

How fast is Noise?

We did some benchmarks by spawning up aus-east1-b Google Cloud (GCP) cluster comprised of 8 n1-standard-1 (1 vCPU, 3.75GB memory) instances.

Noise is able to sign, send, receive, verify, and process a total of ~10,000 messages per second with complete uptime.

We left the cluster running for ~1 week straight, and continue to have it running to this day.

Although the number 10,000 doesn’t appear to be staggering, keep in mind that this was done over a network with single core machines.

Noise’s infrastructure was made with concurrency and maximum utility of cores in mind, and definitely scales linearly with however many cores you throw at it.


A call for contributions

We’re obviously extremely excited with what people can build with Noise, such as the next BitTorrent, YouTube, Steemit, etc.

Heck, we’re building and stress-testing an entirely decentralized cloud computing market that cryptographically binds computing time and resources from the world’s idle devices into a virtual currency off of Noise.

But obviously: Noise is not perfect.

That’s why we need and want your help to start making Noise a standard for the decentralized ecosystem, and are openly calling for all kinds of contributions.

Just start putting up a PR, or even file an issue to relay to us what we can do to make your experience as a Noise developer better.

And to those who really believe in our mission and would love to get to work with us closer, we are hiring.

To grab our attention, look in the contribution guidelines on our Github, or even feel free to reach out and chat with us on Discord 😄.


’Til next time,

Kenta Iwasaki.




原文地址:访问原文地址
快照地址: 访问文章快照