1- use std:: { collections:: BTreeSet , io:: Write } ;
2-
31use anyhow:: Ok ;
42use bdk_esplora:: { esplora_client, EsploraAsyncExt } ;
53use bdk_wallet:: {
6- bitcoin:: { Amount , Network } ,
4+ bitcoin:: { Amount , Network , Txid } ,
75 rusqlite:: Connection ,
86 KeychainKind , SignOptions , Wallet ,
97} ;
8+ use std:: {
9+ collections:: { BTreeSet , HashSet } ,
10+ io:: Write ,
11+ } ;
1012
1113const SEND_AMOUNT : Amount = Amount :: from_sat ( 5000 ) ;
1214const STOP_GAP : usize = 5 ;
@@ -42,7 +44,7 @@ async fn main() -> Result<(), anyhow::Error> {
4244 let balance = wallet. balance ( ) ;
4345 println ! ( "Wallet balance before syncing: {}" , balance. total( ) ) ;
4446
45- print ! ( "Syncing... " ) ;
47+ println ! ( "=== Performing Full Sync === " ) ;
4648 let client = esplora_client:: Builder :: new ( ESPLORA_URL ) . build_async ( ) ?;
4749
4850 let request = wallet. start_full_scan ( ) . inspect ( {
@@ -66,7 +68,12 @@ async fn main() -> Result<(), anyhow::Error> {
6668 println ! ( ) ;
6769
6870 let balance = wallet. balance ( ) ;
69- println ! ( "Wallet balance after syncing: {}" , balance. total( ) ) ;
71+ println ! ( "Wallet balance after full sync: {}" , balance. total( ) ) ;
72+ println ! (
73+ "Wallet has {} transactions and {} utxos after full sync" ,
74+ wallet. transactions( ) . count( ) ,
75+ wallet. list_unspent( ) . count( )
76+ ) ;
7077
7178 if balance. total ( ) < SEND_AMOUNT {
7279 println ! ( "Please send at least {SEND_AMOUNT} to the receiving address" ) ;
@@ -84,5 +91,71 @@ async fn main() -> Result<(), anyhow::Error> {
8491 client. broadcast ( & tx) . await ?;
8592 println ! ( "Tx broadcasted! Txid: {}" , tx. compute_txid( ) ) ;
8693
94+ let unconfirmed_txids: HashSet < Txid > = wallet
95+ . transactions ( )
96+ . filter ( |tx| tx. chain_position . is_unconfirmed ( ) )
97+ . map ( |tx| tx. tx_node . txid )
98+ . collect ( ) ;
99+
100+ println ! ( "\n === Performing Partial Sync ===\n " ) ;
101+ print ! ( "SCANNING: " ) ;
102+ let mut printed = 0 ;
103+ let sync_request = wallet
104+ . start_sync_with_revealed_spks ( )
105+ . inspect ( move |_, sync_progress| {
106+ let progress_percent =
107+ ( 100 * sync_progress. consumed ( ) ) as f32 / sync_progress. total ( ) as f32 ;
108+ let progress_percent = progress_percent. round ( ) as u32 ;
109+ if progress_percent. is_multiple_of ( 5 ) && progress_percent > printed {
110+ print ! ( "{}% " , progress_percent) ;
111+ std:: io:: stdout ( ) . flush ( ) . expect ( "must flush" ) ;
112+ printed = progress_percent;
113+ }
114+ } ) ;
115+ let sync_update = client. sync ( sync_request, PARALLEL_REQUESTS ) . await ?;
116+ println ! ( ) ;
117+
118+ let mut evicted_txs = Vec :: new ( ) ;
119+ for txid in unconfirmed_txids {
120+ let tx_node = wallet
121+ . tx_graph ( )
122+ . full_txs ( )
123+ . find ( |full_tx| full_tx. txid == txid) ;
124+ let wallet_tx = wallet. get_tx ( txid) ;
125+
126+ let is_evicted = match wallet_tx {
127+ Some ( wallet_tx) => {
128+ !wallet_tx. chain_position . is_unconfirmed ( )
129+ && !wallet_tx. chain_position . is_confirmed ( )
130+ }
131+ None => true ,
132+ } ;
133+
134+ if is_evicted {
135+ if let Some ( full_tx) = tx_node {
136+ evicted_txs. push ( ( full_tx. txid , full_tx. last_seen . unwrap_or ( 0 ) ) ) ;
137+ } else {
138+ evicted_txs. push ( ( txid, 0 ) ) ;
139+ }
140+ }
141+ }
142+
143+ if !evicted_txs. is_empty ( ) {
144+ let evicted_count = evicted_txs. len ( ) ;
145+ wallet. apply_evicted_txs ( evicted_txs) ;
146+ println ! ( "Applied {evicted_count} evicted transactions" ) ;
147+ }
148+
149+ wallet. apply_update ( sync_update) ?;
150+ wallet. persist ( & mut conn) ?;
151+
152+ let balance_after_sync = wallet. balance ( ) ;
153+ println ! ( "Wallet balance after sync: {}" , balance_after_sync. total( ) ) ;
154+ println ! (
155+ "Wallet has {} transactions and {} utxos after partial sync" ,
156+ wallet. transactions( ) . count( ) ,
157+ wallet. list_unspent( ) . count( )
158+ ) ;
159+
87160 Ok ( ( ) )
88161}
0 commit comments