@@ -77,23 +77,58 @@ impl<NC: NeighborComms> StackerDBSync<NC> {
77
77
dbsync
78
78
}
79
79
80
- /// Coalesce a list of peers such that each one has a unique IP:port
81
- fn coalesce_peers_by_ipaddr ( peers : Vec < NeighborAddress > ) -> Vec < NeighborAddress > {
82
- // coalesce peers on the same host:port
83
- let mut same_host_port = HashSet :: new ( ) ;
84
- let unique_ip_peers: Vec < _ > = peers
80
+ /// Find stackerdb replicas and apply filtering rules
81
+ fn find_qualified_replicas (
82
+ & self ,
83
+ network : & PeerNetwork ,
84
+ ) -> Result < HashSet < NeighborAddress > , net_error > {
85
+ let mut found = HashSet :: new ( ) ;
86
+ let mut min_age =
87
+ get_epoch_time_secs ( ) . saturating_sub ( network. get_connection_opts ( ) . max_neighbor_age ) ;
88
+ while found. len ( ) < self . max_neighbors && min_age != 0 {
89
+ let peers_iter = PeerDB :: find_stacker_db_replicas (
90
+ network. peerdb_conn ( ) ,
91
+ network. get_local_peer ( ) . network_id ,
92
+ & self . smart_contract_id ,
93
+ min_age,
94
+ self . max_neighbors ,
95
+ ) ?
85
96
. into_iter ( )
86
- . filter_map ( |naddr| {
87
- if same_host_port. contains ( & naddr. addrbytes . to_socketaddr ( naddr. port ) ) {
88
- None
89
- } else {
90
- same_host_port. insert ( naddr. addrbytes . to_socketaddr ( naddr. port ) ) ;
91
- Some ( naddr)
92
- }
97
+ . map ( |neighbor| {
98
+ (
99
+ NeighborAddress :: from_neighbor ( & neighbor) ,
100
+ neighbor. last_contact_time ,
101
+ )
93
102
} )
94
- . collect ( ) ;
103
+ . filter ( |( naddr, _) | {
104
+ if naddr. addrbytes . is_anynet ( ) {
105
+ return false ;
106
+ }
107
+ if !network. get_connection_opts ( ) . private_neighbors
108
+ && naddr. addrbytes . is_in_private_range ( )
109
+ {
110
+ return false ;
111
+ }
112
+ true
113
+ } ) ;
114
+
115
+ for ( peer, last_contact) in peers_iter {
116
+ found. insert ( peer) ;
117
+ if found. len ( ) >= self . max_neighbors {
118
+ break ;
119
+ }
120
+ min_age = min_age. min ( last_contact) ;
121
+ }
95
122
96
- unique_ip_peers
123
+ // search for older neighbors
124
+ if min_age > 1 {
125
+ min_age = 1 ;
126
+ }
127
+ else if min_age == 1 {
128
+ min_age = 0 ;
129
+ }
130
+ }
131
+ Ok ( found)
97
132
}
98
133
99
134
/// Calculate the new set of replicas to contact.
@@ -108,24 +143,13 @@ impl<NC: NeighborComms> StackerDBSync<NC> {
108
143
// keep all connected replicas, and replenish from config hints and the DB as needed
109
144
let mut peers = config. hint_replicas . clone ( ) ;
110
145
if let Some ( network) = network {
111
- let extra_peers: Vec < _ > = PeerDB :: find_stacker_db_replicas (
112
- network. peerdb_conn ( ) ,
113
- network. get_local_peer ( ) . network_id ,
114
- & self . smart_contract_id ,
115
- get_epoch_time_secs ( )
116
- . saturating_sub ( network. get_connection_opts ( ) . max_neighbor_age ) ,
117
- self . max_neighbors ,
118
- ) ?
119
- . into_iter ( )
120
- . map ( |neighbor| NeighborAddress :: from_neighbor ( & neighbor) )
121
- . collect ( ) ;
146
+ let extra_peers = self . find_qualified_replicas ( network) ?;
122
147
peers. extend ( extra_peers) ;
123
148
}
124
149
125
150
peers. shuffle ( & mut thread_rng ( ) ) ;
126
151
127
- let unique_ip_peers = Self :: coalesce_peers_by_ipaddr ( peers) ;
128
- for peer in unique_ip_peers {
152
+ for peer in peers {
129
153
if connected_replicas. len ( ) >= config. max_neighbors {
130
154
break ;
131
155
}
@@ -586,20 +610,8 @@ impl<NC: NeighborComms> StackerDBSync<NC> {
586
610
pub fn connect_begin ( & mut self , network : & mut PeerNetwork ) -> Result < bool , net_error > {
587
611
if self . replicas . len ( ) == 0 {
588
612
// find some from the peer Db
589
- let replicas = PeerDB :: find_stacker_db_replicas (
590
- network. peerdb_conn ( ) ,
591
- network. get_local_peer ( ) . network_id ,
592
- & self . smart_contract_id ,
593
- get_epoch_time_secs ( )
594
- . saturating_sub ( network. get_connection_opts ( ) . max_neighbor_age ) ,
595
- self . max_neighbors ,
596
- ) ?
597
- . into_iter ( )
598
- . map ( |neighbor| NeighborAddress :: from_neighbor ( & neighbor) )
599
- . collect ( ) ;
600
-
601
- let unique_ip_peers = Self :: coalesce_peers_by_ipaddr ( replicas) ;
602
- self . replicas = unique_ip_peers. into_iter ( ) . collect ( ) ;
613
+ let replicas = self . find_qualified_replicas ( network) ?;
614
+ self . replicas = replicas;
603
615
}
604
616
debug ! (
605
617
"{:?}: connect_begin: establish StackerDB sessions to {} neighbors" ,
0 commit comments