diff --git a/crates/chain/tests/test_tx_graph.rs b/crates/chain/tests/test_tx_graph.rs index 7533f6428..907fec27e 100644 --- a/crates/chain/tests/test_tx_graph.rs +++ b/crates/chain/tests/test_tx_graph.rs @@ -1118,6 +1118,44 @@ fn update_last_seen_unconfirmed() { ); } +#[test] +fn transactions_inserted_into_tx_graph_are_not_canonical_until_they_have_an_anchor_in_best_chain() { + let txs = vec![new_tx(0), new_tx(1)]; + let txids: Vec = txs.iter().map(Transaction::compute_txid).collect(); + + // graph + let mut graph = TxGraph::::new(txs); + let full_txs: Vec<_> = graph.full_txs().collect(); + assert_eq!(full_txs.len(), 2); + + // chain + let blocks: BTreeMap = [(0, h!("g")), (1, h!("A")), (2, h!("B"))] + .into_iter() + .collect(); + let chain = LocalChain::from_blocks(blocks).unwrap(); + let canonical_txs: Vec<_> = graph + .list_canonical_txs(&chain, chain.tip().block_id()) + .collect(); + assert!(canonical_txs.is_empty()); + + // tx0 with seen_at should be returned by canonical txs + let _ = graph.insert_seen_at(txids[0], 2); + let mut canonical_txs = graph.list_canonical_txs(&chain, chain.tip().block_id()); + assert_eq!( + canonical_txs.next().map(|tx| tx.tx_node.txid).unwrap(), + txids[0] + ); + drop(canonical_txs); + + // tx1 with anchor is also canonical + let _ = graph.insert_anchor(txids[1], block_id!(2, "B")); + let canonical_txids: Vec<_> = graph + .list_canonical_txs(&chain, chain.tip().block_id()) + .map(|tx| tx.tx_node.txid) + .collect(); + assert!(canonical_txids.contains(&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.