Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
achiurizo Merge pull request #771 from omisego/achiurizo/sentry
Add Sentry for exception reporting
Latest commit 10f0abc Jun 13, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci fix: Appease Murkops Jun 12, 2019
.github refactor pull request template May 24, 2019
apps Merge branch 'master' into achiurizo/sentry Jun 13, 2019
config move logger instance to config Jun 12, 2019
docs Relax solc version to ~>0.4 Jun 10, 2019
rel fix: extract API layer into separate application Jun 5, 2019
rootfs feature: make local watcher run a proper OTP release May 30, 2019
.formatter.exs wip feature: build releases with distillery Apr 9, 2019
.github_changelog_generator add issues section back to changelog Jun 4, 2019
.gitignore wip: setup containers with releases May 23, 2019
AUTHORS Add LICENSE and AUTHORS Aug 11, 2018
CHANGELOG.md add issues section back to changelog Jun 4, 2019
Dockerfile enable sentry reporting with source code Jun 7, 2019
Dockerfile.child_chain fix: gmp dependency to libsecp256k1 May 28, 2019
Dockerfile.watcher feature: make local watcher run a proper OTP release May 30, 2019
LICENSE update copyright year to 2019 May 24, 2019
Makefile Merge branch 'master' into add-changelog Jun 4, 2019
README.md fix: rename omg_rpc to omg_child_chain_rpc Jun 1, 2019
deploy_and_populate.sh [elixir-omg] Add support for zero touch Childchain Linux deployments Nov 23, 2018
dialyzer.ignore-warnings Merge branch 'master' into achiurizo/sentry Jun 12, 2019
docker-compose-full-services-mac.yml fix: fix docker compose to handle DB conn & startup correctly May 29, 2019
docker-compose-full-services-non-mac.yml fix: fix docker compose to handle DB conn & startup correctly May 29, 2019
docker-compose-watcher-mac.yml feature: make local watcher run a proper OTP release May 30, 2019
docker-compose-watcher-non-mac.yml fix: fixing linux watcher and lowering the amount of restarts for blo… May 30, 2019
launcher.py Squash May 31, 2019
mix.exs remove trailing , Jun 12, 2019
mix.lock Merge branch 'master' into achiurizo/sentry Jun 12, 2019

README.md

The elixir-omg repository contains OmiseGO's Elixir implementation of Plasma and forms the basis for the OMG Network.

Build Status Coverage Status Gitter chat

IMPORTANT NOTICE: Heavily WIP, expect anything

Table of Contents

The first release of the OMG Network is based upon Tesuji Plasma, an iterative design step over Plasma MVP. The diagram below illustrates the relationship between the wallet provider and how wallet providers connect to Tesuji Plasma.

eWallet server and OMG Network

See the Tesuji Plasma design document for a full description for the Child Chain Server and Watcher. NOTE not all parts of that design have been implemented!

Getting Started

A public testnet for the OMG Network is coming soon. However, if you are brave and want to test being a Tesuji Plasma chain operator, read on!

Service start up using Docker Compose

This is the recommended method of starting the blockchain services, with the auxiliary services automatically provisioned through Docker. Before attempting the start up please ensure that you are not running any services that are listening on the following TCP ports: 9656, 7434, 5000, 8545, 5432, 5433. All commands should be run from the root of the repo.

NOTE known to work with docker-compose version 1.24.0, build 0aa59064, version 1.17 has had problems

Mac

docker-compose up

Linux

docker-compose -f docker-compose.yml -f docker-compose-non-mac.yml up

Get the deployed contract details

curl localhost:5000/get_contract

Troubleshooting Docker

You can view the running containers via docker ps

If service start up is unsuccessful, containers can be left hanging which impacts the start of services on the future attempts of docker-compose up. You can stop all running containers via docker kill $(docker ps -q).

If the blockchain services are not already present on the host, docker-compose will attempt to build the image with the tag elixir-omg:dockercompose and continue to use that. If you want Docker to use the latest commit from elixir-omg you can trigger a fresh build by passing the --build flag to docker-compose up --build.

Install on a Linux host & manual start up

Follow the guide to install the child chain server and watcher. Then use the guide in manual service startup to stand up.

Follow the demos

After starting the child chain server and/or Watcher as above, you may follow the steps in the demo scripts. Note that some steps should be performed in the Elixir shell (iex) and some in the shell directly.

To start a configured instance of the iex REPL, from the elixir-omg root directory inside the container do:

iex -S mix run --no-start --config ~/config.exs

Follow one of the scripts in the docs directory. Don't pick any OBSOLETE demos.

Troubleshooting

Solutions to common problems may be found in the troubleshooting document.

elixir-omg applications

elixir-omg is an umbrella app comprising of several Elixir applications:

The general idea of the apps responsibilities is:

  • omg_child_chain - child chain server
    • tracks Ethereum for things happening in the root chain contract (deposits/exits)
    • gathers transactions, decides on validity, forms blocks, persists
    • submits blocks to the root chain contract
    • see apps/omg_child_chain/lib/omg_child_chain/application.ex for a rundown of children processes involved
  • omg_db - wrapper around the child chain server's database to store the UTXO set and blocks necessary for state persistence
  • omg_eth - wrapper around the Ethereum RPC client
  • omg_child_chain_rpc - an HTTP-RPC server being the gateway to omg_child_chain
  • omg_performance - performance tester for the child chain server
  • omg_watcher - the Watcher

