pub(crate) fn validate_unit(&self, swunit: &SignedWireUnit<C>) -> Result<(), UnitError> {
        let wunit = swunit.wire_unit();
        let creator = wunit.creator;
        let panorama = &wunit.panorama;
        let timestamp = wunit.timestamp;
        panorama.validate(self)?;
        if panorama.iter_correct(self).any(|v| v.timestamp > timestamp)
            || wunit.timestamp < self.params.start_timestamp()
        {
            return Err(UnitError::Timestamps);
        }
        if wunit.seq_number != panorama.next_seq_num(self, creator) {
            return Err(UnitError::SequenceNumber);
        }
        let r_id = round_id(timestamp, wunit.round_exp);
        let maybe_prev_unit = wunit.previous().map(|vh| self.unit(vh));
        if let Some(prev_unit) = maybe_prev_unit {
            if prev_unit.round_exp != wunit.round_exp {
                // The round exponent must not change within a round: Even with respect to the
                // greater of the two exponents, a round boundary must be between the units.
                let max_re = prev_unit.round_exp.max(wunit.round_exp);
                if prev_unit.timestamp >> max_re == timestamp >> max_re {
                    return Err(UnitError::RoundLengthExpChangedWithinRound);
                }
            }
            // There can be at most two units per round: proposal/confirmation and witness.
            if let Some(prev2_unit) = prev_unit.previous().map(|h2| self.unit(h2)) {
                if prev2_unit.round_id() == r_id {
                    return Err(UnitError::ThreeUnitsInRound);
                }
            }
        }
        if ENABLE_ENDORSEMENTS {
            // All endorsed units from the panorama of this wunit.
            let endorsements_in_panorama = panorama
                .iter_correct_hashes()
                .flat_map(|hash| self.unit(hash).claims_endorsed())
                .collect::<HashSet<_>>();
            if endorsements_in_panorama
                .iter()
                .any(|&e| !wunit.endorsed.iter().any(|h| h == e))
            {
                return Err(UnitError::EndorsementsNotMonotonic);
            }
            for hash in &wunit.endorsed {
                if !wunit.panorama.sees(self, hash) {
                    return Err(UnitError::EndorsedButUnseen {
                        hash: format!("{:?}", hash),
                        wire_unit: format!("{:?}", wunit),
                    });
                }
            }
        }
        if wunit.value.is_some() {
            // If this unit is a block, it must be the first unit in this round, its timestamp must
            // match the round ID, and the creator must be the round leader.
            if maybe_prev_unit.map_or(false, |pv| pv.round_id() == r_id)
                || timestamp != r_id
                || self.leader(r_id) != creator
            {
                return Err(UnitError::NonLeaderBlock(self.leader(r_id)));
            }
            // It's not allowed to create a child block of a terminal block.
            let is_terminal = |hash: &C::Hash| self.is_terminal_block(hash);
            if self.fork_choice(panorama).map_or(false, is_terminal) {
                return Err(UnitError::ValueAfterTerminalBlock);
            }
        }
        match self.validate_lnc(creator, panorama, &wunit.endorsed) {
            None => Ok(()),
            Some(vidx) => Err(UnitError::LncNaiveCitation(vidx)),
        }
    }
/// Returns an error if `swunit` is invalid. Must only be called once `pre_validate_unit`
/// returned `Ok` and all dependencies have been added to the state.
Returns an error if `swunit` is invalid. Must only be called once `pre_validate_unit`
returned `Ok` and all dependencies have been added to the state.
Returns an error if ` swunit ` is invalid . Must only be called once ` pre_validate_unit ` returned ` Ok ` and all dependencies have been added to the state .
pub(crate) fn validate_unit(&self, swunit: &SignedWireUnit<C>) -> Result<(), UnitError> {
        let wunit = swunit.wire_unit();
        let creator = wunit.creator;
        let panorama = &wunit.panorama;
        let timestamp = wunit.timestamp;
        panorama.validate(self)?;
        if panorama.iter_correct(self).any(|v| v.timestamp > timestamp)
            || wunit.timestamp < self.params.start_timestamp()
        {
            return Err(UnitError::Timestamps);
        }
        if wunit.seq_number != panorama.next_seq_num(self, creator) {
            return Err(UnitError::SequenceNumber);
        }
        let r_id = round_id(timestamp, wunit.round_exp);
        let maybe_prev_unit = wunit.previous().map(|vh| self.unit(vh));
        if let Some(prev_unit) = maybe_prev_unit {
            if prev_unit.round_exp != wunit.round_exp {
                // The round exponent must not change within a round: Even with respect to the
                // greater of the two exponents, a round boundary must be between the units.
                let max_re = prev_unit.round_exp.max(wunit.round_exp);
                if prev_unit.timestamp >> max_re == timestamp >> max_re {
                    return Err(UnitError::RoundLengthExpChangedWithinRound);
                }
            }
            // There can be at most two units per round: proposal/confirmation and witness.
            if let Some(prev2_unit) = prev_unit.previous().map(|h2| self.unit(h2)) {
                if prev2_unit.round_id() == r_id {
                    return Err(UnitError::ThreeUnitsInRound);
                }
            }
        }
        if ENABLE_ENDORSEMENTS {
            // All endorsed units from the panorama of this wunit.
            let endorsements_in_panorama = panorama
                .iter_correct_hashes()
                .flat_map(|hash| self.unit(hash).claims_endorsed())
                .collect::<HashSet<_>>();
            if endorsements_in_panorama
                .iter()
                .any(|&e| !wunit.endorsed.iter().any(|h| h == e))
            {
                return Err(UnitError::EndorsementsNotMonotonic);
            }
            for hash in &wunit.endorsed {
                if !wunit.panorama.sees(self, hash) {
                    return Err(UnitError::EndorsedButUnseen {
                        hash: format!("{:?}", hash),
                        wire_unit: format!("{:?}", wunit),
                    });
                }
            }
        }
        if wunit.value.is_some() {
            // If this unit is a block, it must be the first unit in this round, its timestamp must
            // match the round ID, and the creator must be the round leader.
            if maybe_prev_unit.map_or(false, |pv| pv.round_id() == r_id)
                || timestamp != r_id
                || self.leader(r_id) != creator
            {
                return Err(UnitError::NonLeaderBlock(self.leader(r_id)));
            }
            // It's not allowed to create a child block of a terminal block.
            let is_terminal = |hash: &C::Hash| self.is_terminal_block(hash);
            if self.fork_choice(panorama).map_or(false, is_terminal) {
                return Err(UnitError::ValueAfterTerminalBlock);
            }
        }
        match self.validate_lnc(creator, panorama, &wunit.endorsed) {
            None => Ok(()),
            Some(vidx) => Err(UnitError::LncNaiveCitation(vidx)),
        }
    }
