@@ -17,7 +17,7 @@ use bdk::{SignOptions, SyncOptions};
17
17
use bitcoin:: { BlockHash , Script , Transaction , Txid } ;
18
18
19
19
use std:: collections:: HashSet ;
20
- use std:: sync:: { Arc , Mutex , MutexGuard } ;
20
+ use std:: sync:: { Arc , Mutex } ;
21
21
22
22
/// The minimum feerate we are allowed to send, as specify by LDK.
23
23
const MIN_FEERATE : u32 = 253 ;
32
32
watched_transactions : Mutex < Vec < Txid > > ,
33
33
queued_outputs : Mutex < Vec < WatchedOutput > > ,
34
34
watched_outputs : Mutex < Vec < WatchedOutput > > ,
35
- last_sync_height : Mutex < Option < u32 > > ,
35
+ last_sync_height : tokio :: sync :: Mutex < Option < u32 > > ,
36
36
logger : Arc < FilesystemLogger > ,
37
37
}
38
38
48
48
let queued_transactions = Mutex :: new ( Vec :: new ( ) ) ;
49
49
let watched_outputs = Mutex :: new ( Vec :: new ( ) ) ;
50
50
let queued_outputs = Mutex :: new ( Vec :: new ( ) ) ;
51
- let last_sync_height = Mutex :: new ( None ) ;
51
+ let last_sync_height = tokio :: sync :: Mutex :: new ( None ) ;
52
52
Self {
53
53
blockchain,
54
54
wallet,
61
61
}
62
62
}
63
63
64
- pub ( crate ) fn sync_wallet ( & self ) -> Result < ( ) , Error > {
64
+ pub ( crate ) async fn sync_wallet ( & self ) -> Result < ( ) , Error > {
65
65
let sync_options = SyncOptions { progress : None } ;
66
66
67
67
self . wallet
@@ -73,73 +73,70 @@ where
73
73
Ok ( ( ) )
74
74
}
75
75
76
- pub ( crate ) fn sync ( & self , confirmables : Vec < & ( dyn Confirm + Sync ) > ) -> Result < ( ) , Error > {
76
+ pub ( crate ) async fn sync ( & self , confirmables : Vec < & ( dyn Confirm + Sync ) > ) -> Result < ( ) , Error > {
77
77
let client = & * self . blockchain ;
78
78
79
- let cur_height = client. get_height ( ) ?;
79
+ let cur_height = client. get_height ( ) . await ?;
80
80
81
- let mut locked_last_sync_height = self . last_sync_height . lock ( ) . unwrap ( ) ;
81
+ let mut locked_last_sync_height = self . last_sync_height . lock ( ) . await ;
82
82
if cur_height >= locked_last_sync_height. unwrap_or ( 0 ) {
83
- self . sync_best_block_updated (
84
- confirmables. clone ( ) ,
85
- cur_height,
86
- & mut locked_last_sync_height,
87
- ) ?;
88
- self . sync_transactions_confirmed ( confirmables. clone ( ) ) ?;
89
- self . sync_transaction_unconfirmed ( confirmables. clone ( ) ) ?;
83
+ self . sync_best_block_updated ( & confirmables, cur_height, & mut locked_last_sync_height)
84
+ . await ?;
85
+ self . sync_transactions_confirmed ( & confirmables) . await ?;
86
+ self . sync_transaction_unconfirmed ( & confirmables) . await ?;
90
87
}
91
88
// TODO: check whether new outputs have been registered by now and process them
92
89
Ok ( ( ) )
93
90
}
94
91
95
- fn sync_best_block_updated (
96
- & self , confirmables : Vec < & ( dyn Confirm + Sync ) > , cur_height : u32 ,
97
- locked_last_sync_height : & mut MutexGuard < Option < u32 > > ,
92
+ async fn sync_best_block_updated (
93
+ & self , confirmables : & Vec < & ( dyn Confirm + Sync ) > , cur_height : u32 ,
94
+ locked_last_sync_height : & mut tokio :: sync :: MutexGuard < ' _ , Option < u32 > > ,
98
95
) -> Result < ( ) , Error > {
99
96
let client = & * self . blockchain ;
100
97
101
98
// Inform the interface of the new block.
102
- let cur_block_header = client. get_header ( cur_height) ?;
103
- for c in & confirmables {
99
+ let cur_block_header = client. get_header ( cur_height) . await ?;
100
+ for c in confirmables {
104
101
c. best_block_updated ( & cur_block_header, cur_height) ;
105
102
}
106
103
107
104
* * locked_last_sync_height = Some ( cur_height) ;
108
105
Ok ( ( ) )
109
106
}
110
107
111
- fn sync_transactions_confirmed (
112
- & self , confirmables : Vec < & ( dyn Confirm + Sync ) > ,
108
+ async fn sync_transactions_confirmed (
109
+ & self , confirmables : & Vec < & ( dyn Confirm + Sync ) > ,
113
110
) -> Result < ( ) , Error > {
114
111
let client = & * self . blockchain ;
115
112
116
113
// First, check the confirmation status of registered transactions as well as the
117
114
// status of dependent transactions of registered outputs.
118
- let mut locked_queued_transactions = self . queued_transactions . lock ( ) . unwrap ( ) ;
119
- let mut locked_queued_outputs = self . queued_outputs . lock ( ) . unwrap ( ) ;
120
- let mut locked_watched_transactions = self . watched_transactions . lock ( ) . unwrap ( ) ;
121
- let mut locked_watched_outputs = self . watched_outputs . lock ( ) . unwrap ( ) ;
122
115
123
116
let mut confirmed_txs = Vec :: new ( ) ;
124
117
125
118
// Check in the current queue, as well as in registered transactions leftover from
126
119
// previous iterations.
127
- let registered_txs: HashSet < Txid > = locked_watched_transactions
128
- . iter ( )
129
- . chain ( locked_queued_transactions. iter ( ) )
130
- . cloned ( )
131
- . collect ( ) ;
120
+ let registered_txs: HashSet < Txid > = {
121
+ let locked_queued_transactions = self . queued_transactions . lock ( ) . unwrap ( ) ;
122
+ let locked_watched_transactions = self . watched_transactions . lock ( ) . unwrap ( ) ;
123
+ locked_watched_transactions
124
+ . iter ( )
125
+ . chain ( locked_queued_transactions. iter ( ) )
126
+ . cloned ( )
127
+ . collect ( )
128
+ } ;
132
129
133
130
// Remember all registered but unconfirmed transactions for future processing.
134
131
let mut unconfirmed_registered_txs = Vec :: new ( ) ;
135
132
136
133
for txid in registered_txs {
137
- if let Some ( tx_status) = client. get_tx_status ( & txid) ? {
134
+ if let Some ( tx_status) = client. get_tx_status ( & txid) . await ? {
138
135
if tx_status. confirmed {
139
- if let Some ( tx) = client. get_tx ( & txid) ? {
136
+ if let Some ( tx) = client. get_tx ( & txid) . await ? {
140
137
if let Some ( block_height) = tx_status. block_height {
141
- let block_header = client. get_header ( block_height) ?;
142
- if let Some ( merkle_proof) = client. get_merkle_proof ( & txid) ? {
138
+ let block_header = client. get_header ( block_height) . await ?;
139
+ if let Some ( merkle_proof) = client. get_merkle_proof ( & txid) . await ? {
143
140
confirmed_txs. push ( (
144
141
tx,
145
142
block_height,
@@ -156,25 +153,29 @@ where
156
153
}
157
154
158
155
// Check all registered outputs for dependent spending transactions.
159
- let registered_outputs: Vec < WatchedOutput > =
160
- locked_watched_outputs. iter ( ) . chain ( locked_queued_outputs. iter ( ) ) . cloned ( ) . collect ( ) ;
156
+ let registered_outputs: Vec < WatchedOutput > = {
157
+ let locked_queued_outputs = self . queued_outputs . lock ( ) . unwrap ( ) ;
158
+ let locked_watched_outputs = self . watched_outputs . lock ( ) . unwrap ( ) ;
159
+ locked_watched_outputs. iter ( ) . chain ( locked_queued_outputs. iter ( ) ) . cloned ( ) . collect ( )
160
+ } ;
161
161
162
162
// Remember all registered outputs that haven't been spent for future processing.
163
163
let mut unspent_registered_outputs = Vec :: new ( ) ;
164
164
165
165
for output in registered_outputs {
166
- if let Some ( output_status) =
167
- client. get_output_status ( & output. outpoint . txid , output. outpoint . index as u64 ) ?
166
+ if let Some ( output_status) = client
167
+ . get_output_status ( & output. outpoint . txid , output. outpoint . index as u64 )
168
+ . await ?
168
169
{
169
170
if output_status. spent {
170
171
if let Some ( spending_tx_status) = output_status. status {
171
172
if spending_tx_status. confirmed {
172
173
let spending_txid = output_status. txid . unwrap ( ) ;
173
- if let Some ( spending_tx) = client. get_tx ( & spending_txid) ? {
174
+ if let Some ( spending_tx) = client. get_tx ( & spending_txid) . await ? {
174
175
let block_height = spending_tx_status. block_height . unwrap ( ) ;
175
- let block_header = client. get_header ( block_height) ?;
176
+ let block_header = client. get_header ( block_height) . await ?;
176
177
if let Some ( merkle_proof) =
177
- client. get_merkle_proof ( & spending_txid) ?
178
+ client. get_merkle_proof ( & spending_txid) . await ?
178
179
{
179
180
confirmed_txs. push ( (
180
181
spending_tx,
@@ -200,41 +201,38 @@ where
200
201
} ,
201
202
) ;
202
203
for ( tx, block_height, block_header, pos) in confirmed_txs {
203
- for c in & confirmables {
204
+ for c in confirmables {
204
205
c. transactions_confirmed ( & block_header, & [ ( pos, & tx) ] , block_height) ;
205
206
}
206
207
}
207
208
208
- * locked_watched_transactions = unconfirmed_registered_txs ;
209
- * locked_queued_transactions = Vec :: new ( ) ;
210
- * locked_watched_outputs = unspent_registered_outputs ;
211
- * locked_queued_outputs = Vec :: new ( ) ;
209
+ * self . queued_transactions . lock ( ) . unwrap ( ) = Vec :: new ( ) ;
210
+ * self . watched_transactions . lock ( ) . unwrap ( ) = unconfirmed_registered_txs ;
211
+ * self . queued_outputs . lock ( ) . unwrap ( ) = Vec :: new ( ) ;
212
+ * self . watched_outputs . lock ( ) . unwrap ( ) = unspent_registered_outputs ;
212
213
213
214
Ok ( ( ) )
214
215
}
215
216
216
- fn sync_transaction_unconfirmed (
217
- & self , confirmables : Vec < & ( dyn Confirm + Sync ) > ,
217
+ async fn sync_transaction_unconfirmed (
218
+ & self , confirmables : & Vec < & ( dyn Confirm + Sync ) > ,
218
219
) -> Result < ( ) , Error > {
219
220
let client = & * self . blockchain ;
220
221
// Query the interface for relevant txids and check whether they have been
221
222
// reorged-out of the chain.
222
- let unconfirmed_txids = confirmables
223
- . iter ( )
224
- . flat_map ( |c| c. get_relevant_txids ( ) )
225
- . filter ( |txid| {
226
- client
227
- . get_tx_status ( txid)
228
- . ok ( )
229
- . unwrap_or ( None )
230
- . map_or ( true , |status| !status. confirmed )
231
- } )
232
- . collect :: < Vec < Txid > > ( ) ;
233
-
234
- // Mark all relevant unconfirmed transactions as unconfirmed.
235
- for txid in & unconfirmed_txids {
236
- for c in & confirmables {
237
- c. transaction_unconfirmed ( txid) ;
223
+ let relevant_txids =
224
+ confirmables. iter ( ) . flat_map ( |c| c. get_relevant_txids ( ) ) . collect :: < HashSet < Txid > > ( ) ;
225
+ for txid in relevant_txids {
226
+ let tx_unconfirmed = client
227
+ . get_tx_status ( & txid)
228
+ . await
229
+ . ok ( )
230
+ . unwrap_or ( None )
231
+ . map_or ( true , |status| !status. confirmed ) ;
232
+ if tx_unconfirmed {
233
+ for c in confirmables {
234
+ c. transaction_unconfirmed ( & txid) ;
235
+ }
238
236
}
239
237
}
240
238
0 commit comments