nomos-specs/carnot/test_unhappy_path.py

265 lines
9.7 KiB
Python
Raw Normal View History

from carnot.carnot import *
Runnable Python implementation (#7) * use coarse grained events * Add timeout handler * Added runnable carnot implementation bare bones * Removed rusty_results dependency * Make easy tests * Python impl tests (#9) * Make easy tests * Made sure an old aggregatedQC is not used. * Test when a block has an old qc * adding highest voted view so that a node doesn't vote twice. * adding highest voted view so that a node doesn't vote twice. * Tests for voting * Tests for voting * Tests for voting * Tests for voting * Update test_happy_path.py --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Fix commit grandparent * Add tests assertions * Added base vote test * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes * Start unhappy path and update tests (#10) * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Update build timeout qc test * Added block content * Fix tests with block content and comments * Fix all timeouts are from the same view in timeout call * Add check for double view seen different block * Store just highest qc and aggregated views in AggregatedQc, * Fix timeout preconditions * Happy + Unhappy path implementation and tests (#15) * Implement timeouts unhappy path * views are sequential or consecutive. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Cleanup * refactor * Overlay based happy tests (#11) * Cleanup * Leaf committee member vote. * Leaf committee member vote, test. * Leaf committee member vote, test. * Description * Description * Description-refactoring * Cleanup * Fix leaf votes test * Clean overlay * Test single committee advances * Remove unhappy path test file * Update carnot description * Refactor local_timeout for NewView * Fix unhappy path conditions and added broadcasting * Unhappy path tests description * Commit all grandparents of a block from latest_committed view * Cleanup docs * Add unhappy path test vector * Remove block content --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Extract MockCarnot in happy path tests * Add is_safe_to_timeout checks on unhappy path methods * Fix happy math mockoverlay missing methods * Fix unhappy path double increments Fill missing qc building implementations * Implement first case of unhappy path with simple overlay Missing final assertions * Unhappy path base test assertions (#14) * Unhappy path tests replacing timeout msgs with NewView. Also revising the conditions to enter into the unhappy path. * Unhappy path tests assertions. * Fix assertions on test * Cleanup --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Remove redundant code and fix commit parent (#16) * Fix unhappy path tests (#17) * fix test * get highest qc from new view votes * Add missing assertion * Cleanup approve new view function * Remove calls to safe_timeout invariant * Fix approve new view * Make unhappy test continuously timeout * Increment current view on reciving a new qc Refactor reset last timeout qc * Fix happy path current view after receiving block qc * Complete mix succeed fails unhappy test * Refactor timeout_high_qc test to use fail method * Add block assertions on mixed unhappy test * Simplify approve block * add spec tests to ci * Extract implicit information from safe blocks (#19) * extract implicit information from safe blocks * fix test * Refactor last_view_timeout_qc and update calls on unhappy path * Update view upon reception of timeout qc (#20) * update view upon reception of timeout qc * only increase highest_voted_view * fix comments * [WIP] Use events instead of send/broadcast methods (#21) * Remove send and broadcast, use events * Adjust tests to use events * Adjust unhappy path tests to use events * Fix missing wrongly optional return types * Extrac common assert on propose_block * add informative comments and remove panic (#22) * add disclaimer (#23) * fix approve_new_view preconditions --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com> --------- Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com>
2023-05-05 07:58:58 +00:00
from unittest import TestCase
from itertools import chain
class MockCarnot(Carnot):
def __init__(self, id):
super(MockCarnot, self).__init__(id)
def rebuild_overlay_from_timeout_qc(self, timeout_qc: TimeoutQc):
pass
class MockOverlay(Overlay):
"""
Overlay for 5 nodes where the leader is the single member of the root committee
0
12
34
"""
def __init__(self):
self.parents = {
int_to_id(1): {int_to_id(0)},
int_to_id(2): {int_to_id(0)},
int_to_id(3): {int_to_id(1)},
int_to_id(4): {int_to_id(1)}
}
self.childs = {
int_to_id(0): {
int_to_id(1), int_to_id(2)
},
int_to_id(1): {
int_to_id(3), int_to_id(4)
}
}
self.leafs = {
int_to_id(2), int_to_id(3), int_to_id(4)
}
def leaf_committees(self) -> Set[Committee]:
return [[leaf] for leaf in self.leafs]
def root_committee(self) -> Committee:
return {int_to_id(0)}
def is_child_of_root_committee(self, _id: Id) -> bool:
return _id in {int_to_id(1), int_to_id(2)}
def is_member_of_child_committee(self, parent: Id, child: Id) -> bool:
return child in childs if (childs := self.childs.get(parent)) else False
def leader_super_majority_threshold(self, _id: Id) -> int:
return 3
def is_leader(self, _id: Id):
# Leader is the node with id 0, otherwise not
return _id == int_to_id(0)
def is_member_of_root_committee(self, _id: Id):
return _id == int_to_id(0)
def leader(self, view: View) -> Id:
return int_to_id(0)
def parent_committee(self, _id: Id) -> Optional[Committee]:
return self.parents.get(_id)
def is_member_of_leaf_committee(self, _id: Id) -> bool:
return _id in self.leafs
def super_majority_threshold(self, _id: Id) -> int:
thresholds = {
int_to_id(0): 2,
int_to_id(1): 2,
}
return thresholds.get(_id, 0)
def add_genesis_block(carnot: Carnot) -> Block:
genesis_block = Block(view=0, qc=StandardQc(block=b"", view=0), _id=b"")
carnot.safe_blocks[genesis_block.id()] = genesis_block
carnot.receive_block(genesis_block)
carnot.local_high_qc = genesis_block.qc
carnot.current_view = 1
return genesis_block
2023-05-24 11:44:23 +00:00
def initial_setup(test_case: TestCase, overlay: MockOverlay, size: int) -> (Dict[Id, Carnot], MockCarnot, Block):
Runnable Python implementation (#7) * use coarse grained events * Add timeout handler * Added runnable carnot implementation bare bones * Removed rusty_results dependency * Make easy tests * Python impl tests (#9) * Make easy tests * Made sure an old aggregatedQC is not used. * Test when a block has an old qc * adding highest voted view so that a node doesn't vote twice. * adding highest voted view so that a node doesn't vote twice. * Tests for voting * Tests for voting * Tests for voting * Tests for voting * Update test_happy_path.py --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Fix commit grandparent * Add tests assertions * Added base vote test * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes * Start unhappy path and update tests (#10) * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Update build timeout qc test * Added block content * Fix tests with block content and comments * Fix all timeouts are from the same view in timeout call * Add check for double view seen different block * Store just highest qc and aggregated views in AggregatedQc, * Fix timeout preconditions * Happy + Unhappy path implementation and tests (#15) * Implement timeouts unhappy path * views are sequential or consecutive. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Cleanup * refactor * Overlay based happy tests (#11) * Cleanup * Leaf committee member vote. * Leaf committee member vote, test. * Leaf committee member vote, test. * Description * Description * Description-refactoring * Cleanup * Fix leaf votes test * Clean overlay * Test single committee advances * Remove unhappy path test file * Update carnot description * Refactor local_timeout for NewView * Fix unhappy path conditions and added broadcasting * Unhappy path tests description * Commit all grandparents of a block from latest_committed view * Cleanup docs * Add unhappy path test vector * Remove block content --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Extract MockCarnot in happy path tests * Add is_safe_to_timeout checks on unhappy path methods * Fix happy math mockoverlay missing methods * Fix unhappy path double increments Fill missing qc building implementations * Implement first case of unhappy path with simple overlay Missing final assertions * Unhappy path base test assertions (#14) * Unhappy path tests replacing timeout msgs with NewView. Also revising the conditions to enter into the unhappy path. * Unhappy path tests assertions. * Fix assertions on test * Cleanup --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Remove redundant code and fix commit parent (#16) * Fix unhappy path tests (#17) * fix test * get highest qc from new view votes * Add missing assertion * Cleanup approve new view function * Remove calls to safe_timeout invariant * Fix approve new view * Make unhappy test continuously timeout * Increment current view on reciving a new qc Refactor reset last timeout qc * Fix happy path current view after receiving block qc * Complete mix succeed fails unhappy test * Refactor timeout_high_qc test to use fail method * Add block assertions on mixed unhappy test * Simplify approve block * add spec tests to ci * Extract implicit information from safe blocks (#19) * extract implicit information from safe blocks * fix test * Refactor last_view_timeout_qc and update calls on unhappy path * Update view upon reception of timeout qc (#20) * update view upon reception of timeout qc * only increase highest_voted_view * fix comments * [WIP] Use events instead of send/broadcast methods (#21) * Remove send and broadcast, use events * Adjust tests to use events * Adjust unhappy path tests to use events * Fix missing wrongly optional return types * Extrac common assert on propose_block * add informative comments and remove panic (#22) * add disclaimer (#23) * fix approve_new_view preconditions --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com> --------- Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com>
2023-05-05 07:58:58 +00:00
nodes = {int_to_id(i): MockCarnot(int_to_id(i)) for i in range(size)}
# add overlay
for node in nodes.values():
node.overlay = overlay
leader: MockCarnot = nodes[overlay.leader(0)]
genesis_block = None
for node in nodes.values():
genesis_block = add_genesis_block(node)
# votes for genesis block
genesis_votes = set(
Vote(
block=genesis_block.id(),
view=0,
voter=int_to_id(i),
qc=StandardQc(
block=genesis_block.id(),
view=0
),
) for i in range(5)
)
proposed_block = leader.propose_block(1, genesis_votes).payload
test_case.assertIsNotNone(proposed_block)
return nodes, leader, proposed_block
def parents_from_childs(overlay: MockOverlay, childs: List[Id]) -> Set[Id]:
if len(childs) == 0:
return set()
possible_parents = filter(
lambda x: x is not None,
chain.from_iterable(parent for _id in childs if (parent := overlay.parent_committee(_id)))
)
return set(possible_parents) if possible_parents else set()
def succeed(test_case: TestCase, overlay: Overlay, nodes: Dict[Id, Carnot], proposed_block: Block) -> List[Vote]:
Runnable Python implementation (#7) * use coarse grained events * Add timeout handler * Added runnable carnot implementation bare bones * Removed rusty_results dependency * Make easy tests * Python impl tests (#9) * Make easy tests * Made sure an old aggregatedQC is not used. * Test when a block has an old qc * adding highest voted view so that a node doesn't vote twice. * adding highest voted view so that a node doesn't vote twice. * Tests for voting * Tests for voting * Tests for voting * Tests for voting * Update test_happy_path.py --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Fix commit grandparent * Add tests assertions * Added base vote test * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes * Start unhappy path and update tests (#10) * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Update build timeout qc test * Added block content * Fix tests with block content and comments * Fix all timeouts are from the same view in timeout call * Add check for double view seen different block * Store just highest qc and aggregated views in AggregatedQc, * Fix timeout preconditions * Happy + Unhappy path implementation and tests (#15) * Implement timeouts unhappy path * views are sequential or consecutive. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Cleanup * refactor * Overlay based happy tests (#11) * Cleanup * Leaf committee member vote. * Leaf committee member vote, test. * Leaf committee member vote, test. * Description * Description * Description-refactoring * Cleanup * Fix leaf votes test * Clean overlay * Test single committee advances * Remove unhappy path test file * Update carnot description * Refactor local_timeout for NewView * Fix unhappy path conditions and added broadcasting * Unhappy path tests description * Commit all grandparents of a block from latest_committed view * Cleanup docs * Add unhappy path test vector * Remove block content --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Extract MockCarnot in happy path tests * Add is_safe_to_timeout checks on unhappy path methods * Fix happy math mockoverlay missing methods * Fix unhappy path double increments Fill missing qc building implementations * Implement first case of unhappy path with simple overlay Missing final assertions * Unhappy path base test assertions (#14) * Unhappy path tests replacing timeout msgs with NewView. Also revising the conditions to enter into the unhappy path. * Unhappy path tests assertions. * Fix assertions on test * Cleanup --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Remove redundant code and fix commit parent (#16) * Fix unhappy path tests (#17) * fix test * get highest qc from new view votes * Add missing assertion * Cleanup approve new view function * Remove calls to safe_timeout invariant * Fix approve new view * Make unhappy test continuously timeout * Increment current view on reciving a new qc Refactor reset last timeout qc * Fix happy path current view after receiving block qc * Complete mix succeed fails unhappy test * Refactor timeout_high_qc test to use fail method * Add block assertions on mixed unhappy test * Simplify approve block * add spec tests to ci * Extract implicit information from safe blocks (#19) * extract implicit information from safe blocks * fix test * Refactor last_view_timeout_qc and update calls on unhappy path * Update view upon reception of timeout qc (#20) * update view upon reception of timeout qc * only increase highest_voted_view * fix comments * [WIP] Use events instead of send/broadcast methods (#21) * Remove send and broadcast, use events * Adjust tests to use events * Adjust unhappy path tests to use events * Fix missing wrongly optional return types * Extrac common assert on propose_block * add informative comments and remove panic (#22) * add disclaimer (#23) * fix approve_new_view preconditions --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com> --------- Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com>
2023-05-05 07:58:58 +00:00
# broadcast the block
for node in nodes.values():
node.receive_block(proposed_block)
votes = {}
childs_ids = list(chain.from_iterable(overlay.leaf_committees()))
leafs = [nodes[_id] for _id in childs_ids]
for node in leafs:
vote = node.approve_block(proposed_block, set()).payload
votes[node.id] = vote
while len(parents := parents_from_childs(overlay, childs_ids)) != 0:
for node_id in parents:
node = nodes[node_id]
child_votes = [votes[_id] for _id in votes.keys() if overlay.is_member_of_child_committee(node_id, _id)]
if len(child_votes) == overlay.super_majority_threshold(node_id) and node_id not in votes:
vote = node.approve_block(proposed_block, child_votes).payload
votes[node_id] = vote
childs_ids = list(set(parents))
root_votes = [
votes[node_id]
for node_id in nodes
if overlay.is_member_of_root_committee(node_id) or overlay.is_child_of_root_committee(node_id)
]
return root_votes
def fail(test_case: TestCase, overlay: Overlay, nodes: Dict[Id, Carnot], proposed_block: Block) -> List[NewView]:
Runnable Python implementation (#7) * use coarse grained events * Add timeout handler * Added runnable carnot implementation bare bones * Removed rusty_results dependency * Make easy tests * Python impl tests (#9) * Make easy tests * Made sure an old aggregatedQC is not used. * Test when a block has an old qc * adding highest voted view so that a node doesn't vote twice. * adding highest voted view so that a node doesn't vote twice. * Tests for voting * Tests for voting * Tests for voting * Tests for voting * Update test_happy_path.py --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Fix commit grandparent * Add tests assertions * Added base vote test * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes * Start unhappy path and update tests (#10) * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Update build timeout qc test * Added block content * Fix tests with block content and comments * Fix all timeouts are from the same view in timeout call * Add check for double view seen different block * Store just highest qc and aggregated views in AggregatedQc, * Fix timeout preconditions * Happy + Unhappy path implementation and tests (#15) * Implement timeouts unhappy path * views are sequential or consecutive. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Cleanup * refactor * Overlay based happy tests (#11) * Cleanup * Leaf committee member vote. * Leaf committee member vote, test. * Leaf committee member vote, test. * Description * Description * Description-refactoring * Cleanup * Fix leaf votes test * Clean overlay * Test single committee advances * Remove unhappy path test file * Update carnot description * Refactor local_timeout for NewView * Fix unhappy path conditions and added broadcasting * Unhappy path tests description * Commit all grandparents of a block from latest_committed view * Cleanup docs * Add unhappy path test vector * Remove block content --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Extract MockCarnot in happy path tests * Add is_safe_to_timeout checks on unhappy path methods * Fix happy math mockoverlay missing methods * Fix unhappy path double increments Fill missing qc building implementations * Implement first case of unhappy path with simple overlay Missing final assertions * Unhappy path base test assertions (#14) * Unhappy path tests replacing timeout msgs with NewView. Also revising the conditions to enter into the unhappy path. * Unhappy path tests assertions. * Fix assertions on test * Cleanup --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Remove redundant code and fix commit parent (#16) * Fix unhappy path tests (#17) * fix test * get highest qc from new view votes * Add missing assertion * Cleanup approve new view function * Remove calls to safe_timeout invariant * Fix approve new view * Make unhappy test continuously timeout * Increment current view on reciving a new qc Refactor reset last timeout qc * Fix happy path current view after receiving block qc * Complete mix succeed fails unhappy test * Refactor timeout_high_qc test to use fail method * Add block assertions on mixed unhappy test * Simplify approve block * add spec tests to ci * Extract implicit information from safe blocks (#19) * extract implicit information from safe blocks * fix test * Refactor last_view_timeout_qc and update calls on unhappy path * Update view upon reception of timeout qc (#20) * update view upon reception of timeout qc * only increase highest_voted_view * fix comments * [WIP] Use events instead of send/broadcast methods (#21) * Remove send and broadcast, use events * Adjust tests to use events * Adjust unhappy path tests to use events * Fix missing wrongly optional return types * Extrac common assert on propose_block * add informative comments and remove panic (#22) * add disclaimer (#23) * fix approve_new_view preconditions --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com> --------- Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com>
2023-05-05 07:58:58 +00:00
# broadcast the block
for node in nodes.values():
node.receive_block(proposed_block)
node: MockCarnot
timeouts = []
for node in (nodes[_id] for _id in nodes if overlay.is_member_of_root_committee(_id) or overlay.is_child_of_root_committee(_id)):
timeout = node.local_timeout().payload
timeouts.append(timeout)
root_member = next(nodes[_id] for _id in nodes if overlay.is_member_of_root_committee(_id))
timeout_qc = root_member.timeout_detected(timeouts).payload
for node in nodes.values():
node.receive_timeout_qc(timeout_qc)
votes = {}
childs_ids = list(chain.from_iterable(overlay.leaf_committees()))
leafs = [nodes[_id] for _id in childs_ids]
for node in leafs:
vote = node.approve_new_view(timeout_qc, set()).payload
votes[node.id] = vote
while len(parents := parents_from_childs(overlay, childs_ids)) != 0:
for node_id in parents:
node = nodes[node_id]
child_votes = [votes[_id] for _id in votes.keys() if overlay.is_member_of_child_committee(node_id, _id)]
if len(child_votes) == overlay.super_majority_threshold(node_id) and node_id not in votes:
vote = node.approve_new_view(timeout_qc, child_votes).payload
votes[node_id] = vote
childs_ids = list(set(parents))
root_votes = [
votes[node_id]
for node_id in nodes
if overlay.is_member_of_root_committee(node_id) or overlay.is_child_of_root_committee(node_id)
]
return root_votes
class TestCarnotUnhappyPath(TestCase):
def test_timeout_high_qc(self):
"""
At the end of the timeout the highQC in the next leader's aggregatedQC should be the highestQC held by the
majority of nodes or a qc higher than th highestQC held by the majority of nodes.
Majority means more than two thirds of total number of nodes, randomly assigned to committees.
"""
overlay = MockOverlay()
2023-05-24 11:44:23 +00:00
nodes, leader, proposed_block = initial_setup(self, overlay, 5)
Runnable Python implementation (#7) * use coarse grained events * Add timeout handler * Added runnable carnot implementation bare bones * Removed rusty_results dependency * Make easy tests * Python impl tests (#9) * Make easy tests * Made sure an old aggregatedQC is not used. * Test when a block has an old qc * adding highest voted view so that a node doesn't vote twice. * adding highest voted view so that a node doesn't vote twice. * Tests for voting * Tests for voting * Tests for voting * Tests for voting * Update test_happy_path.py --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Fix commit grandparent * Add tests assertions * Added base vote test * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes * Start unhappy path and update tests (#10) * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Update build timeout qc test * Added block content * Fix tests with block content and comments * Fix all timeouts are from the same view in timeout call * Add check for double view seen different block * Store just highest qc and aggregated views in AggregatedQc, * Fix timeout preconditions * Happy + Unhappy path implementation and tests (#15) * Implement timeouts unhappy path * views are sequential or consecutive. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Cleanup * refactor * Overlay based happy tests (#11) * Cleanup * Leaf committee member vote. * Leaf committee member vote, test. * Leaf committee member vote, test. * Description * Description * Description-refactoring * Cleanup * Fix leaf votes test * Clean overlay * Test single committee advances * Remove unhappy path test file * Update carnot description * Refactor local_timeout for NewView * Fix unhappy path conditions and added broadcasting * Unhappy path tests description * Commit all grandparents of a block from latest_committed view * Cleanup docs * Add unhappy path test vector * Remove block content --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Extract MockCarnot in happy path tests * Add is_safe_to_timeout checks on unhappy path methods * Fix happy math mockoverlay missing methods * Fix unhappy path double increments Fill missing qc building implementations * Implement first case of unhappy path with simple overlay Missing final assertions * Unhappy path base test assertions (#14) * Unhappy path tests replacing timeout msgs with NewView. Also revising the conditions to enter into the unhappy path. * Unhappy path tests assertions. * Fix assertions on test * Cleanup --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Remove redundant code and fix commit parent (#16) * Fix unhappy path tests (#17) * fix test * get highest qc from new view votes * Add missing assertion * Cleanup approve new view function * Remove calls to safe_timeout invariant * Fix approve new view * Make unhappy test continuously timeout * Increment current view on reciving a new qc Refactor reset last timeout qc * Fix happy path current view after receiving block qc * Complete mix succeed fails unhappy test * Refactor timeout_high_qc test to use fail method * Add block assertions on mixed unhappy test * Simplify approve block * add spec tests to ci * Extract implicit information from safe blocks (#19) * extract implicit information from safe blocks * fix test * Refactor last_view_timeout_qc and update calls on unhappy path * Update view upon reception of timeout qc (#20) * update view upon reception of timeout qc * only increase highest_voted_view * fix comments * [WIP] Use events instead of send/broadcast methods (#21) * Remove send and broadcast, use events * Adjust tests to use events * Adjust unhappy path tests to use events * Fix missing wrongly optional return types * Extrac common assert on propose_block * add informative comments and remove panic (#22) * add disclaimer (#23) * fix approve_new_view preconditions --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com> --------- Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com>
2023-05-05 07:58:58 +00:00
# In this loop 'view' is the view that fails
for view in range(1, 4, 2):
# When view v fails, a timeout qc is built for view v and nodes jump to view v + 1
# while aggregating votes for the high qc. Those votes are then forwarded to the leader of view v + 2
# which can propose a block with those aggregate votes as proof of the previous round completion.
root_votes = fail(self, overlay, nodes, proposed_block)
proposed_block = leader.propose_block(view+2, root_votes).payload
# Add final assertions on nodes
# Thus, the first block that can be proposed is 2 views after the timeout
self.assertEqual(proposed_block.view, view + 2)
# Its qc is always for the view before the block is proposed for
self.assertEqual(proposed_block.qc.view, view + 1)
# The high qc is 0, since we never had a successful round
self.assertEqual(proposed_block.qc.high_qc().view, 0)
self.assertEqual(leader.last_view_timeout_qc.view, view)
self.assertEqual(leader.local_high_qc.view, 0)
self.assertEqual(leader.highest_voted_view, view+1)
for node in nodes.values():
self.assertEqual(node.latest_committed_view(), 0)
def test_interleave_success_fails(self):
"""
At the end of the timeout the highQC in the next leader's aggregatedQC should be the highestQC held by the
majority of nodes or a qc higher than th highestQC held by the majority of nodes.
Majority means more than two thirds of total number of nodes, randomly assigned to committees.
"""
overlay = MockOverlay()
leader: MockCarnot
2023-05-24 11:44:23 +00:00
nodes, leader, proposed_block = initial_setup(self, overlay, 5)
Runnable Python implementation (#7) * use coarse grained events * Add timeout handler * Added runnable carnot implementation bare bones * Removed rusty_results dependency * Make easy tests * Python impl tests (#9) * Make easy tests * Made sure an old aggregatedQC is not used. * Test when a block has an old qc * adding highest voted view so that a node doesn't vote twice. * adding highest voted view so that a node doesn't vote twice. * Tests for voting * Tests for voting * Tests for voting * Tests for voting * Update test_happy_path.py --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Fix commit grandparent * Add tests assertions * Added base vote test * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes * Start unhappy path and update tests (#10) * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Update build timeout qc test * Added block content * Fix tests with block content and comments * Fix all timeouts are from the same view in timeout call * Add check for double view seen different block * Store just highest qc and aggregated views in AggregatedQc, * Fix timeout preconditions * Happy + Unhappy path implementation and tests (#15) * Implement timeouts unhappy path * views are sequential or consecutive. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Cleanup * refactor * Overlay based happy tests (#11) * Cleanup * Leaf committee member vote. * Leaf committee member vote, test. * Leaf committee member vote, test. * Description * Description * Description-refactoring * Cleanup * Fix leaf votes test * Clean overlay * Test single committee advances * Remove unhappy path test file * Update carnot description * Refactor local_timeout for NewView * Fix unhappy path conditions and added broadcasting * Unhappy path tests description * Commit all grandparents of a block from latest_committed view * Cleanup docs * Add unhappy path test vector * Remove block content --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Extract MockCarnot in happy path tests * Add is_safe_to_timeout checks on unhappy path methods * Fix happy math mockoverlay missing methods * Fix unhappy path double increments Fill missing qc building implementations * Implement first case of unhappy path with simple overlay Missing final assertions * Unhappy path base test assertions (#14) * Unhappy path tests replacing timeout msgs with NewView. Also revising the conditions to enter into the unhappy path. * Unhappy path tests assertions. * Fix assertions on test * Cleanup --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Remove redundant code and fix commit parent (#16) * Fix unhappy path tests (#17) * fix test * get highest qc from new view votes * Add missing assertion * Cleanup approve new view function * Remove calls to safe_timeout invariant * Fix approve new view * Make unhappy test continuously timeout * Increment current view on reciving a new qc Refactor reset last timeout qc * Fix happy path current view after receiving block qc * Complete mix succeed fails unhappy test * Refactor timeout_high_qc test to use fail method * Add block assertions on mixed unhappy test * Simplify approve block * add spec tests to ci * Extract implicit information from safe blocks (#19) * extract implicit information from safe blocks * fix test * Refactor last_view_timeout_qc and update calls on unhappy path * Update view upon reception of timeout qc (#20) * update view upon reception of timeout qc * only increase highest_voted_view * fix comments * [WIP] Use events instead of send/broadcast methods (#21) * Remove send and broadcast, use events * Adjust tests to use events * Adjust unhappy path tests to use events * Fix missing wrongly optional return types * Extrac common assert on propose_block * add informative comments and remove panic (#22) * add disclaimer (#23) * fix approve_new_view preconditions --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com> --------- Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com>
2023-05-05 07:58:58 +00:00
for view in range(2, 5):
root_votes = succeed(self, overlay, nodes, proposed_block)
proposed_block = leader.propose_block(view, root_votes).payload
root_votes = fail(self, overlay, nodes, proposed_block)
proposed_block = leader.propose_block(6, root_votes).payload
for view in range(7, 8):
root_votes = succeed(self, overlay, nodes, proposed_block)
proposed_block = leader.propose_block(view, root_votes).payload
root_votes = fail(self, overlay, nodes, proposed_block)
proposed_block = leader.propose_block(9, root_votes).payload
for view in range(10, 15):
root_votes = succeed(self, overlay, nodes, proposed_block)
proposed_block = leader.propose_block(view, root_votes).payload
committed_blocks = {0, 1, 2, 3, 6, 9, 10, 11}
Runnable Python implementation (#7) * use coarse grained events * Add timeout handler * Added runnable carnot implementation bare bones * Removed rusty_results dependency * Make easy tests * Python impl tests (#9) * Make easy tests * Made sure an old aggregatedQC is not used. * Test when a block has an old qc * adding highest voted view so that a node doesn't vote twice. * adding highest voted view so that a node doesn't vote twice. * Tests for voting * Tests for voting * Tests for voting * Tests for voting * Update test_happy_path.py --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Fix commit grandparent * Add tests assertions * Added base vote test * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes * Start unhappy path and update tests (#10) * Tests for updating latest_committed_view and high_qc. * Vote tests * Vote tests * Get max timeout by highQC * Received Votes tests * Receive timeout msgs * Receive timeout msgs * Remove local files * Stylish, adjustments and fixes --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Update build timeout qc test * Added block content * Fix tests with block content and comments * Fix all timeouts are from the same view in timeout call * Add check for double view seen different block * Store just highest qc and aggregated views in AggregatedQc, * Fix timeout preconditions * Happy + Unhappy path implementation and tests (#15) * Implement timeouts unhappy path * views are sequential or consecutive. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Make sure view changes are incrementally done in ascending order. * Cleanup * refactor * Overlay based happy tests (#11) * Cleanup * Leaf committee member vote. * Leaf committee member vote, test. * Leaf committee member vote, test. * Description * Description * Description-refactoring * Cleanup * Fix leaf votes test * Clean overlay * Test single committee advances * Remove unhappy path test file * Update carnot description * Refactor local_timeout for NewView * Fix unhappy path conditions and added broadcasting * Unhappy path tests description * Commit all grandparents of a block from latest_committed view * Cleanup docs * Add unhappy path test vector * Remove block content --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Extract MockCarnot in happy path tests * Add is_safe_to_timeout checks on unhappy path methods * Fix happy math mockoverlay missing methods * Fix unhappy path double increments Fill missing qc building implementations * Implement first case of unhappy path with simple overlay Missing final assertions * Unhappy path base test assertions (#14) * Unhappy path tests replacing timeout msgs with NewView. Also revising the conditions to enter into the unhappy path. * Unhappy path tests assertions. * Fix assertions on test * Cleanup --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> * Remove redundant code and fix commit parent (#16) * Fix unhappy path tests (#17) * fix test * get highest qc from new view votes * Add missing assertion * Cleanup approve new view function * Remove calls to safe_timeout invariant * Fix approve new view * Make unhappy test continuously timeout * Increment current view on reciving a new qc Refactor reset last timeout qc * Fix happy path current view after receiving block qc * Complete mix succeed fails unhappy test * Refactor timeout_high_qc test to use fail method * Add block assertions on mixed unhappy test * Simplify approve block * add spec tests to ci * Extract implicit information from safe blocks (#19) * extract implicit information from safe blocks * fix test * Refactor last_view_timeout_qc and update calls on unhappy path * Update view upon reception of timeout qc (#20) * update view upon reception of timeout qc * only increase highest_voted_view * fix comments * [WIP] Use events instead of send/broadcast methods (#21) * Remove send and broadcast, use events * Adjust tests to use events * Adjust unhappy path tests to use events * Fix missing wrongly optional return types * Extrac common assert on propose_block * add informative comments and remove panic (#22) * add disclaimer (#23) * fix approve_new_view preconditions --------- Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com> --------- Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com> Co-authored-by: mjalalzai <33738574+MForensic@users.noreply.github.com> Co-authored-by: Giacomo Pasini <Zeegomo@users.noreply.github.com>
2023-05-05 07:58:58 +00:00
for node in nodes.values():
self.assertEqual(committed_blocks, {block.view for block in node.committed_blocks().values()})