local_chain::{
self, ApplyHeaderError, CannotConnectError, CheckPoint, CheckPointIter, LocalChain,
},
+ persist::{PersistBackend, StageExt},
spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult},
tx_graph::{CanonicalTx, TxGraph},
Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeHeightAnchor, FullTxOut,
use bitcoin::{consensus::encode::serialize, transaction, BlockHash, Psbt};
use bitcoin::{constants::genesis_block, Amount};
use core::fmt;
-use core::mem;
use core::ops::Deref;
use descriptor::error::Error as DescriptorError;
use miniscript::psbt::{PsbtExt, PsbtInputExt, PsbtInputSatisfier};
})
}
- /// Stage a ['ChangeSet'] to be persisted later.
- ///
- /// [`commit`]: Self::commit
- fn stage(&mut self, changeset: ChangeSet) {
- self.stage.append(changeset)
- }
-
- /// Take the staged [`ChangeSet`] to be persisted now.
- pub fn take_staged(&mut self) -> ChangeSet {
- mem::take(&mut self.stage)
- }
-
/// Load [`Wallet`] from the given previously persisted [`ChangeSet`].
///
/// Note that the descriptor secret keys are not persisted to the db; this means that after
/// # let changeset = ChangeSet::default();
/// # let mut wallet = Wallet::load_from_changeset(changeset).expect("load wallet");
/// let next_address = wallet.reveal_next_address(KeychainKind::External);
- /// db.write_changes(&wallet.take_staged())?;
+ /// wallet.commit_to(&mut db)?;
///
/// // Now it's safe to show the user their next address!
/// println!("Next address: {}", next_address.address);
.reveal_to_target(&keychain, index)
.expect("keychain must exist");
- self.stage(indexed_tx_graph::ChangeSet::from(index_changeset).into());
+ self.stage.append(index_changeset.into());
spks.into_iter().map(move |(index, spk)| AddressInfo {
index,
/// [`list_output`]: Self::list_output
pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) {
let additions = self.indexed_graph.insert_txout(outpoint, txout);
- self.stage(ChangeSet::from(additions));
+ self.stage.append(additions.into());
}
/// Calculates the fee of a given transaction. Returns [`Amount::ZERO`] if `tx` is a coinbase transaction.
) -> Result<bool, local_chain::AlterCheckPointError> {
let changeset = self.chain.insert_block(block_id)?;
let changed = !changeset.is_empty();
- self.stage(changeset.into());
+ self.stage.append(changeset.into());
Ok(changed)
}
}
let changed = !changeset.is_empty();
- self.stage(changeset);
+ self.stage.append(changeset);
Ok(changed)
}
.next_unused_spk(&change_keychain)
.expect("keychain must exist");
self.indexed_graph.index.mark_used(change_keychain, index);
- self.stage(ChangeSet::from(indexed_tx_graph::ChangeSet::from(
- index_changeset,
- )));
+ self.stage.append(index_changeset.into());
spk
}
};
.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),
- ));
- self.stage(changeset);
+ changeset.append(index_changeset.into());
+ changeset.append(self.indexed_graph.apply_update(update.graph).into());
+ self.stage.append(changeset);
Ok(())
}
+ /// Commits all currently [`staged`](Wallet::staged) changes to the `persist_backend`.
+ ///
+ /// This returns whether anything was persisted.
+ ///
+ /// # Error
+ ///
+ /// Returns a backend-defined error if this fails.
+ pub fn commit_to<B>(&mut self, persist_backend: &mut B) -> Result<bool, B::WriteError>
+ where
+ B: PersistBackend<ChangeSet>,
+ {
+ let committed = StageExt::commit_to(&mut self.stage, persist_backend)?;
+ Ok(committed.is_some())
+ }
+
+ /// Commits all currently [`staged`](Wallet::staged) changes to the async `persist_backend`.
+ ///
+ /// This returns whether anything was persisted.
+ ///
+ /// # Error
+ ///
+ /// Returns a backend-defined error if this fails.
+ #[cfg(feature = "async")]
+ pub async fn commit_to_async<B>(
+ &mut self,
+ persist_backend: &mut B,
+ ) -> Result<bool, B::WriteError>
+ where
+ B: bdk_chain::persist::PersistBackendAsync<ChangeSet> + Send + Sync,
+ {
+ let committed =
+ bdk_chain::persist::StageExtAsync::commit_to(&mut self.stage, persist_backend).await?;
+ Ok(committed.is_some())
+ }
+
+ /// Get the staged [`ChangeSet`] that is yet to be committed.
+ pub fn staged(&self) -> &ChangeSet {
+ &self.stage
+ }
+
/// Get a reference to the inner [`TxGraph`].
pub fn tx_graph(&self) -> &TxGraph<ConfirmationTimeHeightAnchor> {
self.indexed_graph.graph()
.apply_block_relevant(block, height)
.into(),
);
- self.stage(changeset);
+ self.stage.append(changeset);
Ok(())
}
let indexed_graph_changeset = self
.indexed_graph
.batch_insert_relevant_unconfirmed(unconfirmed_txs);
- self.stage(ChangeSet::from(indexed_graph_changeset));
+ self.stage.append(indexed_graph_changeset.into());
}
}