in librabft-v2/src/data_sync.rs [113:177]
fn handle_notification(
&mut self,
smr_context: &mut Context,
notification: Self::Notification,
) -> Async<Option<Self::Request>> {
// Whether we should request more data because of a new epoch or missings records.
let mut should_sync = false;
// Note that malicious nodes can always lie to make us send a request, but they may as
// well send us a lengthy and slow `DataSyncResponse` directly. (DoS prevention is out of
// scope for this simulator.)
should_sync |= notification.current_epoch > self.epoch_id();
if let Some(highest_commit_certificate) = ¬ification.highest_commit_certificate {
// Try to insert the QC just in case.
self.insert_network_record(
highest_commit_certificate.value.epoch_id,
Record::QuorumCertificate(highest_commit_certificate.clone()),
smr_context,
);
should_sync |= (highest_commit_certificate.value.epoch_id > self.epoch_id())
|| (highest_commit_certificate.value.epoch_id == self.epoch_id()
&& highest_commit_certificate.value.round
> self.record_store().highest_committed_round() + 2);
}
if let Some(highest_quorum_certificate) = ¬ification.highest_quorum_certificate {
// Try to insert the QC.
self.insert_network_record(
highest_quorum_certificate.value.epoch_id,
Record::QuorumCertificate(highest_quorum_certificate.clone()),
smr_context,
);
// Check if we should request more data.
should_sync |= (highest_quorum_certificate.value.epoch_id > self.epoch_id())
|| (highest_quorum_certificate.value.epoch_id == self.epoch_id()
&& highest_quorum_certificate.value.round
> self.record_store().highest_quorum_certificate_round());
}
// Try to insert the proposed block right away.
if let Some(block) = notification.proposed_block {
self.insert_network_record(
notification.current_epoch,
Record::Block(block),
smr_context,
);
}
// Try to insert timeouts right away.
for timeout in notification.timeouts {
self.insert_network_record(
notification.current_epoch,
Record::Timeout(timeout),
smr_context,
);
}
// Try to insert votes right away.
if let Some(vote) = notification.current_vote {
self.insert_network_record(notification.current_epoch, Record::Vote(vote), smr_context);
}
// Create a follow-up request if needed.
let value = if should_sync {
Some(self.create_request_internal())
} else {
None
};
Box::pin(future::ready(value))
}