Skip to content

Commit 76afccc

Browse files
notmandatorydanielabrozzoni
authored andcommitted
fix(wallet): add expected descriptors as signers after creating from wallet::ChangeSet
1 parent 4f05441 commit 76afccc

File tree

1 file changed

+50
-12
lines changed

1 file changed

+50
-12
lines changed

crates/bdk/src/wallet/mod.rs

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ pub mod tx_builder;
5454
pub(crate) mod utils;
5555

5656
pub mod error;
57+
5758
pub use utils::IsDust;
5859

5960
use coin_selection::DefaultCoinSelectionAlgorithm;
@@ -606,7 +607,7 @@ impl Wallet {
606607
.map_err(NewOrLoadError::Persist)?;
607608
match changeset {
608609
Some(changeset) => {
609-
let wallet = Self::load_from_changeset(db, changeset).map_err(|e| match e {
610+
let mut wallet = Self::load_from_changeset(db, changeset).map_err(|e| match e {
610611
LoadError::Descriptor(e) => NewOrLoadError::Descriptor(e),
611612
LoadError::Persist(e) => NewOrLoadError::Persist(e),
612613
LoadError::NotInitialized => NewOrLoadError::NotInitialized,
@@ -636,35 +637,72 @@ impl Wallet {
636637
});
637638
}
638639

639-
let expected_descriptor = descriptor
640+
let (expected_descriptor, expected_descriptor_keymap) = descriptor
640641
.into_wallet_descriptor(&wallet.secp, network)
641-
.map_err(NewOrLoadError::Descriptor)?
642-
.0;
642+
.map_err(NewOrLoadError::Descriptor)?;
643643
let wallet_descriptor = wallet.public_descriptor(KeychainKind::External).cloned();
644-
if wallet_descriptor != Some(expected_descriptor) {
644+
if wallet_descriptor != Some(expected_descriptor.clone()) {
645645
return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch {
646646
got: wallet_descriptor,
647647
keychain: KeychainKind::External,
648648
});
649649
}
650+
// if expected descriptor has private keys add them as new signers
651+
if !expected_descriptor_keymap.is_empty() {
652+
let signer_container = SignersContainer::build(
653+
expected_descriptor_keymap,
654+
&expected_descriptor,
655+
&wallet.secp,
656+
);
657+
signer_container.signers().into_iter().for_each(|signer| {
658+
wallet.add_signer(
659+
KeychainKind::External,
660+
SignerOrdering::default(),
661+
signer.clone(),
662+
)
663+
});
664+
}
650665

651666
let expected_change_descriptor = if let Some(c) = change_descriptor {
652667
Some(
653668
c.into_wallet_descriptor(&wallet.secp, network)
654-
.map_err(NewOrLoadError::Descriptor)?
655-
.0,
669+
.map_err(NewOrLoadError::Descriptor)?,
656670
)
657671
} else {
658672
None
659673
};
660674
let wallet_change_descriptor =
661675
wallet.public_descriptor(KeychainKind::Internal).cloned();
662-
if wallet_change_descriptor != expected_change_descriptor {
663-
return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch {
664-
got: wallet_change_descriptor,
665-
keychain: KeychainKind::Internal,
666-
});
676+
677+
match (expected_change_descriptor, wallet_change_descriptor) {
678+
(Some((expected_descriptor, expected_keymap)), Some(wallet_descriptor))
679+
if wallet_descriptor == expected_descriptor =>
680+
{
681+
// if expected change descriptor has private keys add them as new signers
682+
if !expected_keymap.is_empty() {
683+
let signer_container = SignersContainer::build(
684+
expected_keymap,
685+
&expected_descriptor,
686+
&wallet.secp,
687+
);
688+
signer_container.signers().into_iter().for_each(|signer| {
689+
wallet.add_signer(
690+
KeychainKind::Internal,
691+
SignerOrdering::default(),
692+
signer.clone(),
693+
)
694+
});
695+
}
696+
}
697+
(None, None) => (),
698+
(_, wallet_descriptor) => {
699+
return Err(NewOrLoadError::LoadedDescriptorDoesNotMatch {
700+
got: wallet_descriptor,
701+
keychain: KeychainKind::Internal,
702+
});
703+
}
667704
}
705+
668706
Ok(wallet)
669707
}
670708
None => Self::new_with_genesis_hash(

0 commit comments

Comments
 (0)