diff --git a/core/src/sumeragi/main_loop.rs b/core/src/sumeragi/main_loop.rs index 7007948b92e..19aa97bfb6a 100644 --- a/core/src/sumeragi/main_loop.rs +++ b/core/src/sumeragi/main_loop.rs @@ -638,6 +638,7 @@ impl Sumeragi { if cache_full || (deadline_reached && cache_non_empty) { let transactions = self.transaction_cache.clone(); info!(%addr, txns=%transactions.len(), "Creating block..."); + let create_block_start_time = Instant::now(); // TODO: properly process triggers! let mut new_wsv = self.wsv.clone(); @@ -650,8 +651,14 @@ impl Sumeragi { .chain(current_view_change_index, &mut new_wsv) .sign(&self.key_pair); + let created_in = create_block_start_time.elapsed(); if let Some(current_topology) = current_topology.is_consensus_required() { - info!(%addr, block_payload_hash=%new_block.payload().hash(), "Block created"); + info!(%addr, created_in_ms=%created_in.as_millis(), block_payload_hash=%new_block.payload().hash(), "Block created"); + + if created_in > self.pipeline_time() / 2 { + warn!("Creating block takes too much time. This might prevent consensus from operating. Consider increasing `commit_time` or decreasing `max_transactions_in_block`"); + } + *voting_block = Some(VotingBlock::new(new_block.clone(), new_wsv)); let msg = BlockCreated::from(new_block).into(); diff --git a/core/src/sumeragi/network_topology.rs b/core/src/sumeragi/network_topology.rs index eb7c10a16df..35328b6298f 100644 --- a/core/src/sumeragi/network_topology.rs +++ b/core/src/sumeragi/network_topology.rs @@ -194,6 +194,26 @@ impl Topology { // Rotate all once for every view_change topology.rotate_all_n(view_change_index); + { + // FIXME: This is a hack to prevent consensus from running amock due to + // a bug in the implementation by reverting to predictable ordering + + let view_change_limit: usize = view_change_index + .saturating_sub(10) + .try_into() + .expect("u64 must fit into usize"); + + if view_change_limit > 1 { + iroha_logger::error!("Restarting consensus(internal bug). Report to developers"); + let mut peers: Vec<_> = topology.ordered_peers.iter().cloned().collect(); + + peers.sort(); + let peers_count = peers.len(); + peers.rotate_right(view_change_limit % peers_count); + topology = Topology::new(peers.into_iter().collect()); + } + } + topology }