Problem: bridge should not deploy its contracts anymore

Bridge's contracts are now developed in a separate repository
and have their own deployment procedure:

https://github.com/poanetwork/poa-parity-bridge-contracts

However, our integration tests are not yet updated to
use this deployment procedure.

Solution: disable deployment compile-time by default
and only use it in integration tests as a stopgap measure
until the new deployment procedure (or any other viable
alternative) has been used.
This commit is contained in:
Yurii Rashkovskii 2018-05-01 09:43:34 -07:00
parent cdb79b9ba7
commit 9a192c1e07
No known key found for this signature in database
GPG Key ID: 1D60D7CFD80845FF
10 changed files with 107 additions and 66 deletions

6
Makefile Normal file
View File

@ -0,0 +1,6 @@
all: target/release/bridge
.PHONY: target/release/bridge
target/release/bridge:
cd cli && cargo build --release

View File

@ -103,14 +103,14 @@ requires `rust` and `cargo`: [installation instructions.](https://www.rust-lang.
requires `solc` to be in `$PATH`: [installation instructions.](https://solidity.readthedocs.io/en/develop/installing-solidity.html) requires `solc` to be in `$PATH`: [installation instructions.](https://solidity.readthedocs.io/en/develop/installing-solidity.html)
assuming you've cloned the bridge (`git clone git@github.com:paritytech/parity-bridge.git`) assuming you've cloned the bridge (`git clone git@github.com:poanetwork/parity-bridge.git`)
and are in the project directory (`cd parity-bridge`) run: and are in the project directory (`cd parity-bridge`) run:
``` ```
cargo build -p bridge-cli --release make
``` ```
to install copy `../target/release/bridge` into a folder that's in your `$PATH`. and install `../target/release/bridge` in your `$PATH`.
### run ### run
@ -120,8 +120,6 @@ bridge --config config.toml --database db.toml
- `--config` - location of the configuration file. configuration file must exist - `--config` - location of the configuration file. configuration file must exist
- `--database` - location of the database file. - `--database` - location of the database file.
if there is no file at specified location, new bridge contracts will be deployed
and new database will be created
### configuration [file example](./examples/config.toml) ### configuration [file example](./examples/config.toml)
@ -151,10 +149,6 @@ accounts = [
"0x006e27b6a72e1f34c626762f3c4761547aff1421" "0x006e27b6a72e1f34c626762f3c4761547aff1421"
] ]
required_signatures = 2 required_signatures = 2
[transactions]
home_deploy = { gas = 500000 }
foreign_deploy = { gas = 500000 }
``` ```
#### options #### options
@ -190,10 +184,6 @@ foreign_deploy = { gas = 500000 }
#### transaction options #### transaction options
- `transaction.home_deploy.gas` - specify how much gas should be consumed by home contract deploy
- `transaction.home_deploy.gas_price` - specify gas price for home contract deploy
- `transaction.foreign_deploy.gas` - specify how much gas should be consumed by foreign contract deploy
- `transaction.foreign_deploy.gas_price` - specify gas price for foreign contract deploy
- `transaction.deposit_relay.gas` - specify how much gas should be consumed by deposit relay - `transaction.deposit_relay.gas` - specify how much gas should be consumed by deposit relay
- `transaction.deposit_relay.gas_price` - specify gas price for deposit relay - `transaction.deposit_relay.gas_price` - specify gas price for deposit relay
- `transaction.withdraw_confirm.gas` - specify how much gas should be consumed by withdraw confirm - `transaction.withdraw_confirm.gas` - specify how much gas should be consumed by withdraw confirm
@ -206,8 +196,6 @@ foreign_deploy = { gas = 500000 }
```toml ```toml
home_contract_address = "0x49edf201c1e139282643d5e7c6fb0c7219ad1db7" home_contract_address = "0x49edf201c1e139282643d5e7c6fb0c7219ad1db7"
foreign_contract_address = "0x49edf201c1e139282643d5e7c6fb0c7219ad1db8" foreign_contract_address = "0x49edf201c1e139282643d5e7c6fb0c7219ad1db8"
home_deploy = 100
foreign_deploy = 101
checked_deposit_relay = 120 checked_deposit_relay = 120
checked_withdraw_relay = 121 checked_withdraw_relay = 121
checked_withdraw_confirm = 121 checked_withdraw_confirm = 121
@ -217,8 +205,6 @@ checked_withdraw_confirm = 121
- `home_contract_address` - address of the bridge contract on home chain - `home_contract_address` - address of the bridge contract on home chain
- `foreign_contract_address` - address of the bridge contract on foreign chain - `foreign_contract_address` - address of the bridge contract on foreign chain
- `home_deploy` - block number at which home contract has been deployed
- `foreign_deploy` - block number at which foreign contract has been deployed
- `checked_deposit_relay` - number of the last block for which an authority has relayed deposits to the foreign - `checked_deposit_relay` - number of the last block for which an authority has relayed deposits to the foreign
- `checked_withdraw_relay` - number of the last block for which an authority has relayed withdraws to the home - `checked_withdraw_relay` - number of the last block for which an authority has relayed withdraws to the home
- `checked_withdraw_confirm` - number of the last block for which an authority has confirmed withdraw - `checked_withdraw_confirm` - number of the last block for which an authority has confirmed withdraw

View File

@ -30,3 +30,7 @@ jsonrpc-core = "8.0"
[dev-dependencies] [dev-dependencies]
tempdir = "0.3" tempdir = "0.3"
quickcheck = "0.6.1" quickcheck = "0.6.1"
[features]
default = []
deploy = []

View File

@ -1,12 +1,18 @@
use std::sync::Arc; use std::sync::Arc;
use futures::{Future, Poll, future}; use futures::{Future, Poll};
#[cfg(feature = "deploy")]
use futures::future;
use web3::Transport; use web3::Transport;
#[cfg(feature = "deploy")]
use web3::types::U256; use web3::types::U256;
use app::App; use app::App;
use database::Database; use database::Database;
use error::{Error, ErrorKind}; use error::{Error, ErrorKind};
#[cfg(feature = "deploy")]
use api; use api;
#[cfg(feature = "deploy")]
use ethcore_transaction::{Transaction, Action}; use ethcore_transaction::{Transaction, Action};
#[cfg(feature = "deploy")]
use super::nonce::{NonceCheck,TransactionWithConfirmation}; use super::nonce::{NonceCheck,TransactionWithConfirmation};
pub enum Deployed { pub enum Deployed {
@ -16,24 +22,38 @@ pub enum Deployed {
Existing(Database), Existing(Database),
} }
#[cfg(feature = "deploy")]
enum DeployState<T: Transport + Clone> { enum DeployState<T: Transport + Clone> {
CheckIfNeeded, CheckIfNeeded,
Deploying(future::Join<NonceCheck<T, TransactionWithConfirmation<T>>, NonceCheck<T, TransactionWithConfirmation<T>>>), Deploying(future::Join<NonceCheck<T, TransactionWithConfirmation<T>>, NonceCheck<T, TransactionWithConfirmation<T>>>),
} }
#[cfg(not(feature = "deploy"))]
enum DeployState {
CheckIfNeeded,
}
#[allow(unused_variables)]
pub fn create_deploy<T: Transport + Clone>(app: Arc<App<T>>, home_chain_id: u64, foreign_chain_id: u64) -> Deploy<T> { pub fn create_deploy<T: Transport + Clone>(app: Arc<App<T>>, home_chain_id: u64, foreign_chain_id: u64) -> Deploy<T> {
Deploy { Deploy {
app, app,
state: DeployState::CheckIfNeeded, state: DeployState::CheckIfNeeded,
#[cfg(feature = "deploy")]
home_chain_id, home_chain_id,
#[cfg(feature = "deploy")]
foreign_chain_id, foreign_chain_id,
} }
} }
pub struct Deploy<T: Transport + Clone> { pub struct Deploy<T: Transport + Clone> {
app: Arc<App<T>>, app: Arc<App<T>>,
#[cfg(feature = "deploy")]
state: DeployState<T>, state: DeployState<T>,
#[cfg(not(feature = "deploy"))]
state: DeployState,
#[cfg(feature = "deploy")]
home_chain_id: u64, home_chain_id: u64,
#[cfg(feature = "deploy")]
foreign_chain_id: u64, foreign_chain_id: u64,
} }
@ -43,53 +63,60 @@ impl<T: Transport + Clone> Future for Deploy<T> {
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
loop { loop {
let next_state = match self.state { let _next_state = match self.state {
DeployState::CheckIfNeeded => match Database::load(&self.app.database_path).map_err(ErrorKind::from) { DeployState::CheckIfNeeded => match Database::load(&self.app.database_path).map_err(ErrorKind::from) {
Ok(database) => return Ok(Deployed::Existing(database).into()), Ok(database) => return Ok(Deployed::Existing(database).into()),
Err(ErrorKind::MissingFile(_)) => { Err(ErrorKind::MissingFile(_e)) => {
let main_data = self.app.home_bridge.constructor( #[cfg(feature = "deploy")] {
self.app.config.home.contract.bin.clone().0, println!("deploy");
self.app.config.authorities.required_signatures, let main_data = self.app.home_bridge.constructor(
self.app.config.authorities.accounts.clone(), self.app.config.home.contract.bin.clone().0,
self.app.config.estimated_gas_cost_of_withdraw self.app.config.authorities.required_signatures,
); self.app.config.authorities.accounts.clone(),
let test_data = self.app.foreign_bridge.constructor( self.app.config.estimated_gas_cost_of_withdraw
self.app.config.foreign.contract.bin.clone().0, );
self.app.config.authorities.required_signatures, let test_data = self.app.foreign_bridge.constructor(
self.app.config.authorities.accounts.clone(), self.app.config.foreign.contract.bin.clone().0,
self.app.config.estimated_gas_cost_of_withdraw self.app.config.authorities.required_signatures,
); self.app.config.authorities.accounts.clone(),
self.app.config.estimated_gas_cost_of_withdraw
);
let main_tx = Transaction { let main_tx = Transaction {
nonce: U256::zero(), nonce: U256::zero(),
gas_price: self.app.config.txs.home_deploy.gas_price.into(), gas_price: self.app.config.txs.home_deploy.gas_price.into(),
gas: self.app.config.txs.home_deploy.gas.into(), gas: self.app.config.txs.home_deploy.gas.into(),
action: Action::Create, action: Action::Create,
value: U256::zero(), value: U256::zero(),
data: main_data.into(), data: main_data.into(),
}; };
let test_tx = Transaction { let test_tx = Transaction {
nonce: U256::zero(), nonce: U256::zero(),
gas_price: self.app.config.txs.foreign_deploy.gas_price.into(), gas_price: self.app.config.txs.foreign_deploy.gas_price.into(),
gas: self.app.config.txs.foreign_deploy.gas.into(), gas: self.app.config.txs.foreign_deploy.gas.into(),
action: Action::Create, action: Action::Create,
value: U256::zero(), value: U256::zero(),
data: test_data.into(), data: test_data.into(),
}; };
let main_future = api::send_transaction_with_nonce(self.app.connections.home.clone(), self.app.clone(), let main_future = api::send_transaction_with_nonce(self.app.connections.home.clone(), self.app.clone(),
self.app.config.home.clone(), main_tx, self.home_chain_id, self.app.config.home.clone(), main_tx, self.home_chain_id,
TransactionWithConfirmation(self.app.connections.home.clone(), self.app.config.home.poll_interval, self.app.config.home.required_confirmations)); TransactionWithConfirmation(self.app.connections.home.clone(), self.app.config.home.poll_interval, self.app.config.home.required_confirmations));
let test_future = api::send_transaction_with_nonce(self.app.connections.foreign.clone(), self.app.clone(), let test_future = api::send_transaction_with_nonce(self.app.connections.foreign.clone(), self.app.clone(),
self.app.config.foreign.clone(), test_tx, self.foreign_chain_id, self.app.config.foreign.clone(), test_tx, self.foreign_chain_id,
TransactionWithConfirmation(self.app.connections.foreign.clone(), self.app.config.foreign.poll_interval, self.app.config.foreign.required_confirmations)); TransactionWithConfirmation(self.app.connections.foreign.clone(), self.app.config.foreign.poll_interval, self.app.config.foreign.required_confirmations));
DeployState::Deploying(main_future.join(test_future)) DeployState::Deploying(main_future.join(test_future))
}
#[cfg(not(feature = "deploy"))] {
return Err(ErrorKind::MissingFile(_e).into())
}
}, },
Err(err) => return Err(err.into()), Err(err) => return Err(err.into()),
}, },
#[cfg(feature = "deploy")]
DeployState::Deploying(ref mut future) => { DeployState::Deploying(ref mut future) => {
let (main_receipt, test_receipt) = try_ready!(future.poll()); let (main_receipt, test_receipt) = try_ready!(future.poll());
let database = Database { let database = Database {
@ -104,8 +131,9 @@ impl<T: Transport + Clone> Future for Deploy<T> {
return Ok(Deployed::New(database).into()) return Ok(Deployed::New(database).into())
}, },
}; };
#[allow(unreachable_code)] {
self.state = next_state; self.state = _next_state;
}
} }
} }
} }

