diff --git a/carnot/carnot.py b/carnot/carnot.py index 8f53948..5f6e26e 100644 --- a/carnot/carnot.py +++ b/carnot/carnot.py @@ -466,19 +466,17 @@ class Carnot: self.rebuild_overlay_from_timeout_qc(timeout_qc) self.broadcast(timeout_qc) # we broadcast so all nodes can get ready for voting on a new view - def approve_new_view(self, new_views: Set[NewView]): - assert len(set(new_view.view for new_view in new_views)) == 1 + def approve_new_view(self, timeout_qc: TimeoutQc, new_views: Set[NewView]): # newView.view == self.last_timeout_view_qc.view for member of root committee and its children because # they have already created the timeout_qc. For other nodes newView.view > self.last_timeout_view_qc.view. if self.last_timeout_view_qc is not None: assert all(new_view.view >= self.last_timeout_view_qc.view for new_view in new_views) - assert all(new_view.view == new_view.timeout_qc.view for new_view in new_views) + assert all(new_view.view == timeout_qc.view for new_view in new_views) assert len(new_views) == self.overlay.super_majority_threshold(self.id) assert all(self.overlay.is_member_of_child_committee(self.id, new_view.sender) for new_view in new_views) - new_views = list(new_views) - timeout_qc = new_views[0].timeout_qc - new_high_qc = timeout_qc.high_qc + # get the highest qc from the new views + new_high_qc = max([new_view.timeout_qc for new_view in new_views] + [timeout_qc.high_qc], key=lambda qc: qc.view) self.rebuild_overlay_from_timeout_qc(timeout_qc) diff --git a/carnot/test_unhappy_path.py b/carnot/test_unhappy_path.py index a3f4384..6f2f7ca 100644 --- a/carnot/test_unhappy_path.py +++ b/carnot/test_unhappy_path.py @@ -1,4 +1,4 @@ -from .carnot import * +from carnot import * from unittest import TestCase @@ -166,19 +166,22 @@ class TestCarnotHappyPath(TestCase): node.received_timeout_qc(timeout_qc) # new view votes from leafs + for node in (nodes[int_to_id(_id)] for _id in (2, 3, 4)): + node.approve_new_view(timeout_qc, set()) + new_views_leafs_3_4 = [nodes[int_to_id(_id)].latest_event for _id in (3, 4)] new_view_leaf_2 = nodes[int_to_id(2)].latest_event # new view votes from committee 1 () node_1: MockCarnot = nodes[int_to_id(1)] - node_1.approve_new_view(new_views_leafs_3_4) + node_1.approve_new_view(timeout_qc, new_views_leafs_3_4) new_view_1 = node_1.latest_event # committee 1 and committee 2 new view votes new_views = [new_view_1, new_view_leaf_2] # forward root childs votes to root committee (compound of just the leader in this case) - leader.approve_new_view(new_views) + leader.approve_new_view(timeout_qc, new_views) root_new_view = leader.latest_event leader.propose_block(2, [root_new_view, new_view_1, new_view_leaf_2])