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