pub fn collect_best_chain_hashes(
        &self,
        intersection: Option<block::Hash>,
        stop: Option<block::Hash>,
        max_len: usize,
    ) -> Vec<block::Hash> {
        assert!(max_len > 0, "max_len must be at least 1");

        // We can get a block locator request before we have downloaded the genesis block
        let chain_tip_height = if let Some((height, _)) = self.best_tip() {
            height
        } else {
            tracing::debug!(
                response_len = ?0,
                "responding to peer GetBlocks or GetHeaders with empty state",
            );

            return Vec::new();
        };

        let intersection_height = intersection.map(|hash| {
            self.best_height_by_hash(hash)
                .expect("the intersection hash must be in the best chain")
        });
        let max_len_height = if let Some(intersection_height) = intersection_height {
            // start after the intersection_height, and return max_len hashes
            (intersection_height + (max_len as i32))
                .expect("the Find response height does not exceed Height::MAX")
        } else {
            // start at genesis, and return max_len hashes
            let max_height = block::Height(
                max_len
                    .try_into()
                    .expect("max_len does not exceed Height::MAX"),
            );
            (max_height - 1).expect("max_len is at least 1")
        };

        let stop_height = stop.and_then(|hash| self.best_height_by_hash(hash));

        // Compute the final height, making sure it is:
        //   * at or below our chain tip, and
        //   * at or below the height of the stop hash.
        let final_height = std::cmp::min(max_len_height, chain_tip_height);
        let final_height = stop_height
            .map(|stop_height| std::cmp::min(final_height, stop_height))
            .unwrap_or(final_height);
        let final_hash = self
            .best_hash(final_height)
            .expect("final height must have a hash");

        // We can use an "any chain" method here, because `final_hash` is in the best chain
        let mut res: Vec<_> = self
            .any_ancestor_blocks(final_hash)
            .map(|block| block.hash())
            .take_while(|&hash| Some(hash) != intersection)
            .inspect(|hash| {
                tracing::trace!(
                    ?hash,
                    height = ?self.best_height_by_hash(*hash)
                        .expect("if hash is in the state then it should have an associated height"),
                    "adding hash to peer Find response",
                )
            })
            .collect();
        res.reverse();

        tracing::debug!(
            ?final_height,
            response_len = ?res.len(),
            ?chain_tip_height,
            ?stop_height,
            ?intersection_height,
            "responding to peer GetBlocks or GetHeaders",
        );

        // Check the function implements the Find protocol
        assert!(
            res.len() <= max_len,
            "a Find response must not exceed the maximum response length"
        );
        assert!(
            intersection
                .map(|hash| !res.contains(&hash))
                .unwrap_or(true),
            "the list must not contain the intersection hash"
        );
        if let (Some(stop), Some((_, res_except_last))) = (stop, res.split_last()) {
            assert!(
                !res_except_last.contains(&stop),
                "if the stop hash is in the list, it must be the final hash"
            );
        }

        res
    }
/// Returns a list of block hashes in the best chain, following the `intersection` with the best
/// chain. If there is no intersection with the best chain, starts from the genesis hash.
///
/// Includes finalized and non-finalized blocks.
///
/// Stops the list of hashes after:
///   * adding the best tip,
///   * adding the `stop` hash to the list, if it is in the best chain, or
///   * adding `max_len` hashes to the list.
///
/// Returns an empty list if the state is empty,
/// or if the `intersection` is the best chain tip.
Returns a list of block hashes in the best chain, following the `intersection` with the best
chain. If there is no intersection with the best chain, starts from the genesis hash.

Includes finalized and non-finalized blocks.

Stops the list of hashes after:
adding the best tip,
adding the `stop` hash to the list, if it is in the best chain, or
adding `max_len` hashes to the list.

