From: 志宇 Date: Fri, 23 Aug 2024 18:26:28 +0000 (+0000) Subject: feat(electrum)!: depend on `bdk_core` instead of `bdk_chain` X-Git-Tag: v1.0.0-beta.2~2^2~3 X-Git-Url: http://internal-gitweb-vhost/script/%22https:/database/scripts/de/trait.Error.html?a=commitdiff_plain;h=0d302f5f204eeac8902a4b5943b9b820c6b575ab;p=bdk feat(electrum)!: depend on `bdk_core` instead of `bdk_chain` `.populate_tx_cache` has been changed to take in a collection of `Arc`. --- diff --git a/crates/electrum/Cargo.toml b/crates/electrum/Cargo.toml index eff11daa..b91c1366 100644 --- a/crates/electrum/Cargo.toml +++ b/crates/electrum/Cargo.toml @@ -10,11 +10,12 @@ license = "MIT OR Apache-2.0" readme = "README.md" [dependencies] -bdk_chain = { path = "../chain", version = "0.17.0" } +bdk_core = { path = "../core", version = "0.1" } electrum-client = { version = "0.21", features = ["proxy"], default-features = false } [dev-dependencies] bdk_testenv = { path = "../testenv", default-features = false } +bdk_chain = { path = "../chain", version = "0.17.0" } [features] default = ["use-rustls"] diff --git a/crates/electrum/src/bdk_electrum_client.rs b/crates/electrum/src/bdk_electrum_client.rs index 57166075..d78d7f64 100644 --- a/crates/electrum/src/bdk_electrum_client.rs +++ b/crates/electrum/src/bdk_electrum_client.rs @@ -1,10 +1,8 @@ -use bdk_chain::{ +use bdk_core::{ bitcoin::{block::Header, BlockHash, OutPoint, ScriptBuf, Transaction, Txid}, collections::{BTreeMap, HashMap}, - local_chain::CheckPoint, spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult}, - tx_graph::{self, TxGraph}, - Anchor, BlockId, ConfirmationBlockTime, + tx_graph, BlockId, CheckPoint, ConfirmationBlockTime, }; use electrum_client::{ElectrumApi, Error, HeaderNotification}; use std::{ @@ -39,14 +37,11 @@ impl BdkElectrumClient { /// Inserts transactions into the transaction cache so that the client will not fetch these /// transactions. - pub fn populate_tx_cache(&self, tx_graph: impl AsRef>) { - let txs = tx_graph - .as_ref() - .full_txs() - .map(|tx_node| (tx_node.txid, tx_node.tx)); - + pub fn populate_tx_cache(&self, txs: impl IntoIterator>>) { let mut tx_cache = self.tx_cache.lock().unwrap(); - for (txid, tx) in txs { + for tx in txs { + let tx = tx.into(); + let txid = tx.compute_txid(); tx_cache.insert(txid, tx); } } @@ -121,9 +116,10 @@ impl BdkElectrumClient { /// [`CalculateFeeError::MissingTxOut`] error if those `TxOut`s are not /// present in the transaction graph. /// - /// [`CalculateFeeError::MissingTxOut`]: bdk_chain::tx_graph::CalculateFeeError::MissingTxOut - /// [`Wallet.calculate_fee`]: https://docs.rs/bdk_wallet/latest/bdk_wallet/struct.Wallet.html#method.calculate_fee - /// [`Wallet.calculate_fee_rate`]: https://docs.rs/bdk_wallet/latest/bdk_wallet/struct.Wallet.html#method.calculate_fee_rate + /// [`bdk_chain`]: ../bdk_chain/index.html + /// [`CalculateFeeError::MissingTxOut`]: ../bdk_chain/tx_graph/enum.CalculateFeeError.html#variant.MissingTxOut + /// [`Wallet.calculate_fee`]: ../bdk_wallet/struct.Wallet.html#method.calculate_fee + /// [`Wallet.calculate_fee_rate`]: ../bdk_wallet/struct.Wallet.html#method.calculate_fee_rate pub fn full_scan( &self, request: impl Into>, @@ -189,9 +185,10 @@ impl BdkElectrumClient { /// may include scripts that have been used, use [`full_scan`] with the keychain. /// /// [`full_scan`]: Self::full_scan - /// [`CalculateFeeError::MissingTxOut`]: bdk_chain::tx_graph::CalculateFeeError::MissingTxOut - /// [`Wallet.calculate_fee`]: https://docs.rs/bdk_wallet/latest/bdk_wallet/struct.Wallet.html#method.calculate_fee - /// [`Wallet.calculate_fee_rate`]: https://docs.rs/bdk_wallet/latest/bdk_wallet/struct.Wallet.html#method.calculate_fee_rate + /// [`bdk_chain`]: ../bdk_chain/index.html + /// [`CalculateFeeError::MissingTxOut`]: ../bdk_chain/tx_graph/enum.CalculateFeeError.html#variant.MissingTxOut + /// [`Wallet.calculate_fee`]: ../bdk_wallet/struct.Wallet.html#method.calculate_fee + /// [`Wallet.calculate_fee_rate`]: ../bdk_wallet/struct.Wallet.html#method.calculate_fee_rate pub fn sync( &self, request: impl Into>, @@ -514,20 +511,20 @@ fn fetch_tip_and_latest_blocks( // Add a corresponding checkpoint per anchor height if it does not yet exist. Checkpoints should not // surpass `latest_blocks`. -fn chain_update( +fn chain_update( mut tip: CheckPoint, latest_blocks: &BTreeMap, - anchors: impl Iterator, + anchors: impl Iterator, ) -> Result { - for anchor in anchors { - let height = anchor.0.anchor_block().height; + for (anchor, _txid) in anchors { + let height = anchor.block_id.height; // Checkpoint uses the `BlockHash` from `latest_blocks` so that the hash will be consistent // in case of a re-org. if tip.get(height).is_none() && height <= tip.height() { let hash = match latest_blocks.get(&height) { Some(&hash) => hash, - None => anchor.0.anchor_block().hash, + None => anchor.block_id.hash, }; tip = tip.insert(BlockId { hash, height }); } diff --git a/crates/electrum/src/lib.rs b/crates/electrum/src/lib.rs index d303ee40..914b4f19 100644 --- a/crates/electrum/src/lib.rs +++ b/crates/electrum/src/lib.rs @@ -1,22 +1,26 @@ -//! This crate is used for updating structures of [`bdk_chain`] with data from an Electrum server. +//! This crate is used for returning updates from Electrum servers. //! -//! The two primary methods are [`BdkElectrumClient::sync`] and [`BdkElectrumClient::full_scan`]. In most cases -//! [`BdkElectrumClient::sync`] is used to sync the transaction histories of scripts that the application -//! cares about, for example the scripts for all the receive addresses of a Wallet's keychain that it -//! has shown a user. [`BdkElectrumClient::full_scan`] is meant to be used when importing or restoring a -//! keychain where the range of possibly used scripts is not known. In this case it is necessary to -//! scan all keychain scripts until a number (the "stop gap") of unused scripts is discovered. For a -//! sync or full scan the user receives relevant blockchain data and output updates for -//! [`bdk_chain`]. +//! Updates are returned as either a [`SyncResult`] (if [`BdkElectrumClient::sync()`] is called), +//! or a [`FullScanResult`] (if [`BdkElectrumClient::full_scan()`] is called). +//! +//! In most cases [`BdkElectrumClient::sync()`] is used to sync the transaction histories of scripts +//! that the application cares about, for example the scripts for all the receive addresses of a +//! Wallet's keychain that it has shown a user. +//! +//! [`BdkElectrumClient::full_scan`] is meant to be used when importing or restoring a keychain +//! where the range of possibly used scripts is not known. In this case it is necessary to scan all +//! keychain scripts until a number (the "stop gap") of unused scripts is discovered. //! //! Refer to [`example_electrum`] for a complete example. //! //! [`example_electrum`]: https://github.com/bitcoindevkit/bdk/tree/master/example-crates/example_electrum +//! [`SyncResult`]: bdk_core::spk_client::SyncResult +//! [`FullScanResult`]: bdk_core::spk_client::FullScanResult #![warn(missing_docs)] mod bdk_electrum_client; pub use bdk_electrum_client::*; -pub use bdk_chain; +pub use bdk_core; pub use electrum_client; diff --git a/example-crates/example_electrum/src/main.rs b/example-crates/example_electrum/src/main.rs index 662bc423..21910cf6 100644 --- a/example-crates/example_electrum/src/main.rs +++ b/example-crates/example_electrum/src/main.rs @@ -127,7 +127,14 @@ fn main() -> anyhow::Result<()> { let client = BdkElectrumClient::new(electrum_cmd.electrum_args().client(network)?); // Tell the electrum client about the txs we've already got locally so it doesn't re-download them - client.populate_tx_cache(&*graph.lock().unwrap()); + client.populate_tx_cache( + graph + .lock() + .unwrap() + .graph() + .full_txs() + .map(|tx_node| tx_node.tx), + ); let (chain_update, graph_update, keychain_update) = match electrum_cmd.clone() { ElectrumCommands::Scan { diff --git a/example-crates/wallet_electrum/src/main.rs b/example-crates/wallet_electrum/src/main.rs index c0518405..47cbfa15 100644 --- a/example-crates/wallet_electrum/src/main.rs +++ b/example-crates/wallet_electrum/src/main.rs @@ -50,7 +50,7 @@ fn main() -> Result<(), anyhow::Error> { // Populate the electrum client's transaction cache so it doesn't redownload transaction we // already have. - client.populate_tx_cache(wallet.tx_graph()); + client.populate_tx_cache(wallet.tx_graph().full_txs().map(|tx_node| tx_node.tx)); let request = wallet.start_full_scan().inspect({ let mut stdout = std::io::stdout();