diff --git a/libp2p/6-interfaces.md b/libp2p/6-interfaces.md index 5826abb6a..e0303436c 100644 --- a/libp2p/6-interfaces.md +++ b/libp2p/6-interfaces.md @@ -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('', 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.