Skip to content

Commit

Permalink
feat!: change KeychainTxOutIndex methods to always return changesets
Browse files Browse the repository at this point in the history
Change the out signature of methods `reveal_to_target`,
`reveal_next_spk` and `next_unused_spk` to return a tuple of
`(Option<spk(s)>, changeset)` instead of `Option<(spk(s), changeset)>`.
This makes the API more consistent.

Also refactored various helper methods to take in a descriptor instead
of a descriptor id. `.expect` calls now exist outside of these helper
methods, making it more obvious where they are being called.

Docs are updated to reflect the new API.
  • Loading branch information
evanlinjin committed May 15, 2024
1 parent 47ea015 commit 86f3028
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 210 deletions.
80 changes: 36 additions & 44 deletions crates/bdk/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ impl Append for ChangeSet {
}
}

impl From<keychain::ChangeSet<KeychainKind>> for ChangeSet {
fn from(keychain_changeset: keychain::ChangeSet<KeychainKind>) -> Self {
Self {
indexed_tx_graph: keychain_changeset.into(),
..Default::default()
}
}
}

impl From<local_chain::ChangeSet> for ChangeSet {
fn from(chain: local_chain::ChangeSet) -> Self {
Self {
Expand Down Expand Up @@ -813,18 +822,14 @@ impl Wallet {
/// If writing to persistent storage fails.
pub fn reveal_next_address(&mut self, keychain: KeychainKind) -> anyhow::Result<AddressInfo> {
let keychain = self.map_keychain(keychain);
let ((index, spk), index_changeset) = self
.indexed_graph
.index
.reveal_next_spk(&keychain)
.expect("Must exist (we called map_keychain)");

let (next_spk, index_changeset) = self.indexed_graph.index.reveal_next_spk(&keychain);
let (index, spk) = next_spk.expect("Must exist (we called map_keychain)");
self.persist
.stage_and_commit(indexed_tx_graph::ChangeSet::from(index_changeset).into())?;

Ok(AddressInfo {
index,
address: Address::from_script(spk, self.network).expect("must have address form"),
address: Address::from_script(&spk, self.network).expect("must have address form"),
keychain,
})
}
Expand All @@ -845,11 +850,9 @@ impl Wallet {
index: u32,
) -> anyhow::Result<impl Iterator<Item = AddressInfo> + '_> {
let keychain = self.map_keychain(keychain);
let (spk_iter, index_changeset) = self
.indexed_graph
.index
.reveal_to_target(&keychain, index)
.expect("must exist (we called map_keychain)");
let (spk_iter, index_changeset) =
self.indexed_graph.index.reveal_to_target(&keychain, index);
let spk_iter = spk_iter.expect("Must exist (we called map_keychain)");

self.persist
.stage_and_commit(indexed_tx_graph::ChangeSet::from(index_changeset).into())?;
Expand All @@ -872,18 +875,15 @@ impl Wallet {
/// If writing to persistent storage fails.
pub fn next_unused_address(&mut self, keychain: KeychainKind) -> anyhow::Result<AddressInfo> {
let keychain = self.map_keychain(keychain);
let ((index, spk), index_changeset) = self
.indexed_graph
.index
.next_unused_spk(&keychain)
.expect("must exist (we called map_keychain)");
let (next_spk, index_changeset) = self.indexed_graph.index.next_unused_spk(&keychain);
let (index, spk) = next_spk.expect("Must exist (we called map_keychain)");

self.persist
.stage_and_commit(indexed_tx_graph::ChangeSet::from(index_changeset).into())?;

Ok(AddressInfo {
index,
address: Address::from_script(spk, self.network).expect("must have address form"),
address: Address::from_script(&spk, self.network).expect("must have address form"),
keychain,
})
}
Expand Down Expand Up @@ -1038,7 +1038,7 @@ impl Wallet {
/// [`commit`]: Self::commit
pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) {
let additions = self.indexed_graph.insert_txout(outpoint, txout);
self.persist.stage(ChangeSet::from(additions));
self.persist.stage(additions.into());
}

/// Calculates the fee of a given transaction. Returns 0 if `tx` is a coinbase transaction.
Expand Down Expand Up @@ -1607,17 +1607,11 @@ impl Wallet {
Some(ref drain_recipient) => drain_recipient.clone(),
None => {
let change_keychain = self.map_keychain(KeychainKind::Internal);
let ((index, spk), index_changeset) = self
.indexed_graph
.index
.next_unused_spk(&change_keychain)
.expect("Keychain exists (we called map_keychain)");
let spk = spk.into();
let (next_spk, index_changeset) =
self.indexed_graph.index.next_unused_spk(&change_keychain);
let (index, spk) = next_spk.expect("Keychain exists (we called map_keychain)");
self.indexed_graph.index.mark_used(change_keychain, index);
self.persist
.stage(ChangeSet::from(indexed_tx_graph::ChangeSet::from(
index_changeset,
)));
self.persist.stage(index_changeset.into());
self.persist.commit().map_err(CreateTxError::Persist)?;
spk
}
Expand Down Expand Up @@ -2432,21 +2426,19 @@ impl Wallet {
/// [`commit`]: Self::commit
pub fn apply_update(&mut self, update: impl Into<Update>) -> Result<(), CannotConnectError> {
let update = update.into();
let mut changeset = match update.chain {
Some(chain_update) => ChangeSet::from(self.chain.apply_update(chain_update)?),
None => ChangeSet::default(),
};
let mut changeset = ChangeSet::default();

let (_, index_changeset) = self
.indexed_graph
.index
.reveal_to_target_multi(&update.last_active_indices);
changeset.append(ChangeSet::from(indexed_tx_graph::ChangeSet::from(
index_changeset,
)));
changeset.append(ChangeSet::from(
self.indexed_graph.apply_update(update.graph),
));
if let Some(chain_update) = update.chain {
changeset.append(self.chain.apply_update(chain_update)?.into());
}
changeset.append({
let (_, index_changeset) = self
.indexed_graph
.index
.reveal_to_target_multi(&update.last_active_indices);
index_changeset.into()
});
changeset.append(self.indexed_graph.apply_update(update.graph).into());
self.persist.stage(changeset);
Ok(())
}
Expand Down Expand Up @@ -2552,7 +2544,7 @@ impl Wallet {
let indexed_graph_changeset = self
.indexed_graph
.batch_insert_relevant_unconfirmed(unconfirmed_txs);
self.persist.stage(ChangeSet::from(indexed_graph_changeset));
self.persist.stage(indexed_graph_changeset.into());
}
}

Expand Down
Loading

0 comments on commit 86f3028

Please sign in to comment.