Skip to content

Commit

Permalink
Merge pull request #48 from ipfs/libp2p/interfaces
Browse files Browse the repository at this point in the history
libp2p - [WIP] Update the Interfaces chapter
  • Loading branch information
daviddias committed Dec 12, 2015
2 parents 704df04 + d6161dc commit f2b250b
Showing 1 changed file with 55 additions and 95 deletions.
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.

- `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

## 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.

0 comments on commit f2b250b

Please sign in to comment.