Skip to content

Commit

Permalink
Merge branch 'master' into validate-certhashes
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaseizinger authored Jun 3, 2023
2 parents c090e79 + 75edcfc commit 0efc0a5
Show file tree
Hide file tree
Showing 29 changed files with 516 additions and 348 deletions.
41 changes: 41 additions & 0 deletions examples/autonat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## Description

This example consists of a client and a server, which demonstrate the usage of the AutoNAT and identify protocols in **libp2p**.

## Usage

### Client

The client-side part of the example showcases the combination of the AutoNAT and identify protocols.
The identify protocol allows the local peer to determine its external addresses, which are then included in AutoNAT dial-back requests sent to the server.

To run the client example, follow these steps:

1. Start the server by following the instructions provided in the `examples/server` directory.

2. Open a new terminal.

3. Run the following command in the terminal:
```sh
cargo run --bin autonat_client -- --server-address <server-addr> --server-peer-id <server-peer-id> --listen-port <port>
```
Note: The `--listen-port` parameter is optional and allows you to specify a fixed port at which the local client should listen.

### Server

The server-side example demonstrates a basic AutoNAT server that supports the autonat and identify protocols.

To start the server, follow these steps:

1. Open a terminal.

2. Run the following command:
```sh
cargo run --bin autonat_server -- --listen-port <port>
```
Note: The `--listen-port` parameter is optional and allows you to set a fixed port at which the local peer should listen.

## Conclusion

By combining the AutoNAT and identify protocols, the example showcases the establishment of direct connections between peers and the exchange of external address information.
Users can explore the provided client and server code to gain insights into the implementation details and functionality of **libp2p**.
11 changes: 1 addition & 10 deletions examples/autonat/src/bin/autonat_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Basic example that combines the AutoNAT and identify protocols.
//!
//! The identify protocol informs the local peer of its external addresses, that are then send in AutoNAT dial-back
//! requests to the server.
//!
//! To run this example, follow the instructions in `examples/server` to start a server, then run in a new terminal:
//! ```sh
//! cargo run --bin autonat_client -- --server-address <server-addr> --server-peer-id <server-peer-id> --listen-port <port>
//! ```
//! The `listen-port` parameter is optional and allows to set a fixed port at which the local client should listen.
#![doc = include_str!("../../README.md")]

use clap::Parser;
use futures::prelude::*;
Expand Down
8 changes: 1 addition & 7 deletions examples/autonat/src/bin/autonat_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Basic example for a AutoNAT server that supports the /libp2p/autonat/1.0.0 and "/ipfs/0.1.0" protocols.
//!
//! To start the server run:
//! ```sh
//! cargo run --bin autonat_server -- --listen-port <port>
//! ```
//! The `listen-port` parameter is optional and allows to set a fixed port at which the local peer should listen.
#![doc = include_str!("../../README.md")]

use clap::Parser;
use futures::prelude::*;
Expand Down
30 changes: 30 additions & 0 deletions examples/chat-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Description

A basic chat application with logs demonstrating libp2p and the gossipsub protocol combined with mDNS for the discovery of peers to gossip with.
It showcases how peers can connect, discover each other using mDNS, and engage in real-time chat sessions.

## Usage

1. Using two terminal windows, start two instances, typing the following in each:
```sh
cargo run
```

2. Mutual mDNS discovery may take a few seconds. When each peer does discover the other
it will print a message like:
```sh
mDNS discovered a new peer: {peerId}
```

3. Type a message and hit return: the message is sent and printed in the other terminal.

4. Close with `Ctrl-c`. You can open more terminal windows and add more peers using the same line above.

When a new peer is discovered through mDNS, it can join the conversation, and all peers will receive messages sent by that peer.
If a participant exits the application using `Ctrl-c` or any other method, the remaining peers will receive an mDNS expired event and remove the expired peer from their list of known peers.

## Conclusion

This chat application demonstrates the usage of **libp2p** and the gossipsub protocol for building a decentralized chat system.
By leveraging mDNS for peer discovery, users can easily connect with other peers and engage in real-time conversations.
The example provides a starting point for developing more sophisticated chat applications using **libp2p** and exploring the capabilities of decentralized communication.
27 changes: 1 addition & 26 deletions examples/chat-example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! A basic chat application with logs demonstrating libp2p and the gossipsub protocol
//! combined with mDNS for the discovery of peers to gossip with.
//!
//! Using two terminal windows, start two instances, typing the following in each:
//!
//! ```sh
//! cargo run
//! ```
//!
//! Mutual mDNS discovery may take a few seconds. When each peer does discover the other
//! it will print a message like:
//!
//! ```sh
//! mDNS discovered a new peer: {peerId}
//! ```
//!
//! Type a message and hit return: the message is sent and printed in the other terminal.
//! Close with Ctrl-c.
//!
//! You can open more terminal windows and add more peers using the same line above.
//!
//! Once an additional peer is mDNS discovered it can participate in the conversation
//! and all peers will receive messages sent from it.
//!
//! If a participant exits (Control-C or otherwise) the other peers will receive an mDNS expired
//! event and remove the expired peer from the list of known peers.
#![doc = include_str!("../README.md")]

