pub fn received_headers<T: BlockTree>(
        &mut self,
        from: &PeerId,
        headers: Vec<BlockHeader>,
        clock: &impl Clock,
        tree: &mut T,
    ) -> Result<ImportResult, store::Error> {
        let headers = if let Some(headers) = NonEmpty::from_vec(headers) {
            headers
        } else {
            return Ok(ImportResult::TipUnchanged);
        };

        let length = headers.len();
        let best = headers.last().block_hash();

        if let Some(peer) = self.peers.get_mut(from) {
            peer.last_active = Some(clock.local_time());
        } else {
            return Ok(ImportResult::TipUnchanged);
        }
        self.upstream
            .event(Event::HeadersReceived(*from, headers.len()));

        if tree.contains(&best) {
            return Ok(ImportResult::TipUnchanged);
        }

        match self.inflight.remove(from) {
            Some(GetHeaders { locators, .. })
                if headers
                    .iter()
                    .any(|h| locators.0.contains(&h.prev_blockhash)) =>
            {
                // Requested headers. These should extend our main chain.
                // Check whether the start of the header chain matches one of the locators we
                // supplied to the peer. Otherwise, we consider them unsolicited.

                let result = self.extend_chain(headers, clock, tree);

                if let Ok(ref imported) = result {
                    self.upstream
                        .event(Event::HeadersImported(imported.clone()));
                }

                if let Ok(ImportResult::TipChanged(tip, height, _)) = result {
                    let peer = self.peers.get_mut(from).unwrap();

                    if height > peer.height {
                        peer.tip = tip;
                        peer.height = height;
                    }
                }

                match result {
                    Ok(ImportResult::TipUnchanged) => Ok(ImportResult::TipUnchanged),
                    Ok(ImportResult::TipChanged(tip, height, reverted)) => {
                        // Keep track of when we last updated our tip. This is useful to check
                        // whether our tip is stale.
                        self.last_tip_update = Some(clock.local_time());

                        // If we received less than the maximum number of headers, we must be in sync.
                        // Otherwise, ask for the next batch of headers.
                        if length < self.config.max_message_headers {
                            // If these headers were unsolicited, we may already be ready/synced.
                            // Otherwise, we're finally in sync.

                            self.broadcast_tip(&tip, tree);
                            self.sync(clock.local_time(), tree);
                        } else {
                            // TODO: If we're already in the state of asking for this header, don't
                            // ask again.
                            // TODO: Should we use stop-hash for the single locator?
                            let locators = (vec![tip], BlockHash::default());
                            let timeout = self.config.request_timeout;

                            self.request(
                                *from,
                                locators,
                                clock.local_time(),
                                timeout,
                                OnTimeout::Disconnect,
                            );
                        }

                        Ok(ImportResult::TipChanged(tip, height, reverted))
                    }
                    Err(err) => self
                        .handle_error(from, err)
                        .map(|()| ImportResult::TipUnchanged),
                }
            }
            // Header announcement.
            _ if length <= MAX_HEADERS_ANNOUNCED => {
                let root = headers.first().block_hash();

                match tree.import_blocks(headers.into_iter(), clock) {
                    Ok(import_result @ ImportResult::TipUnchanged) => {
                        self.upstream
                            .event(Event::HeadersImported(import_result.clone()));

                        // Try to find a common ancestor that leads up to the first header in
                        // the list we received.
                        let locators = (tree.locator_hashes(tree.height()), root);
                        let timeout = self.config.request_timeout;

                        self.request(
                            *from,
                            locators,
                            clock.local_time(),
                            timeout,
                            OnTimeout::Ignore,
                        );

                        Ok(import_result)
                    }
                    Ok(ImportResult::TipChanged(tip, height, reverted)) => {
                        let peer = self.peers.get_mut(from).unwrap();
                        if height > peer.height {
                            peer.tip = tip;
                            peer.height = height;
                        }

                        self.upstream
                            .event(Event::HeadersImported(ImportResult::TipChanged(
                                tip,
                                height,
                                reverted.clone(),
                            )));

                        Ok(ImportResult::TipChanged(tip, height, reverted))
                    }
                    Err(err) => self
                        .handle_error(from, err)
                        .map(|()| ImportResult::TipUnchanged),
                }
            }
            // We've received a large number of unsolicited headers. This is more than the
            // typical headers sent during a header announcement, and we haven't asked
            // this peer for any headers. We choose to ignore it.
            _ => {
                self.upstream
                    .event(Event::UnsolicitedHeadersReceived(*from, length));

                Ok(ImportResult::TipUnchanged)
            }
        }
    }
