handle abandoned requests
This commit is contained in:
		
							parent
							
								
									ec88a992e3
								
							
						
					
					
						commit
						71e96aca10
					
				| @ -183,8 +183,6 @@ impl Fetcher { | |||||||
| 
 | 
 | ||||||
| 				let subchain_parent = request.subchain_parent.1; | 				let subchain_parent = request.subchain_parent.1; | ||||||
| 
 | 
 | ||||||
| 				// TODO: check subchain parent and punish peers who did framing
 |  | ||||||
| 				// if it's inaccurate.
 |  | ||||||
| 				if request.headers_request.max == 0 { | 				if request.headers_request.max == 0 { | ||||||
| 					if parent_hash.map_or(true, |hash| hash != subchain_parent) { | 					if parent_hash.map_or(true, |hash| hash != subchain_parent) { | ||||||
| 						let abort = AbortReason::BadScaffold(self.scaffold_contributors); | 						let abort = AbortReason::BadScaffold(self.scaffold_contributors); | ||||||
| @ -199,6 +197,18 @@ impl Fetcher { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	fn requests_abandoned(mut self, abandoned: &[ReqId]) -> SyncRound { | ||||||
|  | 		for abandoned in abandoned { | ||||||
|  | 			match self.pending.remove(abandoned) { | ||||||
|  | 				None => {}, | ||||||
|  | 				Some(req) => self.requests.push(req), | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// TODO: track failure rate and potentially abort.
 | ||||||
|  | 		SyncRound::Fetch(self) | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Round started: get stepped header chain.
 | /// Round started: get stepped header chain.
 | ||||||
| @ -223,6 +233,22 @@ impl RoundStart { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// called on failed attempt. may trigger a transition.
 | ||||||
|  | 	fn failed_attempt(mut self) -> SyncRound { | ||||||
|  | 		self.attempt += 1; | ||||||
|  | 
 | ||||||
|  | 		if self.attempt >= SCAFFOLD_ATTEMPTS { | ||||||
|  | 			if self.sparse_headers.len() > 1 { | ||||||
|  | 				let fetcher = Fetcher::new(self.sparse_headers, self.contributors.into_iter().collect()); | ||||||
|  | 				SyncRound::Fetch(fetcher) | ||||||
|  | 			} else { | ||||||
|  | 				SyncRound::Abort(AbortReason::NoResponses) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			SyncRound::Start(self) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	fn process_response<R: ResponseContext>(mut self, ctx: &R) -> SyncRound { | 	fn process_response<R: ResponseContext>(mut self, ctx: &R) -> SyncRound { | ||||||
| 		let req = match self.pending_req.take() { | 		let req = match self.pending_req.take() { | ||||||
| 			Some((id, ref req)) if ctx.req_id() == id => { req.clone() } | 			Some((id, ref req)) if ctx.req_id() == id => { req.clone() } | ||||||
| @ -232,7 +258,6 @@ impl RoundStart { | |||||||
| 			} | 			} | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		self.attempt += 1; |  | ||||||
| 		match response::decode_and_verify(ctx.data(), &req) { | 		match response::decode_and_verify(ctx.data(), &req) { | ||||||
| 			Ok(headers) => { | 			Ok(headers) => { | ||||||
| 				self.contributors.insert(ctx.responder()); | 				self.contributors.insert(ctx.responder()); | ||||||
| @ -252,15 +277,21 @@ impl RoundStart { | |||||||
| 			} | 			} | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		if self.attempt >= SCAFFOLD_ATTEMPTS { | 		self.failed_attempt() | ||||||
| 			if self.sparse_headers.len() > 1 { | 	} | ||||||
| 				let fetcher = Fetcher::new(self.sparse_headers, self.contributors.into_iter().collect()); | 
 | ||||||
| 				SyncRound::Fetch(fetcher) | 	fn requests_abandoned(mut self, abandoned: &[ReqId]) -> SyncRound { | ||||||
| 			} else { | 		match self.pending_req.take() { | ||||||
| 				SyncRound::Abort(AbortReason::NoResponses) | 			Some((id, req)) => { | ||||||
|  | 				if abandoned.iter().any(|r| r == &id) { | ||||||
|  | 					self.pending_req = None; | ||||||
|  | 					self.failed_attempt() | ||||||
|  | 				} else { | ||||||
|  | 					self.pending_req = Some((id, req)); | ||||||
|  | 					SyncRound::Start(self) | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} else { | 			None => SyncRound::Start(self), | ||||||
| 			SyncRound::Start(self) |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -293,7 +324,11 @@ impl SyncRound { | |||||||
| 
 | 
 | ||||||
| 	/// Return unfulfilled requests from disconnected peer. Unknown requests will be ignored.
 | 	/// Return unfulfilled requests from disconnected peer. Unknown requests will be ignored.
 | ||||||
| 	pub fn requests_abandoned(self, abandoned: &[ReqId]) -> Self { | 	pub fn requests_abandoned(self, abandoned: &[ReqId]) -> Self { | ||||||
| 		unimplemented!() | 		match self { | ||||||
|  | 			SyncRound::Start(round_start) => round_start.requests_abandoned(abandoned), | ||||||
|  | 			SyncRound::Fetch(fetcher) => fetcher.requests_abandoned(abandoned), | ||||||
|  | 			other => other, | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/// Dispatch pending requests. The dispatcher provided will attempt to
 | 	/// Dispatch pending requests. The dispatcher provided will attempt to
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user