@@ -490,6 +490,118 @@ impl<P: Poll, CL: ChainListener> MicroSPVClient<P, CL> {
490
490
}
491
491
}
492
492
493
+ #[ cfg( test) ]
494
+ mod spv_client_tests {
495
+ use crate :: test_utils:: { Blockchain , NullChainListener } ;
496
+ use super :: * ;
497
+
498
+ use bitcoin:: network:: constants:: Network ;
499
+
500
+ #[ tokio:: test]
501
+ async fn poll_from_chain_without_headers ( ) {
502
+ let mut chain = Blockchain :: default ( ) . with_height ( 3 ) . without_headers ( ) ;
503
+ let best_tip = chain. at_height ( 1 ) ;
504
+
505
+ let poller = poller:: ChainPoller :: new ( & mut chain as & mut dyn BlockSource , Network :: Testnet ) ;
506
+ let mut client = MicroSPVClient :: init ( best_tip, poller, NullChainListener { } ) ;
507
+ match client. poll_best_tip ( ) . await {
508
+ Err ( e) => assert_eq ! ( e, BlockSourceError :: Persistent ) ,
509
+ Ok ( _) => panic ! ( "Expected error" ) ,
510
+ }
511
+ assert_eq ! ( client. chain_tip, best_tip) ;
512
+ }
513
+
514
+ #[ tokio:: test]
515
+ async fn poll_from_chain_with_common_tip ( ) {
516
+ let mut chain = Blockchain :: default ( ) . with_height ( 3 ) ;
517
+ let common_tip = chain. tip ( ) ;
518
+
519
+ let poller = poller:: ChainPoller :: new ( & mut chain as & mut dyn BlockSource , Network :: Testnet ) ;
520
+ let mut client = MicroSPVClient :: init ( common_tip, poller, NullChainListener { } ) ;
521
+ match client. poll_best_tip ( ) . await {
522
+ Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
523
+ Ok ( ( chain_tip, blocks_connected) ) => {
524
+ assert_eq ! ( chain_tip, ChainTip :: Common ) ;
525
+ assert ! ( !blocks_connected) ;
526
+ } ,
527
+ }
528
+ assert_eq ! ( client. chain_tip, common_tip) ;
529
+ }
530
+
531
+ #[ tokio:: test]
532
+ async fn poll_from_chain_with_better_tip ( ) {
533
+ let mut chain = Blockchain :: default ( ) . with_height ( 3 ) ;
534
+ let new_tip = chain. tip ( ) ;
535
+ let old_tip = chain. at_height ( 1 ) ;
536
+
537
+ let poller = poller:: ChainPoller :: new ( & mut chain as & mut dyn BlockSource , Network :: Testnet ) ;
538
+ let mut client = MicroSPVClient :: init ( old_tip, poller, NullChainListener { } ) ;
539
+ match client. poll_best_tip ( ) . await {
540
+ Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
541
+ Ok ( ( chain_tip, blocks_connected) ) => {
542
+ assert_eq ! ( chain_tip, ChainTip :: Better ( new_tip) ) ;
543
+ assert ! ( blocks_connected) ;
544
+ } ,
545
+ }
546
+ assert_eq ! ( client. chain_tip, new_tip) ;
547
+ }
548
+
549
+ #[ tokio:: test]
550
+ async fn poll_from_chain_with_better_tip_and_without_any_new_blocks ( ) {
551
+ let mut chain = Blockchain :: default ( ) . with_height ( 3 ) . without_blocks ( 2 ..) ;
552
+ let new_tip = chain. tip ( ) ;
553
+ let old_tip = chain. at_height ( 1 ) ;
554
+
555
+ let poller = poller:: ChainPoller :: new ( & mut chain as & mut dyn BlockSource , Network :: Testnet ) ;
556
+ let mut client = MicroSPVClient :: init ( old_tip, poller, NullChainListener { } ) ;
557
+ match client. poll_best_tip ( ) . await {
558
+ Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
559
+ Ok ( ( chain_tip, blocks_connected) ) => {
560
+ assert_eq ! ( chain_tip, ChainTip :: Better ( new_tip) ) ;
561
+ assert ! ( !blocks_connected) ;
562
+ } ,
563
+ }
564
+ assert_eq ! ( client. chain_tip, old_tip) ;
565
+ }
566
+
567
+ #[ tokio:: test]
568
+ async fn poll_from_chain_with_better_tip_and_without_some_new_blocks ( ) {
569
+ let mut chain = Blockchain :: default ( ) . with_height ( 3 ) . without_blocks ( 3 ..) ;
570
+ let new_tip = chain. tip ( ) ;
571
+ let old_tip = chain. at_height ( 1 ) ;
572
+
573
+ let poller = poller:: ChainPoller :: new ( & mut chain as & mut dyn BlockSource , Network :: Testnet ) ;
574
+ let mut client = MicroSPVClient :: init ( old_tip, poller, NullChainListener { } ) ;
575
+ match client. poll_best_tip ( ) . await {
576
+ Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
577
+ Ok ( ( chain_tip, blocks_connected) ) => {
578
+ assert_eq ! ( chain_tip, ChainTip :: Better ( new_tip) ) ;
579
+ assert ! ( blocks_connected) ;
580
+ } ,
581
+ }
582
+ assert_eq ! ( client. chain_tip, chain. at_height( 2 ) ) ;
583
+ }
584
+
585
+ #[ tokio:: test]
586
+ async fn poll_from_chain_with_worse_tip ( ) {
587
+ let mut chain = Blockchain :: default ( ) . with_height ( 3 ) ;
588
+ let best_tip = chain. tip ( ) ;
589
+ chain. disconnect_tip ( ) ;
590
+ let worse_tip = chain. tip ( ) ;
591
+
592
+ let poller = poller:: ChainPoller :: new ( & mut chain as & mut dyn BlockSource , Network :: Testnet ) ;
593
+ let mut client = MicroSPVClient :: init ( best_tip, poller, NullChainListener { } ) ;
594
+ match client. poll_best_tip ( ) . await {
595
+ Err ( e) => panic ! ( "Unexpected error: {:?}" , e) ,
596
+ Ok ( ( chain_tip, blocks_connected) ) => {
597
+ assert_eq ! ( chain_tip, ChainTip :: Worse ( worse_tip) ) ;
598
+ assert ! ( !blocks_connected) ;
599
+ } ,
600
+ }
601
+ assert_eq ! ( client. chain_tip, best_tip) ;
602
+ }
603
+ }
604
+
493
605
#[ cfg( test) ]
494
606
mod chain_notifier_tests {
495
607
use crate :: test_utils:: { Blockchain , MockChainListener } ;
0 commit comments