fn add_vertex(&mut self, now: Timestamp) -> ProtocolOutcomes<I, C> {
        let (maybe_pending_vertex, mut outcomes) = self.synchronizer.pop_vertex_to_add(
            &self.highway,
            &self.pending_values,
            self.config.max_requests_for_vertex,
        );
        let pending_vertex = match maybe_pending_vertex {
            None => return outcomes,
            Some(pending_vertex) => pending_vertex,
        };

        // If unit is sent by a doppelganger, deactivate this instance of an active
        // validator. Continue processing the unit so that it can be added to the state.
        if self.highway.is_doppelganger_vertex(pending_vertex.vertex()) {
            error!(
                vertex = ?pending_vertex.vertex(),
                "received vertex from a doppelganger. \
                 Are you running multiple nodes with the same validator key?",
            );
            self.deactivate_validator();
            outcomes.push(ProtocolOutcome::DoppelgangerDetected);
        }

        // If the vertex is invalid, drop all vertices that depend on this one, and disconnect from
        // the faulty senders.
        let sender = pending_vertex.sender().clone();
        let vv = match self.highway.validate_vertex(pending_vertex.into()) {
            Ok(vv) => vv,
            Err((pvv, err)) => {
                info!(?pvv, ?err, "invalid vertex");
                let vertices = vec![pvv.inner().id()];
                let faulty_senders = self.synchronizer.invalid_vertices(vertices);
                outcomes.extend(faulty_senders.into_iter().map(ProtocolOutcome::Disconnect));
                return outcomes;
            }
        };

        // If the vertex contains a consensus value, i.e. it is a proposal, request validation.
        let vertex = vv.inner();
        if let (Some(value), Some(timestamp), Some(swunit)) =
            (vertex.value(), vertex.timestamp(), vertex.unit())
        {
            let panorama = &swunit.wire_unit().panorama;
            let fork_choice = self.highway.state().fork_choice(panorama);
            if value.needs_validation() {
                self.log_proposal(vertex, "requesting proposal validation");
                let ancestor_values = self.ancestors(fork_choice).cloned().collect();
                let block_context = BlockContext::new(timestamp, ancestor_values);
                let proposed_block = ProposedBlock::new(value.clone(), block_context);
                if self
                    .pending_values
                    .entry(proposed_block.clone())
                    .or_default()
                    .insert((vv, sender.clone()))
                {
                    outcomes.push(ProtocolOutcome::ValidateConsensusValue {
                        sender,
                        proposed_block,
                    });
                }
                return outcomes;
            } else {
                self.log_proposal(vertex, "proposal does not need validation");
            }
        }

        // Either consensus value doesn't need validation or it's not a proposal.
        // We can add it to the state.
        outcomes.extend(self.add_valid_vertex(vv, now));
        // If we added new vertices to the state, check whether any dependencies we were
        // waiting for are now satisfied, and try adding the pending vertices as well.
        outcomes.extend(self.synchronizer.remove_satisfied_deps(&self.highway));
        // Check whether any new blocks were finalized.
        outcomes.extend(self.detect_finality());
        outcomes
    }
/// Adds the given vertices to the protocol state, if possible, or requests missing
/// dependencies or validation. Recursively schedules events to add everything that is
/// unblocked now.
Adds the given vertices to the protocol state, if possible, or requests missing
dependencies or validation. Recursively schedules events to add everything that is
unblocked now.
Adds the given vertices to the protocol state if possible or requests missing dependencies or validation . Recursively schedules events to add everything that is unblocked now .
fn add_vertex(&mut self, now: Timestamp) -> ProtocolOutcomes<I, C> {
        let (maybe_pending_vertex, mut outcomes) = self.synchronizer.pop_vertex_to_add(
            &self.highway,
            &self.pending_values,
            self.config.max_requests_for_vertex,
        );
        let pending_vertex = match maybe_pending_vertex {
            None => return outcomes,
            Some(pending_vertex) => pending_vertex,
        };
        // If unit is sent by a doppelganger, deactivate this instance of an active
        // validator. Continue processing the unit so that it can be added to the state.
        if self.highway.is_doppelganger_vertex(pending_vertex.vertex()) {
            error!(
                vertex = ?pending_vertex.vertex(),
                "received vertex from a doppelganger. \
                 Are you running multiple nodes with the same validator key?",
            );
            self.deactivate_validator();
            outcomes.push(ProtocolOutcome::DoppelgangerDetected);
        }
        // If the vertex is invalid, drop all vertices that depend on this one, and disconnect from
        // the faulty senders.
        let sender = pending_vertex.sender().clone();
        let vv = match self.highway.validate_vertex(pending_vertex.into()) {
            Ok(vv) => vv,
            Err((pvv, err)) => {
                info!(?pvv, ?err, "invalid vertex");
                let vertices = vec![pvv.inner().id()];
                let faulty_senders = self.synchronizer.invalid_vertices(vertices);
                outcomes.extend(faulty_senders.into_iter().map(ProtocolOutcome::Disconnect));
                return outcomes;
            }
        };
        // If the vertex contains a consensus value, i.e. it is a proposal, request validation.
        let vertex = vv.inner();
        if let (Some(value), Some(timestamp), Some(swunit)) =
            (vertex.value(), vertex.timestamp(), vertex.unit())
        {
            let panorama = &swunit.wire_unit().panorama;
            let fork_choice = self.highway.state().fork_choice(panorama);
            if value.needs_validation() {
                self.log_proposal(vertex, "requesting proposal validation");
                let ancestor_values = self.ancestors(fork_choice).cloned().collect();
                let block_context = BlockContext::new(timestamp, ancestor_values);
                let proposed_block = ProposedBlock::new(value.clone(), block_context);
                if self
                    .pending_values
                    .entry(proposed_block.clone())
                    .or_default()
                    .insert((vv, sender.clone()))
                {
                    outcomes.push(ProtocolOutcome::ValidateConsensusValue {
                        sender,
                        proposed_block,
                    });
                }
                return outcomes;
            } else {
                self.log_proposal(vertex, "proposal does not need validation");
            }
        }
        // Either consensus value doesn't need validation or it's not a proposal.
        // We can add it to the state.
        outcomes.extend(self.add_valid_vertex(vv, now));
        // If we added new vertices to the state, check whether any dependencies we were
        // waiting for are now satisfied, and try adding the pending vertices as well.
        outcomes.extend(self.synchronizer.remove_satisfied_deps(&self.highway));
        // Check whether any new blocks were finalized.
        outcomes.extend(self.detect_finality());
        outcomes
    }
