message: improve: handle branch switch
diff: @@ -145,7 +145,49 @@ pub fn reducer(state: &mut State, action: &ActionWithMeta<Action>) {
  // let's check if it's a valid one for us.
  if level_state.latest_proposal.predecessor.hash != new_proposal.predecessor.hash {
  // new_proposal_is_on_another_branch
  + let switch = match (&level_state.endorsable_payload, &new_proposal.block.prequorum) {
  + (None, _) => {
  + // The new branch contains a PQC (and we do not) or a better
  + // fitness, we switch.
  + true
  + }
  + (Some(_), None) => {
  + // We have a better PQC, we don't switch as we are able to
  + // propose a better chain if we stay on our current one.
  + false
  + }
  + (Some(EndorsablePayload { prequorum: current_pqc, .. } ), Some(new_pqc)) => {
  + if current_pqc.round > new_pqc.round {
  + // The other's branch PQC is lower than ours, do not switch
  + false
  + } else if current_pqc.round < new_pqc.round {
  + // Their PQC is better than ours: we switch
  + true
  + } else {
  + // `current_pqc.round < new_pqc.round`
  + // There is a PQC on two branches with the same round and
  + // the same level but not the same predecessor : it's
  + // impossible unless if there was some double-baking. This
  + // shouldn't happen but do nothing anyway.
  + false
  + }
  + }
  + };
  + if switch {
  + level_state.latest_proposal = new_proposal.clone();
  + *round_state = RoundState {
  + current_round: round_by_timestamp(
  + *now_timestamp,
  + &new_proposal.predecessor,
  + &*config,
  + ),
  + current_phase: Phase::NonProposer,
  + };
  } else {
  + return;
  + }
  + }
  +
  let current_round = round_state.current_round;
  if current_round < new_proposal_round {
  // The proposal is invalid: we ignore it.
  @@ -214,7 +256,6 @@ pub fn reducer(state: &mut State, action: &ActionWithMeta<Action>) {
  }
  }
  }
  - }
  _ => return,
  }
  }
  @@ -270,7 +311,7 @@ fn round_by_timestamp(now_timestamp: i64, predecessor: &BlockInfo, config: &Conf
  let elapsed = now_timestamp - start_of_current_level;
  if elapsed < 0 {
  // receive proposal from the future
  - 0
  + i32::MIN
  } else {
  // m := minimal_block_delay
  // d := delay_increment_per_round
  