@@ -43,7 +43,10 @@ use bitcoin::blockdata::block::{Block, BlockHeader};
43
43
use bitcoin:: hash_types:: BlockHash ;
44
44
use bitcoin:: util:: uint:: Uint256 ;
45
45
46
+ use lightning:: chain:: ChainListener ;
47
+
46
48
use std:: future:: Future ;
49
+ use std:: ops:: Deref ;
47
50
use std:: pin:: Pin ;
48
51
49
52
/// Abstract type for retrieving block headers and data.
@@ -155,24 +158,14 @@ pub struct BlockHeaderData {
155
158
/// custom cache eviction policy. This offers flexibility to those sensitive to resource usage.
156
159
/// Hence, there is a trade-off between a lower memory footprint and potentially increased network
157
160
/// I/O as headers are re-fetched during fork detection.
158
- pub struct SpvClient < ' a , P : Poll , C : Cache , L : ChainListener > {
161
+ pub struct SpvClient < ' a , P : Poll , C : Cache , L : Deref >
162
+ where L :: Target : ChainListener {
159
163
chain_tip : ValidatedBlockHeader ,
160
164
chain_poller : P ,
161
165
chain_notifier : ChainNotifier < ' a , C > ,
162
166
chain_listener : L ,
163
167
}
164
168
165
- /// Adaptor used for notifying when blocks have been connected or disconnected from the chain.
166
- ///
167
- /// Used when needing to replay chain data upon startup or as new chain events occur.
168
- pub trait ChainListener {
169
- /// Notifies the listener that a block was added at the given height.
170
- fn block_connected ( & self , block : & Block , height : u32 ) ;
171
-
172
- /// Notifies the listener that a block was removed at the given height.
173
- fn block_disconnected ( & self , header : & BlockHeader , height : u32 ) ;
174
- }
175
-
176
169
/// The `Cache` trait defines behavior for managing a block header cache, where block headers are
177
170
/// keyed by block hash.
178
171
///
@@ -215,7 +208,8 @@ impl Cache for UnboundedCache {
215
208
}
216
209
}
217
210
218
- impl < ' a , P : Poll , C : Cache , L : ChainListener > SpvClient < ' a , P , C , L > {
211
+ impl < ' a , P : Poll , C : Cache , L : Deref > SpvClient < ' a , P , C , L >
212
+ where L :: Target : ChainListener {
219
213
/// Creates a new SPV client using `chain_tip` as the best known chain tip.
220
214
///
221
215
/// Subsequent calls to [`poll_best_tip`] will poll for the best chain tip using the given chain
@@ -241,7 +235,7 @@ impl<'a, P: Poll, C: Cache, L: ChainListener> SpvClient<'a, P, C, L> {
241
235
///
242
236
/// Returns the best polled chain tip relative to the previous best known tip and whether any
243
237
/// blocks were indeed connected or disconnected.
244
- pub async fn poll_best_tip ( & mut self ) -> BlockSourceResult < ( ChainTip , bool ) > {
238
+ pub async fn poll_best_tip ( & mut self ) -> BlockSourceResult < ( ChainTip , bool ) > where < L as std :: ops :: Deref > :: Target : std :: marker :: Sized {
245
239
let chain_tip = self . chain_poller . poll_chain_tip ( self . chain_tip ) . await ?;
246
240
let blocks_connected = match chain_tip {
247
241
ChainTip :: Common => false ,
@@ -261,8 +255,8 @@ impl<'a, P: Poll, C: Cache, L: ChainListener> SpvClient<'a, P, C, L> {
261
255
262
256
/// Updates the chain tip, syncing the chain listener with any connected or disconnected
263
257
/// blocks. Returns whether there were any such blocks.
264
- async fn update_chain_tip ( & mut self , best_chain_tip : ValidatedBlockHeader ) -> bool {
265
- match self . chain_notifier . sync_listener ( best_chain_tip, & self . chain_tip , & mut self . chain_poller , & mut self . chain_listener ) . await {
258
+ async fn update_chain_tip ( & mut self , best_chain_tip : ValidatedBlockHeader ) -> bool where < L as std :: ops :: Deref > :: Target : std :: marker :: Sized {
259
+ match self . chain_notifier . sync_listener ( best_chain_tip, & self . chain_tip , & mut self . chain_poller , & * self . chain_listener ) . await {
266
260
Ok ( _) => {
267
261
self . chain_tip = best_chain_tip;
268
262
true
@@ -315,7 +309,7 @@ impl<'a, C: Cache> ChainNotifier<'a, C> {
315
309
new_header : ValidatedBlockHeader ,
316
310
old_header : & ValidatedBlockHeader ,
317
311
chain_poller : & mut P ,
318
- chain_listener : & mut L ,
312
+ chain_listener : & L ,
319
313
) -> Result < ( ) , ( BlockSourceError , Option < ValidatedBlockHeader > ) > {
320
314
let difference = self . find_difference ( new_header, old_header, chain_poller) . await
321
315
. map_err ( |e| ( e, None ) ) ?;
@@ -383,7 +377,7 @@ impl<'a, C: Cache> ChainNotifier<'a, C> {
383
377
fn disconnect_blocks < L : ChainListener > (
384
378
& mut self ,
385
379
mut disconnected_blocks : Vec < ValidatedBlockHeader > ,
386
- chain_listener : & mut L ,
380
+ chain_listener : & L ,
387
381
) {
388
382
for header in disconnected_blocks. drain ( ..) {
389
383
if let Some ( cached_header) = self . header_cache . block_disconnected ( & header. block_hash ) {
@@ -399,7 +393,7 @@ impl<'a, C: Cache> ChainNotifier<'a, C> {
399
393
mut new_tip : ValidatedBlockHeader ,
400
394
mut connected_blocks : Vec < ValidatedBlockHeader > ,
401
395
chain_poller : & mut P ,
402
- chain_listener : & mut L ,
396
+ chain_listener : & L ,
403
397
) -> Result < ( ) , ( BlockSourceError , Option < ValidatedBlockHeader > ) > {
404
398
for header in connected_blocks. drain ( ..) . rev ( ) {
405
399
let block = chain_poller
@@ -430,7 +424,8 @@ mod spv_client_tests {
430
424
431
425
let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
432
426
let mut cache = UnboundedCache :: new ( ) ;
433
- let mut client = SpvClient :: new ( best_tip, poller, & mut cache, NullChainListener { } ) ;
427
+ let mut listener = NullChainListener { } ;
428
+ let mut client = SpvClient :: new ( best_tip, poller, & mut cache, & mut listener) ;
434
429
match client. poll_best_tip ( ) . await {
435
430
Err ( e) => {
436
431
assert_eq ! ( e. kind( ) , BlockSourceErrorKind :: Persistent ) ;
@@ -448,7 +443,8 @@ mod spv_client_tests {
448
443
449
444
let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
450
445
let mut cache = UnboundedCache :: new ( ) ;
451
- let mut client = SpvClient :: new ( common_tip, poller, & mut cache, NullChainListener { } ) ;
446
+ let mut listener = NullChainListener { } ;
447
+ let mut client = SpvClient :: new ( common_tip, poller, & mut cache, & mut listener) ;
452
448
match client. poll_best_tip ( ) . await {
453
449
Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
454
450
Ok ( ( chain_tip, blocks_connected) ) => {
@@ -467,7 +463,8 @@ mod spv_client_tests {
467
463
468
464
let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
469
465
let mut cache = UnboundedCache :: new ( ) ;
470
- let mut client = SpvClient :: new ( old_tip, poller, & mut cache, NullChainListener { } ) ;
466
+ let mut listener = NullChainListener { } ;
467
+ let mut client = SpvClient :: new ( old_tip, poller, & mut cache, & mut listener) ;
471
468
match client. poll_best_tip ( ) . await {
472
469
Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
473
470
Ok ( ( chain_tip, blocks_connected) ) => {
@@ -486,7 +483,8 @@ mod spv_client_tests {
486
483
487
484
let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
488
485
let mut cache = UnboundedCache :: new ( ) ;
489
- let mut client = SpvClient :: new ( old_tip, poller, & mut cache, NullChainListener { } ) ;
486
+ let mut listener = NullChainListener { } ;
487
+ let mut client = SpvClient :: new ( old_tip, poller, & mut cache, & mut listener) ;
490
488
match client. poll_best_tip ( ) . await {
491
489
Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
492
490
Ok ( ( chain_tip, blocks_connected) ) => {
@@ -505,7 +503,8 @@ mod spv_client_tests {
505
503
506
504
let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
507
505
let mut cache = UnboundedCache :: new ( ) ;
508
- let mut client = SpvClient :: new ( old_tip, poller, & mut cache, NullChainListener { } ) ;
506
+ let mut listener = NullChainListener { } ;
507
+ let mut client = SpvClient :: new ( old_tip, poller, & mut cache, & mut listener) ;
509
508
match client. poll_best_tip ( ) . await {
510
509
Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
511
510
Ok ( ( chain_tip, blocks_connected) ) => {
@@ -525,7 +524,8 @@ mod spv_client_tests {
525
524
526
525
let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
527
526
let mut cache = UnboundedCache :: new ( ) ;
528
- let mut client = SpvClient :: new ( best_tip, poller, & mut cache, NullChainListener { } ) ;
527
+ let mut listener = NullChainListener { } ;
528
+ let mut client = SpvClient :: new ( best_tip, poller, & mut cache, & mut listener) ;
529
529
match client. poll_best_tip ( ) . await {
530
530
Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
531
531
Ok ( ( chain_tip, blocks_connected) ) => {
0 commit comments