Skip to content
This repository has been archived by the owner on Oct 22, 2023. It is now read-only.

Security review TODO #904

Draft
wants to merge 1 commit into
base: to-review-base
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,251 changes: 4,251 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

84 changes: 84 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
[package]
name = "runtime-ethereum"
version = "0.3.0"
authors = ["Oasis Labs Inc. <[email protected]>"]
build = "build.rs"
edition = "2018"

[package.metadata.fortanix-sgx]
heap-size = 134217728
stack-size = 2097152
threads = 2

[[bin]]
name = "runtime-ethereum"
path ="bin/main.rs"

[dependencies]
# Internal.
runtime-ethereum-api = { path = "./api" }
runtime-ethereum-common = { path = "./common" }

# Ekiden.
ekiden-runtime = { git = "https://github.com/oasislabs/ekiden", branch = "master" }
ekiden-keymanager-client = { git = "https://github.com/oasislabs/ekiden", branch = "master" }

# Parity.
common-types = { git = "https://github.com/oasislabs/oasis-parity", branch = "ekiden" }
ethcore = { git = "https://github.com/oasislabs/oasis-parity", branch = "ekiden" }
ethkey = { git = "https://github.com/oasislabs/oasis-parity", branch = "ekiden" }
hashdb = { git = "https://github.com/oasislabs/oasis-parity", branch = "ekiden" }
keccak-hash = { git = "https://github.com/oasislabs/oasis-parity", branch = "ekiden" }
ethereum-types = { version = "0.3", default-features = false, features = ["std", "serialize"] }

# Others.
byteorder = "1.0"
elastic-array = "0.10"
hex = "0.3"
serde_json = "1.0"
serde_bytes = "0.11"
sha3 = "0.6"
failure = "0.1.5"
io-context = "0.2.0"
slog = "2.4.1"

[build-dependencies]
ekiden-tools = { git = "https://github.com/oasislabs/ekiden", branch = "master" }

[dev-dependencies]
assert_matches = "1.3.0"
time = "0.1"
ethabi = "8.0.0"

[features]
default = ["confidential"]
confidential = []
# Use test feature flag since Rust doesn't support conditional compilation using
# cfg(test) on dependent crates.
test = ["runtime-ethereum-common/test"]
benchmarking = ["runtime-ethereum-common/benchmarking"]
production-genesis = ["runtime-ethereum-common/production-genesis"]

[profile.release]
panic = "abort"
peterjgilbert marked this conversation as resolved.
Show resolved Hide resolved

# temporary fix for incompatibility between jsonrpc and ws-rs
[patch."https://github.com/tomusdrw/ws-rs"]
ws = { git = "https://github.com/oasislabs/ws-rs", branch = "ekiden" }

[patch.crates-io]
# TODO: Remove when merged upstream (briansmith/ring#738).
ring = { git = "https://github.com/akash-fortanix/ring", branch = "sgx-target" }
# TODO: Remove when merged upstream (rust-lang-deprecated/rustc-serialize#195).
rustc-serialize = { git = "https://github.com/jethrogb/rustc-serialize", branch = "portability" }
# NOTE: Required because heapsize doesn't work on SGX due to a different allocator.
heapsize = { git = "https://github.com/oasislabs/heapsize", branch = "sgx-target" }

[workspace]
members = [
"api",
"common",
"gateway",
"genesis",
]
exclude = ["tests"]
168 changes: 168 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/usr/bin/env gmake

# Ekiden binary base path.
EKIDEN_ROOT_PATH ?= .ekiden

# Runtime binary base path.
RUNTIME_ROOT_PATH ?= .runtime

# Ekiden cargo target directory.
EKIDEN_CARGO_TARGET_DIR := $(if $(CARGO_TARGET_DIR),$(CARGO_TARGET_DIR),$(EKIDEN_ROOT_PATH)/target)

# Runtime cargo target directory.
RUNTIME_CARGO_TARGET_DIR := $(if $(CARGO_TARGET_DIR),$(CARGO_TARGET_DIR),target)

# Key manager enclave path.
KM_ENCLAVE_PATH ?= $(EKIDEN_CARGO_TARGET_DIR)/x86_64-fortanix-unknown-sgx/debug/ekiden-keymanager-runtime.sgxs

# Genesis files.
GENESIS_ROOT_PATH ?= resources/genesis
GENESIS_FILES ?= \
genesis.json \
genesis_testing.json

# Extra build args.
EXTRA_BUILD_ARGS := $(if $(RELEASE),--release,)

# Check if we're running in an interactive terminal.
ISATTY := $(shell [ -t 0 ] && echo 1)

