fn validate(
        &self,
        tip: &CachedBlock,
        header: &BlockHeader,
        clock: &impl Clock,
    ) -> Result<(), Error> {
        assert_eq!(tip.hash, header.prev_blockhash);

        let compact_target = if self.params.allow_min_difficulty_blocks
            && (tip.height + 1) % self.params.difficulty_adjustment_interval() != 0
        {
            if header.time > tip.time + self.params.pow_target_spacing as BlockTime * 2 {
                block::pow_limit_bits(&self.params.network)
            } else {
                self.next_min_difficulty_target(&self.params)
            }
        } else {
            self.next_difficulty_target(tip.height, tip.time, tip.target(), &self.params)
        };

        let target = BlockHeader::u256_from_compact_target(compact_target);

        match header.validate_pow(&target) {
            Err(bitcoin::util::Error::BlockBadProofOfWork) => {
                return Err(Error::InvalidBlockPoW);
            }
            Err(bitcoin::util::Error::BlockBadTarget) => {
                return Err(Error::InvalidBlockTarget(header.target(), target));
            }
            Err(_) => unreachable!(),
            Ok(_) => {}
        }

        // Validate against block checkpoints.
        let height = tip.height + 1;

        if let Some(checkpoint) = self.checkpoints.get(&height) {
            let hash = header.block_hash();

            if &hash != checkpoint {
                return Err(Error::InvalidBlockHash(hash, height));
            }
        }

        // A timestamp is accepted as valid if it is greater than the median timestamp of
        // the previous MEDIAN_TIME_SPAN blocks, and less than the network-adjusted
        // time + MAX_FUTURE_BLOCK_TIME.
        if header.time <= self.median_time_past(height) {
            return Err(Error::InvalidBlockTime(header.time, Ordering::Less));
        }
        if header.time > clock.block_time() + time::MAX_FUTURE_BLOCK_TIME {
            return Err(Error::InvalidBlockTime(header.time, Ordering::Greater));
        }

        Ok(())
    }
/// Validate a block header as a potential new tip. This performs full header validation.
Validate a block header as a potential new tip. This performs full header validation.
Validate a block header as a potential new tip . This performs full header validation .
fn validate(
        &self,
        tip: &CachedBlock,
        header: &BlockHeader,
        clock: &impl Clock,
    ) -> Result<(), Error> {
        assert_eq!(tip.hash, header.prev_blockhash);
        let compact_target = if self.params.allow_min_difficulty_blocks
            && (tip.height + 1) % self.params.difficulty_adjustment_interval() != 0
        {
            if header.time > tip.time + self.params.pow_target_spacing as BlockTime * 2 {
                block::pow_limit_bits(&self.params.network)
            } else {
                self.next_min_difficulty_target(&self.params)
            }
        } else {
            self.next_difficulty_target(tip.height, tip.time, tip.target(), &self.params)
        };
        let target = BlockHeader::u256_from_compact_target(compact_target);
        match header.validate_pow(&target) {
            Err(bitcoin::util::Error::BlockBadProofOfWork) => {
                return Err(Error::InvalidBlockPoW);
            }
            Err(bitcoin::util::Error::BlockBadTarget) => {
                return Err(Error::InvalidBlockTarget(header.target(), target));
            }
            Err(_) => unreachable!(),
            Ok(_) => {}
        }
        // Validate against block checkpoints.
        let height = tip.height + 1;
        if let Some(checkpoint) = self.checkpoints.get(&height) {
            let hash = header.block_hash();
            if &hash != checkpoint {
                return Err(Error::InvalidBlockHash(hash, height));
            }
        }
        // A timestamp is accepted as valid if it is greater than the median timestamp of
        // the previous MEDIAN_TIME_SPAN blocks, and less than the network-adjusted
        // time + MAX_FUTURE_BLOCK_TIME.
        if header.time <= self.median_time_past(height) {
            return Err(Error::InvalidBlockTime(header.time, Ordering::Less));
        }
        if header.time > clock.block_time() + time::MAX_FUTURE_BLOCK_TIME {
            return Err(Error::InvalidBlockTime(header.time, Ordering::Greater));
        }
        Ok(())
    }
fn validate ( & self , tip : & CachedBlock , header : & BlockHeader , clock : & impl Clock , ) -> Result < ( ) , Error > { assert_eq ! ( tip hash header prev_blockhash ) ; let compact_target = if self . params . allow_min_difficulty_blocks && ( tip . height + 1 ) % self . params . difficulty_adjustment_interval ( ) != 0 { if header . time > tip . time + self . params . pow_target_spacing as BlockTime * 2 { block :: pow_limit_bits ( & self . params . network ) } else { self . next_min_difficulty_target ( & self . params ) } } else { self . next_difficulty_target ( tip . height , tip . time , tip . target ( ) , & self . params ) } ; let target = BlockHeader :: u256_from_compact_target ( compact_target ) ; match header . validate_pow ( & target ) { Err ( bitcoin :: util :: Error :: BlockBadProofOfWork ) => { return Err ( Error :: InvalidBlockPoW ) ; } Err ( bitcoin :: util :: Error :: BlockBadTarget ) => { return Err ( Error :: InvalidBlockTarget ( header . target ( ) , target ) ) ; } Err ( _ ) => unreachable ! ( ) , Ok ( _ ) => { } } // Validate against block checkpoints. let height = tip . height + 1 ; if let Some ( checkpoint ) = self . checkpoints . get ( & height ) { let hash = header . block_hash ( ) ; if & hash != checkpoint { return Err ( Error :: InvalidBlockHash ( hash , height ) ) ; } } // A timestamp is accepted as valid if it is greater than the median timestamp of // the previous MEDIAN_TIME_SPAN blocks, and less than the network-adjusted // time + MAX_FUTURE_BLOCK_TIME. if header . time <= self . median_time_past ( height ) { return Err ( Error :: InvalidBlockTime ( header . time , Ordering :: Less ) ) ; } if header . time > clock . block_time ( ) + time :: MAX_FUTURE_BLOCK_TIME { return Err ( Error :: InvalidBlockTime ( header . time , Ordering :: Greater ) ) ; } Ok ( ( ) ) }
Validate a block header as a potential new tip.
Validate a block header as a potential new tip .
&self
tip
&CachedBlock
header
&BlockHeader
clock
&impl Clock