use async_std::io;
use futures::{future::Either, prelude::*, select};
Expand Down
35 changes: 35 additions & 0 deletions examples/dcutr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Description

The "Direct Connection Upgrade through Relay" (DCUTR) protocol allows peers in a peer-to-peer network to establish direct connections with each other.
In other words, DCUTR is libp2p's version of hole-punching.
This example provides a basic usage of this protocol in **libp2p**.

## Usage

To run the example, follow these steps:

1. Run the example using Cargo:
```sh
cargo run -- <OPTIONS>
```
Replace `<OPTIONS>` with specific options (you can use the `--help` command to see the available options).

### Example usage

- Example usage in client-listen mode:
```sh
cargo run -- --mode listen --secret-key-seed 42 --relay-address /ip4/127.0.0.1/tcp/12345
```

- Example usage in client-dial mode:
```sh
cargo run -- --mode dial --secret-key-seed 42 --relay-address /ip4/127.0.0.1/tcp/12345 --remote-peer-id <REMOTE_PEER_ID>
```

For this example to work, it is also necessary to turn on a relay server (you will find the related instructions in the example in the `examples/relay-server` folder).

## Conclusion

The DCUTR protocol offers a solution for achieving direct connectivity between peers in a peer-to-peer network.
By utilizing hole punching and eliminating the need for signaling servers, the protocol allows peers behind NATs to establish direct connections.
This example provides instructions on running an example implementation of the protocol, allowing users to explore its functionality and benefits.
2 changes: 2 additions & 0 deletions examples/dcutr/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

#![doc = include_str!("../README.md")]