View File

@ -124,7 +124,9 @@ impl Node {
#[derive(Debug, PartialEq, Default, Clone)] #[derive(Debug, PartialEq, Default, Clone)]
pub struct Transactions { pub struct Transactions {
#[cfg(feature = "deploy")]
pub home_deploy: TransactionConfig, pub home_deploy: TransactionConfig,
#[cfg(feature = "deploy")]
pub foreign_deploy: TransactionConfig, pub foreign_deploy: TransactionConfig,
pub deposit_relay: TransactionConfig, pub deposit_relay: TransactionConfig,
pub withdraw_confirm: TransactionConfig, pub withdraw_confirm: TransactionConfig,
@ -134,7 +136,9 @@ pub struct Transactions {
impl Transactions { impl Transactions {
fn from_load_struct(cfg: load::Transactions) -> Self { fn from_load_struct(cfg: load::Transactions) -> Self {
Transactions { Transactions {
#[cfg(feature = "deploy")]
home_deploy: cfg.home_deploy.map(TransactionConfig::from_load_struct).unwrap_or_default(), home_deploy: cfg.home_deploy.map(TransactionConfig::from_load_struct).unwrap_or_default(),
#[cfg(feature = "deploy")]
foreign_deploy: cfg.foreign_deploy.map(TransactionConfig::from_load_struct).unwrap_or_default(), foreign_deploy: cfg.foreign_deploy.map(TransactionConfig::from_load_struct).unwrap_or_default(),
deposit_relay: cfg.deposit_relay.map(TransactionConfig::from_load_struct).unwrap_or_default(), deposit_relay: cfg.deposit_relay.map(TransactionConfig::from_load_struct).unwrap_or_default(),
withdraw_confirm: cfg.withdraw_confirm.map(TransactionConfig::from_load_struct).unwrap_or_default(), withdraw_confirm: cfg.withdraw_confirm.map(TransactionConfig::from_load_struct).unwrap_or_default(),
@ -201,9 +205,10 @@ mod load {
} }
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Transactions { pub struct Transactions {
#[cfg(feature = "deploy")]
pub home_deploy: Option<TransactionConfig>, pub home_deploy: Option<TransactionConfig>,
#[cfg(feature = "deploy")]
pub foreign_deploy: Option<TransactionConfig>, pub foreign_deploy: Option<TransactionConfig>,
pub deposit_relay: Option<TransactionConfig>, pub deposit_relay: Option<TransactionConfig>,
pub withdraw_confirm: Option<TransactionConfig>, pub withdraw_confirm: Option<TransactionConfig>,
@ -235,7 +240,9 @@ mod load {
mod tests { mod tests {
use std::time::Duration; use std::time::Duration;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use super::{Config, Node, ContractConfig, Transactions, Authorities, TransactionConfig}; use super::{Config, Node, ContractConfig, Transactions, Authorities};
#[cfg(feature = "deploy")]
use super::TransactionConfig;
#[test] #[test]
fn load_full_setup_from_str() { fn load_full_setup_from_str() {
@ -313,10 +320,12 @@ home_deploy = { gas = 20 }
keystore: "/keys/".into(), keystore: "/keys/".into(),
}; };
expected.txs.home_deploy = TransactionConfig { #[cfg(feature = "deploy")] {
gas: 20, expected.txs.home_deploy = TransactionConfig {
gas_price: 0, gas: 20,
}; gas_price: 0,
};
}
let config = Config::load_from_str(toml).unwrap(); let config = Config::load_from_str(toml).unwrap();
assert_eq!(expected, config); assert_eq!(expected, config);

View File

@ -18,3 +18,7 @@ env_logger = "0.4"
futures = "0.1.14" futures = "0.1.14"
jsonrpc-core = "8.0" jsonrpc-core = "8.0"
ctrlc = { version = "3.1", features = ["termination"] } ctrlc = { version = "3.1", features = ["termination"] }
[features]
default = []
deploy = ["bridge/deploy"]

View File

@ -151,7 +151,11 @@ fn execute<S, I>(command: I, running: Arc<AtomicBool>) -> Result<String, UserFac
*foreign_nonce = event_loop.run(api::eth_get_transaction_count(app.connections.foreign.clone(), app.config.foreign.account, None)).expect("can't initialize foreign nonce"); *foreign_nonce = event_loop.run(api::eth_get_transaction_count(app.connections.foreign.clone(), app.config.foreign.account, None)).expect("can't initialize foreign nonce");
} }
#[cfg(feature = "deploy")]
info!(target: "bridge", "Deploying contracts (if needed)"); info!(target: "bridge", "Deploying contracts (if needed)");
#[cfg(not(feature = "deploy"))]
info!(target: "bridge", "Reading the database");
let deployed = event_loop.run(create_deploy(app.clone(), home_chain_id, foreign_chain_id))?; let deployed = event_loop.run(create_deploy(app.clone(), home_chain_id, foreign_chain_id))?;
let database = match deployed { let database = match deployed {

View File

@ -4,7 +4,7 @@ version = "0.1.0"
authors = ["snd <kruemaxi@gmail.com>"] authors = ["snd <kruemaxi@gmail.com>"]
[dependencies] [dependencies]
bridge = { path = "../bridge" } bridge = { path = "../bridge", features = ["deploy"] }
futures = "0.1" futures = "0.1"
jsonrpc-core = "8.0" jsonrpc-core = "8.0"
web3 = "0.3" web3 = "0.3"

View File

@ -82,7 +82,7 @@ fn test_basic_deposit_then_withdraw() {
assert!(Command::new("cargo") assert!(Command::new("cargo")
.env("RUST_BACKTRACE", "1") .env("RUST_BACKTRACE", "1")
.current_dir("../cli") .current_dir("../cli")
.arg("build") .args(&["build", "--features", "deploy"])
.status() .status()
.expect("failed to build bridge cli") .expect("failed to build bridge cli")
.success()); .success());

View File

@ -83,7 +83,7 @@ fn test_insufficient_funds() {
assert!(Command::new("cargo") assert!(Command::new("cargo")
.env("RUST_BACKTRACE", "1") .env("RUST_BACKTRACE", "1")
.current_dir("../cli") .current_dir("../cli")
.arg("build") .args(&["build", "--features", "deploy"])
.status() .status()
.expect("failed to build bridge cli") .expect("failed to build bridge cli")
.success()); .success());