Service | Master | Develop |
---|---|---|
Drone (SGX_MODE=HW) | ||
Travis (SGX_MODE=SW) |
This repository provides a Docker network that runs the upcoming Discovery release of the Enigma protocol. It integrates the the following repositories that provide the various components that make up the network: enigma-contract, enigma-core and enigma-p2p:
Repo | Branch | Build |
---|---|---|
enigma-contract | develop | |
enigma-p2p | develop | |
enigma-core | develop |
This repository is configured for Continuous Integration (CI) on two different testing environments: Drone, where SGX runs in hardware mode, and Travis, where SGX runs in simulation mode. The tests include a comprehensive suite of integration tests across the network that cover all these scenarios.
The Enigma Docker network integrates three different repositories that provide all the various services that make up the network. Each service gets its own container in the network as follows (which match the stanzas in the docker-compose.yml that provide the configuration for the Docker network):
- Contract: the Enigma contract provides the consensus layer in the network and is the “source of truth” for the state and results of secret computations, mostly in the form of hashes that are used for verification purposes.
- Enigma.JS Library (client): The Enigma Javascript library is the interface to the Enigma network for secret contract developers, and the entry point for dApp users. Once the network is up and running, this is the component that triggers the deployment of secret contracts in the network and triggers the secret computations, later verifying their correct execution.
- Core: The code running inside the Trusted Execution Environment (TEE, which is SGX in the case of Intel) is written in Rust, and contains Enigma’s adaptation of WASM that runs the bytecode for secret contract in a Virtual Machine inside the secure hardware. It receives the secret contract inputs encrypted from the user, and encrypts its outputs so that only the user can decrypt them.
- Peer-to-Peer (p2p): Each enclave communicates one-on-one with its networking component, written in Javascript, that provides an interface to the rest of the network and to the contract.
- Key Management (km) Node: A special instance of the core code that manages the encryption keys to maintain the state of secret contracts across the network. It responds to requests from other enclaves providing the needed keys to decrypt and re-encrypt the state associated with each secret contract deployed in the network.
There is one more element in the Enigma network that is not part of the Docker network, but it is already live as an online service that Enigma provides. Thus the Docker network requires an active Internet connection to connect to the following service in order for the network to operate properly:
- Remote Attestation Proxy: An online secure web server provided by Enigma as an interface to Intel Remote Attestation Service (IAS), so that anyone can validate that any enclave in the Enigma network runs its code inside a legitimate enclave and runs the code that it is supposed to run and not some other malicious code.
- Docker
- Docker Compose version 1.23.2 or higher. Please be aware that docker introduced a bug in 1.23.0 (also present in 1.23.1) that appended random strings to container names that causes this network configuration to break.
If you want to run SGX in Hardware mode, in the same way it will be run in production, you will also need:
-
A host machine with Intel Software Guard Extensions (SGX) enabled.
- The SGX hardware repository provides a list of hardware that supports Intel SGX, as well as a simple script to check if SGX is enabled on your system.
-
A host machine with Linux SGX driver installed (version 2.x recommended). Upon successful installation of the driver
/dev/isgx
should be present in the system.
However, for development purposes, the Enigma Discovery Docker Network can be run in Simulation (or Software mode), where no specialized hardware is required.
To set up a developer environment, you will need to run the Docker network provided in this repo, and mount local copies of the enigma-contract and enigma-core repositories to be able to make local changes, and do the actual development of secret contracts that you will subsequently deploy and run on the Docker network.
-
Clone the enigma-contract, enigma-core and discovery-docker-network repositories mentioned above onto your local machine with the following commands:
git clone https://github.com/enigmampc/enigma-contract.git git clone https://github.com/enigmampc/enigma-core.git git clone https://github.com/enigmampc/discovery-docker-network.git
From within the discovery-docker-network
directory you have just cloned:
-
Create a
.env
file based off of the.env-template
file and adjustSGX_MODE
to equalSW
(software/simulation) orHW
(hardware-compatible device) accordingly. Refer to the Requirements section above for additional information. -
Refer to the Mounting volumes for development and edit the docker-compose.yml file to volume map your local repositories on the relevant containers (
client
andcore
). You can accomplish this by adding a line item to thevolumes
section in the container’s stanza in the following format:local_folder:folder_in_container
. More specifically:For the
client
container, add the following line to the volumes section:- "/local/path/enigma-contract:/root/enigma-contract"
where you must replace the
/local/path/enigma-contract
fragment with the absolute path to where you have cloned theenigma-contract
repository in step 1 above in your local machine.For the
core
container, add a volumes section and the core repository mapping:volumes: - "/local/path/enigma-core:/root/enigma-core"
where again you must replace the
/local/path/enigma-core
fragment with the absolute path to where you have cloned theenigma-core
repository in step 1 above in your local machine. -
Still within
discovery-docker-network
repo, run:docker-compose build
to build all the Docker images needed for the network. You only need to do this step before the first time you launch the network. Depending on the capabilities of your computer, it can take up an hour or more (Note: the build of
core
andkm
may throw an error that is accounted for, and the build will handle it as needed.). Refer to the Building the Docker images section, if you need to rebuild the Docker images in the future. -
Within the
discovery-docker-network
, run./launch.bash
to launch the Docker network. -
Within the
core
repo folder, create a newlib
Rust project underexamples/eng_wasm_contracts
on the command line with:cd examples/eng_wasm_contracts cargo new <project_name> --lib
and edit the
Cargo.toml
inside the newly created folder, to add the following sections (so that it resembles one of the example ones):[dependencies] eng-wasm = {path = "../../../eng-wasm"} eng-wasm-derive = {path = "../../../eng-wasm/derive"} [lib] crate-type = ["cdylib"] [profile.release] panic = "abort" lto = true opt-level = "z"
-
Write your secret contract. Refer to the example secret contracts: within each folder, refer to
src/lib.rs
for the actual secret contract code). A great starting point would be thesimple_calculator
that provides basic arithmetic operations (add, sub, mul, div) for any two inputs. -
Within the
discovery-docker-network
folder, enter thecore
container by running the following command:docker-compose exec core /bin/bash
which provides a Bash shell (
/bin/bash
) inside thecore
container. Once inside the container (you will see a different prompt), you need to do two things:-
the first time, you need to build the
core
binaries inside the container, which varies depending on whether you are running in Hardware mode or in Simulation mode:Hardware Mode
root@core:~# cd enigma-core/enigma-core root@core:~/enigma-core/enigma-core# make full-clean root@core:~/enigma-core/enigma-core# make DEBUG=1
Simulation Mode
root@core:~# cd enigma-core/enigma-core root@core:~/enigma-core/enigma-core# make full-clean root@core:~/enigma-core/enigma-core# SGX_MODE=SW make DEBUG=1
-
then, you can build/compile your secret contract with the following commands:
root@core:~/enigma-core/enigma-core# cd ~/enigma-core/examples/eng_wasm_contracts/<project_name> root@core:~/enigma-core/examples/eng_wasm_contracts/<project_name># cargo build --release --target wasm32-unknown-unknown
-
you can exit the container with
Ctrl
+c
, and you will return to the prompt of your local computer.
-
-
The
cargo build
command above will compile your secret contract to the following path inside the container:~/enigma-core/examples/eng_wasm_contracts/<project_name>/target/wasm32-unknown-unknown/release/contract.wasm
Because this volume is mounted on your local filesystem, it will also be available at:
/local/path/enigma-core/examples/eng_wasm_contracts/<project_name>/target/wasm32-unknown-unknown/release/contract.wasm
It’s compiled with the name
contract.wasm
as per the package name declaration in your projectCargo.toml
file. Copy this compiled file to the scope of your localenigma-contract
repository in:/local/path/enigma-contract/enigma-js/test/integrationTests/secretContracts/
and rename the file with a name specific to your application instead of the generic
contract.wasm
(refer to the other files in that folder for guidance). -
Create template deploy and compute files like those already found in the integration test folder of the
enigma-contract
repository, and run the corresponding integration tests. For example, refer to template.02_deploy_calculator.js and template.10_execute_calculator.js.
The docker network can run both in SGX Hardware and Software (Simulation) modes. It defaults to SGX Hardware mode. In order to run in simulation mode, you only need to:
-
Edit
.env
and changeSGX_MODE=SW
, and then re-build thecore
andkm
images:docker-compose build --no-cache core km
-
Launch the network with
./launch.bash
as usual.
See the Troubleshooting document for the most common errors and how to solve them.
These resources are geared towards the advanced user who needs additional customization.
The first time that you launch the network, and the images for each container are not yet available, Docker will build them automatically.
If you want to manually rebuild them at a later time, you can do so using the following command, which will only pick up local changes, but will not pick up new commits on any of the remote repos it fetches:
$ docker-compose build
To force a rebuild without using any of the cached previous images (to pick a more recent commit from a remote repo, for example), run:
$ docker-compose build --no-cache
And to rebuild only the image for one of the containers, use any of the labels that you will find in the docker-compose.yml
:
$ docker-compose build {image_name}
where {image_name}
is one of the following: contract
, p2p
, client
, core
, km
, and which can be combined with the --no-cache
option as follows:
$ docker-compose build --no-cache {image_name}
By default, each of the container images are built pulling the latest version of their corresponding repositories, using the branches specified in .env
(see Step 1 in "Running the tests" section above). There are instances in which you may want to use a local copy of that repository where you can introduce changes and test them on the network.
In order to do that you do the following:
-
Clone either one of the three repositories (contract, core, p2p) that you are interested in, for example the contract:
$ git clone https://github.com/enigmampc/enigma-contract.git
-
Edit the
docker-compose.yml
file and add a line in thevolumes
section (you may need to create that section if it's not present in the config for that container) to the container you are interested in, mapping the local folder to where you have cloned the repo to the corresponding folder inside that container (local_folder:folder_in_container
). Again using the contract as an example, the relevant section would become:client: build: context: enigma-contract args: - GIT_BRANCH_CONTRACT=${GIT_BRANCH_CONTRACT} stdin_open: true tty: true networks: - net hostname: client volumes: - "built_contracts:/root/enigma-contract/build/contracts" - "/path_to/enigma-contract:/root/enigma-contract"
Use the following folders for each of these containers:
Container | Repo folder inside container |
---|---|
client | /root/enigma-contract |
contract | /root/enigma-contract |
p2p | /root/enigma-p2p |
core | /root/enigma-core |
km | /root/enigma-core |
The number of worker nodes (a pair of core
+ p2p
makes up one worker node) is controlled by the environment variable NODES
, which defaults to 1
if not set. The maximum number of worker nodes is 9. For example, to launch the network with 3 nodes, run:
$ NODES=3 ./launch.bash
Advanced Tip: If you want to manually enter any p2p
or core
container when there is more than one, you use the --index
parameter as follows (e.g. enter the second p2p
container):
$ docker-compose exec --index=2 p2p /bin/bash
By default, Docker shows the output of all containers running on the network to the stdout of the process that launched the network, color coded by container.
Additionally, the ./launch.bash
script takes an optional parameter -l
that stores the output of each individual container in its own file inside the logs/
folder. A subfolder is created each time the network is launched with the timestamp of the time of launch, for example: logs/2019-05-15T00:19:36-05:00/
.
For additional details on the Docker logging capabilities pertinent to this network configuration, refer to the Logging documentation.
Additionally, core
always logs to ~/.enigma/debug.log
inside the container (verbosity can be adjusted when core
is launched here defaulting to displaying warnings and up).
See the Integration Tests document for additional details on how to run the existing suite of integration tests.