Merge #751: GUI: prune BIP32 derivations for other spending paths when signing with BitBox02
99bbb76228de0762521cf9152fa35e267fca95b2 gui: prune bip32 derivations when signing with BitBox02 (Antoine Poinsot)
b8d6be82a7c9da80333d7470f6079d95e87210b8 gui: update to latest Liana (Antoine Poinsot)
Pull request description:
ACKs for top commit:
edouardparis:
ACK 99bbb76228de0762521cf9152fa35e267fca95b2
Tree-SHA512: 31476a0db1af0d3ce114c6709ec8e693bc9209475da532c541530ad6b96837a3eb4faf0e5061255c93c9adaab9b48503878966bf3a2aec4b7be34e729e2e1056
This commit is contained in:
commit
4de9772a93
2
gui/Cargo.lock
generated
2
gui/Cargo.lock
generated
@ -2415,7 +2415,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "liana"
|
name = "liana"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
source = "git+https://github.com/wizardsardine/liana?branch=master#42578609e2ed340d277d75c747c74449308acbb7"
|
source = "git+https://github.com/wizardsardine/liana?branch=master#87555a8da50702ebec04dbe876e7055432ca805a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bip39",
|
"bip39",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
|
||||||
use liana::config::ConfigError;
|
use liana::{config::ConfigError, descriptors::LianaDescError};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{settings::SettingsError, wallet::WalletError},
|
app::{settings::SettingsError, wallet::WalletError},
|
||||||
@ -15,6 +15,7 @@ pub enum Error {
|
|||||||
Daemon(DaemonError),
|
Daemon(DaemonError),
|
||||||
Unexpected(String),
|
Unexpected(String),
|
||||||
HardwareWallet(async_hwi::Error),
|
HardwareWallet(async_hwi::Error),
|
||||||
|
Desc(LianaDescError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
@ -48,6 +49,7 @@ impl std::fmt::Display for Error {
|
|||||||
},
|
},
|
||||||
Self::Unexpected(e) => write!(f, "Unexpected error: {}", e),
|
Self::Unexpected(e) => write!(f, "Unexpected error: {}", e),
|
||||||
Self::HardwareWallet(e) => write!(f, "{}", e),
|
Self::HardwareWallet(e) => write!(f, "{}", e),
|
||||||
|
Self::Desc(e) => write!(f, "Liana descriptor error: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -365,7 +365,7 @@ impl Action for SignAction {
|
|||||||
self.processing = true;
|
self.processing = true;
|
||||||
let psbt = tx.psbt.clone();
|
let psbt = tx.psbt.clone();
|
||||||
return Command::perform(
|
return Command::perform(
|
||||||
sign_psbt(device.clone(), *fingerprint, psbt),
|
sign_psbt(self.wallet.clone(), device.clone(), *fingerprint, psbt),
|
||||||
Message::Signed,
|
Message::Signed,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -449,11 +449,39 @@ async fn sign_psbt_with_hot_signer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn sign_psbt(
|
async fn sign_psbt(
|
||||||
|
wallet: Arc<Wallet>,
|
||||||
hw: std::sync::Arc<dyn async_hwi::HWI + Send + Sync>,
|
hw: std::sync::Arc<dyn async_hwi::HWI + Send + Sync>,
|
||||||
fingerprint: Fingerprint,
|
fingerprint: Fingerprint,
|
||||||
mut psbt: Psbt,
|
mut psbt: Psbt,
|
||||||
) -> Result<(Psbt, Fingerprint), Error> {
|
) -> Result<(Psbt, Fingerprint), Error> {
|
||||||
hw.sign_tx(&mut psbt).await.map_err(Error::from)?;
|
// The BitBox02 is only going to produce a signature for a single key in the Script. In order
|
||||||
|
// to make sure it doesn't sign for a public key from another spending path we remove the BIP32
|
||||||
|
// derivation for the other paths.
|
||||||
|
if matches!(hw.device_kind(), async_hwi::DeviceKind::BitBox02) {
|
||||||
|
// We need to make sure we don't prune the BIP32 derivations from the original PSBT (which
|
||||||
|
// would end up being updated in the daemon's database and erase the previously unpruned
|
||||||
|
// one). To this end we create a new, pruned, psbt we use for signing and then merge its
|
||||||
|
// signatures back into the original PSBT.
|
||||||
|
let mut pruned_psbt = wallet
|
||||||
|
.main_descriptor
|
||||||
|
.prune_bip32_derivs_last_avail(psbt.clone())
|
||||||
|
.map_err(Error::Desc)?;
|
||||||
|
hw.sign_tx(&mut pruned_psbt).await.map_err(Error::from)?;
|
||||||
|
for (i, psbt_in) in psbt.inputs.iter_mut().enumerate() {
|
||||||
|
if let Some(pruned_psbt_in) = pruned_psbt.inputs.get_mut(i) {
|
||||||
|
psbt_in
|
||||||
|
.partial_sigs
|
||||||
|
.append(&mut pruned_psbt_in.partial_sigs);
|
||||||
|
} else {
|
||||||
|
log::error!(
|
||||||
|
"Not all PSBT inputs are present in the pruned psbt. Pruned psbt: '{}'.",
|
||||||
|
&pruned_psbt
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hw.sign_tx(&mut psbt).await.map_err(Error::from)?;
|
||||||
|
}
|
||||||
Ok((psbt, fingerprint))
|
Ok((psbt, fingerprint))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,7 @@ impl From<&Error> for WarningMessage {
|
|||||||
},
|
},
|
||||||
Error::Unexpected(_) => WarningMessage("Unknown error".to_string()),
|
Error::Unexpected(_) => WarningMessage("Unknown error".to_string()),
|
||||||
Error::HardwareWallet(_) => WarningMessage("Hardware wallet error".to_string()),
|
Error::HardwareWallet(_) => WarningMessage("Hardware wallet error".to_string()),
|
||||||
|
Error::Desc(e) => WarningMessage(format!("Descriptor analysis error: '{}'.", e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user