pub fn process_chain_segment(
        &self,
        chain_segment: Vec<SignedBeaconBlock<T::EthSpec>>,
    ) -> ChainSegmentResult<T::EthSpec> {
        let mut filtered_chain_segment = Vec::with_capacity(chain_segment.len());
        let mut imported_blocks = 0;

        // Produce a list of the parent root and slot of the child of each block.
        //
        // E.g., `children[0] == (chain_segment[1].parent_root(), chain_segment[1].slot())`
        let children = chain_segment
            .iter()
            .skip(1)
            .map(|block| (block.parent_root(), block.slot()))
            .collect::<Vec<_>>();

        for (i, block) in chain_segment.into_iter().enumerate() {
            let block_root = get_block_root(&block);

            if let Some((child_parent_root, child_slot)) = children.get(i) {
                // If this block has a child in this chain segment, ensure that its parent root matches
                // the root of this block.
                //
                // Without this check it would be possible to have a block verified using the
                // incorrect shuffling. That would be bad, mmkay.
                if block_root != *child_parent_root {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error: BlockError::NonLinearParentRoots,
                    };
                }

                // Ensure that the slots are strictly increasing throughout the chain segment.
                if *child_slot <= block.slot() {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error: BlockError::NonLinearSlots,
                    };
                }
            }

            match check_block_relevancy(&block, Some(block_root), self) {
                // If the block is relevant, add it to the filtered chain segment.
                Ok(_) => filtered_chain_segment.push((block_root, block)),
                // If the block is already known, simply ignore this block.
                Err(BlockError::BlockIsAlreadyKnown) => continue,
                // If the block is the genesis block, simply ignore this block.
                Err(BlockError::GenesisBlock) => continue,
                // If the block is is for a finalized slot, simply ignore this block.
                //
                // The block is either:
                //
                // 1. In the canonical finalized chain.
                // 2. In some non-canonical chain at a slot that has been finalized already.
                //
                // In the case of (1), there's no need to re-import and later blocks in this
                // segement might be useful.
                //
                // In the case of (2), skipping the block is valid since we should never import it.
                // However, we will potentially get a `ParentUnknown` on a later block. The sync
                // protocol will need to ensure this is handled gracefully.
                Err(BlockError::WouldRevertFinalizedSlot { .. }) => continue,
                // The block has a known parent that does not descend from the finalized block.
                // There is no need to process this block or any children.
                Err(BlockError::NotFinalizedDescendant { block_parent_root }) => {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error: BlockError::NotFinalizedDescendant { block_parent_root },
                    };
                }
                // If there was an error whilst determining if the block was invalid, return that
                // error.
                Err(BlockError::BeaconChainError(e)) => {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error: BlockError::BeaconChainError(e),
                    };
                }
                // If the block was decided to be irrelevant for any other reason, don't include
                // this block or any of it's children in the filtered chain segment.
                _ => break,
            }
        }

        while let Some((_root, block)) = filtered_chain_segment.first() {
            // Determine the epoch of the first block in the remaining segment.
            let start_epoch = block.slot().epoch(T::EthSpec::slots_per_epoch());

            // The `last_index` indicates the position of the last block that is in the current
            // epoch of `start_epoch`.
            let last_index = filtered_chain_segment
                .iter()
                .position(|(_root, block)| {
                    block.slot().epoch(T::EthSpec::slots_per_epoch()) > start_epoch
                })
                .unwrap_or_else(|| filtered_chain_segment.len());

            // Split off the first section blocks that are all either within the current epoch of
            // the first block. These blocks can all be signature-verified with the same
            // `BeaconState`.
            let mut blocks = filtered_chain_segment.split_off(last_index);
            std::mem::swap(&mut blocks, &mut filtered_chain_segment);

            // Verify the signature of the blocks, returning early if the signature is invalid.
            let signature_verified_blocks = match signature_verify_chain_segment(blocks, self) {
                Ok(blocks) => blocks,
                Err(error) => {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error,
                    };
                }
            };

            // Import the blocks into the chain.
            for signature_verified_block in signature_verified_blocks {
                match self.process_block(signature_verified_block) {
                    Ok(_) => imported_blocks += 1,
                    Err(error) => {
                        return ChainSegmentResult::Failed {
                            imported_blocks,
                            error,
                        };
                    }
                }
            }
        }

        ChainSegmentResult::Successful { imported_blocks }
    }
/// Attempt to verify and import a chain of blocks to `self`.
///
/// The provided blocks _must_ each reference the previous block via `block.parent_root` (i.e.,
/// be a chain). An error will be returned if this is not the case.
///
/// This operation is not atomic; if one of the blocks in the chain is invalid then some prior
/// blocks might be imported.
///
/// This method is generally much more efficient than importing each block using
/// `Self::process_block`.
Attempt to verify and import a chain of blocks to `self`.
The provided blocks _must_ each reference the previous block via `block.parent_root` . An error will be returned if this is not the case.