Returns an empty list if the state is empty,
or if the `intersection` is the best chain tip.
Returns a list of block hashes in the best chain following the ` intersection ` with the best chain . If there is no intersection with the best chain starts from the genesis hash . Includes finalized and non - finalized blocks . Stops the list of hashes after : adding the best tip adding the ` stop ` hash to the list if it is in the best chain or adding ` max_len ` hashes to the list . Returns an empty list if the state is empty or if the ` intersection ` is the best chain tip .
pub fn collect_best_chain_hashes(
        &self,
        intersection: Option<block::Hash>,
        stop: Option<block::Hash>,
        max_len: usize,
    ) -> Vec<block::Hash> {
        assert!(max_len > 0, "max_len must be at least 1");
        // We can get a block locator request before we have downloaded the genesis block
        let chain_tip_height = if let Some((height, _)) = self.best_tip() {
            height
        } else {
            tracing::debug!(
                response_len = ?0,
                "responding to peer GetBlocks or GetHeaders with empty state",
            );
            return Vec::new();
        };
        let intersection_height = intersection.map(|hash| {
            self.best_height_by_hash(hash)
                .expect("the intersection hash must be in the best chain")
        });
        let max_len_height = if let Some(intersection_height) = intersection_height {
            // start after the intersection_height, and return max_len hashes
            (intersection_height + (max_len as i32))
                .expect("the Find response height does not exceed Height::MAX")
        } else {
            // start at genesis, and return max_len hashes
            let max_height = block::Height(
                max_len
                    .try_into()
                    .expect("max_len does not exceed Height::MAX"),
            );
            (max_height - 1).expect("max_len is at least 1")
        };
        let stop_height = stop.and_then(|hash| self.best_height_by_hash(hash));
        // Compute the final height, making sure it is:
        //   * at or below our chain tip, and
        //   * at or below the height of the stop hash.
        let final_height = std::cmp::min(max_len_height, chain_tip_height);
        let final_height = stop_height
            .map(|stop_height| std::cmp::min(final_height, stop_height))
            .unwrap_or(final_height);
        let final_hash = self
            .best_hash(final_height)
            .expect("final height must have a hash");
        // We can use an "any chain" method here, because `final_hash` is in the best chain
        let mut res: Vec<_> = self
            .any_ancestor_blocks(final_hash)
            .map(|block| block.hash())
            .take_while(|&hash| Some(hash) != intersection)
            .inspect(|hash| {
                tracing::trace!(
                    ?hash,
                    height = ?self.best_height_by_hash(*hash)
                        .expect("if hash is in the state then it should have an associated height"),
                    "adding hash to peer Find response",
                )
            })
            .collect();
        res.reverse();
        tracing::debug!(
            ?final_height,
            response_len = ?res.len(),
            ?chain_tip_height,
            ?stop_height,
            ?intersection_height,
            "responding to peer GetBlocks or GetHeaders",
        );
        // Check the function implements the Find protocol
        assert!(
            res.len() <= max_len,
            "a Find response must not exceed the maximum response length"
        );
        assert!(
            intersection
                .map(|hash| !res.contains(&hash))
                .unwrap_or(true),
            "the list must not contain the intersection hash"
        );
        if let (Some(stop), Some((_, res_except_last))) = (stop, res.split_last()) {
            assert!(
                !res_except_last.contains(&stop),
                "if the stop hash is in the list, it must be the final hash"
            );
        }
        res
    }
pub fn collect_best_chain_hashes ( & self , intersection : Option < block :: Hash > , stop : Option < block :: Hash > , max_len : usize , ) -> Vec < block :: Hash > { assert ! ( max_len 0 " " ) ; // We can get a block locator request before we have downloaded the genesis block let chain_tip_height = if let Some ( ( height , _ ) ) = self . best_tip ( ) { height } else { tracing :: debug ! ( response_len 0 " " ) ; return Vec :: new ( ) ; } ; let intersection_height = intersection . map ( | hash | { self . best_height_by_hash ( hash ) . expect ( " " ) } ) ; let max_len_height = if let Some ( intersection_height ) = intersection_height { // start after the intersection_height, and return max_len hashes ( intersection_height + ( max_len as i32 ) ) . expect ( " " ) } else { // start at genesis, and return max_len hashes let max_height = block :: Height ( max_len . try_into ( ) . expect ( " " ) , ) ; ( max_height - 1 ) . expect ( " " ) } ; let stop_height = stop . and_then ( | hash | self . best_height_by_hash ( hash ) ) ; // Compute the final height, making sure it is: //   * at or below our chain tip, and //   * at or below the height of the stop hash. let final_height = std :: cmp :: min ( max_len_height , chain_tip_height ) ; let final_height = stop_height . map ( | stop_height | std :: cmp :: min ( final_height , stop_height ) ) . unwrap_or ( final_height ) ; let final_hash = self . best_hash ( final_height ) . expect ( " " ) ; // We can use an "any chain" method here, because `final_hash` is in the best chain let mut res : Vec < _ > = self . any_ancestor_blocks ( final_hash ) . map ( | block | block . hash ( ) ) . take_while ( | & hash | Some ( hash ) != intersection ) . inspect ( | hash | { tracing :: trace ! ( hash height self best_height_by_hash ( hash ) expect ( " " ) " " ) } ) . collect ( ) ; res . reverse ( ) ; tracing :: debug ! ( final_height response_len res len ( ) chain_tip_height stop_height intersection_height " " ) ; // Check the function implements the Find protocol assert ! ( res len ( ) max_len " " ) ; assert ! ( intersection map ( hash res contains ( hash ) ) unwrap_or ( true ) " " ) ; if let ( Some ( stop ) , Some ( ( _ , res_except_last ) ) ) = ( stop , res . split_last ( ) ) { assert ! ( res_except_last contains ( stop ) " " ) ; } res }
Returns a list of block hashes in the best chain, following the `intersection` with the best
chain.
Returns a list of block hashes in the best chain following the ` intersection ` with the best chain .
&self
intersection
Option<block::Hash>
stop
Option<block::Hash>
max_len
usize