15
15
16
16
#![ deny( rustdoc:: broken_intra_doc_links) ]
17
17
#![ deny( rustdoc:: private_intra_doc_links) ]
18
-
19
18
#![ deny( missing_docs) ]
20
19
#![ deny( unsafe_code) ]
21
-
22
20
#![ cfg_attr( docsrs, feature( doc_auto_cfg) ) ]
23
21
24
22
#[ cfg( any( feature = "rest-client" , feature = "rpc-client" ) ) ]
@@ -58,18 +56,21 @@ use std::ops::Deref;
58
56
use std:: pin:: Pin ;
59
57
60
58
/// Abstract type for retrieving block headers and data.
61
- pub trait BlockSource : Sync + Send {
59
+ pub trait BlockSource : Sync + Send {
62
60
/// Returns the header for a given hash. A height hint may be provided in case a block source
63
61
/// cannot easily find headers based on a hash. This is merely a hint and thus the returned
64
62
/// header must have the same hash as was requested. Otherwise, an error must be returned.
65
63
///
66
64
/// Implementations that cannot find headers based on the hash should return a `Transient` error
67
65
/// when `height_hint` is `None`.
68
- fn get_header < ' a > ( & ' a self , header_hash : & ' a BlockHash , height_hint : Option < u32 > ) -> AsyncBlockSourceResult < ' a , BlockHeaderData > ;
66
+ fn get_header < ' a > (
67
+ & ' a self , header_hash : & ' a BlockHash , height_hint : Option < u32 > ,
68
+ ) -> AsyncBlockSourceResult < ' a , BlockHeaderData > ;
69
69
70
70
/// Returns the block for a given hash. A headers-only block source should return a `Transient`
71
71
/// error.
72
- fn get_block < ' a > ( & ' a self , header_hash : & ' a BlockHash ) -> AsyncBlockSourceResult < ' a , BlockData > ;
72
+ fn get_block < ' a > ( & ' a self , header_hash : & ' a BlockHash )
73
+ -> AsyncBlockSourceResult < ' a , BlockData > ;
73
74
74
75
/// Returns the hash of the best block and, optionally, its height.
75
76
///
@@ -86,7 +87,8 @@ pub type BlockSourceResult<T> = Result<T, BlockSourceError>;
86
87
// TODO: Replace with BlockSourceResult once `async` trait functions are supported. For details,
87
88
// see: https://areweasyncyet.rs.
88
89
/// Result type for asynchronous `BlockSource` requests.
89
- pub type AsyncBlockSourceResult < ' a , T > = Pin < Box < dyn Future < Output = BlockSourceResult < T > > + ' a + Send > > ;
90
+ pub type AsyncBlockSourceResult < ' a , T > =
91
+ Pin < Box < dyn Future < Output = BlockSourceResult < T > > + ' a + Send > > ;
90
92
91
93
/// Error type for `BlockSource` requests.
92
94
///
@@ -111,20 +113,18 @@ pub enum BlockSourceErrorKind {
111
113
impl BlockSourceError {
112
114
/// Creates a new persistent error originated from the given error.
113
115
pub fn persistent < E > ( error : E ) -> Self
114
- where E : Into < Box < dyn std:: error:: Error + Send + Sync > > {
115
- Self {
116
- kind : BlockSourceErrorKind :: Persistent ,
117
- error : error. into ( ) ,
118
- }
116
+ where
117
+ E : Into < Box < dyn std:: error:: Error + Send + Sync > > ,
118
+ {
119
+ Self { kind : BlockSourceErrorKind :: Persistent , error : error. into ( ) }
119
120
}
120
121
121
122
/// Creates a new transient error originated from the given error.
122
123
pub fn transient < E > ( error : E ) -> Self
123
- where E : Into < Box < dyn std:: error:: Error + Send + Sync > > {
124
- Self {
125
- kind : BlockSourceErrorKind :: Transient ,
126
- error : error. into ( ) ,
127
- }
124
+ where
125
+ E : Into < Box < dyn std:: error:: Error + Send + Sync > > ,
126
+ {
127
+ Self { kind : BlockSourceErrorKind :: Transient , error : error. into ( ) }
128
128
}
129
129
130
130
/// Returns the kind of error.
@@ -180,7 +180,9 @@ pub enum BlockData {
180
180
/// Hence, there is a trade-off between a lower memory footprint and potentially increased network
181
181
/// I/O as headers are re-fetched during fork detection.
182
182
pub struct SpvClient < ' a , P : Poll , C : Cache , L : Deref >
183
- where L :: Target : chain:: Listen {
183
+ where
184
+ L :: Target : chain:: Listen ,
185
+ {
184
186
chain_tip : ValidatedBlockHeader ,
185
187
chain_poller : P ,
186
188
chain_notifier : ChainNotifier < ' a , C , L > ,
@@ -226,7 +228,10 @@ impl Cache for UnboundedCache {
226
228
}
227
229
}
228
230
229
- impl < ' a , P : Poll , C : Cache , L : Deref > SpvClient < ' a , P , C , L > where L :: Target : chain:: Listen {
231
+ impl < ' a , P : Poll , C : Cache , L : Deref > SpvClient < ' a , P , C , L >
232
+ where
233
+ L :: Target : chain:: Listen ,
234
+ {
230
235
/// Creates a new SPV client using `chain_tip` as the best known chain tip.
231
236
///
232
237
/// Subsequent calls to [`poll_best_tip`] will poll for the best chain tip using the given chain
@@ -238,9 +243,7 @@ impl<'a, P: Poll, C: Cache, L: Deref> SpvClient<'a, P, C, L> where L::Target: ch
238
243
///
239
244
/// [`poll_best_tip`]: SpvClient::poll_best_tip
240
245
pub fn new (
241
- chain_tip : ValidatedBlockHeader ,
242
- chain_poller : P ,
243
- header_cache : & ' a mut C ,
246
+ chain_tip : ValidatedBlockHeader , chain_poller : P , header_cache : & ' a mut C ,
244
247
chain_listener : L ,
245
248
) -> Self {
246
249
let chain_notifier = ChainNotifier { header_cache, chain_listener } ;
@@ -273,8 +276,10 @@ impl<'a, P: Poll, C: Cache, L: Deref> SpvClient<'a, P, C, L> where L::Target: ch
273
276
/// Updates the chain tip, syncing the chain listener with any connected or disconnected
274
277
/// blocks. Returns whether there were any such blocks.
275
278
async fn update_chain_tip ( & mut self , best_chain_tip : ValidatedBlockHeader ) -> bool {
276
- match self . chain_notifier . synchronize_listener (
277
- best_chain_tip, & self . chain_tip , & mut self . chain_poller ) . await
279
+ match self
280
+ . chain_notifier
281
+ . synchronize_listener ( best_chain_tip, & self . chain_tip , & mut self . chain_poller )
282
+ . await
278
283
{
279
284
Ok ( _) => {
280
285
self . chain_tip = best_chain_tip;
@@ -292,7 +297,10 @@ impl<'a, P: Poll, C: Cache, L: Deref> SpvClient<'a, P, C, L> where L::Target: ch
292
297
/// Notifies [listeners] of blocks that have been connected or disconnected from the chain.
293
298
///
294
299
/// [listeners]: lightning::chain::Listen
295
- pub struct ChainNotifier < ' a , C : Cache , L : Deref > where L :: Target : chain:: Listen {
300
+ pub struct ChainNotifier < ' a , C : Cache , L : Deref >
301
+ where
302
+ L :: Target : chain:: Listen ,
303
+ {
296
304
/// Cache for looking up headers before fetching from a block source.
297
305
header_cache : & ' a mut C ,
298
306
@@ -318,7 +326,10 @@ struct ChainDifference {
318
326
connected_blocks : Vec < ValidatedBlockHeader > ,
319
327
}
320
328
321
- impl < ' a , C : Cache , L : Deref > ChainNotifier < ' a , C , L > where L :: Target : chain:: Listen {
329
+ impl < ' a , C : Cache , L : Deref > ChainNotifier < ' a , C , L >
330
+ where
331
+ L :: Target : chain:: Listen ,
332
+ {
322
333
/// Finds the first common ancestor between `new_header` and `old_header`, disconnecting blocks
323
334
/// from `old_header` to get to that point and then connecting blocks until `new_header`.
324
335
///
@@ -327,29 +338,24 @@ impl<'a, C: Cache, L: Deref> ChainNotifier<'a, C, L> where L::Target: chain::Lis
327
338
/// ended up which may not be `new_header`. Note that the returned `Err` contains `Some` header
328
339
/// if and only if the transition from `old_header` to `new_header` is valid.
329
340
async fn synchronize_listener < P : Poll > (
330
- & mut self ,
331
- new_header : ValidatedBlockHeader ,
332
- old_header : & ValidatedBlockHeader ,
341
+ & mut self , new_header : ValidatedBlockHeader , old_header : & ValidatedBlockHeader ,
333
342
chain_poller : & mut P ,
334
343
) -> Result < ( ) , ( BlockSourceError , Option < ValidatedBlockHeader > ) > {
335
- let difference = self . find_difference ( new_header, old_header, chain_poller) . await
344
+ let difference = self
345
+ . find_difference ( new_header, old_header, chain_poller)
346
+ . await
336
347
. map_err ( |e| ( e, None ) ) ?;
337
348
self . disconnect_blocks ( difference. disconnected_blocks ) ;
338
- self . connect_blocks (
339
- difference. common_ancestor ,
340
- difference. connected_blocks ,
341
- chain_poller,
342
- ) . await
349
+ self . connect_blocks ( difference. common_ancestor , difference. connected_blocks , chain_poller)
350
+ . await
343
351
}
344
352
345
353
/// Returns the changes needed to produce the chain with `current_header` as its tip from the
346
354
/// chain with `prev_header` as its tip.
347
355
///
348
356
/// Walks backwards from `current_header` and `prev_header`, finding the common ancestor.
349
357
async fn find_difference < P : Poll > (
350
- & self ,
351
- current_header : ValidatedBlockHeader ,
352
- prev_header : & ValidatedBlockHeader ,
358
+ & self , current_header : ValidatedBlockHeader , prev_header : & ValidatedBlockHeader ,
353
359
chain_poller : & mut P ,
354
360
) -> BlockSourceResult < ChainDifference > {
355
361
let mut disconnected_blocks = Vec :: new ( ) ;
@@ -383,9 +389,7 @@ impl<'a, C: Cache, L: Deref> ChainNotifier<'a, C, L> where L::Target: chain::Lis
383
389
/// Returns the previous header for the given header, either by looking it up in the cache or
384
390
/// fetching it if not found.
385
391
async fn look_up_previous_header < P : Poll > (
386
- & self ,
387
- chain_poller : & mut P ,
388
- header : & ValidatedBlockHeader ,
392
+ & self , chain_poller : & mut P , header : & ValidatedBlockHeader ,
389
393
) -> BlockSourceResult < ValidatedBlockHeader > {
390
394
match self . header_cache . look_up ( & header. header . prev_blockhash ) {
391
395
Some ( prev_header) => Ok ( * prev_header) ,
@@ -405,16 +409,13 @@ impl<'a, C: Cache, L: Deref> ChainNotifier<'a, C, L> where L::Target: chain::Lis
405
409
406
410
/// Notifies the chain listeners of connected blocks.
407
411
async fn connect_blocks < P : Poll > (
408
- & mut self ,
409
- mut new_tip : ValidatedBlockHeader ,
410
- mut connected_blocks : Vec < ValidatedBlockHeader > ,
411
- chain_poller : & mut P ,
412
+ & mut self , mut new_tip : ValidatedBlockHeader ,
413
+ mut connected_blocks : Vec < ValidatedBlockHeader > , chain_poller : & mut P ,
412
414
) -> Result < ( ) , ( BlockSourceError , Option < ValidatedBlockHeader > ) > {
413
415
for header in connected_blocks. drain ( ..) . rev ( ) {
414
416
let height = header. height ;
415
- let block_data = chain_poller
416
- . fetch_block ( & header) . await
417
- . map_err ( |e| ( e, Some ( new_tip) ) ) ?;
417
+ let block_data =
418
+ chain_poller. fetch_block ( & header) . await . map_err ( |e| ( e, Some ( new_tip) ) ) ?;
418
419
debug_assert_eq ! ( block_data. block_hash, header. block_hash) ;
419
420
420
421
match block_data. deref ( ) {
@@ -436,8 +437,8 @@ impl<'a, C: Cache, L: Deref> ChainNotifier<'a, C, L> where L::Target: chain::Lis
436
437
437
438
#[ cfg( test) ]
438
439
mod spv_client_tests {
439
- use crate :: test_utils:: { Blockchain , NullChainListener } ;
440
440
use super :: * ;
441
+ use crate :: test_utils:: { Blockchain , NullChainListener } ;
441
442
442
443
use bitcoin:: network:: Network ;
443
444
@@ -563,8 +564,8 @@ mod spv_client_tests {
563
564
564
565
#[ cfg( test) ]
565
566
mod chain_notifier_tests {
566
- use crate :: test_utils:: { Blockchain , MockChainListener } ;
567
567
use super :: * ;
568
+ use crate :: test_utils:: { Blockchain , MockChainListener } ;
568
569
569
570
use bitcoin:: network:: Network ;
570
571
@@ -577,10 +578,8 @@ mod chain_notifier_tests {
577
578
let chain_listener = & MockChainListener :: new ( )
578
579
. expect_block_connected ( * chain. at_height ( 2 ) )
579
580
. expect_block_connected ( * new_tip) ;
580
- let mut notifier = ChainNotifier {
581
- header_cache : & mut chain. header_cache ( 0 ..=1 ) ,
582
- chain_listener,
583
- } ;
581
+ let mut notifier =
582
+ ChainNotifier { header_cache : & mut chain. header_cache ( 0 ..=1 ) , chain_listener } ;
584
583
let mut poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
585
584
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
586
585
Err ( ( e, _) ) => panic ! ( "Unexpected error: {:?}" , e) ,
@@ -596,10 +595,8 @@ mod chain_notifier_tests {
596
595
let new_tip = test_chain. tip ( ) ;
597
596
let old_tip = main_chain. tip ( ) ;
598
597
let chain_listener = & MockChainListener :: new ( ) ;
599
- let mut notifier = ChainNotifier {
600
- header_cache : & mut main_chain. header_cache ( 0 ..=1 ) ,
601
- chain_listener,
602
- } ;
598
+ let mut notifier =
599
+ ChainNotifier { header_cache : & mut main_chain. header_cache ( 0 ..=1 ) , chain_listener } ;
603
600
let mut poller = poll:: ChainPoller :: new ( & mut test_chain, Network :: Testnet ) ;
604
601
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
605
602
Err ( ( e, _) ) => {
@@ -620,10 +617,8 @@ mod chain_notifier_tests {
620
617
let chain_listener = & MockChainListener :: new ( )
621
618
. expect_block_disconnected ( * old_tip)
622
619
. expect_block_connected ( * new_tip) ;
623
- let mut notifier = ChainNotifier {
624
- header_cache : & mut main_chain. header_cache ( 0 ..=2 ) ,
625
- chain_listener,
626
- } ;
620
+ let mut notifier =
621
+ ChainNotifier { header_cache : & mut main_chain. header_cache ( 0 ..=2 ) , chain_listener } ;
627
622
let mut poller = poll:: ChainPoller :: new ( & mut fork_chain, Network :: Testnet ) ;
628
623
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
629
624
Err ( ( e, _) ) => panic ! ( "Unexpected error: {:?}" , e) ,
@@ -643,10 +638,8 @@ mod chain_notifier_tests {
643
638
. expect_block_disconnected ( * old_tip)
644
639
. expect_block_disconnected ( * main_chain. at_height ( 2 ) )
645
640
. expect_block_connected ( * new_tip) ;
646
- let mut notifier = ChainNotifier {
647
- header_cache : & mut main_chain. header_cache ( 0 ..=3 ) ,
648
- chain_listener,
649
- } ;
641
+ let mut notifier =
642
+ ChainNotifier { header_cache : & mut main_chain. header_cache ( 0 ..=3 ) , chain_listener } ;
650
643
let mut poller = poll:: ChainPoller :: new ( & mut fork_chain, Network :: Testnet ) ;
651
644
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
652
645
Err ( ( e, _) ) => panic ! ( "Unexpected error: {:?}" , e) ,
@@ -666,10 +659,8 @@ mod chain_notifier_tests {
666
659
. expect_block_disconnected ( * old_tip)
667
660
. expect_block_connected ( * fork_chain. at_height ( 2 ) )
668
661
. expect_block_connected ( * new_tip) ;
669
- let mut notifier = ChainNotifier {
670
- header_cache : & mut main_chain. header_cache ( 0 ..=2 ) ,
671
- chain_listener,
672
- } ;
662
+ let mut notifier =
663
+ ChainNotifier { header_cache : & mut main_chain. header_cache ( 0 ..=2 ) , chain_listener } ;
673
664
let mut poller = poll:: ChainPoller :: new ( & mut fork_chain, Network :: Testnet ) ;
674
665
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
675
666
Err ( ( e, _) ) => panic ! ( "Unexpected error: {:?}" , e) ,
@@ -684,10 +675,8 @@ mod chain_notifier_tests {
684
675
let new_tip = chain. tip ( ) ;
685
676
let old_tip = chain. at_height ( 1 ) ;
686
677
let chain_listener = & MockChainListener :: new ( ) ;
687
- let mut notifier = ChainNotifier {
688
- header_cache : & mut chain. header_cache ( 0 ..=1 ) ,
689
- chain_listener,
690
- } ;
678
+ let mut notifier =
679
+ ChainNotifier { header_cache : & mut chain. header_cache ( 0 ..=1 ) , chain_listener } ;
691
680
let mut poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
692
681
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
693
682
Err ( ( _, tip) ) => assert_eq ! ( tip, None ) ,
@@ -702,10 +691,8 @@ mod chain_notifier_tests {
702
691
let new_tip = chain. tip ( ) ;
703
692
let old_tip = chain. at_height ( 1 ) ;
704
693
let chain_listener = & MockChainListener :: new ( ) ;
705
- let mut notifier = ChainNotifier {
706
- header_cache : & mut chain. header_cache ( 0 ..=3 ) ,
707
- chain_listener,
708
- } ;
694
+ let mut notifier =
695
+ ChainNotifier { header_cache : & mut chain. header_cache ( 0 ..=3 ) , chain_listener } ;
709
696
let mut poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
710
697
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
711
698
Err ( ( _, tip) ) => assert_eq ! ( tip, Some ( old_tip) ) ,
@@ -719,12 +706,9 @@ mod chain_notifier_tests {
719
706
720
707
let new_tip = chain. tip ( ) ;
721
708
let old_tip = chain. at_height ( 1 ) ;
722
- let chain_listener = & MockChainListener :: new ( )
723
- . expect_block_connected ( * chain. at_height ( 2 ) ) ;
724
- let mut notifier = ChainNotifier {
725
- header_cache : & mut chain. header_cache ( 0 ..=3 ) ,
726
- chain_listener,
727
- } ;
709
+ let chain_listener = & MockChainListener :: new ( ) . expect_block_connected ( * chain. at_height ( 2 ) ) ;
710
+ let mut notifier =
711
+ ChainNotifier { header_cache : & mut chain. header_cache ( 0 ..=3 ) , chain_listener } ;
728
712
let mut poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
729
713
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
730
714
Err ( ( _, tip) ) => assert_eq ! ( tip, Some ( chain. at_height( 2 ) ) ) ,
@@ -741,15 +725,12 @@ mod chain_notifier_tests {
741
725
let chain_listener = & MockChainListener :: new ( )
742
726
. expect_filtered_block_connected ( * chain. at_height ( 2 ) )
743
727
. expect_filtered_block_connected ( * new_tip) ;
744
- let mut notifier = ChainNotifier {
745
- header_cache : & mut chain. header_cache ( 0 ..=1 ) ,
746
- chain_listener,
747
- } ;
728
+ let mut notifier =
729
+ ChainNotifier { header_cache : & mut chain. header_cache ( 0 ..=1 ) , chain_listener } ;
748
730
let mut poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
749
731
match notifier. synchronize_listener ( new_tip, & old_tip, & mut poller) . await {
750
732
Err ( ( e, _) ) => panic ! ( "Unexpected error: {:?}" , e) ,
751
733
Ok ( _) => { } ,
752
734
}
753
735
}
754
-
755
736
}
0 commit comments