This operation is not atomic; if one of the blocks in the chain is invalid then some prior
blocks might be imported.

This method is generally much more efficient than importing each block using
`Self::process_block`.
Attempt to verify and import a chain of blocks to ` self ` . The provided blocks _must_ each reference the previous block via ` block . parent_root ` . An error will be returned if this is not the case . This operation is not atomic ; if one of the blocks in the chain is invalid then some prior blocks might be imported . This method is generally much more efficient than importing each block using ` Self :: process_block ` .
pub fn process_chain_segment(
        &self,
        chain_segment: Vec<SignedBeaconBlock<T::EthSpec>>,
    ) -> ChainSegmentResult<T::EthSpec> {
        let mut filtered_chain_segment = Vec::with_capacity(chain_segment.len());
        let mut imported_blocks = 0;
        // Produce a list of the parent root and slot of the child of each block.
        //
        // E.g., `children[0] == (chain_segment[1].parent_root(), chain_segment[1].slot())`
        let children = chain_segment
            .iter()
            .skip(1)
            .map(|block| (block.parent_root(), block.slot()))
            .collect::<Vec<_>>();
        for (i, block) in chain_segment.into_iter().enumerate() {
            let block_root = get_block_root(&block);
            if let Some((child_parent_root, child_slot)) = children.get(i) {
                // If this block has a child in this chain segment, ensure that its parent root matches
                // the root of this block.
                //
                // Without this check it would be possible to have a block verified using the
                // incorrect shuffling. That would be bad, mmkay.
                if block_root != *child_parent_root {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error: BlockError::NonLinearParentRoots,
                    };
                }
                // Ensure that the slots are strictly increasing throughout the chain segment.
                if *child_slot <= block.slot() {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error: BlockError::NonLinearSlots,
                    };
                }
            }
            match check_block_relevancy(&block, Some(block_root), self) {
                // If the block is relevant, add it to the filtered chain segment.
                Ok(_) => filtered_chain_segment.push((block_root, block)),
                // If the block is already known, simply ignore this block.
                Err(BlockError::BlockIsAlreadyKnown) => continue,
                // If the block is the genesis block, simply ignore this block.
                Err(BlockError::GenesisBlock) => continue,
                // If the block is is for a finalized slot, simply ignore this block.
                //
                // The block is either:
                //
                // 1. In the canonical finalized chain.
                // 2. In some non-canonical chain at a slot that has been finalized already.
                //
                // In the case of (1), there's no need to re-import and later blocks in this
                // segement might be useful.
                //
                // In the case of (2), skipping the block is valid since we should never import it.
                // However, we will potentially get a `ParentUnknown` on a later block. The sync
                // protocol will need to ensure this is handled gracefully.
                Err(BlockError::WouldRevertFinalizedSlot { .. }) => continue,
                // The block has a known parent that does not descend from the finalized block.
                // There is no need to process this block or any children.
                Err(BlockError::NotFinalizedDescendant { block_parent_root }) => {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error: BlockError::NotFinalizedDescendant { block_parent_root },
                    };
                }
                // If there was an error whilst determining if the block was invalid, return that
                // error.
                Err(BlockError::BeaconChainError(e)) => {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error: BlockError::BeaconChainError(e),
                    };
                }
                // If the block was decided to be irrelevant for any other reason, don't include
                // this block or any of it's children in the filtered chain segment.
                _ => break,
            }
        }
        while let Some((_root, block)) = filtered_chain_segment.first() {
            // Determine the epoch of the first block in the remaining segment.
            let start_epoch = block.slot().epoch(T::EthSpec::slots_per_epoch());
            // The `last_index` indicates the position of the last block that is in the current
            // epoch of `start_epoch`.
            let last_index = filtered_chain_segment
                .iter()
                .position(|(_root, block)| {
                    block.slot().epoch(T::EthSpec::slots_per_epoch()) > start_epoch
                })
                .unwrap_or_else(|| filtered_chain_segment.len());
            // Split off the first section blocks that are all either within the current epoch of
            // the first block. These blocks can all be signature-verified with the same
            // `BeaconState`.
            let mut blocks = filtered_chain_segment.split_off(last_index);
            std::mem::swap(&mut blocks, &mut filtered_chain_segment);
            // Verify the signature of the blocks, returning early if the signature is invalid.
            let signature_verified_blocks = match signature_verify_chain_segment(blocks, self) {
                Ok(blocks) => blocks,
                Err(error) => {
                    return ChainSegmentResult::Failed {
                        imported_blocks,
                        error,
                    };
                }
            };
            // Import the blocks into the chain.
            for signature_verified_block in signature_verified_blocks {
                match self.process_block(signature_verified_block) {
                    Ok(_) => imported_blocks += 1,
                    Err(error) => {
                        return ChainSegmentResult::Failed {
                            imported_blocks,
                            error,
                        };
                    }
                }
            }
        }
        ChainSegmentResult::Successful { imported_blocks }
    }