ifdef ISATTY
# Running in interactive terminal, OK to use colors!
MAGENTA = \e[35;1m
CYAN = \e[36;1m
RED = \e[31;1m
OFF = \e[0m

# Built-in echo doesn't support '-e'.
ECHO = /bin/echo -e
else
# Don't use colors if not running interactively.
MAGENTA = ""
CYAN = ""
RED = ""
OFF = ""

# OK to use built-in echo.
ECHO = echo
endif


.PHONY: \
all \
check check-tools check-ekiden \
download-artifacts symlink-artifacts \
runtime gateway genesis \
genesis-update \
clean clean-test-e2e \
fmt \
run-gateway run-gateway-sgx \
test test-unit test-e2e

all: check runtime gateway
@$(ECHO) "$(CYAN)*** Everything built successfully!$(OFF)"

check: check-tools check-ekiden

check-tools:
@which cargo-elf2sgxs >/dev/null || ( \
$(ECHO) "$(RED)error:$(OFF) ekiden-tools not installed (or not in PATH)" && \
exit 1 \
)

check-ekiden:
@test -x $(EKIDEN_ROOT_PATH)/go/ekiden/ekiden || ( \
$(ECHO) "$(RED)error:$(OFF) ekiden node not found in $(EKIDEN_ROOT_PATH) (check EKIDEN_ROOT_PATH)" && \
$(ECHO) " Maybe you need to run \"make symlink-artifacts\" or \"make download-artifacts\"?" && \
exit 1 \
)
@test -f $(KM_ENCLAVE_PATH) || ( \
$(ECHO) "$(RED)error:$(OFF) ekiden key manager enclave not found in $(KM_ENCLAVE_PATH) (check KM_ENCLAVE_PATH)" && \
$(ECHO) " Maybe you need to run \"make symlink-artifacts\" or \"make download-artifacts\"?" && \
exit 1 \
)

download-artifacts:
@$(ECHO) "$(CYAN)*** Downloading Ekiden and runtime build artifacts...$(OFF)"
@scripts/download_artifacts.sh "$(EKIDEN_ROOT_PATH)"
@$(ECHO) "$(CYAN)*** Download completed!$(OFF)"

symlink-artifacts:
@$(ECHO) "$(CYAN)*** Symlinking Ekiden and runtime build artifacts...$(OFF)"
@export EKIDEN_CARGO_TARGET_DIR=$(EKIDEN_CARGO_TARGET_DIR) && \
scripts/symlink_artifacts.sh "$(EKIDEN_ROOT_PATH)" "$(EKIDEN_SRC_PATH)" "$(RUNTIME_ROOT_PATH)" $$(pwd)
@$(ECHO) "$(CYAN)*** Symlinking done!$(OFF)"

runtime: check-ekiden
@$(ECHO) "$(CYAN)*** Building runtime-ethereum...$(OFF)"
@export KM_ENCLAVE_PATH=$(KM_ENCLAVE_PATH) && \
cargo build -p runtime-ethereum $(EXTRA_BUILD_ARGS) --target x86_64-fortanix-unknown-sgx && \
cargo build -p runtime-ethereum $(EXTRA_BUILD_ARGS) && \
cargo elf2sgxs $(EXTRA_BUILD_ARGS)

gateway:
@$(ECHO) "$(CYAN)*** Building web3-gateway...$(OFF)"
@cargo build -p web3-gateway $(EXTRA_BUILD_ARGS)

genesis:
@$(ECHO) "$(CYAN)*** Building genesis utilities...$(OFF)"
@cargo build -p genesis $(EXTRA_BUILD_ARGS)

genesis-update:
@$(ECHO) "$(CYAN)*** Generating Ekiden-compatible genesis files...$(OFF)"
@for g in $(GENESIS_FILES); do \
$(ECHO) "$(MAGENTA) * Genesis file: $$g$(OFF)"; \
cargo run -p genesis $(EXTRA_BUILD_ARGS) --bin genesis-init -- \
"$(GENESIS_ROOT_PATH)/$${g}" \
"$(GENESIS_ROOT_PATH)/ekiden_$${g}"; \
done

benchmark: genesis
@$(ECHO) "$(CYAN)*** Building benchmark client...$(OFF)"
@make -C benchmark

run-gateway:
@$(ECHO) "$(CYAN)*** Starting Ekiden node and Web3 gateway...$(OFF)"
@export EKIDEN_ROOT_PATH=$(EKIDEN_ROOT_PATH) RUNTIME_CARGO_TARGET_DIR=$(RUNTIME_CARGO_TARGET_DIR) && \
scripts/gateway.sh single_node 2>&1 | python scripts/color-log.py

run-gateway-sgx:
@$(ECHO) "$(CYAN)*** Starting Ekiden node and Web3 gateway (SGX)...$(OFF)"
@export EKIDEN_ROOT_PATH=$(EKIDEN_ROOT_PATH) RUNTIME_CARGO_TARGET_DIR=$(RUNTIME_CARGO_TARGET_DIR) && \
scripts/gateway.sh single_node_sgx 2>&1 | python scripts/color-log.py

test: test-unit test-e2e

test-unit: check-ekiden
@$(ECHO) "$(CYAN)*** Running unit tests...$(OFF)"
@export KM_ENCLAVE_PATH=$(KM_ENCLAVE_PATH) && \
cargo test \
--features test \
-p runtime-ethereum-common \
-p runtime-ethereum \
-p web3-gateway
@make -C benchmark test

test-e2e: check-ekiden
@$(ECHO) "$(CYAN)*** Running E2E tests...$(OFF)"
@.buildkite/scripts/download_ekiden_test_scripts.sh
@export EKIDEN_ROOT_PATH=$(EKIDEN_ROOT_PATH) && \
.buildkite/scripts/test_e2e.sh

fmt:
@cargo fmt

clean-test-e2e:
@$(ECHO) "$(CYAN)*** Cleaning up E2E tests...$(OFF)"
@rm -rf .e2e
@rm -rf tests/rpc-tests
@rm -rf tests/e2e-tests

clean: clean-test-e2e
@$(ECHO) "$(CYAN)*** Cleaning up...$(OFF)"
@cargo clean

regenerate-single-node:
@$(ECHO) "$(CYAN)*** Regenerating single node config artifacts...$(OFF)"
@export EKIDEN_ROOT_PATH=$(EKIDEN_ROOT_PATH) && \
./scripts/regenerate_single_node.sh
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Ekiden Ethereum runtime

[![Build status](https://badge.buildkite.com/e1de50bd91d01f6aaf2b9fba113ad48b0118459d7d2c5dd2bd.svg?branch=master)](https://buildkite.com/oasislabs/runtime-ethereum)
[![Coverage Status](https://coveralls.io/repos/github/oasislabs/runtime-ethereum/badge.svg?branch=master&t=shmqoK)](https://coveralls.io/github/oasislabs/runtime-ethereum?branch=master)

## Setting up the development environment

First, make sure that you have everything required for Ekiden installed by
following [the Ekiden instructions](https://github.com/oasislabs/ekiden/blob/master/README.md).

For building and running the runtime, you need to have specific Ekiden artifacts available.
To do this, you can either:

* Build Ekiden locally by checking out the Ekiden repository (e.g., in `/path/to/ekiden`)
and then running `EKIDEN_UNSAFE_SKIP_KM_POLICY=1 make -C /path/to/ekiden`. After the
process completes you can then run `make && make symlink-artifacts EKIDEN_SRC_PATH=/path/to/ekiden`
and all the required artifacts will be symlinked under `.ekiden` and `.runtime`.

* (Coming soon...) Download Ekiden artifacts from CI by running `make download-artifacts`. You need to have
the correct `BUILDKITE_ACCESS_TOKEN` set up to do this.

* Manually provide the required artifacts in a custom directory and specify
`EKIDEN_ROOT_PATH=/path/to/ekiden` on each invocation of `make`, e.g.
`make EKIDEN_ROOT_PATH=/path/to/ekiden`.

In the following instructions, the top-level directory is the directory
where the code has been checked out.

## Building the runtime

To build everything required for running the runtime, simply execute in the
top-level directory:
```bash
$ make
```

## Running the gateway

To run a local single-node Ekiden "cluster" and a development version of the gateway, run:
```bash
$ make run-gateway
```

## Benchmarking

Benchmarks require smart contract compilation and deployment tools, so you need
to install:

* rust support for wasm32 target: `rustup target add wasm32-unknown-unknown`,

* wasm-build command: `cargo install owasm-utils-cli --bin wasm-build`,

* abigen command as part of go ethereum devtools:
```bash
go get -u github.com/ethereum/go-ethereum
cd $GOPATH/src/github.com/ethereum/go-ethereum/
make devtools
```
* xxd command for converting binary-compiled contract to readable hex format:
`apt install xxd`,

To build the benchmarking version of the runtime (release build, logging suppressed, nonce checking disabled):
```bash
$ CARGO_TARGET_DIR=target_benchmark cargo build --release --features benchmark
```

Release builds of `gateway` and `genesis` are also used for benchmarking. To build, for each component:
```bash
$ cargo build -p <component> --release
```

Finally, to build the benchmarking go client with benchmarks and Rust smart
contracts:
```bash
$ cd benchmark
$ make
```

Run benchmarks by first spinning up the gateway (see previous chapter) and then
executing `benchmark/benchmark -b <benchmark_name>`. Benchmarks results
will be reported to STDOUT in JSON format.
13 changes: 13 additions & 0 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "runtime-ethereum-api"
version = "0.2.0"
authors = ["Oasis Labs Inc. <[email protected]>"]
edition = "2018"

[dependencies]
ekiden-runtime = { git = "https://github.com/oasislabs/ekiden", branch = "master" }
ethereum-types = { version = "0.3", default-features = false, features = ["std", "serialize"] }
failure = "0.1.5"
serde = "1.0.71"
serde_derive = "1.0"
serde_bytes = "~0.10"
Loading