/// Called when we receive headers from a peer.
Called when we receive headers from a peer.
Called when we receive headers from a peer .
pub fn received_headers<T: BlockTree>(
        &mut self,
        from: &PeerId,
        headers: Vec<BlockHeader>,
        clock: &impl Clock,
        tree: &mut T,
    ) -> Result<ImportResult, store::Error> {
        let headers = if let Some(headers) = NonEmpty::from_vec(headers) {
            headers
        } else {
            return Ok(ImportResult::TipUnchanged);
        };
        let length = headers.len();
        let best = headers.last().block_hash();
        if let Some(peer) = self.peers.get_mut(from) {
            peer.last_active = Some(clock.local_time());
        } else {
            return Ok(ImportResult::TipUnchanged);
        }
        self.upstream
            .event(Event::HeadersReceived(*from, headers.len()));
        if tree.contains(&best) {
            return Ok(ImportResult::TipUnchanged);
        }
        match self.inflight.remove(from) {
            Some(GetHeaders { locators, .. })
                if headers
                    .iter()
                    .any(|h| locators.0.contains(&h.prev_blockhash)) =>
            {
                // Requested headers. These should extend our main chain.
                // Check whether the start of the header chain matches one of the locators we
                // supplied to the peer. Otherwise, we consider them unsolicited.
                let result = self.extend_chain(headers, clock, tree);
                if let Ok(ref imported) = result {
                    self.upstream
                        .event(Event::HeadersImported(imported.clone()));
                }
                if let Ok(ImportResult::TipChanged(tip, height, _)) = result {
                    let peer = self.peers.get_mut(from).unwrap();
                    if height > peer.height {
                        peer.tip = tip;
                        peer.height = height;
                    }
                }
                match result {
                    Ok(ImportResult::TipUnchanged) => Ok(ImportResult::TipUnchanged),
                    Ok(ImportResult::TipChanged(tip, height, reverted)) => {
                        // Keep track of when we last updated our tip. This is useful to check
                        // whether our tip is stale.
                        self.last_tip_update = Some(clock.local_time());
                        // If we received less than the maximum number of headers, we must be in sync.
                        // Otherwise, ask for the next batch of headers.
                        if length < self.config.max_message_headers {
                            // If these headers were unsolicited, we may already be ready/synced.
                            // Otherwise, we're finally in sync.
                            self.broadcast_tip(&tip, tree);
                            self.sync(clock.local_time(), tree);
                        } else {
                            // TODO: If we're already in the state of asking for this header, don't
                            // ask again.
                            // TODO: Should we use stop-hash for the single locator?
                            let locators = (vec![tip], BlockHash::default());
                            let timeout = self.config.request_timeout;
                            self.request(
                                *from,
                                locators,
                                clock.local_time(),
                                timeout,
                                OnTimeout::Disconnect,
                            );
                        }
                        Ok(ImportResult::TipChanged(tip, height, reverted))
                    }
                    Err(err) => self
                        .handle_error(from, err)
                        .map(|()| ImportResult::TipUnchanged),
                }
            }
            // Header announcement.
            _ if length <= MAX_HEADERS_ANNOUNCED => {
                let root = headers.first().block_hash();
                match tree.import_blocks(headers.into_iter(), clock) {
                    Ok(import_result @ ImportResult::TipUnchanged) => {
                        self.upstream
                            .event(Event::HeadersImported(import_result.clone()));
                        // Try to find a common ancestor that leads up to the first header in
                        // the list we received.
                        let locators = (tree.locator_hashes(tree.height()), root);
                        let timeout = self.config.request_timeout;
                        self.request(
                            *from,
                            locators,
                            clock.local_time(),
                            timeout,
                            OnTimeout::Ignore,
                        );
                        Ok(import_result)
                    }
                    Ok(ImportResult::TipChanged(tip, height, reverted)) => {
                        let peer = self.peers.get_mut(from).unwrap();
                        if height > peer.height {
                            peer.tip = tip;
                            peer.height = height;
                        }
                        self.upstream
                            .event(Event::HeadersImported(ImportResult::TipChanged(
                                tip,
                                height,
                                reverted.clone(),
                            )));
                        Ok(ImportResult::TipChanged(tip, height, reverted))
                    }
                    Err(err) => self
                        .handle_error(from, err)
                        .map(|()| ImportResult::TipUnchanged),
                }
            }
            // We've received a large number of unsolicited headers. This is more than the
            // typical headers sent during a header announcement, and we haven't asked
            // this peer for any headers. We choose to ignore it.
            _ => {
                self.upstream
                    .event(Event::UnsolicitedHeadersReceived(*from, length));
                Ok(ImportResult::TipUnchanged)
            }
        }
    }
