]> Untitled Git - bdk/commitdiff
chore(chain)!: rm `missing_heights` and `missing_heights_from` methods
author志宇 <hello@evanlinjin.me>
Tue, 26 Mar 2024 07:11:43 +0000 (15:11 +0800)
committer志宇 <hello@evanlinjin.me>
Tue, 16 Apr 2024 10:01:50 +0000 (18:01 +0800)
These methods are no longer needed as we can determine missing heights
directly from the `CheckPoint` tip.

crates/chain/src/tx_graph.rs
crates/chain/tests/test_tx_graph.rs

index b74ebeda70cc160135d71e9f75545f0897f2ed3b..f6144e7a25680a039cb2bc1c0a31a6beac2c9d2a 100644 (file)
@@ -89,8 +89,8 @@
 //! [`insert_txout`]: TxGraph::insert_txout
 
 use crate::{
-    collections::*, keychain::Balance, local_chain::LocalChain, Anchor, Append, BlockId,
-    ChainOracle, ChainPosition, FullTxOut,
+    collections::*, keychain::Balance, Anchor, Append, BlockId, ChainOracle, ChainPosition,
+    FullTxOut,
 };
 use alloc::collections::vec_deque::VecDeque;
 use alloc::sync::Arc;
@@ -759,69 +759,6 @@ impl<A: Clone + Ord> TxGraph<A> {
 }
 
 impl<A: Anchor> TxGraph<A> {
-    /// Find missing block heights of `chain`.
-    ///
-    /// This works by scanning through anchors, and seeing whether the anchor block of the anchor
-    /// exists in the [`LocalChain`]. The returned iterator does not output duplicate heights.
-    pub fn missing_heights<'a>(&'a self, chain: &'a LocalChain) -> impl Iterator<Item = u32> + 'a {
-        // Map of txids to skip.
-        //
-        // Usually, if a height of a tx anchor is missing from the chain, we would want to return
-        // this height in the iterator. The exception is when the tx is confirmed in chain. All the
-        // other missing-height anchors of this tx can be skipped.
-        //
-        // * Some(true)  => skip all anchors of this txid
-        // * Some(false) => do not skip anchors of this txid
-        // * None        => we do not know whether we can skip this txid
-        let mut txids_to_skip = HashMap::<Txid, bool>::new();
-
-        // Keeps track of the last height emitted so we don't double up.
-        let mut last_height_emitted = Option::<u32>::None;
-
-        self.anchors
-            .iter()
-            .filter(move |(_, txid)| {
-                let skip = *txids_to_skip.entry(*txid).or_insert_with(|| {
-                    let tx_anchors = match self.txs.get(txid) {
-                        Some((_, anchors, _)) => anchors,
-                        None => return true,
-                    };
-                    let mut has_missing_height = false;
-                    for anchor_block in tx_anchors.iter().map(Anchor::anchor_block) {
-                        match chain.get(anchor_block.height) {
-                            None => {
-                                has_missing_height = true;
-                                continue;
-                            }
-                            Some(chain_cp) => {
-                                if chain_cp.hash() == anchor_block.hash {
-                                    return true;
-                                }
-                            }
-                        }
-                    }
-                    !has_missing_height
-                });
-                #[cfg(feature = "std")]
-                debug_assert!({
-                    println!("txid={} skip={}", txid, skip);
-                    true
-                });
-                !skip
-            })
-            .filter_map(move |(a, _)| {
-                let anchor_block = a.anchor_block();
-                if Some(anchor_block.height) != last_height_emitted
-                    && chain.get(anchor_block.height).is_none()
-                {
-                    last_height_emitted = Some(anchor_block.height);
-                    Some(anchor_block.height)
-                } else {
-                    None
-                }
-            })
-    }
-
     /// Get the position of the transaction in `chain` with tip `chain_tip`.
     ///
     /// Chain data is fetched from `chain`, a [`ChainOracle`] implementation.
@@ -1330,8 +1267,6 @@ impl<A> ChangeSet<A> {
     ///
     /// This is useful if you want to find which heights you need to fetch data about in order to
     /// confirm or exclude these anchors.
-    ///
-    /// See also: [`TxGraph::missing_heights`]
     pub fn anchor_heights(&self) -> impl Iterator<Item = u32> + '_
     where
         A: Anchor,
@@ -1346,24 +1281,6 @@ impl<A> ChangeSet<A> {
                 !duplicate
             })
     }
