Merge #1714: fix import backup for existing wallet
904fc728de20cdd283a4273093e6b59c5609630c fix import backup for existing wallet (edouardparis)
Pull request description:
We pass the wallet to the import_backup method
so the wallet id is used to find the correct wallet settings to update in the settings file.
ACKs for top commit:
jp1ac4:
utACK 904fc728de20cdd283a4273093e6b59c5609630c.
Tree-SHA512: 0a2a6c77d333460cc06ad141a7685d88911bc40bc3cd221111dd6611ca45e8c5552f46f7a694e44f0b47b4a5c1cd6946e25c755de83cbfe6259de93d6b9b65e0
This commit is contained in:
commit
63b32ff3a7
@ -83,7 +83,7 @@ impl ExportModal {
|
||||
}
|
||||
ImportExportType::ImportPsbt(_) => "Import PSBT",
|
||||
ImportExportType::ImportDescriptor => "Import Descriptor",
|
||||
ImportExportType::ImportBackup(..) => "Restore Backup",
|
||||
ImportExportType::ImportBackup { .. } => "Restore Backup",
|
||||
ImportExportType::WalletFromBackup => "Import existing wallet from backup",
|
||||
}
|
||||
}
|
||||
@ -111,7 +111,7 @@ impl ExportModal {
|
||||
ImportExportType::ExportBackup(_) | ImportExportType::ExportProcessBackup(..) => {
|
||||
format!("liana-backup-{date}.json")
|
||||
}
|
||||
ImportExportType::WalletFromBackup | ImportExportType::ImportBackup(_, _) => {
|
||||
ImportExportType::WalletFromBackup | ImportExportType::ImportBackup { .. } => {
|
||||
"liana-backup.json".to_string()
|
||||
}
|
||||
}
|
||||
@ -140,15 +140,33 @@ impl ExportModal {
|
||||
}
|
||||
Progress::Finished | Progress::Ended => self.state = ImportExportState::Ended,
|
||||
Progress::KeyAliasesConflict(ref sender) => {
|
||||
if let ImportExportType::ImportBackup(_, None) = &self.import_export_type {
|
||||
self.import_export_type =
|
||||
ImportExportType::ImportBackup(None, Some(sender.clone()));
|
||||
if let ImportExportType::ImportBackup {
|
||||
network_dir,
|
||||
wallet,
|
||||
..
|
||||
} = &self.import_export_type
|
||||
{
|
||||
self.import_export_type = ImportExportType::ImportBackup {
|
||||
network_dir: network_dir.clone(),
|
||||
wallet: wallet.clone(),
|
||||
overwrite_labels: None,
|
||||
overwrite_aliases: Some(sender.clone()),
|
||||
};
|
||||
}
|
||||
}
|
||||
Progress::LabelsConflict(ref sender) => {
|
||||
if let ImportExportType::ImportBackup(None, _) = &self.import_export_type {
|
||||
self.import_export_type =
|
||||
ImportExportType::ImportBackup(Some(sender.clone()), None);
|
||||
if let ImportExportType::ImportBackup {
|
||||
network_dir,
|
||||
wallet,
|
||||
..
|
||||
} = &self.import_export_type
|
||||
{
|
||||
self.import_export_type = ImportExportType::ImportBackup {
|
||||
network_dir: network_dir.clone(),
|
||||
wallet: wallet.clone(),
|
||||
overwrite_labels: Some(sender.clone()),
|
||||
overwrite_aliases: None,
|
||||
};
|
||||
}
|
||||
}
|
||||
Progress::Error(e) => {
|
||||
@ -164,7 +182,7 @@ impl ExportModal {
|
||||
});
|
||||
}
|
||||
Progress::Descriptor(_) => {
|
||||
if self.import_export_type == ImportExportType::ImportDescriptor {
|
||||
if matches!(self.import_export_type, ImportExportType::ImportDescriptor) {
|
||||
self.state = ImportExportState::Ended;
|
||||
}
|
||||
}
|
||||
@ -192,10 +210,13 @@ impl ExportModal {
|
||||
}
|
||||
ImportExportMessage::Close | ImportExportMessage::Open => { /* unreachable */ }
|
||||
ImportExportMessage::Overwrite => {
|
||||
if let ImportExportType::ImportBackup(labels, aliases) =
|
||||
&mut self.import_export_type
|
||||
if let ImportExportType::ImportBackup {
|
||||
overwrite_labels,
|
||||
overwrite_aliases,
|
||||
..
|
||||
} = &mut self.import_export_type
|
||||
{
|
||||
if let Some(sender) = labels.take() {
|
||||
if let Some(sender) = overwrite_labels.take() {
|
||||
return Task::perform(
|
||||
async move {
|
||||
if sender.send(true).await.is_err() {
|
||||
@ -206,7 +227,7 @@ impl ExportModal {
|
||||
},
|
||||
|_| ImportExportMessage::Ignore.into(),
|
||||
);
|
||||
} else if let Some(sender) = aliases.take() {
|
||||
} else if let Some(sender) = overwrite_aliases.take() {
|
||||
return Task::perform(
|
||||
async move {
|
||||
if sender.send(true).await.is_err() {
|
||||
@ -221,10 +242,13 @@ impl ExportModal {
|
||||
}
|
||||
}
|
||||
ImportExportMessage::Ignore => {
|
||||
if let ImportExportType::ImportBackup(labels, aliases) =
|
||||
&mut self.import_export_type
|
||||
if let ImportExportType::ImportBackup {
|
||||
overwrite_labels,
|
||||
overwrite_aliases,
|
||||
..
|
||||
} = &mut self.import_export_type
|
||||
{
|
||||
if let Some(sender) = labels.take() {
|
||||
if let Some(sender) = overwrite_labels.take() {
|
||||
return Task::perform(
|
||||
async move {
|
||||
if sender.send(false).await.is_err() {
|
||||
@ -235,7 +259,7 @@ impl ExportModal {
|
||||
},
|
||||
|_| ImportExportMessage::Ignore.into(),
|
||||
);
|
||||
} else if let Some(sender) = aliases.take() {
|
||||
} else if let Some(sender) = overwrite_aliases.take() {
|
||||
return Task::perform(
|
||||
async move {
|
||||
if sender.send(false).await.is_err() {
|
||||
|
||||
@ -269,8 +269,15 @@ impl State for ImportExportSettingsState {
|
||||
}
|
||||
Message::View(view::Message::Settings(view::SettingsMessage::ImportWallet)) => {
|
||||
if self.modal.is_none() {
|
||||
let modal =
|
||||
ExportModal::new(Some(daemon), ImportExportType::ImportBackup(None, None));
|
||||
let modal = ExportModal::new(
|
||||
Some(daemon),
|
||||
ImportExportType::ImportBackup {
|
||||
network_dir: cache.datadir_path.network_directory(cache.network),
|
||||
wallet: self.wallet.clone(),
|
||||
overwrite_labels: None,
|
||||
overwrite_aliases: None,
|
||||
},
|
||||
);
|
||||
launch!(self, modal, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,8 +289,15 @@ impl State for WalletSettingsState {
|
||||
}
|
||||
Message::View(view::Message::Settings(view::SettingsMessage::ImportWallet)) => {
|
||||
if self.modal.is_none() {
|
||||
let modal =
|
||||
ExportModal::new(Some(daemon), ImportExportType::ImportBackup(None, None));
|
||||
let modal = ExportModal::new(
|
||||
Some(daemon),
|
||||
ImportExportType::ImportBackup {
|
||||
network_dir: cache.datadir_path.network_directory(cache.network),
|
||||
wallet: self.wallet.clone(),
|
||||
overwrite_labels: None,
|
||||
overwrite_aliases: None,
|
||||
},
|
||||
);
|
||||
let launch = modal.launch(false);
|
||||
self.modal = Modal::ImportExport(modal);
|
||||
launch
|
||||
|
||||
@ -86,7 +86,11 @@ pub fn export_modal<'a, Message: From<ImportExportMessage> + Clone + 'static>(
|
||||
)),
|
||||
);
|
||||
let (msg, button) = match import_export_type {
|
||||
ImportExportType::ImportBackup(labels, aliases) => match (labels, aliases) {
|
||||
ImportExportType::ImportBackup {
|
||||
overwrite_labels,
|
||||
overwrite_aliases,
|
||||
..
|
||||
} => match (overwrite_labels, overwrite_aliases) {
|
||||
(Some(_), _) => labels_btn,
|
||||
|
||||
(_, Some(_)) => aliases_btn,
|
||||
|
||||
@ -165,10 +165,12 @@ pub enum ImportExportType {
|
||||
ExportXpub(String),
|
||||
ExportBackup(String),
|
||||
ExportProcessBackup(LianaDirectory, Network, Arc<Config>, Arc<Wallet>),
|
||||
ImportBackup(
|
||||
Option<Sender<bool>>, /*overwrite_labels*/
|
||||
Option<Sender<bool>>, /*overwrite_aliases*/
|
||||
),
|
||||
ImportBackup {
|
||||
network_dir: NetworkDirectory,
|
||||
wallet: Arc<Wallet>,
|
||||
overwrite_labels: Option<Sender<bool>>,
|
||||
overwrite_aliases: Option<Sender<bool>>,
|
||||
},
|
||||
WalletFromBackup,
|
||||
Descriptor(LianaDescriptor),
|
||||
ExportLabels,
|
||||
@ -187,7 +189,7 @@ impl ImportExportType {
|
||||
| ImportExportType::ExportProcessBackup(..)
|
||||
| ImportExportType::ExportXpub(_)
|
||||
| ImportExportType::ExportLabels => "Export successful!",
|
||||
ImportExportType::ImportBackup(_, _)
|
||||
ImportExportType::ImportBackup { .. }
|
||||
| ImportExportType::ImportPsbt(_)
|
||||
| ImportExportType::ImportXpub(_)
|
||||
| ImportExportType::WalletFromBackup
|
||||
@ -196,20 +198,6 @@ impl ImportExportType {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ImportExportType {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Self::ExportPsbt(l0), Self::ExportPsbt(r0)) => l0 == r0,
|
||||
(Self::ExportBackup(l0), Self::ExportBackup(r0)) => l0 == r0,
|
||||
(Self::ImportBackup(l0, l1), Self::ImportBackup(r0, r1)) => {
|
||||
l0.is_some() == r0.is_some() && l1.is_some() == r1.is_some()
|
||||
}
|
||||
(Self::Descriptor(l0), Self::Descriptor(r0)) => l0 == r0,
|
||||
_ => core::mem::discriminant(self) == core::mem::discriminant(other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<JoinError> for Error {
|
||||
fn from(value: JoinError) -> Self {
|
||||
Error::JoinError(format!("{:?}", value))
|
||||
@ -321,7 +309,11 @@ impl Export {
|
||||
)
|
||||
.await
|
||||
}
|
||||
ImportExportType::ImportBackup(..) => import_backup(&sender, path, daemon).await,
|
||||
ImportExportType::ImportBackup {
|
||||
network_dir,
|
||||
wallet,
|
||||
..
|
||||
} => import_backup(&network_dir, wallet, &sender, path, daemon).await,
|
||||
ImportExportType::WalletFromBackup => wallet_from_backup(&sender, path).await,
|
||||
} {
|
||||
if let Err(e) = sender.send(Progress::Error(e)) {
|
||||
@ -694,6 +686,8 @@ pub async fn import_xpub(
|
||||
/// - import labels if no conflict or user ACK
|
||||
/// - update aliases if no conflict or user ACK
|
||||
pub async fn import_backup(
|
||||
network_dir: &NetworkDirectory,
|
||||
wallet: Arc<Wallet>,
|
||||
sender: &UnboundedSender<Progress>,
|
||||
path: PathBuf,
|
||||
daemon: Option<Arc<dyn Daemon + Sync + Send>>,
|
||||
@ -810,32 +804,16 @@ pub async fn import_backup(
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let lianad_datadir = daemon
|
||||
.config()
|
||||
.and_then(|c| c.data_directory())
|
||||
.ok_or(Error::BackupImport("Failed to get Daemon config".into()))?;
|
||||
|
||||
let descriptor_checksum = descriptor
|
||||
.to_string()
|
||||
.split_once('#')
|
||||
.map(|(_, checksum)| checksum)
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
// check if key aliases can be imported w/o conflict
|
||||
let mut write_aliases = true;
|
||||
let settings = if !account.keys.is_empty() {
|
||||
// TODO: change lianad_datadir is common to gui datadir only for legacy wallet before
|
||||
// multiple wallet
|
||||
let network_dir = NetworkDirectory::new(lianad_datadir.path().to_path_buf());
|
||||
let wallet_settings = match WalletSettings::from_file(&network_dir, |w| {
|
||||
w.descriptor_checksum == descriptor_checksum
|
||||
}) {
|
||||
Ok(Some(s)) => s,
|
||||
_ => {
|
||||
return Err(Error::BackupImport("Failed to get App Settings".into()));
|
||||
}
|
||||
};
|
||||
let wallet_settings =
|
||||
match WalletSettings::from_file(network_dir, |w| w.wallet_id() == wallet.id()) {
|
||||
Ok(Some(s)) => s,
|
||||
_ => {
|
||||
return Err(Error::BackupImport("Failed to get App Settings".into()));
|
||||
}
|
||||
};
|
||||
|
||||
let settings_aliases: HashMap<_, _> = wallet_settings
|
||||
.keys
|
||||
@ -937,19 +915,16 @@ pub async fn import_backup(
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = update_settings_file(
|
||||
&NetworkDirectory::new(lianad_datadir.path().to_path_buf()),
|
||||
|mut settings| {
|
||||
if let Some(wallet) = settings
|
||||
.wallets
|
||||
.iter_mut()
|
||||
.find(|w| w.descriptor_checksum == descriptor_checksum)
|
||||
{
|
||||
wallet.keys = settings_aliases.clone().into_values().collect();
|
||||
}
|
||||
settings
|
||||
},
|
||||
)
|
||||
if let Err(e) = update_settings_file(network_dir, |mut settings| {
|
||||
if let Some(wallet) = settings
|
||||
.wallets
|
||||
.iter_mut()
|
||||
.find(|w| w.wallet_id() == wallet.id())
|
||||
{
|
||||
wallet.keys = settings_aliases.clone().into_values().collect();
|
||||
}
|
||||
settings
|
||||
})
|
||||
.await
|
||||
{
|
||||
return Err(Error::BackupImport(format!(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user