[hardware wallet] sleeping -> pollling (#8018)
* Use polling, enable missing doc warnings & docs * make try_connect_polling() a free function
This commit is contained in:
parent
fb17ae7751
commit
81b52c7336
@ -21,8 +21,7 @@ use std::cmp::min;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::time::Duration;
|
use std::time::{Duration, Instant};
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
use ethereum_types::{H256, Address};
|
use ethereum_types::{H256, Address};
|
||||||
use ethkey::Signature;
|
use ethkey::Signature;
|
||||||
@ -353,11 +352,24 @@ impl Manager {
|
|||||||
Err(Error::InvalidDevice)
|
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
|
/// 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 {
|
pub struct EventHandler {
|
||||||
ledger: Weak<Manager>,
|
ledger: Weak<Manager>,
|
||||||
}
|
}
|
||||||
@ -371,21 +383,19 @@ impl EventHandler {
|
|||||||
|
|
||||||
impl libusb::Hotplug for EventHandler {
|
impl libusb::Hotplug for EventHandler {
|
||||||
fn device_arrived(&mut self, device: libusb::Device) {
|
fn device_arrived(&mut self, device: libusb::Device) {
|
||||||
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
|
|
||||||
debug!(target: "hw", "Ledger arrived");
|
debug!(target: "hw", "Ledger arrived");
|
||||||
// Wait for the device to boot up
|
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
|
||||||
thread::sleep(Duration::from_millis(1000));
|
if try_connect_polling(ledger, Duration::from_millis(500)) != true {
|
||||||
if let Err(e) = ledger.update_devices() {
|
debug!(target: "hw", "Ledger connect timeout");
|
||||||
debug!(target: "hw", "Ledger connect error: {:?}", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn device_left(&mut self, device: libusb::Device) {
|
fn device_left(&mut self, device: libusb::Device) {
|
||||||
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
|
|
||||||
debug!(target: "hw", "Ledger left");
|
debug!(target: "hw", "Ledger left");
|
||||||
if let Err(e) = ledger.update_devices() {
|
if let (Some(ledger), Ok(_)) = (self.ledger.upgrade(), Manager::is_valid_ledger(&device)) {
|
||||||
debug!(target: "hw", "Ledger disconnect error: {:?}", e);
|
if try_connect_polling(ledger, Duration::from_millis(500)) != true {
|
||||||
|
debug!(target: "hw", "Ledger disconnect timeout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
//! Hardware wallet management.
|
//! Hardware wallet management.
|
||||||
|
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate ethkey;
|
extern crate ethkey;
|
||||||
extern crate hidapi;
|
extern crate hidapi;
|
||||||
@ -61,12 +63,19 @@ pub enum Error {
|
|||||||
/// or less a duplicate of ethcore::transaction::Transaction, but we can't
|
/// or less a duplicate of ethcore::transaction::Transaction, but we can't
|
||||||
/// import ethcore here as that would be a circular dependency.
|
/// import ethcore here as that would be a circular dependency.
|
||||||
pub struct TransactionInfo {
|
pub struct TransactionInfo {
|
||||||
|
/// Nonce
|
||||||
pub nonce: U256,
|
pub nonce: U256,
|
||||||
|
/// Gas price
|
||||||
pub gas_price: U256,
|
pub gas_price: U256,
|
||||||
|
/// Gas limit
|
||||||
pub gas_limit: U256,
|
pub gas_limit: U256,
|
||||||
|
/// Receiver
|
||||||
pub to: Option<Address>,
|
pub to: Option<Address>,
|
||||||
|
/// Value
|
||||||
pub value: U256,
|
pub value: U256,
|
||||||
|
/// Data
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
|
/// Chain ID
|
||||||
pub chain_id: Option<u64>,
|
pub chain_id: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,9 @@ use super::{WalletInfo, TransactionInfo, KeyPath};
|
|||||||
use std::cmp::{min, max};
|
use std::cmp::{min, max};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::time::Duration;
|
use std::time::{Duration, Instant};
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
use ethereum_types::{U256, H256, Address};
|
use ethereum_types::{U256, H256, Address};
|
||||||
|
|
||||||
use ethkey::Signature;
|
use ethkey::Signature;
|
||||||
use hidapi;
|
use hidapi;
|
||||||
use libusb;
|
use libusb;
|
||||||
@ -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
|
/// Trezor event handler
|
||||||
/// A separate thread is handeling incoming events
|
/// 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 {
|
pub struct EventHandler {
|
||||||
trezor: Weak<Manager>,
|
trezor: Weak<Manager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventHandler {
|
impl EventHandler {
|
||||||
// Trezor event handler constructor
|
/// Trezor event handler constructor
|
||||||
pub fn new(trezor: Weak<Manager>) -> Self {
|
pub fn new(trezor: Weak<Manager>) -> Self {
|
||||||
Self { trezor: trezor }
|
Self { trezor: trezor }
|
||||||
}
|
}
|
||||||
@ -419,20 +431,17 @@ impl libusb::Hotplug for EventHandler {
|
|||||||
fn device_arrived(&mut self, _device: libusb::Device) {
|
fn device_arrived(&mut self, _device: libusb::Device) {
|
||||||
debug!(target: "hw", "Trezor V1 arrived");
|
debug!(target: "hw", "Trezor V1 arrived");
|
||||||
if let Some(trezor) = self.trezor.upgrade() {
|
if let Some(trezor) = self.trezor.upgrade() {
|
||||||
// Wait for the device to boot up
|
if try_connect_polling(trezor, Duration::from_millis(500)) != true {
|
||||||
thread::sleep(Duration::from_millis(1000));
|
debug!(target: "hw", "Ledger connect timeout");
|
||||||
if let Err(e) = trezor.update_devices() {
|
|
||||||
debug!(target: "hw", "Trezor V1 connect error: {:?}", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn device_left(&mut self, _device: libusb::Device) {
|
fn device_left(&mut self, _device: libusb::Device) {
|
||||||
debug!(target: "hw", "Trezor V1 left");
|
debug!(target: "hw", "Trezor V1 left");
|
||||||
if let Some(trezor) = self.trezor.upgrade() {
|
if let Some(trezor) = self.trezor.upgrade() {
|
||||||
if let Err(e) = trezor.update_devices() {
|
if try_connect_polling(trezor, Duration::from_millis(500)) != true {
|
||||||
debug!(target: "hw", "Trezor V1 disconnect error: {:?}", e);
|
debug!(target: "hw", "Ledger disconnect timeout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user