@@ -43,7 +43,10 @@ use bitcoin::blockdata::block::{Block, BlockHeader};
4343use bitcoin:: hash_types:: BlockHash ;
4444use bitcoin:: util:: uint:: Uint256 ;
4545
46+ use lightning:: chain:: ChainListener ;
47+
4648use std:: future:: Future ;
49+ use std:: ops:: Deref ;
4750use std:: pin:: Pin ;
4851
4952/// Abstract type for retrieving block headers and data.
@@ -155,24 +158,14 @@ pub struct BlockHeaderData {
155158/// custom cache eviction policy. This offers flexibility to those sensitive to resource usage.
156159/// Hence, there is a trade-off between a lower memory footprint and potentially increased network
157160/// 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 {
159163 chain_tip : ValidatedBlockHeader ,
160164 chain_poller : P ,
161165 chain_notifier : ChainNotifier < ' a , C > ,
162166 chain_listener : L ,
163167}
164168
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-
176169/// The `Cache` trait defines behavior for managing a block header cache, where block headers are
177170/// keyed by block hash.
178171///
@@ -215,7 +208,8 @@ impl Cache for UnboundedCache {
215208 }
216209}
217210
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 {
219213 /// Creates a new SPV client using `chain_tip` as the best known chain tip.
220214 ///
221215 /// 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> {
241235 ///
242236 /// Returns the best polled chain tip relative to the previous best known tip and whether any
243237 /// 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 {
245239 let chain_tip = self . chain_poller . poll_chain_tip ( self . chain_tip ) . await ?;
246240 let blocks_connected = match chain_tip {
247241 ChainTip :: Common => false ,
@@ -261,8 +255,8 @@ impl<'a, P: Poll, C: Cache, L: ChainListener> SpvClient<'a, P, C, L> {
261255
262256 /// Updates the chain tip, syncing the chain listener with any connected or disconnected
263257 /// 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 {
266260 Ok ( _) => {
267261 self . chain_tip = best_chain_tip;
268262 true
@@ -315,7 +309,7 @@ impl<'a, C: Cache> ChainNotifier<'a, C> {
315309 new_header : ValidatedBlockHeader ,
316310 old_header : & ValidatedBlockHeader ,
317311 chain_poller : & mut P ,
318- chain_listener : & mut L ,
312+ chain_listener : & L ,
319313 ) -> Result < ( ) , ( BlockSourceError , Option < ValidatedBlockHeader > ) > {
320314 let difference = self . find_difference ( new_header, old_header, chain_poller) . await
321315 . map_err ( |e| ( e, None ) ) ?;
@@ -383,7 +377,7 @@ impl<'a, C: Cache> ChainNotifier<'a, C> {
383377 fn disconnect_blocks < L : ChainListener > (
384378 & mut self ,
385379 mut disconnected_blocks : Vec < ValidatedBlockHeader > ,
386- chain_listener : & mut L ,
380+ chain_listener : & L ,
387381 ) {
388382 for header in disconnected_blocks. drain ( ..) {
389383 if let Some ( cached_header) = self . header_cache . block_disconnected ( & header. block_hash ) {
@@ -399,7 +393,7 @@ impl<'a, C: Cache> ChainNotifier<'a, C> {
399393 mut new_tip : ValidatedBlockHeader ,
400394 mut connected_blocks : Vec < ValidatedBlockHeader > ,
401395 chain_poller : & mut P ,
402- chain_listener : & mut L ,
396+ chain_listener : & L ,
403397 ) -> Result < ( ) , ( BlockSourceError , Option < ValidatedBlockHeader > ) > {
404398 for header in connected_blocks. drain ( ..) . rev ( ) {
405399 let block = chain_poller
@@ -430,7 +424,8 @@ mod spv_client_tests {
430424
431425 let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
432426 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) ;
434429 match client. poll_best_tip ( ) . await {
435430 Err ( e) => {
436431 assert_eq ! ( e. kind( ) , BlockSourceErrorKind :: Persistent ) ;
@@ -448,7 +443,8 @@ mod spv_client_tests {
448443
449444 let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
450445 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) ;
452448 match client. poll_best_tip ( ) . await {
453449 Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
454450 Ok ( ( chain_tip, blocks_connected) ) => {
@@ -467,7 +463,8 @@ mod spv_client_tests {
467463
468464 let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
469465 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) ;
471468 match client. poll_best_tip ( ) . await {
472469 Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
473470 Ok ( ( chain_tip, blocks_connected) ) => {
@@ -486,7 +483,8 @@ mod spv_client_tests {
486483
487484 let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
488485 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) ;
490488 match client. poll_best_tip ( ) . await {
491489 Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
492490 Ok ( ( chain_tip, blocks_connected) ) => {
@@ -505,7 +503,8 @@ mod spv_client_tests {
505503
506504 let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
507505 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) ;
509508 match client. poll_best_tip ( ) . await {
510509 Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
511510 Ok ( ( chain_tip, blocks_connected) ) => {
@@ -525,7 +524,8 @@ mod spv_client_tests {
525524
526525 let poller = poll:: ChainPoller :: new ( & mut chain, Network :: Testnet ) ;
527526 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) ;
529529 match client. poll_best_tip ( ) . await {
530530 Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
531531 Ok ( ( chain_tip, blocks_connected) ) => {
0 commit comments