fix(wallet): add expected descriptors as signers after creating from wallet::ChangeSet

This commit is contained in:
Steve Myers 2024-04-15 22:13:07 -05:00 committed by Daniela Brozzoni
parent 4f05441a00
commit 76afccc555
No known key found for this signature in database
GPG Key ID: 7DE4F1FDCED0AB87

View File

@ -54,6 +54,7 @@ pub mod tx_builder;
pub(crate) mod utils; pub(crate) mod utils;
pub mod error; pub mod error;
pub use utils::IsDust; pub use utils::IsDust;
use coin_selection::DefaultCoinSelectionAlgorithm; use coin_selection::DefaultCoinSelectionAlgorithm;
@ -606,7 +607,7 @@ impl Wallet {
.map_err(NewOrLoadError::Persist)?; .map_err(NewOrLoadError::Persist)?;
match changeset { match changeset {
Some(changeset) => { Some(changeset) => {
let wallet = Self::load_from_changeset(db, changeset).map_err(|e| match e { let mut wallet = Self::load_from_changeset(db, changeset).map_err(|e| match e {
LoadError::Descriptor(e) => NewOrLoadError::Descriptor(e), LoadError::Descriptor(e) => NewOrLoadError::Descriptor(e),
LoadError::Persist(e) => NewOrLoadError::Persist(e), LoadError::Persist(e) => NewOrLoadError::Persist(e),
LoadError::NotInitialized => NewOrLoadError::NotInitialized, LoadError::NotInitialized => NewOrLoadError::NotInitialized,
@ -636,35 +637,72 @@ impl Wallet {
}); });
} }
let expected_descriptor = descriptor let (expected_descriptor, expected_descriptor_keymap) = descriptor
.into_wallet_descriptor(&wallet.secp, network) .into_wallet_descriptor(&wallet.secp, network)
.map_err(NewOrLoadError::Descriptor)? .map_err(NewOrLoadError::Descriptor)?;
.0;
let wallet_descriptor = wallet.public_descriptor(KeychainKind::External).cloned(); let wallet_descriptor = wallet.public_descriptor(KeychainKind::External).cloned();
if wallet_descriptor != Some(expected_descriptor) { if wallet_descriptor != Some(expected_descriptor.clone()) {
return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch { return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch {
got: wallet_descriptor, got: wallet_descriptor,
keychain: KeychainKind::External, keychain: KeychainKind::External,
}); });
} }
// if expected descriptor has private keys add them as new signers
if !expected_descriptor_keymap.is_empty() {
let signer_container = SignersContainer::build(
expected_descriptor_keymap,
&expected_descriptor,
&wallet.secp,
);
signer_container.signers().into_iter().for_each(|signer| {
wallet.add_signer(
KeychainKind::External,
SignerOrdering::default(),
signer.clone(),
)
});
}
let expected_change_descriptor = if let Some(c) = change_descriptor { let expected_change_descriptor = if let Some(c) = change_descriptor {
Some( Some(
c.into_wallet_descriptor(&wallet.secp, network) c.into_wallet_descriptor(&wallet.secp, network)
.map_err(NewOrLoadError::Descriptor)? .map_err(NewOrLoadError::Descriptor)?,
.0,
) )
} else { } else {
None None
}; };
let wallet_change_descriptor = let wallet_change_descriptor =
wallet.public_descriptor(KeychainKind::Internal).cloned(); wallet.public_descriptor(KeychainKind::Internal).cloned();
if wallet_change_descriptor != expected_change_descriptor {
return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch { match (expected_change_descriptor, wallet_change_descriptor) {
got: wallet_change_descriptor, (Some((expected_descriptor, expected_keymap)), Some(wallet_descriptor))
keychain: KeychainKind::Internal, if wallet_descriptor == expected_descriptor =>
}); {
// if expected change descriptor has private keys add them as new signers
if !expected_keymap.is_empty() {
let signer_container = SignersContainer::build(
expected_keymap,
&expected_descriptor,
&wallet.secp,
);
signer_container.signers().into_iter().for_each(|signer| {
wallet.add_signer(
KeychainKind::Internal,
SignerOrdering::default(),
signer.clone(),
)
});
}
}
(None, None) => (),
(_, wallet_descriptor) => {
return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch {
got: wallet_descriptor,
keychain: KeychainKind::Internal,
});
}
} }
Ok(wallet) Ok(wallet)
} }
None => Self::new_with_genesis_hash( None => Self::new_with_genesis_hash(