See application architecture for more details.

Child chain server

:omg_child_chain is the Elixir app which runs the child chain server, whose API is exposed by :omg_child_chain_rpc.

For the responsibilities and design of the child chain server see Tesuji Plasma Blockchain Design document.

Using the child chain server's API

The child chain server is listening on port 9656 by default.

HTTP-RPC

HTTP-RPC requests are served up on the port specified in omg_child_chain_rpc's config (:omg_child_chain_rpc, OMG.RPC.Web.Endpoint, http: [port: ...]). The available RPC calls are defined by omg_child_chain in api.ex - paths follow RPC convention e.g. block.get, transaction.submit. All requests shall be POST with parameters provided in the request body in JSON object. Object's properties names correspond to the names of parameters. Binary values shall be hex-encoded strings.

For API documentation see: https://omisego.github.io/elixir-omg.

Running a child chain in practice

TODO other sections

Ethereum private key management

geth

Currently, the child chain server assumes that the authority account is unlocked or otherwise available on the Ethereum node. This might change in the future.

parity

Since parity doesn't support indefinite unlocking of the account, handling of such key is yet to be solved. Currently (an unsafely) such private key is read from a secret system environment variable and handed to parity for signing.

Specifying the fees required

The child chain server will require the incoming transactions to satisfy the fee requirement. The fee requirement reads that at least one token being inputted in a transaction must cover the fee as specified. In particular, note that the required fee must be paid in one token in its entirety.

The fees are configured in the config entries for omg_child_chain see config secion.

Managing the operator address

(a.k.a authority address)

The Ethereum address which the operator uses to submit blocks to the root chain is a special address which must be managed accordingly to ensure liveness and security.

Nonces restriction

The reorg protection mechanism enforces there to be a strict relation between the submitBlock transactions and block numbers. Child block number 1000 uses Ethereum nonce 1, child block number 2000 uses Ethereum nonce 2, always. This provides a simple mechanism to avoid submitted blocks getting reordered in the root chain.

This restriction is respected by the child chain server (OMG.ChildChain.BlockQueue), whereby the Ethereum nonce is simply derived from the child block number.

As a consequence, the operator address must never send any other transactions, if it intends to continue submitting blocks. (Workarounds to this limitation are available, if there's such requirement.)

NOTE Ethereum nonce 0 is necessary to call the RootChain.init function, which must be called by the operator address. This means that the operator address must be a fresh address for every child chain brought to life.

Funding the operator address

The address that is running the child chain server and submitting blocks needs to be funded with Ether. At the current stage this is designed as a manual process, i.e. we assume that every gas reserve checkpoint interval, someone will ensure that gas reserve worth of Ether is available for transactions.

Gas reserve must be enough to cover the gas reserve checkpoint interval of submitting blocks, assuming the most pessimistic scenario of gas price.

Calculate the gas reserve as follows:

gas_reserve = child_blocks_per_day * days_in_interval * gas_per_submission * highest_gas_price

where

child_blocks_per_day = ethereum_blocks_per_day / submit_period

Submit period is the number of Ethereum blocks per a single child block submission) - configured in :omg_child_chain, :child_block_submit_period

Highest gas price is the maximum gas price which the operator allows for when trying to have the block submission mined (operator always tries to pay less than that maximum, but has to adapt to Ethereum traffic) - configured in (TODO when doing OMG-47 task)

Example

Assuming:

  • submission of a child block every Ethereum block
  • 15 second block interval on Ethereum, on average
  • weekly cadence of funding, i.e. days_in_interval == 7
  • allowing gas price up to 40 Gwei
  • gas_per_submission == 71505 (checked for RootChain.sol at this revision. C.f. here)

we get

gas_reserve ~= (4 * 60 * 24 / 1) * 7 * 71505 * (40 / 10**9)  ~= 115 ETH

NOTE that the above calculation doesn't imply this is what is going to be used within a week, just a pessimistic scenario to calculate an adequate reserve. If one assumes an average gas price of 4 Gwei, the amount is immediately reduced to ~11.5 ETH weekly.

Watcher

The Watcher is an observing node that connects to Ethereum and the child chain server's API. It ensures that the child chain is valid and notifies otherwise. It exposes the information it gathers via an HTTP-RPC interface (driven by Phoenix). It provides a secure proxy to the child chain server's API and to Ethereum, ensuring that sensitive requests are only sent to a valid chain.

For more on the responsibilities and design of the Watcher see Tesuji Plasma Blockchain Design document.

Using the watcher

The watcher is listening on port 7434 by default.

Endpoints

For API documentation see: https://omisego.github.io/elixir-omg

Ethereum private key management

Watcher doesn't hold or manage user's keys. All signatures are assumed to be done outside. A planned exception may be to allow Watcher to sign challenges, but using a non-sensitive/low-funded Ethereum account.

