Skip to content
Snippets Groups Projects
thesis.tex 11.5 KiB
Newer Older
Guilhem Niot's avatar
Guilhem Niot committed
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% EPFL report package, main thesis file
% Goal: provide formatting for theses and project reports
% Author: Mathias Payer <mathias.payer@epfl.ch>
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass[a4paper,11pt,oneside]{article}
Guilhem Niot's avatar
Guilhem Niot committed
% Options: MScThesis, BScThesis, MScProject, BScProject
\usepackage[BScProject,lablogo]{EPFLreport}
\usepackage{xspace}
\usepackage{listings}
\usepackage{caption}
\usepackage{subcaption}

\renewcommand{\lstlistingname}{Configuration}
\lstset{
  basicstyle=\footnotesize\ttfamily,
  columns=flexible,
  literate={-}{-}1,
  breaklines=true,
}
\lstset{captionpos=b}
\AtBeginDocument{\def\chapterautorefname{Chapter}}
\AtBeginDocument{\def\sectionautorefname{Section}}%
\AtBeginDocument{\def\subsectionautorefname{Subsection}}%
%

\title{Smallworld: Adding Hypercore support}
Guilhem Niot's avatar
Guilhem Niot committed
\author{Paulette Vazquez and Guilhem Niot}
\supervisor{Dr. Erick Lavoie}
\adviser{Professor Anne-Marie Kermarrec}

\begin{document}
\maketitle

