@@ -6,21 +6,21 @@ 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:: ln:: peer_handler:: APeerManager ;
13
13
14
14
use lightning:: routing:: gossip:: { NetworkGraph , P2PGossipSync } ;
15
- use lightning:: routing:: utxo:: { UtxoFuture , UtxoLookup , UtxoResult , UtxoLookupError } ;
15
+ use lightning:: routing:: utxo:: { UtxoFuture , UtxoLookup , UtxoLookupError , UtxoResult } ;
16
16
17
17
use lightning:: util:: logger:: Logger ;
18
18
19
- use std:: sync:: { Arc , Mutex } ;
20
19
use std:: collections:: VecDeque ;
21
20
use std:: future:: Future ;
22
21
use std:: ops:: Deref ;
23
22
use std:: pin:: Pin ;
23
+ use std:: sync:: { Arc , Mutex } ;
24
24
use std:: task:: Poll ;
25
25
26
26
/// A trait which extends [`BlockSource`] and can be queried to fetch the block at a given height
@@ -29,12 +29,14 @@ use std::task::Poll;
29
29
/// Note that while this is implementable for a [`BlockSource`] which returns filtered block data
30
30
/// (i.e. [`BlockData::HeaderOnly`] for [`BlockSource::get_block`] requests), such an
31
31
/// implementation will reject all gossip as it is not fully able to verify the UTXOs referenced.
32
- pub trait UtxoSource : BlockSource + ' static {
32
+ pub trait UtxoSource : BlockSource + ' static {
33
33
/// Fetches the block hash of the block at the given height.
34
34
///
35
35
/// This will, in turn, be passed to to [`BlockSource::get_block`] to fetch the block needed
36
36
/// for gossip validation.
37
- fn get_block_hash_by_height < ' a > ( & ' a self , block_height : u32 ) -> AsyncBlockSourceResult < ' a , BlockHash > ;
37
+ fn get_block_hash_by_height < ' a > (
38
+ & ' a self , block_height : u32 ,
39
+ ) -> AsyncBlockSourceResult < ' a , BlockHash > ;
38
40
39
41
/// Returns true if the given output has *not* been spent, i.e. is a member of the current UTXO
40
42
/// set.
@@ -45,7 +47,7 @@ pub trait UtxoSource : BlockSource + 'static {
45
47
///
46
48
/// If the `tokio` feature is enabled, this is implemented on `TokioSpawner` struct which
47
49
/// delegates to `tokio::spawn()`.
48
- pub trait FutureSpawner : Send + Sync + ' static {
50
+ pub trait FutureSpawner : Send + Sync + ' static {
49
51
/// Spawns the given future as a background task.
50
52
///
51
53
/// This method MUST NOT block on the given future immediately.
@@ -65,8 +67,8 @@ impl FutureSpawner for TokioSpawner {
65
67
/// A trivial future which joins two other futures and polls them at the same time, returning only
66
68
/// once both complete.
67
69
pub ( crate ) struct Joiner <
68
- A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
69
- 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 ,
70
72
> {
71
73
pub a : A ,
72
74
pub b : B ,
@@ -75,16 +77,20 @@ pub(crate) struct Joiner<
75
77
}
76
78
77
79
impl <
78
- A : Future < Output =Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
79
- B : Future < Output =Result < BlockHash , BlockSourceError > > + Unpin ,
80
- > Joiner < A , B > {
81
- fn new ( a : A , b : B ) -> Self { Self { a, b, a_res : None , b_res : None } }
80
+ A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
81
+ B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
82
+ > Joiner < A , B >
83
+ {
84
+ fn new ( a : A , b : B ) -> Self {
85
+ Self { a, b, a_res : None , b_res : None }
86
+ }
82
87
}
83
88
84
89
impl <
85
- A : Future < Output =Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
86
- B : Future < Output =Result < BlockHash , BlockSourceError > > + Unpin ,
87
- > Future for Joiner < A , B > {
90
+ A : Future < Output = Result < ( BlockHash , Option < u32 > ) , BlockSourceError > > + Unpin ,
91
+ B : Future < Output = Result < BlockHash , BlockSourceError > > + Unpin ,
92
+ > Future for Joiner < A , B >
93
+ {
88
94
type Output = Result < ( ( BlockHash , Option < u32 > ) , BlockHash ) , BlockSourceError > ;
89
95
fn poll ( mut self : Pin < & mut Self > , ctx : & mut core:: task:: Context < ' _ > ) -> Poll < Self :: Output > {
90
96
if self . a_res . is_none ( ) {
@@ -107,14 +113,13 @@ impl<
107
113
} else {
108
114
return Poll :: Ready ( Err ( res. unwrap_err ( ) ) ) ;
109
115
}
110
-
111
116
} ,
112
117
Poll :: Pending => { } ,
113
118
}
114
119
}
115
120
if let Some ( b_res) = self . b_res {
116
121
if let Some ( a_res) = self . a_res {
117
- return Poll :: Ready ( Ok ( ( a_res, b_res) ) )
122
+ return Poll :: Ready ( Ok ( ( a_res, b_res) ) ) ;
118
123
}
119
124
}
120
125
Poll :: Pending
@@ -129,7 +134,8 @@ impl<
129
134
/// value of 1024 should more than suffice), and ensure you have sufficient file descriptors
130
135
/// available on both Bitcoin Core and your LDK application for each request to hold its own
131
136
/// connection.
132
- pub struct GossipVerifier < S : FutureSpawner ,
137
+ pub struct GossipVerifier <
138
+ S : FutureSpawner ,
133
139
Blocks : Deref + Send + Sync + ' static + Clone ,
134
140
L : Deref + Send + Sync + ' static ,
135
141
> where
@@ -145,10 +151,9 @@ pub struct GossipVerifier<S: FutureSpawner,
145
151
146
152
const BLOCK_CACHE_SIZE : usize = 5 ;
147
153
148
- impl < S : FutureSpawner ,
149
- Blocks : Deref + Send + Sync + Clone ,
150
- L : Deref + Send + Sync ,
151
- > GossipVerifier < S , Blocks , L > where
154
+ impl < S : FutureSpawner , Blocks : Deref + Send + Sync + Clone , L : Deref + Send + Sync >
155
+ GossipVerifier < S , Blocks , L >
156
+ where
152
157
Blocks :: Target : UtxoSource ,
153
158
L :: Target : Logger ,
154
159
{
@@ -157,27 +162,34 @@ impl<S: FutureSpawner,
157
162
/// This is expected to be given to a [`P2PGossipSync`] (initially constructed with `None` for
158
163
/// the UTXO lookup) via [`P2PGossipSync::add_utxo_lookup`].
159
164
pub fn new < APM : Deref + Send + Sync + Clone + ' static > (
160
- source : Blocks , spawn : S , gossiper : Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > , peer_manager : APM
161
- ) -> Self where APM :: Target : APeerManager {
165
+ source : Blocks , spawn : S , gossiper : Arc < P2PGossipSync < Arc < NetworkGraph < L > > , Self , L > > ,
166
+ peer_manager : APM ,
167
+ ) -> Self
168
+ where
169
+ APM :: Target : APeerManager ,
170
+ {
162
171
let peer_manager_wake = Arc :: new ( move || peer_manager. as_ref ( ) . process_events ( ) ) ;
163
172
Self {
164
- source, spawn, gossiper, peer_manager_wake,
173
+ source,
174
+ spawn,
175
+ gossiper,
176
+ peer_manager_wake,
165
177
block_cache : Arc :: new ( Mutex :: new ( VecDeque :: with_capacity ( BLOCK_CACHE_SIZE ) ) ) ,
166
178
}
167
179
}
168
180
169
181
async fn retrieve_utxo (
170
- source : Blocks , block_cache : Arc < Mutex < VecDeque < ( u32 , Block ) > > > , short_channel_id : u64
182
+ source : Blocks , block_cache : Arc < Mutex < VecDeque < ( u32 , Block ) > > > , short_channel_id : u64 ,
171
183
) -> Result < TxOut , UtxoLookupError > {
172
184
let block_height = ( short_channel_id >> 5 * 8 ) as u32 ; // block height is most significant three bytes
173
185
let transaction_index = ( ( short_channel_id >> 2 * 8 ) & 0xffffff ) as u32 ;
174
186
let output_index = ( short_channel_id & 0xffff ) as u16 ;
175
187
176
188
let ( outpoint, output) ;
177
189
178
- ' tx_found: loop { // Used as a simple goto
190
+ ' tx_found: loop {
179
191
macro_rules! process_block {
180
- ( $block: expr) => { {
192
+ ( $block: expr) => { {
181
193
if transaction_index as usize >= $block. txdata. len( ) {
182
194
return Err ( UtxoLookupError :: UnknownTx ) ;
183
195
}
@@ -188,7 +200,7 @@ impl<S: FutureSpawner,
188
200
189
201
outpoint = OutPoint :: new( transaction. txid( ) , output_index. into( ) ) ;
190
202
output = transaction. output[ output_index as usize ] . clone( ) ;
191
- } }
203
+ } } ;
192
204
}
193
205
{
194
206
let recent_blocks = block_cache. lock ( ) . unwrap ( ) ;
@@ -202,8 +214,8 @@ impl<S: FutureSpawner,
202
214
203
215
let ( ( _, tip_height_opt) , block_hash) =
204
216
Joiner :: new ( source. get_best_block ( ) , source. get_block_hash_by_height ( block_height) )
205
- . await
206
- . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
217
+ . await
218
+ . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
207
219
if let Some ( tip_height) = tip_height_opt {
208
220
// If the block doesn't yet have five confirmations, error out.
209
221
//
@@ -214,8 +226,8 @@ impl<S: FutureSpawner,
214
226
return Err ( UtxoLookupError :: UnknownTx ) ;
215
227
}
216
228
}
217
- let block_data = source . get_block ( & block_hash ) . await
218
- . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
229
+ let block_data =
230
+ source . get_block ( & block_hash ) . await . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
219
231
let block = match block_data {
220
232
BlockData :: HeaderOnly ( _) => return Err ( UtxoLookupError :: UnknownTx ) ,
221
233
BlockData :: FullBlock ( block) => block,
@@ -237,7 +249,7 @@ impl<S: FutureSpawner,
237
249
}
238
250
}
239
251
break ' tx_found;
240
- } ;
252
+ }
241
253
let outpoint_unspent =
242
254
source. is_output_unspent ( outpoint) . await . map_err ( |_| UtxoLookupError :: UnknownTx ) ?;
243
255
if outpoint_unspent {
@@ -248,22 +260,21 @@ impl<S: FutureSpawner,
248
260
}
249
261
}
250
262
251
- impl < S : FutureSpawner ,
252
- Blocks : Deref + Send + Sync + Clone ,
253
- L : Deref + Send + Sync ,
254
- > Deref for GossipVerifier < S , Blocks , L > where
263
+ impl < S : FutureSpawner , Blocks : Deref + Send + Sync + Clone , L : Deref + Send + Sync > Deref
264
+ for GossipVerifier < S , Blocks , L >
265
+ where
255
266
Blocks :: Target : UtxoSource ,
256
267
L :: Target : Logger ,
257
268
{
258
269
type Target = Self ;
259
- fn deref ( & self ) -> & Self { self }
270
+ fn deref ( & self ) -> & Self {
271
+ self
272
+ }
260
273
}
261
274
262
-
263
- impl < S : FutureSpawner ,
264
- Blocks : Deref + Send + Sync + Clone ,
265
- L : Deref + Send + Sync ,
266
- > UtxoLookup for GossipVerifier < S , Blocks , L > where
275
+ impl < S : FutureSpawner , Blocks : Deref + Send + Sync + Clone , L : Deref + Send + Sync > UtxoLookup
276
+ for GossipVerifier < S , Blocks , L >
277
+ where
267
278
Blocks :: Target : UtxoSource ,
268
279
L :: Target : Logger ,
269
280
{
0 commit comments