pub ( crate ) fn validate_unit ( & self , swunit : & SignedWireUnit < C > ) -> Result < ( ) , UnitError > { let wunit = swunit . wire_unit ( ) ; let creator = wunit . creator ; let panorama = & wunit . panorama ; let timestamp = wunit . timestamp ; panorama . validate ( self ) ? ; if panorama . iter_correct ( self ) . any ( | v | v . timestamp > timestamp ) || wunit . timestamp < self . params . start_timestamp ( ) { return Err ( UnitError :: Timestamps ) ; } if wunit . seq_number != panorama . next_seq_num ( self , creator ) { return Err ( UnitError :: SequenceNumber ) ; } let r_id = round_id ( timestamp , wunit . round_exp ) ; let maybe_prev_unit = wunit . previous ( ) . map ( | vh | self . unit ( vh ) ) ; if let Some ( prev_unit ) = maybe_prev_unit { if prev_unit . round_exp != wunit . round_exp { // The round exponent must not change within a round: Even with respect to the // greater of the two exponents, a round boundary must be between the units. let max_re = prev_unit . round_exp . max ( wunit . round_exp ) ; if prev_unit . timestamp >> max_re == timestamp >> max_re { return Err ( UnitError :: RoundLengthExpChangedWithinRound ) ; } } // There can be at most two units per round: proposal/confirmation and witness. if let Some ( prev2_unit ) = prev_unit . previous ( ) . map ( | h2 | self . unit ( h2 ) ) { if prev2_unit . round_id ( ) == r_id { return Err ( UnitError :: ThreeUnitsInRound ) ; } } } if ENABLE_ENDORSEMENTS { // All endorsed units from the panorama of this wunit. let endorsements_in_panorama = panorama . iter_correct_hashes ( ) . flat_map ( | hash | self . unit ( hash ) . claims_endorsed ( ) ) . collect :: < HashSet < _ > > ( ) ; if endorsements_in_panorama . iter ( ) . any ( | & e | ! wunit . endorsed . iter ( ) . any ( | h | h == e ) ) { return Err ( UnitError :: EndorsementsNotMonotonic ) ; } for hash in & wunit . endorsed { if ! wunit . panorama . sees ( self , hash ) { return Err ( UnitError :: EndorsedButUnseen { hash : format ! ( " " hash ) , wire_unit : format ! ( " " wunit ) , } ) ; } } } if wunit . value . is_some ( ) { // If this unit is a block, it must be the first unit in this round, its timestamp must // match the round ID, and the creator must be the round leader. if maybe_prev_unit . map_or ( false , | pv | pv . round_id ( ) == r_id ) || timestamp != r_id || self . leader ( r_id ) != creator { return Err ( UnitError :: NonLeaderBlock ( self . leader ( r_id ) ) ) ; } // It's not allowed to create a child block of a terminal block. let is_terminal = | hash : & C :: Hash | self . is_terminal_block ( hash ) ; if self . fork_choice ( panorama ) . map_or ( false , is_terminal ) { return Err ( UnitError :: ValueAfterTerminalBlock ) ; } } match self . validate_lnc ( creator , panorama , & wunit . endorsed ) { None => Ok ( ( ) ) , Some ( vidx ) => Err ( UnitError :: LncNaiveCitation ( vidx ) ) , } }
Returns an error if `swunit` is invalid.
Returns an error if ` swunit ` is invalid .
&self
swunit
&SignedWireUnit<C>
&self
swunit
&SignedWireUnit<C>