Skip to content

Commit

Permalink
Problem: required_signatures is static
Browse files Browse the repository at this point in the history
Validators' information is completely configured through validators
contracts and does not depend on `authorities.required_signatures`
parameter of bridge's configuration.

The number of validators also could be changed during run-time and
therefore `authorities.required_signatures` parameter will not reflect
the actual number of signatures required for transaction validation.

Solution: retrieve required_signatures from RequiredSignaturesChanged
event and requiredSignatures() method

Closes #74
  • Loading branch information
yrashk committed May 19, 2018
1 parent cc4147c commit 8a56c5c
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 51 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ accounts = [
"0x006e27b6a72e1f34c626762f3c4761547aff1421",
"0x006e27b6a72e1f34c626762f3c4761547aff1421"
]
required_signatures = 2

[transactions]
deposit_relay = { gas = 3000000, gas_price = 1000000000 }
Expand All @@ -121,7 +120,6 @@ withdraw_confirm = { gas = 3000000, gas_price = 1000000000 }
#### authorities options

- `authorities.account` - all authorities (**required**)
- `authorities.required_signatures` - number of authorities signatures required to consider action final (**required**)

#### transaction options

Expand Down
17 changes: 17 additions & 0 deletions bridge/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,23 @@ pub fn call<T: Transport>(transport: T, address: Address, payload: Bytes) -> Api
}
}

pub fn call_at<T: Transport>(transport: T, address: Address, payload: Bytes, block: Option<BlockNumber>) -> ApiCall<Bytes, T::Out> {
let future = api::Eth::new(transport).call(CallRequest {
from: None,
to: address,
gas: None,
gas_price: None,
value: None,
data: Some(payload),
}, block);

ApiCall {
future,
message: "eth_call",
}
}


/// Returns a eth_sign-compatible hash of data to sign.
/// The data is prepended with special message to prevent
/// chosen-plaintext attacks.
Expand Down
1 change: 1 addition & 0 deletions bridge/src/bridge/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ impl<T: Transport + Clone> Future for Deploy<T> {
checked_deposit_relay: main_receipt.block_number.low_u64(),
checked_withdraw_relay: test_receipt.block_number.low_u64(),
checked_withdraw_confirm: test_receipt.block_number.low_u64(),
withdraw_relay_required_signatures: Some(self.app.config.authorities.required_signatures),
};
return Ok(Deployed::New(database).into())
},
Expand Down
2 changes: 1 addition & 1 deletion bridge/src/bridge/deposit_relay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use itertools::Itertools;

fn deposits_filter(home: &home::HomeBridge, address: Address) -> FilterBuilder {
let filter = home.events().deposit().create_filter();
web3_filter(filter, address)
web3_filter(filter, ::std::iter::once(address))
}

