Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libp2p - [WIP] Update the Interfaces chapter #48

Merged
merged 5 commits into from
Dec 12, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 55 additions & 95 deletions libp2p/6-interfaces.md
Original file line number Diff line number Diff line change
@@ -1,139 +1,99 @@
6 Interfaces
============

`libp2p` is a collection of several protocols working together to offer a common solid interface with talking with any other network addressable process. This is made possible by shimming current exist protocols and implementations through a set of explicit interfaces, from Peer Routing, Discovery, Stream Muxing, Transports, Connections and so on.

## 6.1 libp2p

libp2p, the top module that interfaces all the other modules that make a libp2p instance, must offer an interface for dialing to a peer and plugging in all of the modules (e.g. which transports) we want to support. We present libp2p interface and UX on setion 6.6, after presenting every other module interface.

## 6.2 Peer Routing

## 6.3 Swarm
![](https://raw.githubusercontent.com/diasdavid/abstract-peer-routing/master/img/badge.png)

~~The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like:~~
A Peer Routing service offers a way for libp2p Node to find the PeerInfo of another Node, so that it can dial to that node. In it is most pure form, a Peer Routing module should have a interface that given a 'key', a set of PeerInfos are returned.
See https://github.com/diasdavid/abstract-peer-routing for the interface and tests.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this LGTM.

we may have to rethink some of it when we address peer packet switching.


- `sw.addTransport(transport, [options, dialOptions, listenOptions])` - Add a transport to be supported by this swarm instance. Swarm expects it to implement the [abstract-transport](https://github.com/diasdavid/abstract-transport) interface.
- `sw.addUpgrade(connUpgrade, [options])` - A connection upgrade must be able to receive and return something that implements the [abstract-connection](https://github.com/diasdavid/abstract-connection) interface.
- `sw.addStreamMuxer(streamMuxer, [options])` - Upgrading a connection to use a stream muxer is still considered an upgrade, but a special case since once this connection is applied, the returned obj will implement the abstract-stream-muxer interface.
- `sw.dial(PeerInfo, options, protocol, callback)` - PeerInfo should contain the ID of the peer and its respective multiaddrs known.
- `sw.handleProtocol(protocol, handlerFunction)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol
## 6.3 Swarm

The following figure represents how the network level pieces, are tied together:
Current interface available and updated at:

```
┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌───────────┐
mounted │ mounted │ mounted ││Identify │
│protocol │protocol │protocol │(mounted │
1 │ 2 │ ... ││ protocol) │
└ ─ ─ ─ ─ └ ─ ─ ─ ─ └ ─ ─ ─ ─ └───────────┘
┌─────────────────────────────────────────┐
│ swarm │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ connection │
└─────────────────────────────────────────┘
┌───────────────┐┌───────────┐┌───────────┐
│Transport ││multistream││ stream │
│(TCP, UDP, etc)││ ││ muxer │
└───────────────┘└───────────┘│┌ ─ ─ ─ ─ ┐│
│ spdy │
│└ ─ ─ ─ ─ ┘│
│┌ ─ ─ ─ ─ ┐│
│ multiplex │
│└ ─ ─ ─ ─ ┘│
│┌ ─ ─ ─ ─ ┐│
│ QUIC │
│└ ─ ─ ─ ─ ┘│
│┌ ─ ─ ─ ─ ┐│
│ others │
│└ ─ ─ ─ ─ ┘│
└───────────┘
```
https://github.com/diasdavid/js-libp2p-swarm#usage
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbenet @whyrusleeping would you like to bikeshed a bit these function calls? Same goes for the "abstract-", so that they get written on the spec and making everyone happy

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbenet @whyrusleeping would you like to bikeshed a bit these function calls? Same goes for the "abstract-", so that they get written on the spec and making everyone happy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have the interface in the specs, if not in this page in a swarm page or something.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is currently available on the swarm README, I can copy over. I was hoping for the bikeshed to happen there, so that we don't have to maintain two copies while we discuss the API

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok!


## 6.4 Distributed Record Store
### 6.3.1 Transport

![](https://raw.githubusercontent.com/diasdavid/abstract-transport/master/img/badge.png)

https://github.com/diasdavid/abstract-transport

### 6.3.2 Connection

![](https://raw.githubusercontent.com/diasdavid/abstract-connection/master/img/badge.png)

https://github.com/diasdavid/abstract-connection

### 6.3.3 Stream Muxing

![](https://github.com/diasdavid/abstract-stream-muxer/raw/master/img/badge.png)

----------------------------
OLD
The network protocol's interface has two parts:A
https://github.com/diasdavid/abstract-stream-muxer

1. the _client interface_, for clients (e.g. higher layers of IPFS)
2. the _service interface_, for remote peers (e.g. other IPFS nodes)
## 6.4 Distributed Record Store

![](https://raw.githubusercontent.com/diasdavid/abstract-record-store/master/img/badge.png)

### 4.1 Client Interface
https://github.com/diasdavid/abstract-record-store

The **Client Interface** is exposed to the higher layers of IPFS. It is the entry point for other parts to open + handle streams.

This type system represents the interface exposed to clients. Actual implementations will likely be more complicated, but they should aim to cover this.
## 6.5 Peer Discovery

```go
type PrivateKey interface {
PublicKey() PublicKey
A Peer Discovery system interface should return PeerInfo objects, as it finds new peers to be considered to our Peer Routing schemes

Sign(data []byte) Signature
Decrypt(ciphertext []byte) (plaintext []byte)
}
## 6.6 libp2p interface and UX

type PublicKey interface {
PeerID() PeerID
libp2p implementations should enable for it to be instantiated programatically, or to use a previous compiled lib some of the protocol decisions already made, so that the user can reuse or expand.

Verify(Signature) (ok bool)
Encrypt(plaintext []byte) (ciphertext []byte)
}
### Constructing libp2p instance programatically

// PeerID is a hash of a PublicKey, encoded in multihash
// It represents the identity of a node.
type PeerID Multihash
Example made with JavaScript, should be mapped to other languages

// Node is a peer in the network. It is both a client and server.
// Users may open streams to remote peers, or set handlers for protocols.
type Node interface {
// ID returns the PeerID of this Node
ID() PeerID
```JavaScript
var Libp2p = require('libp2p')

// NewStream creates a new stream to given peerID.
// It may have to establish a new connection to given peer.
// (This includes finding the addresses of a peer, and NAT Traversal.)
NewStream(Protocol, PeerID) (Stream, error)
var node = new Libp2p()

// SetStreamHandler sets a callback for remote-opened streams for a protocol
// Thus clients register "protocol handlers", much like URL route handlers
SetStreamHandler(Protocol, StreamHandler)
// add a swarm instance
node.addSwarm(swarmInstance)

// Raw connections are not exported to the user, only streams.
}
// add one or more Peer Routing mechanisms
node.addPeerRouting(peerRoutingInstance)

type StreamHandler func (Stream)
// add a Distributed Record Store
node.addDistributedRecordStore(distributedRecordStoreInstance)
```

TODO: incorporate unreliable message / packet streams.
Configuring libp2p is quite straight forward since most of the configuration comes from instantiating the several modules, one at each time.

### Dialing and Listening for connections to/from a peer

### 4.2 Protocol Interface
Ideally, libp2p uses its own mechanisms (PeerRouting and Record Store) to find a way to dial to a given peer

The network protocol consists of:
```JavaScript
node.dial(PeerInfo)
```

To receive an incoming connection, specify one or more protocols to handle

- Any secure, reliable, stream transport:
- a reliable transport protocol (TCP, QUIC, SCTP, UDT, UTP, ...)
- a secure PKI based transport protocol (SSH, TLS, ...)
- a stream transport (with flow control, etc) (HTTP2, SSH, QUIC)
- Protocol stream framing, to multiplex services
- Auxiliary protocols for connectivity:
- Identify - exchange node information
- NAT - NAT Traversal (ICE)
- Relay - for when NAT Traversal fails
```JavaScript
node.handleProtocol('<multicodec>', function (duplexStream) {

Both the transport and stream muxer are pluggable. Unless
constraints dictate otherwise, implementations SHOULD implement TCP and HTTP/2
for interoperability. These are the default
})
```

- any reliable transport protocol
- a secure channel encryption
- a stream multiplexor with flow control (e.g. HTTP/2, SPDY, QUIC, SSH)
- every stream protocol header
### Finding a peer

(TODO: unreliable transport)
Finding a peer functionality is done through Peer Routing, so the interface is the same.

### Storing and Retrieving Records

Like Finding a Peer, Storing and Retrieving records is done through Record Store, so the interface is the same.