Skip to content

Commit 1b85707

Browse files
committed
fix: gracefully handle connecting to lagging-behind peer
1 parent b0c5fc7 commit 1b85707

File tree

3 files changed

+18
-25
lines changed

3 files changed

+18
-25
lines changed

modules/peer_network_interface/src/chain_state.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,6 @@ impl ChainState {
220220
for _ in 0..5 {
221221
if let Some((slot, hash)) = iterator.next() {
222222
result.push(Point::Specific(*slot, hash.to_vec()));
223-
} else {
224-
result.push(Point::Origin);
225-
return result;
226223
}
227224
}
228225

@@ -231,9 +228,6 @@ impl ChainState {
231228
for _ in 0..5 {
232229
if let Some((slot, hash)) = iterator.next() {
233230
result.push(Point::Specific(*slot, hash.to_vec()));
234-
} else {
235-
result.push(Point::Origin);
236-
return result;
237231
}
238232
}
239233

@@ -243,9 +237,6 @@ impl ChainState {
243237
for _ in 0..5 {
244238
if let Some((slot, hash)) = iterator.next() {
245239
result.push(Point::Specific(*slot, hash.to_vec()));
246-
} else {
247-
result.push(Point::Origin);
248-
return result;
249240
}
250241
}
251242

modules/peer_network_interface/src/connection.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub enum PeerEvent {
7272
pub enum PeerChainSyncEvent {
7373
RollForward(Header),
7474
RollBackward(Point),
75+
IntersectNotFound(Point),
7576
}
7677

7778
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -146,8 +147,11 @@ impl PeerConnectionWorker {
146147
};
147148
match cmd {
148149
ChainsyncCommand::FindIntersect(points) => {
149-
let (point, _) = client.find_intersect(points).await?;
150+
let (point, tip) = client.find_intersect(points).await?;
150151
reached = point;
152+
if reached.is_none() {
153+
self.sender.write(PeerEvent::ChainSync(PeerChainSyncEvent::IntersectNotFound(tip.0))).await?;
154+
}
151155
}
152156
ChainsyncCommand::FindTip(done) => {
153157
let points = reached.as_slice().to_vec();

modules/peer_network_interface/src/network.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,12 @@ impl NetworkManager {
9999
};
100100
let conn = PeerConnection::new(address, self.network_magic, sender, delay);
101101
let peer = PeerData::new(conn);
102-
if self.chain.preferred_upstream.is_some() {
103-
let points = self.chain.choose_points_for_find_intersect();
104-
if !points.is_empty() {
105-
peer.find_intersect(points);
106-
}
107-
self.peers.insert(id, peer);
108-
} else {
109-
self.peers.insert(id, peer);
102+
let points = self.chain.choose_points_for_find_intersect();
103+
if !points.is_empty() {
104+
peer.find_intersect(points);
105+
}
106+
self.peers.insert(id, peer);
107+
if self.chain.preferred_upstream.is_none() {
110108
self.set_preferred_upstream(id);
111109
}
112110
}
@@ -156,6 +154,13 @@ impl NetworkManager {
156154
PeerEvent::ChainSync(PeerChainSyncEvent::RollBackward(point)) => {
157155
self.chain.handle_roll_backward(peer, point);
158156
}
157+
PeerEvent::ChainSync(PeerChainSyncEvent::IntersectNotFound(tip)) => {
158+
// We called find_intersect on a peer, and it didn't recognize any of the points we passed.
159+
// That peer must either be behind us or on a different fork; either way, that chain should sync from its own tip
160+
if let Some(peer) = self.peers.get(&peer) {
161+
peer.find_intersect(vec![tip]);
162+
}
163+
}
159164
PeerEvent::BlockFetched(fetched) => {
160165
for peer in self.peers.values_mut() {
161166
peer.ack_block(fetched.hash);
@@ -209,13 +214,6 @@ impl NetworkManager {
209214
};
210215
info!("setting preferred upstream to {}", peer.conn.address);
211216
self.chain.handle_new_preferred_upstream(id);
212-
213-
// If our preferred upstream changed, resync all connections.
214-
// That will trigger a rollback if needed.
215-
let points = self.chain.choose_points_for_find_intersect();
216-
for peer in self.peers.values() {
217-
peer.find_intersect(points.clone());
218-
}
219217
}
220218

221219
async fn publish_blocks(&mut self) -> Result<()> {

0 commit comments

Comments
 (0)