fn add_vertex ( & mut self , now : Timestamp ) -> ProtocolOutcomes < I , C > { let ( maybe_pending_vertex , mut outcomes ) = self . synchronizer . pop_vertex_to_add ( & self . highway , & self . pending_values , self . config . max_requests_for_vertex , ) ; let pending_vertex = match maybe_pending_vertex { None => return outcomes , Some ( pending_vertex ) => pending_vertex , } ; // If unit is sent by a doppelganger, deactivate this instance of an active // validator. Continue processing the unit so that it can be added to the state. if self . highway . is_doppelganger_vertex ( pending_vertex . vertex ( ) ) { error ! ( vertex pending_vertex vertex ( ) " \
 " ) ; self . deactivate_validator ( ) ; outcomes . push ( ProtocolOutcome :: DoppelgangerDetected ) ; } // If the vertex is invalid, drop all vertices that depend on this one, and disconnect from // the faulty senders. let sender = pending_vertex . sender ( ) . clone ( ) ; let vv = match self . highway . validate_vertex ( pending_vertex . into ( ) ) { Ok ( vv ) => vv , Err ( ( pvv , err ) ) => { info ! ( pvv err " " ) ; let vertices = vec ! [ pvv inner ( ) id ( ) ] ; let faulty_senders = self . synchronizer . invalid_vertices ( vertices ) ; outcomes . extend ( faulty_senders . into_iter ( ) . map ( ProtocolOutcome :: Disconnect ) ) ; return outcomes ; } } ; // If the vertex contains a consensus value, i.e. it is a proposal, request validation. let vertex = vv . inner ( ) ; if let ( Some ( value ) , Some ( timestamp ) , Some ( swunit ) ) = ( vertex . value ( ) , vertex . timestamp ( ) , vertex . unit ( ) ) { let panorama = & swunit . wire_unit ( ) . panorama ; let fork_choice = self . highway . state ( ) . fork_choice ( panorama ) ; if value . needs_validation ( ) { self . log_proposal ( vertex , " " ) ; let ancestor_values = self . ancestors ( fork_choice ) . cloned ( ) . collect ( ) ; let block_context = BlockContext :: new ( timestamp , ancestor_values ) ; let proposed_block = ProposedBlock :: new ( value . clone ( ) , block_context ) ; if self . pending_values . entry ( proposed_block . clone ( ) ) . or_default ( ) . insert ( ( vv , sender . clone ( ) ) ) { outcomes . push ( ProtocolOutcome :: ValidateConsensusValue { sender , proposed_block , } ) ; } return outcomes ; } else { self . log_proposal ( vertex , " " ) ; } } // Either consensus value doesn't need validation or it's not a proposal. // We can add it to the state. outcomes . extend ( self . add_valid_vertex ( vv , now ) ) ; // If we added new vertices to the state, check whether any dependencies we were // waiting for are now satisfied, and try adding the pending vertices as well. outcomes . extend ( self . synchronizer . remove_satisfied_deps ( & self . highway ) ) ; // Check whether any new blocks were finalized. outcomes . extend ( self . detect_finality ( ) ) ; outcomes }
Adds the given vertices to the protocol state, if possible, or requests missing
dependencies or validation.
Adds the given vertices to the protocol state if possible or requests missing dependencies or validation .
&mut self
now
Timestamp
&mut self
now
Timestamp