This is the accompanying code to the paper "DAMYSUS: Streamlined BFT Consensus Leveraging Trusted Components" which was accepted to EuroSys 2022. A technical report is available here.
The software is under ongoing development.
To tests our protocols, we provide a Python script, called
experiments.py, as well as a Dockerfile to create a Docker
container. We use the
Salticidae library, which
is added here as git submodule.
You won't need to follow this step if you are using our Docker container, as it is done when building the container, and can jump to the next (Python) section. If you decide to install Salticidae locally, you will need git and cmake. In which case, after cloning the repository you need to type this to initialize the Salticidae git submodule:
git submodule init
followed by:
git submodule update
Salticidea has the following dependencies:
- CMake >= 3.9
- C++14
- libuv >= 1.10.0
- openssl >= 1.1.0
sudo apt install cmake libuv1-dev libssl-dev
Then, to instance Salticidae, type:
(cd salticidae; cmake . -DCMAKE_INSTALL_PREFIX=.; make; make install)
We use python version 3.8.10. You will need python3-pip to install the required modules.
The Python script relies on the following modules:
- subprocess
- pathlib
- matplotlib
- time
- math
- os
- glob
- datetime
- argparse
- enum
- json
- multiprocessing
- random
- shutil
- re
If you haven't installed those modules yet, run:
python3 -m pip install subprocess pathlib matplotlib time math os glob datetime argparse enum json multiprocessing random shutil re
To run the experiments within Docker containers, you need to have installed Docker on your machine. This page explains how to install Docker. In particular follow the following instructions so that you can run Docker as a non-root user.
You then need to create the container by typing the following command at the root of the project:
docker build -t damysus .
This will create a container called damysus.
We use jq to extract the IP addresses of Docker containers, so make
sure to install that too.
We explain the various options our Python scripts provides. You will run commands of the following form, followed by various options explained below:
python3 experiments.py --docker --pall
In addition, you can use the following options to change some of the parameters:
--dockerto run the nodes within Docker containers--repeats nto change the number of repeats per experiment ton--payload nto change the payload size ton--faults a,b,cto run the experiments for f=a, f=b, etc.--pallis to run all protocols, instead you can use--p1up to--p6--p1: base protocol, i.e., HotStuff--p2: Damysus-C (checker only)--p3: Damysus-A (accumulator only)--p4: Damysus--p5: chained base protocol, i.e., chained HotStuff--p6: chained Damysus
--netlat nto change the network latency tonms--clients1 nto change the number of clients tonfor the non-chained protocols--clients2 nto change the number of clients tonfor the chained protocols--tvlto compute a "max throughput" graph--onecoreto compute the code using one core only--hwto run SGX in hardware mode- this option cannot be used with docker
- it requires the sgxsdk to be installed here:
/opt/intel/sgxsdk, which can be achieved following the steps in the Dockerfile - it requires installing Salticidae following the steps mentioned above
--clusterto run the nodes remotely (see the Cluster section for more information)- this option will automatically use Docker containers
- it currently cannot user SGX in hardware mode
- it currently cannot be combined with
--tvl
For example, if you run:
python3 experiments.py --docker --p1 --p2 --repeats 2 --faults 1
then you will run the replicas within Docker containers (--docker),
test the base protocol (--p1) and Damysus-C (--p2), repeat the
experiments twice (--repeats 2), and test for f=1 (--faults 1).
If your run:
python3 experiments.py --docker --pall --repeats 10 --faults 1,2,4
then you will run the replicas within Docker containers (--docker),
test all protocols (--pall), repeat the experiments 10 times
(--repeats 10), and test for f=1, f=2, and f=4 (--faults 1,2,4)
We recommend that you try the following experiments. Note that 100 repetitions will take quite a long time. You can start with a smaller value between 2 and 10 to get an idea of the results you will obtain.
- Run all protocols with a 0ms network latency, 0B payloads, for f=1,2,4,10, with 100 repetitions per experiment (consider using less repetitions)
python3 experiments.py --docker --pall --netlat 0 --payload 0 --faults 1,2,4,10 --repeats 100
- Run all protocols with a 100ms network latency, 256B payloads, for f=1,2,4,10, with 100 repetitions per experiment (consider using less repetitions)
python3 experiments.py --docker --pall --netlat 100 --payload 256 --faults 1,2,4,10 --repeats 100
As mentioned above, you can use the --cluster option to start distributed experiments. You will need to do this:
- Generate an
id_rsa.damysuskey using for example:ssh-keygen -t rsa -b 4096 -f id_rsa.damysus - Copy this key to all the nodes in your cluster as follows:
where
ssh-copy-id -i id_rsa.damysus.pub USER@TARGETTARGETis one of your hostnames, andUSERyour username for that host - List the nodes that are in your cluster in a
nodesfile as follows (add as many entries are you like---the cluster here contains 2 nodes):where{ "nodes": [ { "node" : "node1", "user" : "vince", "host" : "192.168.0.1", "dir" : "/home/vince/damysus-test", "key" : "id_rsa.damysus" }, { "node" : "node2", "user" : "vince", "host" : "192.168.0.2", "dir" : "/home/vince/damysus-test", "key" : "id_rsa.damysus" } ] }"node"specifies the name of the node (pick whatever you want),"user"is your username for that node,"host"is the hostname of that node,"dir"is a working directory on that node that will be used to store temporary files, and"key"is the name of the key that will be used to access the node remotely without password. Note that you can have more replicas than nodes, which will result on multiple replicas being deployed on the same node. - You need to make sure that
python,docker,gitandjqare installed on all the machines in your cluster, as well as on the machine that you will use to start the experiments - You will need to generate the
damysusDocker image on all your nodes. You can do that automatically by running:python3 experiments.py --prepare - You can now try an experiment as follows:
python3 experiments.py --cluster --p1 --repeats 1 --faults 1
The AWS experiments are more adhoc. They require images to already
exist in the regions. Change regions to select the regions you want
to use. Then run something like this (as before with the --aws
option):
python3 experiments.py --aws --p1 --repeats 1 --faults 1
In case something goes wrong, you can stop all instances as follows:
python3 experiments.py --stop
To debug on AWS, try something like this:
python3 experiments.py --launch 1
python3 experiments.py --copy XXX
to launch an instance at some address XXX, which will be printed by the first command; then copy all files to the instance. After that you can ssh the address, and do whatever you want there.
Jiangshan Yu was partially supported by the Australian Research Council (ARC) under project DE210100019.
Feel free to contact any of the authors if you have questions: Jeremie Decouchant, David Kozhaya, Vincent Rahli, and Jiangshan Yu.