-
-    /// Returns an iterator for the [`anchor_heights`] in this changeset that are not included in
-    /// `local_chain`. This tells you which heights you need to include in `local_chain` in order
-    /// for it to conclusively act as a [`ChainOracle`] for the transaction anchors this changeset
-    /// will add.
-    ///
-    /// [`ChainOracle`]: crate::ChainOracle
-    /// [`anchor_heights`]: Self::anchor_heights
-    pub fn missing_heights_from<'a>(
-        &'a self,
-        local_chain: &'a LocalChain,
-    ) -> impl Iterator<Item = u32> + 'a
-    where
-        A: Anchor,
-    {
-        self.anchor_heights()
-            .filter(move |&height| local_chain.get(height).is_none())
-    }
 }
 
 impl<A: Ord> Append for ChangeSet<A> {
index 7940913ef1e4208622bcb8e15630142f82945114..1c7a90f72a3eaf760b9ddb6a71224f7734d19d7e 100644 (file)
@@ -1087,139 +1087,6 @@ fn update_last_seen_unconfirmed() {
     assert_eq!(graph.full_txs().next().unwrap().last_seen_unconfirmed, 2);
 }
 
-#[test]
-fn test_missing_blocks() {
-    /// An anchor implementation for testing, made up of `(the_anchor_block, random_data)`.
-    #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, core::hash::Hash)]
-    struct TestAnchor(BlockId);
-
-    impl Anchor for TestAnchor {
-        fn anchor_block(&self) -> BlockId {
-            self.0
-        }
-    }
-
-    struct Scenario<'a> {
-        name: &'a str,
-        graph: TxGraph<TestAnchor>,
-        chain: LocalChain,
-        exp_heights: &'a [u32],
-    }
-
-    const fn new_anchor(height: u32, hash: BlockHash) -> TestAnchor {
-        TestAnchor(BlockId { height, hash })
-    }
-
-    fn new_scenario<'a>(
-        name: &'a str,
-        graph_anchors: &'a [(Txid, TestAnchor)],
-        chain: &'a [(u32, BlockHash)],
-        exp_heights: &'a [u32],
-    ) -> Scenario<'a> {
-        Scenario {
-            name,
-            graph: {
-                let mut g = TxGraph::default();
-                for (txid, anchor) in graph_anchors {
-                    let _ = g.insert_anchor(*txid, anchor.clone());
-                }
-                g
-            },
-            chain: {
-                let (mut c, _) = LocalChain::from_genesis_hash(h!("genesis"));
-                for (height, hash) in chain {
-                    let _ = c.insert_block(BlockId {
-                        height: *height,
-                        hash: *hash,
-                    });
-                }
-                c
-            },
-            exp_heights,
-        }
-    }
-
-    fn run(scenarios: &[Scenario]) {
-        for scenario in scenarios {
-            let Scenario {
-                name,
-                graph,
-                chain,
-                exp_heights,
-            } = scenario;
-
-            let heights = graph.missing_heights(chain).collect::<Vec<_>>();
-            assert_eq!(&heights, exp_heights, "scenario: {}", name);
-        }
-    }
-
-    run(&[
-        new_scenario(
-            "2 txs with the same anchor (2:B) which is missing from chain",
-            &[
-                (h!("tx_1"), new_anchor(2, h!("B"))),
-                (h!("tx_2"), new_anchor(2, h!("B"))),
-            ],
-            &[(1, h!("A")), (3, h!("C"))],
-            &[2],
-        ),
-        new_scenario(
-            "2 txs with different anchors at the same height, one of the anchors is missing",
-            &[
-                (h!("tx_1"), new_anchor(2, h!("B1"))),
-                (h!("tx_2"), new_anchor(2, h!("B2"))),
-            ],
-            &[(1, h!("A")), (2, h!("B1"))],
-            &[],
-        ),
-        new_scenario(
-            "tx with 2 anchors of same height which are missing from the chain",
-            &[
-                (h!("tx"), new_anchor(3, h!("C1"))),
-                (h!("tx"), new_anchor(3, h!("C2"))),
-            ],
-            &[(1, h!("A")), (4, h!("D"))],
-            &[3],
-        ),
-        new_scenario(
-            "tx with 2 anchors at the same height, chain has this height but does not match either anchor",
-            &[
-                (h!("tx"), new_anchor(4, h!("D1"))),
-                (h!("tx"), new_anchor(4, h!("D2"))),
-            ],
-            &[(4, h!("D3")), (5, h!("E"))],
-            &[],
-        ),
-        new_scenario(
-            "tx with 2 anchors at different heights, one anchor exists in chain, should return nothing",
-            &[
-                (h!("tx"), new_anchor(3, h!("C"))),
-                (h!("tx"), new_anchor(4, h!("D"))),
-            ],
-            &[(4, h!("D")), (5, h!("E"))],
-            &[],
-        ),
-        new_scenario(
-            "tx with 2 anchors at different heights, first height is already in chain with different hash, iterator should only return 2nd height",
-            &[
-                (h!("tx"), new_anchor(5, h!("E1"))),
-                (h!("tx"), new_anchor(6, h!("F1"))),
-            ],
-            &[(4, h!("D")), (5, h!("E")), (7, h!("G"))],
-            &[6],
-        ),
-        new_scenario(
-            "tx with 2 anchors at different heights, neither height is in chain, both heights should be returned",
-            &[
-                (h!("tx"), new_anchor(3, h!("C"))),
-                (h!("tx"), new_anchor(4, h!("D"))),
-            ],
-            &[(1, h!("A")), (2, h!("B"))],
-            &[3, 4],
-        ),
-    ]);
-}
-
 #[test]
 /// The `map_anchors` allow a caller to pass a function to reconstruct the [`TxGraph`] with any [`Anchor`],
 /// even though the function is non-deterministic.