pub fn process_chain_segment ( & self , chain_segment : Vec < SignedBeaconBlock < T :: EthSpec > > , ) -> ChainSegmentResult < T :: EthSpec > { let mut filtered_chain_segment = Vec :: with_capacity ( chain_segment . len ( ) ) ; let mut imported_blocks = 0 ; // Produce a list of the parent root and slot of the child of each block. // // E.g., `children[0] == (chain_segment[1].parent_root(), chain_segment[1].slot())` let children = chain_segment . iter ( ) . skip ( 1 ) . map ( | block | ( block . parent_root ( ) , block . slot ( ) ) ) . collect :: < Vec < _ > > ( ) ; for ( i , block ) in chain_segment . into_iter ( ) . enumerate ( ) { let block_root = get_block_root ( & block ) ; if let Some ( ( child_parent_root , child_slot ) ) = children . get ( i ) { // If this block has a child in this chain segment, ensure that its parent root matches // the root of this block. // // Without this check it would be possible to have a block verified using the // incorrect shuffling. That would be bad, mmkay. if block_root != * child_parent_root { return ChainSegmentResult :: Failed { imported_blocks , error : BlockError :: NonLinearParentRoots , } ; } // Ensure that the slots are strictly increasing throughout the chain segment. if * child_slot <= block . slot ( ) { return ChainSegmentResult :: Failed { imported_blocks , error : BlockError :: NonLinearSlots , } ; } } match check_block_relevancy ( & block , Some ( block_root ) , self ) { // If the block is relevant, add it to the filtered chain segment. Ok ( _ ) => filtered_chain_segment . push ( ( block_root , block ) ) , // If the block is already known, simply ignore this block. Err ( BlockError :: BlockIsAlreadyKnown ) => continue , // If the block is the genesis block, simply ignore this block. Err ( BlockError :: GenesisBlock ) => continue , // If the block is is for a finalized slot, simply ignore this block. // // The block is either: // // 1. In the canonical finalized chain. // 2. In some non-canonical chain at a slot that has been finalized already. // // In the case of (1), there's no need to re-import and later blocks in this // segement might be useful. // // In the case of (2), skipping the block is valid since we should never import it. // However, we will potentially get a `ParentUnknown` on a later block. The sync // protocol will need to ensure this is handled gracefully. Err ( BlockError :: WouldRevertFinalizedSlot { .. } ) => continue , // The block has a known parent that does not descend from the finalized block. // There is no need to process this block or any children. Err ( BlockError :: NotFinalizedDescendant { block_parent_root } ) => { return ChainSegmentResult :: Failed { imported_blocks , error : BlockError :: NotFinalizedDescendant { block_parent_root } , } ; } // If there was an error whilst determining if the block was invalid, return that // error. Err ( BlockError :: BeaconChainError ( e ) ) => { return ChainSegmentResult :: Failed { imported_blocks , error : BlockError :: BeaconChainError ( e ) , } ; } // If the block was decided to be irrelevant for any other reason, don't include // this block or any of it's children in the filtered chain segment. _ => break , } } while let Some ( ( _root , block ) ) = filtered_chain_segment . first ( ) { // Determine the epoch of the first block in the remaining segment. let start_epoch = block . slot ( ) . epoch ( T :: EthSpec :: slots_per_epoch ( ) ) ; // The `last_index` indicates the position of the last block that is in the current // epoch of `start_epoch`. let last_index = filtered_chain_segment . iter ( ) . position ( | ( _root , block ) | { block . slot ( ) . epoch ( T :: EthSpec :: slots_per_epoch ( ) ) > start_epoch } ) . unwrap_or_else ( | | filtered_chain_segment . len ( ) ) ; // Split off the first section blocks that are all either within the current epoch of // the first block. These blocks can all be signature-verified with the same // `BeaconState`. let mut blocks = filtered_chain_segment . split_off ( last_index ) ; std :: mem :: swap ( & mut blocks , & mut filtered_chain_segment ) ; // Verify the signature of the blocks, returning early if the signature is invalid. let signature_verified_blocks = match signature_verify_chain_segment ( blocks , self ) { Ok ( blocks ) => blocks , Err ( error ) => { return ChainSegmentResult :: Failed { imported_blocks , error , } ; } } ; // Import the blocks into the chain. for signature_verified_block in signature_verified_blocks { match self . process_block ( signature_verified_block ) { Ok ( _ ) => imported_blocks += 1 , Err ( error ) => { return ChainSegmentResult :: Failed { imported_blocks , error , } ; } } } } ChainSegmentResult :: Successful { imported_blocks } }
Attempt to verify and import a chain of blocks to `self`.
Attempt to verify and import a chain of blocks to ` self ` .
&self
chain_segment
Vec<SignedBeaconBlock<T::EthSpec>>