Contributing to rust-libp2p
Tags: osd600
Published: 2021-11-01 07:53:56

For Hacktoberfest, our professor assigned us the task to work on several open source projects that we could find in GitHub, and submit pull requests to those project.

## The project: rust-libp2p

This time I worked on a Rust project, heavily focused on network technologies, more specifically, peer-to-peer networking.

That project is [rust-libp2p](https://github.com/libp2p/rust-libp2p), an implementation of [libp2p](https://libp2p.io/), a networking stack for supporting peer-to-peer (p2p) networks.

## The issue: PeerId and its representation

Before going into the actual issue, I believe it would be a good idea to talk about what a `PeerId` is and how it is involved in the issue and the project overall.

A `PeerId` is a hash of the public key of the peer. You can view a peer as a member of a network, that communicate to other members in that network, which are also considered peers. Each peer has a pair of keys, a public one and a private one, to carry out encrypted communication.

Previously, a `PeerId` was internally represented as a [`multihash`](https://github.com/multiformats/multihash), a scheme to specify different hashes with their respective hashing methods. These hashes were then encoded in [`base58btc`](https://en.bitcoinwiki.org/wiki/Base58).

However, there were some issues related to this internal representation. One of them was the case-sensibility. If one wanted to use a `PeerId` as a domain name, then several valid `PeerId`s would collapse into a single `PeerId`, because domain names are case insensitive.

Thus, the issue [`#2259: Support and output peer IDs as CIDs`](https://github.com/libp2p/rust-libp2p/issues/2259) focuses on changing this representation to be a [Content IDentifier](https://docs.ipfs.io/concepts/content-addressing/) (CID).

## Setting the project

Fortunately, setting the project was not a huge hassle, thanks to `cargo`.

After I cloned the repository, I fired the tests found in the `core` repository. This triggered the fetching and installation of the dependencies, and after compilation was finished, all the tests ran.

## Writing the PR

Having the project ready, I started to write my code.

Most of the code I had to write was very straightforward: I did not have to write a lot of logic-heavy code, mostly calling the proper functions that took care of what I wanted.

Of course, I spent more time reading the documentation of the [`rust-cid`](https://github.com/multiformats/rust-cid) project to know how to use it, than actually writing code.

After writing most of the changes, I wrote back to one of the maintainers of the project, [Max Inden](https://github.com/mxinden), asking some questions and guidance for the next steps of my code. He followed up, writing a concise explanation for each of my concerns. This helped me to finish the changes necessary, since I learned what we should be expecting from the PR and its changes.

The only major problem I encountered was figuring out what to return for the `Err` variant, since I was not super clear about how Rust was deciding for the returning value.

After researching a little, I found out I could create an enum that would serve the role of the value for the `Err` variant. This new enum type, called `PeerIdError` basically grouped the errors from two crates (libraries), the crate for `multihash`, and the crate for `cid`.

## Submitting my PR

After finishing my code and running the tests, I squashed my commits because I forgot to run `clippy` and `rustfmt` before committing. Thus, instead of leaving the commit and dirtying the history, I decided to squash those minor changes.