fn deposit_relay_payload(home: &home::HomeBridge, foreign: &foreign::ForeignBridge, log: Log) -> Result<Bytes> {
Expand Down
21 changes: 13 additions & 8 deletions bridge/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::sync::{Arc, RwLock};
use std::path::PathBuf;
use futures::{Stream, Poll, Async};
use web3::Transport;
use web3::types::U256;
use web3::types::{U256, Address};
use app::App;
use database::Database;
use error::{Error, ErrorKind, Result};
Expand All @@ -27,7 +27,7 @@ pub use self::withdraw_confirm::{WithdrawConfirm, create_withdraw_confirm};
#[derive(Clone, Copy)]
pub enum BridgeChecked {
DepositRelay(u64),
WithdrawRelay(u64),
WithdrawRelay((u64, u32)),
WithdrawConfirm(u64),
}

Expand All @@ -47,8 +47,9 @@ impl BridgeBackend for FileBackend {
BridgeChecked::DepositRelay(n) => {
self.database.checked_deposit_relay = n;
},
BridgeChecked::WithdrawRelay(n) => {
BridgeChecked::WithdrawRelay((n, sigs)) => {
self.database.checked_withdraw_relay = n;
self.database.withdraw_relay_required_signatures = Some(sigs);
},
BridgeChecked::WithdrawConfirm(n) => {
self.database.checked_withdraw_confirm = n;
Expand All @@ -71,17 +72,18 @@ enum BridgeStatus {
}

/// Creates new bridge.
pub fn create_bridge<T: Transport + Clone>(app: Arc<App<T>>, init: &Database, home_chain_id: u64, foreign_chain_id: u64) -> Bridge<T, FileBackend> {
pub fn create_bridge<T: Transport + Clone>(app: Arc<App<T>>, init: &Database, home_chain_id: u64, foreign_chain_id: u64, foreign_validator_contract: Address) -> Bridge<T, FileBackend> {
let backend = FileBackend {
path: app.database_path.clone(),
database: init.clone(),
};

create_bridge_backed_by(app, init, backend, home_chain_id, foreign_chain_id)
create_bridge_backed_by(app, init, backend, home_chain_id, foreign_chain_id, foreign_validator_contract)
}

/// Creates new bridge writing to custom backend.
pub fn create_bridge_backed_by<T: Transport + Clone, F: BridgeBackend>(app: Arc<App<T>>, init: &Database, backend: F, home_chain_id: u64, foreign_chain_id: u64) -> Bridge<T, F> {
pub fn create_bridge_backed_by<T: Transport + Clone, F: BridgeBackend>(app: Arc<App<T>>, init: &Database, backend: F, home_chain_id: u64, foreign_chain_id: u64,
foreign_validator_contract: Address) -> Bridge<T, F> {
let home_balance = Arc::new(RwLock::new(None));
let foreign_balance = Arc::new(RwLock::new(None));
Bridge {
Expand All @@ -90,7 +92,7 @@ pub fn create_bridge_backed_by<T: Transport + Clone, F: BridgeBackend>(app: Arc<
foreign_balance: foreign_balance.clone(),
home_balance: home_balance.clone(),
deposit_relay: create_deposit_relay(app.clone(), init, foreign_balance.clone(), foreign_chain_id),
withdraw_relay: create_withdraw_relay(app.clone(), init, home_balance.clone(), home_chain_id),
withdraw_relay: create_withdraw_relay(app.clone(), init, home_balance.clone(), home_chain_id, foreign_validator_contract),
withdraw_confirm: create_withdraw_confirm(app.clone(), init, foreign_balance.clone(), foreign_chain_id),
state: BridgeStatus::Wait,
backend,
Expand Down Expand Up @@ -168,13 +170,15 @@ impl<T: Transport, F: BridgeBackend> Stream for Bridge<T, F> {
self.check_balances()?;
}


let w_relay = try_bridge!(self.withdraw_relay.poll().map_err(|e| ErrorKind::ContextualizedError(Box::new(e), "withdraw_relay"))).
map(BridgeChecked::WithdrawRelay);

if w_relay.is_some() {
self.check_balances()?;
}


let w_confirm = try_bridge!(self.withdraw_confirm.poll().map_err(|e| ErrorKind::ContextualizedError(Box::new(e), "withdraw_confirm"))).
map(BridgeChecked::WithdrawConfirm);

Expand Down Expand Up @@ -226,10 +230,11 @@ mod tests {
assert_eq!(1, backend.database.checked_deposit_relay);
assert_eq!(0, backend.database.checked_withdraw_confirm);
assert_eq!(0, backend.database.checked_withdraw_relay);
backend.save(vec![BridgeChecked::DepositRelay(2), BridgeChecked::WithdrawConfirm(3), BridgeChecked::WithdrawRelay(2)]).unwrap();
backend.save(vec![BridgeChecked::DepositRelay(2), BridgeChecked::WithdrawConfirm(3), BridgeChecked::WithdrawRelay((2, 1))]).unwrap();
assert_eq!(2, backend.database.checked_deposit_relay);
assert_eq!(3, backend.database.checked_withdraw_confirm);
assert_eq!(2, backend.database.checked_withdraw_relay);
assert_eq!(1, backend.database.withdraw_relay_required_signatures.unwrap());

let loaded = Database::load(path).unwrap();
assert_eq!(backend.database, loaded);
Expand Down
2 changes: 1 addition & 1 deletion bridge/src/bridge/withdraw_confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use super::nonce::{NonceCheck, SendRawTransaction};

fn withdraws_filter(foreign: &foreign::ForeignBridge, address: Address) -> FilterBuilder {
let filter = foreign.events().withdraw().create_filter();
web3_filter(filter, address)
web3_filter(filter, ::std::iter::once(address))
}

fn withdraw_submit_signature_payload(foreign: &foreign::ForeignBridge, withdraw_message: Vec<u8>, signature: H520) -> Bytes {
Expand Down
Loading

0 comments on commit 8a56c5c

Please sign in to comment.