Make bdk and bdk_chain work under 1.57.0

- rewrite some parts of the code to deal with older borrow checker
- downgraded hashbrown
This commit is contained in:
Steve Myers
2023-03-02 22:05:11 -06:00
committed by Daniela Brozzoni
parent 3a5d727899
commit 38ef170ed1
16 changed files with 85 additions and 195 deletions

View File

@@ -9,8 +9,8 @@ keywords = ["bitcoin", "wallet", "descriptor", "psbt"]
readme = "README.md"
license = "MIT OR Apache-2.0"
authors = ["Bitcoin Dev Kit Developers"]
edition = "2018"
edition = "2021"
rust-version = "1.57"
[dependencies]
log = "^0.4"

View File

@@ -22,7 +22,7 @@ use alloc::{
pub use bdk_chain::keychain::Balance;
use bdk_chain::{
chain_graph,
keychain::{KeychainChangeSet, KeychainScan, KeychainTracker},
keychain::{persist, KeychainChangeSet, KeychainScan, KeychainTracker},
sparse_chain, BlockId, ConfirmationTime, IntoOwned,
};
use bitcoin::consensus::encode::serialize;
@@ -48,7 +48,6 @@ pub(crate) mod utils;
#[cfg(feature = "hardware-signer")]
#[cfg_attr(docsrs, doc(cfg(feature = "hardware-signer")))]
pub mod hardwaresigner;
pub mod persist;
pub use utils::IsDust;
@@ -85,7 +84,7 @@ pub struct Wallet<D = ()> {
signers: Arc<SignersContainer>,
change_signers: Arc<SignersContainer>,
keychain_tracker: KeychainTracker<KeychainKind, ConfirmationTime>,
persist: persist::Persist<D>,
persist: persist::Persist<KeychainKind, ConfirmationTime, D>,
network: Network,
secp: SecpCtx,
}
@@ -196,7 +195,7 @@ impl<D> Wallet<D> {
network: Network,
) -> Result<Self, NewError<D::LoadError>>
where
D: persist::Backend,
D: persist::PersistBackend<KeychainKind, ConfirmationTime>,
{
let secp = Secp256k1::new();
@@ -258,7 +257,7 @@ impl<D> Wallet<D> {
/// (i.e. does not end with /*) then the same address will always be returned for any [`AddressIndex`].
pub fn get_address(&mut self, address_index: AddressIndex) -> AddressInfo
where
D: persist::Backend,
D: persist::PersistBackend<KeychainKind, ConfirmationTime>,
{
self._get_address(address_index, KeychainKind::External)
}
@@ -272,14 +271,14 @@ impl<D> Wallet<D> {
/// be returned for any [`AddressIndex`].
pub fn get_internal_address(&mut self, address_index: AddressIndex) -> AddressInfo
where
D: persist::Backend,
D: persist::PersistBackend<KeychainKind, ConfirmationTime>,
{
self._get_address(address_index, KeychainKind::Internal)
}
fn _get_address(&mut self, address_index: AddressIndex, keychain: KeychainKind) -> AddressInfo
where
D: persist::Backend,
D: persist::PersistBackend<KeychainKind, ConfirmationTime>,
{
let keychain = self.map_keychain(keychain);
let txout_index = &mut self.keychain_tracker.txout_index;
@@ -614,7 +613,7 @@ impl<D> Wallet<D> {
params: TxParams,
) -> Result<(psbt::PartiallySignedTransaction, TransactionDetails), Error>
where
D: persist::Backend,
D: persist::PersistBackend<KeychainKind, ConfirmationTime>,
{
let external_descriptor = self
.keychain_tracker
@@ -1689,7 +1688,7 @@ impl<D> Wallet<D> {
/// [`commit`]: Self::commit
pub fn apply_update<Tx>(&mut self, update: Update<Tx>) -> Result<(), UpdateError>
where
D: persist::Backend,
D: persist::PersistBackend<KeychainKind, ConfirmationTime>,
Tx: IntoOwned<Transaction> + Clone,
{
let changeset = self.keychain_tracker.apply_update(update)?;
@@ -1702,7 +1701,7 @@ impl<D> Wallet<D> {
/// [`staged`]: Self::staged
pub fn commit(&mut self) -> Result<(), D::WriteError>
where
D: persist::Backend,
D: persist::PersistBackend<KeychainKind, ConfirmationTime>,
{
self.persist.commit()
}

View File

@@ -1,124 +0,0 @@
//! Persistence for changes made to a [`Wallet`].
//!
//! BDK's [`Wallet`] needs somewhere to persist changes it makes during operation.
//! Operations like giving out a new address are crucial to persist so that next time the
//! application is loaded it can find transactions related to that address.
//!
//! Note that `Wallet` does not read this persisted data during operation since it always has a copy
//! in memory
//!
//! [`Wallet`]: crate::Wallet
use crate::KeychainKind;
use bdk_chain::{keychain::KeychainTracker, ConfirmationTime};
/// `Persist` wraps a [`Backend`] to create a convienient staging area for changes before they are
/// persisted. Not all changes made to the [`Wallet`] need to be written to disk right away so you
/// can use [`Persist::stage`] to *stage* it first and then [`Persist::commit`] to finally write it
/// to disk.
///
/// [`Wallet`]: crate::Wallet
#[derive(Debug)]
pub struct Persist<P> {
backend: P,
stage: ChangeSet,
}
impl<P> Persist<P> {
/// Create a new `Persist` from a [`Backend`]
pub fn new(backend: P) -> Self {
Self {
backend,
stage: Default::default(),
}
}
/// Stage a `changeset` to later persistence with [`commit`].
///
/// [`commit`]: Self::commit
pub fn stage(&mut self, changeset: ChangeSet) {
self.stage.append(changeset)
}
/// Get the changes that haven't been commited yet
pub fn staged(&self) -> &ChangeSet {
&self.stage
}
/// Commit the staged changes to the underlying persistence backend.
///
/// Retuns a backend defined error if this fails
pub fn commit(&mut self) -> Result<(), P::WriteError>
where
P: Backend,
{
self.backend.append_changeset(&self.stage)?;
self.stage = Default::default();
Ok(())
}
}
/// A persistence backend for [`Wallet`]
///
/// [`Wallet`]: crate::Wallet
pub trait Backend {
/// The error the backend returns when it fails to write
type WriteError: core::fmt::Debug;
/// The error the backend returns when it fails to load
type LoadError: core::fmt::Debug;
/// Appends a new changeset to the persistance backend.
///
/// It is up to the backend what it does with this. It could store every changeset in a list or
/// it insert the actual changes to a more structured database. All it needs to guarantee is
/// that [`load_into_keychain_tracker`] restores a keychain tracker to what it should be if all
/// changesets had been applied sequentially.
///
/// [`load_into_keychain_tracker`]: Self::load_into_keychain_tracker
fn append_changeset(&mut self, changeset: &ChangeSet) -> Result<(), Self::WriteError>;
/// Applies all the changesets the backend has received to `tracker`.
fn load_into_keychain_tracker(
&mut self,
tracker: &mut KeychainTracker<KeychainKind, ConfirmationTime>,
) -> Result<(), Self::LoadError>;
}
#[cfg(feature = "file-store")]
mod file_store {
use super::*;
use bdk_chain::file_store::{IterError, KeychainStore};
type FileStore = KeychainStore<KeychainKind, ConfirmationTime>;
impl Backend for FileStore {
type WriteError = std::io::Error;
type LoadError = IterError;
fn append_changeset(&mut self, changeset: &ChangeSet) -> Result<(), Self::WriteError> {
self.append_changeset(changeset)
}
fn load_into_keychain_tracker(
&mut self,
tracker: &mut KeychainTracker<KeychainKind, ConfirmationTime>,
) -> Result<(), Self::LoadError> {
self.load_into_keychain_tracker(tracker)
}
}
}
impl Backend for () {
type WriteError = ();
type LoadError = ();
fn append_changeset(&mut self, _changeset: &ChangeSet) -> Result<(), Self::WriteError> {
Ok(())
}
fn load_into_keychain_tracker(
&mut self,
_tracker: &mut KeychainTracker<KeychainKind, ConfirmationTime>,
) -> Result<(), Self::LoadError> {
Ok(())
}
}
#[cfg(feature = "file-store")]
pub use file_store::*;
use super::ChangeSet;

View File

@@ -39,6 +39,7 @@
use crate::collections::BTreeMap;
use crate::collections::HashSet;
use alloc::{boxed::Box, rc::Rc, string::String, vec::Vec};
use bdk_chain::ConfirmationTime;
use core::cell::RefCell;
use core::marker::PhantomData;
@@ -525,7 +526,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
/// [`BIP174`]: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
pub fn finish(self) -> Result<(Psbt, TransactionDetails), Error>
where
D: persist::Backend,
D: persist::PersistBackend<KeychainKind, ConfirmationTime>,
{
self.wallet
.borrow_mut()