Skip to content

Commit

Permalink
[fix] #3087: Collect votes from observing peers after view change.
Browse files Browse the repository at this point in the history
Signed-off-by: Sam H. Smith <[email protected]>
  • Loading branch information
SamHSmith committed Feb 1, 2023
1 parent 403c682 commit 786e3d3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
3 changes: 1 addition & 2 deletions client/tests/integration/unstable_network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ fn soft_fork() {
);
}

#[ignore = "ignore, more in #2851"]
#[test]
fn unstable_network_7_peers_1_fault() {
let n_peers = 7;
Expand Down Expand Up @@ -84,7 +83,7 @@ fn unstable_network(
let (network, mut iroha_client) = rt.block_on(async {
let mut configuration = Configuration::test();
configuration.queue.maximum_transactions_in_block = MAXIMUM_TRANSACTIONS_IN_BLOCK;
configuration.logger.max_log_level = Level::ERROR.into();
configuration.logger.max_log_level = Level::INFO.into();
#[cfg(debug_assertions)]
{
configuration.sumeragi.debug_force_soft_fork = force_soft_fork;
Expand Down
36 changes: 31 additions & 5 deletions core/src/sumeragi/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,9 +669,16 @@ fn reset_state(
voting_block: &mut Option<VotingBlock>,
voting_signatures: &mut Vec<SignatureOf<SignedBlock>>,
round_start_time: &mut Instant,
last_view_change_time: &mut Instant,
view_change_time: &mut Duration,
) {
let mut was_commit_or_view_change = current_latest_block_height != *old_latest_block_height;
let mut was_commit_or_view_change = false;
if current_latest_block_height != *old_latest_block_height {
// Round is only restarted on a block commit, so that in the case of
// a view change a new block is immediately created by the leader
*round_start_time = Instant::now();
was_commit_or_view_change = true;
}

if current_view_change_index != *old_view_change_index {
current_topology.rebuild_with_new_view_change_count(current_view_change_index);
Expand All @@ -685,7 +692,7 @@ fn reset_state(

*voting_block = None;
voting_signatures.clear();
*round_start_time = Instant::now();
*last_view_change_time = Instant::now();
*view_change_time = pipeline_time;
info!(addr=%peer_id.address, role=%current_topology.role(peer_id), %current_view_change_index, "View change updated");
}
Expand Down Expand Up @@ -749,6 +756,8 @@ pub(crate) fn run<F: FaultInjection>(
let mut view_change_time = sumeragi.pipeline_time();
// Instant when the current round started
let mut round_start_time = Instant::now();
// Instant when the previous view change or round happened.
let mut last_view_change_time = Instant::now();

while !should_terminate(&mut shutdown_receiver) {
if should_sleep {
Expand Down Expand Up @@ -797,10 +806,11 @@ pub(crate) fn run<F: FaultInjection>(
&mut voting_block,
&mut voting_signatures,
&mut round_start_time,
&mut last_view_change_time,
&mut view_change_time,
);

if round_start_time.elapsed() > view_change_time {
if last_view_change_time.elapsed() > view_change_time {
let role = state.current_topology.role(&sumeragi.peer_id);

if let Some(VotingBlock { block, .. }) = voting_block.as_ref() {
Expand Down Expand Up @@ -912,6 +922,17 @@ pub(crate) fn run<F: FaultInjection>(
Role::ObservingPeer => match message {
Some(Message::BlockCreated(BlockCreated { block })) => {
if let Some(block) = vote_for_block(sumeragi, &state, block) {
if current_view_change_index >= 1 {
let block_hash = block.block.hash();

let msg = MessagePacket::new(
view_change_proof_chain.clone(),
BlockSigned::from(block.block.clone()),
);

sumeragi.broadcast_packet_to(msg, [current_topology.proxy_tail()]);
info!(%addr, %block_hash, "Block validated, signed and forwarded");
}
voting_block = Some(block);
}
}
Expand All @@ -933,8 +954,13 @@ pub(crate) fn run<F: FaultInjection>(
Some(Message::BlockSigned(BlockSigned { hash, signatures })) => {
trace!(block_hash=%hash, "Received block signatures");

let valid_signatures = current_topology
.filter_signatures_by_roles(&[Role::ValidatingPeer], &signatures);
let roles: &[Role] = if current_view_change_index >= 1 {
&[Role::ValidatingPeer, Role::ObservingPeer]
} else {
&[Role::ValidatingPeer]
};
let valid_signatures =
current_topology.filter_signatures_by_roles(roles, &signatures);

if let Some(voted_block) = voting_block.as_mut() {
let voting_block_hash = voted_block.block.hash();
Expand Down

0 comments on commit 786e3d3

Please sign in to comment.