From ea4f02172824371ef162db9ee0b974ef4597a541 Mon Sep 17 00:00:00 2001 From: edouard Date: Fri, 3 Feb 2023 19:17:52 +0100 Subject: [PATCH] fix hws list reloading I wanted the refresh button to add more harware wallet to the list without erasing the previous list in order to not cut the existing communication channels. But with the new display of "unsupported wallet" this behaviour can corrupt the list. An "unsupported wallet" can become "supported" because user switch app or unlock. It is preferable to reset the full list and drop the objects after a refresh. --- gui/src/app/state/spend/detail.rs | 3 ++ gui/src/installer/step/descriptor.rs | 51 +++++++++++++--------------- gui/src/installer/view.rs | 11 ++++-- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/gui/src/app/state/spend/detail.rs b/gui/src/app/state/spend/detail.rs index eacb53c4..4c6f45aa 100644 --- a/gui/src/app/state/spend/detail.rs +++ b/gui/src/app/state/spend/detail.rs @@ -345,6 +345,9 @@ impl Action for SignAction { } } Message::View(view::Message::Reload) => { + self.hws = Vec::new(); + self.chosen_hw = None; + self.error = None; return self.load(wallet, daemon); } _ => {} diff --git a/gui/src/installer/step/descriptor.rs b/gui/src/installer/step/descriptor.rs index 23eabb88..1dc8c5d5 100644 --- a/gui/src/installer/step/descriptor.rs +++ b/gui/src/installer/step/descriptor.rs @@ -14,6 +14,8 @@ use liana::{ }, }; +use async_hwi::DeviceKind; + use crate::{ app::settings::KeySetting, hw::{list_hardware_wallets, HardwareWallet}, @@ -635,6 +637,7 @@ impl DescriptorKeyModal for EditXpubModal { self.hws = hws; } Message::Reload => { + self.hws = Vec::new(); return self.load(); } Message::DefineDescriptor(message::DefineDescriptor::HWXpubImported(res)) => { @@ -873,7 +876,8 @@ impl Step for ParticipateXpub { Message::ConnectedHardwareWallets(hws) => { for hw in hws { if let Some(xpub_hw) = self.xpubs_hw.iter_mut().find(|h| { - h.hw.fingerprint() == hw.fingerprint() && h.hw.kind() == hw.kind() + h.hw.kind() == hw.kind() + && (h.hw.fingerprint() == hw.fingerprint() || !h.hw.is_supported()) }) { xpub_hw.hw = hw; } else { @@ -1026,7 +1030,9 @@ pub struct RegisterDescriptor { descriptor: Option, processing: bool, chosen_hw: Option, - hws: Vec<(HardwareWallet, Option<[u8; 32]>, bool)>, + hws: Vec, + hmacs: Vec<(Fingerprint, DeviceKind, Option<[u8; 32]>)>, + registered: HashSet, error: Option, } @@ -1037,17 +1043,13 @@ impl Step for RegisterDescriptor { fn update(&mut self, message: Message) -> Command { match message { Message::Select(i) => { - if let Some(( - HardwareWallet::Supported { - device, - fingerprint, - .. - }, - hmac, - _, - )) = self.hws.get(i) + if let Some(HardwareWallet::Supported { + device, + fingerprint, + .. + }) = self.hws.get(i) { - if hmac.is_none() { + if !self.registered.contains(fingerprint) { let descriptor = self.descriptor.as_ref().unwrap().to_string(); self.chosen_hw = Some(i); self.processing = true; @@ -1066,26 +1068,21 @@ impl Step for RegisterDescriptor { Ok((fingerprint, hmac)) => { if let Some(hw_h) = self .hws - .iter_mut() - .find(|hw_h| hw_h.0.fingerprint() == Some(fingerprint)) + .iter() + .find(|hw_h| hw_h.fingerprint() == Some(fingerprint)) { - hw_h.1 = hmac; - hw_h.2 = true; + self.registered.insert(fingerprint); + self.hmacs.push((fingerprint, *hw_h.kind(), hmac)); } } Err(e) => self.error = Some(e), } } Message::ConnectedHardwareWallets(hws) => { - for hw in hws { - if !self.hws.iter().any(|(h, _, _)| { - h.fingerprint() == hw.fingerprint() && h.kind() == hw.kind() - }) { - self.hws.push((hw, None, false)); - } - } + self.hws = hws; } Message::Reload => { + self.hws = Vec::new(); return self.load(); } _ => {} @@ -1093,11 +1090,8 @@ impl Step for RegisterDescriptor { Command::none() } fn apply(&mut self, ctx: &mut Context) -> bool { - for (hw, token, registered) in &self.hws { - if *registered { - ctx.hws - .push((*hw.kind(), hw.fingerprint().unwrap(), *token)); - } + for (fingerprint, kind, token) in &self.hmacs { + ctx.hws.push((*kind, *fingerprint, *token)); } true } @@ -1113,6 +1107,7 @@ impl Step for RegisterDescriptor { progress, desc.to_string(), &self.hws, + &self.registered, self.error.as_ref(), self.processing, self.chosen_hw, diff --git a/gui/src/installer/view.rs b/gui/src/installer/view.rs index bedaaf07..b991c028 100644 --- a/gui/src/installer/view.rs +++ b/gui/src/installer/view.rs @@ -3,6 +3,8 @@ use iced::widget::{ }; use iced::{alignment, Alignment, Element, Length}; +use std::collections::HashSet; + use liana::miniscript::bitcoin; use crate::{ @@ -606,7 +608,8 @@ pub fn participate_xpub( pub fn register_descriptor<'a>( progress: (usize, usize), descriptor: String, - hws: &'a [(HardwareWallet, Option<[u8; 32]>, bool)], + hws: &'a [HardwareWallet], + registered: &HashSet, error: Option<&Error>, processing: bool, chosen_hw: Option, @@ -654,10 +657,12 @@ pub fn register_descriptor<'a>( .fold(Column::new().spacing(10), |col, (i, hw)| { col.push(hw_list_view( i, - &hw.0, + hw, Some(i) == chosen_hw, processing, - hw.2, + hw.fingerprint() + .map(|fg| registered.contains(&fg)) + .unwrap_or(false), )) }), )