mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 23:18:01 +00:00
Check for block parent before verification. (#1714)
* Treat verification errors more seriously * Track obsolete requests * Check block parent before verification * Style
This commit is contained in:
@@ -91,14 +91,10 @@ struct Peer<B: BlockT, H: ExHashT> {
|
||||
best_hash: B::Hash,
|
||||
/// Peer best block number
|
||||
best_number: <B::Header as HeaderT>::Number,
|
||||
/// Pending block request if any
|
||||
block_request: Option<message::BlockRequest<B>>,
|
||||
/// Pending block request timestamp
|
||||
block_request_timestamp: Option<time::Instant>,
|
||||
/// Pending block justification request if any
|
||||
justification_request: Option<message::BlockRequest<B>>,
|
||||
/// Pending block justification request timestamp
|
||||
justification_request_timestamp: Option<time::Instant>,
|
||||
/// Current block request, if any.
|
||||
block_request: Option<(time::Instant, message::BlockRequest<B>)>,
|
||||
/// Requests we are no longer insterested in.
|
||||
obsolete_requests: HashMap<message::RequestId, time::Instant>,
|
||||
/// Holds a set of transactions known to this peer.
|
||||
known_extrinsics: HashSet<H>,
|
||||
/// Holds a set of blocks known to this peer.
|
||||
@@ -107,18 +103,6 @@ struct Peer<B: BlockT, H: ExHashT> {
|
||||
next_request_id: message::RequestId,
|
||||
}
|
||||
|
||||
impl<B: BlockT, H: ExHashT> Peer<B, H> {
|
||||
fn min_request_timestamp(&self) -> Option<&time::Instant> {
|
||||
match (self.block_request_timestamp, self.justification_request_timestamp) {
|
||||
(Some(t1), Some(t2)) if t1 < t2 => self.block_request_timestamp.as_ref(),
|
||||
(Some(_), Some(_)) => self.justification_request_timestamp.as_ref(),
|
||||
(Some(_), None) => self.block_request_timestamp.as_ref(),
|
||||
(None, Some(_)) => self.justification_request_timestamp.as_ref(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Info about a peer's known state.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PeerInfo<B: BlockT> {
|
||||
@@ -433,72 +417,22 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
}
|
||||
|
||||
fn handle_response(&mut self, who: NodeIndex, response: &message::BlockResponse<B>) -> Option<message::BlockRequest<B>> {
|
||||
let request = if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) {
|
||||
match (peer.block_request.take(), peer.justification_request.take()) {
|
||||
(Some(block_request), Some(justification_request)) => {
|
||||
if block_request.id == response.id {
|
||||
peer.block_request_timestamp = None;
|
||||
peer.justification_request = Some(justification_request);
|
||||
block_request
|
||||
} else if justification_request.id == response.id {
|
||||
peer.justification_request_timestamp = None;
|
||||
peer.block_request = Some(block_request);
|
||||
justification_request
|
||||
} else {
|
||||
peer.justification_request_timestamp = None;
|
||||
peer.block_request_timestamp = None;
|
||||
trace!(target: "sync", "Ignoring mismatched response packet from {} (expected {} or {} got {})",
|
||||
who,
|
||||
block_request.id,
|
||||
justification_request.id,
|
||||
response.id,
|
||||
);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
(Some(block_request), None) => {
|
||||
if block_request.id == response.id {
|
||||
peer.block_request_timestamp = None;
|
||||
block_request
|
||||
} else {
|
||||
peer.block_request_timestamp = None;
|
||||
trace!(target: "sync", "Ignoring mismatched response packet from {} (expected {} got {})",
|
||||
who,
|
||||
block_request.id,
|
||||
response.id,
|
||||
);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
(None, Some(justification_request)) => {
|
||||
if justification_request.id == response.id {
|
||||
peer.justification_request_timestamp = None;
|
||||
justification_request
|
||||
} else {
|
||||
peer.justification_request_timestamp = None;
|
||||
trace!(target: "sync", "Ignoring mismatched response packet from {} (expected {} got {})",
|
||||
who,
|
||||
justification_request.id,
|
||||
response.id,
|
||||
);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
(None, None) => {
|
||||
let _ = self
|
||||
.network_chan
|
||||
.send(NetworkMsg::ReportPeer(who, Severity::Bad("Unexpected response packet received from peer".to_string())));
|
||||
return None;
|
||||
},
|
||||
if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) {
|
||||
if let Some(_) = peer.obsolete_requests.remove(&response.id) {
|
||||
trace!(target: "sync", "Ignoring obsolete block response packet from {} ({})", who, response.id,);
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
// Clear the request. If the response is invalid peer will be disconnected anyway.
|
||||
let request = peer.block_request.take();
|
||||
if request.as_ref().map_or(false, |(_, r)| r.id == response.id) {
|
||||
return request.map(|(_, r)| r)
|
||||
}
|
||||
trace!(target: "sync", "Unexpected response packet from {} ({})", who, response.id,);
|
||||
let _ = self
|
||||
.network_chan
|
||||
.send(NetworkMsg::ReportPeer(who, Severity::Bad("Unexpected packet received from peer".to_string())));
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(request)
|
||||
.send(NetworkMsg::ReportPeer(who, Severity::Bad("Unexpected response packet received from peer".to_string())));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns protocol status
|
||||
@@ -726,18 +660,19 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
let tick = time::Instant::now();
|
||||
let mut aborting = Vec::new();
|
||||
{
|
||||
for (who, timestamp) in self
|
||||
.context_data
|
||||
.peers
|
||||
.iter()
|
||||
.filter_map(|(id, peer)| peer.min_request_timestamp().map(|r| (id, r)))
|
||||
.chain(self.handshaking_peers.iter())
|
||||
{
|
||||
if (tick - *timestamp).as_secs() > REQUEST_TIMEOUT_SEC {
|
||||
trace!(target: "sync", "Timeout {}", who);
|
||||
for (who, peer) in self.context_data.peers.iter() {
|
||||
if peer.block_request.as_ref().map_or(false, |(t, _)| (tick - *t).as_secs() > REQUEST_TIMEOUT_SEC) {
|
||||
trace!(target: "sync", "Reqeust timeout {}", who);
|
||||
aborting.push(*who);
|
||||
} else if peer.obsolete_requests.values().any(|t| (tick - *t).as_secs() > REQUEST_TIMEOUT_SEC) {
|
||||
trace!(target: "sync", "Obsolete timeout {}", who);
|
||||
aborting.push(*who);
|
||||
}
|
||||
}
|
||||
for (who, _) in self.handshaking_peers.iter().filter(|(_, t)| (tick - **t).as_secs() > REQUEST_TIMEOUT_SEC) {
|
||||
trace!(target: "sync", "Handshake timeout {}", who);
|
||||
aborting.push(*who);
|
||||
}
|
||||
}
|
||||
|
||||
self.specialization
|
||||
@@ -819,12 +754,10 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
best_hash: status.best_hash,
|
||||
best_number: status.best_number,
|
||||
block_request: None,
|
||||
block_request_timestamp: None,
|
||||
justification_request: None,
|
||||
justification_request_timestamp: None,
|
||||
known_extrinsics: HashSet::new(),
|
||||
known_blocks: HashSet::new(),
|
||||
next_request_id: 0,
|
||||
obsolete_requests: HashMap::new(),
|
||||
};
|
||||
self.context_data.peers.insert(who.clone(), peer);
|
||||
self.handshaking_peers.remove(&who);
|
||||
@@ -1182,14 +1115,11 @@ fn send_message<B: BlockT, H: ExHashT>(
|
||||
if let Some(ref mut peer) = peers.get_mut(&who) {
|
||||
r.id = peer.next_request_id;
|
||||
peer.next_request_id = peer.next_request_id + 1;
|
||||
|
||||
if r.fields == message::BlockAttributes::JUSTIFICATION {
|
||||
peer.justification_request = Some(r.clone());
|
||||
peer.justification_request_timestamp = Some(time::Instant::now());
|
||||
} else {
|
||||
peer.block_request = Some(r.clone());
|
||||
peer.block_request_timestamp = Some(time::Instant::now());
|
||||
if let Some((timestamp, request)) = peer.block_request.take() {
|
||||
trace!(target: "sync", "Request {} for {} is now obsolete.", request.id, who);
|
||||
peer.obsolete_requests.insert(request.id, timestamp);
|
||||
}
|
||||
peer.block_request = Some((time::Instant::now(), r.clone()));
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
||||
Reference in New Issue
Block a user