use clap::Parser;
use futures::{
executor::{block_on, ThreadPool},
Expand Down
42 changes: 42 additions & 0 deletions examples/distributed-key-value-store/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## Description

This example showcases a basic distributed key-value store implemented using **libp2p**, along with the mDNS and Kademlia protocols.

## Usage

### Key-Value Store

1. Open two terminal windows, type `cargo run` and press Enter.

2. In terminal one, type `PUT my-key my-value` and press Enter.
This command will store the value `my-value` with the key `my-key` in the distributed key-value store.

3. In terminal two, type `GET my-key` and press Enter.
This command will retrieve the value associated with the key `my-key` from the key-value store.

4. To exit, press `Ctrl-c` in each terminal window to gracefully close the instances.


### Provider Records

You can also use provider records instead of key-value records in the distributed store.

1. Open two terminal windows and start two instances of the key-value store.
If your local network supports mDNS, the instances will automatically connect.

2. In terminal one, type `PUT_PROVIDER my-key` and press Enter.
This command will register the peer as a provider for the key `my-key` in the distributed key-value store.

3. In terminal two, type `GET_PROVIDERS my-key` and press Enter.
This command will retrieve the list of providers for the key `my-key` from the key-value store.

4. To exit, press `Ctrl-c` in each terminal window to gracefully close the instances.


Feel free to explore and experiment with the distributed key-value store example, and observe how the data is distributed and retrieved across the network using **libp2p**, mDNS, and the Kademlia protocol.

## Conclusion

This example demonstrates the implementation of a basic distributed key-value store using **libp2p**, mDNS, and the Kademlia protocol.
By leveraging these technologies, peers can connect, store, and retrieve key-value pairs in a decentralized manner.
The example provides a starting point for building more advanced distributed systems and exploring the capabilities of **libp2p** and its associated protocols.
22 changes: 1 addition & 21 deletions examples/distributed-key-value-store/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! A basic key value store demonstrating libp2p and the mDNS and Kademlia protocols.
//!
//! 1. Using two terminal windows, start two instances. If you local network
//! allows mDNS, they will automatically connect.
//!
//! 2. Type `PUT my-key my-value` in terminal one and hit return.
//!
//! 3. Type `GET my-key` in terminal two and hit return.
//!
//! 4. Close with Ctrl-c.
//!
//! You can also store provider records instead of key value records.
//!
//! 1. Using two terminal windows, start two instances. If you local network
//! allows mDNS, they will automatically connect.
//!
//! 2. Type `PUT_PROVIDER my-key` in terminal one and hit return.
//!
//! 3. Type `GET_PROVIDERS my-key` in terminal two and hit return.
//!
//! 4. Close with Ctrl-c.
#![doc = include_str!("../README.md")]

use async_std::io;
use futures::{prelude::*, select};
Expand Down
72 changes: 72 additions & 0 deletions examples/file-sharing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
## Description

The File Sharing example demonstrates a basic file sharing application built using **libp2p**.
This example showcases how to integrate **rust-libp2p** into a larger application while providing a simple file sharing functionality.

In this application, peers in the network can either act as file providers or file retrievers.
Providers advertise the files they have available on a Distributed Hash Table (DHT) using `libp2p-kad`.
Retrievers can locate and retrieve files by their names from any node in the network.

## How it Works

Let's understand the flow of the file sharing process:

- **File Providers**: Nodes A and B serve as file providers.
Each node offers a specific file: file FA for node A and file FB for node B.
To make their files available, they advertise themselves as providers on the DHT using `libp2p-kad`.
This enables other nodes in the network to discover and retrieve their files.

- **File Retrievers**: Node C acts as a file retriever.
It wants to retrieve either file FA or FB.
Using `libp2p-kad`, it can locate the providers for these files on the DHT without being directly connected to them.
Node C connects to the corresponding provider node and requests the file content using `libp2p-request-response`.

- **DHT and Network Connectivity**: The DHT (Distributed Hash Table) plays a crucial role in the file sharing process.
It allows nodes to store and discover information about file providers.
Nodes in the network are interconnected via the DHT, enabling efficient file discovery and retrieval.

## Architectural Properties

The File Sharing application has the following architectural properties:

- **Clean and Clonable Interface**: The application provides a clean and clonable async/await interface, allowing users to interact with the network layer seamlessly.
The `Client` module encapsulates the necessary functionality for network communication.

- **Efficient Network Handling**: The application operates with a single task that drives the network layer.
This design choice ensures efficient network communication without the need for locks or complex synchronization mechanisms.

## Usage

To set up a simple file sharing scenario with a provider and a retriever, follow these steps:

1. **Start a File Provider**: In one terminal, run the following command to start a file provider node:
```sh
cargo run -- --listen-address /ip4/127.0.0.1/tcp/40837 \
--secret-key-seed 1 \
provide \
--path <path-to-your-file> \
--name <name-for-others-to-find-your-file>
```
This command initiates a node that listens on the specified address and provides a file located at the specified path.
The file is identified by the provided name, which allows other nodes to discover and retrieve it.

2. **Start a File Retriever**: In another terminal, run the following command to start a file retriever node:
```sh
cargo run -- --peer /ip4/127.0.0.1/tcp/40837/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X \
get \
--name <name-for-others-to-find-your-file>
```
This command initiates a node that connects to the specified peer (the provider) and requests the file with the given name.

Note: It is not necessary for the retriever node to be directly connected to the provider.
As long as both nodes are connected to any node in the same DHT network, the file can be successfully retrieved.

This File Sharing example demonstrates the fundamental concepts of building a file sharing application using **libp2p**.
By understanding the flow and architectural properties of this example, you can leverage the power of **libp2p** to integrate peer-to-peer networking capabilities into your own applications.

## Conclusion

The File Sharing example provides a practical implementation of a basic file sharing application using **libp2p**.
By leveraging the capabilities of **libp2p**, such as the DHT and network connectivity protocols, it demonstrates how peers can share files in a decentralized manner.

By exploring and understanding the file sharing process and architectural properties presented in this example, developers can gain insights into building their own file sharing applications using **libp2p**.
58 changes: 2 additions & 56 deletions examples/file-sharing/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,62 +18,8 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! # File sharing example
//!
//! Basic file sharing application with peers either providing or locating and
//! getting files by name.
//!
//! While obviously showcasing how to build a basic file sharing application,
//! the actual goal of this example is **to show how to integrate rust-libp2p
//! into a larger application**.
//!
//! ## Sample plot
//!
//! Assuming there are 3 nodes, A, B and C. A and B each provide a file while C
//! retrieves a file.
//!
//! Provider nodes A and B each provide a file, file FA and FB respectively.
//! They do so by advertising themselves as a provider for their file on a DHT
//! via [`libp2p-kad`]. The two, among other nodes of the network, are
//! interconnected via the DHT.
//!
//! Node C can locate the providers for file FA or FB on the DHT via
//! [`libp2p-kad`] without being connected to the specific node providing the
//! file, but any node of the DHT. Node C then connects to the corresponding
//! node and requests the file content of the file via
//! [`libp2p-request-response`].
//!
//! ## Architectural properties
//!
//! - Clean clonable async/await interface ([`Client`](network::Client)) to interact with the
//! network layer.
//!
//! - Single task driving the network layer, no locks required.
//!
//! ## Usage
//!
//! A two node setup with one node providing the file and one node requesting the file.
//!
//! 1. Run command below in one terminal.
//!
//! ```sh
//! cargo run -- --listen-address /ip4/127.0.0.1/tcp/40837 \
//! --secret-key-seed 1 \
//! provide \
//! --path <path-to-your-file> \
//! --name <name-for-others-to-find-your-file>
//! ```
//!
//! 2. Run command below in another terminal.
//!
//! ```sh
//! cargo run -- --peer /ip4/127.0.0.1/tcp/40837/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X \
//! get \
//! --name <name-for-others-to-find-your-file>
//! ```
//!
//! Note: The client does not need to be directly connected to the providing
//! peer, as long as both are connected to some node on the same DHT.
#![doc = include_str!("../README.md")]

mod network;

use async_std::task::spawn;
Expand Down
Loading

0 comments on commit 0efc0a5

Please sign in to comment.