discovery-docker-network
                                
                                
                                
                                    discovery-docker-network copied to clipboard
                            
                            
                            
                        Docker Network for the Discovery release of the Enigma Protocol
Enigma Discovery Docker Network
| 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.
Table of Contents
- Background
 - Requirements
 - Installation
 - Simulation Mode
 - Troubleshooting
 - Advanced Topics
- Building the Docker images
 - Mounting volumes for development
 - Running multiple workers
 - Logging
 - Integration Tests
 
 
Background
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.
 
Requirements
- 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/isgxshould 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.
Installation
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
.envfile based off of the.env-templatefile and adjustSGX_MODEto 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 (
clientandcore). You can accomplish this by adding a line item to thevolumessection in the container’s stanza in the following format:local_folder:folder_in_container. More specifically:For the
clientcontainer, add the following line to the volumes section:- "/local/path/enigma-contract:/root/enigma-contract"where you must replace the
/local/path/enigma-contractfragment with the absolute path to where you have cloned theenigma-contractrepository in step 1 above in your local machine.For the
corecontainer, 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-corefragment with the absolute path to where you have cloned theenigma-corerepository in step 1 above in your local machine. - 
Still within
discovery-docker-networkrepo, run:docker-compose buildto 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
coreandkmmay 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.bashto launch the Docker network. - 
Within the
corerepo folder, create a newlibRust project underexamples/eng_wasm_contractson the command line with:cd examples/eng_wasm_contracts cargo new <project_name> --liband edit the
Cargo.tomlinside 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.rsfor the actual secret contract code). A great starting point would be thesimple_calculatorthat provides basic arithmetic operations (add, sub, mul, div) for any two inputs. - 
Within the
discovery-docker-networkfolder, enter thecorecontainer by running the following command:docker-compose exec core /bin/bashwhich provides a Bash shell (
/bin/bash) inside thecorecontainer. Once inside the container (you will see a different prompt), you need to do two things:- 
the first time, you need to build the
corebinaries 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=1Simulation 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 buildcommand 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.wasmBecause 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.wasmIt’s compiled with the name
contract.wasmas per the package name declaration in your projectCargo.tomlfile. Copy this compiled file to the scope of your localenigma-contractrepository 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-contractrepository, and run the corresponding integration tests. For example, refer to template.02_deploy_calculator.js and template.10_execute_calculator.js. 
Simulation mode
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
.envand changeSGX_MODE=SW, and then re-build thecoreandkmimages:docker-compose build --no-cache core km - 
Launch the network with
./launch.bashas usual. 
Troubleshooting
See the Troubleshooting document for the most common errors and how to solve them.
Advanced Topics
These resources are geared towards the advanced user who needs additional customization.
Building the Docker images
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}
Mounting volumes for development
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.ymlfile and add a line in thevolumessection (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 | 
Running multiple workers
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
Logging
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).
Integration Tests
See the Integration Tests document for additional details on how to run the existing suite of integration tests.