diff --git a/crates/chain/tests/test_tx_graph.rs b/crates/chain/tests/test_tx_graph.rs index b1edae41ab..f17e9b1325 100644 --- a/crates/chain/tests/test_tx_graph.rs +++ b/crates/chain/tests/test_tx_graph.rs @@ -1098,6 +1098,52 @@ fn update_last_seen_unconfirmed() { ); } +#[test] +fn list_canonical_txs() { + use bdk_chain::local_chain::CheckPoint; + let mut graph = TxGraph::::default(); + + // insert three new txs + // all graph transactions are present, but not canonical + let txs = vec![new_tx(0), new_tx(1), new_tx(2)]; + let txids: Vec<_> = txs.iter().map(Transaction::txid).collect(); + for tx in txs { + let _ = graph.insert_tx(tx); + } + let full_txs: Vec<_> = graph.full_txs().collect(); + assert_eq!(full_txs.len(), 3); + + let cp = CheckPoint::from_block_ids( + [(0, BlockHash::all_zeros()), (2, BlockHash::all_zeros())] + .into_iter() + .map(BlockId::from), + ) + .unwrap(); + let anchor: BlockId = cp.iter().next().unwrap().block_id(); + let chain = LocalChain::from_tip(cp).unwrap(); + + let canonical_txs: Vec<_> = graph + .canonical_transactions(&chain, chain.tip().block_id()) + .collect(); + assert!(canonical_txs.is_empty()); + + // insert seen_at for tx0, it should be returned by `canonical_transactions` + let _ = graph.insert_seen_at(txids[0], 0); + let canonical_txs: Vec<_> = graph + .canonical_transactions(&chain, chain.tip().block_id()) + .collect(); + assert_eq!(canonical_txs.len(), 1); + assert_eq!(canonical_txs.first().unwrap().tx_node.txid, txids[0]); + + // insert anchor for tx1, it is now also canonical + let _ = graph.insert_anchor(txids[1], anchor); + let canonical_txs: BTreeSet<_> = graph + .canonical_transactions(&chain, chain.tip().block_id()) + .collect(); + assert_eq!(canonical_txs.len(), 2); + assert_eq!(canonical_txs.first().unwrap().tx_node.txid, txids[1]); +} + #[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.