pub fn process_new_ref(
    logger: Logger,
    mut blockchain: Blockchain,
    mut tip: Tip,
    candidate: Arc<Ref>,
) -> impl Future<Item = (), Error = Error> {
    use tokio::prelude::future::Either::*;

    let candidate_hash = candidate.hash();
    let mut storage = blockchain.storage().clone();

    tip.clone()
        .get_ref()
        .and_then(move |tip_ref| {
            if tip_ref.hash() == candidate.block_parent_hash() {
                info!(logger, "update current branch tip");
                A(A(tip.update_ref(candidate).map(|_| true)))
            } else {
                match compare_against(blockchain.storage(), &tip_ref, &candidate) {
                    ComparisonResult::PreferCurrent => {
                        info!(logger, "create new branch");
                        A(B(future::ok(false)))
                    }
                    ComparisonResult::PreferCandidate => {
                        info!(logger, "switching to new candidate branch");
                        B(blockchain
                            .branches_mut()
                            .apply_or_create(candidate)
                            .and_then(move |branch| tip.swap(branch))
                            .map(|()| true))
                    }
                }
            }
        })
        .map_err(|_: std::convert::Infallible| unreachable!())
        .and_then(move |tip_updated| {
            if tip_updated {
                A(storage
                    .put_tag(MAIN_BRANCH_TAG.to_owned(), candidate_hash)
                    .map_err(|e| Error::with_chain(e, "Cannot update the main storage's tip")))
            } else {
                B(future::ok(()))
            }
        })
}
/// process a new candidate block on top of the blockchain, this function may:
///
/// * update the current tip if the candidate's parent is the current tip;
/// * update a branch if the candidate parent is that branch's tip;
/// * create a new branch if none of the above;
///
/// If the current tip is not the one being updated we will then trigger
/// chain selection after updating that other branch as it may be possible that
/// this branch just became more interesting for the current consensus algorithm.
process a new candidate block on top of the blockchain, this function may:
update the current tip if the candidate's parent is the current tip;
update a branch if the candidate parent is that branch's tip;
create a new branch if none of the above.

If the current tip is not the one being updated we will then trigger
chain selection after updating that other branch as it may be possible that
this branch just became more interesting for the current consensus algorithm.
process a new candidate block on top of the blockchain this function may : update the current tip if the candidate ' s parent is the current tip ; update a branch if the candidate parent is that branch ' s tip ; create a new branch if none of the above . If the current tip is not the one being updated we will then trigger chain selection after updating that other branch as it may be possible that this branch just became more interesting for the current consensus algorithm .
pub fn process_new_ref(
    logger: Logger,
    mut blockchain: Blockchain,
    mut tip: Tip,
    candidate: Arc<Ref>,
) -> impl Future<Item = (), Error = Error> {
    use tokio::prelude::future::Either::*;
    let candidate_hash = candidate.hash();
    let mut storage = blockchain.storage().clone();
    tip.clone()
        .get_ref()
        .and_then(move |tip_ref| {
            if tip_ref.hash() == candidate.block_parent_hash() {
                info!(logger, "update current branch tip");
                A(A(tip.update_ref(candidate).map(|_| true)))
            } else {
                match compare_against(blockchain.storage(), &tip_ref, &candidate) {
                    ComparisonResult::PreferCurrent => {
                        info!(logger, "create new branch");
                        A(B(future::ok(false)))
                    }
                    ComparisonResult::PreferCandidate => {
                        info!(logger, "switching to new candidate branch");
                        B(blockchain
                            .branches_mut()
                            .apply_or_create(candidate)
                            .and_then(move |branch| tip.swap(branch))
                            .map(|()| true))
                    }
                }
            }
        })
        .map_err(|_: std::convert::Infallible| unreachable!())
        .and_then(move |tip_updated| {
            if tip_updated {
                A(storage
                    .put_tag(MAIN_BRANCH_TAG.to_owned(), candidate_hash)
                    .map_err(|e| Error::with_chain(e, "Cannot update the main storage's tip")))
            } else {
                B(future::ok(()))
            }
        })
}
pub fn process_new_ref ( logger : Logger , mut blockchain : Blockchain , mut tip : Tip , candidate : Arc < Ref > , ) -> impl Future < Item = ( ) , Error = Error > { use tokio :: prelude :: future :: Either :: * ; let candidate_hash = candidate . hash ( ) ; let mut storage = blockchain . storage ( ) . clone ( ) ; tip . clone ( ) . get_ref ( ) . and_then ( move | tip_ref | { if tip_ref . hash ( ) == candidate . block_parent_hash ( ) { info ! ( logger " " ) ; A ( A ( tip . update_ref ( candidate ) . map ( | _ | true ) ) ) } else { match compare_against ( blockchain . storage ( ) , & tip_ref , & candidate ) { ComparisonResult :: PreferCurrent => { info ! ( logger " " ) ; A ( B ( future :: ok ( false ) ) ) } ComparisonResult :: PreferCandidate => { info ! ( logger " " ) ; B ( blockchain . branches_mut ( ) . apply_or_create ( candidate ) . and_then ( move | branch | tip . swap ( branch ) ) . map ( | ( ) | true ) ) } } } } ) . map_err ( | _ : std :: convert :: Infallible | unreachable ! ( ) ) . and_then ( move | tip_updated | { if tip_updated { A ( storage . put_tag ( MAIN_BRANCH_TAG . to_owned ( ) , candidate_hash ) . map_err ( | e | Error :: with_chain ( e , " " ) ) ) } else { B ( future :: ok ( ( ) ) ) } } ) }
process a new candidate block on top of the blockchain, this function may:
 update the current tip if the candidate's parent is the current tip;
 update a branch if the candidate parent is that branch's tip;
 create a new branch if none of the above;
process a new candidate block on top of the blockchain this function may : update the current tip if the candidate ' s parent is the current tip ; update a branch if the candidate parent is that branch ' s tip ; create a new branch if none of the above ;
logger
Logger
blockchain
Blockchain
tip
Tip
candidate
Arc<Ref>
logger
Logger
blockchain
Blockchain
tip
Tip
candidate
Arc<Ref>