@@ -6,24 +6,24 @@ use crate::{AsyncBlockSourceResult, BlockData, BlockSource, BlockSourceError};
6
6
7
7
use bitcoin:: blockdata:: block:: Block ;
8
8
use bitcoin:: blockdata:: constants:: ChainHash ;
9
- use bitcoin:: blockdata:: transaction:: { TxOut , OutPoint } ;
9
+ use bitcoin:: blockdata:: transaction:: { OutPoint , TxOut } ;
10
10
use bitcoin:: hash_types:: BlockHash ;
11
11
12
12
use lightning:: sign:: NodeSigner ;
13
13
14
- use lightning:: ln:: peer_handler:: { CustomMessageHandler , PeerManager , SocketDescriptor } ;
15
14
use lightning:: ln:: msgs:: { ChannelMessageHandler , OnionMessageHandler } ;
15
+ use lightning:: ln:: peer_handler:: { CustomMessageHandler , PeerManager , SocketDescriptor } ;
16
16
17
17
use lightning:: routing:: gossip:: { NetworkGraph , P2PGossipSync } ;
18
- use lightning:: routing:: utxo:: { UtxoFuture , UtxoLookup , UtxoResult , UtxoLookupError } ;
18
+ use lightning:: routing:: utxo:: { UtxoFuture , UtxoLookup , UtxoLookupError , UtxoResult } ;
19
19
20
20
use lightning:: util:: logger:: Logger ;
21
21
22
- use std:: sync:: { Arc , Mutex } ;
23
22
use std:: collections:: VecDeque ;
24
23
use std:: future:: Future ;
25
24
use std:: ops:: Deref ;
26
25
use std:: pin:: Pin ;
26
+ use std:: sync:: { Arc , Mutex } ;
27
27
use std:: task:: Poll ;
28
28
29
29
/// A trait which extends [`BlockSource`] and can be queried to fetch the block at a given height
@@ -32,12 +32,14 @@ use std::task::Poll;
32
32
/// Note that while this is implementable for a [`BlockSource`] which returns filtered block data
33
33
/// (i.e. [`BlockData::HeaderOnly`] for [`BlockSource::get_block`] requests), such an
34
34
/// implementation will reject all gossip as it is not fully able to verify the UTXOs referenced.
35
- pub trait UtxoSource : BlockSource + ' static {
35
+ pub trait UtxoSource : BlockSource + ' static {
36
36
/// Fetches the block hash of the block at the given height.
37
37
///
38
38
/// This will, in turn, be passed to to [`BlockSource::get_block`] to fetch the block needed
39
39
/// for gossip validation.
40
- fn get_block_hash_by_height < ' a > ( & ' a self , block_height : u32 ) -> AsyncBlockSourceResult < ' a , BlockHash > ;
40
+ fn get_block_hash_by_height < ' a > (
41
+ & ' a self , block_height : u32 ,
42
+ ) -> AsyncBlockSourceResult < ' a , BlockHash > ;
41
43
42
44
/// Returns true if the given output has *not* been spent, i.e. is a member of the current UTXO
43
45
/// set.
@@ -48,7 +50,7 @@ pub trait UtxoSource : BlockSource + 'static {
48
50
///
49
51
/// If the `tokio` feature is enabled, this is implemented on `TokioSpawner` struct which
50
52
/// delegates to `tokio::spawn()`.
51
- pub trait FutureSpawner : Send + Sync + ' static {
53
+ pub trait FutureSpawner : Send + Sync + ' static {
52
54
/// Spawns the given future as a background task.
53
55
///
54
56
/// This method MUST NOT block on the given future immediately.
@@ -60,16 +62,14 @@ pub trait FutureSpawner : Send + Sync + 'static {
60
62
pub struct TokioSpawner ;
61
63
#[ cfg( feature = "tokio" ) ]
62
64
impl FutureSpawner for TokioSpawner {
63
- fn spawn < T : Future < Output = ( ) > + Send + ' static > ( & self , future : T ) {
64
- tokio:: spawn ( future) ;
65
- }
65
+ fn spawn < T : Future < Output = ( ) > + Send + ' static > ( & self , future : T ) { tokio:: spawn ( future) ; }
66
66
}
67
67
68
68
/// A trivial future which joins two other futures and polls them at the same time, returning only
69
69
/// once both complete.
70
70
pub ( crate ) struct Joiner <
71
- A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
72
- B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
71
+ A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
72
+ B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
73
73
> {
74
74
pub a : A ,
75
75
pub b : B ,
@@ -78,46 +78,45 @@ pub(crate) struct Joiner<
78
78
}
79
79
80
80
impl <
81
- A : Future < Output =Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
82
- B : Future < Output =Result < BlockHash , BlockSourceError > > + Unpin ,
83
- > Joiner < A , B > {
81
+ A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
82
+ B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
83
+ > Joiner < A , B >
84
+ {
84
85
fn new ( a : A , b : B ) -> Self { Self { a, b, a_res : None , b_res : None } }
85
86
}
86
87
87
88
impl <
88
- A : Future < Output =Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
89
- B : Future < Output =Result < BlockHash , BlockSourceError > > + Unpin ,
90
- > Future for Joiner < A , B > {
89
+ A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
90
+ B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
91
+ > Future for Joiner < A , B >
92
+ {
91
93
type Output = Result < ( ( BlockHash , Option < u32 > ) , BlockHash ) , BlockSourceError > ;
92
94
fn poll ( mut self : Pin < & mut Self > , ctx : & mut core:: task:: Context < ' _ > ) -> Poll < Self :: Output > {
93
95
if self . a_res . is_none ( ) {
94
96
match Pin :: new ( & mut self . a ) . poll ( ctx) {
95
- Poll :: Ready ( res) => {
97
+ Poll :: Ready ( res) =>
96
98
if let Ok ( ok) = res {
97
99
self . a_res = Some ( ok) ;
98
100
} else {
99
101
return Poll :: Ready ( Err ( res. unwrap_err ( ) ) ) ;
100
- }
101
- } ,
102
+ } ,
102
103
Poll :: Pending => { } ,
103
104
}
104
105
}
105
106
if self . b_res . is_none ( ) {
106
107
match Pin :: new ( & mut self . b ) . poll ( ctx) {
107
- Poll :: Ready ( res) => {
108
+ Poll :: Ready ( res) =>
108
109
if let Ok ( ok) = res {
109
110
self . b_res = Some ( ok) ;
110
111
} else {
111
112
return Poll :: Ready ( Err ( res. unwrap_err ( ) ) ) ;
112
- }
113
-
114
- } ,
113
+ } ,
115
114
Poll :: Pending => { } ,
116
115
}
117
116
}
118
117
if let Some ( b_res) = self . b_res {
119
118
if let Some ( a_res) = self . a_res {
120
- return Poll :: Ready ( Ok ( ( a_res, b_res) ) )
119
+ return Poll :: Ready ( Ok ( ( a_res, b_res) ) ) ;
121
120
}
122
121
}
123
122
Poll :: Pending
@@ -132,7 +131,8 @@ impl<
132
131
/// value of 1024 should more than suffice), and ensure you have sufficient file descriptors
133
132
/// available on both Bitcoin Core and your LDK application for each request to hold its own
134
133
/// connection.
135
- pub struct GossipVerifier < S : FutureSpawner ,
134
+ pub struct GossipVerifier <
135
+ S : FutureSpawner ,
136
136
Blocks : Deref + Send + Sync + ' static + Clone ,
137
137
L : Deref + Send + Sync + ' static ,
138
138
Descriptor : SocketDescriptor + Send + Sync + ' static ,
@@ -149,23 +149,35 @@ pub struct GossipVerifier<S: FutureSpawner,
149
149
NS :: Target : NodeSigner ,
150
150
{
151
151
source : Blocks ,
152
- peer_manager : Arc < PeerManager < Descriptor , CM , Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > , OM , L , CMH , NS > > ,
152
+ peer_manager : Arc <
153
+ PeerManager <
154
+ Descriptor ,
155
+ CM ,
156
+ Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > ,
157
+ OM ,
158
+ L ,
159
+ CMH ,
160
+ NS ,
161
+ > ,
162
+ > ,
153
163
gossiper : Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > ,
154
164
spawn : S ,
155
165
block_cache : Arc < Mutex < VecDeque < ( u32 , Block ) > > > ,
156
166
}
157
167
158
168
const BLOCK_CACHE_SIZE : usize = 5 ;
159
169
160
- impl < S : FutureSpawner ,
161
- Blocks : Deref + Send + Sync + Clone ,
162
- L : Deref + Send + Sync ,
163
- Descriptor : SocketDescriptor + Send + Sync ,
164
- CM : Deref + Send + Sync ,
165
- OM : Deref + Send + Sync ,
166
- CMH : Deref + Send + Sync ,
167
- NS : Deref + Send + Sync ,
168
- > GossipVerifier < S , Blocks , L , Descriptor , CM , OM , CMH , NS > where
170
+ impl <
171
+ S : FutureSpawner ,
172
+ Blocks : Deref + Send + Sync + Clone ,
173
+ L : Deref + Send + Sync ,
174
+ Descriptor : SocketDescriptor + Send + Sync ,
175
+ CM : Deref + Send + Sync ,
176
+ OM : Deref + Send + Sync ,
177
+ CMH : Deref + Send + Sync ,
178
+ NS : Deref + Send + Sync ,
179
+ > GossipVerifier < S , Blocks , L , Descriptor , CM , OM , CMH , NS >
180
+ where
169
181
Blocks :: Target : UtxoSource ,
170
182
L :: Target : Logger ,
171
183
CM :: Target : ChannelMessageHandler ,
@@ -177,25 +189,42 @@ impl<S: FutureSpawner,
177
189
///
178
190
/// This is expected to be given to a [`P2PGossipSync`] (initially constructed with `None` for
179
191
/// the UTXO lookup) via [`P2PGossipSync::add_utxo_lookup`].
180
- pub fn new ( source : Blocks , spawn : S , gossiper : Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > , peer_manager : Arc < PeerManager < Descriptor , CM , Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > , OM , L , CMH , NS > > ) -> Self {
192
+ pub fn new (
193
+ source : Blocks , spawn : S , gossiper : Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > ,
194
+ peer_manager : Arc <
195
+ PeerManager <
196
+ Descriptor ,
197
+ CM ,
198
+ Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > ,
199
+ OM ,
200
+ L ,
201
+ CMH ,
202
+ NS ,
203
+ > ,
204
+ > ,
205
+ ) -> Self {
181
206
Self {
182
- source, spawn, gossiper, peer_manager,
207
+ source,
208
+ spawn,
209
+ gossiper,
210
+ peer_manager,
183
211
block_cache : Arc :: new ( Mutex :: new ( VecDeque :: with_capacity ( BLOCK_CACHE_SIZE ) ) ) ,
184
212
}
185
213
}
186
214
187
215
async fn retrieve_utxo (
188
- source : Blocks , block_cache : Arc < Mutex < VecDeque < ( u32 , Block ) > > > , short_channel_id : u64
216
+ source : Blocks , block_cache : Arc < Mutex < VecDeque < ( u32 , Block ) > > > , short_channel_id : u64 ,
189
217
) -> Result < TxOut , UtxoLookupError > {
190
218
let block_height = ( short_channel_id >> 5 * 8 ) as u32 ; // block height is most significant three bytes
191
219
let transaction_index = ( ( short_channel_id >> 2 * 8 ) & 0xffffff ) as u32 ;
192
220
let output_index = ( short_channel_id & 0xffff ) as u16 ;
193
221
194
222
let ( outpoint, output) ;
195
223
196
- ' tx_found: loop { // Used as a simple goto
224
+ ' tx_found: loop {
225
+ // Used as a simple goto
197
226
macro_rules! process_block {
198
- ( $block: expr) => { {
227
+ ( $block: expr) => { {
199
228
if transaction_index as usize >= $block. txdata. len( ) {
200
229
return Err ( UtxoLookupError :: UnknownTx ) ;
201
230
}
@@ -206,7 +235,7 @@ impl<S: FutureSpawner,
206
235
207
236
outpoint = OutPoint :: new( transaction. txid( ) , output_index. into( ) ) ;
208
237
output = transaction. output[ output_index as usize ] . clone( ) ;
209
- } }
238
+ } } ;
210
239
}
211
240
{
212
241
let recent_blocks = block_cache. lock ( ) . unwrap ( ) ;
@@ -220,8 +249,8 @@ impl<S: FutureSpawner,
220
249
221
250
let ( ( _, tip_height_opt) , block_hash) =
222
251
Joiner :: new ( source. get_best_block ( ) , source. get_block_hash_by_height ( block_height) )
223
- . await
224
- . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
252
+ . await
253
+ . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
225
254
if let Some ( tip_height) = tip_height_opt {
226
255
// If the block doesn't yet have five confirmations, error out.
227
256
//
@@ -232,8 +261,8 @@ impl<S: FutureSpawner,
232
261
return Err ( UtxoLookupError :: UnknownTx ) ;
233
262
}
234
263
}
235
- let block_data = source . get_block ( & block_hash ) . await
236
- . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
264
+ let block_data =
265
+ source . get_block ( & block_hash ) . await . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
237
266
let block = match block_data {
238
267
BlockData :: HeaderOnly ( _) => return Err ( UtxoLookupError :: UnknownTx ) ,
239
268
BlockData :: FullBlock ( block) => block,
@@ -255,7 +284,7 @@ impl<S: FutureSpawner,
255
284
}
256
285
}
257
286
break ' tx_found;
258
- } ;
287
+ }
259
288
let outpoint_unspent =
260
289
source. is_output_unspent ( outpoint) . await . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
261
290
if outpoint_unspent {
@@ -266,15 +295,17 @@ impl<S: FutureSpawner,
266
295
}
267
296
}
268
297
269
- impl < S : FutureSpawner ,
270
- Blocks : Deref + Send + Sync + Clone ,
271
- L : Deref + Send + Sync ,
272
- Descriptor : SocketDescriptor + Send + Sync ,
273
- CM : Deref + Send + Sync ,
274
- OM : Deref + Send + Sync ,
275
- CMH : Deref + Send + Sync ,
276
- NS : Deref + Send + Sync ,
277
- > Deref for GossipVerifier < S , Blocks , L , Descriptor , CM , OM , CMH , NS > where
298
+ impl <
299
+ S : FutureSpawner ,
300
+ Blocks : Deref + Send + Sync + Clone ,
301
+ L : Deref + Send + Sync ,
302
+ Descriptor : SocketDescriptor + Send + Sync ,
303
+ CM : Deref + Send + Sync ,
304
+ OM : Deref + Send + Sync ,
305
+ CMH : Deref + Send + Sync ,
306
+ NS : Deref + Send + Sync ,
307
+ > Deref for GossipVerifier < S , Blocks , L , Descriptor , CM , OM , CMH , NS >
308
+ where
278
309
Blocks :: Target : UtxoSource ,
279
310
L :: Target : Logger ,
280
311
CM :: Target : ChannelMessageHandler ,
@@ -286,16 +317,17 @@ impl<S: FutureSpawner,
286
317
fn deref ( & self ) -> & Self { self }
287
318
}
288
319
289
-
290
- impl < S : FutureSpawner ,
291
- Blocks : Deref + Send + Sync + Clone ,
292
- L : Deref + Send + Sync ,
293
- Descriptor : SocketDescriptor + Send + Sync ,
294
- CM : Deref + Send + Sync ,
295
- OM : Deref + Send + Sync ,
296
- CMH : Deref + Send + Sync ,
297
- NS : Deref + Send + Sync ,
298
- > UtxoLookup for GossipVerifier < S , Blocks , L , Descriptor , CM , OM , CMH , NS > where
320
+ impl <
321
+ S : FutureSpawner ,
322
+ Blocks : Deref + Send + Sync + Clone ,
323
+ L : Deref + Send + Sync ,
324
+ Descriptor : SocketDescriptor + Send + Sync ,
325
+ CM : Deref + Send + Sync ,
326
+ OM : Deref + Send + Sync ,
327
+ CMH : Deref + Send + Sync ,
328
+ NS : Deref + Send + Sync ,
329
+ > UtxoLookup for GossipVerifier < S , Blocks , L , Descriptor , CM , OM , CMH , NS >
330
+ where
299
331
Blocks :: Target : UtxoSource ,
300
332
L :: Target : Logger ,
301
333
CM :: Target : ChannelMessageHandler ,
0 commit comments