/// Check whether or not the provided `BlockProposal` can be moved into the
/// validated pool. A `ValidatiorError::TransientError` value is returned
/// when any of the following conditions are met:
///
/// - the `Block`'s validation context is not available locally.
/// - The `Block`'s parent is not in the validated pool
/// - The `Block`'s parent is not notarized
/// - The payload_builder returns an `Err` result of any kind
///
/// A `ValidatorError::PermanentError` is returned when any of the following
/// conditions are met:
///
/// - The signer of the `BlockProposal` does not have the rank claimed on
///   the `Block`
/// - The signature on the `BlockProposal` is invalid.
/// - Any messages included in the payload are present in some ancestor of
///   the block
/// - Any of the values in the `ValidationContext` on the `Block` are less
///   than the corresponding value on the parent `Block`'s
///   `ValidationContext`.
Check whether or not the provided `BlockProposal` can be moved into the
validated pool. A `ValidatiorError::TransientError` value is returned
when any of the following conditions are met.

the `Block`'s validation context is not available locally.

A `ValidatorError::PermanentError` is returned when any of the following
conditions are met.


Check whether or not the provided ` BlockProposal ` can be moved into the validated pool . A ` ValidatiorError :: TransientError ` value is returned when any of the following conditions are met . the ` Block ` ' s validation context is not available locally . A ` ValidatorError :: PermanentError ` is returned when any of the following conditions are met .
fn check_block_validity(
        &self,
        pool_reader: &PoolReader<'_>,
        proposal: &BlockProposal,
        dkg_pool: &dyn DkgPool,
    ) -> ValidationResult<ValidatorError> {
        if proposal.height() == Height::from(0) {
            Err(PermanentError::CannotVerifyBlockHeightZero)?
        }
        // If the replica is upgrading, block payload should be empty.
        match pool_reader
            .registry_version(proposal.height())
            .and_then(|registry_version| {
                lookup_replica_version(
                    self.registry_client.as_ref(),
                    self.replica_config.subnet_id,
                    &self.log,
                    registry_version,
                )
            }) {
            Some(replica_version) => {
                if replica_version != ReplicaVersion::default() {
                    let payload = proposal.as_ref().payload.as_ref();
                    if !payload.is_summary() && !payload.is_empty() {
                        Err(PermanentError::NonEmptyPayloadPastUpgradePoint)?
                    }
                }
            }
            None => Err(TransientError::FailedToGetRegistryVersion)?,
        }
        let parent = get_notarized_parent(pool_reader, proposal)?;
        self.verify_signature(pool_reader, proposal)?;
        // Ensure registry_version, certified_height and time are non-decreasing.
        let proposal = proposal.as_ref();
        if !proposal.context.greater_or_equal(&parent.context) {
            Err(PermanentError::DecreasingValidationContext)?
        }
        let locally_available_context = ValidationContext {
            certified_height: self.state_manager.latest_certified_height(),
            registry_version: self.registry_client.get_latest_version(),
            time: self.time_source.get_relative_time(),
        };
        // If any part of our locally available validation context is less than the
        // proposal's validation context, we cannot validate it yet.
        if !locally_available_context.greater_or_equal(&proposal.context) {
            Err(TransientError::ValidationContextNotReached(
                proposal.context.clone(),
                locally_available_context,
            ))?
        }
        let payloads = pool_reader.get_payloads_from_height(
            proposal.context.certified_height.increment(),
            parent.clone(),
        );
        self.payload_builder
            .validate_payload(&proposal.payload, &payloads, &proposal.context)
            .map_err(|err| {
                err.map(
                    PermanentError::PayloadValidationError,
                    TransientError::PayloadValidationError,
                )
            })?;
        let timer = self
            .metrics
            .validation_duration
            .with_label_values(&["Dkg"])
            .start_timer();
        let ret = dkg::validate_payload(
            self.replica_config.subnet_id,
            self.registry_client.as_ref(),
            self.crypto.as_ref(),
            pool_reader,
            dkg_pool,
            parent,
            proposal.payload.as_ref(),
            self.state_manager.as_ref(),
            &proposal.context,
            &self.metrics.dkg_validator,
        )
        .map_err(|err| {
            err.map(
                PermanentError::DkgPayloadValidationError,
                TransientError::DkgPayloadValidationError,
            )
        });
        let elapsed = timer.stop_and_record();
        self.metrics.add_to_dkg_time_per_validator_run(elapsed);
        ret
    }
fn check_block_validity ( & self , pool_reader : & PoolReader < ' _ > , proposal : & BlockProposal , dkg_pool : & dyn DkgPool , ) -> ValidationResult < ValidatorError > { if proposal . height ( ) == Height :: from ( 0 ) { Err ( PermanentError :: CannotVerifyBlockHeightZero ) ? } // If the replica is upgrading, block payload should be empty. match pool_reader . registry_version ( proposal . height ( ) ) . and_then ( | registry_version | { lookup_replica_version ( self . registry_client . as_ref ( ) , self . replica_config . subnet_id , & self . log , registry_version , ) } ) { Some ( replica_version ) => { if replica_version != ReplicaVersion :: default ( ) { let payload = proposal . as_ref ( ) . payload . as_ref ( ) ; if ! payload . is_summary ( ) && ! payload . is_empty ( ) { Err ( PermanentError :: NonEmptyPayloadPastUpgradePoint ) ? } } } None => Err ( TransientError :: FailedToGetRegistryVersion ) ? , } let parent = get_notarized_parent ( pool_reader , proposal ) ? ; self . verify_signature ( pool_reader , proposal ) ? ; // Ensure registry_version, certified_height and time are non-decreasing. let proposal = proposal . as_ref ( ) ; if ! proposal . context . greater_or_equal ( & parent . context ) { Err ( PermanentError :: DecreasingValidationContext ) ? } let locally_available_context = ValidationContext { certified_height : self . state_manager . latest_certified_height ( ) , registry_version : self . registry_client . get_latest_version ( ) , time : self . time_source . get_relative_time ( ) , } ; // If any part of our locally available validation context is less than the // proposal's validation context, we cannot validate it yet. if ! locally_available_context . greater_or_equal ( & proposal . context ) { Err ( TransientError :: ValidationContextNotReached ( proposal . context . clone ( ) , locally_available_context , ) ) ? } let payloads = pool_reader . get_payloads_from_height ( proposal . context . certified_height . increment ( ) , parent . clone ( ) , ) ; self . payload_builder . validate_payload ( & proposal . payload , & payloads , & proposal . context ) . map_err ( | err | { err . map ( PermanentError :: PayloadValidationError , TransientError :: PayloadValidationError , ) } ) ? ; let timer = self . metrics . validation_duration . with_label_values ( & [ " " ] ) . start_timer ( ) ; let ret = dkg :: validate_payload ( self . replica_config . subnet_id , self . registry_client . as_ref ( ) , self . crypto . as_ref ( ) , pool_reader , dkg_pool , parent , proposal . payload . as_ref ( ) , self . state_manager . as_ref ( ) , & proposal . context , & self . metrics . dkg_validator , ) . map_err ( | err | { err . map ( PermanentError :: DkgPayloadValidationError , TransientError :: DkgPayloadValidationError , ) } ) ; let elapsed = timer . stop_and_record ( ) ; self . metrics . add_to_dkg_time_per_validator_run ( elapsed ) ; ret }
Check whether or not the provided `BlockProposal` can be moved into the
validated pool.
Check whether or not the provided ` BlockProposal ` can be moved into the validated pool .
&self
pool_reader
&PoolReader<'_>
proposal
&BlockProposal
dkg_pool
&dyn DkgPool