diff --git a/.travis.yml b/.travis.yml index 86c26edc..59b03b11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ -sudo: false branches: only: - master @@ -7,51 +6,55 @@ matrix: include: - language: rust rust: stable + sudo: required + dist: trusty cache: cargo fast_finish: false + install: + - sudo apt-get --yes install snapd + - sudo snap install parity --stable + - sudo snap install solc --stable + - snap list before_script: - - sudo add-apt-repository ppa:ethereum/ethereum -y - - sudo apt-get update -y - - sudo apt-get install solc -y - - wget https://parity-downloads-mirror.parity.io/v1.8.6/x86_64-unknown-linux-gnu/parity - - chmod +x parity - - cp parity ${HOME}/bin - - export PATH=${HOME}/bin:${PATH} + - export PATH=/snap/bin:${PATH} - cd integration-tests script: - env BACKTRACE=1 cargo test --all -- --nocapture - language: rust rust: beta + sudo: required + dist: trusty cache: cargo fast_finish: false + install: + - sudo apt-get --yes install snapd + - sudo snap install parity --stable + - sudo snap install solc --stable + - snap list before_script: - - sudo add-apt-repository ppa:ethereum/ethereum -y - - sudo apt-get update -y - - sudo apt-get install solc -y - - wget https://parity-downloads-mirror.parity.io/v1.8.6/x86_64-unknown-linux-gnu/parity - - chmod +x parity - - cp parity ${HOME}/bin - - export PATH=${HOME}/bin:${PATH} + - export PATH=/snap/bin:${PATH} - cd integration-tests script: - env BACKTRACE=1 cargo test --all -- --nocapture - language: rust rust: nightly + sudo: required + dist: trusty cache: cargo fast_finish: false + install: + - sudo apt-get --yes install snapd + - sudo snap install parity --stable + - sudo snap install solc --stable + - snap list before_script: - - sudo add-apt-repository ppa:ethereum/ethereum -y - - sudo apt-get update -y - - sudo apt-get install solc -y - - wget https://parity-downloads-mirror.parity.io/v1.8.6/x86_64-unknown-linux-gnu/parity - - chmod +x parity - - cp parity ${HOME}/bin - - export PATH=${HOME}/bin:${PATH} + - export PATH=/snap/bin:${PATH} - cd integration-tests script: - env BACKTRACE=1 cargo test --all -- --nocapture - language: node_js node_js: node + sudo: false cache: yarn before_script: - cd truffle diff --git a/README.md b/README.md index f10aae22..5ec7687d 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,16 @@ [coveralls-image]: https://coveralls.io/repos/github/paritytech/parity-bridge/badge.svg?branch=master [coveralls-url]: https://coveralls.io/github/paritytech/parity-bridge?branch=master -the bridge is an +parity-bridge is currently an [ERC20 token](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) contract on one ethereum-based blockchain that is backed by ether on **another** ethereum-based blockchain. -users can convert ether +eventually parity-bridge will be able to pass arbitrary messages between +two ethereum-based blockchains. +in the future you'll be able to build the current ether-ERC20 bridge and any other +cross-chain application on top of the message passing bridge. + +currently users can convert ether on one chain into the same amount of ERC20 tokens on the other and back. the bridge securely relays these conversions. @@ -31,12 +36,6 @@ parity is using the bridge project to prototype the system that will eventually connect ethereum and other non-parachains to [polkadot](https://polkadot.io/). -### next steps - -1. deploy to bridge **ethereum** and **kovan** (bridge authorities TBD) -2. make the bridge work with contract-based dynamic validator sets -3. after kovan hardfork 2: deploy to kovan again with dynamic validator set - ### current functionality the bridge connects two chains `home` and `foreign`. @@ -88,6 +87,10 @@ checks that enough authorities in its authority list have signed and finally transfers `value` ether ([minus the relay gas costs](#recipient-pays-relay-cost-to-relaying-authority)) to `recipient`. +### deploy + +[read our deployment guide](deployment_guide.md) + ### run truffle smart contract tests requires `yarn` to be `$PATH`. [installation instructions](https://yarnpkg.com/lang/en/docs/install/) @@ -115,7 +118,7 @@ to install copy `../target/release/bridge` into a folder that's in your `$PATH`. ### run ``` -bridge --config config.toml --database db.toml +env RUST_LOG=info bridge --config config.toml --database db.toml ``` - `--config` - location of the configuration file. configuration file must exist @@ -160,6 +163,8 @@ all fields are required unless marked with *optional*. - `home.ipc` - path to the ipc socket of a parity node that has `home.account` unlocked - `home.contract.bin` - path to the compiled `HomeBridge` contract - required for initial deployment + - run [tools/compile_contracts.sh](tools/compile_contracts.sh) to compile contracts into dir `compiled_contracts` + - then set this to `compiled_contracts/HomeBridge.bin` - `home.required_confirmations` - number of confirmations required to consider transaction final on `home.ipc` - *optional,* default: **12** - `home.poll_interval` - specify how frequently (seconds) `home.ipc` should be polled for changes @@ -174,6 +179,8 @@ all fields are required unless marked with *optional*. - `foreign.ipc` - path to the ipc socket of a parity node that has `foreign.account` unlocked - `foreign.contract.bin` - path to the compiled `ForeignBridge` contract - required for initial deployment + - run [tools/compile_contracts.sh](tools/compile_contracts.sh) to compile contracts into dir `compiled_contracts` + - then set this to `compiled_contracts/ForeignBridge.bin` - `foreign.required_confirmations` - number of confirmations required to consider transaction final on `foreign.ipc` - *optional,* default: **12** - `foreign.poll_interval` - specify how frequently (seconds) `foreign.ipc` should be polled for changes @@ -194,16 +201,21 @@ these are all **optional** and default to `0`. look into the `[transactions]` section in [integration-tests/bridge_config.toml](integration-tests/bridge_config.toml) for recommendations on provided `gas`. +##### these happen on `home`: + - `transaction.home_deploy.gas` - `transaction.home_deploy.gas_price` +- `transaction.withdraw_relay.gas` +- `transaction.withdraw_relay.gas_price` + +##### these happen on `foreign`: + - `transaction.foreign_deploy.gas` - `transaction.foreign_deploy.gas_price` - `transaction.deposit_relay.gas` - `transaction.deposit_relay.gas_price` - `transaction.withdraw_confirm.gas` - `transaction.withdraw_confirm.gas_price` -- `transaction.withdraw_relay.gas` -- `transaction.withdraw_relay.gas_price` ### database file format diff --git a/deployment_guide.md b/deployment_guide.md new file mode 100644 index 00000000..754de0fe --- /dev/null +++ b/deployment_guide.md @@ -0,0 +1,138 @@ +# deployment guide + +this guide assumes that you are one of the authorities of +a PoA chain `foreign` and want to use the bridge to connect +`foreign` to another chain `home`. +this will create an ERC20 token on `foreign` that is backed by +ether on `home`. + +since all bridge authorities use the same contracts on `foreign` and `home` +one authority has to go ahead and deploy them. + +let's call this the **deploying authority**. + +if the process is done correctly the other non-deploying authorities don't have to trust +the deploying authority. + +upfront you must know the addresses of all authorities (`authorities`) +es well as the number of `required_signatures` + +## initial deployment steps for any authority (deploying and non-deploying) + +given you are authority with `authority_address`. + +[build and install the bridge](README.md#build) + +install parity. +we tested it with [parity 1.8.10](https://github.com/paritytech/parity/releases/tag/v1.8.10) +though it should work with the latest stable release. + +start a parity node that connects to `home` chain, has `authority_address` unlocked +and ipc enabled at `home.ipc`. TODO add instructions. please refer to +the parity documentation for now. + +start a parity node that connects to `foreign` chain, has `authority_address` unlocked +and ipc enabled at `foreign.ipc`. TODO add instructions. please refer to +the parity documentation for now. + +### configure the bridge + +copy [integration-tests/bridge_config.toml](integration-tests/bridge_config.toml) +to a local `bridge_config.toml`. + +within `bridge_config.toml` resolve/fill-in all the `ACTION REQUIRED`s. + +for help refer to the comments, [the config option documentation](README.md#configuration). +or [![Join the chat at https://gitter.im/paritytech/parity-bridge](https://badges.gitter.im/paritytech/parity-bridge.svg)](https://gitter.im/paritytech/parity-bridge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +[if you're the **leading** authority continue here](#further-deployment-steps-for-leading-authority) + +[if you're a non-leading authority continue here](#further-deployment-steps-for-non-leading-authorities) + +## further deployment steps for leading authority + +start the bridge by executing: + +``` +env RUST_LOG=info bridge --config bridge_config.toml --database bridge.db +``` + +it should eventually print something like this: + +``` +INFO:bridge: Deployed new bridge contracts +INFO:bridge: +home_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f" +foreign_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f" +home_deploy = 1 +foreign_deploy = 1 +checked_deposit_relay = 1 +checked_withdraw_relay = 1 +checked_withdraw_confirm = 1 +``` + +**congratulations! the bridge has successfully deployed its contracts on both chains** + +`bridge.db` should now look similar to this: + +``` +home_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f" +foreign_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f" +home_deploy = 1 +foreign_deploy = 1 +checked_deposit_relay = 3 +checked_withdraw_relay = 4 +checked_withdraw_confirm = 4 +``` + +(verify the contracts deployed to `home_contract_address` and +`foreign_contract_address` using +https://etherscan.io/verifyContract so the other authorities +can verify that you did an honest deploy without having to trust you.) + +give the `bridge.db` file to the other authorities. +for example by posting it as a gist. +the database file doesn't contain any sensitive information. + +ask the other authorities to follow **this guide you're reading**. + +ensure the process keeps running. else the bridge won't function. +(outside the scope of this guide, your devops team knows what to do). + +## further deployment steps for non-leading authorities + +you MUST receive a `bridge.db` from the leading authority. + +it should look similar to this: + +``` +home_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f" +foreign_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f" +home_deploy = 1 +foreign_deploy = 1 +checked_deposit_relay = 3 +checked_withdraw_relay = 4 +checked_withdraw_confirm = 4 +``` + +(check that the contracts deployed to +`home_contract_address` and `foreign_contract_address` are +verified on https://etherscan.io and that the source code matches +the code in the repo.) + +start the bridge by executing: + +``` +env RUST_LOG=info bridge --config bridge_config.toml --database bridge.db +``` + +it should eventually print this line: + +``` +INFO:bridge: Starting listening to events +``` + +**congratulations! the bridge has successfully started and joined the other authorities** + +ensure the process keeps running. else the bridge won't function. +(outside the scope of this guide, your devops team knows what to do). diff --git a/integration-tests/bridge_config.toml b/integration-tests/bridge_config.toml index f849b0a3..57a2f8f1 100644 --- a/integration-tests/bridge_config.toml +++ b/integration-tests/bridge_config.toml @@ -1,32 +1,65 @@ +# READ THE CONFIG DOCUMENTATION AT: +# https://github.com/paritytech/parity-bridge/#configuration + +# ACTION REQUIRED: for test deployment set this to `"100000"` estimated_gas_cost_of_withdraw = "0" + +# limits total balance on `home` and therefore total ether that could get lost +# if the bridge is faulty or compromised in any way! +# set to `"0"` to disable limit (not recommended at this point) +# currently set to 10 ether. max_total_home_contract_balance = "10000000000000000000" + +# set to `"0"` to disable limit (not recommended at this point) max_single_deposit_value = "1000000000000000000" [home] +# ACTION REQUIRED: set to your authority address account = "0x00bd138abd70e2f00903268f3db08f2d25677c9e" +# ACTION REQUIRED: set the the ipc socket of the parity node that has `home.account` unlocked ipc = "./home.ipc" +# ACTION REQUIRED: for test deployment set this to 12 required_confirmations = 0 [home.contract] +# READ THE CONFIG DOCUMENTATION AT: +# https://github.com/paritytech/parity-bridge/#configuration bin = "../compiled_contracts/HomeBridge.bin" [foreign] +# ACTION REQUIRED: set to your authority address account = "0x00bd138abd70e2f00903268f3db08f2d25677c9e" +# ACTION REQUIRED: set the the ipc socket of the parity node that has `foreign.account` unlocked ipc = "./foreign.ipc" +# ACTION REQUIRED: for test deployment set this to 12 required_confirmations = 0 [foreign.contract] +# READ THE CONFIG DOCUMENTATION AT: +# https://github.com/paritytech/parity-bridge/#configuration bin = "../compiled_contracts/ForeignBridge.bin" [authorities] +# ACTION REQUIRED: set this to the addresses of the authority list accounts = [ "0x00bd138abd70e2f00903268f3db08f2d25677c9e", ] +# ACTION REQUIRED: set this to a (super-)majority of `authorities.accounts` +# example: set to 3 for 5 authorities. set to 7 for 10 authorities required_signatures = 1 [transactions] -home_deploy = { gas = 1000000 } -foreign_deploy = { gas = 3000000 } -deposit_relay = { gas = 150000 } -withdraw_relay = { gas = 100000 } -withdraw_confirm = { gas = 300000 } +# `gas` below should be good defaults for test deployment. +# ACTION REQUIRED: you have to set `gas_price` for each transaction +# if your authority can't do free transactions on the chain. +# `gas_price` might need adjustment once in a while. + +# these happen on `home`: +home_deploy = { gas = 1000000 , gas_price = 0 } +withdraw_relay = { gas = 100000 , gas_price = 0 } + +# these happen on `foreign`: +foreign_deploy = { gas = 3000000 , gas_price = 0 } +deposit_relay = { gas = 150000 , gas_price = 0 } + +withdraw_confirm = { gas = 300000 , gas_price = 0 } diff --git a/tests/tests/withdraw_relay.rs b/tests/tests/withdraw_relay.rs index b7661e76..23a034b6 100644 --- a/tests/tests/withdraw_relay.rs +++ b/tests/tests/withdraw_relay.rs @@ -10,7 +10,7 @@ extern crate ethabi; extern crate ethereum_types; extern crate rustc_hex; -use ethereum_types::{U256, H256}; +use ethereum_types::H256; use rustc_hex::ToHex; use bridge::bridge::create_withdraw_relay; diff --git a/tools/compile_contracts.sh b/tools/compile_contracts.sh new file mode 100755 index 00000000..0821b323 --- /dev/null +++ b/tools/compile_contracts.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +solc \ + --abi \ + --bin \ + --optimize \ + --output-dir compiled_contracts \ + --overwrite \ + contracts/bridge.sol diff --git a/tools/solc_compile.sh b/tools/solc_compile.sh deleted file mode 100755 index 100053f2..00000000 --- a/tools/solc_compile.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -cd contracts -solc --abi --bin -o . --overwrite bridge.sol - -for abi in *.abi; do - python -m json.tool "$abi" > tmp - cat tmp > "$abi" -done - -rm tmp