pub fn received_headers < T : BlockTree > ( & mut self , from : & PeerId , headers : Vec < BlockHeader > , clock : & impl Clock , tree : & mut T , ) -> Result < ImportResult , store :: Error > { let headers = if let Some ( headers ) = NonEmpty :: from_vec ( headers ) { headers } else { return Ok ( ImportResult :: TipUnchanged ) ; } ; let length = headers . len ( ) ; let best = headers . last ( ) . block_hash ( ) ; if let Some ( peer ) = self . peers . get_mut ( from ) { peer . last_active = Some ( clock . local_time ( ) ) ; } else { return Ok ( ImportResult :: TipUnchanged ) ; } self . upstream . event ( Event :: HeadersReceived ( * from , headers . len ( ) ) ) ; if tree . contains ( & best ) { return Ok ( ImportResult :: TipUnchanged ) ; } match self . inflight . remove ( from ) { Some ( GetHeaders { locators , .. } ) if headers . iter ( ) . any ( | h | locators . 0 . contains ( & h . prev_blockhash ) ) => { // Requested headers. These should extend our main chain. // Check whether the start of the header chain matches one of the locators we // supplied to the peer. Otherwise, we consider them unsolicited. let result = self . extend_chain ( headers , clock , tree ) ; if let Ok ( ref imported ) = result { self . upstream . event ( Event :: HeadersImported ( imported . clone ( ) ) ) ; } if let Ok ( ImportResult :: TipChanged ( tip , height , _ ) ) = result { let peer = self . peers . get_mut ( from ) . unwrap ( ) ; if height > peer . height { peer . tip = tip ; peer . height = height ; } } match result { Ok ( ImportResult :: TipUnchanged ) => Ok ( ImportResult :: TipUnchanged ) , Ok ( ImportResult :: TipChanged ( tip , height , reverted ) ) => { // Keep track of when we last updated our tip. This is useful to check // whether our tip is stale. self . last_tip_update = Some ( clock . local_time ( ) ) ; // If we received less than the maximum number of headers, we must be in sync. // Otherwise, ask for the next batch of headers. if length < self . config . max_message_headers { // If these headers were unsolicited, we may already be ready/synced. // Otherwise, we're finally in sync. self . broadcast_tip ( & tip , tree ) ; self . sync ( clock . local_time ( ) , tree ) ; } else { // TODO: If we're already in the state of asking for this header, don't // ask again. // TODO: Should we use stop-hash for the single locator? let locators = ( vec ! [ tip ] , BlockHash :: default ( ) ) ; let timeout = self . config . request_timeout ; self . request ( * from , locators , clock . local_time ( ) , timeout , OnTimeout :: Disconnect , ) ; } Ok ( ImportResult :: TipChanged ( tip , height , reverted ) ) } Err ( err ) => self . handle_error ( from , err ) . map ( | ( ) | ImportResult :: TipUnchanged ) , } } // Header announcement. _ if length <= MAX_HEADERS_ANNOUNCED => { let root = headers . first ( ) . block_hash ( ) ; match tree . import_blocks ( headers . into_iter ( ) , clock ) { Ok ( import_result @ ImportResult :: TipUnchanged ) => { self . upstream . event ( Event :: HeadersImported ( import_result . clone ( ) ) ) ; // Try to find a common ancestor that leads up to the first header in // the list we received. let locators = ( tree . locator_hashes ( tree . height ( ) ) , root ) ; let timeout = self . config . request_timeout ; self . request ( * from , locators , clock . local_time ( ) , timeout , OnTimeout :: Ignore , ) ; Ok ( import_result ) } Ok ( ImportResult :: TipChanged ( tip , height , reverted ) ) => { let peer = self . peers . get_mut ( from ) . unwrap ( ) ; if height > peer . height { peer . tip = tip ; peer . height = height ; } self . upstream . event ( Event :: HeadersImported ( ImportResult :: TipChanged ( tip , height , reverted . clone ( ) , ) ) ) ; Ok ( ImportResult :: TipChanged ( tip , height , reverted ) ) } Err ( err ) => self . handle_error ( from , err ) . map ( | ( ) | ImportResult :: TipUnchanged ) , } } // We've received a large number of unsolicited headers. This is more than the // typical headers sent during a header announcement, and we haven't asked // this peer for any headers. We choose to ignore it. _ => { self . upstream . event ( Event :: UnsolicitedHeadersReceived ( * from , length ) ) ; Ok ( ImportResult :: TipUnchanged ) } } }
Called when we receive headers from a peer.
Called when we receive headers from a peer .
&mut self
from
&PeerId
headers
Vec<BlockHeader>
clock
&impl Clock
tree
&mut T