async fn validate_and_insert_headers(
        &self,
        block_nums: &[u64],
        headers: Vec<BlockHeader>,
    ) -> Result<(), HeaderSyncError>
    {
        if headers.is_empty() {
            return Err(HeaderSyncError::EmptyResponse);
        }
        // Check that the received headers are the requested headers
        if (0..block_nums.len()).any(|i| headers[i].height != block_nums[i]) {
            return Err(HeaderSyncError::IncorrectResponse);
        }
        // Check that header set forms a sequence
        for index in 1..headers.len() {
            let prev_header = &headers[index - 1];
            let curr_header = &headers[index];
            if prev_header.height + 1 != curr_header.height {
                return Err(HeaderSyncError::InvalidHeader(format!(
                    "Headers heights are not in sequence. (Previous height: {}, Current height: {})",
                    prev_header.height, curr_header.height
                )));
            }
            if curr_header.prev_hash != prev_header.hash() {
                return Err(HeaderSyncError::InvalidHeader(
                    "Headers do not form a chain.".to_string(),
                ));
            }
        }
        // Check that the first header is linked to the chain tip header
        assert_eq!(
            headers.is_empty(),
            false,
            "validate_headers: headers.is_empty() assertion failed"
        );
        let first_header = &headers[0];
        let db = &self.shared.db;
        let tip_header = async_db::fetch_tip_header(db.clone()).await?;
        if tip_header.height + 1 != first_header.height {
            return Err(HeaderSyncError::InvalidHeader(format!(
                "Headers do not link to the current chain tip header (Tip height = {}, Received header height = {})",
                tip_header.height, first_header.height
            )));
        }
        if first_header.prev_hash != tip_header.hash() {
            return Err(HeaderSyncError::InvalidHeader(
                "Headers do not form a chain from the current tip.".to_string(),
            ));
        }

        // Validate and insert each header
        let validator = self.shared.sync_validators.header.clone();
        let db = self.db();
        spawn_blocking(move || -> Result<(), HeaderSyncError> {
            for header in headers {
                validator
                    .validate(&header)
                    .map_err(HeaderSyncError::HeaderValidationFailed)?;
                db.insert_valid_headers(vec![header])?;
            }
            Ok(())
        })
        .await??;

        Ok(())
    }
// Check the received set of headers.
Check the received set of headers.
Check the received set of headers .
async fn validate_and_insert_headers(
        &self,
        block_nums: &[u64],
        headers: Vec<BlockHeader>,
    ) -> Result<(), HeaderSyncError>
    {
        if headers.is_empty() {
            return Err(HeaderSyncError::EmptyResponse);
        }
        // Check that the received headers are the requested headers
        if (0..block_nums.len()).any(|i| headers[i].height != block_nums[i]) {
            return Err(HeaderSyncError::IncorrectResponse);
        }
        // Check that header set forms a sequence
        for index in 1..headers.len() {
            let prev_header = &headers[index - 1];
            let curr_header = &headers[index];
            if prev_header.height + 1 != curr_header.height {
                return Err(HeaderSyncError::InvalidHeader(format!(
                    "Headers heights are not in sequence. (Previous height: {}, Current height: {})",
                    prev_header.height, curr_header.height
                )));
            }
            if curr_header.prev_hash != prev_header.hash() {
                return Err(HeaderSyncError::InvalidHeader(
                    "Headers do not form a chain.".to_string(),
                ));
            }
        }
        // Check that the first header is linked to the chain tip header
        assert_eq!(
            headers.is_empty(),
            false,
            "validate_headers: headers.is_empty() assertion failed"
        );
        let first_header = &headers[0];
        let db = &self.shared.db;
        let tip_header = async_db::fetch_tip_header(db.clone()).await?;
        if tip_header.height + 1 != first_header.height {
            return Err(HeaderSyncError::InvalidHeader(format!(
                "Headers do not link to the current chain tip header (Tip height = {}, Received header height = {})",
                tip_header.height, first_header.height
            )));
        }
        if first_header.prev_hash != tip_header.hash() {
            return Err(HeaderSyncError::InvalidHeader(
                "Headers do not form a chain from the current tip.".to_string(),
            ));
        }
        // Validate and insert each header
        let validator = self.shared.sync_validators.header.clone();
        let db = self.db();
        spawn_blocking(move || -> Result<(), HeaderSyncError> {
            for header in headers {
                validator
                    .validate(&header)
                    .map_err(HeaderSyncError::HeaderValidationFailed)?;
                db.insert_valid_headers(vec![header])?;
            }
            Ok(())
        })
        .await??;
        Ok(())
    }
async fn validate_and_insert_headers ( & self , block_nums : & [ u64 ] , headers : Vec < BlockHeader > , ) -> Result < ( ) , HeaderSyncError > { if headers . is_empty ( ) { return Err ( HeaderSyncError :: EmptyResponse ) ; } // Check that the received headers are the requested headers if ( 0 .. block_nums . len ( ) ) . any ( | i | headers [ i ] . height != block_nums [ i ] ) { return Err ( HeaderSyncError :: IncorrectResponse ) ; } // Check that header set forms a sequence for index in 1 .. headers . len ( ) { let prev_header = & headers [ index - 1 ] ; let curr_header = & headers [ index ] ; if prev_header . height + 1 != curr_header . height { return Err ( HeaderSyncError :: InvalidHeader ( format ! ( " " prev_header height curr_header height ) ) ) ; } if curr_header . prev_hash != prev_header . hash ( ) { return Err ( HeaderSyncError :: InvalidHeader ( " " . to_string ( ) , ) ) ; } } // Check that the first header is linked to the chain tip header assert_eq ! ( headers is_empty ( ) false " " ) ; let first_header = & headers [ 0 ] ; let db = & self . shared . db ; let tip_header = async_db :: fetch_tip_header ( db . clone ( ) ) . await ? ; if tip_header . height + 1 != first_header . height { return Err ( HeaderSyncError :: InvalidHeader ( format ! ( " " tip_header height first_header height ) ) ) ; } if first_header . prev_hash != tip_header . hash ( ) { return Err ( HeaderSyncError :: InvalidHeader ( " " . to_string ( ) , ) ) ; } // Validate and insert each header let validator = self . shared . sync_validators . header . clone ( ) ; let db = self . db ( ) ; spawn_blocking ( move | | -> Result < ( ) , HeaderSyncError > { for header in headers { validator . validate ( & header ) . map_err ( HeaderSyncError :: HeaderValidationFailed ) ? ; db . insert_valid_headers ( vec ! [ header ] ) ? ; } Ok ( ( ) ) } ) . await ? ? ; Ok ( ( ) ) }
Check the received set of headers.
Check the received set of headers .
&self
block_nums
&[u64]
headers
Vec<BlockHeader>
&self
block_nums
&[u64]
headers
Vec<BlockHeader>