Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

[hardware wallet] sleeping -> pollling #8018

Merged
merged 2 commits into from
Mar 2, 2018
Merged
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
34 changes: 22 additions & 12 deletions hw/src/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ use std::cmp::min;
use std::fmt;
use std::str::FromStr;
use std::sync::{Arc, Weak};
use std::time::Duration;
use std::thread;
use std::time::{Duration, Instant};

use ethereum_types::{H256, Address};
use ethkey::Signature;
Expand Down Expand Up @@ -353,39 +352,50 @@ impl Manager {
Err(Error::InvalidDevice)
}
}
}

// Try to connect to the device using polling in at most the time specified by the `timeout`
fn try_connect_polling(ledger: Arc<Manager>, timeout: Duration) -> bool {
let start_time = Instant::now();
while start_time.elapsed() <= timeout {
if let Ok(_) = ledger.update_devices() {
return true
}
}
false
}

/// Ledger event handler
/// A seperate thread is handling incoming events
/// A seperate thread is hanedling incoming events
///
/// Note, that this run to completion and race-conditions can't occur but this can
/// therefore starve other events for being process with a spinlock or similar
pub struct EventHandler {
ledger: Weak<Manager>,
}

impl EventHandler {
/// Ledger event handler constructor
/// Ledger event handler constructor
pub fn new(ledger: Weak<Manager>) -> Self {
Self { ledger: ledger }
}
}

impl libusb::Hotplug for EventHandler {
fn device_arrived(&mut self, device: libusb::Device) {
debug!(target: "hw", "Ledger arrived");
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
debug!(target: "hw", "Ledger arrived");
// Wait for the device to boot up
thread::sleep(Duration::from_millis(1000));
if let Err(e) = ledger.update_devices() {
debug!(target: "hw", "Ledger connect error: {:?}", e);
if try_connect_polling(ledger, Duration::from_millis(500)) != true {
debug!(target: "hw", "Ledger connect timeout");
}
}
}

fn device_left(&mut self, device: libusb::Device) {
debug!(target: "hw", "Ledger left");
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
debug!(target: "hw", "Ledger left");
if let Err(e) = ledger.update_devices() {
debug!(target: "hw", "Ledger disconnect error: {:?}", e);
if try_connect_polling(ledger, Duration::from_millis(500)) != true {
debug!(target: "hw", "Ledger disconnect timeout");
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions hw/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

//! Hardware wallet management.

#![warn(missing_docs)]

extern crate ethereum_types;
extern crate ethkey;
extern crate hidapi;
Expand Down Expand Up @@ -61,12 +63,19 @@ pub enum Error {
/// or less a duplicate of ethcore::transaction::Transaction, but we can't
/// import ethcore here as that would be a circular dependency.
pub struct TransactionInfo {
/// Nonce
pub nonce: U256,
/// Gas price
pub gas_price: U256,
/// Gas limit
pub gas_limit: U256,
/// Receiver
pub to: Option<Address>,
/// Value
pub value: U256,
/// Data
pub data: Vec<u8>,
/// Chain ID
pub chain_id: Option<u64>,
}

Expand Down
35 changes: 22 additions & 13 deletions hw/src/trezor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ use super::{WalletInfo, TransactionInfo, KeyPath};
use std::cmp::{min, max};
use std::fmt;
use std::sync::{Arc, Weak};
use std::time::Duration;
use std::thread;
use std::time::{Duration, Instant};

use ethereum_types::{U256, H256, Address};

use ethkey::Signature;
use hidapi;
use libusb;
Expand All @@ -40,8 +38,8 @@ use trezor_sys::messages::{EthereumAddress, PinMatrixAck, MessageType, EthereumT

/// Trezor v1 vendor ID
pub const TREZOR_VID: u16 = 0x534c;
/// Trezor product IDs
pub const TREZOR_PIDS: [u16; 1] = [0x0001];
/// Trezor product IDs
pub const TREZOR_PIDS: [u16; 1] = [0x0001];

const ETH_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003C, 0x80000000, 0, 0]; // m/44'/60'/0'/0/0
const ETC_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003D, 0x80000000, 0, 0]; // m/44'/61'/0'/0/0
Expand Down Expand Up @@ -402,14 +400,28 @@ impl Manager {
}
}

// Try to connect to the device using polling in at most the time specified by the `timeout`
fn try_connect_polling(trezor: Arc<Manager>, duration: Duration) -> bool {
let start_time = Instant::now();
while start_time.elapsed() <= duration {
if let Ok(_) = trezor.update_devices() {
return true
}
}
false
}

/// Trezor event handler
/// A separate thread is handeling incoming events
///
/// Note, that this run to completion and race-conditions can't occur but this can
/// therefore starve other events for being process with a spinlock or similar
pub struct EventHandler {
trezor: Weak<Manager>,
}

impl EventHandler {
// Trezor event handler constructor
/// Trezor event handler constructor
pub fn new(trezor: Weak<Manager>) -> Self {
Self { trezor: trezor }
}
Expand All @@ -419,20 +431,17 @@ impl libusb::Hotplug for EventHandler {
fn device_arrived(&mut self, _device: libusb::Device) {
debug!(target: "hw", "Trezor V1 arrived");
if let Some(trezor) = self.trezor.upgrade() {
// Wait for the device to boot up
thread::sleep(Duration::from_millis(1000));
if let Err(e) = trezor.update_devices() {
debug!(target: "hw", "Trezor V1 connect error: {:?}", e);
if try_connect_polling(trezor, Duration::from_millis(500)) != true {
debug!(target: "hw", "Ledger connect timeout");
}

}
}

fn device_left(&mut self, _device: libusb::Device) {
debug!(target: "hw", "Trezor V1 left");
if let Some(trezor) = self.trezor.upgrade() {
if let Err(e) = trezor.update_devices() {
debug!(target: "hw", "Trezor V1 disconnect error: {:?}", e);
if try_connect_polling(trezor, Duration::from_millis(500)) != true {
debug!(target: "hw", "Ledger disconnect timeout");
}
}
}
Expand Down