README.md 5.42 KB
Newer Older
Jeromy's avatar
Jeromy committed
1 2 3
go-libp2p-swarm
==================

Yusef Napora's avatar
Yusef Napora committed
4 5 6
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)
[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/)
[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p)
Jeromy's avatar
Jeromy committed
7 8
[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-libp2p-swarm/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-libp2p-swarm?branch=master)
[![Travis CI](https://travis-ci.org/libp2p/go-libp2p-swarm.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-swarm)
Yusef Napora's avatar
Yusef Napora committed
9
[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io)
Jeromy's avatar
Jeromy committed
10 11 12

> The libp2p swarm manages groups of connections to peers, and handles incoming and outgoing streams.

Jeromy's avatar
Jeromy committed
13 14 15 16
The libp2p swarm is the 'low level' interface for working with a given libp2p
network. It gives you more fine grained control over various aspects of the
system. Most applications don't need this level of access, so the `Swarm` is
generally wrapped in a `Host` abstraction that provides a more friendly
17
interface. See [the host interface](https://godoc.org/github.com/libp2p/go-libp2p-core/host#Host)
Jeromy's avatar
Jeromy committed
18
for more info on that.
Jeromy's avatar
Jeromy committed
19 20 21 22 23 24 25 26 27 28 29 30 31

## Table of Contents

- [Install](#install)
- [Contribute](#contribute)
- [License](#license)

## Install

```sh
make install
```

Jeromy's avatar
Jeromy committed
32 33
## Usage

Jeromy's avatar
Jeromy committed
34
### Creating a swarm
Jeromy's avatar
Jeromy committed
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
To construct a swarm, you'll be calling `NewSwarm`. That function looks like this:
```go
swarm, err := NewSwarm(ctx, laddrs, pid, pstore, bwc)
```

It takes five items to fully construct a swarm, the first is a go
`context.Context`. This controls the lifetime of the swarm, and all swarm
processes have their lifespan derived from the given context. You can just use
`context.Background()` if you're not concerned with that.

The next argument is an array of multiaddrs that the swarm will open up
listeners for. Once started, the swarm will start accepting and handling
incoming connections on every given address. This argument is optional, you can
pass `nil` and the swarm will not listen for any incoming connections (but will
still be able to dial out to other peers).

After that, you'll need to give the swarm an identity in the form of a peer.ID.
If you're not wanting to enable secio (libp2p's transport layer encryption),
then you can pick any string for this value. For example `peer.ID("FooBar123")`
would work. Note that passing a random string ID will result in your node not
being able to communicate with other peers that have correctly generated IDs.
To see how to generate a proper ID, see the below section on "Identity
Generation".

The fourth argument is a peerstore. This is essentially a database that the
swarm will use to store peer IDs, addresses, public keys, protocol preferences
and more. You can construct one by importing
`github.com/libp2p/go-libp2p-peerstore` and calling `peerstore.NewPeerstore()`.

The final argument is a bandwidth metrics collector, This is used to track
incoming and outgoing bandwidth on connections managed by this swarm. It is
optional, and passing `nil` will simply result in no metrics for connections
being available.

Jeromy's avatar
Jeromy committed
69
#### Identity Generation
Jeromy's avatar
Jeromy committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
A proper libp2p identity is PKI based. We currently have support for RSA and ed25519 keys. To create a 'correct' ID, you'll need to either load or generate a new keypair. Here is an example of doing so:

```go
import (
	"fmt"
	"crypto/rand"

	ci "github.com/libp2p/go-libp2p-crypto"
	pstore "github.com/libp2p/go-libp2p-peerstore"
	peer "github.com/libp2p/go-libp2p-peer"
)

func demo() {
	// First, select a source of entropy. We're using the stdlib's crypto reader here
	src := rand.Reader

	// Now create a 2048 bit RSA key using that
	priv, pub, err := ci.GenerateKeyPairWithReader(ci.RSA, 2048, src)
	if err != nil {
		panic(err) // oh no!
	}

	// Now that we have a keypair, lets create our identity from it
	pid, err := peer.IDFromPrivateKey(priv)
	if err != nil {
		panic(err)
	}

	// Woo! Identity acquired!
	fmt.Println("I am ", pid)

	// Now, for the purposes of building a swarm, lets add this all to a peerstore.
	ps := pstore.NewPeerstore()
	ps.AddPubKey(pid, pub)
	ps.AddPrivKey(pid, priv)

	// Once you've got all that, creating a basic swarm can be as easy as
	ctx := context.Background()
	swarm, err := NewSwarm(ctx, nil, pid, ps, nil)

Nicolas Talle's avatar
Nicolas Talle committed
110
	// voila! A functioning swarm!
Jeromy's avatar
Jeromy committed
111 112 113
}
```

Jeromy's avatar
Jeromy committed
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
### Streams
The swarm is designed around using multiplexed streams to communicate with
other peers. When working with a swarm, you will want to set a function to
handle incoming streams from your peers:

```go
swrm.SetStreamHandler(func(s inet.Stream) {
	defer s.Close()
	fmt.Println("Got a stream from: ", s.SwarmConn().RemotePeer())
	fmt.Fprintln(s, "Hello Friend!")
})
```

Tip: Always make sure to close streams when you're done with them.

Opening streams is also pretty simple:
```go
s, err := swrm.NewStreamWithPeer(ctx, rpid)
if err != nil {
	panic(err)
}
defer s.Close()

io.Copy(os.Stdout, s) // pipe the stream to stdout
```

Just pass a context and the ID of the peer you want a stream to, and you'll get
back a stream to read and write on.

Jeromy's avatar
Jeromy committed
143

Jeromy's avatar
Jeromy committed
144 145 146 147 148 149 150 151 152
## Contribute

PRs are welcome!

Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.

## License

MIT © Jeromy Johnson
153 154 155 156

---

The last gx published version of this module was: 3.0.35: QmQVoMEL1CxrVusTSUdYsiJXVBnvSqNUpBsGybkwSfksEF