@@ -197,6 +197,80 @@ pub fn test_update_tx_graph_gap_limit() -> anyhow::Result<()> {
197197 Ok ( ( ) )
198198}
199199
200+ #[ test]
201+ fn test_last_seen_unconfirmed ( ) -> anyhow:: Result < ( ) > {
202+ use bdk_chain:: ConfirmationTimeHeightAnchor ;
203+ use bdk_chain:: IndexedTxGraph ;
204+ use bdk_chain:: SpkTxOutIndex ;
205+ let env = TestEnv :: new ( ) ?;
206+ let base_url = format ! ( "http://{}" , & env. electrsd. esplora_url. clone( ) . unwrap( ) ) ;
207+ let client = Builder :: new ( base_url. as_str ( ) ) . build_blocking ( ) ?;
208+
209+ // Setup receive graph
210+ let addr =
211+ Address :: from_str ( "bcrt1qj9f7r8r3p2y0sqf4r3r62qysmkuh0fzep473d2ar7rcz64wqvhssjgf0z4" )
212+ . unwrap ( )
213+ . assume_checked ( ) ;
214+ let spk = addr. script_pubkey ( ) ;
215+ let mut graph = {
216+ let mut index = SpkTxOutIndex :: < u32 > :: default ( ) ;
217+ index. insert_spk ( 0 , spk. clone ( ) ) ;
218+ let graph = IndexedTxGraph :: < ConfirmationTimeHeightAnchor , _ > :: new ( index) ;
219+ graph
220+ } ;
221+
222+ // Mine blocks
223+ let miner = env
224+ . rpc_client ( )
225+ . get_new_address ( None , None ) ?
226+ . assume_checked ( ) ;
227+ let _block_hashes = env. mine_blocks ( 100 , Some ( miner. clone ( ) ) ) ?;
228+ while client. get_height ( ) . unwrap ( ) < 101 {
229+ sleep ( Duration :: from_millis ( 10 ) )
230+ }
231+
232+ // Send tx
233+ let amt = Amount :: from_sat ( 10_000 ) ;
234+ let txid = env. send ( & addr, amt) ?;
235+
236+ // Mine empty block and sync. TxGraph should record last seen unconfirmed
237+ let _ = env. mine_empty_block ( ) ?;
238+ while client. get_height ( ) . unwrap ( ) < 102 {
239+ sleep ( Duration :: from_millis ( 10 ) )
240+ }
241+ let timestamp = 2 ;
242+ let graph_update = client. sync ( [ spk. clone ( ) ] , vec ! [ ] , vec ! [ ] , 1 , timestamp) ?;
243+ let changeset = graph. apply_update ( graph_update) ;
244+ assert ! ( changeset. graph. anchors. is_empty( ) ) ;
245+ let tx = graph. graph ( ) . full_txs ( ) . next ( ) ;
246+ assert ! ( tx. is_some( ) ) ;
247+ let tx = tx. unwrap ( ) ;
248+ assert_eq ! ( tx. txid, txid) ;
249+ assert_eq ! ( tx. last_seen_unconfirmed, timestamp) ;
250+
251+ // Time passes, graph should record the new timestamp
252+ let timestamp = 4 ;
253+ let graph_update = client. sync ( [ spk. clone ( ) ] , vec ! [ ] , vec ! [ ] , 1 , timestamp) ?;
254+ let _ = graph. apply_update ( graph_update) ;
255+ let tx = graph. graph ( ) . full_txs ( ) . next ( ) . unwrap ( ) ;
256+ let graph_last_seen = tx. last_seen_unconfirmed ;
257+ assert_eq ! ( graph_last_seen, timestamp) ;
258+
259+ // Now confirm it. When we sync at a later time, last seen is unchanged
260+ let _ = env. mine_blocks ( 1 , Some ( miner) ) ?;
261+ while client. get_height ( ) . unwrap ( ) < 103 {
262+ sleep ( Duration :: from_millis ( 10 ) )
263+ }
264+ let timestamp = 8 ;
265+ let graph_update = client. sync ( [ spk] , vec ! [ ] , vec ! [ ] , 1 , timestamp) ?;
266+ let changeset = graph. apply_update ( graph_update) ;
267+ assert ! ( changeset. graph. last_seen. is_empty( ) ) ;
268+ let tx = graph. graph ( ) . full_txs ( ) . find ( |tx| tx. txid == txid) . unwrap ( ) ;
269+ assert_eq ! ( tx. last_seen_unconfirmed, graph_last_seen) ;
270+
271+ Ok ( ( ) )
272+ }
273+
200274#[ test]
201275fn update_local_chain ( ) -> anyhow:: Result < ( ) > {
202276 const TIP_HEIGHT : u32 = 50 ;
0 commit comments