fn try_construct_fork<T: BlockchainBackend>(
    db: &mut T,
    new_block: Arc<Block>,
) -> Result<VecDeque<Arc<Block>>, ChainStorageError>
{
    let mut fork_chain = VecDeque::new();
    let new_block_hash = new_block.hash();
    let new_block_height = new_block.header.height;
    let mut hash = new_block.header.prev_hash.clone();
    let mut height = new_block_height;
    fork_chain.push_front(new_block);

    loop {
        let fork_start_header = fork_chain
            .front()
            .expect("The new orphan block should be in the queue")
            .header
            .clone();
        debug!(
            target: LOG_TARGET,
            "Checking if block #{} ({}) is connected to the main chain.",
            fork_start_header.height,
            fork_start_header.hash().to_hex(),
        );
        if let Ok(header) = fetch_header_by_block_hash(db, fork_start_header.prev_hash) {
            if header.height + 1 == fork_start_header.height {
                debug!(
                    target: LOG_TARGET,
                    "Connection with main chain found at block #{} ({}) from block #{} ({}).",
                    header.height,
                    header.hash().to_hex(),
                    new_block_height,
                    new_block_hash.to_hex(),
                );
                return Ok(fork_chain);
            }
        }

        debug!(
            target: LOG_TARGET,
            "Not connected, checking if fork chain can be extended.",
        );
        match fetch_orphan(db, hash.clone()).map(Arc::new) {
            Ok(prev_block) => {
                debug!(
                    target: LOG_TARGET,
                    "Checking if block #{} ({}) forms a sequence with next block.",
                    prev_block.header.height,
                    hash.to_hex(),
                );
                if prev_block.header.height + 1 != height {
                    // Well now. The block heights don't form a sequence, which means that we should not only stop now,
                    // but remove one or both of these orphans from the pool because the blockchain is broken at this
                    // point.
                    debug!(
                        target: LOG_TARGET,
                        "A broken blockchain sequence was detected, removing block #{} ({}).",
                        prev_block.header.height,
                        hash.to_hex()
                    );
                    remove_orphan(db, hash)?;
                    return Err(ChainStorageError::InvalidBlock);
                }
                debug!(
                    target: LOG_TARGET,
                    "Fork chain extended with block #{} ({}).",
                    prev_block.header.height,
                    hash.to_hex(),
                );
                hash = prev_block.header.prev_hash.clone();
                height -= 1;
                fork_chain.push_front(prev_block);
            },
            Err(ChainStorageError::ValueNotFound { .. }) => {
                debug!(
                    target: LOG_TARGET,
                    "Fork chain extension not found, block #{} ({}) not connected to main chain.",
                    new_block_height,
                    new_block_hash.to_hex(),
                );
                break;
            },
            Err(e) => return Err(e),
        }
    }
    Ok(VecDeque::new())
}
/// We try and build a chain from this block to the main chain. If we can't do that we can stop.
/// We start with the current, newly received block, and look for a blockchain sequence (via `prev_hash`).
/// Each successful link is pushed to the front of the queue. An empty queue is returned if the fork chain did not
/// link to the main chain.
We try and build a chain from this block to the main chain. If we can't do that we can stop.
We start with the current, newly received block, and look for a blockchain sequence (via `prev_hash`).
Each successful link is pushed to the front of the queue. An empty queue is returned if the fork chain did not
link to the main chain.
We try and build a chain from this block to the main chain . If we can ' t do that we can stop . We start with the current newly received block and look for a blockchain sequence ( via ` prev_hash ` ) . Each successful link is pushed to the front of the queue . An empty queue is returned if the fork chain did not link to the main chain .
fn try_construct_fork<T: BlockchainBackend>(
    db: &mut T,
    new_block: Arc<Block>,
) -> Result<VecDeque<Arc<Block>>, ChainStorageError>
{
    let mut fork_chain = VecDeque::new();
    let new_block_hash = new_block.hash();
    let new_block_height = new_block.header.height;
    let mut hash = new_block.header.prev_hash.clone();
    let mut height = new_block_height;
    fork_chain.push_front(new_block);
    loop {
        let fork_start_header = fork_chain
            .front()
            .expect("The new orphan block should be in the queue")
            .header
            .clone();
        debug!(
            target: LOG_TARGET,
            "Checking if block #{} ({}) is connected to the main chain.",
            fork_start_header.height,
            fork_start_header.hash().to_hex(),
        );
        if let Ok(header) = fetch_header_by_block_hash(db, fork_start_header.prev_hash) {
            if header.height + 1 == fork_start_header.height {
                debug!(
                    target: LOG_TARGET,
                    "Connection with main chain found at block #{} ({}) from block #{} ({}).",
                    header.height,
                    header.hash().to_hex(),
                    new_block_height,
                    new_block_hash.to_hex(),
                );
                return Ok(fork_chain);
            }
        }
        debug!(
            target: LOG_TARGET,
            "Not connected, checking if fork chain can be extended.",
        );
        match fetch_orphan(db, hash.clone()).map(Arc::new) {
            Ok(prev_block) => {
                debug!(
                    target: LOG_TARGET,
                    "Checking if block #{} ({}) forms a sequence with next block.",
                    prev_block.header.height,
                    hash.to_hex(),
                );
                if prev_block.header.height + 1 != height {
                    // Well now. The block heights don't form a sequence, which means that we should not only stop now,
                    // but remove one or both of these orphans from the pool because the blockchain is broken at this
                    // point.
                    debug!(
                        target: LOG_TARGET,
                        "A broken blockchain sequence was detected, removing block #{} ({}).",
                        prev_block.header.height,
                        hash.to_hex()
                    );
                    remove_orphan(db, hash)?;
                    return Err(ChainStorageError::InvalidBlock);
                }
                debug!(
                    target: LOG_TARGET,
                    "Fork chain extended with block #{} ({}).",
                    prev_block.header.height,
                    hash.to_hex(),
                );
                hash = prev_block.header.prev_hash.clone();
                height -= 1;
                fork_chain.push_front(prev_block);
            },
            Err(ChainStorageError::ValueNotFound { .. }) => {
                debug!(
                    target: LOG_TARGET,
                    "Fork chain extension not found, block #{} ({}) not connected to main chain.",
                    new_block_height,
                    new_block_hash.to_hex(),
                );
                break;
            },
            Err(e) => return Err(e),
        }
    }
    Ok(VecDeque::new())
}
fn try_construct_fork < T : BlockchainBackend > ( db : & mut T , new_block : Arc < Block > , ) -> Result < VecDeque < Arc < Block > > , ChainStorageError > { let mut fork_chain = VecDeque :: new ( ) ; let new_block_hash = new_block . hash ( ) ; let new_block_height = new_block . header . height ; let mut hash = new_block . header . prev_hash . clone ( ) ; let mut height = new_block_height ; fork_chain . push_front ( new_block ) ; loop { let fork_start_header = fork_chain . front ( ) . expect ( " " ) . header . clone ( ) ; debug ! ( target LOG_TARGET " " fork_start_header height fork_start_header hash ( ) to_hex ( ) ) ; if let Ok ( header ) = fetch_header_by_block_hash ( db , fork_start_header . prev_hash ) { if header . height + 1 == fork_start_header . height { debug ! ( target LOG_TARGET " " header height header hash ( ) to_hex ( ) new_block_height new_block_hash to_hex ( ) ) ; return Ok ( fork_chain ) ; } } debug ! ( target LOG_TARGET " " ) ; match fetch_orphan ( db , hash . clone ( ) ) . map ( Arc :: new ) { Ok ( prev_block ) => { debug ! ( target LOG_TARGET " " prev_block header height hash to_hex ( ) ) ; if prev_block . header . height + 1 != height { // Well now. The block heights don't form a sequence, which means that we should not only stop now, // but remove one or both of these orphans from the pool because the blockchain is broken at this // point. debug ! ( target LOG_TARGET " " prev_block header height hash to_hex ( ) ) ; remove_orphan ( db , hash ) ? ; return Err ( ChainStorageError :: InvalidBlock ) ; } debug ! ( target LOG_TARGET " " prev_block header height hash to_hex ( ) ) ; hash = prev_block . header . prev_hash . clone ( ) ; height -= 1 ; fork_chain . push_front ( prev_block ) ; } , Err ( ChainStorageError :: ValueNotFound { .. } ) => { debug ! ( target LOG_TARGET " " new_block_height new_block_hash to_hex ( ) ) ; break ; } , Err ( e ) => return Err ( e ) , } } Ok ( VecDeque :: new ( ) ) }
We try and build a chain from this block to the main chain.
We try and build a chain from this block to the main chain .
db
&mut T
new_block
Arc<Block>
db
&mut T
new_block
Arc<Block>