Guilhem Niot's avatar
Guilhem Niot committed
% \maketoc
\section{Another application of Smallworld, the Hypercore Protocol}
The Hypercore Protocol\footnote{\url{https://hypercore-protocol.org/}}~\cite{Robinson2018} is a peer-to-peer protocol that allows sharing files in a distributed network. It is based on append-only logs like Secure-Scuttlebutt (SSB)~\cite{10.1145/3357150.3357396} but it provides more mature core libraries.
Guilhem Niot's avatar
Guilhem Niot committed
As a distributed file sharing protocol, it differs from BitTorrent \footnote{\url{https://www.bittorrent.com/}} in that contents can be updated by their author.
The Hypercore protocol\footnote{\url{https://hypercore-protocol.org/}} was created in 2016 as a way to provide the original protocol, called the Dat protocol\footnote{\url{https://www.datprotocol.com/}}, more abstract foundations that could be reused among several applications. From then, the Hyper project grew and it was decided in 2020 to separate Dat from Hypercore and to provide both with their own governance\footnote{An explanation video is available at \url{https://www.youtube.com/watch?v=mx52uO5SP7A}}.
The hypercore protocol extensively supports both local and remote peer-to-peer connexions using a DHT (Distributed Hash Tables), while the Dat protocol only supports a rendez-vous approach with a centralized server.
The Hypercore protocol is now incompatible with the Dat protocol and provides its own CLI tools and libraries.
This report aims at showing that Hypercore can be used with a Smallworld setup, to easily share files that could be often updated among peers, similarly to a Dropbox instance. We will explain how to configure Dat-store to replicate files, and we will cover a scenario where we replicate files between two clients A and B with the Raspberry Pi acting as an intermediary when only one of the clients is online at a given time.
\subsection{Real time synchronization with dat-store}
Dat-store is a command line tool that provides commands for downloading and syncing Hypercore archives, as well as a service that can be run in background, notably for remote control. \footnote{People usually recommend using a command line tool called \emph{dat-cli} for downloading and syncing Dat archives, but it is not able to run in background, and cannot be remotely controlled and is thus not practical for this application.} \\
Guilhem Niot's avatar
Guilhem Niot committed
Dat-store introduces the concept of provider. Providers are instances of dat-store running either locally or remotely. The default provider is your local instance, but you can also configure other providers, like the Raspberry Pi. 
This notion is particularly useful for remote control of other providers. \\
Guilhem Niot's avatar
Guilhem Niot committed
Dat-store should be installed on both the client and the Raspberry Pi using the following command
Guilhem Niot's avatar
Guilhem Niot committed
\begin{lstlisting}
  npm install -g dat-store
\end{lstlisting}

Guilhem Niot's avatar
Guilhem Niot committed
\textbf{Note:} In case you have permission errors, you may need to fix the permissions of your NPM installations. See the manual guide\footnote{\url{https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally}}. Using sudo instead won't fix the problem.  \\
Guilhem Niot's avatar
Guilhem Niot committed
You should then configure a systemd service to run the store in background. You have to configure both your device and the Raspberry Pi. For the user device you can copy paste the commands from Configuration \ref{cmd:dat_store_systemd_user} in a bash terminal. For the Raspberry Pi you can do the same with the commands from Configuration \ref{cmd:dat_store_systemd_rasp}.
Guilhem Niot's avatar
Guilhem Niot committed
\begin{lstlisting}[label=cmd:dat_store_systemd_user, caption=Sequence of bash commands to configure dat-store as a systemd service on the user device. Copy paste in a bash terminal.]
Guilhem Niot's avatar
Guilhem Niot committed
# This will create the service file.
sudo cat << EOF | sudo tee /etc/systemd/system/dat-store.service > /dev/null
[Unit]
Description=Dat storage provider, keeps dats alive in the background.

[Service]
Type=simple
# Check that dat-store is present at this location
# If it's not, replace the path with its location
ExecStart=$(which dat-store) run-service
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo chmod 644 /etc/systemd/system/dat-store.service

sudo systemctl daemon-reload
sudo systemctl enable dat-store
sudo systemctl start dat-store

sudo systemctl status dat-store
Guilhem Niot's avatar
Guilhem Niot committed
\end{lstlisting}
Guilhem Niot's avatar
Guilhem Niot committed
\begin{lstlisting}[label=cmd:dat_store_systemd_rasp, caption=Sequence of bash commands to configure dat-store as a systemd service on the Raspberry Pi. Copy paste in a bash terminal.]
Guilhem Niot's avatar
Guilhem Niot committed
    
# This will create the service file.
sudo cat << EOF | sudo tee /etc/systemd/system/dat-store.service > /dev/null
[Unit]
Description=Dat storage provider exposed to the internet (for the raspberry pi).

[Service]
Type=simple
# Check that dat-store is present at this location
# If it's not, replace the path with its location
ExecStart=$(which dat-store) run-service --expose-to-internet
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo chmod 644 /etc/systemd/system/dat-store.service

sudo systemctl daemon-reload
sudo systemctl enable dat-store
sudo systemctl start dat-store

sudo systemctl status dat-store
Guilhem Niot's avatar
Guilhem Niot committed
\end{lstlisting}
Guilhem Niot's avatar
Guilhem Niot committed
Dat-store provides interesting commands that we will use in our demo\footnote{See the documentation at \url{https://github.com/datproject/dat-store}.}:
Guilhem Niot's avatar
Guilhem Niot committed
\begin{itemize}
  \item \emph{dat-store add <url|path> [provider]}: Adds a folder or a dat url to the dat-store of the specified provider.
  \item \emph{dat-store set-provider <url> [provider]}: Sets the url of the specified provider.
  \item \emph{dat-store list [provider]}: Retrieves the list of available Dats in the specified provider.
  \item \emph{dat-store clone <path> <url> [provider]}: Clones \emph{<url>} into a local folder.
\end{itemize}
Guilhem Niot's avatar
Guilhem Niot committed
\subsection{Demonstration with two clients, and a Raspberry Pi}
Guilhem Niot's avatar
Guilhem Niot committed

We can then imagine the case where we have two clients A and B and one Raspberry Pi used as a permanent store to synchronize a folder from A to B.

Guilhem Niot's avatar
Guilhem Niot committed
First, A executes the commands from \autoref{cmd:dat_store_example_A}.
Then, client B executes the commands from \autoref{cmd:dat_store_example_B}.

Guilhem Niot's avatar
Guilhem Niot committed
\begin{lstlisting}[label=cmd:dat_store_example_A, caption=Bash commands executed by client A]
  dat-store set-provider http://raspberrypi.local:3472 raspberry
Guilhem Niot's avatar
Guilhem Niot committed
  mkdir mydat
  dat-store add ./mydat
Guilhem Niot's avatar
Guilhem Niot committed
  dat-store list
  dat-store add <url from previous command corresponding to ./mydat> raspberry
  # You can check that the content is actually replicated by accessing
  # http://raspberrypi.local/gateway/<token from hyper url corresponding to ./mydat>/
Guilhem Niot's avatar
Guilhem Niot committed
\end{lstlisting}

Guilhem Niot's avatar
Guilhem Niot committed
\begin{lstlisting}[label=cmd:dat_store_example_B, caption=Bash commands executed by client B]
  dat-store set-provider http://raspberrypi.local:3472 raspberry
Guilhem Niot's avatar
Guilhem Niot committed
  dat-store list raspberry
  dat-store clone ./mydat <url obtained from the previous command>
\end{lstlisting}
Guilhem Niot's avatar
Guilhem Niot committed

Changes from A to the folder \emph{mydat} will be replicated by B, even if A is not connected at the same time.
\section{Beyond Hypercore}
Guilhem Niot's avatar
Guilhem Niot committed
We also experimented with Pushpin\footnote{\url{https://github.com/automerge/pushpin}}, which is a collaborative coarkboard app. We wanted to showcase a peer-to-peer application with a real-time interface. Pushpin is based on hypermerge\footnote{\url{https://github.com/automerge/hypermerge}}, a library providing a JSON-like structure that can be edited concurrently, without worrying about conflicts. And hypermerge is itself based on the Dat protocol.
However, Pushpin was quite unstable, and Electron was crashing from time to time, and the synchronization also stopped until the window was reloaded. \\
On top of that, we were unable to install Pushpin on the Raspberry Pi to have a replicating node as Pushpin requires compiling Node 14 and the Raspberry Pi ran out of memory while doing the compilation.
Guilhem Niot's avatar
Guilhem Niot committed
\section{Conclusion and future work}
Guilhem Niot's avatar
Guilhem Niot committed
In the previous sections, we have shown how to use dat store to replicate files between devices and a simple usage scenario. Many extensions are possible.
First, while implementing this use case, we have noticed a major need shared between SSB and Hypercore, that is to provide a way to determine when two devices ended their synchronization. 
One possible implementation for SSB could be to use the Node.js client\footnote{\url{https://github.com/ssbc/ssb-client}} to determine when new posts are received. A proof of concept is showcased at \url{https://github.com/GuilhemN/ssb-copy-follows/tree/POSTS}. This script could be adapted to make a LED blink for instance to notify the user that the devices have synchronized. The user could also be notified directly on their device using \url{https://github.com/RangerMauve/hyperdrive-publisher}.
Second, Hypercore libraries offer the support of Bees, which are distributed key-value tables, but they are not supported by dat store. In the next section, we detail how to install Hypercore CLI, a CLI tool supporting Bees, on the Raspberry Pi so that future students could extend our work using these libraries instead.
\subsection{Hypercore CLI tool}
The Hyper community provides its own CLI tool in addition to the dat store CLI\footnote{\url{https://github.com/hypercore-protocol/cli}}. It enables the creation of Hyperdrives, i.e.\ folders distributed on the Hyper network, and Bees, which are distributed key-value tables.
% In addition, Hypercore is the underlying library of Hyperspace CLI.  \\
Guilhem Niot's avatar
Guilhem Niot committed
In order to run the Hypercore libraries, the documentation states that Node version 14 or more recent is required. However, Node 14 is not officially supported on the Raspberry Pi Zero as it is based on an ARMv6 CPU.
Thankfully, the NodeJs team is actually still providing unofficial (and "experimental") builds under \url{https://github.com/nodejs/unofficial-builds/} and those are usable on the Raspberry Pi. You may install them using the scripts provided by \url{https://github.com/sdesalas/node-pi-zero}. We tested successfully Node version 14.17.1. \\

You will then be able to install the Hyperspace CLI using \verb|npm install -g @hyperspace/cli|. \\
And now you should be able to interact with Hyperdrives using the \emph{hyp} command. You can check its documentation at \url{https://hypercore-protocol.org/guides/hyp/}.

\textbf{Note:} In case the \emph{hyp} command is not resolved, you may need to add to your \verb|~/.bashrc| the following line: \verb|export PATH=$PATH:$(npm bin -g)| which adds NPM libraries to your PATH.
Guilhem Niot's avatar
Guilhem Niot committed

\cleardoublepage
\phantomsection
\addcontentsline{toc}{chapter}{Bibliography}
\printbibliography

Guilhem Niot's avatar
Guilhem Niot committed
\end{document}