]> Untitled Git - bdk/commitdiff
feat(chain)!: Implement `ConfirmationBlockTime`
authorWei Chen <wzc110@gmail.com>
Mon, 1 Jul 2024 05:40:26 +0000 (13:40 +0800)
committerWei Chen <wzc110@gmail.com>
Mon, 8 Jul 2024 16:23:02 +0000 (00:23 +0800)
Both `bdk_electrum` and `bdk_esplora` now report the exact block
that the transaction is in, which removes the need for having the
old `ConfirmationTimeHeightAnchor` and `ConfirmationHeightAnchor`.
This PR introduces a new, simpler anchor type that can be modified
to support additional data in the future.

17 files changed:
crates/chain/src/chain_data.rs
crates/chain/src/spk_client.rs
crates/chain/src/tx_data_traits.rs
crates/chain/tests/test_indexed_tx_graph.rs
crates/chain/tests/test_tx_graph.rs
crates/electrum/src/bdk_electrum_client.rs
crates/electrum/tests/test_electrum.rs
crates/esplora/src/async_ext.rs
crates/esplora/src/blocking_ext.rs
crates/esplora/src/lib.rs
crates/sqlite/src/store.rs
crates/wallet/src/wallet/export.rs
crates/wallet/src/wallet/mod.rs
crates/wallet/tests/common.rs
example-crates/example_bitcoind_rpc_polling/src/main.rs
example-crates/example_electrum/src/main.rs
example-crates/example_esplora/src/main.rs

index ae0976de579675c1fe6dc9f1df49559502782b51..92ccdb65e6c94772c181fea9d81343cdd0b85e87 100644 (file)
@@ -74,11 +74,11 @@ impl ConfirmationTime {
     }
 }
 