mix configuration parameters

Mix.Config is currently used to configure all the parameters required to set the child chain server and watcher up. Per usual practice, the default values are defined in apps/<app>/config/config.exs.

NOTE: all margins are denominated in Ethereum blocks

Generic configuration - :omg app

  • deposit_finality_margin - the margin that is waited after a DepositCreated event in the root chain contract. Only after this margin had passed:

    • the child chain will allow spending the deposit
    • the watcher will consider a transaction spending this deposit a valid transaction

    It is important that for a given child chain, the child chain server and watchers use the same value of this margin.

    NOTE: This entry is defined in omg, despite not being accessed there, only in omg_child_chain and omg_watcher. The reason here is to minimize risk of Child Chain server's and Watcher's configuration entries diverging.

  • ethereum_events_check_interval_ms - polling interval for pulling Ethereum events (logs) from the Ethereum client.

  • coordinator_eth_height_check_interval_ms - polling interval for checking whether the root chain had progressed for the RootChainCoordinator. Affects how quick the services reading Ethereum events realize there's a new block.

Child chain server configuration - :omg_child_chain app

  • submission_finality_margin - the margin waited before mined block submissions are purged from BlockQueue's memory

  • block_queue_eth_height_check_interval_ms - polling interval for checking whether the root chain had progressed for the BlockQueue exclusively

  • child_block_minimal_enqueue_gap - how many new Ethereum blocks must be mined, since previous submission attempt, before another block is going to be formed and submitted.

  • fee_specs_file_name - path to file which defines fee requirements, see fee_specs.json for an example.

  • ignore_fees - boolean option allowing to turn off fee charging altogether

Watcher configuration - :omg_watcher app

  • exit_processor_sla_margin - the margin to define the notion of a "late", invalid exit. After this margin passes, every invalid exit is deemed a critical failure of the child chain (unchallenged_exit). Such event will prompt a mass exit and stop processing new blocks. See exit validation documentation for details.

  • maximum_block_withholding_time_ms - for how long the Watcher will tolerate failures to get a submitted child chain block, before reporting a block withholding attack and stopping

  • block_getter_loops_interval_ms - polling interval for checking new child chain blocks submissions being mined on the root chain

  • maximum_number_of_unapplied_blocks - the maximum number of downloaded and statelessly validated child chain blocks to hold in queue for applying

  • exit_finality_margin - the margin waited before an exit-related event is considered final enough to pull and process

  • block_getter_reorg_margin - the margin considered by OMG.Watcher.BlockGetter when searching for recent child chain block submission events. This is driving the process of determining the height and particular event related to the submission of a particular child chain block

  • convenience_api_mode - whether Convenience API should be started for the Watcher. This setting is usually set by running the Mix.Tasks.Xomg.Watcher.Start with the appropriate flag.

OMG.DB configuration - :omg_db app

  • path - path to the directory holding the LevelDB data store

  • server_module - the module to use when talking to the OMG.DB

  • server_name - the named process to refer to when talking to the OMG.DB

OMG.Eth configuration - :omg_eth app

All binary entries are expected in hex-encoded, 0x-prefixed.

  • contract_addr - the address of the root chain contract

  • authority_addr - the address used by the operator to submit blocks

  • txhash_contract - the Ethereum-transaction hash holding the deployment of the root chain contract

  • eth_node - the Ethereum client which is used: "geth" | "parity".

  • node_logging_in_debug - whether the output of the Ethereum node being run in integration test should be printed to :debug level logs. If you set this to false, remember to set the logging level to :debug to see the logs

  • child_block_interval - mirror of contract configuration uint256 constant public CHILD_BLOCK_INTERVAL from RootChain.sol

  • exit_period_seconds - mirror of contract configuration uint256 public minExitPeriod

  • ethereum_client_warning_time_ms - queries for event logs made to the Ethereum node lasting more than this will emit a :warn-level log

Contracts

OMG network uses contract code from the contracts repo. Code from a particular branch in that repo is used, see one of mix.exs configuration files for details.

Contract code is downloaded automatically when getting dependencies of the Mix application with mix deps.get. You can find the downloaded version of that code under deps/plasma_contracts.

Installing dependencies and compiling contracts

To install dependencies:

sudo apt-get install libssl-dev solc

Contracts will compile automatically as a regular mix dependency. To compile contracts manually:

mix deps.compile plasma_contracts

Testing & development

Quick test (no integration tests):

mix test

Longer-running integration tests (requires compiling contracts):

mix test --only integration

To run these tests with parity as a backend, set it via ETH_NODE environmental variable (default is geth):

ETH_NODE=parity mix test --only integration

For other kinds of checks, refer to the CI/CD pipeline (https://circleci.com/gh/omisego/workflows/elixir-omg).

To run a development iex REPL with all code loaded:

iex -S mix run --no-start

Working with API Spec's

This repo contains gh-pages branch intended to host Swagger-based API specification. Branch gh-pages is totally diseparated from other development branches and contains just Slate generated page's files.

See gh-pages README for more details.

You can’t perform that action at this time.