|
1 | 1 | use anyhow::Result; |
2 | 2 | use bdk_chain::{ |
3 | | - bitcoin::{hashes::Hash, Address, Amount, ScriptBuf, WScriptHash}, |
| 3 | + bitcoin::{ |
| 4 | + constants::genesis_block, hashes::Hash, Address, Amount, Network, ScriptBuf, WScriptHash, |
| 5 | + }, |
4 | 6 | keychain::Balance, |
5 | 7 | local_chain::LocalChain, |
6 | 8 | ConfirmationTimeHeightAnchor, IndexedTxGraph, SpkTxOutIndex, |
7 | 9 | }; |
8 | 10 | use bdk_electrum::{ElectrumExt, ElectrumUpdate}; |
9 | 11 | use bdk_testenv::TestEnv; |
10 | 12 | use electrsd::bitcoind::bitcoincore_rpc::RpcApi; |
| 13 | +use std::str::FromStr; |
11 | 14 |
|
12 | 15 | fn get_balance( |
13 | 16 | recv_chain: &LocalChain, |
@@ -190,3 +193,58 @@ fn tx_can_become_unconfirmed_after_reorg() -> Result<()> { |
190 | 193 |
|
191 | 194 | Ok(()) |
192 | 195 | } |
| 196 | + |
| 197 | +#[test] |
| 198 | +fn test_last_seen_unconfirmed() -> Result<()> { |
| 199 | + use bdk_chain::ConfirmationHeightAnchor; |
| 200 | + let env = TestEnv::new()?; |
| 201 | + let client = electrum_client::Client::new(env.electrsd.electrum_url.as_str())?; |
| 202 | + |
| 203 | + // Setup receiver |
| 204 | + let addr = |
| 205 | + Address::from_str("bcrt1qj9f7r8r3p2y0sqf4r3r62qysmkuh0fzep473d2ar7rcz64wqvhssjgf0z4")? |
| 206 | + .assume_checked(); |
| 207 | + let spk = addr.script_pubkey(); |
| 208 | + let (chain, _) = LocalChain::from_genesis_hash(genesis_block(Network::Regtest).block_hash()); |
| 209 | + let mut graph = { |
| 210 | + let mut index = SpkTxOutIndex::<u32>::default(); |
| 211 | + index.insert_spk(0, addr.script_pubkey()); |
| 212 | + let graph = IndexedTxGraph::<ConfirmationHeightAnchor, _>::new(index); |
| 213 | + graph |
| 214 | + }; |
| 215 | + |
| 216 | + // Mine blocks |
| 217 | + let _ = env.mine_blocks(101, None)?; |
| 218 | + |
| 219 | + // Send tx and confirm it |
| 220 | + let amt = Amount::from_sat(10_000); |
| 221 | + let txid = env.send(&addr, amt)?; |
| 222 | + let _ = env.mine_blocks(1, None)?; |
| 223 | + |
| 224 | + // Sync. Last seen time should be 0 for confirmed tx |
| 225 | + env.wait_until_electrum_sees_block()?; |
| 226 | + let ElectrumUpdate { relevant_txids, .. } = |
| 227 | + client.sync(chain.tip(), [spk.clone()], None, None, 5)?; |
| 228 | + let missing = relevant_txids.missing_full_txs(graph.graph()); |
| 229 | + let graph_update = relevant_txids.into_tx_graph(&client, None, missing)?; |
| 230 | + let _ = graph.apply_update(graph_update); |
| 231 | + let tx = graph.graph().full_txs().next().unwrap(); |
| 232 | + assert_eq!(tx.txid, txid); |
| 233 | + assert_eq!(tx.last_seen_unconfirmed, 0); |
| 234 | + |
| 235 | + // Send tx 2 |
| 236 | + let txid = env.send(&addr, amt)?; |
| 237 | + |
| 238 | + // Mine empty block and sync. TxGraph should record last seen unconfirmed |
| 239 | + let _ = env.mine_empty_block(); |
| 240 | + env.wait_until_electrum_sees_block()?; |
| 241 | + let ElectrumUpdate { relevant_txids, .. } = client.sync(chain.tip(), [spk], None, None, 5)?; |
| 242 | + let missing = relevant_txids.missing_full_txs(graph.graph()); |
| 243 | + assert!(missing.contains(&txid)); |
| 244 | + let graph_update = relevant_txids.into_tx_graph(&client, Some(2), missing)?; |
| 245 | + let _ = graph.apply_update(graph_update); |
| 246 | + let tx = graph.graph().full_txs().find(|tx| tx.txid == txid).unwrap(); |
| 247 | + assert_eq!(tx.last_seen_unconfirmed, 2); |
| 248 | + |
| 249 | + Ok(()) |
| 250 | +} |
0 commit comments