-impl From<ChainPosition<ConfirmationTimeHeightAnchor>> for ConfirmationTime {
-    fn from(observed_as: ChainPosition<ConfirmationTimeHeightAnchor>) -> Self {
+impl From<ChainPosition<ConfirmationBlockTime>> for ConfirmationTime {
+    fn from(observed_as: ChainPosition<ConfirmationBlockTime>) -> Self {
         match observed_as {
             ChainPosition::Confirmed(a) => Self::Confirmed {
-                height: a.confirmation_height,
+                height: a.block_id.height,
                 time: a.confirmation_time,
             },
             ChainPosition::Unconfirmed(last_seen) => Self::Unconfirmed { last_seen },
@@ -145,9 +145,7 @@ impl From<(&u32, &BlockHash)> for BlockId {
     }
 }
 
-/// An [`Anchor`] implementation that also records the exact confirmation height of the transaction.
-///
-/// Note that the confirmation block and the anchor block can be different here.
+/// An [`Anchor`] implementation that also records the exact confirmation time of the transaction.
 ///
 /// Refer to [`Anchor`] for more details.
 #[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
@@ -156,70 +154,27 @@ impl From<(&u32, &BlockHash)> for BlockId {
     derive(serde::Deserialize, serde::Serialize),
     serde(crate = "serde_crate")
 )]
-pub struct ConfirmationHeightAnchor {
-    /// The exact confirmation height of the transaction.
-    ///
-    /// It is assumed that this value is never larger than the height of the anchor block.
-    pub confirmation_height: u32,
+pub struct ConfirmationBlockTime {
     /// The anchor block.
-    pub anchor_block: BlockId,
-}
-
-impl Anchor for ConfirmationHeightAnchor {
-    fn anchor_block(&self) -> BlockId {
-        self.anchor_block
-    }
-
-    fn confirmation_height_upper_bound(&self) -> u32 {
-        self.confirmation_height
-    }
-}
-
-impl AnchorFromBlockPosition for ConfirmationHeightAnchor {
-    fn from_block_position(_block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
-        Self {
-            anchor_block: block_id,
-            confirmation_height: block_id.height,
-        }
-    }
-}
-
-/// An [`Anchor`] implementation that also records the exact confirmation time and height of the
-/// transaction.
-///
-/// Note that the confirmation block and the anchor block can be different here.
-///
-/// Refer to [`Anchor`] for more details.
-#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, core::hash::Hash)]
-#[cfg_attr(
-    feature = "serde",
-    derive(serde::Deserialize, serde::Serialize),
-    serde(crate = "serde_crate")
-)]
-pub struct ConfirmationTimeHeightAnchor {
-    /// The confirmation height of the transaction being anchored.
-    pub confirmation_height: u32,
+    pub block_id: BlockId,
     /// The confirmation time of the transaction being anchored.
     pub confirmation_time: u64,
-    /// The anchor block.
-    pub anchor_block: BlockId,
 }
 
-impl Anchor for ConfirmationTimeHeightAnchor {
+impl Anchor for ConfirmationBlockTime {
     fn anchor_block(&self) -> BlockId {
-        self.anchor_block
+        self.block_id
     }
 
     fn confirmation_height_upper_bound(&self) -> u32 {
-        self.confirmation_height
+        self.block_id.height
     }
 }
 
-impl AnchorFromBlockPosition for ConfirmationTimeHeightAnchor {
+impl AnchorFromBlockPosition for ConfirmationBlockTime {
     fn from_block_position(block: &bitcoin::Block, block_id: BlockId, _tx_pos: usize) -> Self {
         Self {
-            anchor_block: block_id,
-            confirmation_height: block_id.height,
+            block_id,
             confirmation_time: block.header.time as _,
         }
     }
@@ -305,19 +260,19 @@ mod test {
 
     #[test]
     fn chain_position_ord() {
-        let unconf1 = ChainPosition::<ConfirmationHeightAnchor>::Unconfirmed(10);
-        let unconf2 = ChainPosition::<ConfirmationHeightAnchor>::Unconfirmed(20);
-        let conf1 = ChainPosition::Confirmed(ConfirmationHeightAnchor {
-            confirmation_height: 9,
-            anchor_block: BlockId {
-                height: 20,
+        let unconf1 = ChainPosition::<ConfirmationBlockTime>::Unconfirmed(10);
+        let unconf2 = ChainPosition::<ConfirmationBlockTime>::Unconfirmed(20);
+        let conf1 = ChainPosition::Confirmed(ConfirmationBlockTime {
+            confirmation_time: 20,
+            block_id: BlockId {
+                height: 9,
                 ..Default::default()
             },
         });
-        let conf2 = ChainPosition::Confirmed(ConfirmationHeightAnchor {
-            confirmation_height: 12,
-            anchor_block: BlockId {
-                height: 15,
+        let conf2 = ChainPosition::Confirmed(ConfirmationBlockTime {
+            confirmation_time: 15,
+            block_id: BlockId {
+                height: 12,
                 ..Default::default()
             },
         });
index 1ddf7a6d17c02dea59134daaff1a7312f4f42272..3457dfef770ba3c255661434c0d8592442619c48 100644 (file)
@@ -1,7 +1,7 @@
 //! Helper types for spk-based blockchain clients.
 
 use crate::{
-    collections::BTreeMap, local_chain::CheckPoint, ConfirmationTimeHeightAnchor, Indexed, TxGraph,
+    collections::BTreeMap, local_chain::CheckPoint, ConfirmationBlockTime, Indexed, TxGraph,
 };
 use alloc::boxed::Box;
 use bitcoin::{OutPoint, Script, ScriptBuf, Txid};
@@ -176,7 +176,7 @@ impl SyncRequest {
 /// Data returned from a spk-based blockchain client sync.
 ///
 /// See also [`SyncRequest`].
-pub struct SyncResult<A = ConfirmationTimeHeightAnchor> {
+pub struct SyncResult<A = ConfirmationBlockTime> {
     /// The update to apply to the receiving [`TxGraph`].
     pub graph_update: TxGraph<A>,
     /// The update to apply to the receiving [`LocalChain`](crate::local_chain::LocalChain).
@@ -317,7 +317,7 @@ impl<K: Ord + Clone> FullScanRequest<K> {
 /// Data returned from a spk-based blockchain client full scan.
 ///
 /// See also [`FullScanRequest`].
-pub struct FullScanResult<K, A = ConfirmationTimeHeightAnchor> {
+pub struct FullScanResult<K, A = ConfirmationBlockTime> {
     /// The update to apply to the receiving [`LocalChain`](crate::local_chain::LocalChain).
     pub graph_update: TxGraph<A>,
     /// The update to apply to the receiving [`TxGraph`].
index 80e29d9126f0c52b085d9e30018408c9eee82ecc..8a324f6a5c0c79652087cbca5e53440dc1ef9080 100644 (file)
@@ -20,8 +20,7 @@ use alloc::vec::Vec;
 /// # use bdk_chain::local_chain::LocalChain;
 /// # use bdk_chain::tx_graph::TxGraph;
 /// # use bdk_chain::BlockId;
-/// # use bdk_chain::ConfirmationHeightAnchor;
-/// # use bdk_chain::ConfirmationTimeHeightAnchor;
+/// # use bdk_chain::ConfirmationBlockTime;
 /// # use bdk_chain::example_utils::*;
 /// # use bitcoin::hashes::Hash;
 /// // Initialize the local chain with two blocks.
@@ -50,39 +49,19 @@ use alloc::vec::Vec;
 ///     },
 /// );
 ///
-/// // Insert `tx` into a `TxGraph` that uses `ConfirmationHeightAnchor` as the anchor type.
-/// // This anchor records the anchor block and the confirmation height of the transaction.
-/// // When a transaction is anchored with `ConfirmationHeightAnchor`, the anchor block and
-/// // confirmation block can be different. However, the confirmation block cannot be higher than
-/// // the anchor block and both blocks must be in the same chain for the anchor to be valid.
-/// let mut graph_b = TxGraph::<ConfirmationHeightAnchor>::default();
-/// let _ = graph_b.insert_tx(tx.clone());
-/// graph_b.insert_anchor(
-///     tx.compute_txid(),
-///     ConfirmationHeightAnchor {
-///         anchor_block: BlockId {
-///             height: 2,
-///             hash: Hash::hash("second".as_bytes()),
-///         },
-///         confirmation_height: 1,
-///     },
-/// );
-///
-/// // Insert `tx` into a `TxGraph` that uses `ConfirmationTimeHeightAnchor` as the anchor type.
-/// // This anchor records the anchor block, the confirmation height and time of the transaction.
-/// // When a transaction is anchored with `ConfirmationTimeHeightAnchor`, the anchor block and
-/// // confirmation block can be different. However, the confirmation block cannot be higher than
-/// // the anchor block and both blocks must be in the same chain for the anchor to be valid.
-/// let mut graph_c = TxGraph::<ConfirmationTimeHeightAnchor>::default();
+/// // Insert `tx` into a `TxGraph` that uses `ConfirmationBlockTime` as the anchor type.
+/// // This anchor records the anchor block and the confirmation time of the transaction. When a
+/// // transaction is anchored with `ConfirmationBlockTime`, the anchor block and confirmation block
+/// // of the transaction is the same block.
+/// let mut graph_c = TxGraph::<ConfirmationBlockTime>::default();
 /// let _ = graph_c.insert_tx(tx.clone());
 /// graph_c.insert_anchor(
 ///     tx.compute_txid(),
-///     ConfirmationTimeHeightAnchor {
-///         anchor_block: BlockId {
+///     ConfirmationBlockTime {
+///         block_id: BlockId {
 ///             height: 2,
 ///             hash: Hash::hash("third".as_bytes()),
 ///         },
-///         confirmation_height: 1,
 ///         confirmation_time: 123,
 ///     },
 /// );
index 7ea335ce09a5c1f2f4c118a9d5ddaac84e6e5a90..01d25c061a307d5d399dfaa32df24c64034bf869 100644 (file)
@@ -10,7 +10,7 @@ use bdk_chain::{
     indexed_tx_graph::{self, IndexedTxGraph},
     indexer::keychain_txout::KeychainTxOutIndex,
     local_chain::LocalChain,
-    tx_graph, Balance, ChainPosition, ConfirmationHeightAnchor, DescriptorExt, Merge,
+    tx_graph, Balance, ChainPosition, ConfirmationBlockTime, DescriptorExt, Merge,
 };
 use bitcoin::{
     secp256k1::Secp256k1, Amount, OutPoint, Script, ScriptBuf, Transaction, TxIn, TxOut,
@@ -32,7 +32,7 @@ fn insert_relevant_txs() {
     let spk_0 = descriptor.at_derivation_index(0).unwrap().script_pubkey();
     let spk_1 = descriptor.at_derivation_index(9).unwrap().script_pubkey();
 
-    let mut graph = IndexedTxGraph::<ConfirmationHeightAnchor, KeychainTxOutIndex<()>>::new(
+    let mut graph = IndexedTxGraph::<ConfirmationBlockTime, KeychainTxOutIndex<()>>::new(
         KeychainTxOutIndex::new(10),
     );
     let _ = graph
@@ -140,7 +140,7 @@ fn test_list_owned_txouts() {
     let (desc_2, _) =
         Descriptor::parse_descriptor(&Secp256k1::signing_only(), common::DESCRIPTORS[3]).unwrap();
 
-    let mut graph = IndexedTxGraph::<ConfirmationHeightAnchor, KeychainTxOutIndex<String>>::new(
+    let mut graph = IndexedTxGraph::<ConfirmationBlockTime, KeychainTxOutIndex<String>>::new(
         KeychainTxOutIndex::new(10),
     );
 
@@ -250,9 +250,9 @@ fn test_list_owned_txouts() {
                 local_chain
                     .get(height)
                     .map(|cp| cp.block_id())
-                    .map(|anchor_block| ConfirmationHeightAnchor {
-                        anchor_block,
-                        confirmation_height: anchor_block.height,
+                    .map(|block_id| ConfirmationBlockTime {
+                        block_id,
+                        confirmation_time: 100,
                     }),
             )
         }));
@@ -261,8 +261,7 @@ fn test_list_owned_txouts() {
 
     // A helper lambda to extract and filter data from the graph.
     let fetch =
-        |height: u32,
-         graph: &IndexedTxGraph<ConfirmationHeightAnchor, KeychainTxOutIndex<String>>| {
+        |height: u32, graph: &IndexedTxGraph<ConfirmationBlockTime, KeychainTxOutIndex<String>>| {
             let chain_tip = local_chain
                 .get(height)
                 .map(|cp| cp.block_id())
index dc8f0144cf4c3144d33a4f64f3c26ca56789fdf6..8ddf7f30a656c23796a370fe412d92cb0ad7b80e 100644 (file)
@@ -7,7 +7,7 @@ use bdk_chain::{
     collections::*,
     local_chain::LocalChain,
     tx_graph::{ChangeSet, TxGraph},
-    Anchor, BlockId, ChainOracle, ChainPosition, ConfirmationHeightAnchor, Merge,
+    Anchor, BlockId, ChainOracle, ChainPosition, ConfirmationBlockTime, Merge,
 };
 use bitcoin::{
     absolute, hashes::Hash, transaction, Amount, BlockHash, OutPoint, ScriptBuf, SignedAmount,
@@ -935,7 +935,7 @@ fn test_chain_spends() {
         ..common::new_tx(0)
     };
 
-    let mut graph = TxGraph::<ConfirmationHeightAnchor>::default();
+    let mut graph = TxGraph::<ConfirmationBlockTime>::default();
 
     let _ = graph.insert_tx(tx_0.clone());
     let _ = graph.insert_tx(tx_1.clone());
@@ -944,9 +944,9 @@ fn test_chain_spends() {
     for (ht, tx) in [(95, &tx_0), (98, &tx_1)] {
         let _ = graph.insert_anchor(
             tx.compute_txid(),
-            ConfirmationHeightAnchor {
-                anchor_block: tip.block_id(),
-                confirmation_height: ht,
+            ConfirmationBlockTime {
+                block_id: tip.get(ht).unwrap().block_id(),
+                confirmation_time: 100,
             },
         );
     }
@@ -959,9 +959,12 @@ fn test_chain_spends() {
             OutPoint::new(tx_0.compute_txid(), 0)
         ),
         Some((
-            ChainPosition::Confirmed(&ConfirmationHeightAnchor {
-                anchor_block: tip.block_id(),
-                confirmation_height: 98
+            ChainPosition::Confirmed(&ConfirmationBlockTime {
+                block_id: BlockId {
+                    hash: tip.get(98).unwrap().hash(),
+                    height: 98,
+                },
+                confirmation_time: 100
             }),
             tx_1.compute_txid(),
         )),
@@ -971,9 +974,12 @@ fn test_chain_spends() {
     assert_eq!(
         graph.get_chain_position(&local_chain, tip.block_id(), tx_0.compute_txid()),
         // Some(ObservedAs::Confirmed(&local_chain.get_block(95).expect("block expected"))),
-        Some(ChainPosition::Confirmed(&ConfirmationHeightAnchor {
-            anchor_block: tip.block_id(),
-            confirmation_height: 95
+        Some(ChainPosition::Confirmed(&ConfirmationBlockTime {
+            block_id: BlockId {
+                hash: tip.get(95).unwrap().hash(),
+                height: 95,
+            },
+            confirmation_time: 100
         }))
     );
 
index f333d3c1fd195a1cd02e26e3ad5e8731369bb80f..93c9dea74ab84b1c5e72dba1e8239afc1961f146 100644 (file)
@@ -4,7 +4,7 @@ use bdk_chain::{
     local_chain::CheckPoint,
     spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult},
     tx_graph::TxGraph,
-    Anchor, BlockId, ConfirmationTimeHeightAnchor,
+    Anchor, BlockId, ConfirmationBlockTime,
 };
 use electrum_client::{ElectrumApi, Error, HeaderNotification};
 use std::{
@@ -123,12 +123,12 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
     ) -> Result<FullScanResult<K>, Error> {
         let (tip, latest_blocks) =
             fetch_tip_and_latest_blocks(&self.inner, request.chain_tip.clone())?;
-        let mut graph_update = TxGraph::<ConfirmationTimeHeightAnchor>::default();
+        let mut graph_update = TxGraph::<ConfirmationBlockTime>::default();
         let mut last_active_indices = BTreeMap::<K, u32>::new();
 
-        for (keychain, keychain_spks) in request.spks_by_keychain {
+        for (keychain, spks) in request.spks_by_keychain {
             if let Some(last_active_index) =
-                self.populate_with_spks(&mut graph_update, keychain_spks, stop_gap, batch_size)?
+                self.populate_with_spks(&mut graph_update, spks, stop_gap, batch_size)?
             {
                 last_active_indices.insert(keychain, last_active_index);
             }
@@ -199,17 +199,15 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
     /// Transactions that contains an output with requested spk, or spends form an output with
     /// requested spk will be added to `graph_update`. Anchors of the aforementioned transactions are
     /// also included.
-    ///
-    /// Checkpoints (in `cps`) are used to create anchors. The `tx_cache` is self-explanatory.
-    fn populate_with_spks<I: Ord + Clone>(
+    fn populate_with_spks(
         &self,
-        graph_update: &mut TxGraph<ConfirmationTimeHeightAnchor>,
-        mut spks: impl Iterator<Item = (I, ScriptBuf)>,
+        graph_update: &mut TxGraph<ConfirmationBlockTime>,
+        mut spks: impl Iterator<Item = (u32, ScriptBuf)>,
         stop_gap: usize,
         batch_size: usize,
-    ) -> Result<Option<I>, Error> {
+    ) -> Result<Option<u32>, Error> {
         let mut unused_spk_count = 0_usize;
-        let mut last_active_index = Option::<I>::None;
+        let mut last_active_index = Option::<u32>::None;
 
         loop {
             let spks = (0..batch_size)
@@ -225,8 +223,8 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
 
             for ((spk_index, _spk), spk_history) in spks.into_iter().zip(spk_histories) {
                 if spk_history.is_empty() {
-                    unused_spk_count += 1;
-                    if unused_spk_count > stop_gap {
+                    unused_spk_count = unused_spk_count.saturating_add(1);
+                    if unused_spk_count >= stop_gap {
                         return Ok(last_active_index);
                     }
                     continue;
@@ -247,11 +245,9 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
     ///
     /// Transactions in which the outpoint resides, and transactions that spend from the outpoint are
     /// included. Anchors of the aforementioned transactions are included.
-    ///
-    /// Checkpoints (in `cps`) are used to create anchors. The `tx_cache` is self-explanatory.
     fn populate_with_outpoints(
         &self,
-        graph_update: &mut TxGraph<ConfirmationTimeHeightAnchor>,
+        graph_update: &mut TxGraph<ConfirmationBlockTime>,
         outpoints: impl IntoIterator<Item = OutPoint>,
     ) -> Result<(), Error> {
         for outpoint in outpoints {
@@ -299,7 +295,7 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
     /// Populate the `graph_update` with transactions/anchors of the provided `txids`.
     fn populate_with_txids(
         &self,
-        graph_update: &mut TxGraph<ConfirmationTimeHeightAnchor>,
+        graph_update: &mut TxGraph<ConfirmationBlockTime>,
         txids: impl IntoIterator<Item = Txid>,
     ) -> Result<(), Error> {
         for txid in txids {
@@ -335,7 +331,7 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
     // An anchor is inserted if the transaction is validated to be in a confirmed block.
     fn validate_merkle_for_anchor(
         &self,
-        graph_update: &mut TxGraph<ConfirmationTimeHeightAnchor>,
+        graph_update: &mut TxGraph<ConfirmationBlockTime>,
         txid: Txid,
         confirmation_height: i32,
     ) -> Result<(), Error> {
@@ -364,10 +360,9 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
             if is_confirmed_tx {
                 let _ = graph_update.insert_anchor(
                     txid,
-                    ConfirmationTimeHeightAnchor {
-                        confirmation_height: merkle_res.block_height as u32,
+                    ConfirmationBlockTime {
                         confirmation_time: header.time as u64,
-                        anchor_block: BlockId {
+                        block_id: BlockId {
                             height: merkle_res.block_height as u32,
                             hash: header.block_hash(),
                         },
@@ -382,7 +377,7 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
     // which we do not have by default. This data is needed to calculate the transaction fee.
     fn fetch_prev_txout(
         &self,
-        graph_update: &mut TxGraph<ConfirmationTimeHeightAnchor>,
+        graph_update: &mut TxGraph<ConfirmationBlockTime>,
     ) -> Result<(), Error> {
         let full_txs: Vec<Arc<Transaction>> =
             graph_update.full_txs().map(|tx_node| tx_node.tx).collect();
@@ -454,11 +449,13 @@ fn fetch_tip_and_latest_blocks(
     let agreement_height = agreement_cp.as_ref().map(CheckPoint::height);
 
     let new_tip = new_blocks
-        .clone()
-        .into_iter()
+        .iter()
         // Prune `new_blocks` to only include blocks that are actually new.
-        .filter(|(height, _)| Some(*height) > agreement_height)
-        .map(|(height, hash)| BlockId { height, hash })
+        .filter(|(height, _)| Some(*<&u32>::clone(height)) > agreement_height)
+        .map(|(height, hash)| BlockId {
+            height: *height,
+            hash: *hash,
+        })
         .fold(agreement_cp, |prev_cp, block| {
             Some(match prev_cp {
                 Some(cp) => cp.push(block).expect("must extend checkpoint"),
index 4d98b5150ce5ebdb2eff69299d0bb5eb820c9c6e..825454331333f8928cf78ad0332e653de53d7009 100644 (file)
@@ -2,7 +2,7 @@ use bdk_chain::{
     bitcoin::{hashes::Hash, Address, Amount, ScriptBuf, Txid, WScriptHash},
     local_chain::LocalChain,
     spk_client::{FullScanRequest, SyncRequest},
-    Balance, ConfirmationTimeHeightAnchor, IndexedTxGraph, SpkTxOutIndex,
+    Balance, ConfirmationBlockTime, IndexedTxGraph, SpkTxOutIndex,
 };
 use bdk_electrum::BdkElectrumClient;
 use bdk_testenv::{anyhow, bitcoincore_rpc::RpcApi, TestEnv};
@@ -11,7 +11,7 @@ use std::str::FromStr;
 
 fn get_balance(
     recv_chain: &LocalChain,
-    recv_graph: &IndexedTxGraph<ConfirmationTimeHeightAnchor, SpkTxOutIndex<()>>,
+    recv_graph: &IndexedTxGraph<ConfirmationBlockTime, SpkTxOutIndex<()>>,
 ) -> anyhow::Result<Balance> {
     let chain_tip = recv_chain.tip().block_id();
     let outpoints = recv_graph.index.outpoints().clone();
@@ -262,7 +262,7 @@ fn scan_detects_confirmed_tx() -> anyhow::Result<()> {
 
     // Setup receiver.
     let (mut recv_chain, _) = LocalChain::from_genesis_hash(env.bitcoind.client.get_block_hash(0)?);
-    let mut recv_graph = IndexedTxGraph::<ConfirmationTimeHeightAnchor, _>::new({
+    let mut recv_graph = IndexedTxGraph::<ConfirmationBlockTime, _>::new({
         let mut recv_index = SpkTxOutIndex::default();
         recv_index.insert_spk((), spk_to_track.clone());
         recv_index
@@ -352,7 +352,7 @@ fn tx_can_become_unconfirmed_after_reorg() -> anyhow::Result<()> {
 
     // Setup receiver.
     let (mut recv_chain, _) = LocalChain::from_genesis_hash(env.bitcoind.client.get_block_hash(0)?);
-    let mut recv_graph = IndexedTxGraph::<ConfirmationTimeHeightAnchor, _>::new({
+    let mut recv_graph = IndexedTxGraph::<ConfirmationBlockTime, _>::new({
         let mut recv_index = SpkTxOutIndex::default();
         recv_index.insert_spk((), spk_to_track.clone());
         recv_index
@@ -362,9 +362,11 @@ fn tx_can_become_unconfirmed_after_reorg() -> anyhow::Result<()> {
     env.mine_blocks(101, Some(addr_to_mine))?;
 
     // Create transactions that are tracked by our receiver.
+    let mut txids = vec![];
+    let mut hashes = vec![];
     for _ in 0..REORG_COUNT {
-        env.send(&addr_to_track, SEND_AMOUNT)?;
-        env.mine_blocks(1, None)?;
+        txids.push(env.send(&addr_to_track, SEND_AMOUNT)?);
+        hashes.extend(env.mine_blocks(1, None)?);
     }
 
     // Sync up to tip.
@@ -382,6 +384,13 @@ fn tx_can_become_unconfirmed_after_reorg() -> anyhow::Result<()> {
 
     // Retain a snapshot of all anchors before reorg process.
     let initial_anchors = update.graph_update.all_anchors();
+    let anchors: Vec<_> = initial_anchors.iter().cloned().collect();
+    assert_eq!(anchors.len(), REORG_COUNT);
+    for i in 0..REORG_COUNT {
+        let (anchor, txid) = anchors[i];
+        assert_eq!(anchor.block_id.hash, hashes[i]);
+        assert_eq!(txid, txids[i]);
+    }
 
     // Check if initial balance is correct.
     assert_eq!(
index 939c43a2f68d23b18127cfe4f29ade60fbc29f84..70895a43aa477eaae9670a9464b654beb5a23fbc 100644 (file)
@@ -6,7 +6,7 @@ use bdk_chain::{
     bitcoin::{BlockHash, OutPoint, ScriptBuf, TxOut, Txid},
     collections::BTreeMap,
     local_chain::CheckPoint,
-    BlockId, ConfirmationTimeHeightAnchor, TxGraph,
+    BlockId, ConfirmationBlockTime, TxGraph,
 };
 use bdk_chain::{Anchor, Indexed};
 use esplora_client::{Amount, TxStatus};
@@ -240,10 +240,10 @@ async fn full_scan_for_index_and_graph<K: Ord + Clone + Send>(
     >,
     stop_gap: usize,
     parallel_requests: usize,
-) -> Result<(TxGraph<ConfirmationTimeHeightAnchor>, BTreeMap<K, u32>), Error> {
+) -> Result<(TxGraph<ConfirmationBlockTime>, BTreeMap<K, u32>), Error> {
     type TxsOfSpkIndex = (u32, Vec<esplora_client::Tx>);
     let parallel_requests = Ord::max(parallel_requests, 1);
-    let mut graph = TxGraph::<ConfirmationTimeHeightAnchor>::default();
+    let mut graph = TxGraph::<ConfirmationBlockTime>::default();
     let mut last_active_indexes = BTreeMap::<K, u32>::new();
 
     for (keychain, spks) in keychain_spks {
@@ -333,7 +333,7 @@ async fn sync_for_index_and_graph(
     txids: impl IntoIterator<IntoIter = impl Iterator<Item = Txid> + Send> + Send,
     outpoints: impl IntoIterator<IntoIter = impl Iterator<Item = OutPoint> + Send> + Send,
     parallel_requests: usize,
-) -> Result<TxGraph<ConfirmationTimeHeightAnchor>, Error> {
+) -> Result<TxGraph<ConfirmationBlockTime>, Error> {
     let mut graph = full_scan_for_index_and_graph(
         client,
         [(
index adad25c2e5ece6a72c12b2b4566b4cd111ba53e6..dc95a350b4db8aaebe372b205375d58b8dc23ace 100644 (file)
@@ -6,7 +6,7 @@ use bdk_chain::spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncRe
 use bdk_chain::{
     bitcoin::{Amount, BlockHash, OutPoint, ScriptBuf, TxOut, Txid},
     local_chain::CheckPoint,
-    BlockId, ConfirmationTimeHeightAnchor, TxGraph,
+    BlockId, ConfirmationBlockTime, TxGraph,
 };
 use bdk_chain::{Anchor, Indexed};
 use esplora_client::TxStatus;
@@ -219,10 +219,10 @@ fn full_scan_for_index_and_graph_blocking<K: Ord + Clone>(
     keychain_spks: BTreeMap<K, impl IntoIterator<Item = Indexed<ScriptBuf>>>,
     stop_gap: usize,
     parallel_requests: usize,
-) -> Result<(TxGraph<ConfirmationTimeHeightAnchor>, BTreeMap<K, u32>), Error> {
+) -> Result<(TxGraph<ConfirmationBlockTime>, BTreeMap<K, u32>), Error> {
     type TxsOfSpkIndex = (u32, Vec<esplora_client::Tx>);
     let parallel_requests = Ord::max(parallel_requests, 1);
-    let mut tx_graph = TxGraph::<ConfirmationTimeHeightAnchor>::default();
+    let mut tx_graph = TxGraph::<ConfirmationBlockTime>::default();
     let mut last_active_indices = BTreeMap::<K, u32>::new();
 
     for (keychain, spks) in keychain_spks {
@@ -315,7 +315,7 @@ fn sync_for_index_and_graph_blocking(
     txids: impl IntoIterator<Item = Txid>,
     outpoints: impl IntoIterator<Item = OutPoint>,
     parallel_requests: usize,
-) -> Result<TxGraph<ConfirmationTimeHeightAnchor>, Error> {
+) -> Result<TxGraph<ConfirmationBlockTime>, Error> {
     let (mut tx_graph, _) = full_scan_for_index_and_graph_blocking(
         client,
         {
index 535167ff25b5bb3908272bb53bd182952d22e1b2..718d3cf9c815304d5ac44d926dad7aff040ebdf1 100644 (file)
@@ -16,7 +16,7 @@
 //! [`TxGraph`]: bdk_chain::tx_graph::TxGraph
 //! [`example_esplora`]: https://github.com/bitcoindevkit/bdk/tree/master/example-crates/example_esplora
 
-use bdk_chain::{BlockId, ConfirmationTimeHeightAnchor};
+use bdk_chain::{BlockId, ConfirmationBlockTime};
 use esplora_client::TxStatus;
 
 pub use esplora_client;
@@ -31,7 +31,7 @@ mod async_ext;
 #[cfg(feature = "async")]
 pub use async_ext::*;
 
-fn anchor_from_status(status: &TxStatus) -> Option<ConfirmationTimeHeightAnchor> {
+fn anchor_from_status(status: &TxStatus) -> Option<ConfirmationBlockTime> {
     if let TxStatus {
         block_height: Some(height),
         block_hash: Some(hash),
@@ -39,9 +39,8 @@ fn anchor_from_status(status: &TxStatus) -> Option<ConfirmationTimeHeightAnchor>
         ..
     } = status.clone()
     {
-        Some(ConfirmationTimeHeightAnchor {
-            anchor_block: BlockId { height, hash },
-            confirmation_height: height,
+        Some(ConfirmationBlockTime {
+            block_id: BlockId { height, hash },
             confirmation_time: time,
         })
     } else {
index 5a5468167b485a0199073e2444a5b2cb325a1cd3..5b7992518bf8af1263c507ca8bd2135921a2f07c 100644 (file)
@@ -547,10 +547,7 @@ mod test {
     use bdk_chain::bitcoin::{secp256k1, BlockHash, OutPoint};
     use bdk_chain::miniscript::Descriptor;
     use bdk_chain::CombinedChangeSet;
-    use bdk_chain::{
-        indexed_tx_graph, tx_graph, BlockId, ConfirmationHeightAnchor,
-        ConfirmationTimeHeightAnchor, DescriptorExt,
-    };
+    use bdk_chain::{indexed_tx_graph, tx_graph, BlockId, ConfirmationBlockTime, DescriptorExt};
     use std::str::FromStr;
     use std::sync::Arc;
 
@@ -561,37 +558,15 @@ mod test {
     }
 
     #[test]
-    fn insert_and_load_aggregate_changesets_with_confirmation_time_height_anchor() {
+    fn insert_and_load_aggregate_changesets_with_confirmation_block_time_anchor() {
         let (test_changesets, agg_test_changesets) =
-            create_test_changesets(&|height, time, hash| ConfirmationTimeHeightAnchor {
-                confirmation_height: height,
+            create_test_changesets(&|height, time, hash| ConfirmationBlockTime {
                 confirmation_time: time,
-                anchor_block: (height, hash).into(),
+                block_id: (height, hash).into(),
             });
 
         let conn = Connection::open_in_memory().expect("in memory connection");
-        let mut store = Store::<Keychain, ConfirmationTimeHeightAnchor>::new(conn)
-            .expect("create new memory db store");
-
-        test_changesets.iter().for_each(|changeset| {
-            store.write(changeset).expect("write changeset");
-        });
-
-        let agg_changeset = store.read().expect("aggregated changeset");
-
-        assert_eq!(agg_changeset, Some(agg_test_changesets));
-    }
-
-    #[test]
-    fn insert_and_load_aggregate_changesets_with_confirmation_height_anchor() {
-        let (test_changesets, agg_test_changesets) =
-            create_test_changesets(&|height, _time, hash| ConfirmationHeightAnchor {
-                confirmation_height: height,
-                anchor_block: (height, hash).into(),
-            });
-
-        let conn = Connection::open_in_memory().expect("in memory connection");
-        let mut store = Store::<Keychain, ConfirmationHeightAnchor>::new(conn)
+        let mut store = Store::<Keychain, ConfirmationBlockTime>::new(conn)
             .expect("create new memory db store");
 
         test_changesets.iter().for_each(|changeset| {
index 37f7fac0e22505fa08ffbdfd73b42d72295afb3f..4b49db144284e6835502ac1b151fd478ca85cad1 100644 (file)
@@ -128,7 +128,7 @@ impl FullyNodedExport {
         let blockheight = if include_blockheight {
             wallet.transactions().next().map_or(0, |canonical_tx| {
                 match canonical_tx.chain_position {
-                    bdk_chain::ChainPosition::Confirmed(a) => a.confirmation_height,
+                    bdk_chain::ChainPosition::Confirmed(a) => a.block_id.height,
                     bdk_chain::ChainPosition::Unconfirmed(_) => 0,
                 }
             })
@@ -214,7 +214,7 @@ mod test {
     use core::str::FromStr;
 
     use crate::std::string::ToString;
-    use bdk_chain::{BlockId, ConfirmationTimeHeightAnchor};
+    use bdk_chain::{BlockId, ConfirmationBlockTime};
     use bitcoin::hashes::Hash;
     use bitcoin::{transaction, BlockHash, Network, Transaction};
 
@@ -233,15 +233,20 @@ mod test {
         };
         let txid = transaction.compute_txid();
         let block_id = BlockId {
-            height: 5001,
+            height: 5000,
             hash: BlockHash::all_zeros(),
         };
         wallet.insert_checkpoint(block_id).unwrap();
+        wallet
+            .insert_checkpoint(BlockId {
+                height: 5001,
+                hash: BlockHash::all_zeros(),
+            })
+            .unwrap();
         wallet.insert_tx(transaction);
-        let anchor = ConfirmationTimeHeightAnchor {
-            confirmation_height: 5000,
+        let anchor = ConfirmationBlockTime {
             confirmation_time: 0,
-            anchor_block: block_id,
+            block_id,
         };
         let mut graph = TxGraph::default();
         let _ = graph.insert_anchor(txid, anchor);
index 8c049b0e060f476a9930a7b2bbd4ca424fc5f4b8..9db21ac71d1adaa663092ac7cf9a7fb045b457c1 100644 (file)
@@ -28,7 +28,7 @@ use bdk_chain::{
     },
     spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult},
     tx_graph::{CanonicalTx, TxGraph, TxNode},
-    BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeHeightAnchor, FullTxOut, Indexed,
+    BlockId, ChainPosition, ConfirmationBlockTime, ConfirmationTime, FullTxOut, Indexed,
     IndexedTxGraph, Merge,
 };
 use bitcoin::sighash::{EcdsaSighashType, TapSighashType};
@@ -104,7 +104,7 @@ pub struct Wallet {
     signers: Arc<SignersContainer>,
     change_signers: Arc<SignersContainer>,
     chain: LocalChain,
-    indexed_graph: IndexedTxGraph<ConfirmationTimeHeightAnchor, KeychainTxOutIndex<KeychainKind>>,
+    indexed_graph: IndexedTxGraph<ConfirmationBlockTime, KeychainTxOutIndex<KeychainKind>>,
     stage: ChangeSet,
     network: Network,
     secp: SecpCtx,
@@ -120,7 +120,7 @@ pub struct Update {
     pub last_active_indices: BTreeMap<KeychainKind, u32>,
 
     /// Update for the wallet's internal [`TxGraph`].
-    pub graph: TxGraph<ConfirmationTimeHeightAnchor>,
+    pub graph: TxGraph<ConfirmationBlockTime>,
 
     /// Update for the wallet's internal [`LocalChain`].
     ///
@@ -149,7 +149,7 @@ impl From<SyncResult> for Update {
 }
 
 /// The changes made to a wallet by applying an [`Update`].
-pub type ChangeSet = bdk_chain::CombinedChangeSet<KeychainKind, ConfirmationTimeHeightAnchor>;
+pub type ChangeSet = bdk_chain::CombinedChangeSet<KeychainKind, ConfirmationBlockTime>;
 
 /// A derived address and the index it was found at.
 /// For convenience this automatically derefs to `Address`
@@ -1007,7 +1007,7 @@ impl Wallet {
     /// match canonical_tx.chain_position {
     ///     ChainPosition::Confirmed(anchor) => println!(
     ///         "tx is confirmed at height {}, we know this since {}:{} is in the best chain",
-    ///         anchor.confirmation_height, anchor.anchor_block.height, anchor.anchor_block.hash,
+    ///         anchor.block_id.height, anchor.block_id.height, anchor.block_id.hash,
     ///     ),
     ///     ChainPosition::Unconfirmed(last_seen) => println!(
     ///         "tx is last seen at {}, it is unconfirmed as it is not anchored in the best chain",
@@ -1020,7 +1020,7 @@ impl Wallet {
     pub fn get_tx(
         &self,
         txid: Txid,
-    ) -> Option<CanonicalTx<'_, Arc<Transaction>, ConfirmationTimeHeightAnchor>> {
+    ) -> Option<CanonicalTx<'_, Arc<Transaction>, ConfirmationBlockTime>> {
         let graph = self.indexed_graph.graph();
 
         Some(CanonicalTx {
@@ -1076,8 +1076,7 @@ impl Wallet {
     /// Iterate over the transactions in the wallet.
     pub fn transactions(
         &self,
-    ) -> impl Iterator<Item = CanonicalTx<'_, Arc<Transaction>, ConfirmationTimeHeightAnchor>> + '_
-    {
+    ) -> impl Iterator<Item = CanonicalTx<'_, Arc<Transaction>, ConfirmationBlockTime>> + '_ {
         self.indexed_graph
             .graph()
             .list_canonical_txs(&self.chain, self.chain.tip().block_id())
@@ -1807,7 +1806,7 @@ impl Wallet {
                 .graph()
                 .get_chain_position(&self.chain, chain_tip, input.previous_output.txid)
                 .map(|chain_position| match chain_position {
-                    ChainPosition::Confirmed(a) => a.confirmation_height,
+                    ChainPosition::Confirmed(a) => a.block_id.height,
                     ChainPosition::Unconfirmed(_) => u32::MAX,
                 });
             let current_height = sign_options
@@ -2245,7 +2244,7 @@ impl Wallet {
     }
 
     /// Get a reference to the inner [`TxGraph`].
-    pub fn tx_graph(&self) -> &TxGraph<ConfirmationTimeHeightAnchor> {
+    pub fn tx_graph(&self) -> &TxGraph<ConfirmationBlockTime> {
         self.indexed_graph.graph()
     }
 
@@ -2253,7 +2252,7 @@ impl Wallet {
     /// because they haven't been broadcast.
     pub fn unbroadcast_transactions(
         &self,
-    ) -> impl Iterator<Item = TxNode<'_, Arc<Transaction>, ConfirmationTimeHeightAnchor>> {
+    ) -> impl Iterator<Item = TxNode<'_, Arc<Transaction>, ConfirmationBlockTime>> {
         self.tx_graph().txs_with_no_anchor_or_last_seen()
     }
 
@@ -2373,8 +2372,8 @@ impl Wallet {
     }
 }
 
-impl AsRef<bdk_chain::tx_graph::TxGraph<ConfirmationTimeHeightAnchor>> for Wallet {
-    fn as_ref(&self) -> &bdk_chain::tx_graph::TxGraph<ConfirmationTimeHeightAnchor> {
+impl AsRef<bdk_chain::tx_graph::TxGraph<ConfirmationBlockTime>> for Wallet {
+    fn as_ref(&self) -> &bdk_chain::tx_graph::TxGraph<ConfirmationBlockTime> {
         self.indexed_graph.graph()
     }
 }
@@ -2413,7 +2412,7 @@ where
 fn new_local_utxo(
     keychain: KeychainKind,
     derivation_index: u32,
-    full_txo: FullTxOut<ConfirmationTimeHeightAnchor>,
+    full_txo: FullTxOut<ConfirmationBlockTime>,
 ) -> LocalOutput {
     LocalOutput {
         outpoint: full_txo.outpoint,
@@ -2476,7 +2475,7 @@ macro_rules! floating_rate {
 macro_rules! doctest_wallet {
     () => {{
         use $crate::bitcoin::{BlockHash, Transaction, absolute, TxOut, Network, hashes::Hash};
-        use $crate::chain::{ConfirmationTimeHeightAnchor, BlockId, TxGraph};
+        use $crate::chain::{ConfirmationBlockTime, BlockId, TxGraph};
         use $crate::wallet::{Update, Wallet};
         use $crate::KeychainKind;
         let descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/0/*)";
@@ -2499,13 +2498,13 @@ macro_rules! doctest_wallet {
             }],
         };
         let txid = tx.txid();
-        let block = BlockId { height: 1_000, hash: BlockHash::all_zeros() };
-        let _ = wallet.insert_checkpoint(block);
+        let block_id = BlockId { height: 500, hash: BlockHash::all_zeros() };
+        let _ = wallet.insert_checkpoint(block_id);
+        let _ = wallet.insert_checkpoint(BlockId { height: 1_000, hash: BlockHash::all_zeros() });
         let _ = wallet.insert_tx(tx);
-        let anchor = ConfirmationTimeHeightAnchor {
-            confirmation_height: 500,
+        let anchor = ConfirmationBlockTime {
             confirmation_time: 50_000,
-            anchor_block: block,
+            block_id,
         };
         let mut graph = TxGraph::default();
         let _ = graph.insert_anchor(txid, anchor);
index c124ba21343beeba48205710aa2464baa329454f..9774ec985522d0eecbab539a0bb64a6606b84fde 100644 (file)
@@ -1,5 +1,5 @@
 #![allow(unused)]
-use bdk_chain::{BlockId, ConfirmationTime, ConfirmationTimeHeightAnchor, TxGraph};
+use bdk_chain::{BlockId, ConfirmationBlockTime, ConfirmationTime, TxGraph};
 use bdk_wallet::{
     wallet::{Update, Wallet},
     KeychainKind, LocalOutput,
@@ -65,6 +65,12 @@ pub fn get_funded_wallet_with_change(descriptor: &str, change: &str) -> (Wallet,
         ],
     };
 
+    wallet
+        .insert_checkpoint(BlockId {
+            height: 42,
+            hash: BlockHash::all_zeros(),
+        })
+        .unwrap();
     wallet
         .insert_checkpoint(BlockId {
             height: 1_000,
@@ -205,9 +211,8 @@ pub fn insert_anchor_from_conf(wallet: &mut Wallet, txid: Txid, position: Confir
             .local_chain()
             .range(height..)
             .last()
-            .map(|anchor_cp| ConfirmationTimeHeightAnchor {
-                anchor_block: anchor_cp.block_id(),
-                confirmation_height: height,
+            .map(|anchor_cp| ConfirmationBlockTime {
+                block_id: anchor_cp.block_id(),
                 confirmation_time: time,
             })
             .expect("confirmation height cannot be greater than tip");
index 1749d2f3e4b64812d34c5c9146eaac13245395ae..c71b18fed844c4f4f14861654afb3e32575120ed 100644 (file)
@@ -16,7 +16,7 @@ use bdk_chain::{
     indexed_tx_graph,
     indexer::keychain_txout,
     local_chain::{self, LocalChain},
-    ConfirmationTimeHeightAnchor, IndexedTxGraph, Merge,
+    ConfirmationBlockTime, IndexedTxGraph, Merge,
 };
 use example_cli::{
     anyhow,
@@ -38,7 +38,7 @@ const DB_COMMIT_DELAY: Duration = Duration::from_secs(60);
 
 type ChangeSet = (
     local_chain::ChangeSet,
-    indexed_tx_graph::ChangeSet<ConfirmationTimeHeightAnchor, keychain_txout::ChangeSet<Keychain>>,
+    indexed_tx_graph::ChangeSet<ConfirmationBlockTime, keychain_txout::ChangeSet<Keychain>>,
 );
 
 #[derive(Debug)]
index 0b5454df583c122df11bd72c03390047d969a522..31e8e70411825a49ff7121f368260875cf054181 100644 (file)
@@ -10,7 +10,7 @@ use bdk_chain::{
     indexer::keychain_txout,
     local_chain::{self, LocalChain},
     spk_client::{FullScanRequest, SyncRequest},
-    ConfirmationHeightAnchor, Merge,
+    ConfirmationBlockTime, Merge,
 };
 use bdk_electrum::{
     electrum_client::{self, Client, ElectrumApi},
@@ -100,7 +100,7 @@ pub struct ScanOptions {
 
 type ChangeSet = (
     local_chain::ChangeSet,
-    indexed_tx_graph::ChangeSet<ConfirmationHeightAnchor, keychain_txout::ChangeSet<Keychain>>,
+    indexed_tx_graph::ChangeSet<ConfirmationBlockTime, keychain_txout::ChangeSet<Keychain>>,
 );
 
 fn main() -> anyhow::Result<()> {
@@ -338,17 +338,12 @@ fn main() -> anyhow::Result<()> {
         let chain_changeset = chain.apply_update(chain_update)?;
 
         let mut indexed_tx_graph_changeset =
-            indexed_tx_graph::ChangeSet::<ConfirmationHeightAnchor, _>::default();
+            indexed_tx_graph::ChangeSet::<ConfirmationBlockTime, _>::default();
         if let Some(keychain_update) = keychain_update {
             let keychain_changeset = graph.index.reveal_to_target_multi(&keychain_update);
             indexed_tx_graph_changeset.merge(keychain_changeset.into());
         }
-        indexed_tx_graph_changeset.merge(graph.apply_update(graph_update.map_anchors(|a| {
-            ConfirmationHeightAnchor {
-                confirmation_height: a.confirmation_height,
-                anchor_block: a.anchor_block,
-            }
-        })));
+        indexed_tx_graph_changeset.merge(graph.apply_update(graph_update));
 
         (chain_changeset, indexed_tx_graph_changeset)
     };
index 8f69efb28fdbba06cdf2133f8a204d816668fdde..ffa2ea24e1c7552e2943683dfa043be14b525e09 100644 (file)
@@ -10,7 +10,7 @@ use bdk_chain::{
     indexer::keychain_txout,
     local_chain::{self, LocalChain},
     spk_client::{FullScanRequest, SyncRequest},
-    ConfirmationTimeHeightAnchor, Merge,
+    ConfirmationBlockTime, Merge,
 };
 
 use bdk_esplora::{esplora_client, EsploraExt};
@@ -26,7 +26,7 @@ const DB_PATH: &str = ".bdk_esplora_example.db";
 
 type ChangeSet = (
     local_chain::ChangeSet,
-    indexed_tx_graph::ChangeSet<ConfirmationTimeHeightAnchor, keychain_txout::ChangeSet<Keychain>>,
+    indexed_tx_graph::ChangeSet<ConfirmationBlockTime, keychain_txout::ChangeSet<Keychain>>,
 );
 
 #[derive(Subcommand, Debug, Clone)]