fn handle_notification()

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) = &notification.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) = &notification.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))
    }